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

C[omp]ute

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.

Last 100 entries

Chat Wars; Real-life Financial Co Without ACID Database...; Flexible Muscle-Based Locomotion for Bipedal Creatures; SQL Performance Explained; The Little Manual of API Design; Multiple Word Sizes; CRC - Next Steps; FizzBuzz; Update on CRCs; Decent Links / Discussion Community; Automated Reasoning About LLVM Optimizations and Undefined Behavior; A Painless Guide To CRC Error Detection Algorithms; Tests in Julia; Dave Eggers: what's so funny about peace, love and Starship?; Cello - High Level C Programming; autoreconf needs tar; Will Self Goes To Heathrow; Top 5 BioInformatics Papers; Vasovagal Response; Good Food in Vina; Chilean Drug Criminals Use Subsitution Cipher; Adrenaline; Stiglitz on the Impact of Technology; Why Not; How I Am 5; Lenovo X240 OpenSuse 13.1; NSA and GCHQ - Psychological Trolls; Finite Fields in Julia (Defining Your Own Number Type); Julian Assange; Starting Qemu on OpenSuse; Noisy GAs/TMs; Venezuela; Reinstalling GRUB with EFI; Instructions For Disabling KDE Indexing; Evolving Speakers; Changing Salt Size in Simple Crypt 3.0.0; Logarithmic Map (Moved); More Info; Words Found in Voynich Manuscript; An Inventory Of 3D Space-Filling Curves; Foxes Using Magnetic Fields To Hunt; 5 Rounds RC5 No Rotation; JP Morgan and Madoff; Ori - Secure, Distributed File System; Physical Unclonable Functions (PUFs); Prejudice on Reddit; Recursion OK; Optimizing Julia Code; Cash Handouts in Brazil; Couple Nice Music Videos; It Also Works!; Adaptive Plaintext; It Works!; RC5 Without Rotation (2); 8 Years...; Attack Against Encrypted Linux Disks; Pushing Back On NSA At IETF; Summary of Experimental Ethics; Very Good Talk On Security, Snowden; Locusts are Grasshoppers!; Vagrant (OpenSuse and IDEs); Interesting Take On Mandela's Context; Haskell Cabal O(n^2) / O(n) Fix; How I Am 4; Chilean Charity Supporting Women; Doing SSH right; Festival of Urban Intervention; Neat Idea - Wormholes Provide Entanglement; And a Link....; Simple Encryption for Python 2.7; OpenSuse 13.1 Is Better!; Little Gain...; More Details on Technofull Damage; Palmrest Cracked Too....; Tecnofull (Lenovo Support) Is Fucking Useless; The Neuroscientist Who Discovered He Was a Psychopath; Interpolating Polynomials; Bottlehead Crack as Pre-amp; Ooops K702!; Bottlehead Crack, AKG K701; Breaking RC5 Without Rotation; Great post thank you; Big Balls of Mud; Phabricator - Tools for working together; Amazing Julia RC5 Code Parameterized By Word Size; Chi-Square Can Be Two-Sided; Why Do Brits Accept Surveillance?; Statistics Done Wrong; Mesas Trape from Bravo; European Report on Crypto Primitives and Protocols; Interesting Omissions; Oryx And Crake (Margaret Atwood); Music and Theory; My Arduino Programs; Elliptic Curve Crypto; Re: Licensing Interpreted Code; Licensing Interpreted Code; ASUS 1015E-DS03 OpenSuse 12.3 SSD; translating lettuce feature files into stub steps files; Re: translating lettuce feature files into stub steps files; A Tale of Two Psychiatrists

© 2006-2013 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,
etc.

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
version).

- 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,
broken.

- 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.

Andrew

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
would:
- 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.

Andrew

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
comprehensions:

  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
currying.

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.

Andrew

Partial Evaluation

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

Date: Thu, 17 May 2007 06:29:40 -0400 (CLT)

http://programming.reddit.com/info/1pw8o/comments/c1pyd5 - 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
hey...).

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

http://www.erlang.org/doc/doc-5.5.4/lib/stdlib-1.14.4/doc/html/erl_id_trans.html
http://www.erlang.org/doc/doc-5.5.4/lib/stdlib-1.14.4/doc/html/erl_parse.html

Andrew

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)

Andrew

Comment on this post