Description
openedon Mar 27, 2024
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 parametersbody
: 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 infooNbar
. 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
- Magic support in IPython: https://ipython.readthedocs.io/en/stable/interactive/magics.html?highlight=magic#magic-macro
- C style macros:
Checklist
- I have read and understood the Code of Conduct.
- Searched for existing issues and pull requests.
- The issue name begins with
RFC:
.