10:00 Introduction - me - Richard Gabriel - titles SLIDE: goto - talk to slide SLIDE: black ------------------------------------------------------------ 9:00 What is a macro? - something that circumvents the "normal" rules of evaluation - a programmer-developed "special form" What is a macro good for? - language extension: - eliminating redundancy by capturing a recurring syntactic pattern - ...thereby creating syntaxes better matched to a domain problem. - ...and reducing errors due to screwing up the pattern on a case by case basis ------------------------------------------------------------ 8:00 Uncontroversial example: - Macros essential to productive and error-free (ha!) assembly programming - if hand-writing assembly, you don't want to have to manually type out all of the boilerplate instructions for making a function call each time. - preprocessor expands macros to (inline) assembly instructions - Note: it's a *pre*processor: macro expansion process doesn't get to call assembly language routines, or modify the runtime environment through side-effects - Note also: a macro expansion can't define new macros, or otherwise modify the pre-processing environment - So: macros are essential, but limited in power ------------------------------------------------------------ 7:00 The menace question: - For purposes of this discussion, we'll define menace as "net negative impact" in production programming environment. - Clearly essential to survival with assembly. - Are macros, especially powerful macros, really essential once you're at a higher level? Or just an attractive nusiance? ------------------------------------------------------------ 6:30 What's wrong with *common lisp's* macros? (Mostly scheme, too) - The human reader can't tell a macro expansion from a function call at the invocation site. (Makes it like C++ --- example here) SLIDE: C++ SLIDE: black ------------------------------------------------------------ 6:00 - When compiling, macro expansion is a static event: - changing a macro def'n means recompiling all dependencies SLIDE: Will Donnelly example from Scheme - you can't use a macro programmatically (without resorting to eval) - The antithesis of dynamic languages! ------------------------------------------------------------ 5:30 SLIDE: black - Macro expansion is not inherently idempotent - each expansion of a macro may have side-effects that persist into runtime - rpg told me to tell you why amateurs do this. but I have seen pros do it! - macro expansion can touch the runtime - "order is important" - hinders reproducibility! ------------------------------------------------------------ 4:30 - Incomplete separation of preprocessing phase from compilation phase. This: - makes your program semantics dependent on the order in which you compile and load individual files - makes it very hard to maintain accurate program build order dependencies in complex systems - gives you eval-when SLIDE: eval-when - Unhygenic --- can affect the containing environment! - default behavior is unhygeine! Have to work to gensym. - I have seen experts botch this *every time* - scheme does much better ------------------------------------------------------------ 3:30 SLIDE: black - Tools problems: - Code doesn't look the same in the debugger as it does in the source file - grep can't find generated symbols - Compiler 80% solution --- close enough to compiler access that people who should know better use them when they should just modify the compiler or build a new compiler. ------------------------------------------------------------ 3:00 Beyond CL macros, what's alarming about powerful macro systems generally? - Encourage the multiplication of special forms (language dialects) - Encourage "cleverness": "Everyone knows that debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you write it, how will you ever debug it? " -- Brian W. Kernighan - Make it hard for the code reader. Code is written once, revised a few times, but read over and over. - Human language, you can recognize a noun or a verb by its placement even though it might be unfamiliar. - However, if someone invents new syntax, you will have trouble telling what is going on at all. (then it's called poetry) Menace because: these risks are unnecessary ------------------------------------------------------------ 2:00 SLIDE: claims Claims: - for language *implementation*, "derived" control constructs can be implemented in the "core" as or more easily than with macros. - for language *extension*, in a high level langauge such as Lisp, there are vanishingly few cases where the same effect couldn't be achieved with a small number of language primitives. - e.g. python handles common language extensions: - for statement + iterator/generators: solves dolist, dotimes, do.... - with statement + context guard objects: solves with-* proliferation - for *domain-specific* embedded languages, authors should buckle down and write a proper compiler/interpreter/whatever, and provide a distinct and obvious transition: - Bad: (select * from addresses where city = (get-city thing)) - unheralded macro-driven transition - "regular" lisp evaluation active at irregular points - not programmatically composible --- static! - Better: (sql-query `(select * from addresses where city = ,(get-city thing))) - transition to sublanguage is clear - regular evaluation points are at user-controlled points - programmatic composition now possible: (sql-query `(select * from addresses where ,column = ,value)) - for *domain-specific*, *non-embedded* languages, definitely write a distinct compiler, and put the content in separate files. ------------------------------------------------------------ 0:30 SLIDE: RPG Summary's macro impact: - wise man (rpg) saith: "Macros encourage people who are not good at language design to do something equivalent to language design, using tools that don't help, and with effects that are too powerful. This makes code unreadable to people joining later and for the authors after time has passed. Well designed macros are well documented, but this doesn't happen much." ------------------------------------------------------------ 0:05 SLIDE: Me - smartass (me) saith: Q: What do you get when programmers design a language while trying to get something else done? A: PHP ------------------------------------------------------------ 0:00 Final note: - academic debate for how long? - HCI of programming languages at OOPSLA