Powershell: Tokenisation should not respect operator rules in command parsing mode

Created on 13 Aug 2020  路  16Comments  路  Source: PowerShell/PowerShell

Summary of the new feature/enhancement


The following command should produce three tokens rather than one:

CMD$( )

Proposed technical implementation details (optional)


Actual result: command CMD$( ) not found.
Expected result: command CMD$ not found.
It is confusing when tokenisation rules related to constructs unsupported in the current parsing mode are applied.
In other words: Does $( ) mean anything here? No, it does not. So why is it even a thing? 馃

Issue-Enhancement Resolution-Answered

Most helpful comment

I believe this parser is complex enough to have a lot of such deviations. We have to start with real scenarios that don't work. For example this may have changed for a new DSL that uses this style.
Otherwise it makes sense to add "fixes" with high risk to break something.

All 16 comments

Have you a script example where it raises a problem?

That would require a valid command ending with $ in the name. I do not know any such command.

You could rename an exe.

'ECHO %1' | OUT-FILE CMD$.CMD
ECHO(0)
./CMD$(0)

I renamed an exe in cmd$(0) and this works for me.

The command should call cmd$ of 0.

While I don't disagree that it probably shouldn't have been parsed like that originally, I don't really see the point in changing it now because:

  1. The FunctionName(args) syntax is pretty heavily recommended against, so fixing that syntax for commands that happen to end in $ isn't really worth pursuing
  2. function cmd$(0) { } is valid syntax, so changing it now is a break. Even if not super likely

Your 2. is irrelevant to the case. I would appreciate a source for 1.

Your 2. is irrelevant to the case.

Please add more details when trying to refute a statement. Just telling me I'm wrong without explaining why doesn't actually move the conversation along.

I would appreciate a source for 1.

A source for what? I didn't say it was officially deprecated. Tbh no really talks about the syntax because it's incredibly limited. You can only pass at most a single array as args, and you can't even keep the syntax when there are no args. Also strict mode explicitly throws if you use that syntax for whatever that's worth.

Obviously if you like it no one is going to stop you from using it, but it doesn't make sense for the language to actively design around it more than it already has (which isn't really that much, it mostly works by accident).

Just telling me I'm wrong

I did not tell you you were wrong. I tried to say that this complaint is about what happens when you call a command, not when you define a function. I am sorry if that was not clear enough.

It makes sense for the language to actively design around treating $( ) as an affix token in a location when it is not interpreted as a subexpression operator. Not so much because you want your ( ) to work as because you want to maintain integrity and consistency of the syntax.

You can only pass at most a single array as args

echo(1,2)(3,4)

I tried to say that this complaint is about what happens when you call a command, not when you define a function. I am sorry if that was not clear enough.

Fair enough, no worries!

So what I was getting at is that it makes sense that if you can do:

function cmd$() { param($a) $a }

that you can do:

cmd$() 10

Not always true for sure, but it would be strange to allow that in the function definition and then fail when you try to call it.

It makes sense for the language to actively design around treating $( ) as an affix token in a location when it is not interpreted as a subexpression operator. Not so much because you want your ( ) to work as because you want to maintain integrity and consistency of the syntax.

Oh yeah I agree with you on that. I'd much rather they have not allowed it in the first place, but taking it away now doesn't really win much unfortunately. It's pretty much exclusively just a break with no upside aside from being a bit more technically correct you know?

You can only pass at most a single array as args

echo(1,2)(3,4)

I think we might be talking about different things here. Early on in PowerShell's history there was (and probably still is) some folks who used functions with a "method like" syntax e.g. Get-ChildItem('path') etc. I thought that's what you were going for in the OP but I see you were just talking generally about parsing rules.

It's pretty much exclusively _just_ a break with no upside aside from being a bit more technically correct

I shall reveal the upside as soon as this is fixed. It has to do with PSReadline.

We have enough trouble getting breaks with demonstrated useful outcomes through a review. The chances of a breaking change being made for an unspecified and undefined "benefit" is precisely zero.

I believe this parser is complex enough to have a lot of such deviations. We have to start with real scenarios that don't work. For example this may have changed for a new DSL that uses this style.
Otherwise it makes sense to add "fixes" with high risk to break something.

This issue has been marked as answered and has not had any activity for 1 day. It has been closed for housekeeping purposes.

Was this page helpful?
0 / 5 - 0 ratings