I've evolved my own dynamic language over the years (i.e.
scripting language) with a bunch of nice features:
conditional execution with stack growth related to nesting
depth, not number of iterations; auto-vectorizing (or
auto-streaming) operators reminiscent of APL; a syntax that
is half C expressions, half Lisp-like parameters (fixed
position parameters, both required and optional, and
free-format keyword parameters with defaults and overrides).
I would never posit it as a general purpose language for
widespread use. Mechanisms for objects and parameterized
functions are yet-to-be developed. I've had long-standing
plans for these (I started the design in 83, the
implementation in 89, the Unix port in 94), but I guess I'm
a regular tortoise of a programmer :-).
Instead I've packaged it as the command
interpreter
extension to a vector-graphic drawing editor, where I'm
focusing on two things: primitives for manipulating vector
and raster data in the context of a drawing editor, and
language mechanisms that make that fun.
As for performance, I'm sure I take the normal 10x hit for a
scripting language. I'm proud of the efficiency of the
control constructs (for, while, if, each), but any reference
to a variable through the symbol table requires a hash
operation, and those add up, especially when you rely on
them for language internals (any kind of dynamic binding
costs at least a 3x hit relative to compiled alternatives).
And, can you believe it, the thing is not flawlessly
conceived without kludge or special-case requirements.
Don't get me wrong, it's no Perl or TCL. For the most part
it is incredibly simple and self-consistent. But there came
a day (a
year) a while back when I knew I had no hope of perfecting
the design without building the language, even if there was
little hope in it being perfect if evolved over time.
Why am I writing all this today? Two reasons: obviously
raph
has made it the topic of the day
(hmmm, could that be a new advogato feature?). And I just
forced myself to make the first real significant kludge to
the language that required an opaque change to the run-time
environment (one that can't be explained in simple
language-wide terms). And I wanted to tell you about it
:-). Sometimes it is the blemishes that make things
beautiful. Or maybe that is just my anti-monopolistic
polytheistic Scottish world-view talking.
Ya see, "," is the tuple operator (the list concatenator).
"1,2,3" yields a list "(1,2,3)". You can assign that to a
variable, i.e. "l=1,2,3". Then further values can be
concatenated with just the tuple operator, i.e. "l,4" would
alter the "l" list to be "(1,2,3,4)".
All fine and quirky, but the problem came up that
"(1,2),(3,4)" yields "(1,2,(3,4))", a somewhat
counter-intuitive result. A completely consistent result as
far as the language goes, but confusing. So I sweated it
out a (long) while, and finally made special-case use of the
parentheses to the left of the tuple operator, to yield the
expected "((1,2),(3,4))". This has the added benefit that
now the printed result of evaluating "(1,2),(3,4)" can in
turn be evaluated to yield the same result.
I'm so happy. I promise no more of those for a long while.
Have a good
day.