stdlib-js / stdlib-js/stdlib

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

Abierto
#2,066 0 comentarios 0 reacciones 0 asignados Ver en GitHub
difficulty: 4 Enhancement JavaScript Needs Discussion priority: Normal REPL RFC
Lenguaje dominante
JavaScript
Estrellas
6k
Forks
1.3k
Merge medio
1 d 3 h
PR fusionados (30 d)
611

Descripción

### 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

- Magic support in IPython: https://ipython.readthedocs.io/en/stable/interactive/magics.html?highlight=magic#magic-macro
- C style macros:
- https://gcc.gnu.org/onlinedocs/gcc-2.95.3/cpp_1.html#SEC10
- https://gcc.gnu.org/onlinedocs/cppinternals/Macro-Expansion.html

### Checklist

- [X] I have read and understood the [Code of Conduct](https://github.com/stdlib-js/stdlib/blob/develop/CODE_OF_CONDUCT.md).
- [X] Searched for existing issues and pull requests.
- [X] The issue name begins with `RFC:`.

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.