Token and parser concideration
aminpaks opened this issue · 9 comments
I'd like to introduce !
with ?.
as the tokens for this proposal.
Please bear with me if this sounds a bit silly as I'm just brainstorming with you.
IMHO, the chaining syntax becomes less human readable when it uses the same token to access array indices and call functions:
// Your proposal
obj?.arrayProperty?.[0];
If we'd separate the token usage to only access to properties:
obj?.zProperty?.aProperty;
and add a new must following token !
to access array indices and functions, it becomes more readable:
obj?.arrayProperty![0];
// roughly transpiles to
obj.arrayProperty == null ? undefined : (typeof obj.arrayProperty[Symbol.iterator] !== 'function' ? undefined : obj.arrayProperty[0]);
obj?.someFunc!();
// roughly transpiles to
obj.someFunc == null ? undefined : (typeof obj.someFunc !== 'function' ? undefined : obj.someFunc());
At this point there is only one case that I'm not sure how to solve it and that's functions in scoped/global variables. As the !
must be a following of ?.
this case makes less sense:
const { onChange } = this.props;
?.onChange!(); // No can't do? :(
// with ternary
true ? ?.onChange!() : null; // ?
Some more examples:
var obj = {
a: undefined,
b: () => undefined,
c: [undefined],
}
// optional-chaning
true ? obj?.a : null; // => undefined (property value)
true ? obj?.b : null; // => function
true ? obj?.c : null; // => [undefined] (Array)
true ? obj?.z : null; // => undefined
true ? obj?.z?.a : null; // => undefined
true ? obj?.a() : null; // => TypeError: a is not a function
true ? obj?.a!() : null; // => undefined
true ? obj?.b!() : null; // => undefined (function result) and should be equal with ?&.b()
true ? obj?.c[0] : null; // => undefined (first element of Array)
true ? obj?.z[0] : null; // => TypeError: Cannot read property '0' of undefined
true ? obj?.z![0] : null; // => undefined
true ? obj?.z?.a!() : null; // => undefined
true ? obj?.z?.a![0] : null; // => undefined
// Global variables
var func = () => 'func-return-value';
true ? window?.func() : null; // => 'func-return-value'
true ? window?.notDefined() : null; // => TypeError: notDefined is not a function
true ? window?.notDefined!() : null; // => undefined
// Not allowed or may it's okay?
true ? ?.func() : null; // ?
// Also compatible with nullish-coalescing proposal
true ? obj?.func!() ?? 'value' : null; // => 'value'
Yup very similar, I'll leave it open cause there is a bit of difference (otherwise I'd close it.)
@aminpaks I don’t understand your proposal. For example, when I see obj?&.z![0]
, I’m wondering why you need both ?&
and !
. The current state of the proposal uses just one token ?.
as in: obj.z?.[0]
.
So..., please reformulate your proposal by explaining the semantics instead of expected results of particular examples. I think the simplest way to explain it is showing the desugaring:
obj.z?.[0] // obj.z == null ? undefined : obj.z[0]
@claudepache thanks for your feedback. I updated my initial proposal and changed some stuff. Hope that's okay with you as I'm organizing my thoughts as I'm learning more...
I wonder if the use of an exclamation point here might interfere with some recently introduced typescript features in 2.7...
I do like how the bang plays out with arrays and functions...but syntactically, it might conflict with existing language features of TS, which might very well be viable proposals to ES in the future...
syntactically, it might conflict with existing language features of TS
I hear you, I was just trying to suggest a better syntax for more readability. For sure this conflicts with current existing TS code as !
is ignoring of null values purposely (I just remembered.)
What I proposed is not really solid, but we might come up with a better solution with brainstorming.
I do like the chain of thought here, for sure. I am intrigued by your use of !, and the way you described the outcomes. That's the reason for these proposals. :)
AFAIK there are 2 main usages of !
:
- negation (javascript)
- beware (e.g. mutation in ruby)
Negation is orthogonal to the notion of optionality/uncertainty that is evoked by ?
. For that reason I cannot support !
as an alternative token.
It could be other characters for that use case. The idea is To use .?
only to access property