JoeStrout / miniscript

source code of both C# and C++ implementations of the MiniScript scripting language
MIT License
275 stars 64 forks source link

Brackets could be dropped when `not` is continuously used #147

Closed Withered-Flower-0422 closed 1 month ago

Withered-Flower-0422 commented 5 months ago

Currently, not can't be used continuously:

]not not 1
Compiler Error: got Keyword(not) where number, string, or identifier
 is required [line 1]
]

As not is not a function after all, I prefer things like not not 1 should work, where the brackets could be dropped. See on Discord.

JoeStrout commented 5 months ago

Brackets (parentheses) have nothing to do with it; all they do is make an expression in place of an operator.

The question is, why would not not (as direct operators) ever not be a mistake?

You can't do - - 3 either. This is the exact same thing.

Withered-Flower-0422 commented 5 months ago

not not won't result in any confusions, because not only requires one parameter. Even without parentheses, not not 1 is clear enough to yield a certain value 1. While - requires 2 parameters normally, so parentheses must be here to distinguish - - 3 from - 0 - 3 between - (0 - 3). Anyway it is worth discussing in language-lawyers.

JoeStrout commented 5 months ago

Well then, @@x would be another analogy — in all three cases, we have a unary operator which you are trying to use twice in a row.

What is the use case for this?

Withered-Flower-0422 commented 5 months ago

not not can easily boolean a data. I can do things like a = [42, 43][not not x] rather than if x then a = 43 else a = 42, which is simpler.

Armen138 commented 1 month ago

this is a common way in JavaScript to turn a "truthy" value into a proper boolean

!!"1" === true

JoeStrout commented 1 month ago

Yeah, that doesn't really help here though, first because we don't have ===, and second because truthiness is more nuanced in MiniScript than in most languages.

If x is a number between 0 and 1, then not (not x) returns the same number. It does force it to be 1 (true) or 0 (false) as @Withered-Flower-0422 seems to believe.

If x is a number outside the 0-1 range, then not (not x) does indeed clamp it to this range. And if it's some other datatype, like a string or a list or whatever, then it also works to convert that to 0 or 1. However it seems to me a fairly obtuse way to do it — I would be confused as the reader of the code when I saw this. Something like this would be much clearer:

// utility functions
iff = function(condition, trueValue, falseValue)            
   if condition then return trueValue else return falseValue
end function

// ...later code...
a = iff(x, 43, 42)

...or just the standard if x then this else that pattern.

In cases where you really do mean to use not twice in a row, for whatever reason, I think having to include the parentheses makes it clearer that this was intentional and not just a copy/paste error.