Interesting. there are some parts i like a lot here, but two things that I really dislike syntax wise. One is the lean towards a chainable syntax - this has proven to a big footgun for many devs in both java streams and typescript, making it very easy to go from O(n) to O(2n). The other part i really dislike is the first argument principle noted. If i myself define `string_and_reverse` and I can call it both through `string_and_reverse(42)` and `42.string_and_reverse()` i could definitely see this leading to some very funky looking chaining.
Perhaps it's just one point from me - not liking chaining :D
Is it just me that doesnt like automatically returning the last statement in functions? It makes it hard to see where a function returns, and I dont see how you would do a guard clause at the start of a function without having the entire rest of the function in an else block
It does make me think that the usual types of guards might typically happen higher up (handled by the caller) or hidden with safe / monadic type operators that simply pass through rather than bailing out, so to speak.
I think it is much more obvious than being able to return from anywhere in a function. If the last expression is a match, I know every match body must return the same type. if the last is a (cond ...) I know ever cond branch must return a value. I vastly prefer that.
I remember really bumping up against this learning OCaml in college after having experienced oodles of imperative programming.
I understand the sort of philosophy and ergonomics of not having an early return, but it really does hurt certain kinds of code that otherwise would be more readable
Interesting. there are some parts i like a lot here, but two things that I really dislike syntax wise. One is the lean towards a chainable syntax - this has proven to a big footgun for many devs in both java streams and typescript, making it very easy to go from O(n) to O(2n). The other part i really dislike is the first argument principle noted. If i myself define `string_and_reverse` and I can call it both through `string_and_reverse(42)` and `42.string_and_reverse()` i could definitely see this leading to some very funky looking chaining.
Perhaps it's just one point from me - not liking chaining :D
> making it very easy to go from O(n) to O(2n)
Strictly speaking I assume everyone knows O(n) = O(2n) =O(kn) for k in R.
But I see your point. I assume any decent compiler would merge the loops though
Is it just me that doesnt like automatically returning the last statement in functions? It makes it hard to see where a function returns, and I dont see how you would do a guard clause at the start of a function without having the entire rest of the function in an else block
I suspect the idea would be to use `match` instead of an imperative `if`. There's an example here:
https://github.com/kablorp/blorp/blob/main/benchmarks/blorp/...
Then again, there's really not too many examples of early return guards, but I did manage to find one where the body is stuffed in an `else`:
https://github.com/kablorp/blorp/blob/main/benchmarks/blorp/...
It does make me think that the usual types of guards might typically happen higher up (handled by the caller) or hidden with safe / monadic type operators that simply pass through rather than bailing out, so to speak.
I think it is much more obvious than being able to return from anywhere in a function. If the last expression is a match, I know every match body must return the same type. if the last is a (cond ...) I know ever cond branch must return a value. I vastly prefer that.
I remember really bumping up against this learning OCaml in college after having experienced oodles of imperative programming.
I understand the sort of philosophy and ergonomics of not having an early return, but it really does hurt certain kinds of code that otherwise would be more readable