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.