#clojure logs

2015-12-08

00:00justin_smith,(,,,,+,,,,,,,,2,,,,,,,,,,2,,,,,,,),,,,,,,,,,,,,,,,,,,,,
00:00clojurebot4
00:00dongcarljustin_smith: oh, so it was just for aesthetic purposes?
00:00justin_smithright, they don't do anything
00:00dongcarljustin_smith: thanks!
00:00justin_smithwell, they don't do anything a space or newline wouldn't do (of course)
00:22dongcarlHi guys, is there anywhere that can explain clojure's loop and recur structure to me? I'm a scheme user and I don't think I've seen this elsewhere...
00:29dongcarlhelp anyone?
00:32spiedendongcarl: have you seen this page? https://clojuredocs.org/clojure.core/loop
00:34dongcarlspieden: yes... I think I get it now... so recur just binds the same variables that loop already bound, but to the new values passed to it?
00:51owlbirdhow do you guys test your code?
00:53mlb-dongcarl: sounds right to me
01:08spiedendongcarl: yeah exactly. like a tail optimized recursive call
01:09spiedendongcarl: compiles down to similar bytecode to a java loop i think
01:16dongcarlspieden: because the JVM isn't optimized for tail-recursion?
01:16saraHi, how to call methods from db.clj in core.cljs,i have core.cljs file with login ui and i want to call a method from db.clj when i click a button
01:16saraplease help me if anyone know this..
01:54ridcully_sara: you need to `require` your db ns. e.g. in your (ns ... (:require [my-ns.db :as db])) and then (db/dosomething ...)
01:57jonathanji have some code that calls a function `fetch-contents` which does an HTTP GET and returns some contents, now to test this i'd rather that function returned some predefined data and made no network requests, i think this is called dependency injection? is there a convenient way to achieve this with Clojure?
01:58jonathanji could of course pass the function as a parameter, but then the implementations get a bit longer and uglier
02:01jonathanjooh, `with-redefs` looks like the winner
02:01tolstoyjonathanj You could also define the client with defprotocol, then have a "mock" implementation locally.
02:02tolstoy(defprotocol WebClient (get-data [_ params]))
02:02jonathanjyou still have to pass the implementation to the fn, which is more or less the same as just passing my stubbed version
02:03jonathanjso i'm not quite sure what the point would be for a simple piece of code like this
02:03tolstoyFor your test, you'd just do: (defrecord FakeClient [] protocol/WebClient (get-data [_ params] {:fake "data"})).
02:03jonathanjtolstoy: yeah, but you have to pass an instance of that to the fn trying to use it, not so?
02:03tolstoyjonathanj Yeah, what I was mentioning is better if you've got a bit of complication.
02:03jonathanjagreed
02:04tolstoyNo, I don't think so.
02:04tolstoyThere are two defrecords, the "real" one, and the fake one. You're writing tests to the protocol.
02:04tolstoySo, (get-data (FakeService.) "x" "y") or whatever.
02:05jonathanjokay, except that the tests aren't calling get-data directly
02:05jonathanjit's a higher level function
02:05tolstoyAh.
02:05tolstoyThat's where something like Component helps out.
02:05jonathanjlike: (defn foo [uri] (do-stuff (http/get uri)))
02:05tolstoywith-redefs definately works.
02:05jonathanji'm using system, which is built on component
02:06jonathanjhow does component help me?
02:06tolstoyFor tests, you create a new System with the mock deps you want, then start that up rather than the real one.
02:06jonathanjthe deps still have to get somewhere somehow
02:07tolstoyUsing component (or system)?
02:07jonathanjhow does my mock dep get from my system to the foo function above?
02:08tolstoyHow does the real dep get there? Just use the same way?
02:08jonathanjit's required?
02:08Trioxinis there anything wrong with creating things like maps and vectors with def to work with them later? So far in my tutorial I haven't seen it done but tried it and it seems to word as in (get vec1 :b)
02:09jonathanjtr.
02:09jonathanjTrioxin: (def) defines a value global to the namespace you call it in, so you probably don't want to use it for anything that isn't supposed to be global, or for simple examples/repl work
02:10tolstoyjonathanj : I can't speak to your system cause I can't see it, but I have stuff like (system-map {:web-svc (mk-web-svc) :data-svc (component/using ... {:web :web-svc})) etc.
02:11Trioxinjonathanj, I had put it in a defn to be used within it. so how would I work with a map or vector later? I keep seeing examples of both creating and searching them in the same line but never assigning a name to them.
02:11tolstoySo, in tests, I just make one of those, and instead of (mk-web-svc) I use (mk-fake-web-svc). The data-svc then uses that one. Since they both implement the same interface, it works.
02:11jonathanjTrioxin: what do you mean by "later"?
02:12jonathanjtolstoy: so say you had a function "foo" defined more-or less like i did above, how does it get access to the system map? do you have to pass it to it?
02:12Trioxinjonathanj, create a map and then get a value out of it later in a function
02:12jonathanjTrioxin: within the same function?
02:12Trioxinsure
02:12jonathanjTrioxin: perhaps you're looking for `let`?
02:12jonathanj,(doc let)
02:12clojurebot"([bindings & body]); binding => binding-form init-expr Evaluates the exprs in a lexical context in which the symbols in the binding-forms are bound to their respective init-exprs or parts therein."
02:13jonathanjthat's not actually that useful
02:13jonathanjhttps://clojuredocs.org/clojure.core/let
02:13tolstoyjonathanj Yes, or I'm assuming that "foo" is invoked in the context of an existing component, so has access to that components config. But I guess an example is better. Alas, I don't have one visible.
02:14dongcarldoes clojure do `let' sequentially or in parallel?
02:14jonathanjsequentially
02:14ridcully_sequentially
02:14dongcarljonathanj: so similar to let* in lisp?
02:14jonathanjdunno, the only lisp i know is Clojure
02:14ridcully_,(let [a 1 b (inc a)] b)
02:14clojurebot2
02:15dongcarljonathanj: ridcully_: thanks
02:15jonathanjtolstoy: sorry if i'm being stupid here, but i don't understand how "foo" actually gets a reference to the component in order to peel things out of it
02:17tolstoyjonathanj: https://gist.github.com/zentrope/ff6fee94f39927d1046f
02:18Trioxinjonathanj, I just read let. I am seeing in this tutorial though using defn to create functions that work with sets of data as maps and vectors. This is the accepted way of working with such datasets?
02:18tolstoyjonathanj: In that example, I'd make a new map for "testing" and use, say (make-fake-mail-svc) instead of the real one.
02:18tolstoyjonathanj: Then, when I call a function (do-something-that-results-in-mail (:biz-svc system)), my fake version would be invoked.
02:20ridcully_Trioxin: top level def's (consider ^:const) are fine
02:30tolstoyjonathanj I guess in my apps, maybe nothing ever happens except it's inside one of the components. Perhaps you're doing something different? Crossed assumption in there somewhere. ;)
02:43Trioxinintellij is annoying me. It never lets me backspace a ( or ) or add one when I'm trying to correct a mistake in my program
02:43Trioxini have to cut and paste them
02:46TEttingerTrioxin: sounds like you have paredit on?
02:46TEttingerit's on by default in cursive
02:46Trioxinthx
02:46TEttingerit's either a setting or a button to enable/disable it
02:59ridcully_Trioxin: it's called structural editing. it can be toggled with a small button on the lower/right corner or in the settings
03:02slaterrsdf
03:03lumaTrioxin: also, it's actually quite helpful, since it doesn't let you create uneven parentheses
03:03qsysclojure and desktop applications: is seesaw still the best option? or are there any other/newer/still maintained projects?
03:03TEttingerseesaw doesn't need changes really does it? I mean swing isn't changing
03:03Trioxinoic it. just need to turn it off every now and then
03:04TEttingerseesaw is really nice IMO
03:04qsysallright, never did much in seesaw so far... so well, it's nice and stable
03:05qsysgood enough for me than
03:05qsys*then
03:05TEttingerit helps to check the source of the examples -- docs are good not great
03:06qsysok, thanks.
03:07TrioxinFor GUI of my clojure programs I'll be using nw.js for desktop
03:08qsysnw.js, so clojurescript?
03:09qsys reasons to use nw.js instead of seesaw?
03:10TrioxinHTML5, node, clojurescript, and I should be able to embed jars that can talk in the dom
03:11Trioxinas in an applet or you could just communicate on the backend of the app via node since node code in nw.js interops with the dom code
03:12Trioxinso very easy to make a GUI
03:12qsysyes, I can imagine that
03:13qsysbut easier than, e.g. seesaw? (which looks really simple as well)
03:13Trioxineasy as making a webpage. styling with some jquery dropins
03:15qsyshmmm, maybe I should try both
03:17qsysif jars can be embedded in nw.js - that may be a bit of double resources useage: nw.js running on a javascript engine and starting a jvm for some logic
03:17Trioxinyou could even do both and embed your app at 100% the window if you wanted the extra scripting and node
03:18Trioxinyou can strip nwjs down to be pretty small getting rid of what you don't need
03:19qsysand have just plain access to filesystem and such - I'm talking about a rather small application for desktops only (yes, I have someone asking for that!?)
03:20Trioxinjvm will run as separate process i believe and still you have the interop
03:23qsyswell, maybe time to compare seesaw and nw.js :p
03:24Trioxinin my experience, using html5 for desktop GUI comes out looking very nice very fast and then much of that code is then portable to cordova/phonegap
03:26qsyssound nice, so here I go... seesaw vs nw.js
03:26qsysmight be fun.
03:26Trioxinhttp://jqueryui.com/
03:41TrioxinI'm looking for the last jquery theme I used that was really nice but for some reason I'm missing a file. must be on my external drive
03:42qsys:) don't worry, I'll find out.
03:42qsystheming is not my biggest concern right now :)
03:43Trioxinhttp://www.jquery2dotnet.com/2013/05/jquery-ui-themes-collection.html
04:06alexyakushevHello everyone
04:07alexyakushevWhat is the correct way to fully clojure.edn/read a stream until EOF?
04:08muhukalexyakushev: does it stop reading halfway through?
04:09alexyakushevNo, I just have a file with individual EDN objects, and I want to read them all one-by-one until the file ends
04:09alexyakushevLike `slurp`, but use clojure.edn/read instead
04:11alexyakushevScratch the one-by-one part, I'm being incomprehensible. I just want to read all of them, without catching EOF exception manually
04:11muhukalexyakushev: so you don't want an exception to be thrown on EOF?
04:13alexyakushevI thought there might be some utility reading function like `slurp` that just stops reading at the end of file, and returns the result
04:15noncomalexyakushev: why don't you slurp and then read-string?
04:15noncomalexyakushev: actually it sounds like you'd better wrap the individual edn objects into a edn []
04:16alexyakushevBecause the file is very big, and I reading it as a string first effectively doubles the memory required to process it. Even if it will be GCed shortly after
04:16noncomor maybe something like (read-string (str "[" (slurp file) "]"))
04:16noncomah i see
04:17alexyakushevnoncom: No, wrapping it in a top-level sequence is exactly what I don't want to do. EDN is not some filthy JSON, its meant to be streamed :)
04:17alexyakushev*it's
04:18noncomalexyakushev: afaik there's no such functionality readily available
04:18alexyakushevI want to have both the ability to read it object by object when I need that, and to read it all without extra hassle
04:19alexyakushevnoncom: Yeah, I suspected that, just asked to be sure
04:20noncomalexyakushev: a bit contradictory to the term "edn is meant to be streamed".. but really, there are such holes in functionality - one of them i met when it turned out that clojures ns system is coupled with filesystem, and it is not possible to easily fetch namepsaces from, say, a database or network
04:21alexyakushevYes, there is that
04:22alexyakushevI just recollect that in one of his talks rhickey said that being able to stream EDN or Transit objects is one of their advantages over JSON where you must have one top-level object
04:23muhukstreaming is streaming, EDN or JSON doesn't make a difference.
04:24muhukwhat does `read` return? Multiple values or a single seq?
04:25alexyakushevmuhuk: They do, in fact. Is "foobar" a valid JSON?
04:26alexyakushev*do differ
04:26muhukalexyakushev: how do you connect having a top-level object with streamability?
04:27alexyakushevmuhuk: How do you put three JSON objects — "foo", "bar", "baz" — on a stream?
04:28muhukalexyakushev: how does `read` delimit EDN values of `foo` and `bar` (without ticks)?
04:29alexyakushev,(read-string "foo bar")
04:29clojurebotfoo
04:29muhukalexyakushev: there's your top-level object, it's just not EDN
04:30alexyakushevThere - where? There is no top level object in that string. There are two objects.
04:31muhuk:)
04:31owlbirdhow to add a list of data like ({:math 80} {:math 70} and output {:math 150 :count 2}
04:31muhukalexyakushev: you can write a function that reads a stream of valid JSON, separated with whitespace. It would be no different than the streaming EDN.
04:32muhukowlbird: there is no core function, if you are asking that
04:32alexyakushevowlbird: I don't think there is a single function that does exactly that. But you can construct it from parts
04:32alexyakushev,(merge-with + {:math 80} {:math 70})
04:32clojurebot{:math 150}
04:33alexyakushevThen you can `assoc` the number of maps to it
04:33owlbirdawesome!
04:34alexyakushevmuhuk: OK, now you have a stream of JSON objects separated by whitespace. Is that stream valid by JSON spec? How do you read a single value from it?
04:35muhukalexyakushev: is `foo bar` valid EDN?
04:35alexyakushevYes
04:35muhukread-string said no above
04:35alexyakushevread-string said yes, it correctly read the first value
04:36muhukalexyakushev: observe:
04:36muhuk,(read-string "##")
04:36clojurebot#error {\n :cause "EOF while reading character"\n :via\n [{:type java.lang.RuntimeException\n :message "EOF while reading character"\n :at [clojure.lang.Util runtimeException "Util.java" 221]}]\n :trace\n [[clojure.lang.Util runtimeException "Util.java" 221]\n [clojure.lang.LispReader$DispatchReader invoke "LispReader.java" 677]\n [clojure.lang.LispReader read "LispReader.java" 263]\n [cloj...
04:36muhuk,(read-string "foo ##")
04:36clojurebotfoo
04:37muhukalexyakushev: by your logic `foo ##` is also valid EDN
04:37alexyakushev`##` is not a valid EDN object
04:38alexyakushevBut the reader stops before it
04:39muhukalexyakushev: did you think why?
04:39muhukif `foo bar` is valid EDN, why does read-string just read the first bit?
04:40alexyakushevBecause `foo` is a valid EDN object. `read` reads the first object from the string and returns it.
04:40alexyakushevs/string/stream/ but the idea is the same
04:41muhukno it's not. `foo bar` not valid EDN, `[foo bar]` is, also `(foo bar)` etc.
04:41muhuk`foo bar` is two valid EDN parts, joined with a space
04:43muhukin spec it says "There is no enclosing element at the top level. Thus edn is suitable for streaming and interactive applications."
04:43muhukI guess it's time I eat my words. :(
04:45alexyakushevmuhuk: No shame as long as the knowledge increases after the discussion
04:45alexyakushevAnd you were right that by separating json elements on a stream with whitespace it might be enough to imitate this behaviour
04:46alexyakushevBut since JSON spec says nothing about that, it is entirely on the shoulders of the implementor to either support that or not
04:46muhukyeah, that bit I would still defend. JSON is as streamable as any encoding.
04:47muhukthe spec says there's no enclosing element at the top level, but there is actually an enclosing list/seq, implicitly
04:47alexyakushevThere's no such thing as "JSON stream" officially
04:47alexyakushevhttps://en.wikipedia.org/wiki/JSON_Streaming
04:48muhukyeah I know
04:48muhukbut in practise people do stream JSON
04:48alexyakushevSure
04:48muhukand it works just fine
04:48alexyakushevBut if I say to me "I will send you a JSON stream", how should I treat that?
04:49muhukyou're right. I would ask how you delimit.
04:49muhuk"\r\n" is what's used mostly (prints well)
04:49alexyakushevIndeed. So it's not really JSON at this point, but our custom format on top of JSON
04:50muhukalexyakushev: aren't you at least a bit curious why read-string doesn't support this behavior?
04:50muhukI mean reads just the first thing, ignoring the rest.
04:50alexyakushevI think that's the behavior most people expect, or have learned to expect
04:51alexyakushevread-string is no different from read, except that it turns a string into a stream
04:51alexyakushevAnd I wouldn't want `read` to consume the whole stream if I need just one element
04:51muhukbut since I now know `foo bar` is valid EDN, I would expect to get a '(foo bar) and not just 'foo
04:52alexyakushevImagine you have a 50GB file of EDN objects, and you want just the top 10 of them
04:52muhukmy point is, definition of valid EDN seems to differ, when you're expecting a stream and when you are not.
04:53muhukalexyakushev: also did you try setting :eof param in options to something like ::this-is-the-end?
04:56alexyakushevDamn it, that's where they moved it! I'm so dumb
04:56alexyakushevThanks, now that was really helpful:)
04:56muhukalexyakushev: yw
04:57alexyakushevAnd back to `read-string` question
04:57alexyakushevLike I've said, `read-string` is just a wrapper around `read`
04:58alexyakushevSo it shouldn't really know if somewhere later in the string there is invalid EDN
04:59alexyakushevA stream can't know that, a string can, but we'll have to parse the whole string first to ensure that all EDN is valid, and then return only the first element. Which is weird
05:07sara_how to use web-server to handle the requests from clojurescript
05:08muhukalexyakushev: that's what I'm saying: it is weird and confusing
05:08muhukalexyakushev: I'm not really arguing though, if spec says it is, it is
05:09alexyakushevmuhuk: It might be confusing at first, but at least it is consistent. Which is much more valuable for me
05:09muhukbut if I was designing it, I would make "streaming EDN" as an extension to EDN
05:09muhukI don't think it's consistent
05:10muhukfor the same input; you get a seq from `read`, but `read-string` reads the first thing
05:10ridcully_sara_: are you asking the same questions on stack-overflow? then see the comments there
05:11muhukand paste the link to SO so we don't have to fish the details out
05:11ridcully_sorry, i was just guessing
05:12alexyakushevmuhuk: What is an example where you get different things from read and read-string?
05:14muhukalexyakushev: take "foo bar", make a reader out of it. Essentially they are the same input right?
05:15alexyakushevAbsolutely
05:15alexyakushev,(read (java.io.PushbackReader. (java.io.StringReader. "foo bar")))
05:15clojurebotfoo
05:16alexyakushev,(read-string "foo bar")
05:16clojurebotfoo
05:16muhukdamn you alexyakushev, you made a fool of me again :D
05:17muhukI thought read was returning a lazy-seq of some sort
05:17alexyakushevOh
05:18alexyakushevWell, now you know:) It's all for the best
05:18alexyakushevAnd thanks again for pointing me at the correct edn/read option! I gonna do so some actual work now
05:18alexyakushevCheers
05:18muhukalexyakushev: OK, it's not confusing or inconsistent etc. anymore. Just need to RTFM
05:19muhukbyw
05:19muhukbye
07:36clgvI tried to test direct linking with clojure 1.8-RC3 but it didn't seem to work. I used the following profiles {:uberjar {:aot :all}, :1.8-DL {:dependencies [[org.clojure/clojure "1.8.0-RC3"]], :jvm-opts ^:replace ["-Dclojure.compiler.direct-linking=true"]}} and assumed that direct linking should be used in "lein with-profile 1.8-DL do clean, uberjar" then
07:38clgvbut functions are still resolved via .getRawRoot on call sites
07:41Bronsaclgv: I just tried and it's definitely direct linking my vars
07:41Bronsawith that same setup
07:42clgvBronsa: ok, that's weird then
07:43clgvBronsa: does direct linking have fallback code generated and I confused that?
07:45clgvI looked up the invoke function of my.ns$my_fn.class with a java decompiler
07:46Bronsaclgv: DL generates an invokeStatic method
07:46clgvBronsa: in the same class?
07:46Bronsayes
07:46clgvok that's definitely missing
07:46Bronsaclgv: what functions are you trying to compile?
07:46Bronsaif you try (defn foo [x] x) (defn bar [x] (foo x))
07:47clgvthat's the layout, yes
07:47Bronsabar should be compiled into invokestatic Foo.invokeStatic
07:47clgvBronsa: I'll enter this simple example in the same namespace and check again
07:50clgvBronsa: might be a build tool problem - the code is in a non-aot dependency library
07:50clgvthough it is compiled just fine
08:01clgvBronsa: is there a known issue with leiningen 2.5.0 wrt dynamic linking or jvm options?
08:01Bronsano idea
08:05clgvthere's not a single invokeStatic in the whole target/classes folder :(
08:14Bronsaclgv: I'm using lein 2.5.3 and it works fine
08:14BronsaI really don't see why lein would affect DL though
08:15clgvme neither, I should just set the JVM options and then it is supposed to work
08:16Bronsaare you sure you're using 1.8?
08:17clgvyes, according to lein with-profile 1.8-DL deps :tree
08:25clgvBronsa: a simple dummy project without profiles worked
08:27clgvok, the :jvm-opts in the profile seem to be the problem
08:36noncomdid anyone use Pallet for shell scripting in Clojure? http://palletops.com/pallet/doc/reference/script/
08:39clgvnoncom: yes some small remote startup scripts
08:39noncomclgv: did you find it really useful?
08:40noncomi mean, it does not look like it allows using {}s easily..
08:40noncomjust does some very rough and primitive clj->bash translation?
08:41clgvI just needed bash scripts so it was good for that job
08:41clgvI am not sure what you mean with "allows using {}s easily."
08:42noncomclgv: well, if i would like to use the capabilities of {}s for data manipulation, that won't work since there are no analogous bash concepts
08:43clgv"{}s" = shortcut for clojure maps?
08:45ARM9{} is an empty map
08:45clgvARM9: sure, I was trying to find out what it meant for noncom in his description of bash tasks
08:46noncomclgv: oh, yes, sorry, i meant exactly maps, right
08:46noncomi just find that in clojurespeak, typing {}, [] or () or {:kw [] ..} is a good way to describe data structs
08:47clgvnoncom: yeah, in bash you get just streams that you can pipe through different programs
08:49clgv"^doubles" is not resolved anymore in Clojure 1.8?
08:49clgvpreviously it could be used to tag arrays to avoid reflection
08:53clgvWhat is the correct way to type hint double arrays now?
08:53clgv,(type (double-array 0))
08:53clojurebot[D
08:53clgvthat thing^^?
08:54justin_smithclgv: ^"[D" should work, but ^doubles should too
08:56clgvI have https://www.refheap.com/112483 which worked <= 1.6, and it had to be a string since there was a compiler error otherwise
08:58justin_smithclgv: I had no idea hints on let bindings would be on the symbol rather than the value
09:00DEA7THIs there a function which would transform [1 1 3 1 3 1] into [[1 1] [1] [1]], treating each 3 as a separator like a string split?
09:01clgv,(->> [1 1 3 1 3 1] (split-with #{3}) (remove #{3}))
09:01clojurebot(() (1 1 3 1 3 ...))
09:01clgvups
09:02clgvDEA7TH: ok so no. gotta write that yourself
09:02justin_smithclgv: `(let [a# ^doubles ~a] ...) appears to work with reflection warnings turned on I see no warning
09:03clgvjustin_smith: there were error cases with that one
09:03jeayeDEA7TH: You can do that with a single reduce.
09:03clgvjustin_smith: the metadata might get lost for macros (and inline fns?)
09:03justin_smithclgv: I got an error case with [^doubles a# ~a] but not with [a# ^doubles ~a]
09:04clgvjustin_smith: which?
09:04justin_smithCompilerException java.lang.IllegalArgumentException: Unable to resolve classname: clojure.core/doubles, compiling:(/tmp/form-init4469662376927938804.clj:1:1)
09:04jeayeDEA7TH: In each call to the reduce fn, conj onto the last vector; when you hit a 3, conj a new vector on
09:04clgvthat it can not resolve clojure.core/doubles to a type?
09:04DEA7THeh, I used str/split. it was actually a string, but I preferred to use partial rather than a lambda
09:05clgvjustin_smith: yeah that's pretty strange that it works in functions but not in macros. but it is totally fine to type hint the binding name
09:05DEA7THstr/split's middle argument is the data, not sure why.
09:07ridcully_,(remove (partial = '(3)) (partition-by #{3} [1 1 3 1 3 1]))
09:07justin_smithclgv: my version works inline and inside macros
09:07clojurebot((1 1) (1) (1))
09:08clgvjustin_smith: call it with a macro in argument position or an inline fn
09:10clgvjustin_smith: the stupid thing is that I only get that error when AOT compiling
09:10clgvon repl it just compiles fine
09:17DEA7THis there something like ctrl-o which works in the REPL? I have to retype 10 lines of code and I'd rather not do (uparrow 10 times + enter) 10 times
09:18ridcully_DEA7TH: clojure-rlwrap: aliased to rlwrap -m -M .clj
09:19ridcully_DEA7TH: CTRL-^ then open your $VISUAL
09:24clgvDEA7TH: better use some sane dev env with editor-repl-integration
10:05Bronsaclgv: (fn [a] (let [^doubles x a] (aset x 1 1.0))) works with no reflection warnings for me
10:06clgvBronsa: sure, (defn ^doubles f [...] ...) caused an error when AOT compiling via leiningen, but not in REPL
10:06Bronsaclgv: that's wrong
10:06Bronsametadata on var names is evaluated
10:07Bronsadoubles is resolved to the clojure.core/doubles function
10:07clgvBronsa: but (defn f ^doubles [...] ...) does not work either
10:07Bronsait should
10:07BronsaI just tried, it works
10:07clgvBronsa: I tried and got reflection warnings anyway. pre 1.8 the var was the place where the metadata was used to avoid reflection
10:08Bronsa(defn f ^doubles [] (double-array 10)) (aset (f) 0 1.0)
10:08Bronsaworks w/ no refelction warnings
10:08Bronsaclgv: no, that never worked
10:09Bronsaclgv: it's always been the case that you can type hint on both the var name and the argvec
10:09Bronsathey have different semantics
10:09Bronsatype hints on arg name are evaluated, on the argvec are not
10:09Bronsaso (defn foo ^doubles [] ..) ~= (defn ^{:tag 'doubles} foo [] ..)
10:09clgvBronsa: ok, maybe stale definition then... I tried all possibilities there..
10:10clgvBronsa: so is it now possible to only tag types on the arg vec?
10:10Bronsano, you can do both, depending on the type hint
10:10clgvTHat did only work for primitives up to clojure 1.6
10:11Bronsait always worked for every type hint, with some caveats
10:11clgvBronsa: yeah, the caveats were what made me say it didnt work
10:11clgvBronsa: so now I can establish the convention of only tagging the argvec in my projects?
10:11Bronsayeah, those have been fixed in 1.8
10:11Bronsaclgv: yes
10:11clgvgreat :)
10:11BronsaI would suggest that
10:13Bronsait has the additional benefit of throwing an exception when you use invalid type hints aswell (some are calling that a bug :( http://dev.clojure.org/jira/browse/CLJ-1863)
10:14rhg135A npe...
10:15clgvBronsa: well, let's switch that to a more informative exception ;)
10:16clgvso let's see whether there is an improvement through direct linking
10:21Bronsarhg135: clgv: you try to convince clojure/core that type-hinting validation is reasonable and I'll be more than willing to fix that :) I've been starting that same discussion multiple times for over 3 years now and they just seem not to care
10:22Bronsaso a NPE at compile time to me is still an improvement over silently ignoring type hints & maybe throwing at callsite
10:25rhg135The worrying part is that it could throw at runtime
10:25clgvBronsa: read at least one of the discussions on the ML ;)
10:26rhg135But then again if you need the type hint to not blow up, then you need more help
10:34jonathanjhrm, how can i turn an Enumeration<String> into a Clojure object that is readable using (println)?
10:49rhg135seq
10:49rhg135Maybe
10:54jonathanj(enumeration-seq) appears to have worked
11:07jonathanjclass "org.bouncycastle.asn1.ASN1Object"'s signer information does not match signer information of other classes in the same package
11:07jonathanjhow on earth do i resolve this type of error?
11:21jonathanjnevermind, figured it out with the help of `lein deps :tree`
11:22jonathanjis there something like (for) that would produce a map instead?
11:22jonathanji could do (into {} (for ...)) but i was wondering if there was something more direct
11:25j-pb(into {} is the idiomatic way to create maps from pairs :)
11:26j-pbif you have a keysequence and a value sequence you can combine them into a map with zipmap
11:26clgvhmm no real difference between 1.8 and 1.8 with direct-linking on this benchmark
11:27clgvapprox 5% improvement from 1.7
11:27rhg135Hey, that means non direct is pretty fast
11:29clgvok, since I needed that code as fast as possible on 1.6 this likely means that I found all hotspots where inline functions were worth it ;)
11:29rhg135Indeed
11:30clgvso this results is probably not that representative
11:30rhg135Maybe it's meant for less hand optimized code
11:30clgvdefinitely
11:30clgvsince the JVM can inline if it detects that as beneficial
11:32rhg135The clojure compiler doesn't optimize much I think
11:32rhg135But the jvm is good at it
14:39Stalkr_Hi, I wish to explore some Clojure as I have heard a lot of good stuff about it. I am wondering though, I am just creating a very simple "Hello, World" server using Compojure, how come it eats over 100mb of RAM just for that? Is that just how it is with Clojure?
14:44justin_smithStalkr_: yes, you can't run clojure code without loading the whole language and compiler into your runtime
14:45justin_smithStalkr_: which is bad if you are worried about RAM usage, but in practice we tend to use it for things that start up once, stay running for months at a time, and we just live with the inflated memory usage.
14:47Stalkr_justin_smith: I see, I'm only worried about having 512mb RAM on a cheap DigitalOcean host but I assume that means it takes more to reach 200mb or more RAM usage then
14:53justin_smithyeah, most of that usage is just from loading clojure itself - unlike most languages there is no way to run clojure without loading the full language (though there are experiments to do otherwise)
14:54justin_smithStalkr_: if heap usage is a big concern, you could also check out clojurescript under node.js
14:54Stalkr_justin_smith: I come from mainly JavaScript, so ClojureScript interests me too
14:54Stalkr_but I suspect CS will be a pretty big change from JS too
14:54justin_smithStalkr_: one bonus is all of js is accessible very easily from interop
14:55justin_smithwhich can be a crutch, but also eases things
14:56Stalkr_justin_smith: I could run Express with ClojureScript through interop if I wanted right? I am not sure if Clojure or ClojureScript seems most appealing to me
15:30juanjo_hi, can you help me with luminus?
15:30juanjo_i have created a demo app with h2
15:30jonathanjis anyone here familiar with <https://github.com/stuartsierra/component&gt;?
15:30juanjo_but id like to use postgresql in heroku
15:31juanjo_how should I do it?
15:31jonathanji have a question about composing components
15:31codefingerjuanjo_: when you generate the luminus app use +postgres
15:32juanjo_codefinger: that's the problem, the app is aready generated
15:32juanjo_how can I add +postgres now?
15:33codefingerjuanjo_: hmm, not sure. you could generate a new app and see what's different. but i don't think there is much. mainly the jdbc driver
15:33codefingers/there is/there is not/
15:33juanjo_ok
15:34codefingererr no. was right first time :)
15:35codefingerjuanjo_: i don't have an app in front of my but i think you'll need to add [postgresql "9.4-1201-jdbc4"] to project.clj
15:37codefingerjuanjo_: and because yesql/conman use DATABASE_URL, it will just pick up the right driver for the postgres:// protocol
15:39mavbozojonathanj, what is your question?
15:40jonathanjmavbozo: i think i've answered it, just testing some code
15:41schmir[org.postgresql/postgresql "9.4-1206-jdbc42"]
15:46codefingerschmir: +1 juanjo_ ^^
15:46juanjo_thanks
15:46jonathanjmavbozo: i'm actually using https://github.com/danielsz/system
15:47jonathanjanyway, i'm trying to use this component to define a ring handler: https://github.com/danielsz/system/blob/master/src/system/components/app.clj
15:48jonathanjbut apparently whatever code i'm running doesn't match that
15:49jonathanj(component/using (new-app #'some-ns/my-ring-handler) produces clojure.lang.ArityException: Wrong number of args (1) passed to: app/new-app
15:50jonathanjoh, there has been a release since i last looked
15:50jonathanjthanks for the rubber duck session, mavbozo :|
15:53mavbozojonathanj, :)
15:58jonathanjexcept now it's still not working, apparently some dependency is nil for reasons i'm unable to explain
16:00ridcully_i thought the rubber duck was replaced with the plushy cthulu?
16:02jonathanjso (component/using (new-app #'some-ns/my-ring-handler) [:foo]) ends up invoking some-ns/my-ring-handler with nil as the only parameter, that makes no sense to me
16:02jonathanjin particular because another component is initialized before with the same component dependency and it's not nil there
16:13mavbozojonathanj, i don't see any component/using usages in danielsz/system readme.
16:15mavbozoso, now you use stuartsierra's component directly?
16:18jonathanjmavbozo: i'm sure it mentions it, it might be kind of indirect
16:18jonathanjanyway, i discovered the issue, the new-app component expects the dependent component to be named "db"
16:23jonathanjwhich seems like a stupid requirement
16:23justin_smithStalkr_: yes, you should be able to use Express with cljs
16:24justin_smithStalkr_: sorry for the delay, just got back from lunch
16:24justin_smithStalkr_: a walkthrough I found http://www.mase.io/code/clojure/node/2015/01/25/clojurescript-and-node-part-2-express/
16:26Stalkr_justin_smith: No problemo, I will probably give both a try over a few weeks, since I am interested in front-end too cljs with Om/Reagent or some React-wrapper like those seems very interesting. I'll give the article a look later :-) Does it make most sense to have Clojure on back-end + cljs on front-end or in that case keep it all cljs?
16:29ridcully_jonathanj: in component the using part would name the things you want to autowire/inject
16:30jonathanjridcully_: yeah, i mean that the "generic ring app" component in system has the thing named "db"
16:32justin_smithStalkr_: I have not tried cljs on the backend but a friend has in production and says it works well
16:32justin_smithStalkr_: but clojure on the backend is definitely the mainstream choice - it's the "official" version and all
16:33MJB47cljs + node works well
16:33MJB47but using normal clojure is easier imo
16:34MJB47but depends what you wanna do
16:34MJB47you obviously dont get threads with cljs
16:34MJB47which you may or may not care about
16:34Stalkr_justin_smith: I have tried to search for isomorphic (rendering JavaScript HTML server-side) but I could not find much, only a single article, but was thinking that it made more sense that with cljs to have isomorphic sites. Though I guess it should be possible with Java Nashorn
16:34Stalkr_MJB47: is threads important when you have core.async?
16:34MJB47core.async is just an abstraction
16:34MJB47it doesnt replace threads
16:35MJB47like you can do what core.async does with callbacks
16:35MJB47https://www.youtube.com/watch?v=fICC26GGBpg
16:35MJB47also i recommend this
16:35Stalkr_I know, not saying it does but I mean it's the best we got for async programming with cljs right?
16:35MJB47which goes into some depth about server side rendering
16:35MJB47arguably yes it is
16:36MJB47but if your project would like to have proper concurrency, i would not recommend node
16:36justin_smithStalkr_: yeah, you might find something on pre-rendering reagent or om components via nashorn or node
16:36Stalkr_Ahh cool, I'll give it a watch, I have seen some cool stuff with Clojure(Script), like Figwheel but I still feel like it's a very different world from JS
16:37ridcully_jonathanj: i don't know system. i just added this, because component injects by the name _you_ give it in your record. so maybe the same with that other thingy
16:37ridcully_jonathanj: if this just adds to the confusion... sorry ;P
16:37Stalkr_MJB47: I am not sure when I would require that, but in any case, I could have one Node server for rendering, another pure Clojure for heavy tasks that requires proper concurrency right?
16:37MJB47you could yes
16:38Stalkr_Of course that is more expensive for the machine than a single Clojure + front-end cljs
16:38MJB47but you have to think about the complexity that would involve
16:38MJB47ultimately that might be the set up that suits you best
16:38MJB47or it might not
16:38MJB47who knows
16:38gfrederickstcrawley: ping
16:39Stalkr_Yeah I don't have any particular reasons for using Clojure yet so that's hard to say, that will definitely be something I will have to think about some day when doing a real project
16:39tcrawleygfredericks: what up, dog?
16:39gfrederickstcrawley: are you familiar with the general idea of how component works?
16:39Stalkr_but for now I will explore Clojure(Script) some more, see how it fits with me
16:40tcrawleyI feel like that's a trick question, but I'll respond with a tentative yes
16:40gfrederickstcrawley: okay so I'm using immutant and component at the same time
16:41gfrederickswhich so far has been fine but now I want an http server too
16:41gfredericksand don't know enough about how immutant works to be able to tell if that is even possible
16:41gfredericksthe big question I think is whether I can start/stop the web server myself, or if it has to be registered w/ the deploy somehow such that I don't have control over it
16:42gfredericks(this works fine with jetty instead of immutant, since you can just call start-jetty and get a server object that you can later stop)
16:43tcrawleygfredericks: see if https://github.com/danielsz/system/commit/1bdc182022bdbd79129d4f75bf770613b60a6499 is helpful
16:44gfrederickstcrawley: I bet so; okay thanks man thanks
16:44tcrawleyyou can pass the return value of immutant.web/run to immutant.web/stop, which is what ^ does
16:44tcrawleymy pleasure!
16:46gfrederickstcrawley: wait wait what if I'm using immutant 1.1.4?
16:46tcrawleyoh dear
16:47gfredericksI'm so sorry
16:47tcrawleyin that case, you're kindof in a pickle
16:47gfrederickstcrawley: okay maybe my real question is about upgrading then -- do I have to upgrade other apps deployed to the same server in synchrony?
16:48tcrawleywait, you should be able to do something similar in 1.1.4 though, let me look
16:48gfredericksimmutant.web/start doesn't say what it returns
16:48tcrawleyif you want to upgrade, then you have to upgrade the container itself to WildFly, or move the apps out to run as uberjars
16:49tcrawleyyou can't run an Immutant 2.x app inside the Immutant 1.x container
16:49gfredericksroger
16:50tcrawleyyou can do (immutant.web/start "/" handler) (immutant.web/stop "/")
16:50tcrawleyor (immutant.web/start handler) (immutant.web/stop), and "/" will be assumed in both casees
16:51gfrederickstcrawley: okay I will try that thanks Señor crawley
16:51tcrawleymy pleasure! I'm always here for you
16:51gfredericksyou are!
16:52gfredericks~tcrawley is always here for me
16:52clojurebot'Sea, mhuise.
16:53jcrossley3gfredericks: one other thing, if it matters: there is an undocumented option, :auto-start, that can be set to false in order to create a server without actually starting it, after which you can (.start s) or (.stop s) it. that may play nicer with component, depending on what you're doing
16:55gfredericksjcrossley3: thanks; I think the main thing that feels weird about it is that it's global rather than OOP; but it amounts to the same thing I think so it's not a big deal
16:55gfredericksif you call immutant.web/start twice with the same args will the second one throw?
16:55jcrossley3gfredericks: er... :auto-start is for the (server ...) function, not (run ...). that was added for pedestal, iirc
16:57jcrossley3gfredericks: there is no start, only run or server. i don't think run throws if you restart.
16:57gfredericksjcrossley3: there's a start because I'm using a 17-year-old version of immutant
16:58jcrossley3gfredericks: you probably need to stop doing that
16:58gfredericksjcrossley3: it's hard since there's like seven other apps too
16:59jcrossley3gfredericks: SIMPLICITY IS HARD!
17:00gfredericksthat was the punchline of rich's famous talk "Simplicity Is Hard"
17:00jcrossley3gfredericks: fwiw, i would be surprised if start tossed if called twice
17:01gfredericksjcrossley3: roger roger ack ack
17:01MorgawrThis is probably a silly question but what's the most elegant way to obtain the index of an element searched in a vector that fits a given condition?
17:02Morgawrlike I have a vector of maps with an :id property and I want to get the index of a specific map with a given :id within that vector
17:02gfredericks(first (keep-indexed (fn [idx el] (when (pred el) idx)) coll))
17:02Morgawrgfredericks: thanks, didn't know about keep-indexed :) cheers
17:16tcrawleygfredericks: calling start twice with the same context path should replace the former handler
17:16gfrederickstcrawley: the component gods are mildly sad about this
17:16amalloyMorgawr: also consider storing a map instead of a list, since you are looking stuff up by id often
17:18Morgawramalloy: that's a good point, I'll keep that in mind. I need to check if I look it up more often than I need it ordered or not :) But yeh, I'll consider it
17:18MJB47you could always use a sorted map
17:58WorldsEndlessWhat's the clojure equivalent of "import namespace.*"?
17:59tolstoyIs it use? (use '[some.lib.core])?
17:59amalloyuhhh, it kinda depends whether you mean import or namespace or what. like, you import things, but not namespaces
18:00WorldsEndlessSo, java has import java.util.*;
18:00WorldsEndlessThat one happens to have a nice clojure wrapper, but for those that don't...
18:01amalloythere is no way to import all classes from a package
18:01WorldsEndlessI suppose that's for the best
18:01amalloyyes, whenever you do it in java someone tells you not to
18:01WorldsEndlessJust makes translating this java code a little trickier...
18:02WorldsEndlessdang someone
18:02WorldsEndlesscan :import use :as the same way :require does?
18:03amalloysadly not
18:03amalloythat is a feature that would be cool, unlike import foo.*
18:03WorldsEndlessshucks
18:09tolstoyWorldsEndless: When porting java, I don't use imports at all. Let the compiler tell me what it can't find. Most of the imports aren't needed.
18:23WorldsEndlesslook what I found:
18:23WorldsEndless(:import [cc.mallet.util.*])
18:24WorldsEndlessSo apparently you can do the bad stuff
18:25amalloythat just like...doesn't do anything
18:25amalloythat import is literally a no-op
18:25WorldsEndlessHmm... well, it's in the text book
18:25amalloyRIP textbook
18:25amalloyunless something new went into 1.8 i guess. i'm not super up to date
18:28puredangerNope
18:29amalloythanks puredanger, i just confirmed it myself by looking at the source too
18:29amalloyWorldsEndless: confirmed. who wrote this cargo-culting textbook?
18:29WorldsEndlessLet's see... "Mastering Clojure Data Analysis" by Eric Rochester
18:30WorldsEndlesscargo-culting?
18:31amalloymmm. i haven't heard of eric rochester, and the book seems to be about data analysis, not about clojure. so like, he's obviously wrong, but that's not totally unexpected given the focus of the book, nor really a huge condemnation of the book either. if it were a book about clojure it'd be a bigger issue
18:31amalloyhttps://en.wikipedia.org/wiki/Cargo_cult#Metaphorical_uses_of_the_term
18:32WorldsEndlessThat's a great idiom. I'm gonna use it, so I look smart like you guys.
18:33WorldsEndless:|
18:34WorldsEndlessSeriously, though, that's a great term.
18:35justin_smithsomewhere there are polynesian devs that are like "yeah, my grandpa was in a cargo cult, and now I cargo cult in my code, what about it?"
18:39PupenoWhat’s the best way to have one or more example programs that exercise my library in my library’s project? Should they be full leiningen projects on their own?
18:40WorldsEndlessPupeno: I'd try to make them as tests
18:40PupenoWorldsEndless: I don't want tests, this is on top of tests.
18:41WorldsEndlessIn that case, making seperate lein projects is what I often see on Github, with a readme in the primary project that links to them
18:53Takeijils
19:19didibusI've asked this before, but what's the Clojure syntax for destructuring inside nested maps when using :keys ?
19:20didibus,{:first "John" :last "Doe" :parents {:mother "Alicia" :father "George"}}
19:20clojurebot{:first "John", :last "Doe", :parents {:mother "Alicia", :father "George"}}
19:20didibus,(let [{:keys [parents]}]
19:20clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
19:21didibus, (let [{:keys [parents]} {:first "John", :last "Doe", :parents {:mother "Alicia", :father "George"}}] parents)
19:21clojurebot{:mother "Alicia", :father "George"}
19:21didibusNow say I wanted mother and father too?
19:32justin_smith, (let [{:keys [parents] {:keys [mother father]} :parents} {:first "John", :last "Doe", :parents {:mother "Alicia", :father "George"}}] [parents mother father])
19:32clojurebot[{:mother "Alicia", :father "George"} "Alicia" "George"]
19:33justin_smithalso, it might be clearer not to do keys when you have nesting
19:34justin_smith, (let [{{:keys [mother father] :as parents} :parents} {:first "John", :last "Doe", :parents {:mother "Alicia", :father "George"}}] [parents mother father])
19:34clojurebot[{:mother "Alicia", :father "George"} "Alicia" "George"]
19:34justin_smith, (let [{{mother :mother father :father :as parents} :parents} {:first "John", :last "Doe", :parents {:mother "Alicia", :father "George"}}] [parents mother father]) ; there's also doing away with :keys altogether
19:34clojurebot[{:mother "Alicia", :father "George"} "Alicia" "George"]
19:35justin_smithI think that version is a little easier to puzzle out (though :keys is convienient)
19:54kenrestivowhat are some sane/reasonable ways to pass settings from a clojure app to a clojurescript app?
19:55kenrestivoi.e. i have src/foo.clj , i also have src-cljs/foo.cljs. it's not so much state that i want to share, as global settings. i can't use the network to pass the state because it involves setting up the network
19:56kenrestivoand project.clj is not the place for it, since i don't want these in git. i'm using schema and component to load settings from an edn file
19:56amalloyfwiw i think the :keys version is more readable than manual map destructuring
19:57amalloyjustin_smith: ^ i have to read the manual map destructuring carefully because it being manual implies it's doing something more sophisticated than :keys
19:58didibusWow, nice, so many different ways.
20:00kenrestivoyeah, :keys is fantastic. i'm addicted to it.
20:01kenrestivomakes it very clear when reading code, what things are passed in as parameters and where they come from
20:02kenrestivoand speaking of passing parameters...
20:02kenrestivothe current nasty hack i'm using is a moustache template with "var settings = {{{settings}}}" in the clj ring handler, and then reading that on the cljs side.
20:03kenrestivo(defonce state (atom {:settings (js->clj js/settings)}) etc. i hate this.
20:19LuminousMonkeyHey #clojure, sorry, I've got a question and my google-fu is failing. When it comes to lein deps, and specifying versions, is there a best practice? For example, I write a library that can be used with Clojure 1.6 or 1.7, etc. In the project deps do I specify a range, or just the latest version?
20:22rhg135I'd just go for the latest. If people want to use old versions, they can read the readme
20:26LuminousMonkeyI thought so, I've never noticed any problems, but I have had lein deps :tree give exculsion suggestions. I thought it might just a suggested way to stop my libraries causing that, even though I have noticed problems. Ta.
20:26LuminousMonkey*haven't
20:31amalloyranges cause more problems than you can possibly imagine, despite seeming like good ideas on the surface
20:36LuminousMonkeySo, basically just the highest version for all your deps at the time?
20:36TEttingerhighest version you've tested with
20:37LuminousMonkeyCool.
20:37LuminousMonkeyTa.
20:56didibusIs there a function that sorts a nested map structure recursively in alphabetical order?
20:57xeqiis there a function that turns a channel into a lazyseq?
21:01kenrestivoa transducer might
21:01TimMcdidibus: Not a single function, no, but there are tree walk fns + sorted-map-by
21:04didibusOk, I'll look into the walk functions
21:21TimMcdidibus: clojure.walk/postwalk seems to be the thing to use
21:39dongcarlHi guys, can anyone explain to me what #(or %2 %1) does in (merge-with #(or %2 %1) state new-data)?
21:39justin_smithit's the same as (merge state new-data)
21:40justin_smith,'#(or %2 %1)
21:40clojurebot(fn* [p1__26# p2__25#] (or p2__25# p1__26#))
21:40justin_smithwait, not the same because the new-data could have false or nil
21:40justin_smithright,
21:41dongcarlso... #(or %2 %1) is like syntactic sugar for a lambda?
21:42justin_smith,'#()
21:42clojurebot(fn* [] ())
21:42justin_smithin general #(...) is syntactic sugar for a lambda, yeah
21:42dongcarljustin_smith: thanks!
21:43justin_smithone gotcha with #() is that it doesn't nest - because it would be impossible to specify the args
21:43TEttingeror will short-circuit evaluate in that case and, if the second argument given to the lambda is true, will return that without ever evaluating the first arg (I think)
21:43TEttingerpretty sure that's the reason for %2 and then %1 after it
21:44TEttinger,(merge-with #(or %2 %1) {:a 1 :c 3} {:a 10 :b 20})
21:44justin_smithTEttinger: the second item is already fully realized before the or sees it
21:44clojurebot{:a 10, :c 3, :b 20}
21:45TEttingerah, so it's just to prefer the second arg then
21:45justin_smithright, which is the normal merge behavior
21:45justin_smithexcept special case for nil or false
21:45justin_smith,(merge-with #(or %2 %1) {:a 0 :b 1} {:a nil :b 2})
21:45clojurebot{:a 0, :b 2}
21:45TEttinger(I mean why %2 is before %1, which is normally a little odd)
21:45dongcarljustin_smith: what happens in those cases? how is it different?
21:45justin_smith,(merge {:a 0 :b 1} {:a nil :b 2})
21:46clojurebot{:a nil, :b 2}
21:46dongcarljustin_smith: ah!
21:46justin_smithin the merge case, the nil is newer, so it replaces the original
21:46TEttingerinteresting
21:46TEttingerwhere's you see this code, dongcarl?
21:46TEttinger*where did
21:47TEttingerI'm a bit curious
21:47dongcarlTEttinger: one sec
21:48dongcarlTEttinger: https://github.com/shaunlebron/parinfer/blob/master/lib/src/parinfer/reader.cljc#L129
21:48TEttingerah ok thanks
21:48dongcarlI'm trying to port this to emacs-lisp for an emacs plugin
21:49justin_smithoh, cool
21:50justin_smithit would make writing lisps just like writing python or haskell I guess
23:42kenrestivodoes this new 1.8 socket repl break nrepl?
23:43justin_smithit's meant to replace it
23:43kenrestivo:(
23:43justin_smithI would be surprised if it broke nrepl - it's going to be a better alternative though
23:44justin_smithkenrestivo: when I compare clojure startup times, nrepl, lein, and clojure itself are about equal in the time each takes to load - even just an improvement on that front would be great
23:46kenrestivoi'm sure it'll be better, i just have to budget time for dealing with all my tooling breaking
23:47justin_smithI'm actually not using anything that relies on nrepl at the moment - I use lein repl but only because that's easier than starting up clojure.main
23:48dongcarlHI guys can you help me understand what's going on here: https://github.com/shaunlebron/parinfer/blob/master/lib/src/parinfer/reader.cljc#L59
23:50justin_smithit takes something like {:ch \)} then returns something different based on whether it's opening, closing, or neither
23:50puredangerkenrestivo: no, the socket repl does not break nrepl
23:50justin_smithor {:ch \a} - that's easier to read
23:50puredangerjustin_smith: and no it is not intended to replace it
23:50justin_smithpuredanger: oh!
23:50puredangerthey are alternatives
23:50justin_smithpuredanger: wishful thinking on my part
23:51dongcarljustin_smith: so I know that it takes in a state map which has a key :ch, would that work as well?
23:51justin_smithdongcarl: the other keys don't matter, it just looks at the :ch key
23:51justin_smithand that should have a char
23:51TEttinger\a is the syntax for char literal lowercase a
23:51puredangerjustin_smith: the socket repl is really a socket server + a repl that runs over it. you could also run something that did nrepl framing over the socket server afaik if you wanted to
23:51TEttingerwhat would be 'a' in C or Java
23:52justin_smith,(int \a)
23:52dongcarljustin_smith: if it's opening, it calls "
23:52clojurebot97
23:52dongcarl(defmethod push-char* :open ...)"?
23:52justin_smithit would be 97 in emacs
23:52puredangerthe provided socket repl is stream-oriented, whereas nrepl is more message-oriented, as far as I understand it
23:53justin_smithdongcarl: defmulti defines the dispatch, the defmethods define what it does for different dispatch values
23:57dongcarljustin_smith: okay. So let me get this straight. It grabs ch from the :ch key in the input, checks if it's opening, if it is, it'd call (defmethod push-char* :open ...), then check if it's closing, if it is, it'd call (defmethod push-char* :close ...), otherwise, it calls a (defmethod push-char* ch ...), and if there are no defmethods with ch, then it calls (defmethod push-char* :default ...)?
23:57justin_smithdongcarl: no, it can only call one of the dispatch values
23:58justin_smithit either calls the method for :open, :close, or the char itself - though it's clearly poorly named, because looking at the methods defined, it is dispatching on string not char
23:58dongcarljustin_smith: okay so it's what I said but if one of the defmethods are called, the other ones aren't called? like an ifelse?
23:59owlbirdhow to write a fun just return its arguments? I tried eval like this (if (nil? style) #(eval %) #(:node %)), which seems very slow.
23:59justin_smithdongcarl: right, first the dispatch in the defmulti is called, and based on that, one of the dispatch values is called