Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend infix operators with instructions for the formatter. #6072

Open
wants to merge 1 commit into
base: infix-base
Choose a base branch
from

Conversation

cristianoc
Copy link
Collaborator

@cristianoc cristianoc commented Mar 14, 2023

This extends infix operators #6076 with instructions for the formatter.
The @@infix.add instruction tells the formatter to transform existing code, into code using infix operators.
The @@infix.remove instruction does the opposite: tells formatter to transform code written using infix operators, into code that does not use them.

Example of add:

let plus = (x, y) => x + y
let minus = (x, y) => x - y

@@infix.add(("馃榾", "plus"))
@@infix.add(("馃挬馃挬", "minus"))

let q = minus(plus(3, 4), 5)

reformats to

let plus = (x, y) => x + y
let minus = (x, y) => x - y

@@infix(("馃榾", "plus"))
@@infix(("馃挬馃挬", "minus"))

let q = 3 馃榾 4 馃挬馃挬 5

Example of .remove:

let plus = (x, y) => x + y
let minus = (x, y) => x - y

@@infix.remove(("馃榾", "plus"))
@@infix.remove(("馃挬馃挬", "minus"))

let q = 3 馃榾 4 馃挬馃挬 5

reformats to

let plus = (x, y) => x + y
let minus = (x, y) => x - y

@@infix.remove(("馃榾", "plus"))
@@infix.remove(("馃挬馃挬", "minus"))

let q = minus(plus(3, 4), 5)

@fhammerschmidt
Copy link
Contributor

Looks great!

I would rather have a @@infix.reset (or similar) annotation to just disable all infixes again, though.

Also, are there any forbidden characters or a length restriction?

@glennsl
Copy link
Contributor

glennsl commented Mar 14, 2023

What would be the result in this case:

let plus = (x, y) => x + y
let minus = (x, y) => x - y

@@infix.add(("馃榾", "plus"))
@@infix.add(("馃榾", "minus"))
@@infix.remove(("馃榾", "minus"))

let q = 3 馃榾 4

or

let plus = (x, y) => x + y
let minus = (x, y) => x - y

@@infix.add(("馃榾", "plus"))
@@infix.add(("馃榾", "minus"))
@@infix.remove(("馃榾", "plus"))

let q = 3 馃榾 4

And would it be possible to use normal scoping rules instead of explicit remove declarations, e.g.:

let plus = (x, y) => x + y
let minus = (x, y) => x - y

%%infix(("馃榾", "plus"))

let x = {
  %%infix(("馃榾", "minus"))
  3 馃榾 4  // 3 - 4
}

let q = 3 馃榾 4 // 3 + 4

This feels much more natural to me in a functional language.

@cristianoc
Copy link
Collaborator Author

Looks great!

I would rather have a @@infix.reset (or similar) annotation to just disable all infixes again, though.

Also, are there any forbidden characters or a length restriction?

That's not what .remove does: it actively converts things back (on reformat), as opposed to just ignoring @@infix added earlier.

Btw the .xxx variants, which are purely instructions for the formatter, are kind of nice to play with, to know that it's possible to automatically convert existing code into- and out-of infix, but are not really an essential part.

@cristianoc
Copy link
Collaborator Author

Also, are there any forbidden characters or a length restriction?

Not right now, as an initial exploration. But one could be more prescriptive.

@cristianoc
Copy link
Collaborator Author

What would be the result in this case:

let plus = (x, y) => x + y
let minus = (x, y) => x - y

@@infix.add(("馃榾", "plus"))
@@infix.add(("馃榾", "minus"))
@@infix.remove(("馃榾", "minus"))

let q = 3 馃榾 4

or

let plus = (x, y) => x + y
let minus = (x, y) => x - y

@@infix.add(("馃榾", "plus"))
@@infix.add(("馃榾", "minus"))
@@infix.remove(("馃榾", "plus"))

let q = 3 馃榾 4

And would it be possible to use normal scoping rules instead of explicit remove declarations, e.g.:

let plus = (x, y) => x + y
let minus = (x, y) => x - y

%%infix(("馃榾", "plus"))

let x = {
  %%infix(("馃榾", "minus"))
  3 馃榾 4  // 3 - 4
}

let q = 3 馃榾 4 // 3 + 4

This feels much more natural to me in a functional language.

The result is pretty much undefined (whatever the quick implementation happens to be doing right now).

Adding scope makes sense. There's a state mechanism this inserts into, and that mechanism currently does not preserve scoping. That's pretty random and not intended, but wanted to check that there are no consequences to the existing mechanism first.

@cristianoc
Copy link
Collaborator Author

cristianoc commented Mar 14, 2023

So yes scoping makes sense. And .remove really is a different thing than closing a scope: it's an instruction for the formatter, to be executed once, rather than something that stays in the final code.

So perhaps I should remove .add and .remove from the description, as they mostly only cause confusion.

@cristianoc
Copy link
Collaborator Author

Added per-module scope.

@cristianoc cristianoc changed the base branch from master to infix-base March 15, 2023 12:57
@cristianoc
Copy link
Collaborator Author

Moving to a more basic PR without .add and .remove: #6076

Add support for `@@infix.add` and `@@infix.remove`.
@cristianoc cristianoc changed the title Proof of Concept: explore per-file custom infix operators. Extend infix operators with instructions for the formatter. Mar 15, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants