Skip to content
New issue

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

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

not operator #287

Closed
edemaine opened this issue Jan 24, 2023 · 17 comments · May be fixed by #548
Closed

not operator #287

edemaine opened this issue Jan 24, 2023 · 17 comments · May be fixed by #548
Labels
enhancement New feature or request

Comments

@edemaine
Copy link
Collaborator

Civet has and and or, but currently no not. It does have not in, not instanceof, etc., and not is now reserved.

It's probably time to add a not operator as shorthand for !.

@STRd6 wanted this to have different precedence than coffeeNot. Is it that not x == y parses as not (x == y) as in Python, as compared to (not x) == y in CoffeeScript? How should not x or y parse? I would guess (not x) or y. Trying to figure out the general rule...

@edemaine edemaine added the enhancement New feature or request label Jan 24, 2023
@STRd6
Copy link
Contributor

STRd6 commented Jan 24, 2023

I think it should bind tighter than |> and looser than just about everything else.

not a >>>> !a
not a === b >>>> !(a === b)
not a = b >>>> !(a = b)
not a or b >>>> !(a || b)
not a or not b >>>> !(a || !b)  *
list.map not& >>>> list.map($ => !$)
data
  |> not&
---
($=>!$)(data)

* marks the one that I think may be dubious.

@edemaine
Copy link
Collaborator Author

edemaine commented Jan 24, 2023

I think I figured out why I find this confusing. Currently:

  • and and && have the same precedence
  • or and || have the same precedence

...so it feels a little weird for not and ! to have different precedence.

But I think the fix is to change the precedence of and and or, to make them low as well! I just recalled that Perl does this. Having two levels of precedence lets you do neat things like this:

x || y and z || w >>>> (x || y) && (z || w)

I notice that Perl goes a little far: x = y or z parses as (x = y) or z. Maybe we don't want to go that far, but I think making and/or lower precedence than &&/|| would make me much happier about lowering not's precedence. (I think you want = to be added to your list with |> of lower precedence.)

I'd argue that not should be slightly higher precedence than and/or. Hence, if you stick to the same "type" of operator, you get intuitive (to me) relation between not/and/or:

!a || !b >>>> (!a) || (!b)
not a or not b >>>> (!a) || (!b)
not a || not b >>>> !(a || (!b))

What do you think? We'd need to turn this off for coffeeCompat.

@STRd6
Copy link
Contributor

STRd6 commented Jan 24, 2023

I think that having different precedence for word and symbol operators in fine/good. I also agree that it would be best to keep the precedence the same within groups (!, &&, ||) and (not, and, or).

But having and /or and &&/|| be exactly equivalent is nice too.

Interesting to think about... we might want to let this one stew for a while.

@GoToLoop
Copy link

Indeed, having and & or logical operators in but leaving not out is inconsistent.
Also Python folks would be confused if they couldn't find not while having and & or available.

Extending the subject further, I'd love other CoffeeScript keywords to officially return to Civet.
Like isnt, on, off, yes and no. ^_^

And to please Pythonists even more, elif as a shorthand for else if. 🐍

@edemaine
Copy link
Collaborator Author

Like isnt, on, off, yes and no. ^_^

is not is already available in base Civet, and the others are all available if you set "civet coffeeCompat" (or more specifically "civet coffeeIsnt" and "civet coffeeBooleans").

elif is an interesting idea... By default or hidden behind a compiler flag?

@GoToLoop
Copy link

GoToLoop commented Jan 24, 2023

Yea, that was my 1st Civet letdown that we'd need those "civet" flag thingies. 😿
What I'm hoping for is the official comeback of those CoffeeScript keywords to Civet as default. 🔑
We could make those keywords as opt-out flags instead of the current opt-in. 🙏

@STRd6
Copy link
Contributor

STRd6 commented Jan 24, 2023

I'm trying to be very judicious about adding to the number of reserved words. Each additional reserved word prevents existing code from moving to Civet without issue.

@edemaine
Copy link
Collaborator Author

@GoToLoop Hopefully config files will mitigate your issue once #103 gets completed. I myself have my preference on which flags I want on and which I want off, and I suspect everyone's preference will differ slightly.

@GoToLoop
Copy link

GoToLoop commented Jan 24, 2023

Each additional reserved word prevents existing code from moving to Civet without issue.

  • Indeed keywords such as yes, isnt, off prevent them to be used as labels.
  • But I've never seen them as variable names anywhere in my whole life!
  • For such rare edge-cases when a file needs to use any of them as regular labels, an opt-out flag would turn them off.
  • In my defense to have them as actual Civet keywords is, as I understand, this language provides lots of shorthands already.
  • So why not keeping those already existing CoffeeScript keywords as Civet keywords too, given they had never been an issue on CoffeeScript AFAIK.

@edemaine
Copy link
Collaborator Author

FWIW, I believe on/off/yes/no come from YAML originally. They might make sense if we add more YAML features to make most YAML a subset of Civet.

I don't see why one would prefer isnt (which looks like a misspelling) over is not... but to each their own, of course.

@GoToLoop
Copy link

isnt as shorthand for is not is similar to elif in place of else if. :D

@edemaine
Copy link
Collaborator Author

edemaine commented Feb 20, 2023

Back to not/and/or vs. !/&&/|| precedence, some more prior art (beyond Perl) is that LiveScript gives such low precedence to and/or/xor that they close implicit calls:

even 0 and 3      even(0) && 3
even 0 &&  3      even(0 && 3)

It looks like Ruby also agrees on not/and/or being lower precedence than !/&&/||. It even puts not/and/or below assignment and x? null checking.

CoffeeScript seems to be the odd one out in making them aliases (at the lexer level) so identical precedence.

At this point I'd lean toward not/and/or being lower precedence than !/&&/|| (we'll have to decide exactly where), but coffee-precedence (or a better name?) / coffee-compat restores the CoffeeScript precedence.

The one downside is that this complicates the grammar... Related question: what precedence do custom operators have? Once there are two possible answers for binary operators, it's less clear... 😦

@edemaine
Copy link
Collaborator Author

edemaine commented Jun 4, 2023

  • Indeed keywords such as yes, isnt, off prevent them to be used as labels.
  • But I've never seen them as variable names anywhere in my whole life!

In fact off is a pretty common variable name, sometimes short for offset. GitHub search reveals ~53,000 instances. on has over 42,000 occurrences. isnt is indeed rare at 190 instances, though it's apparently the name of an NPM package so it's not a crazy variable name.

P.S. not, and, and or are surprisingly common too, at 24,700, 11,000, and 14,900 occurrences. Sadly this code will be harder to port.

The lack of not is getting pretty surprising; coffeeNot is now the first Civet flag I reach for (and sometimes the only). So I'm going to try to implement the above two-different-precedences plan (word operators lower precedence than symbols, unless you specify coffeeCompat). Let me know if you think we should instead stick to CoffeeScript's flat precedence as the only option.

@GoToLoop
Copy link

GoToLoop commented Jun 4, 2023

P.S. not, and, and or are surprisingly common too,

Well, for sure those happen in languages that don't have them as reserved keywords, right?

Civet is closely related to CoffeeScript, Python, Ruby.

Any programmer writing code for a Python-related language would already know they can't use those labels.

Idem for CoffeeScript. Once the compiler warns a programmer they can't use a reserved keyword as a label, such as off or yes, they'll just rename the variable.

@edemaine
Copy link
Collaborator Author

edemaine commented Jun 4, 2023

Any programmer writing code for a Python-related language would already know they can't use those labels.

Right, so and/or/not are not that surprising as keywords. on/off/yes/no are, unless you come specifically from CoffeeScript (or YAML). I think we should just agree to disagree on this, as we already have coffeeBooleans to satisfy those who want them.

elif could probably be a similar flag extension, although I note only 99 occurrences throughout GitHub, and we could make it a soft keyword (activating only after an if block), so maybe it's worth adding to core. @GoToLoop Do you want to open a separate issue for it, so this thread can get back to not?

edemaine added a commit that referenced this issue Jun 4, 2023
* New "low-predecence" operators `and`/`or`/`not` via parse tree and
  parenthesization, effectively just below `&&`/`||`/`!`
* Implement `not` in all cases (fixes #287)
* New `coffeeAndOr` restores CoffeeScript's precedence for `and`/or`
  (same as `&&`/`||`)
* Old `coffeeNot` restores CoffeeScript's precedence for `not`
  (same as `!`)
edemaine added a commit that referenced this issue Jun 4, 2023
* New "low-precedence" operators `and`/`or`/`not` via parse tree and
  parenthesization, effectively just below `&&`/`||`/`!`
* Implement `not` in all cases (fixes #287)
* New `coffeeAndOr` restores CoffeeScript's precedence for `and`/or`
  (same as `&&`/`||`)
* Old `coffeeNot` restores CoffeeScript's precedence for `not`
  (same as `!`)
edemaine added a commit that referenced this issue Jun 4, 2023
* New "low-precedence" operators `and`/`or`/`not` via parse tree and
  parenthesization, effectively just below `&&`/`||`/`!`
* Implement `not` in all cases (fixes #287)
* New `coffeeAndOr` restores CoffeeScript's precedence for `and`/`or`
  (same as `&&`/`||`)
* Old `coffeeNot` restores CoffeeScript's precedence for `not`
  (same as `!`)
@STRd6
Copy link
Contributor

STRd6 commented Aug 27, 2023

Is this closed by #557 ?

@edemaine
Copy link
Collaborator Author

Yes, unless we want to continue discussing lower-precedence and/or/not. But I guess we have #548 to track that. I'm also not super convinced separate precedence is that important...

@STRd6 STRd6 closed this as completed Aug 27, 2023
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants