⚡ Sangsakala Proxy 🏠 Home
Skip to content

Compiler CLI and Scalability #131

Open

Description

@vishesh

This document proposes to replace/(enhance) the racks tool currently used to compile RacketScript programs.

Motivation

racks is slow

  • It compiles each file serially, which is particularly frustrating during first compilation.
  • We did some work to avoid recompiling unchanged modules, but it still not foolproof and may require full recompile under certain circumstances. Eg. If a module with macro changes, any other module using that macro must be recompiled.
  • The identifier graph used to follow the bindings is recomputed in each run, which takes noticeable number of seconds. This graph can potentially be cached, and only affected modules should be processed to update this graph.

racks is impractical

It simply compiles what it gets. It has no notion of package.json, info.rkt which is often used in practical applications. It overwrites package.json with the default one.

Some common examples:

  • User can't specify JS dependencies at all.
  • No control over how to produce the distribution JavaScript file, and limited to what we allow to use e.g. Gulp, Babel, Minifiers ...
  • Plain JavaScript files has to be copied manually to distribution directory.

Proposal

racks should be replaced with a tool that more or less is like what raco is to Racket or lein is to ClojureScript. Here's a rough workflow I see:

  • Create a new project:

      racks init my-new-project
    
  • Install all dependencies:

      racks install
    
  • Create a new project using some a template project structure. However, unlike current situation, this is used just to create project. The config can be edited to whatever.

      racks init my-new-project -t babel-webpack
    
  • Builds the project:

      racks build
    
  • Watch the project and build automatically:

      racks build --watch
    
  • Start a REPL

      racks repl
    

All these command could be simple raco extensions, like raco racketscript <subcommand>, and racks can just be alias for raco racketscript or something like that.

Secondly, compilation of each module should be independent of other module as much as possible. There is only much we can do here as mentioned earlier, but there is still scope.

info.rkt can act as combined project configuration, i.e. for both Racket and JavaScript. Since, package.json is simply a JSON, it can just be a S-expression in info.rkt. The project config can also specify the main entry point, any additional JavaScript/static files that needs to copied, or pretty much anything user may want to do pre/post operations.

Conclusion

The documents proposes much more than what we have currently have time and resources for. However I believe it is certainly something we should start thinking about. I will keep on updating this document based on later discussions.

This shouldn't require any changes to existing compiler or runtime, and can be built as a new script. So, while we slowly work on it, it shouldn't block us with any other tasks in hand.

Activity

  1. vishesh commented on Sep 12, 2017

    @vishesh
    MemberAuthor

    Shoot your ideas, and we can get a better picture on what this should look like. The above description will keep getting updated.

  2. jackfirth commented on Sep 12, 2017

    @jackfirth

    Is it possible to reuse raco pkg and raco setup for some of this? In particular, the install-collection, pre-install-collection, post-install-collection, and clean fields of info.rkt allow collections to control their installation with arbitrary scripts (see "Controlling raco setup with info.rkt"). Racketscript could provide a simple raco script-bundle command of some sort to consume installed Racketscript packages and produce bundled JS and other assets.

  3. vishesh commented on Sep 13, 2017

    @vishesh
    MemberAuthor

    @jackfirth I think we can use that. Hooks aroundsetup can compile Racket sources to JavaScript, and hence we don't have to recompile them for programs/packages that depend on them. I'm not sure if we can add hooks to raco make though, which is useful when making changes to existing code.

  4. jackfirth commented on Sep 13, 2017

    @jackfirth

    @vishesh Hooks around raco make sounds tough; that's fairly deep in the internals of racket's compilation model. Maybe a #lang racketscript/compile could generate a main submodule that compiles its dependencies to javascript? Or perhaps a DrRacket plugin that added a button to compile the currently opened module with racketscript would be better.

  5. vishesh commented on Sep 13, 2017

    @vishesh
    MemberAuthor

    Maybe a #lang racketscript/compile could generate a main submodule

    We still have to run this though right? As make doesn't actually evaluate module. But this sounds useful, as it can potentially allow users to have more say on how compilations should happen. In a way this is equivalent to having our own subcommand?

    DrRacket plugin that added a button

    DrRacket integration is definitely worth doing, but IMO is an add-on over last task.

  6. jackfirth commented on Sep 13, 2017

    @jackfirth

    We still have to run this though right? As make doesn't actually evaluate module. But this sounds useful, as it can potentially allow users to have more say on how compilations should happen. In a way this is equivalent to having our own subcommand?

    That was my thinking, yes. Alternatively, the compilation could happen at expansion time and use register-external-file to declare compilation dependencies on non-Racket files like Javascript sources. I've never worked with these internals of the compiler before though, so I don't know how well that would work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions