Keyword literal as function apply(:<<) result

Description

Fails:

(let [x [:k1 :k2 :k3]] (m/match [x] [(:k1 :<< first)] :first))
Invalid list syntax :<< in (:k1 :<< first). Valid syntax: [[:default :guard] [:or :default] [:default :only] [:default :seq] [:default :when] [:default :as] [:default :<<] [:default :clojure.core.match/vector]]

Work:

(let [k1 :k1 x [:k1 :k2 :k3]] (m/match [x] [(k1 :<< first)] :first))

Is it a bug or a feature?
How to match keywords correctly?

Environment

[org.clojure/clojure "1.9.0-beta2"]
[org.clojure/core.match "0.3.0-alpha5"]

Activity

Show:

Greg Chapman November 2, 2017 at 9:52 PM

This is an unfortunate corner case. A list pattern is expected to have a literal keyword in position 1 or 2; the keyword is used in dispatching the emit-pattern-for-syntax multimethod. In your first case, you have literal keywords in both positions; if you look at the dispatch function for emit-pattern-for-syntax, you'll see that in this case, the first keyword wins. Since no pattern syntax is defined for :k1, you get the error. I believe quoting the :k1 literal ought to work in this case:

(let [x [:k1 :k2 :k3]] (m/match [x] [(':k1 :<< first)] :first))

Details

Assignee

Reporter

Priority

Created October 16, 2017 at 9:55 AM
Updated November 2, 2017 at 9:52 PM

Flag notifications