Fork me on GitHub
#clojure-dev
<
2017-02-22
>
thheller17:02:53

@bronsa I'm trying to use tools.reader on *in* which is a clojure.lang.LineNumberingPushbackReader but that does not seem to work

thheller17:02:11

clojure.lang.ExceptionInfo: clojure.lang.LineNumberingPushbackReader cannot be cast to java.io.InputStream {:type :reader-exception}
	at clojure.core$ex_info.invokeStatic(core.clj:4725)
	at clojure.core$ex_info.invoke(core.clj:4725)
	at clojure.tools.reader$read_STAR_.invokeStatic(reader.clj:934)
	at clojure.tools.reader$read_STAR_.invoke(reader.clj:897)
	at clojure.tools.reader$read.invokeStatic(reader.clj:965)
	at clojure.tools.reader$read.invoke(reader.clj:942)

thheller17:02:39

it all looks like it should be supported, all I do is (reader/read opts *in*)

bronsa17:02:55

@thheller upgrade the tools.reader dependency

bronsa17:02:20

I think only the last version supports that

bronsa17:02:27

or one of the latest

thheller17:02:58

which one is that? I have tools.reader-1.0.0-beta3.jar

bronsa17:02:08

it only works since 1.0.0-alpha1

bronsa17:02:28

user=> (require '[clojure.tools.reader :as r])
nil
user=> (r/read *in*)
1
1

thheller17:02:43

it is the one that comes with clojurescript I think

bronsa17:02:09

are you sure you don't have an older version on your classpath

thheller17:02:23

(io/resource "clojure/tools/reader.clj")

thheller17:02:33

#object[java.net.URL 0x642ac8fe "jar:file:/Users/zilence/.m2/repository/org/clojure/tools.reader/1.0.0-beta3/tools.reader-1.0.0-beta3.jar!/clojure/tools/reader.clj"]

bronsa17:02:36

try and read #:foo{:bar 1}

bronsa17:02:57

if that fails, you're using an older version

bronsa17:02:46

if it doesn't, can you try and give me a minimal repro? as you can See above I just tried it and it worked fine for me

thheller17:02:03

hmm it works if I call it in the repl directly

bronsa17:02:18

well the repl doesn't use tools.reader

bronsa17:02:40

i meant (r/read-string "#:foo{:bar 1}")

bronsa17:02:58

if that fails, you might have multiple versions of tools.reader in your classpath or something like that

thheller17:02:59

that works just fine

bronsa17:02:31

what's the value of opts? although it shouldn't make any difference

thheller17:02:45

opts
         {:eof eof-sentinel
          :read-cond :allow
          :features #{:cljs}}

thheller17:02:51

yeah doesn't matter

bronsa17:02:39

right, so just to make sure if you eval (reader/read *in*) and type 1 you get that exception?

thheller17:02:25

no if I run that in the REPL it works just fine

bronsa17:02:35

then what causes it to fail?

thheller17:02:42

form
         (binding [*ns*
                   (create-ns ns)

                   ana/*cljs-ns*
                   ns

                   ana/*cljs-file*
                   name

                   reader/*data-readers*
                   tags/*cljs-data-readers*

                   reader/*alias-map*
                   (merge reader/*alias-map*
                     (:requires ns-info)
                     (:require-macros ns-info))]

           (prn [:reading-from *in* opts])
           (try
             (reader/read opts in)
             (catch Exception e
               (prn [:wtf (.getMessage e)])
               (throw e))))

thheller17:02:59

[:reading-from #object[clojure.lang.LineNumberingPushbackReader 0x726ff63d "clojure.lang.LineNumberingPushbackReader@726ff63d"] {:eof #object[java.lang.Object 0x208ac70d "java.lang.Object@208ac70d"], :read-cond :allow, :features #{:cljs}}]

thheller17:02:08

[:wtf "clojure.lang.LineNumberingPushbackReader cannot be cast to java.io.InputStream"]

bronsa17:02:17

how is in defined?

bronsa17:02:47

are you sure

thheller17:02:59

it works if I actually use *in* ...

thheller17:02:13

teh fuck ... I'm sorry 🙂

bronsa17:02:13

that sounds like somethingis calling (input-stream-reader *in*)

bronsa17:02:16

or somethign like that

thheller17:02:24

yeah exactly

thheller17:02:48

thanks and sorry again for wasting your time

bronsa17:02:56

no worries

thheller17:02:38

is there any way to get all this to work with source-logging-pushback-reader?

thheller17:02:09

wait let me try this with actual *in* first .. not that I mess that up again

thheller17:02:48

k it works, just had some messed up repl state 😉

thheller21:02:45

@alexmiller how "official" is the socket REPL sessions stuff? I have some thoughts on the subject but nothing except clojure.core.server/*session* seems to exist?

Alex Miller (Clojure team)21:02:24

That all got yanked out before the final

thheller21:02:03

are there any open tickets or discussions about this?

thheller21:02:13

anything already in progress?

Alex Miller (Clojure team)21:02:14

No, no plans to do anything more with that right now

Alex Miller (Clojure team)21:02:31

But you can write your own socket server that does whatever you need

thheller21:02:56

yeah just checking, the building blocks are basically there to do what I need

Alex Miller (Clojure team)21:02:27

They can be programmatically installed too, so you can set up whatever you need before you start the server

thheller21:02:43

yeah I just have one issue so far when it comes to nesting one REPL in another

Alex Miller (Clojure team)21:02:16

Should work - what's the issue?

thheller21:02:26

specifically a CLJS repl, say I'm at the normal clojure.main/repl

thheller21:02:33

I then eval (cljs) or something

thheller21:02:54

this then starts its own loop off *in* and prints to *out* as intended

thheller21:02:20

the issue is if you have a tool reading *out* trying to do things like syntax highlighting (ie. Cursive)

thheller21:02:40

is that it cannot identify which "level" this came from

Alex Miller (Clojure team)21:02:08

Yeah, not sure what the repl could do about that

thheller21:02:37

the (cljs) loop can rebind *out* but at some point some output must go the real *out*

Alex Miller (Clojure team)21:02:11

I have a repo with some sketches of how tools could work with the socket repl at https://github.com/puredanger/replicant

thheller21:02:15

my idea was that every new loop, informs the current loop that it is no longer in charge

thheller21:02:33

so it should stop parsing *out* and just pass it through maybe?

thheller21:02:58

basically this would happen as soon as you bind clojure.core.server/*session*

thheller21:02:10

just a rough idea at this point

Alex Miller (Clojure team)21:02:38

Generally it's easiest to design the repl you want rather than to nest

thheller21:02:30

yeah probably

Alex Miller (Clojure team)21:02:22

The main repl is very customizable

thheller21:02:43

yeah as long as you stick to in,out,err

thheller21:02:56

but I also have the output of the cljs compiler I must put somewhere

thheller21:02:08

and other status message like things

thheller21:02:30

would be nice to have a standard way of doing things that is not nrepl 😉

thheller21:02:50

the nesting stuff is just so much nicer

thheller21:02:44

anyways, I will try some things. just wanted to check if there was some official progress on that front.

Alex Miller (Clojure team)21:02:07

If you want a stream compliant client, then in/out/err is all you have. :)

thheller21:02:34

yes, but there should be a way to tools provide "more".

thheller21:02:20

ie. I start a loop and bind *session* with {:call-me-with-compiler-output some-fn}

thheller21:02:47

the nested loop can check that binding and call that fn if it supports that feature

thheller21:02:57

otherwise is can just print to *out*

thheller21:02:59

just a rough idea so far, might totally not work out. basically I'm just looking for a way to "extend" the standard stream model. If I'm in an IDE I want pretty output, when I just telnet somewhere it is ok to just have text

thheller22:02:59

(loop []
  (prompt)

  (let [form
        (read)

        [js warnings]
        (cljs-compile form)]

    (if-let [cb (get *session* :cljs/compiler-warnings)]
      (cb warnings)
      (print-warnings warnings))

    (let [result (eval js)]

      (print result)
      (recur))))

thheller22:02:37

if whoever created the parent loop binds *session* with {:cljs/compiler-warnings (fn [warnings] ...)} they go somewhere else

thheller22:02:48

that is the idea at least, probably terrible in practice

thheller22:02:41

nevermind the fact that a cljs loop looks very different due to eval happening in another runtime, but the idea is the same