I wonder how well this approach scales for switch expressions, though.
I recently looked into how to compile them (for a different language) and it feels like it’s a tough problem if one isn’t content with settling with “compare common part with each branch by equality”, e. g.
.. is Person("Joe", "Smith", 45) then true
.. .firstName == "john" then true
.. .age + 23 > jane.age then true
On one hand you only want to evaluate the shared part once, but for type-checking purposes on the other hand you want to fuse the shared part into each branch, etc.
I don’t claim to be doing the most scalable approach :) But also I am not quite sure what you mean – I am not familiar with the “compare common part” approach. I’ve never tried to compile pattern matching, only simple if.
I don’t quite follow @soc’s example, but I think it would be like de-sugaring
(case (most-recent person)
(1 (println "1"))
(2 (println "2")))
(let ((x (most-recent person)))
(if (= x 1)
(if (= x 2)
where the “common part” is the binding for x to avoid repetitive calls to (most-recent person). Of course all of that could be done between the reader and the compiler.
Clojure’s ‘core.match’ library has some nice references to papers on fast pattern matching (the generalized case of switch). It tries to make pattern matching faster by creating an optimal sequence of comparisons to “search” the space of possible matches. That’s as opposed to just compiling the patterns in the order they appear. IIRC this is also done all in macro-land before the code gets compiled.
I apologize, it wasn’t meant as a criticism!
Lol no need for an apology I’m just trying to figure out where I could work that sort of thing into the project