stdlib-js/stdlib

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

Opened this issue · 0 comments

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:.