Fork me on GitHub
#unrepl
<
2017-11-22
>
volrath09:11:38

@cgrand good morning, last night I did a more generic implementation of elision expansion, and I noticed something weird for maps, that I think it's related to the into used in unrepl.print/ednize

volrath09:11:56

[14] user=> (zipmap (map char (range 97 (+ 97 11))) (range 11))
> {\a 0 \b 1 \c 2 \d 3 \e 4 \f 5 \g 6 \h 7 \i 8 \j 9 ...}
[15] user=> (zipmap (map char (range 97 (+ 97 11))) (range 11))
> { ... \a 0 \b 1 \c 2 \d 3 \e 4 \f 5 \g 6 \h 7 \i 8 \j 9}
[16] user=> (zipmap (map char (range 97 (+ 97 11))) (range 11))
> {\a 0 \b 1 \c 2 \d 3 \e 4 \f 5 \g 6 \h 7 \i 8 \j 9 ...}
[17] user=> (zipmap (map char (range 97 (+ 97 11))) (range 11))
> {\a 0 \b 1 ... \c 2 \d 3 \e 4 \f 5 \g 6 \h 7 \i 8 \j 9}
[18] user=> (zipmap (map char (range 97 (+ 97 11))) (range 11))
> {\a 0 \b 1 \c 2 \d 3 \e 4 ... \f 5 \g 6 \h 7 \i 8 \j 9}
[19] user=> (zipmap (map char (range 97 (+ 97 11))) (range 11))
> {\a 0 \b 1 \c 2 \d 3 \e 4 \f 5 \g 6 ... \h 7 \i 8 \j 9}
[20] user=> (zipmap (map char (range 97 (+ 97 11))) (range 11))
> {\a 0 \b 1 \c 2 \d 3 \e 4 \f 5 \g 6 \h 7 \i 8 \j 9 ...}

volrath09:11:02

take a look at the ...

volrath09:11:14

it changes positions

volrath09:11:25

non deterministicly afaik

volrath09:11:51

it always holds the last char though

cgrand09:11:29

in elisp you read maps as lists or alists?

volrath09:11:54

hah.. good point

volrath09:11:59

it can be the parser

cgrand09:11:36

At some point I thought “it doesn’t matter” but if it makes life too hard...

volrath09:11:49

yes it does

volrath09:11:04

but pretty sure it's the parser, I'll take a look

volrath09:11:07

(zipmap (map char (range 97 (+ 97 11))) (range 11))
[:read {:from [1 1], :to [2 1], :offset 0, :len 52} 1]
[:started-eval {:actions {:interrupt (unrepl.replG__24139/interrupt! :session24584 1), :background (unrepl.replG__24139/background! :session24584 1)}} 1]
[:eval {\a 0, #unrepl/... {:get (unrepl.replG__24139/fetch :G__24587)} #unrepl/... nil, \b 1, \c 2, \d 3, \e 4, \f 5, \g 6, \h 7, \i 8, \j 9} 1]
[:prompt {:file "unrepl-session", :line 2, :column 1, :offset 52, clojure.core/*warn-on-reflection* false, clojure.core/*ns* #unrepl/ns user}]

volrath09:11:19

there the elision is 2nd

cgrand09:11:45

yeah I know — I wasn’t blaming your parser, just trying to figure out things.

volrath09:11:41

haha no worries, me too.

cgrand09:11:21

so my position was “it doesn’t matter — let revisit when clients authors show up with pitchforks”

cgrand09:11:26

do you have a fork?

volrath09:11:41

I can fix it on my side though, I can just make sure to print the ... at the end

volrath09:11:47

at least for now

cgrand09:11:52

yeah but...

cgrand09:11:06

the current solution is bad for all: • those who read maps as maps can’t lookup for elision because the key is random • those who read maps as list can’t rely on it being at the end. So in both cases you have to do a linear scan (yeah I know reading a map is linear anyway) instead of a get or looking at the last value

volrath09:11:22

so you're thinking on changing the structure for ednizedkvs? kind of like with ednized strings

cgrand09:11:44

not going that far but requiring the server to print the elisions last AND to reverse padding and actual elision, so that the key would always be #unrepl/... nil

volrath09:11:34

sounds good

baptiste-from-paris13:11:49

it’s really a genuine question but why do you need this-as if you don’t use it ?

baptiste-from-paris13:11:58

(defn make-pr-str-stream
  []
  (let [transform (fn [v enc cb]
                    (this-as this
                      (cb nil (prn-str v))))]
    (Transform. #js {:writableObjectMode true
                     :transform transform})))

cgrand13:11:30

dead code left after refactoring?

cgrand14:11:24

I dusted off a text layout algorithm that I adapted to data, here is the result https://gist.github.com/cgrand/fd67ff7459b1a446a14a533095261c14

cgrand14:11:46

So it’s an experiment in compact pretty printing

cgrand14:11:33

Do you like the produced layouts?

volrath14:11:11

what would be the context? where/how do you see this coming into play?

cgrand14:11:20

I could see it used by unravel to format values.

volrath14:11:30

cool... I don't know the details of the implementation but I guess it should take care special care of pair of values (kvs, tagged literals)

volrath14:11:53

would love to see it inside unravel 🙂

cgrand15:11:07

Good point about pairs. The algorithm lays out unbreakable spans (and spans have an indent value). A first naive approach would be to merge the last span of the key and the first one of the value and add an extra indent for the value.

cgrand15:11:13

Actually I think there’s a better way

volrath15:11:22

I think I found a bug with blob customization (trying it right now)

volrath15:11:34

one second

volrath15:11:18

so, the unrepl_make_blob task reads the session action map with {:default tagged-literal}

volrath15:11:32

the thing is that this outputs the actual tagged literal into the blob

volrath15:11:08

it puts something like :my.own/action (some.ns/fun #unrepl/param :bar)

volrath15:11:10

whereas what's seem to be need is something like :my.own/action (some.ns ~(tagged-literal 'unrepl/param :bar))

volrath16:11:08

I tried to fix it but couldn't to be hones I couldn't get it to work and i think it might be an easy fix, so I rather ask

volrath16:11:48

the easiest way to reproduce the problem is by simply generating a new custom blob and try to upgrade to unrepl with it

volrath16:11:12

it will raise a read error because the #unrepl/param is not recognized

cgrand16:11:45

AFK could you show me the relevant portion of the generated blob?

volrath16:11:25

sure, one moment

volrath16:11:47

:actions (into
                                                                {:exit `(exit! ~session-id)
                                                                 :start-aux `(start-aux ~session-id)
                                                                 :log-eval
                                                                 `(some-> ~session-id session :log-eval)
                                                                 :log-all
                                                                 `(some-> ~session-id session :log-all)
                                                                 :print-limits
                                                                 `(let [bak# {:unrepl.print/string-length p/*string-length*
                                                                              :unrepl.print/coll-length *print-length*
                                                                              :unrepl.print/nesting-depth *print-level*}]
                                                                    (some->> ~(tagged-literal 'unrepl/param :unrepl.print/string-length) (set! p/*string-length*))
                                                                    (some->> ~(tagged-literal 'unrepl/param :unrepl.print/coll-length) (set! *print-length*))
                                                                    (some->> ~(tagged-literal 'unrepl/param :unrepl.print/nesting-depth) (set! *print-level*))
                                                                    bak#)
                                                                 :set-source
                                                                 `(unrepl/do
                                                                    (set-file-line-col ~session-id
                                                                      ~(tagged-literal 'unrepl/param :unrepl/sourcename)
                                                                      ~(tagged-literal 'unrepl/param :unrepl/line)
                                                                      ~(tagged-literal 'unrepl/param :unrepl/column)))
                                                                 :unrepl.jvm/start-side-loader
                                                                 `(attach-sideloader! ~session-id)}
                                                                {:my.own/action (unrepl.repl/ensure-ns (foo/bar #unrepl/param :baz))})

volrath16:11:01

there, now i'ts better

volrath16:11:18

every other action's params are ~(tagged-literal 'unrepl/param :some/name), and the generated by the customization is #unrepl/param :some/name

volrath16:11:59

if I try to upgrade with that blob, I get

$> cat test-blob.clj - | nc localhost 5555
user=> [:unrepl.upgrade/failed]
RuntimeException No reader function for tag unrepl/param  clojure.lang.LispReader$CtorReader.readTagged (LispReader.java:1245)

volrath16:11:55

by now I'm just using ~(tagged-literal 'unrepl/param :my/param) to generate a custom blob, but maybe this is an easy fix

cgrand16:11:01

You are right

cgrand16:11:57

It’s a rather easy fix: need a reader and a record for unrepl/param

volrath16:11:19

yeah the record for the unrepl/param was the one I didn't figure out, I had problems with the ~, I forgot about unquote

volrath16:11:16

I'll submit a PR later tonight, I'm heading out.. thanks for the help!

cgrand16:11:25

@volrath there’s a way simpler fix: pass a default tag reader to read in gen-blob.

baptiste-from-paris17:11:11

what blob.clj is used for ?

volrath17:11:28

@cgrand Now I'm afk, but i'm under the impression that's a clojure.core/read, not a clojure.edn/read, is it possible to add readers to that function? If so, that would definitely be better.

volrath20:11:11

@cgrand I'm back, I don't see how I can pass a default tag reader to clojure.core/read, not sure if I'm missing out on something... I tried to go with the other approach, having a tag reader for #unrepl/param but I'm a bit blocked. Best I can get is

{:readers {'unrepl/param (fn [param-kw]
                                        '(unquote (tagged-literal 'unrepl/param param-kw)))}
              :default tagged-literal}
But then the parent form (list 'unrepl.repl/ensure-ns v) would have to be syntax-quoted..

cgrand22:11:57

*default-data-reader-fn* but I’m blocked too by a subtle error related to pr-dup

cgrand22:11:44

Not so subtle, it’s just too late.

baptiste-from-paris17:11:51

humm lein unrepl-make-blob strange ^^

baptiste-from-paris17:11:33

so that’s what transfors classical nREPL message in unrepl ones

cgrand19:11:25

There’s no nREPL involved!

cgrand19:11:00

Hey I’ve got a new one: unREPL the underground REPL

baptiste-from-paris20:11:01

so you telling me that I understood all wrong ^^

cgrand20:11:07

when we say “repl” it’s a plain repl (generally socket one so clojure 1.8) as provided by clojure

cgrand20:11:32

However as a proof of concept we have the nREPL-bridge project which recreates a plain repl on top of nREPL. Then you can upgrade it to unrepl.

baptiste-from-paris20:11:33

okay but blob.clj is transforming REPL message to unrepl protocol right ?

baptiste-from-paris20:11:40

or I am completly lost