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

C-ORM: docs, API.

Last 100 entries

Cherry Jam; Lebanese Writer Amin Maalouf; Learning From Trump; Chinese Writer Hu Fayun; C++ - it's the language of the future; 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; Jenny Erpenbeck (Author); Dijkstra, Coins, Tables; Python libraries error on OpenSuse; Deserving Trump; And Smugness; McCloskey Economics Trilogy; cmocka - Mocks for C; Concept Creep (Americans); Futhark - OpenCL Language; Moved / Gone; Fan and USB issues; Burgers in Santiago; The Origin of Icosahedral Symmetry in Viruses; autoenum on PyPI; Jars Explains; Tomato Chutney v3; REST; US Elections and Gender: 24 Point Swing; PPPoE on OpenSuse Leap 42.1; SuperMicro X10SDV-TLN4F/F with Opensuse Leap 42.1; Big Data AI Could Be Very Bad Indeed....; Cornering; Postcapitalism (Paul Mason); Black Science Fiction; Git is not a CDN; Mining of Massive Data Sets

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

Learning Erlang

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

Date: Sun, 15 Apr 2007 12:18:37 -0400 (CLT)

I have been playing around with Erlang this weekend.

While I haven't yet used the threading stuff I have written a parser
combinator library (although Erlang does include some kind of yacc-like
tool).

Some random observations:

- Apart from the message sending and infrastructure, it's a very simple,
pure functional language.  There's no mutable state (no Monads, no mutable
references) except for (i) global process namespace (thanks to Kragen for
pointing this one out) and (ii) an integrated "object" database.

- The hot code replacement stuff makes working in the shell a pain (I
couldn't work out how to force recompiled code to load!), so the best
thing to do is use the emacs mode fully (which includes an embedded shell
and forces reload on recompile).

- Dependencies aren't recompiled automatically.  There is a make-like
tool, but I haven't used it and don't know how well it's integrated with
the emacs edit/compile/run cycle.

- Error messages could be a little less cryptic.  Syntax errors in
particular give you just the line number to work with.

- For a functional language the handling of higher order functions is very
clumsy.  While functions can be invoked on arguments via the usual syntax:
  foo(...)
  module:foo(...)
they cannot be referred to as such:
  lists:map(foo, [...]) % error
  lists:map(module:foo, [...]) % error
instead you need to use a {module, name} tuple;
  lists:map({module, foo}, [...])
And if an expression evaluates to a function it cannot be applied
directly.  Instead, the whole thing must be enclosed in parens:
  hof(...)(...) % error
  (hof(...))(...)

- In general the docs are good.  However I couldn't find anything that
described inline operators (++, --, arithmetic, others?).  Partly because
these are difficult to search for...

- For some reason (strange compatibility with shell stadards) the regexp
(which is much more limited than perl5) will not match " *" against the
empty string(!).

- There are a couple of language extensions that seem a bit "ad-hoc" and
poorly integrated.  One is support for records (named access to tuple
fields).  The other is a kind of ADT (called "behaviours").  Don't have
more specific criticism of these yet as I haven't used them.

Andrew

Datalog Parser in Erlang

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

Date: Sun, 15 Apr 2007 15:18:23 -0400 (CLT)

It's probably not complete (although I'm not sure there is a formal def
for Datalog, it doesn't support extra conditions like equality and
certainly doesn't support negation), but here's an example of the parser
output:

Eshell V5.5.4  (abort with ^G)
1> parse_datalog:rule("forefather(X, Y) :- forefather(X, Z), father(Z, Y)").
{rule,{predicate,{name,"forefather"},[{var,"X"},{var,"Y"}]},
      [{predicate,{name,"father"},[{var,"Z"},{var,"Y"}]},
       {predicate,{name,"forefather"},[{var,"X"},{var,"Z"}]}]}
2> parse_datalog:fact("father(\"Rodney\", \"Andrew\")").
{fact,{name,"father"},[{name,"Rodney"},{name,"Andrew"}]}


And here's the code (just the top level, not the libraries):


-module(parse_datalog).

% testing only(?)
-export([space/0, space/1, list/1, list_tail/1, args/1]).

-export([var/0, var/1, name/0, name/1, fact/1, rule/1]).

-import(parse, [empty/0, label/2, function/2, either/2, cons/2, drop/1,
                star/1, both/3, append/1, all/1, seq/1, result/2, export/3,
                parser_lift/1, eos_/0]).
-import(parse_string, [string/1, regexp/1, quote/2]).


var() -> label(var, regexp("[A-Z][0-9a-zA-Z_]*")).
name() ->
    label(name, either(regexp("[a-z][0-9a-zA-Z_]*"), quote("\\", "\""))).

% erlang lib fails to match empty string with " *"
space() -> drop(either(regexp(" *"), empty())).
space(Parser) -> append([space(), Parser, space()]).

open() -> drop(space(string("("))).
close() -> drop(space(string(")"))).
entail() -> drop(space(string(":-"))).
comma() -> drop(space(string(","))).

list_tail(Parser) -> seq([comma(), Parser]).
list(Parser) -> cons(Parser, star(list_tail(Parser))).

% ouch - list reversal needed here :o(
args(Parser) ->
    (parser_lift({lists, reverse}))
      (append([open(), list(Parser), close()])).

fact() -> both(fact, name(), args(name())).
predicate() -> both(predicate, name(), args(either(name(), var()))).
rule() -> both(rule, predicate(), append([entail(), list(predicate())])).

complete(Parser, Stream) ->
    export(seq([Parser, space(), eos_()]), Stream, fail).

var(Stream) -> export(var(), Stream, fail).
name(Stream) -> export(name(), Stream, fail).

fact(Stream) -> complete(fact(), Stream).
rule(Stream) -> complete(rule(), Stream).

Re: Learning Erlang

From: "Joe Armstrong" <joearms@...>

Date: Mon, 16 Apr 2007 09:43:31 +0200

- The hot code replacement stuff makes working in the shell a pain (I
couldn't work out how to force recompiled code to load!), so the best
thing to do is use the emacs mode fully (which includes an embedded shell
and forces reload on recompile).

> c(foo).
{ok, foo}

foo is loaded and ready to run - you don't have to do anything
(well you might have to if foo was spawned by large number of parallel
process and
made funny tail calls that we can't handle - the point is that this
should just work
even when you have very large systems wih loads of different modules
involved

- Dependencies aren't recompiled automatically.  There is a make-like
tool, but I haven't used it and don't know how well it's integrated with
the emacs edit/compile/run cycle.

Source code dependencies must be handled with something "external"
- I just use make - run-time dependencies are handled automatically.
ie if foo calls bar and you reload bar then all the calls to bar from
foo will be
changed to the new versions without you having to do anything to foo.


- For a functional language the handling of higher order functions is very
clumsy.  While functions can be invoked on arguments via the usual syntax:
  foo(...)
  module:foo(...)
they cannot be referred to as such:
  lists:map(foo, [...]) % error
  lists:map(module:foo, [...]) % error
instead you need to use a {module, name} tuple;
  lists:map({module, foo}, [...])
And if an expression evaluates to a function it cannot be applied
directly.  Instead, the whole thing must be enclosed in parens:
  hof(...)(...) % error
  (hof(...))(...)

   You need a fun keyword :-)


   lists:map(fun foo/2, [...])  %% ok a reference to the local function foo

   lists:map(fun remote:var/4, ...)   %% a remote reference

Records are poorly integrated - we always said we know this sucks but
can anybody come
up with a better syntax - nobody has (well not quite true, there is a
better syntax but
compiling it is tricky)

Behaviours are much more than ASTs - think of them as HOFS working with parallel
processes to provide things like fault-tolerance or scalability

Erlang is not a functional language with "added concurrency" it's the other
way around.

The important thing is that Erlang is a concurrent language where you happen
to do things in a functional language.

It was not designed for  an edit/compile/run cycle.

it was designed for startOnce/evovle ....

ie for never-stop evolving systems ( we have some systems that have
run for six years
and evolved thought dozens of major upgrades)

The "threading stuff" is what it's all about - this what makes Erlang
differ from
most other languages - Because our threading stuff does not mutate state we can
run on a multicore - with no locks and no sharing - so when the 100+ core CPUs
come our very slow and pure code will run much faster than all
these silly things that mutate state and crash each other quickly.

Cheers

/Joe Armstrong

Thanks for comment and apologies for ignoring/formatting

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

Date: Tue, 17 Apr 2007 11:52:43 -0400 (CLT)

Hi,

I just saw that you replied to something I posted on my blog about Erlang.
 Thank-you for taking the time to do so.  I was reading the page because I
was going to add an update myself, having found the "fun" keyword.

Sorry for the poor formatting and apparent attribution to me, not you.  At
some point (maybe this weekend) I will fix the code (just some bash
scripts that put emails into web pages) and regenerate the site.  It's not
a popular site - I think you are my second reply ever - and lacks a
certain polish, I'm afraid.

Also sorry if my comments came across as a criticism of Erlang without
mentioning the importance of concurrency.  The reason I am using the
language is because I want the concurrency and I can't see how to do it
reasonably with any other approach.  However I am just starting out so
thought it better to get a grip on the base language first.

Incidentally, I realise I am guilty of "not using the language as it was
designed to be used", but if I could add one thing it would be, at the
moment, not a nicer syntax for records, but currying.  That and not (even)
needing "fun" for function references... :o)

Cheers,
Andrew

Thanks for comment and apologies for ignoring/formatting

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

Date: Wed, 18 Apr 2007 09:14:33 -0400 (CLT)

Hi,

I just saw that you replied to something I posted on my blog about Erlang.
 Thank-you for taking the time to do so.  I was reading the page because I
was going to add an update myself, having found the "fun" keyword.

Sorry for the poor formatting and apparent attribution to me, not you.  At
some point (maybe this weekend) I will fix the code (just some bash
scripts that put emails into web pages) and regenerate the site.  It's not
a popular site - I think you are my second reply ever - and lacks a
certain polish, I'm afraid.

Also sorry if my comments came across as a criticism of Erlang without
mentioning the importance of concurrency.  The reason I am using the
language is because I want the concurrency and I can't see how to do it
reasonably with any other approach.  However I am just starting out so
thought it better to get a grip on the base language first.

Incidentally, I realise I am guilty of "not using the language as it was
designed to be used", but if I could add one thing it would be, at the
moment, not a nicer syntax for records, but currying.  That and not (even)
needing "fun" for function references... :o)

Cheers,
Andrew

Comment on this post