[LOGIC-44] ex* could expand macros in patterns Created: 19/Jul/12 Updated: 17/Mar/13
|Reporter:||Joe Osborn||Assignee:||David Nolen|
|Labels:||enhancement, patch, test|
|Patch:||Code and Test|
So, tagged data structures are probably interesting in a relational context. Say you have a relation with some default logic about dogs:
Assume there's a (defmacro breed [t] `[:breed ~t]).
That's nicer than having to drop [:breed :golden-retriever] in there or whatever, since it's compile-time-checkable, less error-prone, reduces duplication, etc.
This little patch makes ex* expand macros in patterns so it doesn't treat e.g. (breed :golden-retriever) as introducing a new LVar called "breed". Test also provided.
|Comment by David Nolen [ 19/Jul/12 4:41 PM ]|
I'm surprised that this doesn't already work. We have support for unifying expressions in the pattern already. Look at line 1230 in tests.clj in the master branch.
So this should just work, no need to explicitly support macros as far as I can tell. If it's not working, then there's a bug.
|Comment by Joe Osborn [ 19/Jul/12 5:18 PM ]|
At least on 0.7.5, matching against a macro gives a runtime error:
Using a fn instead of a macro gives the same:
Here's (glyph-) for reference (don't mind all the extra , I have a weird key/value thing because of some conveniences for maintaining fact identity in a temporal database):
and type-enum as a macro:
and as a fn:
I'll mess around and see if my example works in HEAD.
|Comment by Joe Osborn [ 19/Jul/12 5:37 PM ]|
Same exception with this test case in HEAD (sorry for all the facts):
Now that I look at it, I may be expecting a wrong-format return value, but the point is that I don't even get that far.
Using the REPL, I checked out how (defna drawable- . . .) expands (tidied up slightly):
Note the (clojure.core.logic/fresh [type-enum] . . .) forms, which are exactly what I would not want to see in this case.
I'm not really sure why this doesn't work here yet works for the matche test case.
|Comment by David Nolen [ 19/Jul/12 5:47 PM ]|
This pattern make it seem like you want to match:
Note extra level of brackets here. Is this the case?
Even so I agree that the expansion doesn't look quite right. We should never descend into a seq form like that.
|Comment by Joe Osborn [ 19/Jul/12 5:57 PM ]|
Yes, that's exactly the desired outcome in this case--a tagged value in my naive interpretation. Is the reason it fails whereas the test on :1230 doesn't the fact that it's producing a vector and not a list? Changing the fn to return a list instead of a vector didn't seem to help.
My patch, fwiw, doesn't exhibit that behavior (at least for macros, haven't tested it with fns).
|Comment by David Nolen [ 19/Jul/12 9:11 PM ]|
What I mean is don't you want the following instead?
Note that I removed a layer of square brackets.
|Comment by Joe Osborn [ 20/Jul/12 10:28 AM ]|
Nope! I actually want both. I'm doing some temporal logic stuff and I wanted some conveniences for "updating" a fluent, so I wanted to distinguish between the "key part" and the "value part" of the arguments. It looks silly for facts with no "value part", but it lets me write procedures and fns something like this:
And I write all the non-temporal fluents that way too for consistency and to help prevent mistakes.
|Comment by David Nolen [ 20/Jul/12 2:58 PM ]|
I'll try to give a closer look at this issue over the weekend.
|Comment by David Nolen [ 17/Mar/13 7:05 PM ]|
We're thinking about a more general solution here: http://github.com/clojure/core.logic/wiki/Better-syntax-support