puffnfresh / roy

Small functional language that compiles to JavaScript.
http://roy.brianmckenna.org/
MIT License
834 stars 74 forks source link

Function composition operators #125

Open puffnfresh opened 12 years ago

puffnfresh commented 12 years ago

I'd love to use . as the composition operator but might be confusing to have the following be very different:

console.log
console . log

Might be good to have something like << and >> from F#. Bitwise shift operators in F# become >>> and <<<.

paulmillr commented 12 years ago

how about ?

getData ∘ getUser

https://github.com/pufuwozu/roy/blob/master/lib/prelude.roy#L17

andreypopp commented 12 years ago

@paulmillr it's a straight road down to APL :-)

paulmillr commented 12 years ago

@andreypopp imo apl failed because of shitty charset standards back there in 80s. we now have unicode etc. the only thing that concerns me is editor support but it's achievable too.

that's what scalaz (quite popular module for scala) also does

andreypopp commented 12 years ago

@paulmillr no, just take a look at your keyboard

alsonkemp commented 12 years ago

I like Paul's suggestion even if I would have to type Ctrl-Shift-2218 for ∘.

One tricky thing is that there are lots of very similar Unicode characters and it's difficult to tell which to use. For example, the arrow in src/lexer.js @ 254:11 is U+2192 (→), but I don't see that in http://en.wikipedia.org/wiki/List_of_Unicode_characters. Doesn't mean that Wikipedia is right and Roy is wrong, but it does make it difficult to figure out which Unicode character to use. U+2192 (→), U+27F6 (⟶), U+U+2794 (➔), U+2799 (➙) and U+279D (➝) all seem reasonable to use...

paulmillr commented 12 years ago

@andreypopp that's what I meant by editor support, but the resolution is definitely achievable. Scalaz guys use some cool keyboard input source. I mean, it's pretty easy to make new keyboard input sources, so we could just make another one that on ⌥-> will produce →.

michaelficarra commented 12 years ago

@alsonkemp: In vim, (U+2192) is Ctrl-k followed by ->, so a natural choice for at least that reason. Unfortunately, the function composition operator being proposed (, U+2218) is Ctrl-k followed by Ob, not a very obvious sequence to me. It's better than not having a digraph defined, though.

jb55 commented 12 years ago

For vim I use these bindings https://gist.github.com/2253102

When in insert mode... C-j is lambda C-l is right arrow C-h is left arrow C-o is compose

Although I don't think we should rely on people having their editors set up to support this.

I like << since it kind of puts an image in your head of the flow from input to output.

rtfeldman commented 11 years ago

<< and >> sound reasonable.

Just to throw an idea out there, ** is closer to and it's easy to remember: "++ for concatenation, ** for composition".

joneshf commented 11 years ago

I like << and >> as well. ** has connotations in other languages, like f#, to mean exponentiation. So, I think it'd be a bit confusing to have that mean composition.

cassiemeharry commented 11 years ago

+1 on << and >>. While I would rather have , the double angle brackets have the benefits of allowing backward function composition ((f << g) x = f (g x) and (f >> g) x = g (f x)).

There's a couple options for Unicode equivalents:

Similarly, would it make sense to have a pipe operator? It's similar to function composition except that instead of adding one more argument at the end of the arguments list, it would put the result as the first argument.

let f x y = x - y
let g z = z * z

g 4 |> f 5 = f (g 4) 5 = 9

I'm not sure how this would work in the type system, but it would be useful for functions that pass the subject in the first argument and, for example, options in the second. Not sure about Unicode equivalents for this one, though.

joneshf commented 11 years ago

Pipes sound like a good addition to me.

So are we cool with these additions/changes:

rtfeldman commented 11 years ago

+1 to >> and << for composition and >>> and <<< for bitwise shifts.

I would suggest deferring consideration of |> and <| until a later release. Pipe is certainly not an urgent inclusion (as I'd say composition is for a functional language), and casual additions to the initial release of a language have a tendency to come back and cause unforeseen headaches later on.

Which is not to say that Roy should never have them, just that I think it's better to err on the side of a narrower scope for the initial release of the language.

joneshf commented 11 years ago

That's probably a good idea.

taku0 commented 11 years ago

ECMAScript has two right shift operators: the signed right shift operator (>>) and the unsigned right shift operator (>>>). I worry that using >> as a function composition, >>> as a signed right shift operator, and >>>> as unsigned right shift operator might confuse JavaScript programmers.

How about <. and .> for function composition? Alternatively, -<- and ->- for composition and -< and >- for pipe?

joneshf commented 11 years ago

Good point. I have to wonder though, how often do people use the shift operators in js, and is it less of an issue for someone using roy?

rtfeldman commented 11 years ago

Wow, I had no idea >>> and <<< were already taken!

For what it's worth, given how much more often composition will presumably be used compared to bit shifts, I think it's safe to assume that if >> is known to be for composition in Roy, anyone in the extremely uncommon position of needing a bit shift will hit the Roy docs to hunt down the appropriate operators. I doubt enough people will try to intuit it and then get confused to be worth worrying about.

My objection to .> is that all Roy operators can be used (as far as I know) without whitespace separating them from surrounding terms, which means foo.>bar would denote function composition...even though it could just as easily appear that you're trying to access the >bar field of the foo object instead. Neither foo>-bar nor foo>>bar has that problem. Personally I wouldn't use a composition operator without whitespace, but I've had coworkers who never used whitespace around operators; if it's allowed, some people will adopt it as a style, and that does seem like a potential cause for confusion.

I don't have any strong preferences on >> vs. continuing to seek alternatives (although for whatever it's worth, one Haskell guy I talked to at a conference thought >> sounded confusing because it does something else in Haskell), but I would prefer to avoid three-character operators like ->- for tasks as common as composition when we could have two-character operators instead.

taku0 commented 11 years ago

I noticed that foo>-bar is ambiguous, i.e. foo > (-bar). I withdraw -< and >-.

Indeed shift operators are rarely used in JS, many programmers know shift operators. Therefore, if JavaScript programmer sees a Roy code, he/she would think the code is full of shift operators for some reason. For example, reading readLine >> split ',', he/she thinks like that “It reads a line and... shifts it bitwise? Shifting a string? Does split ',' returns a number???”. On the other hand, if he/she reads readLine .> split ',', he/she would think “OK, there is an unknown operator. I should refer to the document.”

NickHeiner commented 11 years ago

:+1: The |> operator is one of my favorite features from F# that I constantly miss in js.