This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-11-25
Channels
- # adventofcode (1)
- # announcements (1)
- # beginners (244)
- # calva (20)
- # cider (11)
- # cljs-dev (34)
- # clojure (50)
- # clojure-spec (1)
- # clojure-uk (3)
- # clojurebridge (1)
- # clojurescript (21)
- # code-reviews (1)
- # cursive (19)
- # events (1)
- # expound (1)
- # fulcro (65)
- # hyperfiddle (6)
- # luminus (3)
- # nrepl (3)
- # off-topic (23)
- # protorepl (4)
- # re-frame (18)
- # rum (11)
- # shadow-cljs (77)
- # spacemacs (8)
- # tools-deps (2)
- # unrepl (1)
- # vim (2)
@cfleming: I have an external tool similar to the IntelliJ Todo "applet" -- it collects comments matching a certain regex, and when you click on the comment, it jumps the IDE to the corresponding file/line
Clojure gurus! I'd like to have a short comment to one design decision. I have three various environments which all connect to their data sources a bit differently and also the data processing is a bit different. I need to implement n different functions for data processing. I could do this using multimethods and dispatch based on environmental variable value which I know for each environment (defined in profiles.clj). But I was wondering if this could be implemented more elegantly e.g. using protocols. Any suggestions?
I was reading about protocols in "Joy of Clojure" and "Clojure Applied". I think I have an idea how to do it more elegantly. I create one namespace per one environment/defrecord definition, and inside that defrecord I define the data processing functions for that environment. I'll create a git branch for this and experiment a bit. Clojure is so fun. ๐
Damn, I love Clojure REPL. And using IntelliJ IDEA with Cursive and its REPL makes experimenting with the code so fluent and fast. I was having major difficulties to figure out how to call function b from function a using the same protocol. Then I experimented it using REPL and figured out how to do it in a couple of minutes just by experimenting.
"You're living in your program invoking your tools, instead of living in your tools invoking your program" - Stuart Halloway.
But... I have one issue I can't figure out how to do and the Clojure books I have doesn't provide an example for that.
And what would that be?
(defprotocol EmailProtocol (lowername [this name]) (email [this host])) (defrecord EmailRecord [ourcompany] EmailProtocol (lowername [this name] (clojure.string/lower-case name)) (email [this contractor] (let [contractorname (lowername this contractor) companyname (lowername this ourcompany)] (str "ext-" contractorname "@" companyname))))
This works well when EmailProtocol and EmailRecord are in the same namespace...
But if I put EmailRecord into another namespace then Clojure complains that it cannot find function lowercase...
(def ourcompany (->EmailRecord "CoolCompany")) (lowername ourcompany "David") => "david" (email ourcompany "David") => "ext-david@coolcompany"
So, if defrecord EmailRecord is defined in another namespace, the Clojure complains that: Unable to resolve symbol: lowername in this context
Please evaluate the following forms in your repl.
(ns pro)
(defprotocol EmailProtocol
(lowername [this name])
(email [this host]))
(ns user)
(require '[pro])
(defrecord EmailRecord [ourcompany]
pro/EmailProtocol
(lowername [this name] (clojure.string/lower-case name))
(email [this contractor]
(let [contractorname (pro/lowername this contractor)
companyname (pro/lowername this ourcompany)]
(str "ext-" contractorname "@" companyname))))
(def ourcompany (->EmailRecord "CoolCompany"))
(pro/lowername ourcompany "David")
(pro/email ourcompany "David")
You wanna require and namespace qualify the protocol.
Hope this helps.
Damn, that worked. Why didn't I figure that out. ๐
Thanks a lot!
I defined the protocol (abstraction) in the namespace pro
and depend on (`require`) the abstraction in the implementation, the user
namespace.
Anytime!
In fact, the definition of the protocol, the record/type, and the coupling of the protocol and the implementation can be in three different namespaces.
With extend-type
This means you can extend a third party type to a protocol by yet another third party in your namespace.
They seem to be very powerful abstraction.
This is Clojure's solution to the expression problem. https://en.wikipedia.org/wiki/Expression_problem
who needs types anyway
everything is a pixel type ๐
Hi, how can I append into an atom?
(def tv-state {:tales [{m1} {m2} {m3}]})
I want to (swap! tv-state ??? [:tales] m4)
to get tv-state {:tales [{m1} {m2} {m3} {m4}]}
? did you delete your solution? it worked haha
I wanted to test in a repl ๐
XD i just tried it and it works perfectly
(swap! tv-state update :tales conj m4)
(swap! tv-state update :tiles conj new-post-map)
thanks ๐
no problem!
I took me a mental leap to understand that the first time.
You are calling update
on the the value of tv-state
and you are passing conj new-post-map
as the arguments to update
i kept putting [:tiles]
instead of just :tiles
so many tabs in search of the answer... so thanks ๐
how do I ignore a variable when unifying in core.logic? the usual suspect of _
fails in this case: (== x [_ b])
not sure if this is what youโre looking for, but you could introduce a new, unbound logic variable in that position: (== x [(lvar) b])
@sova If you use update-in
, you can pass [:tiles]
-- just in case you want to go deeper into a nested structure and need multiple levels.