
Sweet.js – Hygienic Macros for JavaScript - pcr910303
https://www.sweetjs.org/
======
dang
Thread from 2017:
[https://news.ycombinator.com/item?id=14695495](https://news.ycombinator.com/item?id=14695495)

2014:
[https://news.ycombinator.com/item?id=7978897](https://news.ycombinator.com/item?id=7978897)

[https://news.ycombinator.com/item?id=7219267](https://news.ycombinator.com/item?id=7219267)

2012:
[https://news.ycombinator.com/item?id=4650929](https://news.ycombinator.com/item?id=4650929)

[https://news.ycombinator.com/item?id=4560691](https://news.ycombinator.com/item?id=4560691)

------
jimbob45
For those who don't know, hygienic macros are ones that avoid variable name
collision. An example below from [https://www.geeksforgeeks.org/hygienic-
macros-introduction/](https://www.geeksforgeeks.org/hygienic-macros-
introduction/)

// C program to illustrate a situation known as

// accidental capture of identifiers - an

// undesirable result caused by unhygienic macros

#define INCI(i) do { int x = 0; ++i; } while(0)

int main(void) { int x = 4, y = 8;

    
    
        // macro called first time 
        INCI(x); 
          
        // macro called second time 
        INCI(y); 
          
        printf("x = %d, b = %d\n", x, y); 
        return 0; 
    }

~~~
na85
>int x = 0; ++i;

That can't be right.

~~~
phamilton
It's right. Expanded it's `int x = 0; ++x` and `int x = 0; ++y`.

The first case doesn't have any side effects. The second case does.

~~~
na85
Thanks. Obviously I don't write any C so I appreciate the explanation.

------
FluffyKitty
I actually work on a JS project that needed to heavily rely on macros to
reduce build file size (the project is from before ES6 and rollup.js). I ended
up going to MetaScript [1] as all of its syntax was based on comments. So all
the other tooling and code highlighting worked without issue.

[1]
[https://github.com/dcodeIO/MetaScript](https://github.com/dcodeIO/MetaScript)

------
btown
Typescript doesn't officially support macros yet, but if you want to live
dangerously (which you would if you were choosing to use Sweet.js!) you can
check out
[https://github.com/cevek/ttypescript#transformers](https://github.com/cevek/ttypescript#transformers)
:)

~~~
crandycodes
I didn't know about this project. I've wanted something like this for like 2
years or so.

------
ar_lan
On the README:

> Currently, Sweet should be considered experimental and under heavy
> development (re-development more like). As such, the API will be undergoing
> a bit of churn until probably the end of the year. So, probably best not to
> try Sweet in production systems just yet. If you're interested in helping
> out though we'd love to have you!

Project last updated 2 years ago. I think this is dead.

------
slaymaker1907
Racket likely has the most sophisticated (mostly) hygienic macro system out
there. In particular, syntax parameters are a really neat feature which lets
you implement things normally requiring breaking hygiene in a hygienic way.
For example, implementing early return using return as a keyword can be done
using a syntax parameter which allows for nesting, renaming the “return” if
you want, and composing it with other macros which utilize their own “return”
keyword.

~~~
Quekid5
Racket truly has some great stuff wrt. macros -- I'm not sure if it was
invented as a research vehicle for macros specifically[0], but they've even
gone as far as implementing fairly advanced type systems _as macros_ [1].

Besides the one I've linked, they have lots of interesting papers around the
macro system: the handling of 'stages', the modularity, etc. Basically just
google "Racket [something]" and go from there :)

[0] Probably more just a general 'extensible languages' type thing?

[1] [http://www.ccs.neu.edu/home/stchang/pubs/ckg-
popl2017.pdf](http://www.ccs.neu.edu/home/stchang/pubs/ckg-popl2017.pdf)

~~~
quelltext
I only glanced over the paper but its novelty seems to lie in the turnstile
language itself, i.e. the design of a metalanguage to define EDSLs that have a
typesystem.

Yes, it is built using macros and I assume cleverly uses whatever macro system
features Racket provides so there is possibly something novel there as well.

However, the fact that it can be done or has been done on its own is not quite
so surprising to me. If you have the ability to inspect syntax you can
obviously do something like that.

------
sawyerjhood
It is a little bit of a shame that it doesn't seem to be under active
development anymore. For personal projects, it would be fun to be able to
write up little DSLs

~~~
hombre_fatal
It seemed to undergo a major rewrite and then died.

I could also never really figure it out post-rewrite. Pre-rewrite, I had made
some cool macros just out of intuition after reading some of its examples.
Now, I can't get many of its own examples to compile in its live editor.

Too bad. It's about 1000x simpler than, say, implementing low-level Babel
transformations.

~~~
yuchi
I feel the pain. Things got a little bit easier with Babel Plugin Macros and
Typescript (which forces you to build macros that adhere to a reasonable type
system)

~~~
lioeters
I've only recently learned about Babel Plugin Macros and haven't used it in
production - but here are a few links in case anyone's interested.

[https://babeljs.io/blog/2017/09/11/zero-config-with-babel-
ma...](https://babeljs.io/blog/2017/09/11/zero-config-with-babel-macros)

[https://github.com/kentcdodds/babel-plugin-
macros](https://github.com/kentcdodds/babel-plugin-macros)

[https://github.com/jgierer12/awesome-babel-
macros](https://github.com/jgierer12/awesome-babel-macros)

These "macros" take a different approach than Sweet.js: they're not syntax
extensions, but rather code transformers that you import and use explicitly.

------
Lowkeyloki
After falling in love with Clojure and then Clojure being rejected by my
company, I so wanted Sweet.js to become a thing. Macros allow for some
incredible magic and amazing productivity, in my experience. Unfortunately,
Sweet.js looks abandoned last I checked. And I'd be surprised if I could sell
my company on it.

------
galaxyLogic
I wonder, ES6 template strings allow any kind of string inside them which can
be constructed based on existing values in the surrounding function. So I can
give such a string as argument to a function which returns some non-string
JavaScript value, perhaps a function.

Would this qualify as a "hygienic macro"?

------
Lerc
Are there any active projects that do anything similar?

The two things I'd quite like to transform are

In a es2015 Class function if base identifier foo is a class field (in this or
ancestor class) it becomes this.foo . Only for fields defined in the Class
definition.

for (x of y) becomes for (let x of y)

------
hashkb
This project is dead, but writing a Babel transform using something like
[https://github.com/benjamn/recast](https://github.com/benjamn/recast) is easy
and fun!

------
acjohnson55
Was a great project. I experimented with it about 5 years ago and really liked
what I saw. But at the end of the day, it's not so fun having syntax that none
of your tooling understands.

------
k__
What's the main reason to use this?

I mean, I've seen languages like Rust using macros excessively, but why would
you do so in JS?

------
totechite
pls explain me difference between it and eval

~~~
wry_discontent
From what I gather reading the docs, this ties into Babel and that lets you
define actual new syntax rather than just eval strings.

------
m1sta_
There was a period where the developer considering reversibility. I wonder
where that arc ended up.

