Sweet.js – Hygienic Macros for JavaScript
sweetjs.org
sweetjs.org
So it's not due to lack of familiarity that I won't use it; it is simply atrocious.
Recently I needed a preprocessor (featuring just simple if/ifdef/elif/endif) in a Linux distro build system (Yocto). I didn't want to add anything new.
To avoid inflicting m4 on myself and everyone who has to interact with this in the future, I wrote a simple awk script wrapped around cpp.
The tiny awk script implements this pipeline, which involves encoding and decoding the input so that cpp never sees the syntax of the file:
this is our 1 1 this is our
original 2 2 --> [dec] original
@ifdef FOO --[enc]--> #ifdef FOO --[cpp]--> 6 file
input 4
@endif #endif
file 6
this works with nearly any textual input. Your input can contain broken C tokens and comments and whatnot.I switched the # to @ to remind people that this isn't the C preprocessor, and because # is a comment character in the preprocessed language, which could look confusing.
It is also essentially JavaScript so no special syntax had to be learned.
https://github.com/babel/babylon/blob/master/src/parser/expr...
But in this case it's pretty straightforward to write a function like "get('b', 'c')(a)" or use a lib like lodash [1]
Are there any transpilers that do use Sweet.js?
Not for long: https://github.com/babel/babel/pull/5813
I.e. a macro program is a piece of code that defines new keywords, operators, etc. and their implementation.
Five years down the line your language is losing popularity fast, because all the hip new languages have an "unless" statement which is the opposite of an if statement. They have for-each loops, cond statements, and their if/else statements return values, so you can write less code to do those common patterns in those new languages than your language.
You rewind time 5 years using a time machine and this time, when you create your langauge, you add all those cool features, only to realize in another 10 years your language has lost popularity because there's a new set features they want, lambdas, argument piping, etc.
So this time when you go back in time, you add macros to your language. Macros are bits of code that allow people using your language to write code that produces more code. Now, you don't even have to write an unless statement, you can let the community write one for you and release it as a package. Anyone at any time can effectively add features to the language in their own project.
That sounds fantastic, and it often is, but macros need to not be abused. If a developer writes a bunch of code using lots of his own macros in your language, anyone reading that code later is going to be very confused seeing that many language features that aren't in the language docs, because that random developer wrote them himself. Functions are much more explicit than macros, so if you can write whatever you're trying to write as a function instead of a macro, you'll be better off. For every success story of a language becoming easier to use because of macros, there's another story of a different language becoming frighteningly complicated due to macro abuse.
In other words, a macro is a program that writes programs.
In languages that make heavy use of macros (like Lisp), a macro is compiled almost transparently, so you can use it as if it were a function. It behaves like a function but can do a lot more.
One simple use is to eliminate having to write repetitive or "boilerplate" code, since you can just program a macro to write generate code for you. This generation occurs on the fly and transparently, so the code is more maintainable as well.