Skip to content
GitLab
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • S sweet-core
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 62
    • Issues 62
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 4
    • Merge requests 4
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages and registries
    • Packages and registries
    • Package Registry
    • Infrastructure Registry
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • sweet-js
  • sweet-core
  • Issues
  • #437
Closed
Open
Issue created Dec 21, 2014 by Tim Disney@disnetContributor

proposed changes to syntax binding forms

So right now we have some problems when it comes to our binding forms for macros. At the moment we have two, the recursive declaration form and non-recursive let form:

// declaration form
macro m {
    ...
}

// let form
let m = macro {
    ...
}

They are modeled after the definition forms in scheme:

(define-syntax m
  ...)

(let-syntax [(m ...)]
  ...)

The problem is that these are not a good analog for JS forms (var, let and function declarations). In particular let macros are not really a perfect analogue to let (temporal dead zone etc.). It also doesn't give us a nice general syntax binding form for things other than macros.

So, here's my idea. We add a new binding form, stx, as a drop-in replacement for let on compiletime values and remove the let macro form.

stx m = ...

In particular, its behavior is:

  1. duplicate declarations in the same scope are an error
  2. block scoping so no hoisting
  3. temporal deadzone, references before stx are unbound except in nested structures
  4. m is not bound in the initializer (not recursive by default)
// puts a number into the compiletime environment
stx m = 42;
// puts a normal function into the compiletime environment
stx m = function(stx) { ... }
// puts the primitive form of a macro onto the compiletime environment
stx m = macro { function(stx) { ... } }
// macro is a macro
stx m = macro { rule {} => { 42 } }
stx m = macro { case {_} => { #{42} } }
// and can be recursive by naming itself
stx m = macro m { rule {} => { m } }
stx m = macro m { case {_} => { #{m} } }

// equiv of define-syntax-rules
stx m = macro rule {} => { 42 }
stx m = macro case {_} => { #{42} }
// and the recursive form
stx m = macro m rule {} => { m }
stx m = macro m case {_} => { #{m} }

We could also use syntax instead of stx (though stx has a nice symmetry with var and let in terms of length). Perhaps other variants?

And just like function declarations we can also have a macro declaration form:

macro m {
    rule {} => {}
}

That expands to stx m = ....

Does this seem reasonable to people?

Assignee
Assign to
Time tracking