Fork me on GitHub
#clojuredesign-podcast
<
2020-11-25
>
jrwdunham06:11:32

Hey! I enjoyed the branching out episode. In it, one of you stated that the problem with case, cond and condp was that the return value of the condition is not available to the consequent. However, the ternary clause form of the condp macro does actually pass the return value of the condition to the consequent, which is a function:

=> (let [sorter (fn [s]
                  (condp re-matches s
                    #"(.+)@(gmail|yahoo)\.(.+)" :>>
                    (fn [[_ email domain tld]] {:email email :domain domain :tld tld})
                    #"(.+)@(.+)\.(.+)" :>>
                    (fn [[_ email domain tld]] {:email email :unverified-domain domain :tld tld})
                    #"(.+)@(.+)" :>>
                    (fn [[_ email domain]] {:email email :unparsed-domain domain})))]
     (map sorter ["" "" "me@abc"]))
({:email "me", :domain "gmail", :tld "com"}
 {:email "me", :unverified-domain "hotmail", :tld "com"}
 {:email "me", :unparsed-domain "abc"})

nate17:11:01

you are absolutely right

nate17:11:55

funny thing is, I was listening to the episode and preparing the notes and happened to look at the condp doc page again, and I saw the ternary form and laughed

nate17:11:52

I was ranting about cond (which I use far more) during the condp section of the episode and condp doesn't have that problem

nate17:11:18

I won't soon forget this and I'll probably use condp a little more now

jrwdunham17:11:02

Yeah, I might use it more for this reason too. I thought during the podcast one of you was trying to lead into this usage of condp, but you got distracted. anyway

jrwdunham18:11:42

Has anyone here found themselves missing pattern-matching in Clojure? Given all the branching constructs discussed in the last episode, as well as Clojure's destructuring and multimethods, I haven't really found myself wishing Clojure had it. However, I don't have much experience working in Erlang or other languages that use it all the time, so maybe I don't know what I'm missing. I know we have libraries like https://git.sr.ht/~technomancy/fnl-match — any thoughts on that? I guess an issue with that kind of approach is that you have to invoke the match macro explicitly: it would be better if you could have pattern-matching built right into function signatures. I guess you could write your own defn macro to do that, but then you're veering quite far away from Clojure idiomaticity...

nate18:11:58

I remember using pattern matching a lot in my limited time in scala, mostly to deal with maybes. all the things you mention chip away at use cases for pattern matching, and I think nil punning takes care of the remainder

neumann22:11:12

@UCSDH9JQ7 I haven't used fnl-match myself, but I have used https://github.com/clojure/core.match in a few places. When writing Haskell, Erlang, and Scala, I used pattern matching a lot, but I have found that I don't use it as much in Clojure. I think that's because I uses maps quite a lot more than tuples.

neumann22:11:40

In Clojure, it's more typical for me to have a map with optional keys and do logic based on those keys existing. I can destructure out all the keys I want and just check the optional ones for nil values.

genekim19:11:33

I'm having great fun using this: https://github.com/killme2008/defun I loved this talk from Sean Johnson on pattern matching from Clojure/conj 2015, especially when he describes his experiences 1) not using any pattern matching, 2) maximal use of pattern matching, replacing all conditionals, and 3) a middle-ground. And his code review of Rich Hickey code b/c of nested ifs, noting it could be made more legible with pattern matching. 😂😂 https://youtu.be/n7aE6k8o_BU

genekim19:11:20

Does fnl support the use of guards? defun supports it, like so: (defun funny ([(N :guard #(= 42 %))] true) ([_] false)) (funny 42) ;; true (funny 43) ;; false