While we're throwing out wild and whacky ideas, here's one I've been mulling for a few days.
You know how the lisp evaluator reads a list, evals all the elements, passes the cdr as arguments to the car? Forget all that. New rules: a) Adjacent expressions = function application. factorial 5 => 120 ++ 3 => 4 Corollary: The function doesn't have to come first. 5 factorial => 120 3 ++ => 4 b) What if a function needs 2 args? Or 3? Curry. + 1 2 => ((+ 1) 2) => 3 Now we suddenly have infix for free, thanks to above corollary. 1 + 2 => ((1 +) 2) => 3 (Still no precedence though. Sorry, math guys :) 1 + 2 * 3 => ((((1 +) 2) *) 3) c) You don't have to repeatedly curry functions, you can just pass in a list. +(1, 2) => 3 cons(1, 2) => (1 . 2) As a corollary, parentheses are just for grouping. They never mean a function call. (+ 1 2) <=> ((+ 1 2)) And that's it! I think this s-expression language would admit convenient macros. And I'm not sure if you need quote anymore.. === I've thought about a couple of additional frills you could add to this language: A. You could interpret this programming model using an accumulator. > + 1 2 ; + => store + in accumulator ; 1 => combine + and 1, store a curried function in accumulator ; 2 => combine curried function and 2, store 3 in accumulator 3 ; finally print 3 The combination of currying and an accumulator seems to do what a stack does in forth or factor. Instead of functions picking up arguments from a stack, there's a *queue* of arguments trotting into a function's mouth. When the function's done eating all the args it needs it closes its mouth, digests, excretes a result to the accumulator, and vanishes. B. If you have rules for how values of various types coerce to functions you can get array and hash dereference. Just treat all kinds of brackets as groupers. array[2, 3] => (array 2 3) => ((array 2) 3) hash{key} => (hash key) You can also coerce booleans to functions and turn 'if' into a single-arg function. if (x < 3) { print "haha"; 34; } ; => (if (x < 3)) { .. } ; => true { .. } ; => eval-all { print "haha"; 34 } Compare this with smalltalk: (3 < 4) :iftrue [ print "haha"; 34; ] (I suck at smalltalk, so this has a negligible chance of being correct syntax.) One assumption I'm making in this code fragment is that semi-colons are delimiters. Just like all kinds of brackets behave the same, semi-colons and commas are delimiters and behave the same, serving only to separate elements of a list or array. { a; b; c; d } <=> (a, b, c, d) <=> [a, b, c, d] This flexibility allows us to add the illusion of syntax without giving up s-expressions and macros. C. You can make parens optional like in ruby: f a, b, c => f(a, b, c) All of this suggests to me that all talk of lisp 'permitting macros' because it is 'homoiconic' is a canard. You can build parse trees and macros for any syntax. It's just that the people who want such syntax haven't cottoned on to the power of macros. Or they haven't realized the value of optional syntax, or of redundant syntax where multiple tokens mean exactly the same thing. I'm not sure I would use all this syntax, but it might be worth turning this idea into a language, just as a proof of concept. The name for this language is blazingly self-evident: Blub. PS: Either this is broken in some fundamental way, or somebody's already discovered this before. Please educate me. ------------------------------------------------------------------------------ Live Security Virtual Conference Exclusive live event will cover all the ways today's security and threat landscape has changed and how IT managers can respond. Discussions will include endpoint security, mobile security and the latest in malware threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ _______________________________________________ Readable-discuss mailing list Readable-discuss@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/readable-discuss