3 ms·
I've been reading about Erlang recently, and guards (the when clause) seem much more expressive than something like type annotations for function parameters. Fo
by chickenfries 9y ago
I've been reading about Erlang recently, and guards (the when clause) seem much more expressive than something like type annotations for function parameters. For example, TypeScript's annotations can't express something like this (which also shows Erlang's pattern matching):
right_age(X) when X >= 16, X =< 104 ->
true;
right_age(_) ->
false.
http://learnyousomeerlang.com/syntax-in-functions#guards-guards http://learnyousomeerlang.com/syntax-in-functions#guards-gua...
- jacquesm 9y agoCan't?
- chickenfries 9y agoThat was awkwardly phrased. I was trying to say "TypeScript's annotations can't express something this Erlang example."
- always_good 9y agoUnless you're telling me Elixir has static analysis that can tell me that `right_age(18) == true` then I'm not sure how that competes with types much less is so different from any other runtime conditional.
- rdtsc 9y ago> Unless you're telling me Elixir has static analysis Sure does: http://erlang.org/doc/apps/dialyzer/dialyzer_chapter.html http://erlang.org/doc/apps/dialyzer/dialyzer_chapter.html > I'm not sure how that competes with types much less is so different from any other runtime conditional. You can write: f(5) -> "got a 5"; f(X) when is_integer(X), X > 1000 -> "got an integer greater than 1000"; f(X) -> "not 5 and not an integer greater than 1000". Sure you can do it with an if statement in some languages. Except in Erlang can also have the same guards on process message receive expressions. There would have to process all messages then check the type and somehow re-insert it back into the message queue.
- always_good 9y agoLooking at the dialyzer docs and how you truncated my full question, I'm still not sure if Elixir has static analysis that is aware of those guards or not.
- rdtsc 9y agoSorry for being confusing. I think this might be better description of static type analysis: http://learnyousomeerlang.com/dialyzer http://learnyousomeerlang.com/dialyzer Erlang is a dynamic, strongly typed language. Dynamic means the compiler doesn't do static type checks. "Strongly typed" means once a variable has a type it usually doesn't get automatically coerced to other types. So adding a string "5" and an integer 1 doesn't return a string "6" or integer 6 but throws an exception. In addition to the compiler there is also a tool called Dialyzer. It's based on the idea of Success Types (paper on it: http://www.it.uu.se/research/group/hipe/papers/succ_types.pdf http://www.it.uu.se/research/group/hipe/papers/succ_types.pd...). It checks for type inconsistencies, violations, etc just like a compiler in a traditional statically typed language. But it doesn't emit optimized code based on it. So say it deduced that a variable can only be an integer between 1 and 10 it doesn't have a way to emit some optimized assembly code based on that information. Besides the types it automatically infers, additional typing constraints can be specified by the user. So for the guard in question, if say the second clause of right_age(_) -> wasn't there and it saw calls to the function with X=105, then Dialyzer would come back with an error with something like: your_module:105: Clause guard cannot succeed.