On Wednesday, September 27, 2017 at 12:48:55 PM UTC-6, Michał Muskała wrote: > > is_struct is impossible to implement right now. The implementation in the > linked library is faulty and will fail as soon as you use the or operator > or multiple when clauses. For example, given an is_struct/2 guard when we > use it as: >
Yes it is, I did that on purpose along with a few other limitations in the git version to prevent people from actually using it (I don't want to release/publish anything that overwrite `def` and so forth). On Wednesday, September 27, 2017 at 12:48:55 PM UTC-6, Michał Muskała wrote: > > def foo(arg) when is_struct(arg, Decimal) or is_integer(arg) > > There is no way to translate this to valid Elixir syntax. Such a change > would require changes to VM itself and expanding the guard functions with a > map_get/2 or something similar. As far as I know, allowing for pattern > matching or case in guards was already rejected by the OTP team. > Actually that would be valid, and would always fail. Just like doing: ```elixir def foo(arg) when hd(arg) == :something or is_integer(arg) ``` This would fail as well. Such head splitting should be 'in' the defined guard only, it should not magically make contradictory code work. Any `defguard` thing, for all intents and purposes, should be considered failable like `hd` is unless the creator of it takes special handling of course (which something like `is_struct/...` could not really do). The example you gave should have those in different `when` clauses, not in the same `when` clause with an `or`. On Wednesday, September 27, 2017 at 12:38:26 PM UTC-6, José Valim wrote: > > While I agree it would be awesome to have an is_struct/1 guard, the > correct solution to this problem is to contribute this feature upstream and > allow map access in guards. So I agree your proposal does add new > possibilities but that's not how we should go about implementing them, > especially because of the complexity it would add to the compiler and the > cost in the duplication of clauses (space and time). > > For maps specifically, yes, however structually testing can be significantly easier (say going down 5 deep in a Plug.Conn struct) is far more natural, in addition to things like `map_key` not existing in guards (yet?). And do not, I'm just trying to spur discussion, not necessarily get this in. I'm actually, quite significantly actually, for *not* putting the current 1.6.0 proposal of `defguard` in elixir as I think it is wrong in design and it is able to be handled by a library as it is, thus even further making it so that it is not necessary to add it to the kernel (at least until it is played around enough in its library form before it is finalized on after plenty of real-world usage). > -- 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 [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/9687b72f-e844-414a-9473-acf7cbde2d90%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.
