Fork me on GitHub
#unrepl
<
2017-11-21
>
cgrand10:11:50

@pesterhazy ^^ not like Chez

volrath10:11:28

@cgrand last night I was wondering about your thoughts on what can clients do to show objects in a "pretty way", or put in a different way: it'd be nice to be able to show objects 'a la pr'.. for example, in clojure.main/repl, the print function is prn, so if I eval + i get #function[clojure.core/+] back, and I would like to show the same in unrepl.el, but it's not derivable from the current #unrepl/object tagged literal

volrath10:11:29

the only thing I could think of was extending the #unrepl/object so that it includes its pr, but I don't know if there's a better way

cgrand10:11:12

#function seems very new as it’s not in beta 3

cgrand10:11:21

(haven’t tried on RC)

volrath10:11:04

hmm didn't noticed, I thought it was already stable

cgrand10:11:38

you are on RC1?

volrath10:11:32

actually no.

cgrand10:11:47

*clojure-version*

volrath10:11:06

oss/unrepl [ JVM_OPTS='-Dclojure.server.myrepl={:port,5555,:accept,clojure.core.server/repl}' lein repl                                                                                        master * ] 11:54 >
nREPL server started on port 46374 on host 127.0.0.1 - 
REPL-y 0.3.7, nREPL 0.2.12
Clojure 1.8.0
Java HotSpot(TM) 64-Bit Server VM 1.8.0_101-b13
    Docs: (doc function-name-here)
          (find-doc "part-of-name-here")
  Source: (source function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
    Exit: Control+D or (exit) or (quit)
 Results: Stored in vars *1, *2, *3, an exception in *e

user=> +
#function[clojure.core/+]

volrath10:11:41

user=> +
#function[clojure.core/+]
user=> *clojure-version*
{:major 1, :minor 8, :incremental 0, :qualifier nil}

volrath10:11:10

although if I start the repl using the clojure 1.8.0 jar, I get #object

volrath10:11:27

oss/unrepl [ java -Dclojure.server.myrepl="{:port 5555,:accept,clojure.core.server/repl}" -jar ~/.m2/repository/org/clojure/clojure/1.8.0/clojure-1.8.0.jar                                    master * ] 11:52 >
Clojure 1.8.0
user=> +
#object[clojure.core$_PLUS_ 0x4c2bb6e0 "clojure.core$_PLUS_@4c2bb6e0"]

volrath10:11:09

(if I run cider for the unrepl repo, I also get #function )

cgrand10:11:27

lein repl
Initializing NoDisassemble Transformer
nREPL server started on port 52727 on host 127.0.0.1 - 
REPL-y 0.3.7, nREPL 0.2.12
Clojure 1.8.0
Java HotSpot(TM) 64-Bit Server VM 1.8.0_05-b13
    Docs: (doc function-name-here)
          (find-doc "part-of-name-here")
  Source: (source function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
    Exit: Control+D or (exit) or (quit)
 Results: Stored in vars *1, *2, *3, an exception in *e

user=> +
#object[clojure.core$_PLUS_ 0x4ce1ff96 "clojure.core$_PLUS_@4ce1ff96"]

cgrand10:11:54

so it’s cider

volrath11:11:23

everything I sent was outside cider

volrath11:11:04

I do have cider as a global lein plugin

volrath11:11:10

let me try without it

cgrand11:11:20

>>> ;; Extending print-method defined in clojure.core, to provide ;; prettier versions of some objects. This applies to anything that ;; calls print-method, which includes return values, pr, print ;; and the likes.

cgrand11:11:34

(def ^:dynamic *pretty-objects*
  “If true, cider prettifies some object descriptions.
  For instance, instead of printing functions as
      #object[clojure.core$_PLUS_ 0x4e648e99 \“clojure.core$_PLUS_@4e648e99\“]
  they are printed as
      #function[clojure.core/+]
  To disable this feature, do
      (alter-var-root #’cider.nrepl.print-method/*pretty-objects* not)”
  true)

cgrand11:11:14

monkey-patching print-method, so cute

volrath11:11:28

right, yeah I tried without the plugin and got #object

volrath11:11:36

I feel cheated haha

cgrand11:11:33

So they just demunge the classname

volrath11:11:34

so it seems

cgrand11:11:36

the thing with their #function tag is that: 1/ it’s not namespaced 2/ it loses identity information, so you can’t tell if two closures created by the same function are the same or not

volrath11:11:54

yes, agreed

cgrand11:11:35

(partial map inc)
#function[clojure.core/partial/fn--4759]

cgrand11:11:18

@volrath + now prints #unrepl/object [#unrepl.java/class clojure.core$_PLUS_ “0x774afe65” clojure.core/+ {:bean {#unrepl/... {:get (unrepl.replG__997/fetch :G__1443)} #unrepl/... nil}}]

volrath11:11:19

awesome, maybe what I can do is print the demunged version and have the #object show as a tooltip 🙂

cgrand11:11:18

I would keep the hash out of the tooltip

volrath11:11:32

makes sense

cgrand11:11:02

as long as your rendering hints that magic happens (special color whatever), I’m ok with it

volrath11:11:31

here's another related question

cgrand11:11:53

principle of least surprise (unlike #function that you assumed was standard)

volrath11:11:20

pretty printing in general.. cider also does it with cider-nrepl.. so that if I have a very long map or whatever, I get a pretty version of it... I was thinking on how to enable that only in my blob

volrath11:11:49

and maybe only on demand, so that I can give users the ability to opt out of it

cgrand11:11:28

unrepl-make-blob does not yet offer a way to plug in the printer (so you have to resort to the hacksaw)

cgrand11:11:00

There are many potential extensions points but I’m waiting for needs to arise.

volrath11:11:43

Yes, I was thinking on something like middlewares or interceptors... or a function you could define with a session action

volrath11:11:11

i figured...

cgrand11:11:49

To me pretty printing should be done on the client side. Traditional pretty printing is a bit at odd with elisions anyway (if you plan to transclude them — whic I guess you do given how you treated string elisions)

cgrand11:11:00

There are many potential extensions points but I’m waiting for needs to arise.

volrath11:11:58

yeah I looked around for clj (or even lisp) pretty printers written in elisp, but without much luck. so that's the thing on relaying pretty printing on an elisp client.

volrath11:11:41

there are definitely some border cases with pretty printing and elision, but i think it's manageable.

cgrand11:11:15

what are your requirements for PP?

volrath11:11:41

I haven't thought about it too much.. from a user point of view, I guess pp-ing lists, vectors, maps, and sets, will do..

volrath11:11:23

I'd like to look a bit more on how cider does it, maybe see if there's something that can be improved there

cgrand11:11:36

@volrath think a bit more as how as a user you like your stuff printed, when you want to transition from line to column etc.

cgrand11:11:49

think also about interactivity: we already have elisions but maybe we can toggle the display mode of a collection, collapse it etc. (This doesn’t make up for good defaults.)

cgrand11:11:17

What if we had the option to render a list of similarly keyed maps as a table?

volrath12:11:02

so, taking collapsing out of the equation, I see that either done in elisp (not my fav option), or as possible :aux actions to be sent to unrepl and have the processing be done in clojure

volrath12:11:03

I say taking out collapsing because hiding information that it's already there should be pretty straight forward

cgrand12:11:24

Implementing stuff in: • Clojure: just require your helper ns on an aux connection and send it forms: pros easy cons when CLJS will come you’ll have to rewrite it (hopefully it will be cljs) • Elisp: pros works with any blob, any lang; cons elisp (it could be vim^Hworth).

dominicm12:11:29

Clojure pro: Vim can use it for free

dominicm12:11:43

cider-nrepl has been a valuable asset to vim users.

cgrand12:11:01

if you don’t like your host lang spawn a CLJS repl

volrath12:11:06

right, the thing about the aux helper is that I wouldn't have a way to use it as a default.. so for example, let's say I allow users to choose they want their stuff PPed, then I would have to send each client input wrapped in a helper?

volrath12:11:27

it's an option for sure, not discarding it, but just wondering if there's a better way

cgrand12:11:16

“each client input output” you meant?

volrath12:11:00

input.. maybe I'm under/overthinking this. I was thinking, user types: user=> *code that generates -long- data* ; the elisp client will send (my-custom-wrapper-for-pprint *code that generates -long- data*) so that I get the result pp-ed

volrath12:11:46

I know the other option could be to wait for the :eval message and then send an aux helper like (pprint-me-this <eval result>)

volrath12:11:55

but I was thinking on avoiding the roundtrip

cgrand12:11:26

:thinking_face:

cgrand12:11:11

(my-custom-wrapper-for-pprint *code that generates -long- data*) looks like a bad idea (unrepl-wise) because in a sense you are framing input.

cgrand12:11:55

you could customize the blob (and with enough persuasion I will make it easier) to emit your own [:unrepl.el/pprinted xxx id] messages.

volrath12:11:55

(btw, I wasn't planning on working on pp soon, it is down the road.. but just thought on bringing up the topic)

cgrand12:11:32

The thing is: if your code generates long data do you want to display all the data at once?

volrath12:11:33

I also thought about that a little bit yesterday.. I think the answer is maybe. I thought on making it customizable in the elisp client, let the user decide

volrath12:11:23

at least at the beginning it could be as easy as a boolean value: the client will either resolve all elisions automatically or won't

volrath12:11:37

I also plan to make the max-print-length customizable inside emacs.. the user can decide it there and I'll use the session helpers to adjust when I receive :hello

volrath12:11:58

tbh, I think of elision as pretty printing, both are great, but should be optional

cgrand12:11:56

I disagree but let’s experiment!

cgrand15:11:34

At the Conj @chouser asked about pair programming and unrepl, I jotted down some thoughts after chatting with him today https://github.com/Unrepl/unrepl/wiki/Pair-(or-more)-Programming

baptiste-from-paris16:11:25

hello all, I am trying to install unravel but I got an Error: EACCES: permission denied, open 'lumo_mac.zip'

baptiste-from-paris16:11:17

nevermind it’s working, was a rights issue on node

baptiste-from-paris16:11:30

and unravel looks awesome ^^

baptiste-from-paris16:11:26

the doc right above the repl is really cool

cgrand16:11:16

@baptiste-from-paris you built from master?

cgrand17:11:58

could you give a try to parfix (multiline + paren completion)?

baptiste-from-paris20:11:19

@cgrand could you send a link for parfix ?

volrath20:11:07

I believe he's referring to the parfix branch: https://github.com/Unrepl/unravel/tree/parfix, you should have multiline and paren completion there

cgrand20:11:24

Yeah it’s the name of the branch.

baptiste-from-paris21:11:05

@cgrand how many open-source projects do you manage and are you humain ? 😄

cgrand08:11:12

Thanks to you I have a sudden urge of listening to Daft Punk’s “Human after all” and Katerine’s “Robots après tout” LPs 😉

cgrand08:11:40

It would be cool to create a modern Bourbaki 🙂

baptiste-from-paris21:11:34

ok, working great with ident

baptiste-from-paris21:11:34

and that’s almost the best REPL XP that I had in a terminal

baptiste-from-paris21:11:31

it seems that history does not work anymore

baptiste-from-paris21:11:32

I don’t get where unrepl is loaded in unravel, no lein/boot project file

cgrand08:11:22

You mean as a dep when building unravel?

cgrand08:11:34

Well unrepl is a protocol so you don’t have to require it. The unrepl repo is also a built tool to create server implementations of this protocol.

cgrand08:11:52

The artifact produced is the famous blob.

cgrand08:11:03

See scripts/update-unrepl and resources/unrepl/blob.clj

cgrand21:11:17

@baptiste-from-paris on this branch it’s ctrl up/down for history.