Strict Relational Operators
Jordan Harband
ljharb at gmail.com
Fri Apr 14 00:15:14 UTC 2017
Perhaps a simpler approach (short of type systems) would be a single binary
operator that returned true only when the Type() of each operand was the
same?
In other words (using "=@=@=" to avoid bikeshedding on the syntax itself):
`a =@=@= b` would be equivalent to `(a === null || b === null) ? (a ===
null && b === null) : typeof a === typeof b` - then you could use the
operator to explicitly guard any comparison operators where you wanted the
type to be the same, and throw, return false, or coerce to your heart's
content.
On Thu, Apr 13, 2017 at 5:35 AM, James Treworgy <jamietre at gmail.com> wrote:
> That would seem to make more sense. At the end of the day, for me, I just
> don't much value in adding new syntax for operators to do this. The only
> time I can think of in my own code where this would be useful (in the sense
> that it would have avoided some extra type check to ensure things work as I
> want) is evaluating >= 0, where the current Javascript behavior is
> unfortunate:
>
> *null >= 0 // true*
> *undefined >= 0 // false*
>
> But for most situations, it doesn't help much, you still need to do a
> manual type check to avoid unexpected behavior. If I'm comparing a counter
> to a limit, a loop might just run forever. If I'm comparing one thing to
> another for sorting, it just puts all non-typed things first. The behavior
> of many things will be different, but unlikely better. It doesn't help you
> write code that avoids unwanted code paths.
>
> I also feel like the problem of "are a and b of the same type, and is a
> greater than/less than b" is very easily solved with a helper:
>
>
> *if (strict.gt <http://strict.gt>(a, v)) { }*
> *if (strict.lt <http://strict.lt>(a, b)) { }*
>
> What we REALLY need is runtime type checking. I write lots of code like
> this (or using helpers to accomplish the same with less boilerplate) in
> public APIs:
>
> *function(a, b) {*
> * assert.ok(typeof a === 'number')*
> * assert.ok(typeof b === 'string')*
> * ...*
> *}*
>
> I don't see why we can't have a flow-like syntax that is syntactic sugar
> for this:
>
> *function(a: string, b: number) {*
> * let c: string[] = [a, 'foo']*
> *}*
>
> Yeah - different discussion - but I feel like addding indirect ways to
> check types with new expression or operator syntax, rather than just
> addressing the problem head-on by allowing runtime type checking at
> variable declaration & function invocation time, is just going to further
> confuse matters and make code quality and readibility worse, not better.
>
>
>
>
>
>
> On Thu, Apr 13, 2017 at 8:04 AM, T.J. Crowder <
> tj.crowder at farsightsoftware.com> wrote:
>
>> Yeah. I suggested that if we aren't doing symbolic operators but rather
>> functions or something else, they should result in `undefined` for mixed
>> types, so you can differentiate if appropriate. (Symbolic operators like
>> `<=<` would need to be consistent with `===` and `!==`, though, which
>> don't, sadly, do that; and that won't be changing. :-) ) Functions or
>> non-symbolic operators would have the option of doing that, or throwing,
>> whatever people end up thinking is best.
>>
>> -- T.J. Crowder
>>
>> On Thu, Apr 13, 2017 at 12:41 PM, James Treworgy <jamietre at gmail.com>
>> wrote:
>>
>>> Put another way === is useful because you test for strict equality.
>>> Either it is or is not what you need. But always returning false when
>>> comparing things with less than or greater than doesn't ensure that you got
>>> what you want. A false value can be success as much as a true value.
>>>
>>> On Apr 13, 2017 7:37 AM, "James Treworgy" <jamietre at gmail.com> wrote:
>>>
>>>> Strict expressions. In the case of always returning false, that seems
>>>> like little help in avoiding bugs to me, since code flow always continues...
>>>>
>>>> On Apr 13, 2017 7:35 AM, "T.J. Crowder" <tj.crowder at farsightsoftware.c
>>>> om> wrote:
>>>>
>>>>> James, are you commenting on felix's idea of strict expressions (in
>>>>> which case, I suggest the other thread: https://esdiscuss.org/topic/st
>>>>> rict-non-coercing-expressions), or strict relational operators?
>>>>>
>>>>> Other than felix's strict expressions, I don't think anyone was
>>>>> suggesting that strict relational operators should throw. It would be
>>>>> important that they behave consistently with `===` and `!==`: Just result
>>>>> in `false` when the types don't match.
>>>>>
>>>>> -- T.J. Crowder
>>>>>
>>>>>
>>>>> On Thu, Apr 13, 2017 at 12:29 PM, James Treworgy <jamietre at gmail.com>
>>>>> wrote:
>>>>>
>>>>>> I am of the opinion that this isn't really a worthwhile effort in the
>>>>>> context of a non-typed language. There are several issues.
>>>>>>
>>>>>> First, it doesn't actually create any parity with ===. Triple equals
>>>>>> never throws an error, it just returns false if the types are unequal.
>>>>>> These constructs would change the way the language works fundamentally in
>>>>>> that an expression can cause an error which it currently cannot.
>>>>>>
>>>>>> Second, it really just provides a kind of "too late" poor man's type
>>>>>> checking. What you really wanted was a guard when the variable was created
>>>>>> or the argument passed. It may provide little help about the actual source
>>>>>> of the bug.
>>>>>>
>>>>>> New syntax and the complexity it creates seems a high price to pay
>>>>>> for a little band aid.
>>>>>>
>>>>>> If we were going to add some simple syntax to try to help this
>>>>>> problem without going full typescript/flow then I'd be much more in favor
>>>>>> of simply adding type guard clauses to function arguments that are
>>>>>> evaluated at runtime.
>>>>>>
>>>>>>
>>>>>> On Apr 13, 2017 2:44 AM, "T.J. Crowder" <
>>>>>> tj.crowder at farsightsoftware.com> wrote:
>>>>>>
>>>>>>> I've started a separate thread to discuss felix's idea of an
>>>>>>> expression mode making all operators within it non-coercing (as it's rather
>>>>>>> more broad than this topic): https://esdiscuss.org/topic/st
>>>>>>> rict-non-coercing-expressions
>>>>>>>
>>>>>>> -- T.J. Crowder
>>>>>>>
>>>>>>>
>>>>>>> On Thu, Apr 13, 2017 at 6:58 AM, Darien Valentine <
>>>>>>> valentinium at gmail.com> wrote:
>>>>>>>
>>>>>>>> > It's reasonable for non-coercing === to work on different types,
>>>>>>>> but what would a non-coercing + do with different types? It has to
>>>>>>>> throw an error.
>>>>>>>>
>>>>>>>> Ah, didn’t catch that you were talking about non-relational
>>>>>>>> operators as well. Assuming a strict `+` was still overloaded for string
>>>>>>>> concatenation, yeah, an error makes sense (whereas if numeric only, NaN
>>>>>>>> might also be considered a reasonable answer).
>>>>>>>>
>>>>>>>> For strict `<`, etc, I think it would be unintuitive to get an
>>>>>>>> error or to have arbitrary type order. Rather I’d expect it to be false
>>>>>>>> when the types didn’t match, since, for example, the correct answer to both
>>>>>>>> the questions "is seven greater than an object?" and "is an object greater
>>>>>>>> than 7?" is "no". This would be consistent with the behavior of the
>>>>>>>> existing always-incomparable value, NaN, as well. That said, I think an
>>>>>>>> error would be better than having an arbitrary type order if those were the
>>>>>>>> two choices.
>>>>>>>>
>>>>>>>> On Thu, Apr 13, 2017 at 12:56 AM, felix <felix8a at gmail.com> wrote:
>>>>>>>>
>>>>>>>>> On Wed, Apr 12, 2017 at 7:23 PM, Darien Valentine <
>>>>>>>>> valentinium at gmail.com> wrote:
>>>>>>>>> >> One common JS problem is NaNs ending up in unexpected places,
>>>>>>>>> and it's
>>>>>>>>> >> often difficult to trace back where they came from. Getting a
>>>>>>>>> type error
>>>>>>>>> >> instead of a NaN would be nice.
>>>>>>>>> >
>>>>>>>>> > I’m not sure this would help with that. NaN may be the product
>>>>>>>>> of coercion,
>>>>>>>>> > but NaN itself is a numeric value, and it can be produced
>>>>>>>>> without any type
>>>>>>>>> > coercion, e.g. `Infinity/Infinity`, `(-1) ** 0.5`, etc. And the
>>>>>>>>> `===`
>>>>>>>>> > operator is a strict, non-coercive comparison, but that doesn’t
>>>>>>>>> mean it
>>>>>>>>> > throws type errors.
>>>>>>>>>
>>>>>>>>> Mysterious NaNs in js are usually due to implicit conversion of
>>>>>>>>> random
>>>>>>>>> objects to numbers, not normal numeric computation.
>>>>>>>>>
>>>>>>>>> It's reasonable for non-coercing === to work on different types,
>>>>>>>>> but
>>>>>>>>> what would a non-coercing + do with different types? It has to
>>>>>>>>> throw
>>>>>>>>> an error.
>>>>>>>>>
>>>>>>>>> Non-coercing < might throw an error or use some arbitrary ordering
>>>>>>>>> of
>>>>>>>>> types. I don't have strong feelings about that.
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> _______________________________________________
>>>>>>>> es-discuss mailing list
>>>>>>>> es-discuss at mozilla.org
>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss
>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>> _______________________________________________
>>>>>>> es-discuss mailing list
>>>>>>> es-discuss at mozilla.org
>>>>>>> https://mail.mozilla.org/listinfo/es-discuss
>>>>>>>
>>>>>>>
>>>>>
>>
>
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20170413/279c61ce/attachment-0001.html>
More information about the es-discuss
mailing list