Civet
Civet copied to clipboard
Pipeline placeholder ^^ or %% or `|x>`
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 :)
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 >.
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...
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.
@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.