Comments (20)
Thanks for the suggestions!
We'll probably add the |>
pipe operator at some point.
I don't think we'll add LiveScript's operators as functions, instead we have &
function syntax which covers a lot of that same need.
list.map &+1
people.map &.name
---
list.map($=>$+1)
people.map($=>$.name)
I also don't think we'll add -->
curried functions but I'm open to be convinced with examples.
from civet.
Guys, it would be sexy syntax!
toJson := res => res.toJson()
pick := (key:: keyof T, obj:: T) ==> obj[key]
id := 123
fetch 'api/users/:#{id}'
.then toJson
.catch pick 'message'
.finally console.log
from civet.
I have checked the ligatures, and we have all of them!
== === != !== > --> => ==> ~> >->
π
I think ==>
& -->
are the best:
add := (x:: number, y:: number) ==> x + y
// equals π
const add = curry((x: number, y: number) => x + y)
add := (x:: number, y:: number) --> x + y
// equals π
const add = curry(
function(x: number, y: number) {
return x + y
}
)
In the second example, we can use this
.
Not sure why but anyway:
add := (x:: number, y:: number) -->
console.log(@.name)
x + y
from civet.
I think using explicit arrow functions as a way to re-order arguments or specify a local alias is good. That way you can add type annotations and make use of destructuring and everything should compose fine. This way we can combine with existing language features rather than making special purpose syntaxes for every situation.
x + 1 |> ($) => $ * $
credentials
|> login
|> getUser
|> ({id}) => register id, 1
from civet.
I have noticed the ->
is taken for the function declaration.
It could be great if it were for curried functions.
Just an example:
fun add(x::number, y::number)
x + y
// equals π
function add(x: number, y: number) {
return x + y
}
add := (x:: number, y:: number) => x + y
// equals π
const add = (x: number, y: number) => x + y
add := (x:: number, y:: number) -> x + y
// equals π
const add = curry((x: number, y: number) => x + y)
// π§add can be called:
add(1, 2)
add(1)(2)
// usage
input := 4
// pipe version
input
|> add 3
|> subtract 2
|> console.log
// function composition
compute := compose(
console.log
minus 2
add 3
)
compute input
// prints π 5
Many monospaced fonts have that array in ligatures.
from civet.
What about
~>
?
Ideally whichever we choose would have both ==>
and -->
versions to correspond to the two ES flavors of functions.
from civet.
@sultan99 The ::
is for #126, where we plan to provide a more concise way to destructure and type parameters at the same time.
from civet.
@kabo Sounds good. I don't think we have another issue specifically for composition / flow yet. There are some discussions and maybe an issue that are related but we can link them in later.
Thanks for the detailed report and clear description!
from civet.
I think
==>
&-->
are the best:
@sultan99 Agreed, out of those⦠There is also =>>
and ->>
, which havenβt been mentioned, and I think visually express currying quite wellβ¦ also have ligatures. cc: @STRd6 @edemaine
from civet.
We now have the pipe operator |>
, but I think we're still lacking in what are called placeholders in the TC39 proposal, which I think is a natural way to support partials/currying. Copying from #83 (comment) :
I imagine it's really common to want to pass the piped value in as a first argument to a function, with other arguments given explicitly. What we want is shorthand for ($) => func($, foo, bar)
.
- One proposal on Discord was
func((&), foo, bar)
, where each extra layer of parens around&
pushes the function wrapper up a level. - Another option might be
func(&&, foo, bar)
, where each additional&
pushes the function wrapper up a level. - A bolder option would be to redefine the meaning of
func(&, foo, bar)
in the context of the right-hand side of|>
(probably a bad idea?). - The TC39 proposal suggests
func(%, foo, bar)
or various other notation that is specific to pipelining; for example,^^
might mean the left-hand side of|>
(no matter how deep we are), or we could optionally add an identifier like|foo>
to mean "wrap the right-hand side in a function with single argumentfoo
). For example,|$> func($, foo, bar)
would be equivalent to|> ($) => func($, foo, bar)
.
Not sure what's best, but it kind of highlights the limitation of the current &
notation... yet it feels like we're close.
from civet.
@sultan99 Thanks that's a great example for how curried functions can combine with the pipe operator.
I think using LiveScript's -->
or your suggestion of >->
for a curried function declaration is something we could add.
from civet.
@STRd6, any of these can be!
>->
& -->
monolisa & fira fonts have them:
from civet.
What about ~>
?
from civet.
If we're using the ==>
operator, why do we need the ::
instead of normal :
?
As for the compilation output, not sure you need a utility function, you could just compile it this way
add := (x:: number, y:: number) ==> x + y
const add = (x: number) => (y: number) => x + y
add := (x:: number, y:: number) --> x + y
const add = (x: number) => function (y: number) { return x + y }
from civet.
I have seen ::
in the discord chat as a suggestion to use it for typing.
I'm not familiar with syntax yet and I'm still confusing proposals with real syntax.
Sorry...
from civet.
Not sure if this is the right ticket for what I'm after, let me know if not and I'll create a new ticket instead.
I use ramda a lot and I'm curious if civet could support a few things natively. Something I do a lot with ramda is create a function using pipe. For example:
const doTheThing = R.pipe(
R.pluck('myprop'),
R.map(R.toUpper)
)
console.log(doTheThing([{myprop: 'hello'}])) // outputs [HELLO]
My attempt at doing this with civet
input := [myprop: 'hello']
pluck := (prop) => .map .`${prop}`
// works
input
|> pluck 'myprop'
|> .map .toUpperCase()
|> console.log
// doesn't do what I want it to do
doTheThing := pluck 'myprop' |> .map .toUpperCase()
// doesn't work either, but in a different way
doTheThing2 := .map .myprop |> .map .toUpperCase()
console.log doTheThing2 input
doTheThing comes out as
const doTheThing = pluck("myprop").map(($3) =>
$3.toUpperCase()
);
// as the first thing in the pipe is a function I would have wanted
const doTheThing = ($) => pluck("myprop")($).map(($3) =>
$3.toUpperCase()
);
doTheThing2 comes out as
const doTheThing2 = (($4) =>
$4.map(($5) => $5.myprop)).map(($6) =>
$6.toUpperCase()
);
// I would have wanted (note one less paren after $5.myprop, it's added to the last line instead
const doTheThing2 = (($4) =>
$4.map(($5) => $5.myprop).map(($6) =>
$6.toUpperCase()
));
Or perhaps I'm just using it wrong, perhaps the pipe operator |>
is only intended to be used when there's a start value, and there's something like fp-ts flow operator that I'm missing? Pipe vs flow in fp-ts.
from civet.
the operator works only on a start value, you are looking for a function composition operator (flow in fp-ts) which we discussed a bit in the Discord.
from civet.
@kabo this might work but I agree that it would be nice to have a cleaner syntax for function composition kinds of things.
doTheThing := ($) => (pluck 'myprop' |> .map .toUpperCase())($)
from civet.
ok, so I can go ahead and create a ticket for a function composition / flow operator?
from civet.
Closing this as:
- Pipelines have been implemented
- Partials have been implemented:
f(x, ., y)
compiles to$ => f(x, $, y)
, especially useful in pipelines- Note that we still don't have a pipeline placeholder operator
%
. There are some limited cases not yet covered, like|> foo(a, bar(b, %))
. But we can revisit that in the future.
- Note that we still don't have a pipeline placeholder operator
- Currying has a separate issue #818
- Composition has a separate issue #1112
from civet.
Related Issues (20)
- `yield x; loop` has strange behavior
- Trailing pipe or property access should expressionize statement HOT 1
- ASI fails before symbol-typed property
- Pipeline unwrapping should add refs
- `&` does not work in indented operator application
- `&` doesn't always work in `if` statement HOT 1
- if type errors
- `comptime` object literal with ES6 method generates invalid JS HOT 1
- `for own` doesn't work inside `comptime` HOT 1
- Comptime generator functions
- Cannot optional-chain prototype
- Top-level `comptime` block is always `undefined` in the REPL HOT 2
- Empty array matching still broken
- `--inline-map` suppresses comptime serialization errors
- `guard`-`else` HOT 4
- Stray semicolon in class body causes ParseError
- `&` is not compiled to `$ => $` in specific contexts HOT 1
- `<` is weirdly sensitive to being less-than or extends in SAFE HOT 4
- Matching nested property with same name generates invalid JS
- Ampersand bugs HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from civet.