Skip to content

[RFC]: add support for defining and using macros in the REPL #2066

Open

Description

Description

This RFC proposes adding macro support in the REPL. To allow users to define macros, we could add a command having the following signature:

macro( name, body )

where

  • name: macro name (e.g., FOR) and may include named parameters
  • body: macro body

E.g.,

In [1]: macro( 'FOR', 'for ( let i = 0; i < 10; i++ ) {' );

would define a macro for define the conditions of a for loop. To use, a user would type

In [2]: FOR

followed by ENTER in order to expand the macro. Note, in this proposal, hitting ENTER should not cause the macro body to execute; only for the macro to expand.

To parameterize the above macro, we could do

In [3]: macro( 'FORN(N)', 'for ( let i = 0; i < N; i++ ) {' );

where N is a macro parameter. To use,

In [4]: FORN( 100 )

would, after hitting ENTER, expand to

In [5]: for ( let i = 0; i < 100; i++ ) {<|>

where <|> is the cursor.

Related Issues

No.

Questions

  • Do we want to support recursive macro definitions? My guess is no, at least to start, as that makes things rather complex. It is doable, I suppose. Just keep performing macro substitution until one can no longer find macro definitions.

  • What should happen when a user embeds a MACRO among other expressions:

    In [1]: foo; FOR console.log( i ); }; beep
    

    Presumably, we'd need to check for the presence of macros BEFORE attempting to evaluate a line. If a macro is found, then we must expand and then the user needs to press ENTER again in order to execute.

  • Are there any built-in macros we'd want to support?

  • Longer term, we'd probably want to support allowing a user to define macros at REPL instantiation (e.g., through configuration or a startup file).

  • IPython also allows defining macros based on line number(s). Would we want to support something similar? This assumes that line numbers are displayed (i.e., that a user has not changed the input prompt). If we chose to support, would we support via a different API or overload the same API?

  • We'd want to be careful regarding substitution. For example, if a macro has a parameter N, we'd need to avoid replacing the N in fooNbar. This may be tricky to get right, so may be worth studying how C macro parameter substitution works and consider emulating. As another idea, we could support a macro string syntax similar to template strings or @stdlib/string/format, where there's a special markup for placeholders which should be replaced by provided arguments.

Other

Checklist

  • I have read and understood the Code of Conduct.
  • Searched for existing issues and pull requests.
  • The issue name begins with RFC:.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    EnhancementIssue or pull request for enhancing existing functionality.JavaScriptIssue involves or relates to JavaScript.Needs DiscussionNeeds further discussion.REPLIssue or pull request specific to the project REPL.RFCRequest for comments. Feature requests and proposed changes.difficulty: 4Likely to be moderately difficult.priority: NormalNormal priority concern or feature request.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions