5 ms·
Show HN: L2: An elegant untyped, unsafe, unhygienic programming language
- murisitarusenga 9y agoL2 is an experimental programming language that maps efficiently to machine code (like C). I think it is interesting because I have not seen 1) control flow primitives that are like Scheme's continuations but that are also efficient 2) L2's variant of s-expressions that do not need a symbol or string data type 3) a macro system that is equivalent to but operates differently from Common Lisp's
- notjack 9y agoIt's hard to tell from a cursory overview, but I'm pretty sure L2's macro system is roughly equivalent to "fexpr" based macro systems used by some other lisps and schemes.
- murisitarusenga 9y agoI'm not sure if this is correct. Googling fexprs takes me to this Lambda the Ultimate post: http://lambda-the-ultimate.org/node/3640#comment-51665 http://lambda-the-ultimate.org/node/3640#comment-51665. There it says that fexprs map from s-expressions (of the operands to fexpr) to a value (which replaces the fexpr call). L2's macro system does not do this. L2 maps from s-expressions (of the operands to the macro) to s-expressions (that are supposed to replace the macro call).
- fao_ 9y agoAs far as I know, scheme's continuations are efficient. That's kind of the basis of RABBIT, Orbit, and a chunk of Appel's work, isn't it? (See also: http://lambda-the-ultimate.org/node/2406#comment-36369 http://lambda-the-ultimate.org/node/2406#comment-36369)
- shakna 9y agoAs far as I can tell, L2's continuations look very similar to the Cheney on the M.T.A. [0] approach to continuations. [0] http://home.pipeline.com/~hbaker1/CheneyMTA.html http://home.pipeline.com/~hbaker1/CheneyMTA.html
- murisitarusenga 9y agoThanks for the link. I am not sure if I see the similarity. L2 neither uses the heap nor garbage collection nor are its programs converted into continuation-passing-style. Am I missing something?
- gsg 9y agoThose compilers use CPS as an intermediate language - a bit like SSA form for functional languages - which is (mostly) independent of supporting first class continuations. Support for first class continuations is a matter of tradeoffs. It's quite reasonable for an implementation to choose 'slow' continuations (in which call/cc copies the stack) in order to be able to use the more efficient native stack for function calls. (EDIT: and in response to the linked post, it is quite possible to efficiently compile what would be contifiable functions in direct style - see the recent paper Compiling Without Continuations in which the GHC hackers do exactly that.)
- murisitarusenga 9y agoI will try to read into the details of Scheme's implementation of continuations... The reason I made the claim about efficiency is because Scheme's continuations have an unlimited lifetime. This is in contrast to L2's continuations that can only have a dynamic lifetime. (The rules for manipulating continuations in L2 are analogous (and only analogous) to the rules for returning the addresses of local variables in C.) So I just assumed that Scheme implementations must occur an overhead for the greater generality of their continuations.
- bitwize 9y agoDifferent Scheme implementations, presumably, have different implementations of continuations. An implementation of call/cc can be efficient provided you are willing to sacrifice the notion of a single execution stack and embrace constructs like spaghetti stacks that allow for indefinite lifetime of an execution context.
- nickpsecurity 9y agoVery interesting. Especially combining a language primitive, English description, and assembly. I proposed that with a minimal Lisp for bootstrapping recently. The one I was looking at you might find interesting as you experiment with this stuff: https://en.m.wikipedia.org/wiki/PreScheme https://en.m.wikipedia.org/wiki/PreScheme Both the PreScheme and VLISP papers have stuff about it.
- murisitarusenga 9y agoThank you. I personally struggled to understand Scheme continuations from their English descriptions, so I made a point of including concrete implementation details in my write-up. Thank you for the link to PreScheme. It seems to have exactly the same goals that I was aiming for. I will look into it.
- pavlov 9y agoIs there a runtime at all? It seems to me there isn't. Would it be unfair to say this is a Lispy evolution of the oldschool macro assembler?
- murisitarusenga 9y agoI'm not sure of the exact definition of a runtime... The best I can say is that the instructions emitted by the compiler correspond directly to the commands in the source file. You are certainly correct about the Lispyness. I've not yet had the opportunity to use a macro assembler, so I cannot say how similar L2 is to it. To aid your comparison, I think L2 is also quite similar to B language.
- pmarreck 9y agoSo... Forth, basically. ;)
- bhaavan 9y agoFifth!
- murisitarusenga 9y agoThough you jest, Forth did influence certain decisions in L2's design. In particular, by using continuations you can make an L2 function temporarily leave a variable amount of data at the top of the stack in order for the caller or some other function to use.
- andrewflnr 9y agoThis is why I read HN.
- _qc3o 9y agoI get all the other adjectives but where is the elegance?
- moron4hire 9y agoJesus Christ, dude. Try to live a little.
- dTal 9y ago(function frst (l) [fst [rst [' l]]]) (function frfst (l) [fst [rst [fst [' l]]]]) (function frrst (l) [fst [rst [rst [' l]]]]) (function frrrst (l) [fst [rst [rst [rst [' l]]]]]) (function rfst (l) [rst [fst [' l]]]) (function ffst (l) [fst [fst [' l]]]) (function llst (a b c) [lst [' a] [lst [' b] [' c]]]) (function lllst (a b c d) [lst [' a] [lst [' b] [lst [' c] [' d]]]]) (function llllst (a b c d e) [lst [' a] [lst [' b] [lst [' c] [lst [' d] [' e]]]]]) (function llllllst (a b c d e f g) [lst [' a] [lst [' b] [lst [' c] [lst [' d] [lst [' e] [lst [' f] [' g]]]]]]]) Don't you see? Elegant!
- dkarapetyan 9y agoIndeed.
- metaobject 9y agoIs there an abbreviation for "function"?