Redundant API in stdlib, which to choose?

I recently come across some two redundant function pairs (aliases) in stdlib, specifically those two:

I know I can use either, and none of those is marked deprecated apparently.

But is there some advice which of them to use? Maybe the documentation could/should mention which is an alias for which, and what’s the canonical way, so it is easier to maintain a consistent style?

See also this comment on Github by @gasche.

Also, is it okay to directly write an issue report if I encounter such documentation issues, or should I rather ask here first? I don’t want to cause unnecessary noise.

Thanks for your code style advice and support.

No, you will only get opinions. Use whatever feels best in your context.

But if your goal is to maintain a consistent style, rather use List.concat instead of List.flatten as you have List.concat_map and not List.flat_map.

Okay, I can do that. I guess in certain contexts I might prefer one over the other.

But still, wouldn’t it be nice if the docs would consistently point to each other’s aliases then? Currently neither Seq.return nor Seq.singleton refer to the other function as an alias, and List.flatten mentions List.concat, but not vice-versa. (It confused me at first, so I looked into the source to see if they are really identical.)

The documentation is short enough to find the aliases, but still, I think it’s something that could be improved. (I’d be happy to do a tiny PR too, but I don’t want to submit anything without understanding the rationale behind certain API decisions, of course.) (I’d also be happy if someone else does it.)

This is fixable with a small PR to update the documentation :wink:

To me it feels like two different ideas. return is when I want to lift a value into the Seq monad, singleton is for when I want a Seq with a single value. They do fundamentally the same, but I would find it obscure to do a bind and then instead of return use singleton (despite the effect being exactly the same).

I see how different names could reflect the semantics better, even if the functions do the same.

But not sure if that makes code more readable.

I remember the issues with applicative functors in Haskell (I haven’t really been following up), but I seem to remember there were also some duplications arising, like pure vs return.

What is a bind in OCaml? With regard to sequences, would that be Seq.concat_map? But that is not named bind.

Surprise, we do have Seq.flat_map. :rofl: