This is a very interesting proposal! I really like the flexibility of `is` and `is_any`. I think that def something_magical(x) when is_any(x, [:integer, :float, :list, :map]) do #... end reads a whole lot better than def something_magical(x) when is_integer(x) or is_float(x) or is_list(x) or is_map(x) do #... end
That being said, I think you're taking it a little too far with specifications like {:list, 1} that check if something is a list having length one. I think that it is clearer to keep these separated. The same goes for the comparison ones like `{:<=, term}`. Just using `x <= term` in the guard clause seems clearer. I like the non-tuple kinds in the 'basic and built-in types' list. I think that things like 'odd', 'even', comparisons and most of the convenience ones are better to be written in their normal longer form. Finally, when I started reading your post, I expected the kinds to be the module names of the built-in Elixir types that are also used when you want to implement a protocol for a built-in type, like Integer, Float, PID, Tuple, etc. Of course, when I looked at the documentation, I found out that the reason you didn't was to match @specs more closely, and because there are things like `:zero_or_neg_float` for which there isn't a clear module name. I think that something like is_any(x, [List, Map, Tuple]) would be a really interesting and readable guard syntax. On Thursday, August 11, 2016 at 5:31:12 PM UTC+2, eksperimental wrote: > > Hi everyone in this list, > > I hope it has a good reception among the community, since it has the > potential to change the way we write functions guards in a very positive > and more natural way. > > Guards clauses are a key feature in Elixir. Researching > how to make it easier for developers to define guards, has led me to > two enhancement proposal. This is the first one, which will allow > developers to write guards, guard safe macros and other clauses in a > more natural and succinct way. > > All the following macros are allowed in guards: > - `is_kind(term, kind)` determines if a given `term` is of a certain > `kind`. > - `term is kinds` determines if `term` is each kind in `kinds`. > - `term is_not kinds` determines if `term` is not of any of the `kinds`. > - `term is_any kinds` determines if `term` is of any of the `kinds`. > - `terms are kinds` determines if every term in list `terms` is of > every kind in `kinds`. > - `terms are_not kinds` determines if every item in list `terms` is not > of `kind`. > - `terms are_any kinds` determines if every term in list `terms` is not > of any of the `kinds`. > > Allowing us to write functions guards as regular code, that otherwise > it would take a really long lines of code: > > def check(letter) when letter is :char, do: true > > iex> [100, 200] are [:even, {:>=, 100}] > true > > write expressions in a more natural way: > iex> term is_not nil > > as opposed to > iex> not is_nil(term) > > For a list of all supported kinds, see the list: > > https://gist.github.com/eksperimental/a6df4348e9675109e49ccf4e34101bfe#list-of-supported-kinds-by-is_kind2 > > > Here's the proposal: > https://gist.github.com/eksperimental/a6df4348e9675109e49ccf4e34101bfe > > and here the its full implementation: > https://github.com/eksperimental/elixir/tree/is-kind > > Looking forwards to hear your opinions > -- You received this message because you are subscribed to the Google Groups "elixir-lang-core" group. To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-core+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/5f5b1bc4-ac77-46f5-9773-e445a99f53b2%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.