Reputation: 27803
I feel like I am misunderstanding something here.
Lets say I have the numbers 1, 2, 3, and 4 and I want to add 5 and 6 to it. Common sense tells me to List.append
it, but when I try that I get:
[1;2;3;4] |> List.append [5;6];;
val it : int list = [5; 6; 1; 2; 3; 4]
Why is it prepending the values to my list instead of appending them?
Upvotes: 0
Views: 1138
Reputation: 6223
You are absolutely right to be confused. The way this function behaves is not intuitive from its name at all. List.append
actually does what (@)
does:
List.append ['a'] ['b'] // ['a'; 'b']
['a'] @ ['b'] // ['a'; 'b']
(@) ['a'] ['b'] // ['a'; 'b']
If I say "append a to b", I expect the result to be ba. Take the statement "add a to the set s": it is written as Set.add a s
. But List.append
swaps the position of the arguments, which is especially dangerous since the arguments have the same type. Now, one could read this as "append a and b", but that's not good syntax even in spoken language.
Thus, the pipeline operator reads just as nonsensically: input |> append a
is equal to append a input
, which strangely translates to "append input to a" in spoken language.
If you ask me, it would have been better to pick a different name for this one.
Upvotes: 1
Reputation: 26174
It's not really prepending. You're changing the order the arguments appear by using the forward pipe operator, which in this case reverses the order but if you write the function without altering the order it makes more sense:
List.append [1;2;3;4] [5;6] // [1;2;3;4;5;6]
Note that this is coherent with Array.append
and Seq.append
. It's also coherent with the string concatenation operator as function (+)
.
The forward operator 'moves' the last argument to the beginning of the expression, which in some cases may be desired (piping) but it may be confusing in other scenarios, take for instance the division as function (/)
if you use it as part of a piping, with a forward operator:
5 |> (/) 10
It evaluates to 10 / 5
but at first sight you may get the wrong impression that it will do 5 divided by 10.
Upvotes: 16
Reputation: 144136
This is being parsed as
[1;2;3;4] |> (List.append [5;6])
and List.append [5;6]
returns a function int list -> int list
which appends the input to the list [5;6]
. You are then applying the list [1;2;3;4]
to this function.
Upvotes: 5
Reputation: 47904
I think this is an odd function in that the order of the args doesn't work well with pipelines. Instead the order reflects the resulting list, i.e., List.append [1;2] [3;4]
yields [1;2;3;4]
.
Upvotes: 5