This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-05-06
Channels
- # babashka (130)
- # beginners (97)
- # biff (36)
- # calva (6)
- # cherry (23)
- # clojure (29)
- # clojure-dev (1)
- # clojure-europe (9)
- # clojurescript (5)
- # datomic (24)
- # emacs (13)
- # fulcro (5)
- # hyperfiddle (33)
- # interop (2)
- # jobs (18)
- # kaocha (1)
- # london-clojurians (1)
- # lsp (20)
- # nrepl (1)
- # off-topic (60)
- # pathom (4)
- # reitit (7)
- # releases (1)
- # remote-jobs (4)
- # scittle (3)
- # specter (1)
- # tools-deps (7)
- # xtdb (16)
A little confused over the relationship between Datafiable and Navigable protocols-
if I have eg. an obj
~ {:k1 v1}
and (datafy obj)
returns {:k2 v2}
which collection / key / value is intended as the input to nav
?
ie. in the arglist of nav: (nav coll k v)
:
Is the coll
argument supposed to be the ILookup-able result of calling datafy
on some arbitrary object?
v = (get coll k)
But this does not make sense since coll
is the thing which the Navigable protocol dispatches on, unless the Datafiable impl is careful to return a particular record or attach metadata to the returned map.
Or maybe coll
is the original object itself, in which case
v = (get (datafy coll) k)
But this means the docstring and "coll" naming are inaccurate, since the original thing might have been an opaque blob which did not implement Indexed/ILookup.This is a rather helpful article on the topic: https://corfield.org/blog/2018/12/03/datafy-nav/
Notice how the docstring of nav
says: "Returns (possibly transformed) v in the context of coll and k".
So that coll
is the original data, k
is a key in that data (whatever "key" means), and v
is the value at that key.
Meaning, in some scenarios you can use things like (nav obj :x (get (datafy obj) :x))
.
Or (datafy obj)
can return a plain Clojure data structure that has clojure.core.protocols/nav
function in its metadata - then (let [coll (datafy obj)] (nav coll :x (get coll :x)))
is possible.
Yeah, that was the source of my confusion - whether the semantics of nav are for the coll
to be the original obj or the datafied structure (in which case metadata extension seems to be the main use convention for the protocol)
I've read the blog post and the code in https://github.com/clojure/java.jdbc/blob/java.jdbc-0.7.12/src/main/clojure/clojure/java/jdbc/datafy.clj for a concrete implementation.
Maybe I'm not too familiar with databases, but I don't quite understand why nav
is necessary if datafy
already returns the map values processed in some domain specific manner.
I'm guessing the main use case is laziness? ie. (datafy obj)
returns a map of key -> <dummy value>
and the expensive computations like "foreign table lookup" are only run when you "drill down" into that specific column.
> why nav
is necessary if datafy
already returns the map values processed in some domain specific manner.
You can't get to the data that's not there by using only datafy
. Or at least, it'll be a very kludgy solution, the way I imagine it.
With nav
it's relatively straightforward to fetch additional data.
Right, I was imagining things in terms of nested data structures or a Java blob, where all the data is already "there" in a sense, and navigating one level deeper involves no side effects. But if some additional "fetching" is involved in the act of navigation, then it makes sense that datafy
wouldn't simply return a map of k -> (fetch k)
for performance reasons.
Another thing that bothers me - having to pass v
as an argument seems overspecified if you could always derive it from coll
and k
,
Why is the interface not (nav coll k)
- "navigate to the thing in coll given by k" which would naturally draw parallels with (get coll k)
Framing it in terms of "transforming v in the context which it was looked up" seems unecessarily generalized and vague... maybe that's just so the default identity impl could be provided for all Objects?
Would someone ever substitute different v
s in a call to nav that weren't the result of looking up (whatever that means) k
in coll
?
It is necessarily generalized. From the docstring:
Callers should attempt to provide the key/index
context k for Indexed/Associative/ILookup colls if possible, but not
to fabricate one e.g. for sequences (pass nil).
So k
for some coll
can be meaningless. Or in some cases, deriving v
is costly. Perhaps there are other reasons as well.Okay, I think I'm slowly understanding.. the concern of nav
should have nothing to do with lookup, this is already handled by datafy
returning some associative map etc.
In fact a more natural interface might be (nav coll v)
"navigate to the thing v in coll", except the key which it was derived from might have contained some contextually relevant information. And having optional middle argument arities ([coll v] [coll k v])
would be quite unnatural.
@seancorfield It seems you (help) maintain core.memoize
and I have a small doc string fix. Do I just create a JIRA ticket and attach the patch? I’ve signed the CA.
If you have a Jira account already, sure, go ahead and create a ticket and add a patch, otherwise put it on Ask and either I or @U050WRF8X will fix it.
Merged. Thanks!
I wish it was more substantive, but my nickname isn’t ‘the red pen’ for nothing lol
All contributions are appreciated!
I want to read in a binary file and I want to println
the binary representation. When I have the input-stream
from the file I can do (println (Integer/toBinaryString (.read in)))
and I can see the first eight bits printed 10001001
. But when I store the contents from input-stream
into a byte-array
I am getting different result: (println (Integer/toBinaryString (first buf)))
. (`11111111111111111111111110001001`)
Last eight bits are the right ones but why is it filled up with 1s?
Thanks @U0NCTKEV8, I thought about that, but why so many?
However you are converting the int from .read to a byte to store in a byte array it is converting it to a negative byte (makes sense the msb is 1), and then when the byte is converted back to an int the sign is extended