sweet-js / sweet-core

Sweeten your JavaScript.
https://www.sweetjs.org
BSD 2-Clause "Simplified" License
4.58k stars 208 forks source link

add equivalent of racket's begin-for-syntax #581

Open WreckedAvent opened 8 years ago

WreckedAvent commented 8 years ago

Context:

I want to be able to write private helpers for my macros. Currently, the only way to do this is to have another module which you import. This seems less-than-ideal to me and involves some weirdness like import ... for syntax. I suggest having a syntax block which puts all of the statements into the correct phase to be used in macros.

Example:

syntax {
  let next = ctx => ctx.next().value
  syntax inc = ctx => #`${next(ctx)} + 1`
}

inc 10

would compile to

10 + 1

Considerations:

disnet commented 8 years ago

Yeah, racket calls this begin-for-syntax and we've discussed it before in the context of the initial module implementation.

I definitely want this but haven't found a syntax I'm happy with yet. Nesting like racket or your suggestion goes against normal binding forms (except for vars hoisting kinda).

Maybe a prefix on the binding?

let x for syntax = // ...
for syntax let x = // ...
syntax let x = // ...
// maybe a special labeled statement?
syntax: let x = //..
WreckedAvent commented 8 years ago

Well, personally, if it isn't a block, it's going to be a lot of repeated stuff::

import m1 from ... for syntax
import m2 from ... for syntax
for syntax let h1 ...
for syntax let h2 ...

vs

for syntax {
  import m1 from ...
  import m2 from ...
  let h1 ...
  let h2 ...
}
disnet commented 8 years ago

Agreed. Seems like our options are either violate DRY or violate lexical nesting. I don't like either. On Sat, Aug 20, 2016 at 2:41 PM Justin notifications@github.com wrote:

Well, personally, if it isn't a block, it's going to be a lot of repeated stuff::

import m1 from ... for syntax import m2 from ... for syntax for syntax let h1 ... for syntax let h2 ...

vs

for syntax { import m1 from ... import m2 from ... let h1 ... let h2 ... }

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/sweet-js/sweet.js/issues/581#issuecomment-241225334, or mute the thread https://github.com/notifications/unsubscribe-auth/AAAJOpZJNtsbP1QRNRnGYVZG6OQcyVBDks5qh3SGgaJpZM4JnukA .

vendethiel commented 8 years ago

I propose commas to separate the let / imports.

WreckedAvent commented 8 years ago

@vendethiel you mean like this?

import m1 from ...,
import m2 from ... for syntax

for syntax let h1 ...,
           let h2 ...
gabejohnson commented 8 years ago

@disnet var violates lexical nesting so there's precedent. I personally like the block solution. It could be implemented later as a reader macro though.

gabejohnson commented 8 years ago

@WreckedAvent Now that I look at it again I like your solution if we could do:

for syntax const foo ...;
for syntax const bar ...,
                 baz ...;

This is no different than how binding forms currently work. As far as the imports go though ¯_(ツ)_/¯ In the common case you shouldn't have too many imports for syntax.