Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bikeshedding the Hack topic token #91

Open
js-choi opened this issue Feb 4, 2018 · 749 comments
Open

Bikeshedding the Hack topic token #91

js-choi opened this issue Feb 4, 2018 · 749 comments
Labels
bikeshed Discussion about naming or similar

Comments

@js-choi
Copy link
Collaborator

js-choi commented Feb 4, 2018

This issue is for bikeshedding the spelling of the topic token in Hack pipes, branching off from #75 (comment). For more context, see the Hack pipes proposal and the wiki home page.

The table has its own editable page on the wiki. Please read this table first before contributing to this issue.

Please also keep discussion on topic: bikeshedding the topic token for Hack pipes. For other topics, search for other existing issues. Thank you!

Old obsolete questions

These currently are the most topical bikeshedding questions that I see now:

  1. What is the optimal tradeoff in writability (easily typed ASCII soup, e.g., ?, or easily typed privileged valid variable, e.g., $) versus readability (less easily inputted non-ASCII syntax, e.g., )?

  2. Related to question 2: Can non-ASCII Unicode syntax characters be considered for the pipe placeholder, or must they be categorically excluded?

    A list of all possible Pattern_Syntax Unicode characters is available.

  3. If question 3’s answer is that non-ASCII Unicode syntax may be excluded, which non-ASCII syntax character would be visually understandable and/or less difficuldif­fi­cultt?

    Many non-ASCII symbols are easily inputted in certain OSes. For instance, in macOS, several dozen typographic characters are directly typable using Option or Option + Shift (image of keyboards with various active modifier keys via Macworld article. It may be worth determining if there is an intersection of these easily typable non-ASCII characters across the default keyboard layouts of many OSes.

  4. For nullary operators vs. valid variable identifiers: How important is it that the placeholder be statically analyzable?

    A nullary operator can be always be statically recognized in the RHS. In contrast, a valid identifier can be statically recognized only if the rule is: “Tacit function calling may occur only when the RHS is a bare identifier, rather than allowing the RHS to be any arbitrary expression without a placeholder.”

  5. Operator vs. identifier again: How often would someone want to use an identifier from an outer lexical context of the same name as the pipe placeholder?

    If the placeholder is $, how often would a programmer want to use jQuery’s $ or another externally defined $ in a pipe’s RHS, as well as the pipe placeholder? How often would they be surprised if they could not, without defining a dummy variable for the outer $? How bad of a footgun (i.e., bug by programmer-unexpected behavior) would this be?

  6. How much should the pipe placeholder stay compatible with @rbuckton’s higher-order functional operators, which possibly would use {…}?

  7. @rbuckton proposed a partial-application placeholder that may be explainable by multiple topic placeholders. In other words, the pipeline syntax might be completely unifiable with the PA syntax with the right enhancements.

    Assuming a future shorthand “pipe-function operator” like +> (which would be an abbreviation for x=>x|>), then @rbuckton’s proposal’s f(?, 3) would instead be +> f(?, 3), which in turn would be shorthand for x=>x|> f(?, 3).

    Creating non-unary functions could be done
    by adding numbers to placeholders,
    such as ?0, ?1, ?2, etc.
    For instance, example.sort(+> ?0 - ?1)
    would mean example.sort((x, y) => x - y).
    (?0 would be equivalent to plain ?.)

    Which placeholders would have any problems with staying forward compatible with such a future proposal?

As of 2022-07-11, I like ^^ then more distantly $_, @@, %%, and #_.

@ljharb
Copy link
Member

ljharb commented Feb 4, 2018

There's a few choices that use ? but might avoid some of the confusion:

  • <?>
  • {?}

Also, I find ^^ confusing in that what it does is not related to what ^ does.

@aikeru
Copy link

aikeru commented Feb 4, 2018

FWIW, I really like ^^. I find it clever, and illustrative in that it points up, as though at the previous expression which is likely to be the LHS of the pipeline operator, reminding you where the value comes from.

@ljharb
Copy link
Member

ljharb commented Feb 4, 2018

Pipelines will be single-line just as often as multiline; so "points up" and "points at the previous" won't consistently be the same.

@littledan
Copy link
Member

I take it that, if we go down the Hack-style path, we're not trying for any kind of path for the placeholder to be subsumed by @rbuckton's partial application proposal, and therefore should avoid using the same token, is that right?

@gilbert
Copy link
Collaborator

gilbert commented Feb 4, 2018

My 2c: I personally really like $ as the placeholder variable binding. Because it's a valid identifier, it feels like an actual variable, which it certainly is (albiet smaller in scope). It also prevents the Hack-style proposal from claiming another operator that might be useful for future proposals.

I think the "jQuery problem" is probably overblown for these reasons:

  • How many libraries out there actually expose a global $? I would imagine very few.
  • The pipeline operator does not impede using these libraries. Rather, using these libraries impedes using the pipeline operator, which is not a big deal.
  • jQuery would hardly benefit from the pipeline operator anyway since it uses heavy method chaining.
  • If you're not using global scripts and using modules instead, then you can easily rename your import / require variable to something other than $.
  • _ would still available, and is much more commonly used for utility functions (lodash, underscore, rambda, etc.), although becoming less so due to static ES module imports.

@mAAdhaTTah
Copy link
Collaborator

Is it at all possible to use $ in the partial application proposal? If we're trying to leave open the door for a partial application proposal in the future, we could end up with two different syntaxes for partial application / placeholders, one inside pipelines and one outside.

@littledan
Copy link
Member

@mAAdhaTTah I don't think it's possible for partial application to use $ unless there's a token which is used to start off the partial application expression. The current partial application proposal does not have such a token.

@js-choi
Copy link
Collaborator Author

js-choi commented Feb 5, 2018

@littledan: I take it that, if we go down the Hack-style path, we're not trying for any kind of path for the placeholder to be subsumed by @rbuckton's partial application proposal, and therefore should avoid using the same token, is that right?

From what I could tell, syntactic partial application could use the same placeholder as Hack style iff syntactic partial application were forbidden in every placeholder-using pipe’s RHS. This could be a footgun—it creates a hidden context dependency between two very different results, which may cause the programmer to accidentally commit a mode error—but if we logically proceed anyway:

Proposal 2: Hack Style Only and Proposal 4: Smart Mix would forbid syntactic partial application in the RHS of all pipes—or, rather, the parser would always interpret the presence of a RHS placeholder as a pipe placeholder, not a partial-application placeholder. For instance, if |> is always a Hack pipe and ? is the placeholder for both |> and partial application, then f(?, 3) would be partial application, and x |> f(?, 3) would be f(x, 3).

Proposal 3: Split Mix would forbid syntactic partial application in the RHS of Hack pipes. It could also forbid it in the RHS of F-sharp pipes but it could also allow them. If |> is an F-sharp pipe, |: is a Hack pipe, and ? is the placeholder for both |: and partial application, then f(?, 3) would be partial application, x |> f(?, 3) would be f(?, 3)(x) (or it could be a syntax error), and x |: f(?, 3) would be f(x, 3).

If that analysis is correct, I’ll add it to the original post’s ? option. The problems of hidden contextual dependency—and of visual confusion with nullish coalescing and optional method chaining (assuming that syntactic partial application would stick with ?)—would remain.

@ljharb
Copy link
Member

ljharb commented Feb 5, 2018

I would be very opposed to using any valid identifier - including $. It is a very common pattern to do var $ = document.querySelectorAll as well, for example - it’s not just about globals.

Shadowing bindings is fine when users explicitly choose the identifier - it would not be ok with me that a magic implicit binding would appear that shadows my code just for using an operator.

@barneycarroll
Copy link

I prefer personally ?, but I think it's worth unpacking 'visually confusing'. I think the statement that it is visually confusing in relation to the two other stage 1 proposals is misleading — those statements are more visually confusing with each other and with the ternary operator than anything else. Even if both of those get through, the ? placeholder proposal should not be held back on their account.

The ambiguity only creeps in when placeholders are nested in further expressions — @gilbert's original example being a placeholder in a ternary expression: ? ? : foo. This is the kind of scenario where the other two stage 1 operator proposals become problematic, when ?? can be read as either an optional chain on the placeholder.

It's a truism that nested ASCII operations are difficult to parse, but I think the placeholder is a special case inasmuch as it already bears the application-space cognitive weight of a deferred value within a special lexical scope of a higher order operation (the pipeline). So the situation only becomes complicated when we allow that the placeholder be used as an operand within a further expression nested inside a pipeline. Might it be worth outlawing that particular condition? — that is to say, a placeholder must be standalone, invocable only with ( or , either side of it?

In passing, I am firmly against the idea that an otherwise valid generic reference (like _ or $) be special cased. There is a special kind of semantic ambiguity introduced in scenarios like that of this in class arrow methods, when lexical parsing rules change based on higher order context. To do that with something which is otherwise up to user semantics is by all accounts a really imposing proposal (I foresee eslint rules to try and retro-ban them to compensate for this, invalidating previously legitimate and self-explanatory code).

@stephaneraynaud
Copy link

stephaneraynaud commented Feb 5, 2018

What about parameters with a name ?
for example:

anArray
  |array> pickEveryN(array, 2)
  |array> array.filter(...)
  |filteredArray> makeQuery(filteredArray)
  |query> await readDB(query, config)
...

Then one could write something like this:

anArray
  |$> pickEveryN($, 2)
  |$> $.filter(...)
  |$> makeQuery($)
  |$> await readDB($, config)
...

I think this would improve code readability, as there may be a lot of transformations applied. If I want to read one particular line, I won't know what's passed to the function and what's for.

Other proposal, reuse arrow functions : [edit: actually, I noticed this is proposal 1]

anArray
  |> array => pickEveryN(array, 2)
  |> array => array.filter(...)
  |> filtered => makeQuery(filtered)
...

I like this proposal because it can be used with destructuring and stuff like this, while being readable.

There are probably a lot of issues with those proposals, but my main idea is that variables like "$" or "^^" lack of readability and are not really elegant (from my point of view).

@mAAdhaTTah
Copy link
Collaborator

Whichever token we choose is going have an effect on the placeholder syntax, either by producing two different placeholder syntaxes (which I'd prefer to avoid), by superseding the placeholder syntax (effectively killing it), or by forcing its hand (requiring it to use the same token). We should probably decide which approach we're taking and keep that in mind as we bikeshed the token for use in the pipeline.


@bisouduperou I think we ran into problems with a similar proposal for await, e.g. this:

x |$> pickEveryN($, 2)

could be parsed as:

x | ($ > pickEveryN($, 2))

@charmander
Copy link

Reusing arrow functions’ arrow works very well for most purposes, but not for await.

@aikeru
Copy link

aikeru commented Feb 5, 2018

Honestly I just really hope any form that has a placeholder variable of any shape or spelling gets adopted, because it adds tremendous power and flexibility to an operator that would otherwise be much more limited and constrained... Thanks for letting me add my 2c.

@js-choi
Copy link
Collaborator Author

js-choi commented Feb 6, 2018

In #84 (comment) I used a ## nullary operator as a pipe placeholder. It looks nice and it doesn’t mess up GitHub’s current JavaScript syntax highlighting, but it probably would be quite visually confusing with private fields, so I don’t actually think it’s a good idea, heh.

@gilbert
Copy link
Collaborator

gilbert commented Feb 7, 2018

Ok, if $ is too commonly used in user-land, then how about $$, like the actual Hack pipe operator?

@mAAdhaTTah
Copy link
Collaborator

@gilbert I was also thinking about $_ as another possibility.

@stephaneraynaud
Copy link

Let's try to not end up with smileys please $_$

@js-choi
Copy link
Collaborator Author

js-choi commented Feb 7, 2018

Ah, $_ brings back dormant memories of Perl…

For what it’s worth, Perl 6 actually turns Perl 5’s $_ into an impressively unified concept of a lexical “topic variable”, which may be lexically bound using a given block or a for block and which is implicitly used by many other types of statements, operators, and functions, making for rather pithy tacit code. Think of it like linguistic topics. And in general, Perl 6’s design (fun fact: they actually released 6.0 some time back) is worth checking out you want to dive into the heart of some ingeniously mad and madly ingenious PL design.

I am in no way suggesting that an implicit topic variable be a thing in JavaScript beyond Pipe Proposal 2/3/4, though it’s pretty fun to think about.

@ljharb
Copy link
Member

ljharb commented Feb 7, 2018

@gilbert tbqh, i very strongly would object to any valid identifier there - it’s not just about “commonly used” for me, it’s about “ever used”.

@gilbert
Copy link
Collaborator

gilbert commented Feb 7, 2018

@ljharb I think such a strong stance to take would make sense if $$ were made globally available, but here it's only on the right-hand side of a pipeline – a very small scope, of which a programmer consciously introduces by writing |> in the first place.

@ljharb
Copy link
Member

ljharb commented Feb 7, 2018

Magically introducing an implicit binding that shadows something defined in an outer scope is with-like behavior, and after we all worked so hard to remove with from strict mode, I’d think we’d be loath to reintroduce it.

@gilbert
Copy link
Collaborator

gilbert commented Feb 7, 2018

I agree it's implicit, but I would not equate to with. Yes we'd be loath to reintroduce with, but this is not remotely the same thing.

@rbuckton
Copy link
Collaborator

rbuckton commented Feb 7, 2018

PowerShell also uses $_ as a topic variable in a number of places:

// pipes
Get-Files | ForEach-Object { Out-Host $_ };

// catch blocks
try { ... }
catch [System.Exception] {
  Out-Host $_.Exception.GetType().FullName; 
}

// filters/functions
function Foo {
  begin { ... }
  process { Out-Host $_; }
  end { ... }
}

Of course, that's because every variable in PowerShell is prefixed with $...

@aikeru
Copy link

aikeru commented Feb 8, 2018

Ah, $_ brings back dormant memories of Perl…

PowerShell also uses $_ as a topic variable in a number of places:

FWIW, Ruby uses this too. If JS were to adopt $_ as a topic variable or something like it, there's lots of precedent.

@jridgewell
Copy link
Member

there's lots of precedent.

Node's also set precedent with _ being the last evaluated expression, but if it's defined in-scope it the variable you set it to.

@js-choi
Copy link
Collaborator Author

js-choi commented Feb 8, 2018

There is also Safari Web Inspector’s use of $1, $2, … to denote previously evaluated expressions in its console REPL, I suppose.

I used to be very against using a valid identifier for a pipe placeholder, but being reminded of Perl and Ruby made me realize that it might not be that weird. Then again, that there is an implicit binding at all in a Proposal-2,3,4 pipe is relatively unprecedented in ES. with was very bad especially because of its mucking up of static optimization, which Proposal-2,3,4 pipes do not have at all. But could using a valid identifier make static analysis of a pipe’s RHS—e.g., to determine whether there is no placeholder in the RHS—more difficult?

I plan to have my Babel plugin for Proposal 4 support configuration of what its placeholder is, to encourage experimentation (if its tokenization permits it). What its default placeholder should be, I don’t yet know. Maybe a non-ASCII placeholder by default might be interesting after all, haha.

@stephaneraynaud
Copy link

I don't think it's about weirdness but about origin. That you don't know about what an operator means is ok. You may don't know what "yield" or "await" means, because those are operators. But a valid identifier is, by default, a variable previously defined somewhere. By adding valid identifiers like "$_", you will need to ask yourself "am I in pipe ?" "does it come from pipe" "is it a global / simple variable?". I deeply encourage to avoid such (little) confusion.

While I personnally prefer meaningful placeholders ("$_" is as readable as "let thing = stuff()"), why not using @ as placeholder?

anArray
  |> pickEveryN(@, 2)
  |> @.filter(...)
  |> makeQuery(@)
  |> await readDB(@, config)
...

@Mado007
Copy link

Mado007 commented Mar 17, 2023

Which placeholders would have any problems with staying forward compatible with a future shorthand "pipe-function operator" like +>?
If a future shorthand "pipe-function operator" like +> were introduced, some placeholders might have problems staying forward compatible because they could conflict with the syntax of the new operator.

For example, if we use ? as a placeholder, it might cause conflicts with ? being used as a query parameter placeholder in some query languages. Similarly, if we use {} as a placeholder, it might conflict with the syntax of object literals or block statements in some programming languages.

On the other hand, if we use placeholders that are unlikely to conflict with other syntax, such as ^^, $, @@, %%, or #, they would have fewer problems staying forward compatible with a future shorthand "pipe-function operator" like +>.

Here's an example of using ^^ as a placeholder with a potential future shorthand "pipe-function operator" like +>:

const array = [1, 2, 3];

const result = array.sort(+> ^^0 - ^^1);

console.log(result); // Output: [3, 2, 1]

In this example, ^^ is used as the placeholder to represent the first and second parameters of the arrow function passed to sort(). If a shorthand "pipe-function operator" like +> were introduced in the future, we could use it instead of the arrow function like this:

const array = [1, 2, 3];

const result = array.sort(+> ^^0 - ^^1);

console.log(result); // Output: [3, 2, 1]

In this example, +> is used as the shorthand "pipe-function operator" to represent the arrow function passed to sort(). The ^^ placeholders are still compatible with this new syntax, and we get the same result as before.

@cronosmain
Copy link

cronosmain commented Mar 21, 2023

I believe that % is a great choice for a topic since it serves as a string placeholder in numerous programming languages. However, it can appear messy in some cases as it can be mistaken for the remainder operator (%).

To address this issue, I suggest using {%} instead of % to represent the topic. Here's an example code snippet:

'42' |> Number({%}) |> console.log('The answer is', {%})

By using {%} instead of %, you can avoid confusion and make your code more readable.

@Seiyial
Copy link

Seiyial commented Mar 21, 2023

@cronosmain I think it's an interesting suggestion, but I'm not sure if {%} is an effective replacement; while % is used in as a remainder operator, I think it's fair to say { } is used far more often as part of the object literal syntax, and I think our eyes may be trained to see { } as "this is an object containing..." (unless it's after => or a function ()). and because {x} is shorthand for { 'x': x }, my first reaction to {%} was that % is still the token and {%} is shorthand for { [%]: % }. This may become convoluted when we want to turn the piped value into an object or other stuff; we may create confusing syntax like:-

// assuming `getData()` returns a string `"foo"`
// without pipe
const x = getData()
const xMapped = { x }

// with pipe
// correct
const xMapped = getData() |> { {%} }
const xMapped = getData() |> { [{%}]: {%} }
// wrong
const xMapped = getData() |> { % }
const a = "one"
const b = "two"
"three" |> [{ a }, { b }, { % }].map((item) => Object.values(item)).flat() // ["one", "two", "t","h","r","e","e"]
"three" |> [{ a }, { b }, {{ % }}].map((item) => Object.values(item)).flat() // ["one", "two", "three"]

We may still find this a feasible tradeoff. Just wanted to point out some potential considerations 👍🏻

@Jonas-Seiler-Wave
Copy link

Critical mass might have already been reached for operators in js. Of the ASCII characters, only # and @ are not used already, but are set to be with the decorators and tuple/record proposals. Unfortunately the bitwise operators exist and $ and _ are valid identifiers, but these mistakes probably won't ever be remedied.

I think the disqualifications so far are too restrictive and in my opinion at least these ones should be reevaluated:

Token Disqualification reason
... ...
# #[0] is ambiguous with tuple literals.
@ Complex interactions with decorator syntax that may close off further extensions to decorator syntax.
:: Lack of support from any TC39 representative.
<?> ″″
>?< ″″
{?} ″″
(?) ″″
... ...

If nothing else works, maybe there needs to be effort put in to coordinate this proposal with the decorator and/or the tuple/record proposal to share the two remaining unused ASCII chars between at least three different special uses.

That, or just go the path of least resistance with something like ^^, it's not like that's unusable or particularly ugly.

Either way, at some point it simply won't be possible to add any features in need of new syntax without introducing either breaking changes or special parsing rules, so care must be taken to add the right features with the right syntax.

@ethanlal04
Copy link

ethanlal04 commented May 2, 2023

@Jonas-Seiler-Wave,

I think the decorators proposal is way too big to tamper with as it's heavily built into typescript frameworks like Lit, Angular, Stencil and Nest. Records and tuples tho, being only in stage 2, can be modified. Maybe this way?

const record = |{ x: 1, y: 2 }|
const tuple = |[1, 2, 3, 4]|

This leaves the # token, which I really like, available for usage. # being short for number, seems like a good placeholder for a value. Its also used to indicate randomness sometimes, which reflects its purpose as a variable.

As for the tokens containing ?, they're not bad but are a little too long to type productively. Personally, ^^ doesn't mean much to me. A ? or a # would make sense, but ^^ feels kinda odd in a codebase.

Anybody else up for #?

@shicks
Copy link

shicks commented May 5, 2023

I still significantly dislike eating up so much syntax space by making a single-character non-identifier token that essentially behaves exactly like an identifier. Trying to be forward-looking, I suspect we might come to regret such a choice when the next proposal for some future paradigm we can't imagine today is stymied because there's no good operator. I'll admit that such an ambiguous concern isn't a great reason to avoid any sort of syntax, but it's an argument to consider the (opportunity) cost-benefit tradeoff, which I ultimately don't believe is worth it in this case, when an identifier already has exactly the right behavior, if only we could see past a few minor (in my humble opinion - i.e. it doesn't break the web or anything, it just requires some care when refactoring) quibbles with co-opting an identifier.

But I've already said my piece there. The reason I'm responding now is to point out that R&T is effectively dead in the water at this point. It's not impossible that it might want to revive someday, but I wouldn't hold my breath. So it's possible that # is more available than it was a year ago. I think it's ill-advised, but it might not be blocked anymore.

@lozandier
Copy link

…It seems this thread has latently/inadvertently validated why a token-based pipeline operator isn't desired by a very meaningful amount of people–especially the existing JavaScript ecosystem–more than anything else in the first place.

Especially people who are familiar with the unix | operator and the concept of pipelining fundamentally (i.e. in math) in general as a functional composition operator.

I'm of the opinion these nuances that have to be explained using the pipeline operator with a token by default pales in comparison to its classical representation and existing usage in the JS ecosystem desired to be the default (explained favorably by me against the rebuttals of various TC39 members in #217) prior to the Hack-style proposal unceremoniously/abruptly becoming the path forward for this proposal.

Such a need to have a token to use the pipeline operator seemingly makes more sense to be associated with the partial application spec accounting for people who want to use pipeline operator to have the output of an expression on its left side not be passed as the first argument to a function passed on its right side. I'm of the strong opinion that such people are the minority among those who find the pipeline operator useful, that seems to be very much shared by others who have followed this proposal.

Such a pivot enables the pipeline operator to more align with its most commonly understood usage across multiple disciplines that it invaluably makes more simple and clearer method-chaining that is becoming increasingly important (#296).

Such a pivot would also realign the operator to have the core value proposition of an operand firmly established by other computational operators part of the language not be eccentrically being deviated from just because it involves functions: Make more tacit a computation involving two or more values or expressions than manually expressing the computation.

The reasons this is being deviated from for this operator I continue to be unconvinced of that also seems to be shared by most who have followed this proposal for years or want this operator to exist.

It seems this pursuit of an ideal topic token for the hack-style is adding questionable delays to addressing the core reasons this operator was desired and campaigned for by the JS ecosystems–use cases that do not need a topic token at all (being completely irrelevant).

@brad4d
Copy link

brad4d commented Jun 16, 2023

@lozandier I cannot figure out what concrete proposal you are making.

@shicks
Copy link

shicks commented Jun 16, 2023

@brad4d My understanding is that they're proposing we drop the Hack style pipes entirely and revisit the F# style, where the RHS of the pipe operator is just a function - this would obviate the need for a placeholder.

I have mixed feelings about this. On the one hand, I agree that this thread is evidence of the fact that this proposal has stalled because of the difficulty of getting agreement on a token. If the choice is between no pipes at all (because of lack of consensus) or F# style, I can see a point that going with F# style could still provide some significant benefit in light of recent trends toward top-level functions. And personally I have no immediate problem with the style. On the other hand, I think the efficiency issue is real, as pointed out in #217 issues. In order to use F#-style pipes, you need to curry your functions, and that's not something that any engines currently do efficiently. You'd also need to rethink a number of existing APIs (including Array.groupBy, as mentioned in #296) to be curried. It's possible that a new bind operator could come to the rescue here, and that VMs could skip the closures when they find pipe and bind used together. But depending on what the bind syntax looks like, it may also end up requiring a placeholder of its own, and it's a long road to standardization anyway.

Ultimately, I'd like to see this proposal move forward, and I'm open to the suggestion of revisiting F# style if it's the only viable option, but in the balance (consensus feasibility aside) I think the arguments for Hack style still win out.

@tabatkins
Copy link
Collaborator

The committee has explicitly rejected F#-style. It is not a viable option, and attempts to revive it will continue to be rejected, for reasons that are well-documented in this repository. The champions of the current proposal have not had the time to make another push for the current proposal, but it will happen in time.

@tabatkins
Copy link
Collaborator

And more directly for this topic: this is a thread about bikeshedding the topic token. Off-topic discussions will be hidden and/or deleted.

@severinraez
Copy link

severinraez commented Jul 3, 2023

Regarding ^^: Please note that ^ is a prefix key on Swiss (and I think German and French) keyboard layouts. We type ^, a to get â. To write ^^ reliably we need to type ^ four times (where only keystrokes 1 and 3 have a visual effect). Not the ergonomics I'd wish for :) 🚲 🏠

@jods4
Copy link

jods4 commented Jul 25, 2023

@severinraez that's incorrect, at least for Swiss-French keyboard (fr-CH), which I'm using (aka QWERTZ).

When the second keypress after ^ can't be accented, then the ^ is simply printed by itself.
So although pressing ^ then e results in ê; pressing ^ then q results in ^q.

Likewise, pressing ^ then ^ again results in ^^.

More precisely:

  • First press ^, nothing happens on screen. Input is waiting for 2nd character that would be accented with ^, e.g. a or i.
  • Second press ^, this can't combine with previous keypress so ^^ appears on screen.

@severinraez
Copy link

severinraez commented Jul 26, 2023

@jods4 interesting! The behavior seems to be dependent on the operating system. For de-CH, on Windows it's behaving exactly as you describe. On Ubuntu 23.04, it behaves as I described.

@jods4
Copy link

jods4 commented Jul 26, 2023

@severinraez right, I should have taken OS in consideration. I'm using Windows indeed.

@Akryum
Copy link

Akryum commented Aug 21, 2023

Fedora also needs four keypresses to type ^^

@nmn
Copy link

nmn commented Dec 11, 2023

Although ^^ is not going to be the choice due to Linux behaving the way it does, I checked macOS. When typing ^, it shows up immediately with a little blue line under it. If you type an a, e, or i, The ^ is replaced by a â. But if you type anything else, including a space or a ,, then the ^ character is left as-is and the next character is inserted after.

Looks like Linux is the only problematic OS for this.

@bhallstein
Copy link

bhallstein commented Dec 13, 2023

I'm curious if the following has been considered:

Current proposals/token discussions are of the form:
foobar |> `$ ${<TOKEN>}` |> console.log

A possible alternative:
foobar <KEYWORD> foo |> `$ ${foo}` |> console.log where foo is a coder-supplied identifier that is then used as the ‘token’.

For example (not evaluated these possibilities for robustness, but just to illustrate the idea & show this might read nicely):

  • foobar as foo |> `$ ${foo}`
  • foobar :: foo |> `$ ${foo}`

In my view giving the programmer control over the identifier would be a desirable goal. This discussion's long duration suggests that no single choice of token such as ^^ can please everyone. Also, the programmer then has an opportunity to choose an identifier that is reads nicely in context. (However, note this would be more tricky than choosing a regular variable identifier, as the meaning of the operand will change as it is passed through multiple |>s.)

@tomByrer
Copy link
Contributor

giving the programmer control over the identifier would be a desirable goal. This discussion's long duration suggests that no single choice of token such as ^^ can please everyone. Also, the programmer then has an opportunity to choose an identifier that is reads nicely in context.

I'm leaning towards of having a static identifier & not putting changing as part of the spec. Of course, someone could make their own library to have whatever tokens however they want.

IMHO 6 years is far too long to be bikeshedding anything; right now no one is getting any pipe spec into JS, instead of upsetting half of the folks & getting something out the door.

@kamoshi
Copy link

kamoshi commented Jan 8, 2024

Is choosing the topic token the only obstacle blocking this proposal from moving to stage 3?

@nmn
Copy link

nmn commented Jan 9, 2024

The "topic token" wasn't a blocker for the proposal at all from what I understand? I thought this is just us wasting time as the committee moves the proposal forward.

@zoodogood
Copy link

zoodogood commented Jan 27, 2024

What about a %` (or %') token - might that be a good option?

numeric |> %` % 5

I think this option is more visually appealing and, perhaps obvious, but this more difficult to write compare to:

numeric |> %% % 5

Edited:
Although it has no logic, the construct

5%`some string literal` // old code: can be wrong

is allowed in Javascript. A compatible option would be @`


When it comes to three-character tokens, my favorites are |%| or |^|

|^|[5] 
^^[5]

@mybearworld
Copy link

mybearworld commented Feb 3, 2024

If ` is at the end of the symbol for the topic, calling the topic as a tagged template function would look like this:

(...a) => a
 |> @```

In my view giving the programmer control over the identifier would be a desirable goal.

Not having to come up with new names for every substep is a big plus of having pipe expressions - so ideally, the programmer wouldn't have to choose a name.

@tabatkins
Copy link
Collaborator

Quotes always come in pairs; breaking that association would only be done with an extremely good reason. That's definitely off the table as an option, I think.

@mybearworld
Copy link

* would look nice, as it's often used as a kind of placeholder value meaning "anything can go here". Of course, that's already used by the multiplication and exponent operators, so this probably shouldn't be used, but it's worth thinking about (maybe [*] or <*>?)

2
  |> addOne(*)
  |> add(*, 5)
  |> * * 2 // not great
  |> **2 // very bad

@sant123
Copy link

sant123 commented Feb 9, 2024

What about $# like shell count parameters?

value |> foo($#)

@Daniel15
Copy link

What about $# like shell count parameters?

value |> foo($#)

This looks a bit weird because JavaScript doesn't prefix variables with $ like shells do.

@sant123
Copy link

sant123 commented Feb 27, 2024

What about $# like shell count parameters?
value |> foo($#)

This looks a bit weird because JavaScript doesn't prefix variables with $ like shells do.

Yes but you can still do it, the advantage with # is that you will not break existing JS code. $# can’t be defined by anyone.

@mybearworld
Copy link

The shebang syntax #! does exist, but it'll only be ever used as the first two characters in a file (and it's only legal in that position).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bikeshed Discussion about naming or similar
Projects
None yet
Development

No branches or pull requests