Well, I'm not sure I really want to get involved here, but the topic was interesting, at least ostensively.
I have been designing a simple interpreted language called
aliae (
A List
Is
An
Evaluation). It is something of a cross between
Tcl and
Scheme. There are still some issues to figure out with the REPL, scoping, and some syntaxis (particularly with quoting), but it looks something like this:
1 2 3 4 5 6 7 8 9 10 11 12 13
|
function n! n # Compute the factorial of n
{
if (n <= 1)
then { return 1 }
else { return (n * (n! (n - 1))) }
}
variable x
print "Calculate the factorial of a number\n",
"Please enter a number\n",
"> "
input x
print "f( ", x, " ) = ", (n! x), "\n"
|
The basic structure in the language is a
list. The basic premise of the language is that a list is an expression to be
evaluated. That is, as in Tcl and Scheme, a list is both code and data. Hence,
a list is an evaluation.
The elements of a list are separated by whitespace, and elements may themselves be lists (that is, lists are technically
s-expressions). Unlike in Scheme, all lists are proper lists. Sublists are delimited by parentheses (either '(' and ')' or '{' and '}', which are equivalent but not interchangeably pairable).
A list is sequentially evaluated, using a lazy, accumulating reduce and transform process. The language allows nice functional constructs: lambdas, currying, proper tail-recursion, and closures in a convenient, almost automatic way. For example, the recursion on line 5 of the example above is recognized as tail-recursive, and handled as such for you. The way the REPL works also makes creating new control constructs surprisingly painless and easy. (Imagine writing your own
if control structure!)
A special type of function (or named lambda) is an
operator, which is a binary function that can be used in infix notation. There is no concept of precedence, so parentheses (or sublists) must be properly applied (as you can see on line 5 of the example above).
A special operator is the
lambda operator, which is expressed as the comma (see lines 9-11 and 13). It is an n-ary operator that applies the next N elements of the list to the
previous lambda (instead of the previous
result, as binary operators do). The 'print' function is a unary function, so the lambda operator is useful to print more than one thing at once.
Commentary is signalled with a leading hash. It may be whitespace delimited (see line 1) or parenthetically delimited:
print "Hello ", #( a comment )# "world!" #(don't forget the newline)# ,"\n" #tada!
Identifiers may be composed of any sequence of characters excluding the following
( ) sublist delimiters
{ } sublist delimiters
" ' quotes
[ ] list splice
. scope resolution
, lambda operator
# comment
: reserved
; reserved
\ character escape
Also, built-in identifiers (like
if and
lambda) may not be redefined, as they can in Tcl and Scheme.
It was designed to be easy to implement in a small amount of code, and usable in either an embedded context or as a stand-alone program. I was considering using it as part of a series of articles here... Alas for time. (And energy.)
Well, that's it for the moment...