Fork me on GitHub
#reveal
<
2021-08-26
>
simongray14:08:10

Here is an example nav implementation. There is no difference between selecting either a key or a value from this map (e.g. in Reveal’s navigation dropdown it would say either (nav :a) or (nav 1)). In both cases whatever is the key in the relevant key-value pair becomes k and whatever is the value becomes v. This makes it impossible to disambiguate which part was actually selected, the key or the value? Can someone explain if this is a limitation with Navigable, Reveal or my skills? Reveal itself seems to know the difference since it correctly displays (nav 1) if I select the 1 for example.

(with-meta {:a 1 :b 2}
           {`p/nav (fn [coll k v] [k v])})

simongray14:08:58

I want to implement Navigable for some Clojure data structures, but I want to return different data depending on whether the key or the value is selected, so this part is tripping me up,

vlaaad15:08:40

IIRC the design of datafy/nav is that you can only navigate to keys

vlaaad15:08:05

Reveal just adds minor niceties by suggesting correct nav call regardless of key or val selection

vlaaad15:08:49

i.e. nav only means "navigate to the key of that coll, and by the way the value was this", not 2 separate "navigate to key"/"navigate to value" functions

vlaaad15:08:32

(ns datafy-fn
  (:require [clojure.core.protocols :as p]))

(extend-protocol p/Datafiable
  clojure.lang.Fn
  (datafy [f]
    (with-meta {:exec '...}
               {`p/nav (fn [_ k v]
                         (case k
                           :exec (f)
                           v))})))

{:msg "Are you sure you want to quit"
 :yes (constantly {:msg "Sure sure?"
                   :yes! #(System/exit 0)})}

vlaaad15:08:52

Found some fun example of custom datafy/nav

vlaaad15:08:29

I'd suggest experimenting with datafy/nav in REBL since it has idiomatic datafy/nav handling

seancorfield16:08:19

The design is such that nav mirrors get @U4P4NREBY

3
seancorfield16:08:54

I like to think of it as a square:

Object -datafy-> Data
               / |
              /  |
          nav   get
        /        |
      L          v
Object'         Data'
datafy takes you from objects to data; get navigates in the data-world; nav is like get but takes you back to a "corresponding" object.

seancorfield16:08:10

(you can't easily navigate from Object to Object' directly -- and it's not always true that (datafy (nav (datafy obj) k v)) would get you from Object to Data' because the navigation is conceptual)

simongray19:08:05

Thank you, both of you!

simongray19:08:21

I guess I will just have to live with this limitation. I'm using the Navigable protocol to navigate an RDF graph in Apache Jena, so having to choose between either navigating to the object or the predicate part of the triple is an annoying limitation when both are resources with meaningful properties to query. But it's better than nothing 🙂 makes a lot of sense to think of it as like get

vlaaad05:08:31

You probably can achieve what you want with different implementation for datafy, so your triple is datafied as a map with 3 keys — object, predicate, subject. Then you can nav further to any part of the triple

9
👍 9
simongray07:08:03

I don’t control the datafication, Luke Vanderheart does (I’m merely using/extending his Aristotle wrapper for Apache Jena). He was clearly aiming for it to look as much like Datomic as possible. Anyway, if I have to choose between either a 3-tuple vector and a map, I think I’ll have to go with the 3-tuple for a number of different reasons. The nav implementation was just some sugar on top of a bunch of other improvements I’ve made while retaining overall compatibility.