Vincent Zoonekynd's Blog

Sun, 14 Dec 2008: Programming languages

Programmers should learn a new programming language every year -- not necessary to ditch the one(s) they are currently using, but we might glean new ideas, new programming paradigms and a more informed, objective, critical view of the programming landscape and its latest fads. In the past few months, I "learned" three of them (it might sound a lot, but because of lack of time, my survey remained very superficial): Oz, Erlang and Chuck.

Oz

Many, may years ago, I tried to program in Prolog: it was an unpleasant experience. The premise of logic programming looked appealing: just tell the computer what you want (a list of statements, rules of derivation and a few questions to answer) and let it figure out how to get to the result (it "just" had to explore the tree of all potential proofs built from the data we gave it). Sadly, Prolog did not live up to my expectations: it could try to explore, depth first, a potentially infinite tree and, even worse, could not efficiently be used without some procedural tricks (such as the "cut" operator"), which made the language non-declarative: for instance, the order in which you write apparently declarative statements could influence the result...

Oz is a multiparadigm language: it provides functional programming, single assignment variables (as Haskell), message-passing concurrent programming (as Erlang -- see below), stateful objects (as Java) and logic programming. It does not seem to be a language for real-world applications but rather a language designed to teach/learn programming languages paradigms and design.

Concepts, techniques and models of computer programming
P. Van Roy and S. Haridi (2003)
http://www.librecours.org/documents/5/521.pdf

Its logic programming capabilities, however, are much, much cleaner than Prolog's -- and more powerful as well: in particular, you can fine-tune how the tree will be built and explored (depth-first, breadth first, which branches should be explored first, etc.); you can also use it for optimization problems.

% The following code solves a graph colouring problem
% The capital letters are the countries,
% the colours are coded as 1, 2, 3.
% For more examples:
%   http://www.mozart-oz.org/documentation/fdp/index.html
%   http://www.mozart-oz.org/home/doc/tutorial
declare
proc {Colouring Root}
  P E F L B N G S A I
in
  Root = solution(p:P e:E f:F l:L b:B n:N g:G s:S a:A i:I)
  Root ::: 1#3
  P \=: E
  E \=: F
  B \=: F
  L \=: F
  G \=: F
  S \=: F
  N \=: G
  L \=: G
  S \=: G
  A \=: G
  B \=: L
  A \=: I
  S \=: I
  F =: 1
  G =: 2
  S =: 3
  {FD.distribute ff Root}
end
{ExploreAll Colouring}
{Browse {SearchAll Colouring}}

You might be perplexed by the weird equal signs -- Oz really has a lot of them: = (binding), := asignment, == (test), =: (constraint propagation); \=: is an inequality constraint propagation.

Logic programming, in Oz, is based on the notion of constraint space: the set of solutions is represented as a box, i.e., a cartesian product of intervals of integers, with constraints. You could be tempted to use the constraints to actually "cut" the box, to have a description of the set of solutions, but it would no longer be a box and would be tricky to handle. Instead, the box can be cut in two, along a coordinate axis, yielding two boxes, with the same constraints; if the cut was wisely chosen, some of the constraints either disappear or can be used to reduce the box sizes (but they must remain rectangular, axis-aligned boxes). By iterating this process, we get a tree of boxes, that we have to explore -- in many branches, if the cuts are wisely chosen, the constraints are not compatible with the cut boxes, so that the reduced boxes are empty, thereby proving that the branch contains no solution and can be discarded.

http://cmr.soc.plymouth.ac.uk/tanders/teaching/TorstenAnders-AINT503-e1.pdf
http://cmr.soc.plymouth.ac.uk/tanders/teaching/TorstenAnders-AINT503-e2.pdf
http://cmr.soc.plymouth.ac.uk/tanders/teaching/TorstenAnders-AINT503-e3.pdf
http://cmr.soc.plymouth.ac.uk/tanders/teaching/TorstenAnders-AINT503-e4.pdf

Strasheela is a musical application of the constraint satisfaction capabilities of Oz:

http://strasheela.sourceforge.net/strasheela/doc/index.html

All is not perfect, though: Oz/Mozart is not portable and does not run on 64-bit machines...

Erlang

Erlang has been touted as the archetypal message-passing concurrent programming language for several years now.

http://lambda-the-ultimate.org/node/2000

It is even mentionned (together with Haskell) in the latest Game Programming Gems -- but only in the introduction, not in the articles.

http://www.amazon.com/Game-Programming-Gems/dp/1584505273/

The recipe is simple: since concurrency-related bugs and non-linear scaling come from shared states and locks, we can just remove shared states (Erlang even removes states, i.e., mutable variables, that is cleaner but not absolutely necessary) and use message-passing instead. Threads become (light, Unix-like) processes (threads are spawned as would background proccesses in shell), that do not share anything and communicate through pipes.

Nothing ground-breaking, but that very simplicity is the reason why it works.

Not all is perfect, though: since Erlang was designed for separate, distant processors, efficiently harnessing the power of today's multicore processors requires a special (SMP) Erlang executable, that only exists for a small number of processors (I am not sure I have seen 64-bit processors in the list) and a limited number of cores (two).

http://www.amazon.com/Programming-Erlang-Software-Concurrent-World/dp/193435600X/

Chuck

I have not received a decent musical education (only the 4-year compulsory French one: I can read a score provided there are no flats or sharps, the only notes are F, G, A, B and C in the middle of the stave, the most complicated rythm is a dotted eigth note followed by a sixteenth note (in this order) and there is at most one note at a time; I am not supposed to have ever heard of scales, modes or chords; and of course there is no ear training at all), but once in a while, I try to see if my programming or mathematical skills can help me teach the computer to produce pleasant sounds. It has always been a complete failure.

The computer music landscape, from a programmer's point of view (actual musicians will disagree), is not very satisfactory, not to say, extremely bleak.

(I do not mention purely graphical applications, many of which are mature.)

CSound

CSound is a fortran-like language (I even hesitate to say machine-language-like) that allows you to create sound by connecting units that generate or modify sound signals (or more slowly-moving "control" signals) and has been around for 10 or 20 years. Given its antiquity, you might expect it to be rock-solid (say, like (La)TeX) -- on the contrary, it seems to crash rather often. It also provides the most appalling example of the XML epidemic that broke out a few years ago: to look more "modern" they added a few pointy brackets whose sole role is to separate the (already distinct) two parts of a CSound program, initialization and actual "code" (this is comparable to isolating the "#include" lines in a C program: you can easily recognise them without any markup -- they start with "#include").

http://www.csounds.com/

Pure Data

Graphical programming languages such as Pure Data use the same idea (connecting units that generate or modify sound signals) but are designed for non-programmers: for that audience, they are indeed very powerful, but programmers do feel limited. It is a step away from CSound, in the good direction, which is already very good.

http://en.wikipedia.org/wiki/Pure_Data

Lisp

For some unexplicable reason, the Lisp programming language is still widely used: while the functional programming paradigm it encourages is a good idea, the countless parentheses the outdated Lisp syntax requires are not needed and more programmer-friendly functional languages have emerged in the past decade or two (Haskell is one such example).

Notes From the Metalevel
H. Taube (Routeledge, 2004)
http://www.amazon.com/Notes-Metalevel-Introduction-Computer-Composition/dp/9026519753

Miscellanies

There is also a myriad of unsupported/unportable applications that are probably helpful to handfuls of people, such as SuperCollider, often touted as a "better CSound" -- but the syntax is still awful (not as bad, but that would have been very hard) and it was explicitely designed to be non-portable (32-bit-only).

Chuck

Chuck is a (still immature) music programming language, which can be seen as a flow programming language or as a textual analogue of graphical environments such as Pure Data -- Chuck also has graphical interfaces, whose screenshots look much more impressive and futuristic than Pure Data, but I have never used them.

http://chuck.cs.princeton.edu/
http://audicle.cs.princeton.edu/

The language is rather simple: you program in "frozen time" (i.e., between two samples) with several threads if you want, with a funny, heavily overloaded operator => used for assignment, to link instruments and filters, to advance time, etc. (in particular, Chuck also gets rids of the antiquated separation between control rate and sample rate inherited from CSound).

I feel I should include some sample code here, but what I wrote produces awful sounds: rather check their Wiki.

http://wiki.cs.princeton.edu/

posted at: 07:23 | path: /Linux | permanent link to this entry