ericmj/ex2ms

support `in` macro for integers in range or list literal in guard clauses

Closed this issue · 4 comments

So if I understand correctly there was some belief this was already supported, but it wasn't working for me... In my fork on master, I have a test that shows the error (though the test isn't currently testing what would be valid match_spec output), and then a commit that makes the test as written pass but isn't useful yet. Before I make a real PR wanted to discuss here.

I'm not 100% familiar with the code base and haven't done a ton of macro-based Elixir, but I'm happy to take a shot at this, my read so far is that a quick and dirty version could work by adding a new clause at the start of the cond block here for when fun == :in and depending on args, essentially call this for a list or one of the in_range versions above it for ranges, though since they're private functions in there we'd have to copy paste and/or extract them to a module in Elixir that we could call here. If either/both of those sound like good approaches I'd be happy to get started on. Thanks for all your awesome work @ericmj !

in/2 is a macro so we should try to expand it like a macro instead of adding special cases for specific macros. I thought that this clause [1] would handle it, I would suggest looking into why the expansion doesn't work.

[1]

expansion = is_expandable(fun_call, state.caller) ->

Thought something like that might be the case, but wasn't sure why wasn't working, my only guess is that bootstrapped? here is false but like I said I'm pretty new to macro metaprogramming in Elixir. I'll try digging into that when I have a chance unless someone beats me to it.

OK, you're right, and it is hitting that clause and coming back expandable/expanded, but translate_cond is failing to match anything but the error guard in it's recursion when the expansion comes back as a tuple from that call... somethign like {:., [], [:erlang, :orelse]}, [], [{{:., [], [:erlang, :"=:="]}, [], [{:n, [line: 240], nil}, :b]}, {{:., [], [:erlang, :orelse]}, [], [{{:., [], [:erlang, :"=:="]}, [], [{:n, [line: 240], nil}, :c]}, {{:., [], [:erlang, :"=:="]}, [], [{:n, [line: 240], nil}, :a]}]}] though that's got an ellipsis in it from an inspect... Hopefully I can look at this more later and dig in, but I don't... really understand what's happening so far 🙃

Closing this due to lack of activity.