4 ms·
sorry to ask, but what do you mean by "unprincipled metaprogramming"? what would be "principled metaprogramming" to contrast it with? (it's really the first tim
by nnq 14y ago
sorry to ask, but what do you mean by "unprincipled metaprogramming"? what would be "principled metaprogramming" to contrast it with? (it's really the first time I heard the terms in a macro discussion...)
- colanderman 14y agoYa, I sort of made those terms up, sorry. What I mean roughly is: * unprincipled metaprogramming: any metaprogramming facility whereby module-level elements (e.g. delcarations, code, modules themselves) may partake in Turing-complete transformations (hence precluding complete analysis), may generate unsound code (i.e. what would be a compile-time error), or may modify code at run-time (i.e. through dynamic scope or global mutation). * principled metaprogramming: not the above; i.e., all code transformations terminate (allowing automatic analysis), all generated code is syntactically sound (mostly this means not having to worry about escaping stuff), and code transformations don't modify existing code. There are probably other things and some exceptions, but that's the jist of it. eval(), C++ templates, C macros, and prototypes are all examples of unprincipled metaprogramming. Parametric modules (OCaml), hygienic macros (Racket), and multistage programming (MetaOCaml almost) are all examples of principled metaprogramming. (I say "almost" for MetaOCaml because code generation expressions may not terminate; but this is neither required nor encouraged, and it is easy to guard against.)
- jeremyjh 14y agoElixir's macros are hygenic. They are expanded at compile time. Other code is not modified. Elixir does have eval, just as Erlang does.
- colanderman 14y agoMy concern isn't Elixir's macros (which I'm glad to see are hygienic); it's the concept that "declarations are expressions".
- klibertp 14y agoYou are aware that Racket (hygienic) macros are Turing-complete? You can loop and branch, and macro expansion may not terminate too. I think only OCaml functors really qualify to what you call "principled", but then - it's not the most powerful kind of metaprogramming I've seen.
- colanderman 14y agoMm, last time I used Racket (then PLT Scheme) macros I did not encounter those features… the only "looping" I saw was limited to the "..." construct (which is a finite expansion), and all branching was lexical (i.e. branching couldn't be used to form infinite loops). If I am incorrect then I retract my Racket example.
- klibertp 14y agoYou're most likely incorrect - I cannot be sure about Racket back when it wasn't called that, but Scheme hygienic macro systems - those created with SYNTAX-RULES - are Turing complete. Look here for a "primer" which explains how to 'loop' (by means of recursion) and branch with pattern matching. At the end of a tutorial you can find basic Scheme interpreter written as a set of Scheme macros. For example, in terms of this macro system, you can (and you could for a long time) define a simplest non-terminating macro like this: (define-syntax loop (syntax-rules () ((loop) (loop)))) Racket Macro Stepper gives a following warning when used to step through the macro expansion: Macro expansion has taken a suspiciously large number of steps. Click Stop to stop macro expansion and see the steps taken so far, or click Continue to let it run a bit longer.
- smosher 14y agoPrototypes... that blurs the subject a bit don't you think?