Conversation
Edited 10 days ago

IMO it should be way more common for a programming language to let you express a series of data-transformations as a left-to-right pipeline

like instead of doing this:

let foo = someCall(args);
foo = anotherCall(foo);
foo = aThirdCall(foo);

let me do this:

let foo = someCall(args)
    |> anotherCall
    |> aThirdCall;

a lot of functional languages do this even worse than in my first example, because you have to write it like this instead:

let foo = aThirdCall( anotherCall( someCall(args) ) );

or in Haskell syntax it would be more like this, I think:

foo = aThirdCall . anotherCall . someCall $ args

in both cases, the functions go in right-to-left order instead of left-to-right which IMO is pretty counterintuitive

(Lisps do this really well though, thanks to threading macros 💙)

5
2
4

eli (ˈe̝ːli), vampire kitsune

@kasdeya pipe operator my beloved

0
0
1

@kasdeya <joke> Shell being forward thinking yet again </joke>

TIL that someone made a Typst package to do this..if a little ugly.

https://typst.app/universe/package/weave/

1
0
1

in the past I’ve played with the idea of reversing the order of a function and its arguments:

(args)someCall

so that my “functional language” example would look like this instead:

( ( (args)someCall )anotherCall )aThirdCall

that way, for a simple example like this you can read the order of the operations from left-to-right. although this is very unintuitive to me. I think a much better solution would just be to make it so that function composition is left-to-right instead of right-to-left:

someCall . anotherCall . aThirdCall $ args

but even then, things get trickier once you have functions which need multiple arguments:

let foo = someCall(args);
foo = anotherCall(moreArgs, foo);
foo = aThirdCall(foo, yetMoreArgs);

so you really need proper pipeline syntax for that:

let foo = someCall(args)
    |> anotherCall(moreArgs, %)
    |> aThirdCall(%, yetMoreArgs);
(~> (someCall args)
  (anotherCall moreArgs _)
  (aThirdCall _ yetMoreArgs))
2
0
2

@benrob0329 oohh - it’s amazing that Typst is powerful enough for it to even be possible to create the pipeline operator in it!

0
0
1

@kasdeya Haskell has the (&) for this purpose: you can write

args & aCall & anotherCall & aThirdCall

Or if it's monadic code you can write

args >>= aCall >>= anotherCall >>= aThirdCall

1
0
1

@dregntael oohh that’s amazing! I wish I had known about & while I was learning Haskell

0
0
1

@kasdeya Have you considered concatenative languages like Forth?

1
0
2

@kasdeya They're convenient.

I first encountered them in Clojure.

It's interesting how they've changed over the years.

0
0
0

@kasdeya Can I offer you a nice De Bruijn notation in this trying time? https://en.wikipedia.org/wiki/De_Bruijn_notation

1
0
1

@stiiin oohh! I don’t understand anything in this article but it sounds like it’s lambda calculus, except the arguments go before the functions? in which cause that sounds great actually

1
0
0

@kasdeya Correct! So with lambda calculus your function definitions look like

`function = λ arg1 arg2 arg3 . body`

and applying functions look like

`function input1 input2 input3`

which is short for

`(λ arg1 arg2 arg3 . body) input1 input2 input3`

but with De Bruijn notation things flip around a bit. Function definitions still look like

`function = [arg1] [arg2] [arg3] body`

but now applying functions looks like

`(input3) (input2) (input1) function`

which... may look worse. But consider that it's short for

`(input3) (input2) (input1) [arg1] [arg2] [arg3] body`

and you may see that directly adjacent pairs of parentheses and square brackets now match up. The above will evaluate to

`(input3) (input2) [arg2] [arg3] body-with-arg1-filled-in`

which in turn evaluates to

`(input3) [arg3] body-with-arg1-and-arg2-filled-in`

1
0
1

@stiiin oohh! that is actually really cool. I think I like this notation a lot more than the lambda calculus notation that I’m used to (the one that you used in the beginning)

0
0
0

@emmy oohh omg I had no idea that there were other languages like Forth! I had a lot of fun playing with it in the past - its simplicity really appeals to me

0
0
1