[MATCH-35] Bug in seq pattern matching Created: 27/Oct/11 Updated: 16/Jun/13 Resolved: 16/Jun/13 |
|
| Status: | Resolved |
| Project: | core.match |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Defect | Priority: | Critical |
| Reporter: | David Nolen | Assignee: | David Nolen |
| Resolution: | Completed | Votes: | 0 |
| Labels: | None | ||
| Description |
(let [l '(1 2 3)]
(match [l]
[([a & [b & [c d]]] :seq)] :a0
:else :a1))
Matches when it shouldn't. |
| Comments |
| Comment by Greg Chapman [ 11/Jan/12 10:24 AM ] |
|
Another example of (I think) the same issue: user=> (let [x ()] (match [x] [([h & t] :seq)] [h t] [_] :a1)) Perhaps SeqPattern's IPatternCompile should call seq in order to filter empty seqs? (e.g.: (to-source* [this ocr] |
| Comment by David Nolen [ 16/Jun/13 10:38 PM ] |
|
fixed, http://github.com/clojure/core.match/commit/37564e32d34547e7d8a71f7abc631cce9585dd4e |
[MATCH-47] vector patterns dispatch on count after dispatching on type Created: 23/Dec/11 Updated: 16/Jun/13 Resolved: 16/Jun/13 |
|
| Status: | Resolved |
| Project: | core.match |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Defect | Priority: | Critical |
| Reporter: | David Nolen | Assignee: | David Nolen |
| Resolution: | Completed | Votes: | 0 |
| Labels: | None | ||
| Description |
|
The current behavior just creates complications. |
| Comments |
| Comment by David Nolen [ 16/Jun/13 10:22 PM ] |
|
as of http://github.com/clojure/core.match/commit/59df5b32b3c06b0038f76ccb88670fa9f42e5547 we always check size when applicable |
[MATCH-68] Vector match "underflow" => IndexOutOfBoundsException Created: 22/Apr/13 Updated: 16/Jun/13 Resolved: 16/Jun/13 |
|
| Status: | Resolved |
| Project: | core.match |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Defect | Priority: | Major |
| Reporter: | Chas Emerick | Assignee: | David Nolen |
| Resolution: | Completed | Votes: | 0 |
| Labels: | None | ||
| Attachments: |
|
| Patch: | Code and Test |
| Description |
|
This fails with 0.2.0-alpha12: (match [[:x]] [[m n & _]] 1) I expect nil, but an unguarded subvec call throws an IndexOutOfBoundsException. A WIP patch is attached that fixes this (perhaps incorrectly) but which produced regressions (outside of core.match), e.g. (match [[[:x "t"]]]
[[[:x & a] & tail]] :a
[[[:y & p] [:x & a] & tail]] :b)
=> nil
The patch also "fixes" this (by changing pattern-compare behaviour for rest VectorPattern s, but that leads to a regression in the vector-pattern-rest-2 testcase in core.match. (Original discussion with further background here.) |
| Comments |
| Comment by Greg Chapman [ 24/Apr/13 5:26 PM ] |
|
FWIW, I've been using the patch described here, and haven't yet run into any problems, though I also haven't used core.match that much. Anyway, with the change to subvec-inline, both of the cases here act as expected (producing nil and :a, respectively). (I note looking at my patch that I'm doubly-evaluating ocr in the second overload; obviously that should be fixed with a let binding). |
| Comment by David Nolen [ 18/May/13 3:11 PM ] |
|
The patch looks like it's going in the right direction. Can you explain why your patch without the pattern-compares case causes the second example to fail? |
| Comment by David Nolen [ 16/Jun/13 10:10 PM ] |
|
fixed, http://github.com/clojure/core.match/commit/302c355ebf751fa8dc442c8db8b901ebb4eacfae |
[MATCH-56] IndexOutOfBoundsException when matching empty vector Created: 27/Mar/12 Updated: 16/Jun/13 Resolved: 16/Jun/13 |
|
| Status: | Resolved |
| Project: | core.match |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Defect | Priority: | Major |
| Reporter: | Greg Chapman | Assignee: | David Nolen |
| Resolution: | Completed | Votes: | 0 |
| Labels: | None | ||
| Environment: |
Clojure 1.3 |
||
| Attachments: |
|
| Description |
|
Using the latest core.match: user=> (let [x []] (match [x] [[h & t]] [h t] :else :nomatch))
IndexOutOfBoundsException clojure.lang.RT.subvec (RT.java:1451)
Not sure if this is the best fix, but I resolved this specific case by slightly changing subvec-inline (see attached diff). |
| Comments |
| Comment by David Nolen [ 27/Mar/12 10:28 AM ] |
|
Thanks for the report. The patch is not going to work - we should be checking that the vector has at least one item. |
| Comment by David Nolen [ 16/Jun/13 10:08 PM ] |
|
fixed http://github.com/clojure/core.match/commit/59df5b32b3c06b0038f76ccb88670fa9f42e5547 |
[MATCH-69] AOT-compiling match expression produces stack overflow Created: 24/Apr/13 Updated: 16/Jun/13 Resolved: 16/Jun/13 |
|
| Status: | Closed |
| Project: | core.match |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Defect | Priority: | Minor |
| Reporter: | Chas Emerick | Assignee: | Chas Emerick |
| Resolution: | Declined | Votes: | 0 |
| Labels: | None | ||
| Description |
|
The offending match expression is pretty gnarly, will try to simplify and post it here later. For now, a (partial) stack trace, eliding the repeating bits: Caused by: java.lang.StackOverflowError at clojure.core$map$fn__4207.invoke(core.clj:2479) at clojure.lang.LazySeq.sval(LazySeq.java:42) at clojure.lang.LazySeq.seq(LazySeq.java:60) at clojure.lang.ChunkedCons.chunkedNext(ChunkedCons.java:59) at clojure.lang.ChunkedCons.next(ChunkedCons.java:43) at clojure.lang.PersistentVector.create(PersistentVector.java:51) at clojure.lang.LazilyPersistentVector.create(LazilyPersistentVector.java:31) at clojure.core$vec.invoke(core.clj:354) at clojure.core.match.PatternMatrix.column(match.clj:713) at clojure.core.match$useful_p_QMARK_.invoke(match.clj:811) at clojure.core.match.PatternMatrix$iter__1458__1464$fn__1465$iter__1460__1466$fn__1467$fn__1468.invoke(match.clj:765) at clojure.core.match.PatternMatrix$iter__1458__1464$fn__1465$iter__1460__1466$fn__1467.invoke(match.clj:763) at clojure.lang.LazySeq.sval(LazySeq.java:42) at clojure.lang.LazySeq.seq(LazySeq.java:60) at clojure.lang.RT.seq(RT.java:484) at clojure.core$seq.invoke(core.clj:133) at clojure.core.match.PatternMatrix$iter__1458__1464$fn__1465.invoke(match.clj:764) at clojure.lang.LazySeq.sval(LazySeq.java:42) at clojure.lang.LazySeq.seq(LazySeq.java:67) at clojure.lang.RT.seq(RT.java:484) at clojure.core$seq.invoke(core.clj:133) at clojure.core$partition$fn__4309.invoke(core.clj:2834) at clojure.lang.LazySeq.sval(LazySeq.java:42) at clojure.lang.LazySeq.seq(LazySeq.java:60) at clojure.lang.RT.seq(RT.java:484) at clojure.core$seq.invoke(core.clj:133) at clojure.core$map$fn__4207.invoke(core.clj:2479) at clojure.lang.LazySeq.sval(LazySeq.java:42) at clojure.lang.LazySeq.seq(LazySeq.java:60) at clojure.lang.Cons.next(Cons.java:39) at clojure.lang.PersistentVector.create(PersistentVector.java:51) at clojure.lang.LazilyPersistentVector.create(LazilyPersistentVector.java:31) at clojure.core$vec.invoke(core.clj:354) at clojure.core.match.PatternMatrix.useful_matrix(match.clj:763) at clojure.core.match.PatternMatrix.necessary_column(match.clj:755) at clojure.core.match.PatternMatrix$choose_column__1441.invoke(match.clj:720) at clojure.core.match.PatternMatrix.compile(match.clj:738) at clojure.core.match$first_column_chosen_case$switch_clauses__1406$fn__1407.invoke(match.clj:643) at clojure.core$map$fn__4211.invoke(core.clj:2492) at clojure.lang.LazySeq.sval(LazySeq.java:42) at clojure.lang.LazySeq.seq(LazySeq.java:60) at clojure.lang.RT.seq(RT.java:484) at clojure.core$seq.invoke(core.clj:133) at clojure.core.protocols$seq_reduce.invoke(protocols.clj:30) at clojure.core.protocols$fn__6026.invoke(protocols.clj:54) at clojure.core.protocols$fn__5979$G__5974__5992.invoke(protocols.clj:13) at clojure.core$reduce.invoke(core.clj:6177) at clojure.core$into.invoke(core.clj:6229) at clojure.core.match$first_column_chosen_case$switch_clauses__1406.invoke(match.clj:646) at clojure.core.match$first_column_chosen_case.invoke(match.clj:676) at clojure.core.match.PatternMatrix.compile(match.clj:740) at clojure.core.match$first_column_chosen_case$switch_clauses__1406$fn__1407.invoke(match.clj:643) at clojure.core$map$fn__4211.invoke(core.clj:2492) at clojure.lang.LazySeq.sval(LazySeq.java:42) at clojure.lang.LazySeq.seq(LazySeq.java:60) at clojure.lang.RT.seq(RT.java:484) at clojure.core$seq.invoke(core.clj:133) at clojure.core.protocols$seq_reduce.invoke(protocols.clj:30) at clojure.core.protocols$fn__6026.invoke(protocols.clj:54) at clojure.core.protocols$fn__5979$G__5974__5992.invoke(protocols.clj:13) at clojure.core$reduce.invoke(core.clj:6177) at clojure.core$into.invoke(core.clj:6229) |
| Comments |
| Comment by David Nolen [ 02/Jun/13 11:39 AM ] |
|
As it is this ticket is not useful. Chas can you add the minimal case? Thanks! |
| Comment by David Nolen [ 15/Jun/13 10:37 PM ] |
|
Without more details I'm inclined closed to this. I just need a minimal case and will be happy to investigate. |
| Comment by Chas Emerick [ 16/Jun/13 4:47 PM ] |
|
I never was able to get a sane minimal case together. Later, I just coded around the problem, and all of the changes on master may make the issue moot at this point anyway. Closing. |
[MATCH-55] Matching a sequence with just a rest pattern fails to compile Created: 21/Mar/12 Updated: 16/Jun/13 Resolved: 16/Jun/13 |
|
| Status: | Resolved |
| Project: | core.match |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Defect | Priority: | Major |
| Reporter: | Hugo Duncan | Assignee: | David Nolen |
| Resolution: | Completed | Votes: | 0 |
| Labels: | None | ||
| Description |
|
In 0.2.0-alpha9, (match [ [1 2] ] [([& _] :seq)] true)
fails to compile with No method in multimethod 'to-source' for dispatch value: class clojure.core.match.RestPattern |
| Comments |
| Comment by David Nolen [ 16/Jun/13 4:13 PM ] |
|
fixed, http://github.com/clojure/core.match/commit/d09ef3bf3d4264aee0c6da5436b760a996811e17 |
[MATCH-2] Matching Diagnostics Created: 04/Sep/11 Updated: 16/Jun/13 |
|
| Status: | Open |
| Project: | core.match |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Enhancement | Priority: | Minor |
| Reporter: | David Nolen | Assignee: | David Nolen |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Description |
|
Communicate to the user precisely what failed to match. Conversation here: http://groups.google.com/group/clojure/browse_thread/thread/675456fba1712214. We adopt the behavior of condp since that is closer to what match does and will do (predicate dispatch) |
| Comments |
| Comment by David Nolen [ 05/Sep/11 10:40 AM ] |
|
Continuing the conversation from GitHub - concerning your changes, we should probably show what current occurrence failed to match as well as the breadcrumb. |
| Comment by David Nolen [ 26/Sep/11 7:10 AM ] |
|
Matching diagnostics will be complicated by |
| Comment by Ambrose Bonnaire-Sergeant [ 30/Sep/11 4:39 AM ] |
|
I haven't yet kept up with your backtracking changes, and I just noticed this conversation, so I'll have to have another look at diagnostics with backtracking. |
| Comment by David Nolen [ 16/Jun/13 1:57 PM ] |
|
Lowering priority. Happy to take a patch, but I don't think I'll be looking into this myself in the near future. |
[MATCH-63] IllegalArgumentException when AOT compiling namespace using clojure.core.match since alpha10 Created: 08/Aug/12 Updated: 15/Jun/13 Resolved: 15/Jun/13 |
|
| Status: | Resolved |
| Project: | core.match |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Defect | Priority: | Major |
| Reporter: | Paudi Moriarty | Assignee: | David Nolen |
| Resolution: | Completed | Votes: | 3 |
| Labels: | None | ||
| Environment: |
core.match 0.2.0-alpha10 and 0.2.0-alpha11-SNAPSHOT (git 7ad66cc) |
||
| Attachments: |
|
| Description |
|
Getting this when AOT compiling a trivial project (attached) using alpha10: (works fine with alpha9) Caused by: java.lang.IllegalArgumentException: No method in multimethod 'to-source' for dispatch value: class clojure.core.match.WildcardPattern
at clojure.lang.MultiFn.getFn(MultiFn.java:121)
at clojure.lang.MultiFn.invoke(MultiFn.java:167)
at clojure.core.match$dag_clause_to_clj.invoke(match.clj:424)
at clojure.lang.AFn.applyToHelper(AFn.java:167)
at clojure.lang.AFn.applyTo(AFn.java:151)
at clojure.core$apply.invoke(core.clj:602)
at clojure.lang.AFn.applyToHelper(AFn.java:167)
at clojure.lang.RestFn.applyTo(RestFn.java:132)
at clojure.core$apply.invoke(core.clj:604)
at clojure.core$partial$fn__3796.doInvoke(core.clj:2343)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.core$map$fn__3811.invoke(core.clj:2430)
at clojure.lang.LazySeq.sval(LazySeq.java:42)
at clojure.lang.LazySeq.seq(LazySeq.java:60)
at clojure.lang.RT.seq(RT.java:466)
at clojure.core$seq.invoke(core.clj:133)
at clojure.core$apply.invoke(core.clj:600)
at clojure.core$mapcat.doInvoke(core.clj:2459)
at clojure.lang.RestFn.invoke(RestFn.java:423)
at clojure.core.match.SwitchNode.n_to_clj(match.clj:446)
at clojure.core.match.BindNode.n_to_clj(match.clj:411)
at clojure.core.match$executable_form.invoke(match.clj:1713)
at clojure.core.match$clj_form.invoke(match.clj:1721)
at clojure.core.match$match.doInvoke(match.clj:1750)
|
| Comments |
| Comment by Frederik De Bleser [ 20/Nov/12 4:18 PM ] |
|
I can confirm the same issue on alpha11. |
| Comment by David Nolen [ 23/Nov/12 4:52 PM ] |
|
I believe I may have found the cause and have fixed master - if someone can confirm I'll happily cut another release. http://github.com/clojure/core.match/commit/cbcc6e5fa070a7025e72f5eab4e83eaec100332b |
| Comment by Paudi Moriarty [ 15/Jan/13 9:42 AM ] |
|
Thanks David, That change has not fixed the issue for me. |
| Comment by Paudi Moriarty [ 15/Jan/13 9:56 AM ] |
|
So the pattern parameter being passed to dag-clause-to-clj: (defn dag-clause-to-clj [occurrence pattern action]
(let [test (if (instance? clojure.core.match.IPatternCompile pattern)
(to-source* pattern occurrence)
(to-source pattern occurrence))]
...
is a WildcardPattern which doesn't implement IPatternCompile and doesn't have a to-source method. So it seems it shouldn't be passed at all. Indeed, in normal usage it isn't. ;; ## Wildcard Pattern ;; ;; A wildcard pattern accepts any value. ;; ;; In practice, the DAG compilation eliminates any wildcard patterns. (defprotocol IWildcardPattern (sym [this])) (deftype WildcardPattern [sym _meta] IWildcardPattern (sym [_] sym) clojure.lang.IObj (meta [_] _meta) (withMeta [_ new-meta] (WildcardPattern. sym new-meta)) Object (toString [_] (str sym))) |
| Comment by David Nolen [ 15/Jan/13 11:17 AM ] |
|
Can you include an example pattern which works under normal circumstances but fails under AOT? This must meant that WildcardPatterns are making it through under AOT and getting to the multimethod case but not under incremental compilation at the REPL. |
| Comment by Paudi Moriarty [ 16/Jan/13 9:34 AM ] |
|
This seems to do it: (match {}
{:a :x :b b} :dummy
:else :dummy)
|
| Comment by Tim Olsen [ 26/Feb/13 1:55 PM ] |
|
I've seen this problem as well. If I try to compile a second time, however, without running lein clean, the compilation succeeds. Maybe it's a bootstrapping problem? |
| Comment by David Nolen [ 15/Jun/13 10:38 PM ] |
|
as far as I can tell, this is the same issue as |
[MATCH-65] cata matching Created: 23/Nov/12 Updated: 15/Jun/13 |
|
| Status: | Open |
| Project: | core.match |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Enhancement | Priority: | Minor |
| Reporter: | David Nolen | Assignee: | David Nolen |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Description |
|
Dan Friedman's pattern matcher has a nice feature called cata-matching - allowing recursive matching from the match itself. Useful when writing compilers. |
[MATCH-54] Cannot AOT with certain match expression. Created: 04/Mar/12 Updated: 15/Jun/13 Resolved: 15/Jun/13 |
|
| Status: | Resolved |
| Project: | core.match |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Defect | Priority: | Major |
| Reporter: | Jason Jackson | Assignee: | David Nolen |
| Resolution: | Completed | Votes: | 0 |
| Labels: | None | ||
| Description |
|
If you try to AOT this code, you get an exception. (defn -main [& args]
(println args)
(let [x nil]
(match x
["=" _ _] true
[[:invoke _] _] true)))
Stack Trace: Compiling foo.core Exception in thread "main" java.lang.IndexOutOfBoundsException, compiling:(foo/core.clj:8) at clojure.lang.Compiler.analyzeSeq(Compiler.java:6416) at clojure.lang.Compiler.analyze(Compiler.java:6216) at clojure.lang.Compiler.analyze(Compiler.java:6177) at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5572) at clojure.lang.Compiler$LetExpr$Parser.parse(Compiler.java:5873) at clojure.lang.Compiler.analyzeSeq(Compiler.java:6409) at clojure.lang.Compiler.analyze(Compiler.java:6216) at clojure.lang.Compiler.analyzeSeq(Compiler.java:6397) at clojure.lang.Compiler.analyze(Compiler.java:6216) at clojure.lang.Compiler.analyze(Compiler.java:6177) at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5572) at clojure.lang.Compiler$FnMethod.parse(Compiler.java:5008) at clojure.lang.Compiler$FnExpr.parse(Compiler.java:3629) at clojure.lang.Compiler.analyzeSeq(Compiler.java:6407) at clojure.lang.Compiler.analyze(Compiler.java:6216) at clojure.lang.Compiler.analyzeSeq(Compiler.java:6397) at clojure.lang.Compiler.analyze(Compiler.java:6216) at clojure.lang.Compiler.access$100(Compiler.java:37) at clojure.lang.Compiler$DefExpr$Parser.parse(Compiler.java:492) at clojure.lang.Compiler.analyzeSeq(Compiler.java:6409) at clojure.lang.Compiler.analyze(Compiler.java:6216) at clojure.lang.Compiler.analyze(Compiler.java:6177) at clojure.lang.Compiler.compile1(Compiler.java:6980) at clojure.lang.Compiler.compile(Compiler.java:7046) at clojure.lang.RT.compile(RT.java:385) at clojure.lang.RT.load(RT.java:425) at clojure.lang.RT.load(RT.java:398) at clojure.core$load$fn__4610.invoke(core.clj:5386) at clojure.core$load.doInvoke(core.clj:5385) at clojure.lang.RestFn.invoke(RestFn.java:408) at clojure.core$load_one.invoke(core.clj:5200) at clojure.core$compile$fn__4615.invoke(core.clj:5397) at clojure.core$compile.invoke(core.clj:5396) at user$eval27.invoke(NO_SOURCE_FILE:1) at clojure.lang.Compiler.eval(Compiler.java:6465) at clojure.lang.Compiler.eval(Compiler.java:6455) at clojure.lang.Compiler.eval(Compiler.java:6431) at clojure.core$eval.invoke(core.clj:2795) at clojure.main$eval_opt.invoke(main.clj:296) at clojure.main$initialize.invoke(main.clj:315) at clojure.main$null_opt.invoke(main.clj:348) at clojure.main$main.doInvoke(main.clj:426) at clojure.lang.RestFn.invoke(RestFn.java:421) at clojure.lang.Var.invoke(Var.java:405) at clojure.lang.AFn.applyToHelper(AFn.java:163) at clojure.lang.Var.applyTo(Var.java:518) at clojure.main.main(main.java:37) Caused by: java.lang.IndexOutOfBoundsException at clojure.lang.PersistentVector.arrayFor(PersistentVector.java:106) at clojure.lang.PersistentVector.nth(PersistentVector.java:110) at clojure.lang.RT.nth(RT.java:741) at clojure.core.match.PatternRow.invoke(match.clj:327) at clojure.core.match.PatternMatrix.pattern_at(match.clj:713) at clojure.core.match$useful_p_QMARK_.invoke(match.clj:778) at clojure.core.match.PatternMatrix$iter__832__838$fn__839$iter__834__840$fn__841$fn__842.invoke(match.clj:735) at clojure.core.match.PatternMatrix$iter__832__838$fn__839$iter__834__840$fn__841.invoke(match.clj:733) at clojure.lang.LazySeq.sval(LazySeq.java:42) at clojure.lang.LazySeq.seq(LazySeq.java:60) at clojure.lang.RT.seq(RT.java:466) at clojure.core$seq.invoke(core.clj:133) at clojure.core.match.PatternMatrix$iter__832__838$fn__839.invoke(match.clj:734) at clojure.lang.LazySeq.sval(LazySeq.java:42) at clojure.lang.LazySeq.seq(LazySeq.java:67) at clojure.lang.RT.seq(RT.java:466) at clojure.core$seq.invoke(core.clj:133) at clojure.core$partition$fn__3913.invoke(core.clj:2777) at clojure.lang.LazySeq.sval(LazySeq.java:42) at clojure.lang.LazySeq.seq(LazySeq.java:60) at clojure.lang.RT.seq(RT.java:466) at clojure.core$seq.invoke(core.clj:133) at clojure.core$map$fn__3811.invoke(core.clj:2424) at clojure.lang.LazySeq.sval(LazySeq.java:42) at clojure.lang.LazySeq.seq(LazySeq.java:60) at clojure.lang.Cons.next(Cons.java:39) at clojure.lang.PersistentVector.create(PersistentVector.java:50) at clojure.lang.LazilyPersistentVector.create(LazilyPersistentVector.java:31) at clojure.core$vec.invoke(core.clj:345) at clojure.core.match.PatternMatrix.useful_matrix(match.clj:733) at clojure.core.match.PatternMatrix.necessary_column(match.clj:725) at clojure.core.match.PatternMatrix$choose_column__815.invoke(match.clj:690) at clojure.core.match.PatternMatrix.compile(match.clj:708) at clojure.core.match$first_column_chosen_case$switch_clauses__780$fn__781.invoke(match.clj:613) at clojure.core$map$fn__3815.invoke(core.clj:2437) at clojure.lang.LazySeq.sval(LazySeq.java:42) at clojure.lang.LazySeq.seq(LazySeq.java:60) at clojure.lang.RT.seq(RT.java:466) at clojure.core$seq.invoke(core.clj:133) at clojure.core$reduce.invoke(core.clj:5994) at clojure.core$into.invoke(core.clj:6004) at clojure.core.match$first_column_chosen_case$switch_clauses__780.invoke(match.clj:616) at clojure.core.match$first_column_chosen_case.invoke(match.clj:646) at clojure.core.match.PatternMatrix.compile(match.clj:710) at clojure.core.match$first_column_chosen_case$switch_clauses__780$fn__781.invoke(match.clj:613) at clojure.core$map$fn__3815.invoke(core.clj:2437) at clojure.lang.LazySeq.sval(LazySeq.java:42) at clojure.lang.LazySeq.seq(LazySeq.java:60) at clojure.lang.RT.seq(RT.java:466) at clojure.core$seq.invoke(core.clj:133) at clojure.core$reduce.invoke(core.clj:5994) at clojure.core$into.invoke(core.clj:6004) at clojure.core.match$first_column_chosen_case$switch_clauses__780.invoke(match.clj:616) at clojure.core.match$first_column_chosen_case.invoke(match.clj:646) at clojure.core.match.PatternMatrix.compile(match.clj:710) at clojure.core.match$clj_form.invoke(match.clj:1616) at clojure.core.match$match.doInvoke(match.clj:1645) at clojure.lang.RestFn.invoke(RestFn.java:573) at clojure.lang.Var.invoke(Var.java:426) at clojure.lang.AFn.applyToHelper(AFn.java:193) at clojure.lang.Var.applyTo(Var.java:518) at clojure.lang.Compiler.macroexpand1(Compiler.java:6320) at clojure.lang.Compiler.analyzeSeq(Compiler.java:6395) ... 46 more |
| Comments |
| Comment by David Nolen [ 15/Jun/13 10:33 PM ] |
|
as far as I can tell this AOT bug is resolved in master |
[MATCH-70] Matches against maps are treated as wildcards, even though they are not Created: 29/May/13 Updated: 15/Jun/13 Resolved: 15/Jun/13 |
|
| Status: | Resolved |
| Project: | core.match |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Defect | Priority: | Major |
| Reporter: | David Pollak | Assignee: | David Nolen |
| Resolution: | Completed | Votes: | 0 |
| Labels: | None | ||
| Attachments: |
|
| Patch: | Fixed |
| Description |
|
The following tests fail: (deftest map-pattern-match-bind-2
(is (= (let [xqq {:cz 1 :dz 2}]
(match [xqq]
[{:z a :zz b}] [:a0 a b]
[{:cz a :dz b}] [:a2 a b]
:else []))
[:a2 1 2])))
(deftest map-pattern-match-bind-3
(is (= (let [xmm {:bz 2}]
(match [xmm]
[{:az a}] [:a0 a]
[{:bz b}] [:a1 b]
:else []))
[:a1 2])))
|
| Comments |
| Comment by David Nolen [ 29/May/13 8:26 PM ] |
|
Thanks for the patch but this won't work - this defeats sharing tests. I'm looking into it. |
| Comment by David Pollak [ 29/May/13 10:38 PM ] |
|
Thanks David. I was thinking about putting a "is this really a wildcard" flag on Wildcard and set it to false for Wildcards in MapPattern. Anyway... if you want me to keep working on the issue, I'll be glad to. If my clumsy code and clumsy approach doesn't help... I'm down for sitting on the sidelines and watching you do the work. |
| Comment by David Nolen [ 30/May/13 12:35 AM ] |
|
The issue is a bit trickier than it seems. core.match is written in a way such that we always try to share tests across patterns as much as possible. For example consider what happens with map patterns: (match [x]
[{:a _ :b 1}] ...
[{:b _ :c 2}] ...)
In order to do optimal test sharing we expand the above into the following more or less (which is wrong): :a :b :c [_ 1 _] [_ _ 2] The problem here is that only the last element in the first row and the first element of the second row are true wildcards. Currently as you discovered the analysis doesn't consider the fact that the other wildcards really must be tested. So really we want something like the following: :a :b :c [V(_) 1 _] [_ V(_) 2] Here you can see we wrap the wildcard in a new pattern type - MapValuePattern. This will prevent the bad analysis. I hope this makes sense - I've started implementing this and I don't think it will take me too long. Just to make it a bit more clear imagine the following: (match [x]
[{:a _ :b _}] ...
[{:b _ :c _}] ...)
:a :b :c [V(_) V(_) _ ] [_ V(_) V(_)] The wrapping now prevents the first row from being considered a row of wildcards. |
| Comment by David Nolen [ 02/Jun/13 11:33 AM ] |
|
This should be fixed in master as of this commit http://github.com/clojure/core.match/commit/a07c2e9620df5b9d331bd6c380d47c15bf7cd60d Let me know if it works for you. |
| Comment by David Pollak [ 02/Jun/13 1:00 PM ] |
|
Awesome. Thanks! Please let me know when there are new JAR files in clojars. |
| Comment by David Nolen [ 15/Jun/13 10:30 PM ] |
|
this has been resolved http://github.com/clojure/core.match/commit/a07c2e9620df5b9d331bd6c380d47c15bf7cd60d |
[MATCH-57] Non deterministic match behavior for seqs when AOT Created: 05/Apr/12 Updated: 15/Jun/13 Resolved: 15/Jun/13 |
|
| Status: | Resolved |
| Project: | core.match |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Defect | Priority: | Major |
| Reporter: | Ronen Narkis | Assignee: | David Nolen |
| Resolution: | Completed | Votes: | 0 |
| Labels: | None | ||
| Environment: |
Clojure 1.3 Leiningen 1.7.1 on Java 1.6.0_26 core.match "0.2.0-alpha9" |
||
| Description |
|
The following source example: https://github.com/narkisr/match-issue/blob/master/src/match_issue/core.clj The defrule macro calls a function called lhs that use the match library, this function calls it self recursively and print out the rest of body left to be matched, When running lein compile two different results appear (in non deterministic fashion): (when $message :> Message (== level 6) :from (entry-point event-stream)) This is the bug, as (== level 6) should be matched by: [([([(o :when operator?) f s] :seq) :as c & r] :seq)] In other cases the output is (the correct one): (when $message :> Message (== level 6) :from (entry-point event-stream)) |
| Comments |
| Comment by David Nolen [ 06/Apr/12 11:03 AM ] |
|
All AOT related issues w/o patches are low priority for the foreseeable future. They are simply too time consuming to track down and I don't have the bandwidth at the moment. I will get to them eventually, but if you want movement on this please submit a patch. I will happily apply it! |
| Comment by Ronen Narkis [ 07/Apr/12 7:53 PM ] |
|
Hey David, After going through the source code and some more in depth look I managed to understand what was going on, first iv stepped through the different stages (def m (emit-matrix ['body] (def c (cm/compile m)) (pprint c) (pprint (executable-form c)) The last pprint failed aot compilation: $ lein compile ... Which was very weird as I could clearly see that: (deftype WildcardPattern [sym _meta] Then iv also tried to enabled trace: (set-trace! true) Which resulted with: $ lein compile ... TRACE: DAG: Column 0 : [#<SeqPattern #<LiteralPattern window> #<LiteralPattern :time> #<WildcardPattern t> #<WildcardPattern unit>>] The most weird thing was that on second compile it all went well, this raised a flag and my suspicion was that the core.match classes got compiled on the first run: $ ls classes/ match$analyze_actions$analyze_action__1166.class Then iv decided to AOT compile clojure.core match: $ git checkout core.match-0.2.0-alpha9
After using the aot jar it all went smooth including passing my non deterministic case (which is deterministic but very confusing to track down), In order to reproduce it its important to run: $ lein clean And only then run $ lein compile Otherwise the classes dir might contain AOT'ed classes and make it seem that even non-aot jar works fine (its enough to run lein compile once to cause the classes to get compiled), The fix in my case is simple, just AOT ns. Im not sure if this Is a bug in the way Clojure AOT its classes but I think that adding the AOT'ed classes to the default core match distro is a reasonable workaround BTW when using master (and not the tag) iv stumbled upon: Exception in thread "main" java.lang.AssertionError: Assert failed: Unknown predicate in [is-type?] Which is a pred defined in my ns. |
| Comment by David Nolen [ 15/Jun/13 10:30 PM ] |
|
This sounds very similar to the other AOT bug reported by Kevin Lynagh |
[MATCH-36] throw on unsuccessful match Created: 27/Oct/11 Updated: 15/Jun/13 Resolved: 15/Jun/13 |
|
| Status: | Resolved |
| Project: | core.match |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Defect | Priority: | Critical |
| Reporter: | David Nolen | Assignee: | David Nolen |
| Resolution: | Completed | Votes: | 1 |
| Labels: | None | ||
| Description |
|
I was on the fence about this. But after looking at the literature as well as the behavior of condp, I've decided that throwing on unsuccessful match is the way to go. This is particularly important since we put no constraints on the types allowed - we cannot determine exhaustiveness. |
| Comments |
| Comment by David Pollak [ 28/May/13 10:20 AM ] |
|
FWIW, I think the existing behavior (returning a nil) is the correct behavior. If a user wants to throw an exception, they can add an :else clause. Why is the existing behavior correct? Think of a Map as a match. When you look up a key that is not in the Map, you get a nil. There are simple ways to add additional behavior to maps to return something other than a nil, but the default is nil. A Map, like a pattern match, is defined at some values of the input and not other values of the input. |
| Comment by David Nolen [ 28/May/13 10:26 AM ] |
|
The behavior aligns with Clojure's case. The issue is that Clojure being dynamically typed (and match actively taking advantage of this) can't really do exhaustiveness checking in all cases - I think throwing is desirable, and experience seems to suggest this as well - otherwise nils will flow in likely unintentional ways. Users can always add the explicit nil return if they like. I suspect users will not do this. |
| Comment by David Nolen [ 15/Jun/13 10:27 PM ] |
|
fixed, http://github.com/clojure/core.match/commit/63e56f524e60644460a9e43e1312966c42c3a5d5 |
[MATCH-64] Improve match compile times Created: 15/Aug/12 Updated: 15/Jun/13 |
|
| Status: | Open |
| Project: | core.match |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Enhancement | Priority: | Minor |
| Reporter: | David Nolen | Assignee: | David Nolen |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
[MATCH-61] Exception thrown when matching using :seq when there is a seq call in the tail of the occurrences Created: 22/Jun/12 Updated: 15/Jun/13 |
|
| Status: | Open |
| Project: | core.match |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Defect | Priority: | Major |
| Reporter: | Emma Tosch | Assignee: | David Nolen |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | bug, seq | ||
| Environment: |
with Clojure 1.3 |
||
| Description |
|
The following match throws: (let [q '(a) y '(b) z '(c)] (match [q (seq y) z] [([_] :seq) _ _] 'a [_ _ _] 'b)) Looking at the macro expansion there's something clearly wrong simply with the fact that the seq expression occurs in multiple places instead of just at the beginning of the macro expansion. |
| Comments |
| Comment by Emma Tosch [ 22/Jun/12 5:33 PM ] |
|
https://gist.github.com/626088b01817ac638fae (clojure.core/let [q_tail_3472 q_tail_3472 |
[MATCH-51] Fail to match empty vector Created: 21/Jan/12 Updated: 15/Jun/13 Resolved: 15/Jun/13 |
|
| Status: | Resolved |
| Project: | core.match |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Defect | Priority: | Major |
| Reporter: | Jason Jackson | Assignee: | David Nolen |
| Resolution: | Completed | Votes: | 0 |
| Labels: | None | ||
| Description |
(match (vector) ([(re :guard string?)] :seq) 4 [] 6) This should evaluate to 6 not nil. |
| Comments |
| Comment by Jason Jackson [ 21/Jan/12 9:30 AM ] |
|
tested on 0.2.0-alpha10-SNAPSHOT |
| Comment by David Nolen [ 15/Jun/13 10:03 PM ] |
|
resolved in master, added test case http://github.com/clojure/core.match/commit/b21d1a09e0d495003fc45ca48568355609ed69bd |
[MATCH-53] Match doesn't work when AOT compiled into a JAR, but manually macroexpanding and JAR'ing works fine. Created: 24/Feb/12 Updated: 15/Jun/13 Resolved: 15/Jun/13 |
|
| Status: | Resolved |
| Project: | core.match |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Defect | Priority: | Major |
| Reporter: | Kevin Lynagh | Assignee: | David Nolen |
| Resolution: | Completed | Votes: | 0 |
| Labels: | None | ||
| Description |
|
Code here: https://gist.github.com/35fa11df7d7516abff50 Running lein uberjar on source containing the offending function, geo->svg, results in a non-working application. |
| Comments |
| Comment by Kevin Lynagh [ 24/Feb/12 2:27 PM ] |
|
"non-working" meaning that the match always drops directly the :else clause. |
| Comment by Kevin Lynagh [ 24/Feb/12 6:09 PM ] |
|
Updated code to minimal example. Problem persists with both Lein 1.7 and cake 0.6.3 |
| Comment by David Nolen [ 25/Feb/12 7:35 PM ] |
|
AOT bugs are a bit tricky to track down. Not sure how soon I'll be able to really dive into this one. |
| Comment by David Nolen [ 15/Jun/13 10:00 PM ] |
|
this AOT case at least is resolved on master. |