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
  • #61
Closed
Open
Issue created Feb 15, 2013 by Administrator@rootContributor

No way to get gensymmed identifiers without introducing closure

Created by: jhusain

I'm confused about something. The first thing I tried was a simple foreach macro. The forEach function is too slow on some of our devices so we continually write out counting for loops.

macro foreach { case ($name:ident $collection) $body => { var arr = $collection, counter, length; for(counter = 0, length = arr.length; counter < length; counter++) { $name = arr[counter]; $body } } }

foreach (x [3, 4, 5]) { console.log(x); }

// generates...

var arr = [ 3, 4, 5 ], counter, length; for (counter = 0, length = arr.length; counter < length; counter++) { x = arr[counter]; { console.log(x); } }

Pretty darn good. An extra scope being introduced for the body, but otherwise easy and nice. The problem came up when I tried to nest foreach's. My variables weren't gensymmed.

foreach (x [3, 4, 5]) { foreach (y [3, 4, 5]) { console.log(x + y); } }

// generates...

var arr = [ 3, 4, 5 ], counter, length; for (counter = 0, length = arr.length; counter < length; counter++) { x = arr[counter]; { var arr = [ 3, 4, 5 ], counter, length; for (counter = 0, length = arr.length; counter < length; counter++) { y = arr[counter]; { console.log(x + y); } } } }

Yikes! I looked at other examples and found that sweetJS looked for a new function scope as an indication that variables should be gensymmed. I thought this very logical...until I realized the function made it's way into the generated code.

macro foreach { case ($name:ident $collection) $body => { (function(arr,counter,length) { arr = $collection; for(counter = 0, length = arr.length; counter < length; counter++) { $name = arr[counter]; $body } }) } }

foreach (x [3, 4, 5]) { console.log(x) }

// generates...

(function (arr$53, counter$54, length$55) { arr$53 = [ 3, 4, 5 ]; for (counter$54 = 0, length$55 = arr$53.length; counter$54 < length$55; counter$54++) { x = arr$53[counter$54]; { console.log(x); } } });

I'm probably missing something obvious here, but it seems to me that when I create a function scope I don't need gensyms because javascript creates a new scope. Any outer variables with the same names will be hidden by the new identifiers. It would be much more useful for me if var's within the macro and the in-lined body were all gensymed.

I'm specifically trying to avoid introducing a function call and scope for performance reasons. If I were going to do that, I could simply do this:

[1,2,3].forEach(function(item) { console.log(item); })

Thanks,

Jafar

Assignee
Assign to
Time tracking