This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-12-03
Channels
- # adventofcode (198)
- # aleph (10)
- # announcements (7)
- # aws (17)
- # beginners (353)
- # boot (1)
- # calva (13)
- # cider (18)
- # cljdoc (2)
- # cljs-dev (11)
- # cljsrn (1)
- # clojure (87)
- # clojure-austin (1)
- # clojure-brasil (2)
- # clojure-greece (13)
- # clojure-italy (18)
- # clojure-kc (2)
- # clojure-nl (9)
- # clojure-quebec (1)
- # clojure-russia (1)
- # clojure-spec (55)
- # clojure-uk (114)
- # clojurescript (18)
- # clojurex (14)
- # code-reviews (5)
- # core-async (17)
- # cursive (23)
- # data-science (1)
- # datomic (82)
- # docker (8)
- # duct (10)
- # emacs (8)
- # figwheel (3)
- # figwheel-main (5)
- # fulcro (13)
- # hyperfiddle (8)
- # jobs (1)
- # midje (1)
- # mount (1)
- # nrepl (2)
- # off-topic (72)
- # om (2)
- # pathom (10)
- # portkey (2)
- # re-frame (9)
- # reagent (3)
- # reitit (9)
- # ring-swagger (14)
- # schema (1)
- # shadow-cljs (91)
- # spacemacs (21)
- # sql (6)
- # tools-deps (19)
- # unrepl (9)
- # vim (41)
defrecord getBasis behaves differently when used to look up record fields
(defrecord Person [name age company]) (def p1 {:name "foo", :age 27, :company :bar}) (map #(% p1) (keys p1)) ("foo" 27 :bar)user=> (map #(% p1) (Person/getBasis)) (nil nil nil nil)
user=> (map #(class %) (Person/getBasis)) (clojure.lang.Symbol clojure.lang.Symbol clojure.lang.Symbol clojure.lang.Symbol)
getBasis seems to return the symbol but the record lookup doesnt work
any idea why
I dont wish to use keys on the record instance since the instance might be missing some fields in the record
p1
has keywords for the keys, not symbols.
Also @gayathrik if you're really just getting started, it's worth noting that everyone is in this channel, but #beginners is specifically for a) folks who are just starting out and b) the folks who've opted in to helping beginners, so it's usually the better place for "just getting started" questions...
ok thanks. will post in beginner channel.
I may be bike-shedding here but isn’t the term synchronized
instead of serialized
?
I’m not a native English speaker, so maybe my understanding of serialized is wrong. I associate it more with writing data over a wire or to disk.
https://dev.clojure.org/jira/browse/CLJ-2448
it's serialized in the same sense as per https://en.wikipedia.org/wiki/Serializability I believe
but is the less important aspect
When I start REBL up, I'm getting an error WARNING: Loading FXML document with JavaFX API of version 8.0.141 by JavaFX runtime of version 8.0.60
- I got a similar error on my other machine which is using a different JDK. Is there a specific JDK I need to be running, or is there a way to load the correct version of JavaFX from my deps.edn so that I don't have to deal with changing JDKs?
@shaun-mahood I ran it without warnings on Windows 10, Leiningen 2.7.1, Java 8.
I haven't, yet, tried it on my Mac, but that's also currently running Java 8.
Got the warning on both mac and linux - linux is on openjdk and the mac has a warning when starting cursive but works otherwise. Might just have to install oracle jdk on the linux one I guess.
Until whatever date you have to start paying Oracle to use it? 😉
Isn't Oracle Java 8 always going to be under the old no-$$ license?
Yeah, although you'll stop getting (security) updates in January (unless you pay for more support, or you're only using it for non-commercial use, based on the wording on Oracle's Java SE support pages). Very strange that they'll offer free updates for Personal Use for a further year... I mean, how many people really use Java for purely non-commercial stuff?
This reminds me, I need to open a JIRA at work to switch us to a supported OpenJDK 8 or move to OpenJDK 11 and get our legacy stuff tested on it!
REBL works perfectly with Oracle Java and no warnings.
is there a sane option to host a public Clojure REPL/evaluator online without safety risks? I think I’m going to try self-hosted CLJS, but if there are JVM options I’d like to know. There is the try-clojure repo, but maybe there are others options right now?
I used clojail back in the day. Depending on the needs, if I had to do something like that today, I'd look at using kubernetes and spinning up a separate instance for each repl.
anecdotally, clojurebot
ended up needing to blacklist a lot of things, including anything that creates a var in a namespace
that's just for security, for correctness / trolling related concerns it resets the whole sandbox on a fifteen minute cycle
@noisesmith is this code available?
I think what is run in practice might be stricter than what's configured out of the box with that repo
(might be newer forks available)
I'm trying to figure out how nav
works and not having much luck. From reading the docstring, my assumption was that if I call (clojure.datafy/nav [:a :b :c] nil 0)
it should return :a
, but it seems like no matter what I try it always returns whatever I pass to v
(0 in this case). Am I totally out to lunch with what nav is for, or am I just calling the function wrong?
You are calling it wrong -- it's certainly non-obvious so I sympathize.
The args are coll k v
-- in other words, it assumes you are calling it with the already selected collection element (`v`).
I am not certain how REBL calls nav
for vectors but I would expect it to either be (d/nav [:a :b :c] 0 :a)
or (d/nav [:a :b :c] nil :a)
Certainly for hash maps, it calls (d/nav {:a 1 :b 2 :c 3} :a 1)
(and then with :b 2
and then with :c 3
).
See https://github.com/clojure/java.jdbc/blob/master/src/main/clojure/clojure/java/jdbc/datafy.clj#L79
I believe it would be like (d/nav [:a :b :c] 0 :a)
but don’t have it running atm to check
I'm trying to understand how nav is used. So I should still use find/nth? But nav will potentially have side effects for that pair?
speaking from rebl, when you have something on the left, then you “select” it, you would nav (with left data and selected key/value), then datafy to get the new focused data
(->> val (datafy/nav coll key) datafy/datafy)
Yeah, what he said 🙂
is this why “trivial” examples like vectors/maps of scalar values don’t really show what makes datafy/nav useful
my naive understanding of nav
rationale is that it enables lazy navigation through data structures, that may or not be “realized” before you nav
them. Is there a better rationale or explanation somewhere
java.jdbc
produces simple vectors of maps today -- but the new clojure.java.jdbc.datafy
namespace has versions of the query functions that are "compatible" with datafy
(i.e., they include metadata with clojure.core.protocols/datafy
) which, if you call datafy
on them, produce data representations with clojure.core.protocols/nav
metadata on them, to do lazy fetching of related data if you call nav
on them.
Ok, let me test my understading. If I'm in the repl and call (datafy/nav [:a :b [:c [:d :e]]] 0 [:c [:d :e]])
and get the result [:c [:d :e]]
, then I could call (datafy/datafy *1)
and get the datafied result (which I can then nav over again). I've been trying to test if it's working by checking with (meta *1)
and keep getting nil
, so I might be doing that part wrong as well.
this is kinda what I’m getting at when I say a simplistic example doesn’t really expose the motivation for datafy/nav, i.e. would there ever be a reason to datafy
something that’s already data like [:c [:d :e]]
? It’s already data
Why would you pass [:c [:d :e]]
here (datafy/nav [:a :b [:c [:d :e]]] 0 [:c [:d :e]])
?
Based on coll k v
, v
should be :a
(or k
should be 2
)
I see the motivation in the java.jdbc datafy/nav usage: it’s adorning rows/result sets with info/metadata on how to nav
igate to related data
Also, you won't get any metadata unless something is adding that metadata.
datafy
of a pure Clojure data structure will produce the exact same pure Clojure data structure.
nav
of a pure Clojure value will produce that exact same pure Clojure value.
These two functions only "do something" if you pass them something that satisfies the two underlying protocols -- which may well be provided through metadata or a protocol extension.
But the defaults for Object
(and nil
in the case of Datafiable
) do pretty much nothing https://github.com/clojure/clojure/blob/master/src/clj/clojure/core/protocols.clj#L182
Then there are a few types extended here https://github.com/clojure/clojure/blob/master/src/clj/clojure/datafy.clj#L42
Ok, for some reason I thought that the clojure data structures had support for nav already and just tied myself in knots trying to understand how it worked on the core data structures.
I think I am getting a bit of a better idea of how it works , though I'm still not sure what the docstring means when it says e.g. for sequences (pass nil)
. I think I'm going to go build something against JDBC to figure it out.
For associative collections, you have a natural key to pass. For sequences, you do not.
So if I had used a list instead of a vector then I would call it with coll nil v
, right?
The key thing that may be missing from your thinking about this is that you start with an arbitrary "thing" and you call datafy
on it to get a "data representation" -- which may include pieces that satisfy the Navigable
protocol -- and then you can call nav
and datafy
on parts of that to navigate through it all.
But Clojure data structures are already data and they are already navigable.
When you datafy
an IRef
you are implicitly deref'ing it to get at the data representation, for example.
Yeah, I had this idea that nav
was kind of a universal navigation function - so I thought that I would be able to call (nav map key)
and (nav vector index)
and get that data back for further navigation, but then also be able to call (nav database row)
and get the datafied row which you built the support for, like an arbitrary zipper or something like that.
I guess I need to think of it more like the ability to deref
things arbitrarily once they have support for it. Much clearer (assuming I'm not wrong about that part 🙂 )
With all this nav
and datafy
going on, isn’t it a shortcoming that Strings and Longs don’t accept metadata?
I was very confused by nav until I realized that it only has a purpose when an element of a coll can itself be expanded by "going down a level". The browser would first enumerate the elements of a collection as usual, without calling nav. Then when the UI button "go right" is clicked, nav is called to expand the element and evaluate it as a coll (if possible), starting the process over again. This is my understanding anyway. So the args to nav are the coll, key and element that have already been enumerated.
@shaun-mahood If you start by calling datafy
, and then calling nav
, you would be correct.
But for Clojure hash map X with key k and associated value v, (datafy X)
is just X
by definition and (-> X (datafy) (nav k v))
is just v
by definition.
What java.jdbc.datafy
does is change the behavior for the hash maps that are rows. They become "special" insofar as if you call datafy
on them, they become hash maps that know how to lazily fetch related rows (based on some columns being treated as foreign keys).
Again, tho', having datafy
d a row, it isn't treated as anything other than data unless you call nav
on it.
I guess you could also implement pagination pretty well with this - datafy the first result set so that you can nav to the next (pretty sure Stu mentioned that in the talk so I guess I don't get credit for thinking of it)
@seancorfield very nice, appreciated!
Because nav
sits on top of the underlying associative lookup. You do (get coll k)
first to get v
, and then you call nav
on coll
, passing k
and v
to allow it to return an updated value.
Because you go from "thing" to "data representation" of "thing" (via datafy
), and then you can do the simple associative lookup in the data representation, not the original thing, and then you use nav
to get back to the relevant equivalent part of the "thing", and then you datafy
that again to get pure data.
Does that help @dominicm?