11 ms·
Sweet.js – Hygienic Macros for JavaScript
- longlho 9y agothis is already covered in basically any AST transform systems (babylon, acorn, TS...)
- zeckalpha 9y agoThis predates those, and is hygienic.
- adgasf 9y agoI believe that Babel lacks custom infix operators whilst Sweet.js provides them.
- btown 9y agoYou're absolutely right; Babel's parser is very much hand-coded, and adding syntax requires deep knowledge of the internals. Not impossible, but not for the faint of heart. My dreams of having the safe navigation operator from Coffeescript (a?.b?.c) must yet remain unfulfilled... https://github.com/babel/babylon/blob/master/src/parser/expression.js#L461 https://github.com/babel/babylon/blob/master/src/parser/expr...
- scribu 9y agoThat raises a question: What's stopping Babel from using Sweet.js instead of a custom parser? Are there any transpilers that do use Sweet.js?
- zeckalpha 9y agoContracts.coffee IIRC, uses Sweet for Contracts.
- djfm 9y agoWell "a.b.c" violates the principle that you should never access a property more than one level deep anyway ;) But in this case it's pretty straightforward to write a function like "get('b', 'c')(a)" or use a lib like lodash [1] [1]: https://lodash.com/docs/#get https://lodash.com/docs/#get
- btown 9y agoThe Law of Demeter doesn't always apply neatly, especially when you're introspecting JSON sent over the wire and you don't have a "class" with object oriented behavior for each sub object (at best, they're strongly typed). And the runtime overhead AND verbosity of a function may not be ideal, with the string parsing required in lodash and the awkward syntax of the curried function. Something that compiles natively in a DRY way to a && a.b ... would be used widely imo.
- chocolateboy 9y ago> My dreams of having the safe navigation operator from Coffeescript (a?.b?.c) must yet remain unfulfilled... Not for long: https://github.com/babel/babel/pull/5813 https://github.com/babel/babel/pull/5813
- btown 9y agoYou just made my day :)
- andreypopp 9y agoThat's not just "AST transform system", Sweet.js provides a way to extend grammar with new productions. That allows to introduce new syntax constructs.
- eatonphil 9y agoComing from a Scheme background, if there's one thing I can't believe we live without in Javascript, it's macros. Hell even C has macros... I've looked at Sweet.js a few times to add support for macros to the Linode Manager. Between m4, the gcc preprocessor, and something native, this seemed like the easiest potential sell. However, I've been turned off by how complicated this looks compared to any of the other options and I'm not sure it actually even supports the feature I want: allow some code to show up in "development" mode but for that code to not even exist in the compiled output of "production" mode. (The other feature that's just as important though is being able to wrap shared code up in a single function that gets compiled in at compile time, but I think Sweet.js supports that.)
- ykler 9y agoWho uses m4? It has been around forever, but I have never really seen it used except in autoconf. When I looked at it (a long time ago) it struck me as really tricky and confusing, even more than lisp macros (but maybe on a par with TeX). However, this was just a first impression -- I didn't go too deep.
- chas 9y agoI have used it recently. I have a similar attitude towards m4 as shell scripts: they are good for quick hacks, proofs of concept, and very simple systems. When I need to sprinkle just a bit of macros on something, m4 is great. For example, a one-off piece of technical documentation I wrote is markdown interspersed with code examples. I wanted to make sure the code passed its unit tests, so it lives in separate files and I use m4 to include it into the bigger document. This is nicer than catting separate file chunks together because the text can all be contiguous, but if I needed to do anything more sophisticated I would probably switch to purpose-built templating or static site system.
- dflock 9y agoI've used it for really simple templating stuff with Dockerfiles - which it works fine for.
- kazinator 9y ago
- couchand 9y agoThe in-the-wild code I've seen that uses Sweet.js has been atrocious. Of course I'm not saying that this is necessarily the case. I'd love to see some real world examples whter this is used effectively.
- btown 9y agoSeparately, could you point to some examples of the bad Sweet code you've seen? If it's anything like C macro misuse, it'll at the very least be educational to see just how badly one can shoot oneself in the foot.
- joshschreuder 9y agoI must say I don't see the use case... What real world examples do you have?
- d--b 9y agoAlso known as: 'how to build your own javascript dialect that you won't be able to hire for'
- jaywunder 9y agoThe last thing the JS community needs is macros IMO. From what I've seen in other languages, macros are difficult to maintain and document, and they add syntax constructs to languages that aren't supported by code highlighters. The difference between this and babel, is documentation. Babel is working off of a specification of how the language should work, whereas I doubt someone will document their macros as well as TC39 does the JS syntax
- flavio81 9y agoEvery language benefits from macros, and certainly JS.
- lmeyerov 9y agoWe were looking into sweetjs for adding cross-module contracts to the graphistry stack, but nixed the project when it became too much to generate code that passed our basic linters. TS largely scratches that itch, so we've been moving to that. I'm still hopeful though :)
- alnitak 9y agoWhat would hygienic mean in this context?
- devdad 9y agoCan someone please explain macros, in an easy to grasp way?
- sscarduzio 9y agoMacros are a tool given to the user by PL designers to extend the language with new syntax. I.e. a macro program is a piece of code that defines new keywords, operators, etc. and their implementation.
- coltonv 9y agoSay you're creating a programming language and you know everyone is going to love it and use it. You add some nice features like if statements, switch statements, and for loops which allow the people that use your language to decide when certain code runs and shortens the syntax for common patterns. 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.
- 9y ago
- lamlam 9y agoI personally prefer MetaScript [1] as it's comment based so JavaScript highlighters/linters don't have issues with it. It is also essentially JavaScript so no special syntax had to be learned. [1] https://github.com/dcodeIO/MetaScript https://github.com/dcodeIO/MetaScript