Path: csiph.com!x330-a1.tempe.blueboxinc.net!newsfeed.hal-mli.net!feeder3.hal-mli.net!newsfeed.hal-mli.net!feeder1.hal-mli.net!border3.nntp.dca.giganews.com!border1.nntp.dca.giganews.com!border4.nntp.dca.giganews.com!border2.nntp.dca.giganews.com!nntp.giganews.com!news.iecc.com!nerds-end From: Kaz Kylheku Newsgroups: comp.compilers Subject: Re: Looking for volunteers for XL Date: Sat, 26 Nov 2011 05:43:16 +0000 (UTC) Organization: A noiseless patient Spider Lines: 113 Sender: news@iecc.com Approved: comp.compilers@iecc.com Message-ID: <11-11-051@comp.compilers> References: <11-11-048@comp.compilers> NNTP-Posting-Host: news.iecc.com X-Trace: leila.iecc.com 1322342288 57156 64.57.183.58 (26 Nov 2011 21:18:08 GMT) X-Complaints-To: abuse@iecc.com NNTP-Posting-Date: Sat, 26 Nov 2011 21:18:08 +0000 (UTC) Keywords: design Posted-Date: 26 Nov 2011 16:18:08 EST X-submission-address: compilers@iecc.com X-moderator-address: compilers-request@iecc.com X-FAQ-and-archives: http://compilers.iecc.com Xref: x330-a1.tempe.blueboxinc.net comp.compilers:353 On 2011-11-23, Christophe de Dinechin wrote: > Hello, > > I'm the designer of the XL programming language (http://xlr.sf.net). > This language is designed to make it as easy to extend the language as > it is today to add classes in traditional languages. Common Lisp and Clojure blow this out of the water, sorry. I will wait until X turns to Y, then to Z, A, B and finally we get to CL. Greenspunning complete! :) XL: user-defined optimizations (example from XL website): translation Simplify when 'X' * 2 then return parse_tree('X'+'X') It looks slick, but it's nothing I can't get with 1980 vintage CL compiler macros: ;; the function (defun mult (left right) (* left right)) ;; the compiler macro to optimize it (define-compiler-macro mult (&whole form left right) (cond ;; if left is a constant expression evaluating to 2 ;; then ((and (constantp left) (eql 2 (eval left))) `(+ ,right ,right)) ((and (constantp right) (eql 2 (eval right))) `(+ ,left ,left)) ;; fallback on the original form (t form))) This has worked for more than 30 years. But the above has a flaw: multiple evaluation. Does the XL transformer deal with it? I mean, parse_tree('X'+'X') looks like it it might calls for two evaluations of X. Are these X's pointers to a common subexpression that is ultimately evaluated once? (DAG structure in the AST?) In that case, what if you sometimes WANT multiple evaluation? How do I take a single X into three copies of X that are independent? Fix for the issue: generate code to evaluate once to a temporary variable, then add the temporary to itself: (define-compiler-macro mult (&whole form left right) (let ((temp (gensym))) (cond ;; if left is a constant expression evaluating to 2 ;; then ((and (constantp left) (eql 2 (eval left))) (let ((temp ,right)) `(+ ,temp ,temp))) ((and (constantp right) (eql 2 (eval right))) (let ((temp ,left)) `(+ ,temp ,temp))) ;; fallback on the original form (t form)))) > [There were a bazillion extensible languages in the 1970s, many quite > sophisticated. They all disappeared without a trace, largely because > the ability to do per-program extensions meant that every program was John, most languages that were ever designed disappeared without a trace, extensible or not, without any common reason for that other than that only a few such things can be popular at one time. Some successful technologies are accidentally so. (Speaking of lines dying out, all human beings came from the same mother. So, what happened to her sister's children and their descendants?) > written in a different language, making them all unreadable. Common Lisp programs are all written in a different macro language, and it all works just fine. People understand each other's programs; different macro packages get loaded into the same image and play along, etc. It's just as easy (or hard) to understand someone's morass of functions, or macros. Data flows can be hard to follow, control flows can be hard to follow, code transformations can be hard to follow. Or easy. > It turned > out that semantic extension, a la C++ overloaded operators, is a lot > more usable than extra syntax. C++ /is/ extra syntax that was initially a C preprocessor. C++ is still acquiring more syntax as we speak, like a giant muddy snowball. Even if you just use functional abstraction, you are still developing a new language. Every program has its own language. Just because you memorized the specification of C doesn't mean you can sit down and easily understand the FreeBSD kernel. Furthermore, there is a language which is not written down: in the designer's head. If the designer does not have language extension at his disposal, then he will resort to "macro expanding" the idea he has in his head and writing the expansion. Constructs that would be easily recognizeable in the original language become an undifferentiated mess in the target language. The expansion may be written in a language you know, but it would be easier and more productive for you to learn the original language and the original concept.