This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-03-01
Channels
- # announcements (1)
- # babashka (1)
- # beginners (45)
- # business (3)
- # calva (43)
- # clojure (57)
- # clojure-spec (6)
- # clojure-uk (4)
- # clojured (8)
- # clojurescript (14)
- # cryogen (3)
- # datomic (2)
- # emacs (36)
- # fulcro (20)
- # garden (2)
- # jobs (2)
- # lumo (3)
- # meander (9)
- # off-topic (1)
- # other-lisps (1)
- # reagent (13)
- # shadow-cljs (25)
- # spacemacs (20)
- # tools-deps (11)
Given:
(defn foo []
(Math/pow 2 1/2))
...I can use clj-java-decompiler and get an answer:// Decompiling class: eastwood_warning$foo
import clojure.lang.*;
public final class eastwood_warning$foo extends AFunction
{
public static final Object const__0;
public static final Object const__1;
public static Object invokeStatic() {
return Math.pow(RT.doubleCast(const__0), RT.doubleCast(const__1));
}
@Override
public Object invoke() {
return invokeStatic();
}
static {
const__0 = 2L;
const__1 = RT.readString("1/2");
}
}
hey all, i'm trying to figure out a generic way to propagate dynamic bindings onto a defrecord
's functions. in essence, what i would like to do is replace all functions in a defrecord
with ones wrapped in bound-fn
.
does anyone know of a good example what the best approach for doing this is? it seems various mocking libraries don't work with protocols / defrecord, so it appears that it's tricky to do?
This piqued my interest. However I'm not able to reproduce the issue as I undestand it - I do get 42
being printed:
(defprotocol P
(do-it [this]))
(def ^:dynamic *dyn* nil)
(defrecord R []
P
(do-it [this]
(println *dyn*)))
(binding [*dyn* 42]
(-> (R.) (do-it)))
it doesn't work when you pass around the record as value, thus losing the dynamic thread bound variables
usually one would wrap the callback functions using bound-fn, but with records/protocols this is a bit more tricky
Interestingly, the following prints nil:
(let [record (R.)]
(binding [*dyn* 42]
(-> (Thread. #(-> record (do-it)))
.start)))
...but if I change the Thread.
for a future
, I get 42 printedyes this is an issue "by design", dynamic bindings are not supposed to automatically propagate. this is why clojure provides functions bound-fn
, bound-fn*
and with-conveyed-bindings
, and i'm now struggling to figure out how to use these in combination with records/protocols
I'm not sure bound-fn
will make arbitrary concurrent facilities work.
Still, you may want to play with metadata extension:
(defprotocol P
:extend-via-metadata true
(do-it [this]))
(def ^:dynamic *dyn* nil)
(defn make-record []
^{`do-it (bound-fn [this]
(println *dyn*))}
{:id 42
:age 60})
(binding [*dyn* 52] (-> (make-record) (do-it)))
one approach i'm thinking of is creating an entirely new type, and use extend-protocol for each function with the exact same signature
One common approach (albeit, it's probably based on different considerations) is to make all record functions "private" (start the names with -
) and instead call them from regular functions in the same namespace.
hmmm but doesn't that mean that then the record itself don't contain the bindings anymore, thus losing the ability to just pass around the record as value ?
i'm almost inclined to implement a wrapper aorund the defrecord macro itself for this
Or maybe I misunderstand the question, given your response in the other thread. Sorry, I meant something like
(defprotocol P
(-f [this]))
(defrecord R [a b c]
P
(-f [_] ...))
(defn f [r]
(-f r))
right, but wouldn't it mean if i pass r
through some async context / to another thread, it loses any dynamic bindings ?
A, so you don't want to manually use bound-fn
in f
, you want just to say something like (with-all-bound-fn rec)
?
(defrecord WithConveyedBindings [bindings that]
p/MyProtocol
(start! [this]
(with-bindings [bindings]
(p/start! that))))
(defn with-conveyed-bindings [that]
(let [bindings (get-thread-bindings)]
(map->WithConveyedBindings {:bindings bindings
:that that})))
this shows at least how it could work, but it requires me to manually implement each protocol functionSorry, no idea - even if what you want is possible, it definitely requires a deeper knowledge of Clojure than I have right now. :) The only thing I can add is that dynamic bindings are evil. :D
i don’t quite understand datomic. does it often latency guarantee when the app scales out?
seems like I need to run a datomic server process on some ec2 node, and let the client talk to that server process.
@i There's a #datomic channel where folks can probably help you more.
Has anyone worked with social logins with Clojure? Is there a framework to handle it easier? Found this one https://github.com/tiensonqin/clj-social but perhaps there’s another one better…
Hi, http://conj.io is down. I don’t know who is maintaining it so if anyone knows him/her, pretty please ping them 🙂 kthx
I thought http://conj.io went offline ages ago?
https://github.com/clojure-grimoire/grimoire -- the project was archived a while back.
@seancorfield I didn’t knew it 😛 I am reading Clojure for Finance book and one chapter mentioned it. menawhile web archive has some snippets of it
@seancorfield ah ok then. I must find some alternative.
I'll caution that most Packt books are terrible, by the way.
(that book has three 1-star reviews on Amazon -- and most Packt books are similarly poorly edited)
@seancorfield oh really? dam it… it was the only one I found on this subject (clojure + finance). Do you know any better?
I don't know of any other finance-related Clojure book.
That's kind of how Packt operates tho', by finding niche topics to release bad books in, where they have no competition 😞
@seancorfield I was using oreilly library and it has few clojure books 😞
If you're trying to learn Clojure, I'd recommend Clojure for the Brave and True (has a free online version), Getting Clojure, or Living Clojure.
Ah, well... those are the best books for beginners -- everything else will seem even more advanced.
But if you have any questions, as you're learning, the #beginners channel here has a lot of people who've opted in to helping folks come up to speed on Clojure (this channel -- #clojure -- tends to lean more to established Clojure devs).
Ops sorry to start this http://conj.io thread here. I will sure move to #beginners 🙂 thanks again
The only "downside" to Brave & True, in my opinion, is that it tries to teach you Emacs at the same time as teaching you Clojure -- which is a bit overwhelming, I think. If you are comfortable with an editor that already has a Clojure integration, it's probably easier to stick with that and ignore Emacs 🙂