DanielXMoore / Civet

A TypeScript superset that favors more types and less typing
https://civet.dev
MIT License
1.33k stars 28 forks source link

Pipeline placeholder ^^ or %% or `|x>` #1273

Open crystalthoughts opened 1 month ago

crystalthoughts commented 1 month ago

Hi, I think it would be a good idea to have the possiblity of aligning Civet more closely to the pipeline operator proposal (hack style). I think the only thing needed would be a configuration option to change something like: pp:= & |> (JSON.stringify ., null, 2) |> console.log to pp:= & |> (JSON.stringify ^^, null, 2) |> console.log

I also think it's a bit more readable. Any thoughts welcome :)

edemaine commented 1 month ago

The TC39 pipe proposal actually uses % currently, though there's various other notation mentioned. (I think ^^ is an older proposal. Note that it currently means logical xor in Civet, though that might be fine parsing wise, just confusing.)

TC39's % placeholder also has a different meaning than our current placeholders . and &: it can only be used in pipelines, and the arrow function gets pulled all the way out to just before the pipeline. See https://github.com/DanielXMoore/Civet/issues/75#issuecomment-1365340146

It's interesting to look at the examples from the proposal. All of them currently can be written using . and/or &, but it depends on the example. Here's one example that needs both:

return links
  |> Object.keys(.).map(function (rel) {
    return '<' + links[rel] + '>; rel="' + rel + '"';
  })
  |> link + &.join(', ')
  |> this.set('Link', .);

Now that we have good general support for placeholders, I wonder if we should add a pipeline-specific one, in particular to align with the TC39 pipe proposal as you say. Simple example:

data |> f(%) + g(%)
↓↓↓
f(data) + g(data)

This example can't be written with & (it won't pull outside the function calls) nor with . (each call makes its own function). And in general it could be nice to work with pipelines without having to think about the intricacies of & vs. ., and just have a placeholder that refers to the previous pipeline result.

I think the only hard part is we need to choose a placeholder syntax. % seems OK. ^ and <, or ^^ or <<, make some sense in the ways they point, though we've discussed using ^ for other things (implicit imports). I wonder if there's something obviously syntactically related to the pipeline |> itself.

Related, another option we've discussed (also mentioned in the TC39 bikeshedding issue) is

data |x> f(x) + g(x)
↓↓↓
f(data) + g(data)

where you can put any identifier (e.g. $) in between | and >.

crystalthoughts commented 1 month ago

I think the last suggestion is really nice - it sidesteps the issue of needing to remember an explicit symbol out of the mix of candidates. $ (or x) could be the suggested placeholder. It could even unpack an array or an object:

[1,2] |(a,b)> a + b //3 ["head","tail","tail"] |(h,t)> [h,t] // ["head",["tail","tail"]]

[1,2,10] |$> $[0]+$[2] //11

{a:1,b:2,c:10} |(a,b)> a+b //3

Of course this gets away from the TC39 a bit...

edemaine commented 1 month ago

I'm not sure about that paren operator, but I'd definitely like to support standard JS destructuring:

[1,2] |[a,b]> a + b // 3
["head","tail","tail"] |[h,...t]> [h,t] // ["head",["tail","tail"]]
[1,2,10] |$> $[0]+$[2] // 11
{a:1,b:2,c:10} |{a,b}> a+b // 3

Admittedly |x> looks a little unwieldly when it grows to a destructuring pattern.

This notation is mentioned in https://github.com/tc39/proposal-pipeline-operator/issues/91#issuecomment-363092439 (more examples here: https://github.com/tc39/proposal-pipeline-operator/issues/91#issuecomment-1188236632, https://github.com/tc39/proposal-pipeline-operator/issues/91#issuecomment-1332224740) so it's plausibly being considered for the TC39 proposal. Although there are hundreds of proposals in that issue, so who knows what they will decide.

@STRd6 What do you think of this notation? Worth trying? It is a little funny that |x> is just shorthand for |> (x) =>, but it is shorter, and it will be easy to implement.

STRd6 commented 1 month ago

@edemaine if you're excited about trying |id> it go for it! Destructuring in there is fine as well. We probably won't really know the pros and cons until we try out using it ourselves.