5 ms·
M4 is of historical interest, but nowadays it seem just using a templating system would be much better in almost all cases, no? Modern systems like Jinja2 or T4
by 1wd 8y ago
M4 is of historical interest, but nowadays it seem just using a templating system would be much better in almost all cases, no? Modern systems like Jinja2 or T4 are IMO actually more powerful, easier to to use, maintain and debug, and just plain nicer. Am I missing something?
- enriquto 8y agoWhat is the difference between a macro language and a templating system? I do some m4 from time to time and it is actually very easy to use and really nice.
- 1wd 8y agoI'm not sure. I get the impression with such old-school macro languages (like M4) you have to use a lot of quoting tricks, evaluation order hacks, and use low level primitives like divert and dnl to build up even the simplest of useful things. Many scripts seem to start by inventing a looping construct. While modern templating systems (like Jinja2 or T4) use a proper programming language (like Python or C#) so using even high-level constructs and complex data models is trivial.
- yayana 8y agoI think this last paragraph is a bit misleading: > use a proper programming language m4 is a small proper language that can be used directly. jinja2 is a DSL written in python that doesn't actually have access to much of python. m4 is harder to work with in the domain (quoting, escaping, and data modeling) since it is a general purpose language, but it is easier to do general purpose processing tasks with m4 if they violate the stereotypes of what should be done in the domain.
- alxlaz 8y agoA macro processing language is pretty much a language purpose-built for describing how to copy text from here to there while performing certain changes in the process. A templating system is a set of language-specific constructs (a library, a module, whatever they happen to call in that language) that essentially deals only with the latter (i.e. describing how to perform the changes). It's generally up to you to deal with the "copy text from here to there" part, although most templating engines give you a specific interface that you have to adhere to. I suppose the difference is better illustrated by PyExpander ( http://pyexpander.sourceforge.net/ http://pyexpander.sourceforge.net/ ) which is a macro processing language based on python vs. Jinja (http://jinja.pocoo.org/ http://jinja.pocoo.org/) which is a templating engine for Python. I don't think any general statement about which on is "better" can be meaningful. I suppose that, if you have a full project already written in one language, with all work performed by a single program, it's easier to get what you need via templating engine. If your project is already a collection of tools, whose outputs you need to tie together, it's often less effort to bring in a macro language than write your processing logic from scratch in a non-macro language just to leverage a templating engine. Assuming, of course, that you have someone who knows the macro language in your team ;-). If all your team knows is Jinja2, you're gonna get Jinja2. FWIW, I also do a little M4 from time to time (and a long time ago I also worked with GPP) and find both of them fairly easy to use.
- jolmg 8y agoI think the main difference is that a templating language is explicit in what causes an interpolation, while a macro language is implicit. For example, compare this use of the m4 macro language: $ m4 << EOF > define(name, Jane)dnl > hello name > EOF hello Jane with the equivalent using the erb templating language: $ erb -T- << EOF > <% name = "Jane" -%> > hello <%= name %> > EOF hello Jane In the m4 example, Jane, hello, or name might even be another macro, and you'd need to know that to know what the result will be: $ m4 << EOF > define(name, nombre)dnl > define(hello, hola)dnl > define(Jane, Joe)dnl > define(name, Jane)dnl > hello nombre > EOF hola Joe Imagine you source those first 3 lines from elsewhere, a file serving as a library. Things can get pretty confusing if conventions aren't established and followed. You'd need to explicit in what you don't want to interpolate to get the same understandability as a templating language: $ m4 << EOF > define(\`name', \`nombre')dnl > define(\`hello', \`hola')dnl > define(\`Jane', \`Joe')dnl > define(\`name', \`Jane')dnl > \`hello 'name > EOF hello Jane By quoting like this, you can look at any single line and know what's going on. name is not quoted in the last line so it "must" (mandated only by convention) be interpolated. "name" and "Jane" are quoted in the second-to-last line, so they're not interpolated, and they can only mean that "name" will be substituted by "Jane". This convention offers the same benefits of a templating language, only it's more burdensome and error prone. Now, as to what is better? I think templating languages are better for modifications of documents based on variables, like making the rows of an HTML table correspond with a listing of data. The only good use-case I can think of for macro languages is extensions of languages. Like making mini-compilers (or do they call them transpilers nowadays?) by writing m4 scripts. That's the only time I think it'd be better to have implicit interpolation, when you have more interpolations than not, and the document source language is generally understood to be something far different than the target language. This means that, since the majority of the time CPP (a macro language) is generally used for interpolation of data or code in what is generally understood to be C code as source and target language, I think it would have been better designed as a templating language. That way, you wouldn't have people joking about doing things like: #define TRUE FALSE which would have no ill effect in a templating language. On second thought, however, C being what it is (a low-level language with inflexible syntax and semantics), I can see that the intention of CPP was indeed probably to write extensions to the language, which would make it suitable to be a macro language.
- kevin_thibedeau 8y agoI used m4 to add high level macros to an assembler [1]. You can't do that with templating without jarring syntax changes. m4's willingness to accept simple strings as macro invocations is it's strongest asset. [1] https://kevinpt.github.io/opbasm/rst/m4.html https://kevinpt.github.io/opbasm/rst/m4.html