14:56
<jschoi>

There are vague future plans for object-literal decorators like @(d) { x: 0 }. So:

x |> @(d)
{ x: 0 }

…also needs to be future proofed with an early error. We presumably should do the same with array literals. (And tuple/record literals when they come.)

Blocks are fine.

x |> @(d)
{ 0 }

…only has one reasonable interpretation (as x |> @(d); { 0 }).

I don’t think there’s anything else on the expression level that might get decorated…Maybe identifiers? Right now there are only plans for parameter identifiers so maybe we also ban this too:

x |> @(d)
y

…or maybe ban any DecoratorList Expression immediately following |>.

15:01
<jschoi>
So the plan is to use a cover grammar ShortCircuitExpression |> CoverPipeBodyOrDecoratedExpression. PipeBody is the usual. DecoratedExpression is something like DecoratorList Expression. It’s an early error if DecoratedExpression covers CoverPipeBodyOrDecoratedExpression.
15:02
<nicolo-ribaudo>
I have heard about obejct property decorators, but never about decorators for the whole object. It can just be a function call?
15:02
<jschoi>
Not sure. Take a look at https://github.com/tc39/proposal-decorators/blob/master/EXTENSIONS.md#object-literal-and-property-decorators-and-annotations.
15:04
<pokute>
It feels a bit that pipeline is taking into account other possible proposals in a way that many other proposals don't.
15:04
<jschoi>
Since (if?) we’re going with @ as the topic reference, I think it’s reasonable to try to future proof against any potential future conflict with future decorator extensions.
15:05
<jschoi>
The only proposal that that pipe has to be careful about is decorators.
15:05
<pokute>
It though that we have to be careful about infix operators too.
15:05
<jschoi>
(…Well, I guess there’s the dataflow stuff in general. Like how pipe will not advance unless bind-this advances. But I’m talking about syntax only.)
15:06
<jschoi>
It though that we have to be careful about infix operators too.
I don’t think we have to be careful about future non-identifier infix operators. It’s future infix operators that have to be careful of pipe (or specifically of the @ topic). And those future proposals will be able to use some simple lookahead rules when they get proposed (https://github.com/tc39/proposal-pipeline-operator/issues/91#issuecomment-1085006912), and it should be fine.
15:08
<nicolo-ribaudo>
I wish we could just ban ASI after pipes
15:08
<nicolo-ribaudo>
If that would be enough
15:09
<jschoi>
I’ll think about if we can do that instead.
15:10
<jschoi>
But the problem isn’t that ASI is happening. It’s that developers might expect ASI to happen when it wouldn’t.
15:10
<jschoi>
x |> @(d)
class C {}

Here, ASI would not happen. It would be equivalent to:

x |> (@(d) class C {})

But a developer might expect ASI to happen, as if it were:

x |> @(d); class C {}
15:11
<nicolo-ribaudo>
Well, that's the same expectation in ``` a = b [c].map(f) ```
15:12
<nicolo-ribaudo>
If you use ASI, learn it and don't complain 🤷
15:12
<jschoi>
Yes, that is true, heh.
15:12
<jschoi>
But there is also future-proofing.
15:12
<jschoi>
x |> @(d)
{ a: 0 }
15:12
<jschoi>
ASI does happen…until object-literal decorators get added.
15:12
<nicolo-ribaudo>
We could ask to the other delegates if anyone feels like all those decorators extensions are a possibility on the future
15:14
<jschoi>
I think it’s reasonable to just ban PipeExpression : ShortCircuitExpression |> DecoratorList Expression.
Come to think of it, we probably don’t even need a cover grammar.
15:14
<nicolo-ribaudo>
That's a great idea
15:15
<pokute>
That's always a pipe token, never decorator (missing parens I think)
15:16
<jschoi>
I think it’s reasonable to just ban PipeExpression : ShortCircuitExpression |> DecoratorList Expression.
Come to think of it, we probably don’t even need a cover grammar.
PipeExpression :
  ShortCircuitExpression `|>` PipeBody
  ShortCircuitExpression `|>` DecoratorList [lookahead ∉ {`class`}] Expression

It is a Syntax Error if PipeBody covers DecoratorList class BindingIdentifier? ClassTail.
It is a Syntax Error if PipeExpression covers ShortCircuitExpression |> DecoratorList Expression.

15:17
<jschoi>
That's always a pipe token, never decorator (missing parens I think)
It is currently two statements because PipeBody will only parse up to a valid expression, and @d { a: 0 } is not a valid expression…until, in the future, they add object-literal decorators. Then @d { a: 0 } suddenly becomes a valid expression.
15:18
<pokute>
It is currently two statements because PipeBody will only parse up to a valid expression, and @d { a: 0 } is not a valid expression…until, in the future, they add object-literal decorators. Then @d { a: 0 } suddenly becomes a valid expression.
Aren't decorators illegal in pipe body unless inside parens?
15:19
<pokute>
Or did I just mess up everything in my mind? :-)
15:20
<jschoi>
Aren't decorators illegal in pipe body unless inside parens?

Right now, the plan is:

x |> @(foo) class { x = @ }

…is illegal.

x |> (@(foo) class { x = @ })

…is legal.

x |> (() => @(foo) class { x = @ })

…is legal.

x |> do { @(foo) class { x = @ }; }

…is legal.

15:20
<jschoi>
The plan is that, if PipeBody covers a decorated class, then it is an early error.
15:21
<jschoi>
But we also need to cover for future cases that are not yet covered by PipeBody because they are not yet valid expressions (like @(foo) function () {} or @(foo) { a: 0 }).
15:22
<jschoi>
And, as usual, developers should be discouraged from putting any decorators inside pipe bodies anyway…
15:24
<pokute>
I would expect that x |> (@(d) { a: 0 }) to be a minimal valid usage.
15:24
<pokute>
Could we expect that infix operators to always be in x infixOp y form and never in x (infixOp) y?
15:25
<jschoi>
I would expect that x |> (@(d) { a: 0 }) to be a minimal valid usage.
That would also be valid.
15:25
<pokute>
Parens aren't really needed since you shouldn't ever use expressions as infix operators (IMO)
15:26
<jschoi>
Could we expect that infix operators to always be in x infixOp y form and never in x (infixOp) y?
Even if we added an infixOp (where infixOp is already a valid identifier), then we could just ban @ infixOp operand.
15:27
<jschoi>
Or, rather, we would make @ infixOp operand always mean a decorated operand, not “topic infixOp operand”.
15:32
<ljharb>
It feels a bit that pipeline is taking into account other possible proposals in a way that many other proposals don't.
every proposal should, and I’m not aware of any that knowingly don’t
15:32
<pokute>
Ok, here's another wild scenario that I haven't seen mentioned yet: class foo extends Date |> (@dateDecorator(@)) { ... }
15:33
<jschoi>
~~That should just be class foo extends (Date |> (dateDecorator(@))) { … }, unless I’m missing something.~~ I misread this example.
15:33
<pokute>
Should this be possible, any problems?
15:37
<pokute>
I've seen at least one person who's really interested in using pipelines in extends part and I don't recall anyone discussing it yet. Now when using @ topic token, it would be better to probe if anyone can spot any problems arising due to decorators with it.
15:39
<jschoi>
I don’t think it should be a problem at all, but let us know if you find one.
15:42
<pokute>
Actually, I think it probably is just impossible. I don't think Date |> (@dateDecorator(@)) is valid anyway.
15:42
<jschoi>
Oh wait, I misread your original example.
15:42
<jschoi>
Yes, that is not valid.
15:42
<pokute>
Maybe Date |> dateDecorator(@) is
15:42
<jschoi>
Because @dateDecorator(Date) is not an expression; it is a decorator.
15:43
<jschoi>
You would want @(Date |> dateDecorator(@)).
15:48
<pokute>
One possible partial solution would be to never allow decorator extensions proposals from using @decoratorFun <thing> for anything where decoratorFun(<thing>) works as ergonomically.
15:48
<pokute>
<thing> that wouldn't support @decoratorFun could include object literal likes, arraylikes and functions.
15:50
<pokute>
While code blocks & do expressions would support @decoratorFun { return 0; }
15:51
<pokute>
It might be that @decoratorFun class ... is already a precedent that makes this difficult.
15:59
<pokute>
🚎 Maybe we could've forgotten the prefix decorators alltogether and instead have class A { function b() {} |@> methodDecorator } |@> classDecorator, but I guess we're too late.
16:03
<pokute>
Alarmingly, it's starting to make more and more sense to me.
16:46
<jschoi>
FYI: https://github.com/tc39/proposal-pipeline-operator/pull/268
16:50
<rbuckton (OOF thru Apr. 1st)>
One possible partial solution would be to never allow decorator extensions proposals from using @decoratorFun <thing> for anything where decoratorFun(<thing>) works as ergonomically.
@dec and @dec() aren't synonymous. The 1st is a decorator, the 2nd is a decorator factory
16:52
<rbuckton (OOF thru Apr. 1st)>
🚎 Maybe we could've forgotten the prefix decorators alltogether and instead have class A { function b() {} |@> methodDecorator } |@> classDecorator, but I guess we're too late.
Please no
16:56
<rbuckton (OOF thru Apr. 1st)>
<thing> that wouldn't support @decoratorFun could include object literal likes, arraylikes and functions.
Definitely want functions to work in the future. We spent multiple plenary meetings discussing the possibility of decorating many other things as well. I'd rather not have pipeline derail decorators, and I'm more and more concerned that using @ is a very future hostile hazard considering the very valid use cases for decorated functions, structs, and enums (assuming the latter two also end up with expression forms), plus any other future syntax.
16:57
<rbuckton (OOF thru Apr. 1st)>
This is making me less and less convinced that @ is viable every time I think about it. It feels like we're cooking up future hazards for the convenience of a single character token. I'd rather see pipeline use @@ or ## than have this hazard
17:01
<pokute>
@dec and @dec() aren't synonymous. The 1st is a decorator, the 2nd is a decorator factory
The latter example, decoratorfun(<thing>) was missing @ deliberately. Admittedly I'm not sure if it would work the same during runtime for all those examples (object literals, functions) and whether engine implementors want to be sure that nothing can touch the intermediary form.
17:01
<jschoi>

Check the specification and see what you think. It has a bunch of future proofing that (hopefully) covers any possible decorator expression.

If you find a concerning example, then put it here and we’ll take a look.
Developers should not be putting decorators in pipes anyway.

17:02
<rbuckton (OOF thru Apr. 1st)>

Check the specification and see what you think. I think the future proofing should be okay.

If you find a concerning example, then put it here and we’ll take a look.
Developers should not be putting decorators in pipes anyway.

I agree, but it's not the intentional use of decorators in pipes I'm worried about, it's the unintentional use.
17:02
<rbuckton (OOF thru Apr. 1st)>
I'm in an airport now, I'll read through the spec tonight.
17:03
<jschoi>

The spec does also try to prevent unintentional use of decorators, making things like the following an early error:

// Syntax Error: Pipe body does not contain topic reference;
// pipe body cannot be unparenthesized decorated expression.
x |> @(foo)
{ x: 0 };

Thank you for looking!

17:14
<jschoi>
rbuckton (OOF thru Apr. 1st): FYI, I just found a typo in the pull request; just force pushed, so go refresh in case you’re looking at it already.
17:16
<rbuckton (OOF thru Apr. 1st)>
For Apr.1 you should announce the topic was changed to $#!+ to make it easier to see in a pipeline
17:16
<pokute>
This is making me less and less convinced that @ is viable every time I think about it. It feels like we're cooking up future hazards for the convenience of a single character token. I'd rather see pipeline use @@ or ## than have this hazard

For every imaginable hazard, we can list them and see if they can be mitigated. If they're all mitigated, then they wouldn't be hazards any more.

For this reason, I think the proponents of @ as a topic should try their best to discover those hazards, as with any proposal. For this, checking out every possible proposal / idea for conflicts that result in hazards is important. I don't think unpublished ideas/proposals nor unimaginable hazards should influence the decision - no proposal would advance with that kind of burden.

17:18
<rbuckton (OOF thru Apr. 1st)>

For every imaginable hazard, we can list them and see if they can be mitigated. If they're all mitigated, then they wouldn't be hazards any more.

For this reason, I think the proponents of @ as a topic should try their best to discover those hazards, as with any proposal. For this, checking out every possible proposal / idea for conflicts that result in hazards is important. I don't think unpublished ideas/proposals nor unimaginable hazards should influence the decision - no proposal would advance with that kind of burden.

Keep in mind Waldemar required grouped/auto-accessors to use a keyword so as not to pave over any other future id {} proposal in class bodies.
17:20
<jschoi>
For Apr.1 you should announce the topic was changed to $#!+ to make it easier to see in a pipeline

Announcing the new topic token:

𓀀

17:20
<rbuckton (OOF thru Apr. 1st)>
JS already has limited syntax space because of ASI hazards, anything we can do to avoid eating up unnecessary real estate is important
17:20
<pokute>
I believe he, or anyone could come up with such possible conflicting proposals on the spot for that case.
17:25
<pokute>
For arguments against @, I would require it to practically be an extension (or usage) of decorators since it's the only other established proposal using @ and thus practically unable to use another symbol.
19:33
<jschoi>
A rendered version of the draft spec for everyone’s convenience.
21:58
<ljharb>
JS already has limited syntax space because of ASI hazards, anything we can do to avoid eating up unnecessary real estate is important
except we’ve previously decided not to let asi hazards block new features in the future, so while theyre best avoided it’s totally fine to add new ones