I was reading Ola Bini’s post about operators in Ioke (Ioke being the new language that Ola is developing).
It is a common saying around LISPers that everything that is being done in “modern” languages is a return to LISP. And the argument holds some ground. The truth is, among the 4 most conceptually influential programming languages that I can think of (Lisp/Functional, Fortran/Imperative, Smalltalk/OO, Prolog/Logic), the bad option (Fortran) won as it is the major philosophical contributor to current programming languages (much more than Smalltalk).
Take the reinvention of operators on Ioke as per the post above. This concept is available in Prolog for decades. It is all there: precedence (i.e. 2*3+4 means (2*3)+4 and not 2*(3+4)). Associativity (left or right – ie. 3-2-1 is 0 (3-2)-1 and not 2 3-(2-1) ). And even more as new operators can be defined and can be made of alphanumeric characters (want to create a new operator called say, “in”? go ahead). In fact people were doing DSLs a long time ago (in the small Prolog community at least) using techniques such as these.
The next thing that you will need (and we are getting there with macros and AST access) is no default interpretation. This is especially important with arithmetic, let me give an example:
Imagine the expression 1+x. Most languages will evaluate this expression and will return the sum of 1 + x. If x is defined and say is 4, then 1+x is 5. If x is not defined then an error (compile or run)-time will be raised. This is an absolute disgrace for DSLs with are essentially declarative (i.e., detached from semantics). “1+x” might be something that you want to evaluate now (and get the result) or might be something that you want to specify in order to evaluate later (say, I want to do a chart of all values of x between 1 and 5, or I want to differentiate), look at this pseudo-code
1 2 3 4 5 6 7 | Var x Exp expression = 1 + x**2 chart(expression, [[x,[1, 5]]]) //do a chart, x between 1 and 5 evaluate(expression, [[x,3]]) //Evaluate expression where x is 3 (i.e. 10) diffe = differentiate(expression, x) //returns the expression 2*x prettyprint(expression) //Pretty prints the expression. |
Most people automatically associate the operation evaluate to 1+x**2. That might be so in an imperative world (can I call it shitty world?). But in an declarative/DSL world 1+x**2 is just that, an expression, it has no meaning attached per se. What you do with it depends on the context. Pretty print it, differentiate it, integrate it, or even evaluate it by instantiating x to 3 and getting the “precious” 10.
Update: I was rereading the post and noticed that it might be read as seeing Ola’s work as less interesting. Not at all: I actually think the way forward is precisely improving the current “imperative” setting in the way Ola is doing.
Sam Aaron says:
Haha, nice point, I agree completely. I have never thought of comparing Ioke with Prolog, but this does make complete sense from a declarative DSL perspective.
I do hope lispy languages like Ioke get more mindshare. There is a treasure chest of wonderfully valuable and useful concepts waiting to be discovered…
January 9, 2009, 14:24mat says:
Very good post; for declarative arithmetic, check out constraint logic programming in Prolog. For example, in SWI Prolog, there are the clpq, clpr and clpfd libraries, which give you arithmetic in all directions (as opposed to the one-way evaluation of other languages).
January 9, 2009, 17:08Kaveh Shahbazian says:
Very nice! I like io very much and it seems ioke is going to be a more pragmatic io.
You should take a look at http://code.google.com/p/pure-lang/. Pure is a modern-style functional programming language based on term rewriting. It seems interasting.
January 9, 2009, 22:45