Well then what you would call succinct, I would call sparse
Ruby and Elixir has the right balance of succinctness IMO.
Python, OCaml, Elm etc is too sparse for my taste (in your example above, I MUCH prefer the Elixir version)
C, PHP, JS etc with all their endless brackets and semi colons are too convoluted for me.
But that’s just my personal preference and that’s not to say I won’t use other languages. I’m still going to check out Bucklescript at some point, though, I do wish the syntax was more like Ruby and Elixir
It all comes to personal preference in the end. I prefere whitespace to do…end or brackets, since you indent code for readability anyway. I don’t remember how many times I forgot that stupid do in either ruby or elixir and got enigmatic errors about totally different lines
Yes, it is. OCaml has the same elegance of expression as the other languages in the ML family. Technically it works mostly the same as Haskell, for example. The difference in how it’s written mostly seems to lie in that they’re not as perversely happy to create new operators, etc.
Yeah… That there is an operator for nearly every other binary function annoys me as hell… I can’t remember most of them and use their names counterparts. Most of the time it’s a huge gain in readability compared to the code of a co student who worships point free and operators…
Jose said something about it in a interview before. Basically to achieve this it requires some fundamental changes on Erlang. I think from the perspective of writing productivity, Elixir is great already. If you want the “safe” thing for writing software on server side, I think OCaml should do(through Bucklescript it does the front end as well). It’s been battle proven like Erlang and very fast(think about C++). I was a big Elm fan and I wanted to have the experience of Elm everywhere as well. And I came across @OvermindDL1 's thread about Bucklescript and start porting my Elm code on his project https://github.com/OvermindDL1 . Basically it’s an Elm Architecture on OCaml and I found it so fascinating that OCaml is totally capable of expressing what Elm could express in a similar manner and almost identical structure. So my plan is to replace Elm with Bucklescript and master OCaml on the way. Well anyway highly recommend OCaml/Bucklescript for you!
let someFunction = function
| 42, _ -> "You passed in a 42! Ignoring the second element"
| x, str when x>10 -> "Your number is greater than 10 and not 42, and your string is: " ^ str
| x, str -> "Your number is less than or equal to 10, and your string is: " ^ str
In Erlang/Elixir you pattern matching is linear and the functions have to be together, it is not that different in OCaml. Except OCaml will even tell you when you match is not exhaustive based on the types you accept, or you can mark it to throw an exception on a nomatch. ^.^
EDIT: For example, leaving out that last line gives this warning:
Warnings: File "testing.ml", line 1, characters 19-173:
Warning 8: this pattern-matching is not exhaustive.
Here is an example of a value that is not matched:
(0, _)
(However, some guarded clause may match this value.)
Plus I get nice squiggly lines showing it all in both atom and emacs. ^.^
This seems like somewhat of a nitpick. Syntactically it’s not “top level”, but conceptually the first entry point in the function will do pattern matching. For all you know, it all just compiles down to the same conceptual matching as Erlang/Elixir.
I used to care about it (the pattern matching) not being as intuitive as Erlang/Haskell, but the only thing it means is that you’ll have your matches one indentation deeper.
Can you elaborate what do you mean by that? I think that OCaml example translate roughly to
def someFunction(42, _) do
"You passed in a 42! Ignoring the second element"
end
def someFunction(x, str) when str > 10 do
"Your number is greater than 10 and not 42, and your string is: #{str}"
end
def someFunction(x, str) do
"Your number is less than or equal to 10, and your string is: #{str}"
end
And to be honest I think OCaml is more readable (at least for those online function bodies) for me and does exactly the same job, more over let you patter match everything you can in Elixir. And I’d really would like to learn OCaml, and so far one thing that stops me from doing this is that it doesn’t have OTP and so easy and powerful concurrency model, and that’s where aim when it comes to my programming future. And that does not mean that I think that one or the other is better from syntactical point of view. Neither is very familiar to me
Of ocurse it is more readable, but if you really want to translate it to elixir, it is the following:
def someFunction() do
fn (42, _) -> # stuff
(x, str) when x > 10 -> # other stuff
(x, str) -> # fallback stuff
end
end
OK, I do assume OCaml is properly curried, so I do also assume, that in OCaml in fact there is no semantic difference, but still, I prefer a pattern match on the left hand side of the =, without any additional layer of syntax, as I do have it in erlang, elixir, and haskell, but not in elm, OCaml or Rust.
Do you think fn -> end and def end noisy? I think mostly def end is OK but I hate fn -> end. To me it’s kind of a trade-off like the difference of binding once/rebinding in Erlang and Elixir. You got top-level pattern match but you lose the convenience of easy function declaration.
Erlang/elixir is the same way though, just one indention level up. You still have to keep your function heads together and in the order that you want them tested.
Precisely. ^.^
You can separate the cases with newlines if you want, you can even move them up without indentation if you want to too (OCaml is not whitespace sensitive unlike Haskell:
let someFunction = function
| 42, _ -> "You passed in a 42! Ignoring the second element"
| x, str when x>10 -> "Your number is greater than 10 and not 42, and your string is: " ^ str
| x, str -> "Your number is less than or equal to 10, and your string is: " ^ str
Or you can even define the types that everything accepts in the ‘head’ too:
let someFunction : int * string -> string = function
| 42, _ -> "You passed in a 42! Ignoring the second element"
| x, str when x>10 -> "Your number is greater than 10 and not 42, and your string is: " ^ str
| x, str -> "Your number is less than or equal to 10, and your string is: " ^ str
No, actually the example you gave in Elixir would be like this in OCaml:
let someFunction(x, str) =
match x, str with
| x, str when x > 10 -> "blah"
| x, str -> "blee"
There are some functional differences between them.
It is properly curried, but it also uncurries in the (f)lambda compiler. You can match before the = too, but only once:
let someFunction 10 str = "This function only accepts a '10' for its first arg, your second is: " ^ str
That is why the function keyword exists, it gives a top level matching context (near identically to how erlang does it internally too).
Remember that everything is an expression. If you wanted to have syntax like:
let blah 10 = "blah"
let blah 15 = "blorp"
let blah x = string_of_int x
Well each is defining its own variable in the context, and as the context is updated as it is built you get a new definition because in OCaml you can redefine functions (think an implicit defoverridable in elixir terminology, thus to have a top level match context you have to state that you are doing it some-how. Even in both erlang and elixir I rarely do multiple top-level function heads but rather do an internal case on a single one. Makes it easier to reason about especially in elixir with optional arguments, default arguments, etc…
As a comparison, haskell also does not have the ability to redefine functions, it is one of the things in the language that is odd, because you can define new scopes in haskell that redefine something, yet not to top level functions, it is an inconsistency and one of the reasons it is white-space important. The top level context of OCaml is no different than any other context in any other location except the in is optional, so I could just as easily define the above inside a function and use it too, like this:
let someOuterFunction x =
let someFunction = function
| 42, _ -> "You passed in a 42! Ignoring the second element"
| x, str when x>10 -> "Your number is greater than 10 and not 42, and your string is: " ^ str
| x, str -> "Your number is less than or equal to 10, and your string is: " ^ str
in someFunction x "blah"
Yeah Erlang is the same way. I prefer function definitions that follow the same format everywhere (which OCaml does).
That was it! Oh I programmed so much on that thing! That is an assembly chip worth working on! ^.^
i think that more than compiling, the ELM abstraction approach could also be translated, and the idea of Message, command, etc… added to a gen_server would be great