#clojure log - Mar 10 2015

The Joy of Clojure
Main Clojure site
Google Group
List of all logged dates

0:11 the_danko: yo yo

0:11 so where is the idiomatic place to put java source files in a default lein project?

0:11 in the directory structure

0:15 amalloy: the_danko: lein will look in src/java if you don't say otherwise

0:16 the_danko: amalloy so i have src/clojureproject and src/java

0:16 amalloy and that is good form?

0:16 amalloy it works for me.

0:16 amalloy: well, it's kinda tacky to have src/java and not have src/clj

0:17 the_danko: ok, got it

0:17 so then i have to change some lein settings

0:19 amalloy: do you? i guess you do

0:48 seubert: I'm having issues loading a shared object file

0:49 hm maybe this is better asked in #leiningen

1:39 Mercwithamouth: any ragtime users here?

1:39 nsjph: yes but limited

1:40 Mercwithamouth: when doing migrations i noticed they name them with the year,month,date...then there are some additional #s afterwards. can those be random or is there any logic to naming your migrations?

1:40 nsjph: i know in my recent experience

1:40 Mercwithamouth: or does ragtime have a migration generator built in i'm not aware of?

1:40 nsjph: i had YYYYMMDDXX

1:40 i had YYYYMMDDXX-description.[up|down].sql

1:41 where XX was if i had multiple migrations for a particular day

1:41 ie, 01, 02, 03

1:41 Mercwithamouth: ahh! gotcha. that works for me. makes perfect sense =P

1:41 nsjph: np

1:41 Mercwithamouth: ok, thanks. now i can jump in

1:41 nsjph: i ran into that as well

1:42 creese: Is it possible to build an uberjar that reads from a config file?

1:42 nsjph: yes

1:42 wait, when do you expect it to read from a config file

1:42 Mercwithamouth: yeah in the examples they use a lot of extra digits..seemed random

1:42 creese: Seems like I have to rebuild when I change the config

1:42 when I change the file

1:42 nsjph: which config are you referring to?

1:42 creese: I don't want to rebuild

1:42 nsjph: project.clj?

1:43 creese: I have a config file in resources/

1:43 it's an edn

1:43 nsjph: yep

1:44 if you edit your config in your resources, then your previous uberjar would no longer match what a new uberjar would produce

1:45 what i have done in that case, is to have a 'defaults.edn' in resources/, and on first launch of the uberjar, it creates a ~/.myapp/config.edn from resources/defaults.edn

1:45 i also throw in a pretty-print step so it's not too messy when saved to disk

1:46 (spit config-path (with-out-str (pprint @config))) (where @config is from slurping io/resource "defaults.edn")

1:47 that way i can just edit the ~/.myapp/config.edn without rebuilding uberjar

3:18 wei_: what’s the idiomatic way to package node.js modules written in cljs?

4:04 paulswilliamsesq: Morning all

4:04 SagiCZ: morning Sir

4:39 alvin`: Are the sources/namespaces in the env folder in a leiningen project reachable through the lein repl?

4:54 owl-v-: i'm having trouble using lein

4:55 i'm trying to use https://github.com/mikera/core.matrix

4:55 lazylambda: guys, is it possible to flatten a seq in clojure using only for comprehensions? I found that you can do this in python l = [[x, x+1] for x in range(10)], then flatten it using [e for x in l for e in x]

4:55 what's the equivalent in clojure?

5:00 SagiCZ: lazylambda: well i guess you could write some sort of macro.. but whats wrong with nested fors?

5:01 i honestly dont find that python construct readible and similar constructs that are widely used in python are a reason why i stay clear of the language all toghether

5:01 lazylambda: SagiCZ: nothing wrong with nested fors, but I couldn't get the right output

5:02 SagiCZ: well thats another problem.. so what the input and whats the output you want?

5:02 lazylambda: I tried (for [i l] (for [e i] e)), but obviously that's wrong

5:02 SagiCZ: what does the input structure look like?

5:03 lazylambda: (def l (for [i (range 10)] [i (inc i)])

5:03 so l = [[0 1] [1 2] [2 3] [3 4] [4 5] ... [9 10]]

5:03 SagiCZ: ,(for [i (range 10)] [i (inc i)])

5:03 clojurebot: ([0 1] [1 2] [2 3] [3 4] [4 5] ...)

5:04 lazylambda: I want [0 1 1 2 2 3 3 4 4 5 5 ..]

5:04 SagiCZ: ,(apply concat (for [i (range 10)] [i (inc i)]))

5:04 clojurebot: (0 1 1 2 2 ...)

5:04 lazylambda: that's what I thought

5:05 I was wondering if it's possible to using only fors and not concating

5:05 SagiCZ: it might be but i dont know how

5:06 lazylambda: I am not sure if it's possible, but thanks anyway

5:06 SagiCZ: np

5:06 lazylambda: still, the clojure version is much readable

5:06 SagiCZ: thats what i am thinking.. i honestly dont understand the pyhton statement at all

5:07 lazylambda: I am not a fan of python myself, but I just wondered if it was possible to flatten a nested seq in clojure using only fors

5:08 SagiCZ: maybe if you ask this again in couple hours, some experienced users might help you

5:08 TEttinger: ,(for [i (range 10) n [0 1]] (+ i n))

5:08 clojurebot: (0 1 1 2 2 ...)

5:09 TEttinger: only usable in this narrow case but hey

5:09 lazylambda: ^

5:09 SagiCZ: TEttinger: i dont like it

5:09 TEttinger: apply concat is a better solution but this is one for

5:09 SagiCZ: yeah i understand

5:14 lazylambda: TEttinger: thanks, but that only generates the result, it doesn't flatten a given nested seq

5:14 TEttinger: right, so you want a second for loop to flatten an existing one?

5:14 lazylambda: yep

5:15 so if I have ,(for [i (range 10)] [i (inc i)])

5:15 I was trying to flatten that using only fors

5:15 jaen: Hmm am I doing something wrong here that I get "unable to resolve symbol a" - https://gist.github.com/jaen/a1b025093642e1df691b - or do :or and :as not compose in core.match?

5:16 TEttinger: &(let [thing ([0 1] [1 2] [2 3] [3 4] [4 5] [5 6] [6 7] [7 8] [8 9] [9 10])] (for [i thing idx [0 1]] (nth i idx)))

5:16 lazybot: clojure.lang.ArityException: Wrong number of args (9) passed to: PersistentVector

5:17 TEttinger: &(let [thing [[0 1] [1 2] [2 3] [3 4] [4 5] [5 6] [6 7] [7 8] [8 9] [9 10]]] (for [i thing idx [0 1]] (nth i idx)))

5:17 lazybot: ⇒ (0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10)

5:18 TEttinger: &(let [thing [[0 1] [1 2 3 4 5] [2 3 4] [3 4] [4 5] [5 6] [6 7 8] [7 8] [8 9] [9 10]]] (for [i thing idx (range (count i))] (nth i idx)))

5:18 lazybot: ⇒ (0 1 1 2 3 4 5 2 3 4 3 4 4 5 5 6 6 7 8 7 8 8 9 9 10)

5:18 TEttinger: so with that it will handle an arbitray sequence of sequences

5:18 instead of just pairs

5:30 lazylambda: TEttinger: cool, thanks

5:31 TEttinger: lazylambda, it won't handle nesting deeper than one level, or nesting with non-indexed sequences like maos

5:31 Atarian: Dumb question: If I were to implement MVC, Would you seperate it into seperate files with seperate namespaces and then (:require) them in the controller (-main)?

5:31 lazylambda: Crap, what I was looking for was very simple

5:31 (for [x l i x] i)

5:31 TEttinger: oh haha

5:32 lazylambda: yep, I hadn't had any breakfast or coffee yet

5:32 Atarian: Ooh coffee, that sounds like a good idea

5:32 brb

5:35 Dammit, coffee pot all furry :(

5:36 alvin`: asking again about the lein thing... A change in a template I used moved files from src to env. And I'm not exactly sure how to reach those namespaces anymore.

5:46 kris__: Is a keyword in Clojure literally a function or does it just act like a function? I'm thinking of (:a { :a 'a' :b 'b' })

5:46 Empperi: kris__: it is a function

5:47 kris__: @Empperi Thanks :)

5:47 Empperi: kris__: see https://github.com/clojure/clojure/blob/clojure-1.6.0/src/jvm/clojure/lang/Keyword.java

5:47 public class Keyword implements IFn, Comparable, Named, Serializable, IHashEq {

5:48 Keyword class implements IFn, thus it is a function in clojure

5:48 kris__: I know when passed a hash-map it looks itself up in the hash, I wasn't sure if this was a reader/compiler trick.

5:49 Empperi: maps, sets etc are also functions in clojure

5:49 ,({:foo 1} :foo)

5:49 clojurebot: 1

5:49 SagiCZ: kris__: no you can do anything with keyword you would do with a function.. like map it.. juxtapose it.. etc

5:50 kris__: nice, I'm new to functional. So in the case of ({:foo 1} :foo) the hash is a function which takes the argument :foo and looks it up?

5:51 SagiCZ: yes it looks it up in itself

5:51 kris__: Thanks, I will keep reading!

5:53 zot: any ss/component users out there — is there a standard idiom for re-starting 1 service from a depending service, and properly updating the root service map?

5:55 for example, i've got a message stream that needs to be rewound, which requires interrupting the existing message stream (since it doesn't support live rewind), and restarting. i could also wrap the stream in a core.async channel and control this myself, but wondered if i can cleanly update the config, and restart the service, without any nasty side effects

6:09 m00nlight: Can anyone tell me the reason why I get "Generate tmp file failed exit code 132 reason : nil" , it works well under ubuntu, while has the probelm on a centos server

6:42 nsjph: i'd try using strace <your command> to see what is happening just before that failure

7:41 Atarian: I made a 10x10 2D array of Character/TYPE, but when I use (aset myarray 5 5 "*") I get argument type mismatch. aset-char doesn't appear to like 2d arrays either. What am I doing wrong?

7:43 Bronsa: Atarian: "*" is a String not a char

7:44 Atarian: I think I just got it using \A

7:44 is that right? (aset myarray 5 5 \A)

7:44 Bronsa: Atarian: yes

7:44 Atarian: Briiliant thanks Bronsa

8:39 noncom: whodidthis: hi! got any answer on your prolog question yet?

8:52 sveri: cfleming: ping

9:51 justin_smith: m00nlight: is this running in an app container?

9:59 AeroNotix: I have a clojure uberjar with gen-interface calls, when I load that jar into intellij it doesn't see the classes

9:59 strange thing is, it *used* to see them, not sure what may have changed.

9:59 Any ideas?

9:59 the ns which has the gen-interface calls is in the :aot vector of the project

10:00 justin_smith: AeroNotix: if you open the uberjar, do you see the relevant class files?

10:00 AeroNotix: justin_smith: jar tf foo.jar lists the classes, yeah

10:01 justin_smith: so for some reason the classes are in the jar, but are not being found when the jar runs?

10:01 AeroNotix: sounds like it right?

10:03 justin_smith: this sounds like it could be an intellij issue, unless the class files are not in the right place in the jar or some weirdness like that

10:03 AeroNotix: justin_smith: weird thing is, it finds one class from the same package

10:03 but not the others

10:14 justin_smith: any ideas?

10:15 justin_smith: frankly, no. other than like checking for typos for the class or package name, stuff like that

10:15 converting - to _ in the package, etc.

10:17 AeroNotix: justin_smith: I'm looking at the jar contents in intellij and it finds com.foo.package

10:17 but only has one java package from there but it needs three

10:25 justin_smith: wait, you expect more packages, or more classes?

10:25 AeroNotix: classes

10:25 justin_smith: that's what I thought

10:26 AeroNotix: so lets say I generate com.foo.bar.IFooBar

10:26 and com.foo.bar.FooBar

10:26 and some other

10:26 justin_smith: right

10:26 AeroNotix: I can only see one of these classes for some reason

10:26 but they are all inside the jar

10:26 justin_smith: is it specifically the interfaces that intellij is not seeing?

10:26 maybe it shows interfaces differently?

10:26 AeroNotix: no, just some random class it can see

10:26 justin_smith: hmm

10:26 AeroNotix: (seemingly random class)

10:29 justin_smith: i've had this working before but I deleted the target directory and rebuilt the uberjar and now nothing

10:29 justin_smith: that's really weird

10:30 maybe someone like Bronsa or puredanger who knows more about the compiler / bytecode output would be more help

10:30 AeroNotix: awesome, I'll stick around

10:30 justin_smith: as a lark, you could try using a different clojure.core version, couldn't hurt to try

10:30 maybe you hit an obscure bug

10:30 AeroNotix: ok sec

10:30 puredanger: what version are you using?

10:30 some of this stuff changed in the 1.7 alphas

10:31 AeroNotix: [org.clojure/clojure "1.6.0"]

10:31 puredanger: well, you could try 1.7.0-alpha5 - there were changes with gen-interface and classloading

10:31 AeroNotix: oke doke

10:36 does intellij cache jar files?

10:36 puredanger: justin_smith http://i.imgur.com/QKTaALg.png

10:36 I changed the classname and now it still uses the old name

10:37 justin_smith: sounds like intellij is being dummj

10:37 AeroNotix: haha

10:38 arrdem: puredanger: get any interest in that documentation format project?

10:40 puredanger: arrdem: yes, couple

10:40 arrdem: good

10:41 puredanger: AeroNotix: ¯\_(ツ)_/¯

10:41 AeroNotix: puredanger: sup? :(

10:42 puredanger: just no clue why you're seeing that

10:42 AeroNotix: sadness

10:42 arrdem: puredanger: still taking project ideas? we could really use a pygments style formatter in clojure for clojure :P

10:42 `fogus: @arrdem: "documentation format project" ???

10:42 lazybot: `fogus: Oh, absolutely.

10:42 AeroNotix: it looks like intellij is using some old version of the jar or something but searching my disk for other jars turns up nothing

10:43 `fogus: arrdem: "documentation format project" ???

10:43 lazybot: `fogus: Oh, absolutely.

10:43 puredanger: AeroNotix: I think cfleming would have some clue, but I don't

10:43 AeroNotix: ok, thanks

10:43 * arrdem confused

10:43 justin_smith: AeroNotix: you could try temporarily moving your intellij config, IDEs can be weird sometimes

10:43 lazybot: are you a goofball??

10:43 lazybot: justin_smith: Uh, no. Why would you even ask?

10:43 AeroNotix: justin_smith: I don't usually use one but I'm writing something for people who do use one to use my library, so I want to test.

10:44 puredanger: `fogus: see http://dev.clojure.org/display/community/Project+Ideas

10:44 `fogus: thanks!

10:44 justin_smith: AeroNotix: in that case, maybe just delete your intellij config then :P

10:45 puredanger: `fogus: in the time-honored tradition of having too many things I want to do, I am trying to have someone else do them for me :)

10:45 AeroNotix: justin_smith: looking where it is now :)

10:45 `fogus: I subscribe to this philosophy

10:46 justin_smith: `fogus: nice to see you around here btw, thanks for the cool books and blog posts and stuff, I learned a lot from you

10:46 `fogus: justin_smith: I'd love to be around more, but the real-world keeps getting in the way... as it does.

10:47 justin_smith: and thank you. :)

10:49 lazylambda: fogus: I bought your joy of clojure a few months ago. The book is super tits.

10:50 puredanger: lazylambda: I don't think that language is appropriate here

10:51 lazylambda: puredanger: oops, my apologies. Sometimes I forget I am not social media.

10:55 delaney: hi, is there a way to disable repl support at the distribution/uberjar build step?

10:56 justin_smith: delaney: as in, not launching an nrepl listener, or as in making it impossible to run a repl from the uberjar?

10:56 the latter, probably not, because clojure.main is a repl

10:57 delaney: yeah, bascially i don't see a way to make a 'secure' jar where it 'just runs'

10:57 not allowing modification

10:58 justin_smith: delaney: the jvm doesn't even make such a thing possible, some other program can always load your jar and use the classes as it likes

10:58 delaney: and in the clojure case, clojure does not have a way to run without the compiler present

10:59 delaney: if you switch to clojurescript, it will compile to js that does not include the compiler

10:59 but it's not like js is a "secure runtime" or anything

10:59 delaney: well i thought maybe it could munges the namespace/names and then only see from inside the package

11:00 justin_smith: there are tools like that for java source, but munging can always be reverse engineered

11:00 because all it does is hide names

11:01 delaney: justin_smith: you i know, just trying to answer a few questions at work. perceptions of 'secure'

11:01 justin_smith: delaney: there are bytecode obfuscators, and you could try to aot your whole project and use one, but I have no idea how well they would work for clojure

11:01 delaney: fair enough

11:01 delaney: yeah, I lost a client because they started up a "static analysis" policy and I couldn't offer anything like that for clojure

11:02 so I know where you're coming from

11:03 agarman: justin_smith: what kind of static analysis policy?

11:03 justin_smith: delaney: the problem with using a bytecode obfuscator with clojure is anything that tries to work at runtime would need to know about the obfuscated names, or would break

11:03 agarman: they required static analysis of all code for security issues

11:04 nsjph: you need to decrypt it to run it

11:04 * nsjph remembers the days of hardware dongles

11:04 justin_smith: nsjph: well, if the obfuscator is obfuscating a full java program that does not use reflection, it can make sure nothing breaks, but clojure does weird stuff at runtime that normal java code would not

11:05 nsjph: are languages that are garbage-collector-backed suitable for runtime obfuscation?

11:05 agarman: justin_smith: I've yet to see a production Java application that doesn't use reflection

11:06 justin_smith: nsjph: sure, as long as it's a whole-program transform that keeps everything consistent

11:06 delaney: given the 'code as data' paradims probably could have a public key encryption of your code, decrypting/run at startup

11:06 justin_smith: haha

11:06 that likely is an option

11:07 replace require with require-encrypted

11:07 the rest of the language can stay as is I guess?

11:07 delaney: coming from C# clojure is a very odd duck. i have most everything clojure has, but seems like clojure forces better behavior

11:08 justin_smith: yeah, (require-ecc "pass" 'foo.bar)

11:08 tbaldridge: delaney: a lot of it is about defaults as well. F# and C# are almost the same except F# defaults to immutability, C# to mutability, same sort of stuff for C# vs Clojure

11:09 agarman: F# has records

11:09 object expressions

11:09 justin_smith: I think a lot of language design is what you make easy, and what you make difficult

11:09 delaney: yeah, i mean the core concepts of functional style make sense, but the persistent defaults make way more sense in use. cause functional style in C# does lead to tons of memory usage if you use the defaults

11:09 justin_smith: or you have some languages (perl) that try to make *everything* easy, and some (fill in the blank) that want everything to be hard

11:10 tbaldridge: delaney: "tons of memory usage", moreso that Clojure or F#?

11:10 delaney: well clojure's syntax is easy, its 'real' syntax though is in how you call things like list comprehsions, which is not super clear (compared to python for example)

11:10 tbaldridge: *more so than

11:11 agarman: delaney: using functional style objects doesn't increase memory usage, it just increases GC churn

11:11 delaney: yeah, from my work i've seen java is faster, but C# usings like half the memory for same problems. well i meant larger footprints, more copying, more GC

11:12 agarman: delaney: functional collections usually reduce memory size because it eliminates need for defensive copying

11:12 delaney: not long term memory

11:12 in game dev you tend to have more component/entity based systems so the need for defensive copies goes down

11:12 its like a mini-actor system

11:13 but again, the languages don't make you go down that route

11:14 justin_smith: delaney: nothing stops you from using arrays and java.util.HashMap for everything in clojure, it's just a lot less convenient :)

11:15 delaney: justin_smith: well yeah i see that

11:15 AeroNotix: the fact that you can use unbounded mutability when necessary is a huge win imho

11:15 a lot of functional languages don't allow for this

11:16 delaney: yeah, its one reason clojure seems worth learning

11:17 one thing i wish it had out of the box is a way to serialize say 2 maps to edn. load back and do a diff/merge so they share the same memory again.

11:18 like a way to serialize the actual backing stores of map/list/etc

11:18 justin_smith: well, a list doesn't really have a backing store, it's a naive linked list

11:18 vector, on the other hand

11:21 delaney: cause for games, the undo/reverse time stuff works great, but if you want to store that to disk... it becomes huge and loading back loses the persitent connections

11:22 AeroNotix: justin_smith: after deleting my intellij config, I couldn't start intellij (lol) and so I tried to re-install, wouldn't start. Then I tried to downgrade and now it doesn't find Java itself, but now it finds my new classes!

11:22 phew-- is using IDEs really this painful?

11:22 justin_smith: AeroNotix: rofl

11:23 delaney: i couldn't get cursive to work with intelij 14, got frustrated and tried CC, worked great.

11:23 clojurebot: Gabh mo leithscéal?

11:29 eric_normand: delaney: Im not positive, but could a custom fressian optimizer work?

11:33 zot: is there a way in midje to declare a test that *doesn't* run by default, but can be enabled with one of the lein midje pattern expressions?

11:36 justin_smith: eric_normand: yeah, that's probably a good lead

11:38 delaney: eric_normand: yeah, this looks like it addresses your concern https://github.com/Datomic/fressian/wiki/Caching

11:38 if it works as advertised

11:38 eric_normand: It seems like an important piece of the "tree in an atom" approach

11:44 AeroNotix: looks like intellij stupidly caches some jars you set somewhere

11:44 but I can't find where

11:47 ah found it

12:27 creese: I want to load config from the classpath for an uberjar. Can someone tell me what is wrong with this?

12:27 java -cp /etc/myapp -jar /opt/myapp/target/uberjar/myapp-0.1.0-SNAPSHOT-standalone.jar

12:28 justin_smith: creese: I don't typically use -cp and -jar in one invocation, though it may in fact work

12:28 creese: how would you do it?

12:28 I want it to look in /etc/myapp for a file called "config.edn"

12:29 justin_smith: java -cp /etc/myapp:/opt/myapp/target/uberjar/myapp-0.1.0-SNAPSHOT-standalone.jar clojure.main -m my.ns

12:29 creese: what is the mean of the last part of that invocation?

12:29 meaning

12:29 justin_smith: you specify clojure.main as the class to run (clojure.main/-main)

12:30 then "-m" "my.ns" are the args that clojure.main gets

12:30 and clojure knows it should load that ns, and invoke it's -main

12:30 creese: if you put thin your project.clj, can you leave it off?

12:30 that

12:31 justin_smith: if you aot compiled your main class, you may be able to specify that instead of clojure.main

12:31 but the clojure.main approach is more flexible

12:31 hiredman: you cannot use -cp and -jar together

12:31 justin_smith: that's what I though

12:31 t

12:31 hiredman: if you set one jave ignores the other

12:31 (and doesn't complain)

13:11 AeroNotix: grr, my project compiles on archlinux with "Leiningen 2.5.0 on Java 1.7.0_75 OpenJDK 64-Bit Server VM" but not Ubuntu with the same

13:12 complains that some gen-class'd classes aren't available

13:12 but then I look into the target directory and they are

13:21 everything is the same it seems in my project, lein, java{,c} version both match. Anything else that it could be?

13:28 gfredericks: ,(Object.)

13:28 clojurebot: #<Object java.lang.Object@3ce754f3>

13:28 justin_smith: (Overruled.)

13:31 creese: justin_smith: thanks for earlier, it's working now

13:31 AeroNotix: doing it with `lein repl` works and I can import the classes

13:32 justin_smith: creese: cool

13:33 AeroNotix: but on this ubuntu box (and some of my other colleagues mac boxes) it complains it can't find a class which is clearly already compiled and in the tree

13:39 * AeroNotix scratches head

13:43 hiredman: ,(Object.)

13:43 clojurebot: #object[java.lang.Object "java.lang.Object@5bd76887"]

13:43 hiredman: object object object

13:45 justin_smith: ,(read-string (str (Object.)))

13:45 clojurebot: java.lang.Object

13:45 justin_smith: interesting...

13:46 ,(str (Object.))

13:46 clojurebot: "java.lang.Object@cd35cb2"

13:46 justin_smith: ,(read-string (pr-str (Object.)))

13:46 clojurebot: #error{:cause "No reader function for tag object", :via [{:type java.lang.RuntimeException, :message "No reader function for tag object", :at [clojure.lang.LispReader$CtorReader readTagged "LispReader.java" 1180]}], :trace [[clojure.lang.LispReader$CtorReader readTagged "LispReader.java" 1180] [clojure.lang.LispReader$CtorReader invoke "LispReader.java" 1164] [clojure.lang.LispReader$DispatchReade...

13:48 hiredman: delightful

13:48 ane: is there a shorter way to do fn [m f] (f a)

13:49 justin_smith: ane: #(%2 a)

13:49 ane: oh, oops, (f m)

13:49 so #(%2 51)

13:49 %1

13:49 justin_smith: yeah

13:50 ane: i'm folding over a list of functions

13:50 justin_smith: ((apply comp fns) initial)

13:50 err, maybe you want to reverse fns first though :)

13:51 ane: well, order doesn't matter, as they are essentially updating a map, but each on a different key

13:51 i guess i could just map fn map and then merge everything

13:51 justin_smith: yeah, in that case apply comp may be more straightforward than reduce with #(%2 %1)

13:52 apply comp is simpler than a map + merge too (as well as being less work done to generate the result)

13:55 ane: yeah, it would look silly. thanks

14:03 gfredericks: ,(str (Object.))

14:03 clojurebot: "java.lang.Object@506cff4b"

14:03 gfredericks: oooh right

14:03 so is it easier/harder for a repl user to distinguish a thrown exception from a returned one?

14:04 rich's commit didn't seem to touch the repl so I'm not sure, especially since I don't really know how you currently do that

14:05 hiredman: gfredericks: the repl since a few releases back just prints the classname and the message of exceptions

14:05 it doesn't prn them, or print a stackstrace

14:06 clojurebot does pr the exception

14:06 gfredericks: okay so you distinguish because thrown exceptions give unreadable output

14:06 while returned exceptions give you the #error {...}

14:06 hiredman: (not printing the stacktrace in the repl is terrible)

14:07 gfredericks: yeah I've seen that confuse so many people

14:07 hiredman: (you all did this with your complaining about clojure stacktraces)

14:07 gfredericks: pretty much anything you do with exceptions will make somebody mad

14:07 hiredman: (I will never forgive you)

14:07 gfredericks: you all |did| this with your complaining about clojure stacktraces

14:07 ~you all |did| this with your complaining about clojure stacktraces

14:07 clojurebot: c'est bon!

14:07 gfredericks: ~I |will never forgive| you

14:08 clojurebot: Ack. Ack.

14:09 hiredman: ztellman and cemerick were tweeting about fsm and ztellman's automat library yesterday, and now I really want to rewrite clojurebot to run a little core.async machine per user

14:10 each user would effectively have their own possibly stateful session

14:10 gfredericks: does "user" include channels?

14:10 hiredman: no

14:10 every user in a channel

14:12 so if you and I were evaluating stuff, it would likely be evaluated in the same sandbox, but if there was some complicated stateful factoid command stuff like, that would be independent

14:13 I am thinking commands for editing factoids, or just walking through a listing or whatever

14:31 sveri: justin_smith: don't know if you remember my problem from last weekend, I had some time today to do it right, this is the recursive part now: (reduce (fn [a b] (conj a (create-single-node b (create-list-of-converted-nodes (:children b))))) [:ul] fs) much much easier than I thought it would be, thanks for hinting me to do it right :-)

14:32 justin_smith: sveri: np, glad you figured out the right way to do it

14:38 AeroNotix: anyone got any ideas why I can't compile on ubuntu when the versions are the exact same as my archlinux box?

14:38 scroll back has more details.

14:38 Raynes: I can't scroll back that far

14:38 justin_smith: AeroNotix: did you use lein install for any of your deps? Just a random thought.

14:39 AeroNotix: hmm, don't think so

14:39 Raynes: I'd blow away the local maven repo anyways.

14:39 Just for giggles

14:39 AeroNotix: :(

14:39 ok

14:39 justin_smith: instead of blow-away you can just temporarily move it

14:39 Raynes: It'll be okay, man.

14:39 justin_smith: and then put it back later if you sort things out

14:39 Raynes: I suppose

14:39 There isn't a ton of risk in blowing it away though

14:40 If you can't get back the way you were before automatically, probably best you realize now.

14:43 AeroNotix: same difference

14:43 it's complaining it cannot find a class which is part of gen-class/gen-interface

14:43 on one box, this works from a clean .m2/repository and blown target

14:44 the other it does not and complains about one of the generated classes being missing

14:44 all versions match 1:1

15:02 daniel___: compojure started serving a load of random nonsense at / https://gist.githubusercontent.com/danielstockton/cbd13a38308f2cf6eb88/raw/d9c6c1f2ed97078d8a0e3433371a1a1e4888576a/gistfile1.txt

15:02 i have no idea where this html is coming from

15:03 {blake}: Clojurescript?

15:03 daniel___: anyone had similar problems? i have a (route/resources "/") route and later a (GET "/*" (page)) catch-all to serve an index.html under resources/

15:03 if i visit /dfasdsads (for example), it serves the real index.html page

15:04 {blake}: yes, trying to serve a cljs app

15:04 something is generating this html and i have no idea what

15:04 {blake}: daniel___: Those look like includes needed for Clojurescript, is all.

15:04 Did it start suddenly?

15:05 daniel___: yep, seemingly randomly

15:05 {blake}: Did you possibly upgrade your Clojurescript?

15:05 daniel___: i can't pinpoint a particular change, i didnt upgrade at the moment it switched but i was playing with lein clean and clean-targets

15:06 so it may have removed some old files

15:06 im thinking if it was a cljs upgrade, someone else would have had the same issue

15:06 {blake}: daniel___: Yeah, probably. I'm just noticing all that "random nonsense" are includes for google closure files.

15:07 daniel___: So it seems to me that something in your toolchain thinks you need those on your pages.

15:07 daniel___: {blake}: if i had to guess, i'd say it was something figwheel related

15:07 {blake}: Oh! Did you try running without figwheel, then?

15:12 daniel___: i tried to skip it, didnt seem to make a difference, im not sure if i removed everything necessary

15:12 anyway, don't worry, i'll work it out eventually

15:12 just thought it might be familiar to someone

15:13 {blake}: daniel___: Good luck. Nah, it just looks like some of the stuff that cljs auto-loads to me.

15:15 dnolen: daniel___: this is how Google Closure has always worked, it writes script tags to the document on demand when in dev mode. Including a browser REPL would cause all those deps to get loaded onto the page.

15:15 daniel___: if you haven't gone through the new ClojureScript quick start now is a good time.

15:17 daniel___: dnolen: trouble is, i don't know where this html is coming from, seems to be something in my toolchain

15:17 its not the index.html im trying to serve

15:17 dnolen: daniel___: are you saying that's the actual response from the server?

15:18 if so I don't really see how that's possible

15:18 but if you inspecting the DOM and it looks like that, then someone is loading browser REPL

15:19 daniel___: no but this is https://gist.github.com/danielstockton/cbd13a38308f2cf6eb88

15:19 i've tried grepping my project for secretary.js, it's nowhere

15:20 all the other closure stuff seems to be loaded by the goog.require secretary.core

15:20 dnolen: daniel___: but what are you using? Chestnut?

15:20 i.e. something that implicitly loads secretary

15:20 daniel___: yeah, tried to copy it

15:20 it does?

15:21 AeroNotix: daniel___: show project.clj

15:21 daniel___: its an older project, generated from chestnut a long time ago

15:21 and i've tried to keep it up to date

15:21 dnolen: daniel___: maybe, I don't know I haven't tried Chestnut in a long while

15:22 daniel___: added my project.clj AeroNotix https://gist.github.com/danielstockton/cbd13a38308f2cf6eb88

15:23 AeroNotix: daniel___: secretary is in the dependencies

15:24 daniel___: yep, im using it in my client side app

15:24 AeroNotix: so you're using it..

15:24 daniel___: but before it was just doing a goog.require("app")

15:24 i don't know where the secretary stuff crept into the server response

15:25 i strongly suspect figwheel or something else is loading its own routes somewhere

15:26 ill study the latest chestnut output and see if anything seems off

15:34 i noticed there was a mismatch in figwheel and figwheel-sidecar versions

15:34 made them the same, now i get this curious error on lein run https://gist.github.com/danielstockton/dff66055ed47f955e451

15:35 anyway, more and more convinced figwheel is the problem

15:36 oh well, my fault for using versions so close to the edge

15:39 dnolen: daniel___: I didn't any in figwheel related to secretary but I may have missed it

15:39 s/any/see anything

15:46 om``: is there a way to change the type hint of a dynamic var from another ns with bindings/redefs?

15:48 daniel___: not to worry dnolen, thanks

15:48 om``: i am trying to rebind clojure.data.generators/*rnd* to org.apache.commons.math3.random.MersenneTwister

15:48 daniel___: its pretty strange but ill work it out

15:54 AeroNotix: om: why do you need to change the type hint?

15:54 om: if you really need you could subclass it

15:55 gfredericks: om: yeah I don't think there should be any need to change the typehint for that kind of use case

15:56 om: AeroNotix: because if I do a binding on gen/*rnd* I get a cannot be cast to java.util.Random

15:56 gfredericks: if MersenneTwister is not a Random you probably can't use it at all; type hinting won't help

15:57 I don't know the details of data.generators enough to say for sure

15:57 AeroNotix: om: subclass it then

15:57 gfredericks: om: are you having issues with the default RNG that prompted you to try this?

15:58 om: gfredericks: I see what you mean, but the point is that org.apache.commons.math3.random.RandomGenerator copies the java.util.Random interface

15:58 all methods invocation are the same

15:58 AeroNotix: om: the same interface but this is not expressed in code

15:58 it doesn't subclass or implement any java interfaces

15:58 so in the type system, it isn't a java.util.Random

15:59 gfredericks: om: you'd have to recompile data.generators to take advantage of coincidental names

15:59 om: AeroNotix: sure it doesn't ; but the methods are identical .nextInt, .nextDouble etc

15:59 AeroNotix: om: doesn't matter

15:59 gfredericks: and would have to modify any other ^Random type hints throughout the data.generators code

15:59 AeroNotix: those are just names

16:00 gfredericks: on the jvm a method name includes the type it's defined on

16:00 justin_smith: om: the jvm does not do duck typing

16:00 AeroNotix: om: first: why do you need this different randomness source?

16:00 om: so in fact, at the moment, I simply rewrote most of data.generators, with just no ^Random type hint in front of *rnd* and it works

16:00 justin_smith: om: why not reify Random with calls to youre preferred generator?

16:01 gfredericks: that can work if there is no ^Random anywhere else in that code

16:01 om: justin_smith: oh, good idea

16:01 AeroNotix: this is what I meant with subclass :(

16:01 om: gfrederiks: exactly

16:01 gfredericks: justin_smith: om: I think you have to use proxy instead of reify

16:01 Random is a class, not an interface

16:01 justin_smith: AeroNotix: I thought I was defending your point :)

16:01 AeroNotix: justin_smith: I know I know

16:02 om: AeroNotix: I missed that point of yours, sorry

16:02 AeroNotix: I should've just made it clearer with proper pointers to reify/proxy

16:02 om: so it was welcome to say it twice :)

16:02 cool

16:02 justin_smith: gfredericks: weird, so random what is or isn't an interface, huh :)

16:02 gfredericks: om: I'm still interested in what prompted you to switch RNGs

16:03 om: and the reason why I need it, are the other methods in commons.math3.random

16:03 gfredericks: justin_smith: OOP across the generations

16:03 justin_smith: gfredericks: with random mutations

16:03 random

16:03 AeroNotix: the type hint on there seems a bit weird

16:04 gfredericks: om: what sort of methods?

16:04 justin_smith: looks like commons just copypasta'd it into an interface: https://commons.apache.org/proper/commons-math/apidocs/org/apache/commons/math3/random/RandomGenerator.html

16:04 om: gfredericks: distribution related

16:04 no need to reimplement

16:04 gfredericks: om: btw have you tried test.check?

16:05 om: gfredericks: exactly

16:05 gfredericks: huh?

16:05 oh the earlier thing

16:05 om: gfredericks: I do use it; but what do you mean?

16:06 gfredericks: oh wait

16:06 data.generators is not test.generative

16:06 om: is this for testing or something else?

16:06 om: :)

16:06 no this is for statistical modelling

16:06 gfredericks: oh okay neverminds then

16:08 om: I will try with reify (seems more a fit than proxying in this case, isn't it?)

16:08 thanks

16:09 gfredericks: om: no if you use the builtin data.generators you need proxy

16:10 because you have to subclass, since java.util.Random is a class rather than an interface

16:10 if you use a modified data.generators with the commons interface then reify is fine

16:11 okay everybodies here's a good library question

16:11 I wrote this testing helper function in a client library for stubbing the client

16:12 (with-stubbed-foo data-to-stub-with & body)

16:12 then a user accidentally calls it without the first arg: (with-stubbed-foo (do stuff))

16:12 om: gfredericks: oh, right, I see your point, thanks

16:12 gfredericks: since the macro is variadic it doesn't notice, and tries to eval (do stuff) in order to setup the stubbing function

16:13 consequently running the body in an entirely unstubbed environment; confusion ensues

16:13 justin_smith: gfredericks: what about checking if the first arg is associative?

16:13 gfredericks: justin_smith: well it might not be a literal

16:13 and then you still have to eval it to check

16:13 justin_smith: ahh, and the macro can't check that

16:13 right

16:13 gfredericks: so should the lib guard against this mistake? and is the best way by doing a pre-stub to a throwing function?

16:15 justin_smith: gfredericks: an ugly way would be (defmacro with-stubbed-foo [data first-element-of-body & other-elements-of-body] ...)

16:15 gfredericks: doesn't catch mistakes with longer bodies

16:15 justin_smith: right

16:38 AeroNotix: gah i still can't figure this compilation issue out

16:38 I wonder what is different about the environments..

16:40 maybe hiredman would know.

16:40 bhurlow: Hi Clojure people

16:42 Hey everyone, I have a question about how to handle work queues. What tools are you guys using to deal with large "piles" of work that needs to be done concurrently?

16:43 AeroNotix: bhurlow: kind of a big and broad question

16:43 what kinds of work?

16:44 bhurlow: to be more specific, I have an incoming stream of urls that need to be scraped, associated with images, etc. We want to do as much work as possible in a given time but maintain some sort of concurrency limit so our program doesn't explode

16:45 AeroNotix: bhurlow: can you drop work or do you want to make sure you complete all work?

16:45 bhurlow: work must be completed

16:45 can't drop jobs

16:45 AeroNotix: bhurlow: make a channel with a max size and spawn N workers to read off that queue

16:46 bhurlow: @AeroNotix how does that differ from pmap?

16:46 AeroNotix: bhurlow: can you set the number of concurrent works with pmap?

16:47 workers*

16:47 puredanger: no

16:47 AeroNotix: so there you go

16:47 that's why

16:47 danneu: think youre socrates dude?

16:48 bhurlow: <AeroNotix> interesting thanks. how would go about "spawning" works in different threads?

16:48 does core.async spawn those for you?

16:48 AeroNotix: bhurlow: depends if you want to use threads or go blocks

16:48 danneu: wut

16:48 go blocks shouldn't do io

16:49 puredanger: for chunky work, pmap works in some cases

16:49 but otherwise, you can drop down to Java ExecutorService stuff

16:50 or there are a few libraries out there that wrap that up in a Clojure way if you like

16:50 bhurlow: this is mostly io stuff. shelling out work to image cutting processes etc

16:50 puredanger: so you might also look at the pipeline-* fns in core.async for that

16:50 bhurlow: <puredanger> what are some of those wrapping libs?

16:51 puredanger: I think claypoole is one

16:51 https://github.com/TheClimateCorporation/claypoole

16:52 I think there are others, but can't recall them off the top of my head

16:53 bhurlow: many thanks!

16:54 puredanger: whole chapter on this in the I-wish-it-was-out-now Clojure Applied https://pragprog.com/book/vmclojeco/clojure-applied (+ reducers and some other stuff)

16:58 gfredericks: oh hey om:

16:58 did you see https://commons.apache.org/proper/commons-math/apidocs/org/apache/commons/math3/random/RandomAdaptor.html

16:58 so that you don't have to do your own proxy

17:56 {blake}: OK, [B to something clojure.data.csv can parse... I'm turning it into a string with "(apply str (map char my-data))". It could get rather big, though.

17:56 AeroNotix: {blake}: (String. byte-array)

17:58 {blake}: (inc AeroNotix)

17:58 lazybot: ⇒ 9

17:58 {blake}: AeroNotix: Thank ye.

17:58 AeroNotix: nw

17:59 justin_smith: ,(String. (.getBytes (String. (.getBytes "hello"))))

17:59 clojurebot: "hello"

19:04 cfleming: AeroNotix: did you get that problem sorted out?

19:13 AeroNotix: cfleming: no, I posted to the mailing list

19:14 cfleming: basically now my problem is that my code will compile on one machine, but not on another which has the same versions of everything relevant.

19:14 amalloy: (defn id::String->String [s] (String. (.getBytes s)))

19:15 gfredericks: whazzat amalloy?

19:16 amalloy: gfredericks: justin_smith was doing it by hand, i thought he could use a function definition to reuse

19:16 gfredericks: doing what by hand?

19:17 amalloy: gfredericks: (String. (.getBytes (String. (.getBytes "hello"))))

19:17 the code cries out to be DRYed

19:18 gfredericks: I see I was hoping id::String->String was a new static typing lib you had just conceived of

19:18 amalloy: gfredericks: i was just going to call it identity, but it's not really because it's specialized for String

19:18 aperiodic: amalloy: bah, let the compiler DRY it out

19:19 amalloy: so i figured it would be dishonest to use that name, and therefore the only honest name would include a type declaration

19:19 cfleming: AeroNotix: Interesting - so is this related to the problem that IntelliJ couldn't see your classes? Sorry, I haven't had time to read all the chat history

19:21 AeroNotix: cfleming: no that was earlier in the day

19:21 I fixed that by just removing config for intellij

19:21 seems that it likes to cache jars/libraries

19:21 dunno why

19:22 cfleming: AeroNotix: Hmm, that's strange. What can happen is that its indexes get in a funky state from time to time.

19:22 AeroNotix: The first thing to try to rule that out is File->Invalidate Caches and Restart which will rebuild them

19:28 AeroNotix: cfleming: yupp, since learned this option

19:28 thanks

20:11 justin_smith: haha

21:18 gfredericks: just made a lein task for benchmarking a lein task https://github.com/gfredericks/corncob-cigar#benchmark-task

21:23 xemdetia: so how well does itself fare against itself

21:37 gfredericks: um

21:38 * gfredericks runs it on itself

21:39 gfredericks: https://www.refheap.com/98291

21:53 bjarn: hi - possibly a silly question here. is it possible to destructure a ratio into its quotient and remainder?

21:53 gfredericks: nope

21:54 bjarn: didn't think so

21:54 one can dream

21:54 gfredericks: one can

21:54 bjarn: thanks

21:54 gfredericks: np

21:54 justin_smith: hmm, what about methods to get the quotient and remainder?

21:54 ,(bean (/ 7 5))

21:54 bjarn: yeah - i will use those

21:54 clojurebot: {:class clojure.lang.Ratio}

21:55 bjarn: i was thinking more like: (let [[q r] (/ 43870 3600)] (dostuff...))

21:55 justin_smith: (.numerator (/ 7 5))

21:55 ,(.numerator (/ 14 10))

21:55 clojurebot: 7

21:56 justin_smith: ,(.denominator (/ 14 10))

21:56 clojurebot: 5

21:56 justin_smith: cool beans

21:56 gfredericks: ,(let [[q r] ((juxt quot rem) 43870 3600)] (prn [q r]))

21:56 clojurebot: [12 670]\n

21:56 justin_smith: that could be simplified though

21:57 bjarn: ...awesome

21:58 gfredericks: ,(def jqr (juxt quot rem))

21:58 clojurebot: #'sandbox/jqr

21:58 gfredericks: ,(let [[q r] (jqr 43870 3600)] [q r])

21:58 clojurebot: [12 670]

21:58 amalloy: if only ISeqable were a protocol, we could do such disastrous things

21:59 justin_smith: ,(def jnd #(vector (.numerator %) (.denominator %)))

21:59 clojurebot: #'sandbox/jnd

21:59 amalloy: (extend-protocol ISeqable clojure.lang.Ratio (seq [this] (seq ((numerator denominator) this))))

22:00 justin_smith: ,(let [[q r] (jnd 43870 3600)] (prn [q r]))

22:00 clojurebot: #error{:cause "Wrong number of args (2) passed to: sandbox/jnd", :via [{:type clojure.lang.ArityException, :message "Wrong number of args (2) passed to: sandbox/jnd", :at [clojure.lang.AFn throwArity "AFn.java" 429]}], :trace [[clojure.lang.AFn throwArity "AFn.java" 429] [clojure.lang.AFn invoke "AFn.java" 36] [sandbox$eval194 invoke "NO_SOURCE_FILE" -1] [clojure.lang.Compiler eval "Compiler.java"...

22:00 justin_smith: erp

22:00 ,(let [[q r] (jnd (/ 43870 3600))] (prn [q r]))

22:00 clojurebot: [4387 360]\n

22:00 amalloy: oh my. #error must be new in 1.7 as well

22:00 justin_smith: yeah

22:03 cfleming: amalloy: Yeah, #object and #error are new

22:03 justin_smith: ,(Object.)

22:03 clojurebot: #object[java.lang.Object "java.lang.Object@76c6415a"]

22:04 amalloy: i heard about #object

22:04 but i don't follow the mailing list anymore, so i only hear about stuff when it shows up in clojurebot

22:04 cfleming: Is clojurebot built from head? I didn't think these changes had made it into a release yet.

22:04 amalloy: yes, clojurebot is updated early and often

22:04 well. clojurebot itself runs on a quite old version of clojure last i checked

22:05 but the sandbox he uses to run user code is bleeding edge

22:05 cfleming: Ah, I see

22:10 gfredericks: bleeedge

22:11 so this means that pr-str on arbitrary anything will pretty much always give you something entirely readable

22:12 justin_smith: ,(read-string (pr-str (Object.)))

22:12 clojurebot: #error{:cause "No reader function for tag object", :via [{:type java.lang.RuntimeException, :message "No reader function for tag object", :at [clojure.lang.LispReader$CtorReader readTagged "LispReader.java" 1180]}], :trace [[clojure.lang.LispReader$CtorReader readTagged "LispReader.java" 1180] [clojure.lang.LispReader$CtorReader invoke "LispReader.java" 1164] [clojure.lang.LispReader$DispatchReade...

22:12 gfredericks: actually that sort of solves a problem I've had with json serialization from libs

22:12 justin_smith: ,(read-string (str (Object.)))

22:12 clojurebot: java.lang.Object

22:12 justin_smith: gfredericks: it's the opposite

22:12 pr-str of it can't be read, str of it can

22:12 which I think is odd

22:12 gfredericks: justin_smith: you know what I mean

22:12 justin_smith: do I?

22:12 gfredericks: &(str (Object.))

22:12 lazybot: ⇒ "java.lang.Object@52bdc73e"

22:12 gfredericks: ^ that's readable by accident

22:13 justin_smith: I was actually confused

22:13 OK

22:13 gfredericks: I'm not saying it's readable by default

22:13 but if you set up your data readers like a boss

22:13 justin_smith: ahh, right, that could be done

22:13 gfredericks: see my issue is in a logging lib I want to serialize arbitrary objects to json

22:14 and I don't want to accomplish this by globally extending the json lib

22:14 oh wait

22:14 ,+

22:14 clojurebot: #object[clojure.core$_PLUS_ "clojure.core$_PLUS_@40a6d7d4"]

22:14 gfredericks: oh hey look at that

22:15 justin_smith: so it's just like the new syntax for unreadable things then?

22:15 gfredericks: yeah

22:15 but now what I can do in the logging lib

22:15 is round-trip the thing through edn

22:15 and read #object into a special type

22:16 this might still be terrible

22:16 but it's an option

22:16 justin_smith: ~gfredericks

22:16 clojurebot: gfredericks is a menace to bots everywhere

22:16 alvin`: ;q

22:17 oops, disregard

22:17 justin_smith: I thought maybe that was a "licking my nose" emoticon. Not that I know what that would mean.

22:18 gfredericks: in any case I feel like this opens up new options for tooling

22:18 you could do this yourself before by doing print-method on Object and Throwable but libs can't really do that

22:22 cfleming: Yeah, this is intended in conjunction with the new network REPL

22:23 justin_smith: new network repl?

22:23 cfleming: So that I guess pretty much everything will be readable, you just won't get back what you put in

22:23 gfredericks: cfleming: are the two changes orthogonal?

22:23 does the network repl need readability for some reason?

22:24 justin_smith: geez man don't you sit around waiting for clojure-dev emails like the rest of us?

22:24 TEttinger: heh, I'm not sure what this network repl is either

22:24 justin_smith: gfredericks: it appears I am outside of that loop

22:24 haha

22:25 gfredericks: this is big man; rhickey himself even came into irc just to ping cfleming

22:25 cfleming: https://groups.google.com/d/topic/clojure-dev/Dl3Stw5iRVA/discussion

22:25 gfredericks: things that haven't been seen since the days of what was the last big change he came in here to talk about

22:25 justin_smith: gfredericks: oh, I did not see that

22:25 gfredericks: $seen rhickey

22:25 lazybot: rhickey was last seen quittingQuit: rhickey 1 day and 2 hours ago.

22:26 justin_smith: I was here, I guess I did not read that part of my scrollback closely

22:26 gfredericks: cfleming: I thought his point about a separate RPC socket was interesting

22:27 I wonder if that's any more palatable to nrepl-haters

22:28 such a thing would probably just be nrepl-lite eh?

22:29 cfleming: Yeah, I think so

22:30 I'm not sure if by doing that you just get the worst of both worlds

22:30 gfredericks: which really just means removing middleware

22:30 cfleming: Yup

22:30 gfredericks: which in a sense you can do with nrepl already

22:30 by using minimal middleware

22:30 (since everything is middleware)

22:30 cfleming: I'd be interested to know what the load-file problems people have are, but I've never had enough detail to figure that out

22:31 The separate RPC socket is an interesting one, but you still have to be really careful that nothing you call ever writes to out or err, otherwise reading gets screwed up

22:31 You still need something like interruptible-eval

22:32 I suspect that most people, if they use this at all, will end up re-inventing something like that

22:33 gfredericks:

22:33 Oops

22:33 Fat finger

22:33 gfredericks: To answer your earlier question, I think they're mostly orthogonal, but the new reader part makes the RPC REPL connection much easier

22:34 gfredericks: the 2-socket thing?

22:34 cfleming: Well, in general, layering an RPC over a straight REPL socket

22:35 verma: holy shit I feel dumb reading that exchange

22:35 cfleming: It would be the same for a machine-to-machine connection

22:35 Anything where you have to be able to eval a form, and read the result back reliably

22:36 gfredericks: it's always a string at a lower level though, right?

22:36 cfleming: Right.

22:36 gfredericks: I'm not seeing what functionality is missing if you pretend everything returns a string, like nrepl does

22:37 cfleming: Well, in Cursive people like to have their REPL output syntax highlighted. If they return a data structure containing some unreadable form, things blow up when I try to read it so that I can pretty-print it.

22:38 Currently, I deal with that by using Cursive's lexer rather than (read), and the lexer handles #<> forms

22:38 That step wouldn't be required with the new functionality

22:39 gfredericks: okay gotcha

22:39 cfleming: So what gets sent back is a string, but for a lot of things you want to be able to read it on the client side

22:39 gfredericks: I wonder if there are a few stray print-methods that still use #<>

22:39 ,(future)

22:39 clojurebot: #error{:cause "no threads please", :via [{:type java.lang.SecurityException, :message "no threads please", :at [clojurebot.sandbox$enable_security_manager$fn__857 invoke "sandbox.clj" 94]}], :trace [[clojurebot.sandbox$enable_security_manager$fn__857 invoke "sandbox.clj" 94] [clojurebot.sandbox.proxy$java.lang.SecurityManager$Door$f500ea40 checkAccess nil -1] [java.lang.ThreadGroup checkAccess "Th...

22:39 cfleming: Haha

22:39 Ummm

22:39 gfredericks: ,(atom)

22:39 clojurebot: #error{:cause "Wrong number of args (0) passed to: core/atom", :via [{:type clojure.lang.ArityException, :message "Wrong number of args (0) passed to: core/atom", :at [clojure.lang.AFn throwArity "AFn.java" 429]}], :trace [[clojure.lang.AFn throwArity "AFn.java" 429] [clojure.lang.RestFn invoke "RestFn.java" 399] [sandbox$eval51 invoke "NO_SOURCE_FILE" -1] [clojure.lang.Compiler eval "Compiler.jav...

22:39 mfikes: cfleming: The only odd things I ran into for Ambly I/O was async printing (instead of REPL, RPPEPPLPP), and a desire to read a little bit from the user at the very beginning of the REPL life to get input from the user to configure the REPL (which is arguably very odd).

22:39 gfredericks: ,(atom 3)

22:39 clojurebot: #<Atom@51bb91c2: 3>

22:39 cfleming: ,(uuid)

22:40 clojurebot: #error{:cause "Unable to resolve symbol: uuid in this context", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.RuntimeException: Unable to resolve symbol: uuid in this context, compiling:(NO_SOURCE_PATH:0:0)", :at [clojure.lang.Compiler analyze "Compiler.java" 6535]} {:type java.lang.RuntimeException, :message "Unable to resolve symbol: uuid in this context", :at [clojur...

22:40 gfredericks: ^ see the atom up there :)

22:40 ,(java.util.UUID/randomUUID)

22:40 clojurebot: #uuid "a9011b33-fa03-4924-b894-de715a1e31d7"

22:40 gfredericks: ^ no reason for that to do anything different

22:41 cfleming: mfikes: Yeah - if you try to separate the exchange into RPC and I/O, you get all sorts of interleaving issues

22:41 mfikes: I definitely want to fix the need-input thing, but it's tricky from a UI perspective and the bang for the buck has been low since no-one seems to use it

22:41 mfikes: cfleming: Yeah, I read the Group thread. It rasied a lot of interesting ideas IMHO.

22:42 cfleming: gfredericks: Right, duh, UUID was a bad example :)

22:43 mfikes: Definitely. It's a hard problem. I don't think there's one perfect solution, the problem is gracefully supporting a sliding scale from full streaming to full RPC depending on need.

22:43 gfredericks: ,(with-local-vars [x 12] x)

22:43 clojurebot: #<Var: --unnamed-->

22:43 mfikes: cfleming: The only place Ambly needs to read input is the "Choice: 1" line in the example at https://github.com/omcljs/ambly (arguably very strange for a REPL to be doing stuff like that)

22:44 cfleming: By example, I mean this section: https://github.com/omcljs/ambly#repl

22:44 cfleming: mfikes: Yeah, I see

22:45 mfikes: cfleming: IMHO, that is so weird, it shuldn't drive design. But, it _is_ an example, where I wanted to read. In Cursive, you could see that even popping up graphical UI instead. Dunno.

22:45 cfleming: mfikes: It's hard to support in Cursive because IntelliJ editors are "strongly typed". So to get the good functionality when it's being used in the 99.99% case the REPL editor is a Clojure editor. The best solution is probably a popup, right.

22:46 mfikes: Or I might be able to swap out the Swing component briefly and replace it with a text one, but that might be very confusing.

22:46 mfikes: The problem with the popup is that it'll be really annoying if someone ever does implement a text adventure in a REPL

22:46 mfikes: cfleming: I have a workaround. I just configure the REPL to choose the first device. https://github.com/omcljs/ambly/wiki/REPL-in-Cursive

22:47 cfleming: mfikes: I see, nice.

22:47 mfikes: Well, a little ugly, but a nice workaround - sorry about the need for that :)

22:47 mfikes: cfleming: I'm not really asking you to consider popping up graphics for a REPL. That would be even stranger. :) Ambly could perhaps pop up some funky swing dialog of its own if it really needed to.

22:48 cfleming: mfikes: Well, I'm going to have to do something sooner or later, I just haven't figured out what yet

22:48 mfikes: cfleming: All of that stuff isn't "well baked" anyway. It is just an example where I hit a wall where I wanted to read and found that I couldn't when in Cursive.

22:50 cfleming: For a simple example, start up `lein repl` and then evaluate (read-line). Type some text. If you do the same in Cursive, it illustrates the thing I ran into.

22:54 cfleming: FWIW, I really like the Cursive REPL in that you can edit your form in the little editor at the bottom before sending it for evaluation. It is more complex than "R" in "REPL", but it is nice IMHO.

22:56 cfleming: mfikes: Yeah, it's easy to provoke the problem, but I'm actually surprised how few people that's a problem for.

22:57 mfikes: Yeah, I like it too. A few people used to a more traditional REPL find it strange, and it has this sort of limitation, but it's nice for editing Clojure which is what you mostly want to do.

22:57 mfikes: I would say it's an 80/20 win but in practice it's more like a 99.99/0.01 win

22:57 mfikes: cfleming: I even find `rlwrap` unsatisfying :)

22:58 cfleming: mfikes: Hehe, no doubt

22:58 mfikes: I'm actually working right now on REPL refactoring, so hopefully I'll be working on CLJS REPLs within a week or so

22:59 mfikes: cfleming: Cool :) I am now in a position to at least not be speaking utter nonsense on the subject :)

22:59 cfleming: mfikes: I suspect that's been the case for a while :)

22:59 mfikes: Are you planning on going to Clojure/West?

23:00 mfikes: cfleming: It was only half a year ago when you pointed me to Weasel I think :)

23:00 cfleming: No... I should have made it to the one here in D.C. when I had the chance :( ... son's birthday was then.

23:01 cfleming: mfikes: Yeah, I remember you said. Next time perhaps!

23:01 mfikes: cfleming: Like REPLs, conjs loop too :)

23:01 crazydiamond: Hi. What's format is preferable to store huge pieces of data, (that Clojure programs must read) — EDN or JSON, or...?

23:02 I have 83Mb of EDN, and (load-file...) doesn't seem to be able to read it

23:02 cfleming: mfikes: Unfortunately the latency from NZ is high - the Washington trip was quite a beating. Not sure I'll do that one again.

23:02 crazydiamond: got "CompilerException java.lang.OutOfMemoryError: Java heap space"

23:04 mfikes: cfleming: I'll come down to NZ :)

23:04 gfredericks: crazydiamond: have you increased your jvm's heap size?

23:05 crazydiamond: no... what I'm doing just "smells like" wrong way

23:05 cfleming: mfikes: That sounds like an excellent plan. Or you could organise a vacation to coincide with EuroClojure :)

23:05 amalloy: 83MB probably expands into a fairly large object

23:06 crazydiamond: may be JSON is better?

23:06 or XML?

23:06 amalloy: the notation doesn't matter; it's the object you're expandning it into that i speculate could be large

23:07 crazydiamond: yep... so it's wrong way

23:07 i.e. I shouldn't store it like this

23:07 verma: cfleming: +1 for all the awesome cursive work, I've never really used IDEs before but Cursive has been a real treat so far :)

23:07 crazydiamond: but I don't know how I should

23:07 cfleming: crazydiamond: Depending on how you need to process it, XML or JSON would give you better options to treat the data in a streaming way if you can

23:08 crazydiamond: If you need all your data in memory, amalloy is right, it doesn't matter how you store it.

23:08 verma: Thanks! Glad you're enjoying it!

23:08 crazydiamond: yep, my data is like collection, i.e. it's natural language dictionary (stream of about 30000 articles)

23:09 so I need to select few random ones now

23:10 verma: cfleming: very much so :) .. I was a little worried about the CLJS support, but it seems to be no problem at all, looking forward to your CLJS work :)

23:10 CLJS repl*

23:10 cfleming: verma: Yeah, I'm hoping that will be soon (couple of weeks)

23:10 crazydiamond: well thanks for answering all, I probably need just database

23:11 verma: cfleming: nice!

23:11 cfleming: crazydiamond: Do you need to have all your data in memory?

23:12 crazydiamond: Or can you process items one by one?

23:15 crazydiamond: cfleming, one by one - for now, and in next stages - don't know yet. Items are relatively loosely connected with each other

23:17 cfleming: crazydiamond: Check out https://github.com/FasterXML/jackson, which will allow you to perform streaming processing on JSON documents. I don't know if any of the Clojure JSON libs expose that functionality, but you could always use interop.

23:17 crazydiamond: Any of the standard Java streaming XML technologies (STAX, for example) will allow you to do the same.

23:18 crazydiamond: cfleming, thanks!

23:19 In the future I'll probably move to Datomic with proper indexing setup

23:19 cfleming: crazydiamond: That's probably your best solution, yeah

Logging service provided by n01se.net