I'd be afraid of inheriting any codebase that made extensive use of these JS macros.<p>You really have no idea what this is doing (the canonical example from sweetjs.org):<p><pre><code> class Person {
constructor(name) {
this.name = name;
}
say(msg) {
console.log(this.name + " says: " + msg);
}
}
</code></pre>
It's not javascript -- it's your own made up "language" of macros.<p>I do believe with a steady hand this could lead to some great things, but the example on sweetjs.org seems rather heavy handed. Having different `class` macro definitions between codebases that use sweet.js will devolve into madness.
Glad someone finally wrote a post about this. Coming from the lisp world, that's the thing I constantly see missing from languages wrapping javascript. They generally change the syntax a bit, add a few features to minimize boilerplate in some areas, and call it a day. Why would I want to learn a new syntax to program in a language I already know well? Unless you give me the tools to write code that writes code, I'm not going to bother learning/using a new javascript syntax.
Since sweet.js code can't be directly run in the browser, you need some "compiling" or "interpreting" step. It's not obvious why this is any different from a compile-to-js language that had support for macros.<p>For example, someone wrote a macro system for coffeescript: <a href="https://github.com/mrluc/macros.coffee" rel="nofollow">https://github.com/mrluc/macros.coffee</a><p>Related discussions: <a href="https://github.com/jashkenas/coffee-script/pull/3171" rel="nofollow">https://github.com/jashkenas/coffee-script/pull/3171</a> <a href="https://github.com/gkz/LiveScript/issues/328" rel="nofollow">https://github.com/gkz/LiveScript/issues/328</a>
JavaScript compilers aren't only for syntax sugar. Closure Compiler, Dart2JS, and GWT are <i>optimizing</i> compilers. Most large Google applications for example would be hideously large without an optimizing compiler.
This is basically just saying "Choose Sweet.js in combination with some unknown array of macro libraries as your only language that compiles to JavaScript."<p>But because the article doesn't really frame it this way, it doesn't really explain to me why I would choose Sweet.js over ClojureScript or Scala.js or Black Coffee or whatever.
I barely trust Guy Steele with macros. You know who I don't trust with macros? Random JS coder dudes that haven't learned what true hardship is, when debugging a macro that is 5 levels deep and subtly changes the language because, hey, I have a macro! And having a macro means using a macro.<p>Language design is hard. Scheme has gotten it wrong. Over. And over. And over. They didn't get hygiene right for more than a decade. They <i>still</i> don't have it right. But people think they can easily invent new syntax that somehow doesn't do unexpected things. Your clever macro isn't so clever when some poor son of a bitch has been beating his head on a bug all day long just to find out your macro-that-looks-like-a-function isn't evaluating all its arguments because your macro-that-looks-like-a-function is really a function-that-is-a-macro. Don't get me started on missing IF branches and undefined behavior...
I would also recommend the WISP: A homoiconic JavaScript dialect with Clojure syntax, s-expressions and macros. More details at: <a href="https://github.com/Gozala/wisp" rel="nofollow">https://github.com/Gozala/wisp</a>
I strongly agree with everything the author writes, but I believe that sweet.js might not go far enough. For example, I am very fond of TypeScript. I'm also very fond of React's JSX. Yet, I cannot mix the two, and neither JavaScript extension could be expressed as Sweet.js macros.
>>>> "What if JavaScript actually adopted macros natively so that we never even had to run the build step?"<p>Honestly, that's pretty damn exciting. In my book, if JavaScript did that, it would very nearly complete a "worst to almost-first" transformation as a language. Starting with its early versions and all their ugly "bad parts", and advancing all the way to one of the most exciting, expressive languages to work with.
I find the title kind of ironic, given that sweet.js is still a compiler. :P<p>However, it is true it would be better to have one standard-ish compiler that can just execute whichever macros you throw into it.<p>That being said, you still run into the issue that `sync` brought up.
Best way I know of using macros in JS is <a href="https://github.com/Gozala/wisp" rel="nofollow">https://github.com/Gozala/wisp</a>, which generates pretty readable code. If you're going to pre-process, you might as well write in a nicer language...
So, after puzzling around with the macro for swap a bit, it seems like macros are like functions, except without the scoping rules, which suggests to me that we now have two kinds of functions, to keep track of in the code, each of which look identical, but behave differently. swap(a,b) looks like a function, but can interact with all the variables in the same scope (or above) as when it's called (is this the same for global functions?). Maybe I'm missing something big, but that seems dangerous when the macro is declared in another file, and I have to go figure out how it behaves.
How do you deal with naming collisions of macros from different developers? Are you considering to introduce name spaces? To me macros as well as other surprise code modification stuff seem unfeasible in teams with more than a few developers. Don't you think you risk maintainability with a huge macro apparatus?
sweetjs was a good idea, but I've found it hard to use, or rather..it's not the using part that's hard, but writing your own macro.<p>sweetjs has this hygienic thing that renames identifiers. To prevent it from renaming, there are many hoops that you have to jump through to prevent it.<p>sweetjs introduces of a lot of new concepts. These concepts are not as easy to understand as the ones in C. The macros are certainly more powerful. It's just that assuming it's C-like macro will give you the wrong kind of expectation with sweetjs.
I'm not super into the idea of code running on code because I likes it as simple as I can gets it. But, I know this notion is popular with lispers so I get it.
Did you had a look at [gorillascript](<a href="http://ckknight.github.io/gorillascript/" rel="nofollow">http://ckknight.github.io/gorillascript/</a>)? Its [prelude](<a href="https://github.com/ckknight/gorillascript/blob/master/src/jsprelude.gs" rel="nofollow">https://github.com/ckknight/gorillascript/blob/master/src/js...</a>) is written in gorilla macros :)
Very interesting! I've often thought that Javascript could actually be a pretty language with some syntactic sugar. It'd be even more interesting if you could run it client-side without preprocessing an sjs file into js first, sort of like how you can include LESS stylesheets and load a JS module to compile them in the browser.
You can also use C macros with Javascript <a href="http://vpj.svbtle.com/coffeescript-and-macros-clean-and-fast" rel="nofollow">http://vpj.svbtle.com/coffeescript-and-macros-clean-and-fast</a>
There are many reasons why people are writing *->js compilers, lack of macros isn't the least of the problems for js. Please keep the compilers coming, no productive coder really wants to write js.
I think things like syntactic sugar is perfectly fine, <i>as long as I can desugar it in a straightforward way</i>. I want to be able to programmatically desugar some piece of code, not have to Google it each time I am curious.<p>I think that if it is easy to investiage things like syntactic sugar, and not have it be buried in something like a compiler or lang spec, then DSL/language implementers (and anyone else, if the language permits it) could get away with implementing things that objectively make the language more complex to deal with, because to decipher it is only a query away, anyway.
Sup dawg, I heard you wanted to stop writing JS compilers and start using macros so here's a JS compiler that implements macros.<p>/head asplodes