an atypical entry

Nov 12, 2005 20:39

I've found that I have a hard time thinking in Microsoft. I can think in C, C++, Smalltalk, Java, Bourne, BASIC, Perl, LISP, and any kind of scripting you could care to name. But, hand me C#, VB, J, or any of the other language Microsoft has designed in the last ten years, and I just can't hack it. Well, I can, but it just seems ... the long way ( Read more... )

programming, rants, tech

Leave a comment

lumiere April 11 2006, 23:31:22 UTC
One trouble with Lisp and similar languages with complex compile-time code-generation systems is that macros and other code-generators are not first-class citizens of the programming environment. For example:
  • macros generate code, and multiple macros generate lots of code, and those code-generators interact in interesting, and sometimes incorrect, ways, and the details of code generation are extremely difficult to track down and change, especially if you are not the author of the code generators in question;
  • programming understanding tools such as profilers & debuggers gather information on the basis of the generated code, but rarely are able to correctly map that back into the source format which the programmer understands, and in the absence of that reverse mapping the programmer must learn how what the code generation process does in order to do the back-mapping by hand;
  • code-generation is generally hard to delay until runtime, yet sometimes you will need that delay so you can collect the proper inputs to the code generator.
  • There are ( ... )

    Reply

    zanfur April 12 2006, 08:16:31 UTC
    Well, although I agree that macros in general are not first class citizens of the programming environment, LISP is an exception: LISP's macro system is actually turing-complete, making it a full-blown programming language unto itself. Actually, the macro system isn't a separate language -- it's just more LISP -- but you can use all of LISP to generate the code. Except for the macro you're currently defining, of course. This is an obvious extension of LISP, because its code syntax and list syntax are identical, and the code therefore easy to programmatically generate, but there are other systems (such as Slate, a smalltalk derivative) that manage to have a turing-complete macro system as well. You still run into problems of badly written code, but it's a lot easier to avoid (and easier to catch) than in most languages.

    Badly written programs will have badly written bugs, of course. Because LISP macros are literally programs unto themselves, badly written macros will have badly written bugs. But, there are ways (actually, it's ( ... )

    Reply

    lumiere April 12 2006, 14:21:20 UTC
    I've programmed in Chez Scheme and am familiar with hygenic macros and other nice properties of LISP-style macros.

    Making macros Turing-complete, even making them expressed in the host programming language, does not make them first-class citizens of the programming language. It does make them far more powerful and far easier to write.

    Here's another example of the second bullet point: static analysis. Your generic static analysis tool will operate on the fully-expanded syntax; how do results get mapped back onto the source syntax? There are workable approaches, but it's not a simple problem.

    Reply

    zanfur April 12 2006, 08:49:39 UTC
    I agree that macros pose some issues. You got me on the "debuggers can't back-map well" one, at least. Thankfully, because the forward mapping is so easy, it's never been a problem. That's in addition to the easy Tu Quoque defense I could make, but really, it just hasn't been a problem. It's a problem in C -- it's pretty hard to figure out what the expansion will be, once you start layering macros -- but I think that's mainly because C doesn't have a good "macro-expand this code and show me the result" function, and LISP does. (ALthough evan just wrote a C REPL, though, which may change that. I wanna be like him when I grow up.)

    I just really prefer writing code that says exactly what it does. I can't do that with C. I can write something pretty close to english in LISP, and get what I want done. That's made possible by the openness and simplicity of the LISP macro system.

    I like your comment that addressing these problems is in the arena of the development environment. LISP images are the development environment. The ( ... )

    Reply

    lumiere April 12 2006, 14:30:15 UTC
    I'm not going to defend the C/C++ macro system. I applaud Stroustroup's claim that his hope for C++ templates was to eliminate the C preprocessor. Even so, C++ templates are Turing-complete themselves, and thus make it possible to write macro-free programs that are nigh-on-impossible to understand.

    The Visual Studio languages you were discussing were the ones MS introduced (C# & VB); that comment really only applies to them, and not to Visual C++, which has the worst of both worlds.

    .NET 2.0 does a much better job than 1.x on runtime code generation & compilation, but 1.x could do it, and the XmlSerializer class, among others, has used that extensively since 1.0. What the MS .NET languages lack is a syntax-quote mechanism to make runtime code generation & compilation easy, akin to LISP S-expressions & eval.

    Reply


    Leave a comment

    Up