Andrew Cooke | Contents | Latest | RSS | Twitter | Previous | Next


Welcome to my blog, which was once a mailing list of the same name and is still generated by mail. Please reply via the "comment" links.

Always interested in offers/projects/new ideas. Eclectic experience in fields like: numerical computing; Python web; Java enterprise; functional languages; GPGPU; SQL databases; etc. Based in Santiago, Chile; telecommute worldwide. CV; email.

Personal Projects

Lepl parser for Python.

Colorless Green.

Photography around Santiago.

SVG experiment.

Professional Portfolio

Calibration of seismometers.

Data access via web services.

Cache rewrite.

Extending OpenSSH.

C-ORM: docs, API.

Last 100 entries

[Link] Neat Python Exceptions; [Link] Fix for Windows 10 to Avoid Ads; [Link] Attacks on ZRTP; [Link] UK Jazz Invasion; [Review] Cuba; [Link] Aricle on Gender Reversal of US Presidential Debate; {OpenSuse] Fix for Network Offline in Updater Applet; [Link] Parkinson's Related to Gut Flora; Farellones Bike Park; [Meta] Tags; Update: Second Ride; Schwalbe Thunder Burt 2.1 v Continental X-King 2.4; Mountain Biking in Santiago; Books on Ethics; Security Fail from Command Driven Interface; Everything Old is New Again; Interesting Take on Trump's Lies; Chutney v6; References on Entropy; Amusing "Alexa.." broadcast; The Shame of Chile's Education System; Playing mp4 gifs in Firefox on Opensuses Leap 42.2; Concurrency at Microsoft; Globalisation: Uk -> Chile; OpenSuse 42.2 and Synaptics Touch-Pads; Even; Cherry Jam; Lebanese Writer Amin Maalouf; C++ - it's the language of the future; Learning From Trump; Chinese Writer Hu Fayun; And; Apricot Jam; Also; Excellent Article on USA Politics; Oh Metafilter; Prejudice Against The Rurals; Also, Zizek; Trump; Why Trump Won; Doxygen + Latex on CentOS 6; SMASH - Solve 5 Biggest Problems in Physics; Good article on racism, brexit, and social divides; Grandaddy are back!; Consciousness From Max Entropy; Democrats; Harvard Will Fix Black Poverty; Modelling Bicycle Wheels; Amusing Polling Outlier; If Labour keeps telling working class people...; Populism and Choice; Books on Defeat; Enrique Ferrari - Argentine Author; Transcript of German Scientists on Learning of Hiroshima; Calvert Journal; Owen Jones on Twitter; Possible Japanese Authors; Complex American Literature; Chutney v5; Weird Componentized Virus; Interesting Argentinian Author - Antonio Di Benedetto; Useful Thread on MetaPhysics; RAND on fighting online anarchy (2001); NSA Hacked; Very Good LRB Article on Brexit; Nussbaum on Anger; Tasting; Apple + Kiwi Jam; Hit Me; Sudoku - CSP + Chaos; Recycling Electronics In Santiago; Vector Displays in OpenGL; And Anti-Aliased; OpenGL - Render via Intermediate Texture; And Garmin Connect; Using Garmin Forerunner 230 With Linux; (Beating Dead Horse) StackOverflow; Current State of Justice in China; Axiom of Determinacy; Ewww; Fee Chaos Book; Course on Differential Geometry; Okay, but...; Sparse Matrices, Deep Learning; Sounds Bad; Applebaum Rape; Tomato Chutney v4; Have to add...; Culturally Liberal and Nothing More; Weird Finite / Infinite Result; Your diamond is a beaten up mess; Maths Books; Good Bike Route from Providencia / Las Condes to Panul; Iain Pears (Author of Complex Plots); Plum Jam; Excellent; More Recently; For a moment I forgot StackOverflow sucked; A Few Weeks On...; Chilean Book Recommendations; How To Write Shared Libraries

© 2006-2017 Andrew Cooke (site) / post authors (content).

Erlang's Syntax

From: "andrew cooke" <andrew@...>

Date: Fri, 11 May 2007 09:58:46 -0400 (CLT)

Recently there has been discussion on the Erlang mailing list about "monads".

Monads were popularised by Haskell - they are defined by type constructor
(something that "makes" monads) and two operations: unit and a binding
operation.  And they are used to impose a sequence on a set of operations.
 This is necessary because Haskell is lazy - the order in which functions
are evaluated is not the order in which they are defined in the program -
and so some kind of ordering is needed when doing things that involve
mutable state (for example, asking the user to enter data should come
before reading input!).

OK, but what has this got to do with Erlang?  Very little - Erlang is an
eager language and evaluates functions in a nice, easy-to-understand way. 
So there is no need for ordering.

Monads provide more than ordering - it it turns out that the "monad API"
is quite fundamental, and can be applied to many different scenarios.  So
it provides a unifying concept across lists, optional values, exceptions,

But, again, the Erlang discussions have nothing to do with this.

In fact, the Erlang discussions are not about the semantics of monads at
all.  The posters are purely concerned with the "syntactic sugar" that
Haskell added to support monads.  This lets you write code in an
"imperative style" - it gives the appearance of mutable values.

So what is really happening?

Partly this is a social phenomenon - it's a lot more acceptable to say "we
need monads" (which are a "cool" concept) than to admit that you want to
program using a style unsuited to the paradigm supported by the language.

But that's not the whole explanation.  This is clear from Haskell, where
the monad syntax is not used for "most" code.  Examples of elegant code,
which are abundant for Haskell, use Haskell's succinct and powerful
"fucntional" syntax.  It, in fact, a "newbie error" to write a program
entirely using the monad-specific "do syntax".

So it's clear it's possible write clear, elegant programs in a functional
style (even when the monad syntax is available).  Why don't people want to
do this in Erlang?

Part of the answer to that question is, again, social.  Erlang is growing
rapidly from a small user base.  So there is a lot of pressure from
incoming programmers, accustomed to procedural programming, who want what
they are accustomed to having.

But part of the answer is also found in Erlang's poor support for common
functional programming idioms.

Take the following line of code, which I wrote earlier today, as an example:

  NonBlankLines =
    filter(compose_1(fun util:not_/1, fun util:is_blank/1), Lines).

This filters a list of lines, discarding those which are not blank.  It
could just have well have been written as:

  NonBlankLines = filter(not is_blank, Lines).

In other words - Erlang *punishes* you when you write code in a functional
style.  It requires you to add a whole pile of pointless noise.  For
example, in the code above:

- compose_1 is necessary because Erlang does not have a syntax for
composing functions.  All I want to do is join two functions together, so
the first processes the output from the second.  This is a basic building
block in functional programming and could be supported by simply writing
the two fucntion names together ("not is_blank", as in the second

- not_ is a utility function necessary because there is no way (that i
could fine) to refer to the inbuilt function "not" directly.  So "not_" is
defined as "not" just because inbuilt functions are, in some odd sense,

- namespace:name is necessary because even though i have imported these
functions the namespace is *still* necessary when referring to a function
directly.  There's no ambiguity - I could have used "is_blank" alone
(without "util:") if I just wanted to call the function.  This strange
restriction is only necessary when referring to the function's name.

- fun is necessary to flag functions.  Again, this is pointless - when I
call a function I don't need to specify what it is.  Erlang code
religiously follows a naming convention that separates functions and
variables (by case of the first letter) so this doesn't even require any
type analysis.

It's crazy.  The parser is brain-dead lazy.  No wonder people don't "get"
it and keep trying to turn Erlang into C or Java.


Two More Problems with Erlang

From: "andrew cooke" <andrew@...>

Date: Fri, 11 May 2007 19:54:11 -0400 (CLT)

Something that doesn't appear in the example above, but is a very common
problem - no support for currying.  This is harder to fix because Erlang
treats functions with the same name but different arities as distinct. 
Also, all parentheses types are already used, so it's hard to add a new
syntax.  However, function application currently alwys looks like
foo(...), so you could use either [...] or {...} and then resolve
ambiguities (with lists and tuples) by context.  Since currying is more
like lists that tuples, I would suggest that foo[1] could be used and
- be an error if more than one arity was defined for a function
- would curry the function by the first argument otherwise.

An alternative would be to use simple juxtaposition, which I was using for
function composition.  Then you'd need a separate operator for composition
- perhaps @ which I don't think is used otherwise.

The second problem is that modules can only define functions.  It is an
error to assign to a variable at the top level of a module.  This has two
consequences - first, it is difficult to export constant values (I tend to
use 0 arity functions for this) and second it is difficult (impossible?)
to define a set of functions with a circular dependency, since there is no
way to "break the loop".  It seems that you have to resort to managing
your own namespace (eg a function that returns a map of functions,
possible because it is created inside a function's scope where bindings to
variables are allowed).

I may be wrong on the second of these - you may need mutability (or
laziness).  I've just come across this problem.  Need to think some more. 
The problem may be that you need higher order functions and these cannot
be "unpacked" into a module's API without more flexibilty at the top level
of modules.


Re: Erlang functional syntax

From: "andrew cooke" <andrew@...>

Date: Sat, 12 May 2007 14:48:06 -0400 (CLT)

---------------------------- Original Message ----------------------------
Subject: Re: Erlang functional syntax
From:    "Mike McNally" <m5@...>
Date:    Sat, May 12, 2007 11:06 am
To:      compute-ErlangsSyn0@...

I don't disagree completely, but your first example ignores Erlang list

  NonBlankLines = [L || L <- Lines, not is_blank(L)]

That doesn't seem so bad to me.

Mike McNally

You're right + Possible Currying Syntax

From: "andrew cooke" <andrew@...>

Date: Sat, 12 May 2007 15:00:57 -0400 (CLT)

You're right - I keep completely under-using list comprehensions.

However, as far as I know (maybe I simply haven't used them enough)
they're of fairly restricted use - they certainly don't help with

Incidentally, I think I have a good syntax for currying which would be
backwards compatible with current code.  It involves explicitly specifying
the arity of the function.  In cases where there's no amibuity you can
also use "*".

So, for example,

add(A, B) -> A + B,
Incrementer = add/2(1).

If the function is a variable then it is uniquely specified:

MyAdder = fun add/2.
Incrementer2 = Myadder/*(1).

And the annoying "fun" can be dropped completely, since the trailing
/arity is sufficient to identify functions.  So to increment an array
(maybe I whould be using list comprehensions...)

lists:map(add/2(1), [1,2,3]).

Which is compact, elegant, doesn't break existing code (in particular, I
think common error sin existing code would continue to be errors rather
than silently accepted with a new semantics) and generally "fits in" with
Erlang's style.


Partial Evaluation

From: "andrew cooke" <andrew@...>

Date: Thu, 17 May 2007 06:29:40 -0400 (CLT) - has another
solution to this problem, which I also like:

 foo(_, 1, 2),    % fun (A) -> foo(A, 1, 2) end,
 foo(_, 1, _),    % fun (A, B) -> foo(A, 1, B) end,

Then the example might be

 lists:map(add(1, _), [1,2,3]).

(not so keen on the poster's attitude and weird anti-Haskell stance, but

They also mention "parse_transform" - it seems Erlang supports some kind
of tree re-writing in the parser, which is pretty cool.  For more info see


Composition via Partial Application

From: "andrew cooke" <andrew@...>

Date: Thu, 17 May 2007 08:04:08 -0400 (CLT)

It seems like partial application either supports, or could be made to
support, composition too:

  NonBlankLines =
    filter(compose_1(fun util:not_/1, fun util:is_blank/1), Lines).

could become

  NonBlankLines = filter(not_(is_blank(_)), Lines).

(There's an unfortunate blurring of underlines there, but I wanted to keep
the same function names as earlier)


Comment on this post