Martin Kavalar / Nov 22 2018

Better References

1.
Current References

We currently support three types of references:

1.1.
Result

The reference of a result is currently called output in code. To not confuse it with stdout/stderr output, result is probably a better name for it. Maybe value might also be an alternative. I'm not sure if result would exclude streaming. Might be good to look at how observable does it, see thier generators.

123

We can reference the result of a code cell either inline: nil or in another code cell:

(+ nil 2)
{:kind "ref"
 :line 1
 :from 3
 :to 68
 :var nil
 :node [:node "94102e1a-3532-48a1-8bea-98ee26f3c33f"]}
Julia

1.2.
Code Import

We can use a code import to reference the resolved content of another code cell.

The references currently looks like this

{:kind "import"
 :line 1
 :from 0
 :to 1173
 :var nil
 :node #node}

1.3.
Code Listing

{:deps {:hello :world}}
Julia
nil
{:kind "ref"
 :line 1
 :from 0
 :to 71
 :var :content
 :node [:node "94102e1a-3532-48a1-8bea-98ee26f3c33f"]}
Julia

2.
Discussion

A reference in a code cell has a representation as both an element in the :refs of the node as well as a textual represenation. Maybe a reader literal could be used to get rid of one.

(+ #nextjournal/ref {:link [:node "94102e1a-3532-48a1-8bea-98ee26f3c33f"]} 1)

Some approach like that would work nicely in Clojure/Script. Not so in Python or Julia because we don't have support for reader conditionals there. To make it 100% safe we would have to change a cell's content to also be edn like so:

#nextjournal/join [#nextjournal/ref {:link [:node "94102e1a-3532-48a1-8bea-98ee26f3c33f"]}
"+ 1" "#nextjournal/ref 1"]
Julia

Something along those lines could wo

(defmethod print-method ::reference [l w]
  (.write w (str "#nextjournal/reference" (str (vary-meta l dissoc :type)))))

(pr-str (with-meta {:link [:node (java.util.UUID/randomUUID)]} {:type ::reference}))

We want to be able to reach multiple things from a reference or link. E.g. when pointing to the content of a node, the reference marker would acutallly display the name of the linked node.

Our transclusion links currently look like this:

[:node {:article/nextjournal.id #uuid "random-uuid"
        :change/nextjournal.id #uuid "another-uuid"
        :node/id "random uuid"}]
Julia

The vector format is inspired by lookup refs and has the upside of being useable as a re-frame subscription as is. Making the second map self-contained should be a goal. In the com.nextjournal.graph.link namespace this could become

[::reference 
  {:article/nextjournal.id #uuid "random-uuid"
   :change/nextjournal.id #uuid "another-uuid"
   :node/id "random uuid"}]
Clojure

Moving the kind into the map (and also having it outside for re-frame) we would get:

{:link/kind ::output
 :article/nextjournal.id "random-uuid"
 :change/nextjournal.id "another-random-uuid"
 :node/id "random uuid"}
Clojure

Adding additional data is trivial:

{:link/kind ::reference
 :article/nextjournal.id "random-uuid"
 :change/nextjournal.id "another-random-uuid"
 :node/id "random uuid"
 :node/attribute :content
 :reference/display :name
 :reference/position {:line 0 :from 1 :to 57}}
Clojure

Like seen above, the code refs could be the same thing with additional data for the marker position.

A link to a secret could be represented like this:

{:link/kind ::secret
 :secret/id "my-random-secret-id"}
Clojure

3.
Text Representation

For copy & paste we have a plain-text representation.

The text representation of a link should probably be changed to be based on edn, not transit.

#nextjournal/link{:link/kind …}
Julia

Maybe having it be a url you can paste would even be cooler but for this we need to lock down url url structure first.

https://nextjournal.com/mk/better-refs@2018-11-22
Julia