Hacker News new | ask | show | jobs
by _v7gu 1202 days ago
Implementation looks dead simple for this too:

    $ = (f, x) => f(x)
    flip = f => (x, y) => f(y, x)
    |> = (x, ...fs) => fs.reduce(flip($), x)
However, |> in typescript is quite hard to type (no recursive types). The best approximation you can get is to manually insert

   |> = <A, B1>(x:A, f1:(a:A)=>B1)
   |> = <A, B1, B2>(x:A, f1:(a:A)=>B1, f2:(b1:B1)=>B2)
At that point, a simpler binary function will make more sense

   |> = flip($)
And tsc will interpret the types in the pipe more correctly. Of course, the compiler can allow functions to be called without parentheses to avoid a macro for pipe calls, which will bring our definitions to

     $ = (f, x) => f x
     flip = f => (x, y) => f y x
     |> = (x, f) => (flip $) x f
It might also help to add a simpler function composition function too, as it will greatly help reuse without requiring you to write lambdas

     $ = (f, x) => f x
     flip = f => (x, y) => f y x
     . = (f, g) => x => $ f (g x)
     |> = . flip $
It could also help to remove those pesky parentheses from lambda definitions too, maybe with simpler declarations like `f x y =` converting to `f = (x, y) =>` and enabling automatic currying:

     $ f x = f x
     flip f x y = f y x
     . f g x = $ f (g x)
     |> = . flip $
But, have you noticed that we mostly have binary functions? We could greatly improve readability by making our "modifier" functions (aka combinators or adverbs) into operators. So civet could implement a special syntax for operator definition, and then we would write for definitions like

     ($) f x = f x
     flip f x y = f y x
     (.) f g x = f $ (g x)
     (|>) = flip . $
(Oh wait, does this look like something else?) So we would be able to express `console.log(Object.keys(data))` like

    data
      |> Object.keys
      |> console.log
or equivalently

   (console.log . Object.keys) $ data
without having to special case for pipes! But more importantly, if you enjoy the Clojure method of piping, you can define

    |>> x f ...fs = f ? |>> (f x) ...fs : x
which would give you the syntax you like. And I have a feeling the types will compile just right in a language that looks like this...