unrepl

discussing specification of an edn-based repl and its implementations.
cgrand 2017-06-16T07:18:34.416678Z

@volrath thanks!

đź‘Ť 1
cgrand 2017-06-16T07:32:32.566398Z

@volrath yes the documentation for :prompt is out of sync

volrath 2017-06-16T07:32:54.570269Z

Ok

cgrand 2017-06-16T08:00:14.885405Z

I was looking at compliment (https://github.com/alexander-yakushev/compliment). Some thoughts: • completion if a half static/half dynamic task, does the in-process tooling should take care of the static part? • a separate concern is vim editors with crippled scripting where there’s a push to offload brains to the tooled process (they need a proper isolation)

cgrand 2017-06-16T08:05:20.951701Z

So basically can we start with just a :completion action that takes a string (or a tagged-lit regex) and returns a list of matches? And without specifying much (in the string case) how the match is done (strict prefix, fuzzy, even fuzzier)

cgrand 2017-06-16T08:11:27.029040Z

(and an unrepl source for compliment could be added, allowing compliment to be used... on the editor side)

cgrand 2017-06-16T08:12:56.047737Z

I don’t see myself commiting fine-grained actions in unrepl.

volrath 2017-06-16T08:31:16.283132Z

sounds good. I also think that a :completion action could be generic enough to accommodate for completion libraries like compliment. One thing though, maybe I didn't understand well what you meant by a "tagged-lit regex", but I'm guessing that the action should take at least two parameters: the whole string/form the user's been typing and a cursor position, so that completion libraries can take advantage of context. in case of compliment: https://github.com/alexander-yakushev/compliment/wiki/Context

plexus 2017-06-16T08:33:06.307249Z

@thheller I'm sorry you had to deal with that print.cljc. It basically came about when I asked "what's the next thing we need to make a cljs unrepl happen", and someone said "port print.clj", so I fired up Lumo in inf-clojure and start going through it top to bottom, making sure I could evaluate each form without errors. After that I wasn't sure how to continue as it seemed there were some other pieces missing (I guess that would be cljs-js-repl which I wasn't aware of at the time).

cgrand 2017-06-16T08:35:09.333716Z

I’m the someone 🙂

plexus 2017-06-16T08:36:45.354601Z

I'll be working more on unrepl.el this weekend. Current status there is that I've started writing a Clojure/EDN parser from scratch out of frustration with edn.el. This will likely become its own Emacs package as it seems some other tooling could benefit from a good parser as well. But so there's a bit of yak shaving to be done at the moment. After that I want to implement proper tracking of eval/echo, which should make it possible to get proper in-buffer evaluation with results in an overlay, as well as other tooling-related evaluation that does something else with the result than show it in the repl.

plexus 2017-06-16T08:37:09.359772Z

@cgrand I think it was someone else repeating what you had said previously 🙂

cgrand 2017-06-16T08:37:41.366458Z

@plexus ok fine, blame the messenger!

plexus 2017-06-16T08:38:18.374519Z

I don't blame anyone, I think it's all worthwhile, just want to make sure people don't expect too much from print.cljc

cgrand 2017-06-16T08:39:21.388445Z

@volrath it’s not what I have on my mind (for compliment, I was thinking of just providing enough to implement a new source, and have compliement run in the editor, not in the “server” process) So I was thinking “small string” while you are thinking “whole form + cursor position”, it’s coarse grained too and I didn’t consider it. Interesting.

plexus 2017-06-16T08:40:18.400875Z

the clojure/edn parser will be a hand written shift-reduce parser, which will be able to give a partial syntax tree in case of parse errors, and which can be used to either parse EDN to elisp lists/vectors/hashes, or Clojure to a tools.analyzer style AST. It uses an internal stack instead of using recursion, which means it doesn't overflow the elisp stack (which edn.el is prone to do)

plexus 2017-06-16T08:42:15.427257Z

Also I'll be speaking (remotely) about unrepl/unrepl.el at the London Emacs Meetup on the 26th. There will be video afterwards. I'm in charge of the recording and editing though so it might take a while 🙂

cgrand 2017-06-16T08:46:21.480791Z

the elisp stack is rather shallow? Anyway sounds promising

plexus 2017-06-16T08:51:51.553635Z

yeah it's rather shallow, also edn.el is based on the PEG parser generator library, which seems to use many more stack frames than necessary

thheller 2017-06-16T08:53:02.569412Z

@plexus no worries .. I’m rather surprised that this actually works in lumo since it should be using the same tools.reader I do?

plexus 2017-06-16T08:57:40.633144Z

No idea to be honest, I would have to dive in again.

cgrand 2017-06-16T09:07:20.767468Z

If the selection is wrapped in a do before evaluation it may explain the behaviour

pesterhazy 2017-06-16T09:21:26.957243Z

@cgrand, I agree about starting with a simple approach

cgrand 2017-06-16T09:22:03.965347Z

yes but which one?

pesterhazy 2017-06-16T09:22:57.977124Z

hehe I'm typing slowly today

pesterhazy 2017-06-16T09:23:08.979335Z

I started with this brain-dead approach: https://github.com/pesterhazy/unravel/blob/master/src/unravel/loop.cljs#L70

pesterhazy 2017-06-16T09:23:39.986272Z

one question could be how that falls short

pesterhazy 2017-06-16T09:24:43.000349Z

on the completer side, it only does non-fuzzy prefix-completion; on the "gathering candidates" side, it looks at namespaces and local or qualified vars

pesterhazy 2017-06-16T09:25:05.005297Z

how could this be improved?

pesterhazy 2017-06-16T09:25:12.006858Z

- moving into unrepl source code

pesterhazy 2017-06-16T09:26:04.018424Z

- more candidate gathering sources (keywords? method names?)

pesterhazy 2017-06-16T09:26:56.029913Z

- better completion algorithms (allow for typos, allow for missing characters ("repfir" will match "replace-first"))

pesterhazy 2017-06-16T09:28:20.048463Z

- more generality

pesterhazy 2017-06-16T09:28:55.056480Z

- cljs support (but that would require cljs support in unrepl first)

pesterhazy 2017-06-16T09:29:03.058090Z

- better sorting of matches

pesterhazy 2017-06-16T09:29:27.063713Z

- adding annotations to matches (fn signature, first line of docstring)

cgrand 2017-06-16T09:43:49.253321Z

“gathering candidates side” is in CLJS?

cgrand 2017-06-16T09:46:00.282036Z

plexus: I put comments on your commit but it’s more for me than for you: things to keep in mind when I merge some of your changes.

đź‘Ť 1
pesterhazy 2017-06-16T10:52:02.069138Z

Yeah

cgrand 2017-06-16T10:53:33.085512Z

so you agree with me that that part should not be part of unrepl, right?

pesterhazy 2017-06-16T11:42:37.599082Z

can you explain a bit more what you're suggesting?

cgrand 2017-06-16T11:42:41.599712Z

Turns out there are rough edges to the repl experience in bootstrap

pesterhazy 2017-06-16T11:42:59.602644Z

i want to be sure what I'm agreeing to

cgrand 2017-06-16T11:44:03.613425Z

@pesterhazy unrepl only exposes stuff that the client can’t do, so only completion of dynamic things (namespaces, vars, maybe classes)

cgrand 2017-06-16T11:44:32.618558Z

keywords, locals etc are done by the client

pesterhazy 2017-06-16T11:45:40.630807Z

sounds right to me

pesterhazy 2017-06-16T11:46:45.641879Z

just to be clear that I'm understanding, the client would gather keywords by e.g. scanning the file for #":[a-z-]*"

pesterhazy 2017-06-16T11:47:22.648404Z

the client cannot do that effectively with namespaces because it needs to inspect the dynamic runtime environment

cgrand 2017-06-16T11:47:52.653889Z

Yes

pesterhazy 2017-06-16T11:48:38.662090Z

we don't want to extend unrepl's scope too much, so our principle would be to expose the data the client needs and cannot get by itself, but nothing more

pesterhazy 2017-06-16T11:50:36.683829Z

so one thing to add would be a completion function. E.g. (unrepl/candidates-by-prefix "fil") would return [{:symbol 'filter :docstring "..."} ,,,]?

thheller 2017-06-16T12:00:42.795083Z

wth? does unrepl suddenly do completions?

cgrand 2017-06-16T13:19:00.896978Z

@thheller 🙂 tryiing to find a tradeoff between “do nothing” and “do just enough for the client to be independent” (again, commands are optional and they are an openset etc.)

thheller 2017-06-16T13:19:44.910538Z

yeah, talked with Paulus. Misunderstanding on my part

dominicm 2017-06-16T13:51:06.510388Z

@thheller curious as to what made you feel okay with it.

thheller 2017-06-16T13:54:40.583619Z

not my decision to make … I’ll be building the language server and expose RPC-ish commands like clj/eval and cljs/eval

thheller 2017-06-16T13:54:56.589225Z

those will throw if you try to (read) as all this is not going to be a REPL

thheller 2017-06-16T13:55:11.594464Z

strictly for tools not humans (not actually strict RPC, message based with async notifications and RPC)

thheller 2017-06-16T13:56:10.614892Z

I have a simple socket REPL for humans that exposes enough information to make autocomplete and stuff work

thheller 2017-06-16T13:56:40.625742Z

but the autocomplete will then go over the RPC thing, not the REPL

thheller 2017-06-16T13:57:02.633418Z

very different goal than unrepl

thheller 2017-06-16T13:58:39.667710Z

trying to figure out how the upgrade works with CLJS makes my head hurt too much

cgrand 2017-06-16T14:56:46.961603Z

One could also imagine advertising the language server endpoint in unrepl hello.

thheller 2017-06-16T15:14:18.368327Z

yeah the thing I just can’t figure out is how the upgrade can work for CLJS without actually controlling how its started

thheller 2017-06-16T15:14:55.382235Z

the send a blob approach just doesn’t work since eval is in JS

cgrand 2017-06-16T15:23:44.580401Z

The loop on the js side has to be made upgradable

thheller 2017-06-16T15:42:55.017367Z

but there is no loop on the JS side

pesterhazy 2017-06-16T17:09:43.811688Z

au contraire! Javascript is loops all the way down

cgrand 2017-06-16T17:11:19.841951Z

Lambda the ultimate GOTO

cgrand 2017-06-16T17:19:28.996100Z

The message queue from which the strings (js code) to eval are received has to be public and have a .pushListener method and maintains a stack of listeners, only the top one is active.