#clojure logs

2015-08-17

00:00TEttinger,(map inc [1 2 3])
00:00clojurebot(2 3 4)
00:00TEttinger,(map first {:a 1 :b 2 :c 3})
00:00clojurebot(:a :b :c)
00:00TEttinger,(map inc #{1 2 3})
00:00clojurebot(2 4 3)
00:01TEttingerimportant stuff real fast! the set is not in the order it came in for a reason!
00:01slaterrset is a binary tree with just a key I guess
00:02palinkasjustin_smith: the only problem I can see with the sandboxing is that it won't even allow to create namespaces
00:02justin_smithpalinkas: ahh, you should check out which sanbox clojurebot uses
00:02TEttingersets and hash-maps are unordered by default. the order you get stuff out when you convert them to seqs, as map does and as most fns in clojure that work with collections do, is determined by a lot of factors but can't be relied on
00:02TEttingerthat's why there are sorted-map and sorted-set
00:03TEttinger,(map inc (sorted-set 1 2 3))
00:03clojurebot(2 3 4)
00:03TEttinger1 2 3 is already sorted, this actually sorts it again
00:03TEttinger,(map inc (sorted-set 1 2 3 0 -1))
00:03clojurebot(0 1 2 3 4)
00:03slaterrsorted-set = binary tree, set = hash table?
00:05TEttingerfairly close. sorted data structures use a (not sure if binary) tree for the sorting. I'll be perfectly honest, I have never used a hashtable.
00:05TEttingersets ensure uniqueness, not ordering
00:05TEttingerthat's their most important attribute
00:06slaterryeah
00:06TEttingersorted-sets ensure uniqueness and ordering by sorting (you can specify how to sort them too, so not limited to ascending order)
00:06justin_smithhash-sets use a fancy kind of tree optimized for immutable sets that do structural sharing
00:06TEttingerradix 32 hash-array-mapped trie?
00:07TEttinger"now you know why we don't talk about the internals"
00:07justin_smithTEttinger: the gotcha is that you can use an arbitrary sorting key, but if two things sort as equal by your function, then one of them will disappear
00:08TEttingeroccasionally when you see stuff that draws from clojure, but isn't written in clojure, you may find people implementing HAMTs. I think we're all thankful that it's been done for us in clojure.
00:11TEttingergood thing to point out early on: you also have access to mutable, fixed-length, single-typed arrays and java's mutable data types in clojure. typically you only reach for those tools in the toolbox if you need to call java code that expects them, or if you have found a particular spot in your code that drastically needs performance and is a good fit for a mutable algorithm.
00:11TEttingerotherwise, those are not commonly used, because you lose the advantages of immutable code for reasoning about what something will have as its value
00:13TEttinger(also, even in the latter case, there are tools clojure has that let you create a temporarily mutable copy of a clojure data structure, mutate away, and return the mutated copy. don't worry about that stuff yet, but just know that clojure probably has the tools you need)
00:15TEttingermacros can be super useful but also can be hard to write. I think I have written between 2 and 3 macros total, you can go really far without needing them, and when you do need them, justin_smith loves writing small ones :)
00:15justin_smithhaha
00:16justin_smithsmall macros as a service h-something
00:17TEttingerprobably the most important thing you can do to learn clojure is to keep experimenting. it helps to learn more and more of the standard lib, which has a huge amount of useful functions for many, many common needs.
00:17TEttingerhey Olajyd!
00:21palinkas,(ns test)
00:21clojurebotnil
00:22palinkas,(def a "something")
00:22clojurebot#'sandbox/a
00:22justin_smithpalinkas: any two commands are not in the same eval context
00:22justin_smithpalinkas: maybe try using do
00:22justin_smith,(do (ns 'test) (def a "OK"))
00:22clojurebot#error {\n :cause "clojure.lang.PersistentList cannot be cast to clojure.lang.Symbol"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.PersistentList cannot be cast to clojure.lang.Symbol"\n :at [clojure.lang.RT$1 invoke "RT.java" 239]}]\n :trace\n [[clojure.lang.RT$1 invoke "RT.java" 239]\n [sandbox$eval79 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval79 invoke "NO_S...
00:22justin_smithhmm
00:22justin_smith,(do (ns test) (def a "OK"))
00:22clojurebot#'test/a
00:23palinkasand also I guess once the request finished, the sandbox is destroyed
00:24justin_smith,test/a
00:24clojurebot"OK"
00:24justin_smithpalinkas: it has a set lifetime, but it isn't immediately destroyed
00:25palinkasthe question is: can I run two sandbox side-by-side, without conflicting with each other?
00:26justin_smithas far as I know, yes
00:26justin_smithI have not personally tried it though
00:27palinkasany way to try it out?
00:27palinkasI assume that clojurebot here has only a single sandbox
00:28justin_smithpalinkas: I thought that it was using a sandbox lib, but maybe it has one in its source...
00:28palinkashttps://github.com/hiredman/clojurebot
00:28justin_smithpalinkas: here's the subproject https://github.com/hiredman/clojurebot/tree/master/clojurebot-eval
00:29Bronsalazybot uses clojail, clojurebot uses an internal one AFAIK
00:29justin_smithBronsa: yeah, he was looking at clojail but found it too restrictive
00:30slaterrTEttinger appreciate all the pointers
00:32TEttingerno prob
01:16weebzI'm trying to do the following typecast in Clojure, but I can't get it to actually cast
01:16weebz((JavascriptExecutor)driver).executeScript("return $('.cheese')[0]")
01:16weebz(cast JavascriptExecutor driver) returns a FirefoxDriver and not a JavascriptExecutor
01:28hiredmanthat is not how casting works
01:29hiredmancasting (for java, and pretty much everywhere) isn't an operation that changes the value being cast, it just tells the compiler to treat the object differently
01:30hiredmanso for dynamic langues (like clojure) casting doesn't really do anything
01:31hiredmanand, even if does do something, it can't / won't change the dynamic type of an object
02:37luxbockhow do I define a test.check generator that chooses elements from a collection I provide while shrinking so that it chooses the earlier elements more often?
02:37luxbockthe doc of gen/one-of says "Shrinks toward choosing an earlier generator...", but I'm not seeing it
02:37clojurebotHuh?
02:38luxbock(frequencies (gen/sample (gen/one-of [(gen/return 1) (gen/return 2) (gen/return 3)]) 10000)) returns {3 3362, 2 3296, 1 3342}
02:43OlajydHi TEttinger :)
02:45OlajydTEttinger, I’m a junior cloure dev, I hope u’ll be available for more problem solving :)
02:45OlajydHey justin_smith
02:46TEttingerall right, good stuff
02:55nakiyaguys, any of you accessing Facebook graph api with clojure? What is your setup?
03:11nakiya,(doc get)
03:12clojurebot"([map key] [map key not-found]); Returns the value mapped to key, not-found or nil if key not present."
04:01clj123jdbc hive parameterized queries like ["create table as select col1, col2 from table1 where col1=?" "blah"] don't work. Is there any issue with jdbc.clj or hive ?
04:39luxbockI wonder if there's a reason for why assoc-in shouldn't take arbitrary amount of key-vectors and values instead of just one pair
04:43gilliardluxbock: I don't think there is http://dev.clojure.org/jira/browse/CLJ-1771
05:02crocketHow do I create a simple standalone command line application in clojure without leiningen?
05:02crocketI want to use clojure as a replacement of bash.
05:04schmircrocket: better take a look at boot: https://github.com/boot-clj/boot/wiki/Scripts
05:05crocketschmir, Is that it?
05:06luxbockcrocket: http://clojure.org/repl_and_main
05:14crocket"java -cp clojure.jar clojure.main /path/to/myscript.clj"
05:14crocketDoes "java -cp clojure.jar clojure.main /path/to/myscript.clj" execute -main in myscript.clj?
05:15luxbockI think so but I have never tried it
05:15crocketIt executes nothing.
05:17crocketI saved http://dpaste.com/00MPG39 as doit.clj, and "java -cp ~/Apps/clojure-1.7.0.jar clojure.main doit.clj" executes nothing.
05:20TEttingercrocket: -main is only used by lein I think. you would need a toplevel call to (-main) most likely? not sure how it handles additional command line args
05:27d0kyhello i would know how to make https communication i found less-awful-ssl and by readme i have done the first test-ssl done but next part is to create ssl-context and i dont know how to generate to ca.crt ... third certificate of ssl-context ... as you can see here https://github.com/aphyr/less-awful-ssl
05:33crocketTEttinger, I don't know a way
05:33crockethow do I call -main?
05:33crocketAh shit
05:34crocketI guess I have to -main directly in the source code.
05:34crocketI was right.
05:35TEttinger(-main)
05:35TEttingerit's a fn you defined
05:36crocketHow do I get access to the list of arguments?
05:37crocketOh, there is *command-line-args*
05:37crocketNot cool
05:37TEttingergood find
05:37TEttinger-main is a lein thing I think, it sets up the java-like main method
05:38crocketAnyway, it is relatively fast to load a .clj file via clojure.jar
05:38TEttingerthe plain clojure.main method is uh different
05:41crocketIs clojure.java.shell/sh synchronous or asynchronous?
05:45kwladykaah... how it was called... functions which one the same input give always the same output?
05:45kwladykaoh pure functions
05:49crocketboot-clj seems reasonable
05:51crocketTEttinger, (apply -main *command-line-args*)
05:51TEttingerah there you go!
05:52OlajydHI, TEttinger
05:52crocketHow do I iterate over two seqs of the same length?
05:52crocketor multiple seqs
05:52OlajydTEttinger, how do I serach for a particular character in a string?
05:52crocketOh, seqs sounds like "sex".
05:52TEttingerOlajyd: do you want first match?
05:53OlajydYup
05:53oddcully.indexOf
05:53Olajydoh more of a global search in a string
05:53TEttingerthe regex functions like re-find will tell you if the character has been found, but not where it is.
05:53Olajydoh hi odcully :)
05:53TEttinger(inc oddcully)
05:53lazybot⇒ 15
05:54TEttinger,(.indexOf "alphabet" \p)
05:54clojurebot#error {\n :cause "No matching method found: indexOf for class java.lang.String"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "No matching method found: indexOf for class java.lang.String"\n :at [clojure.lang.Reflector invokeMatchingMethod "Reflector.java" 80]}]\n :trace\n [[clojure.lang.Reflector invokeMatchingMethod "Reflector.java" 80]\n [clojure.lang.Reflector invokeInst...
05:54TEttinger,(.indexOf "alphabet" "p")
05:54clojurebot2
05:54TEttingerso that can take a single-letter string or a multiple-letter one
05:54TEttinger,(.indexOf "alphabet" "bet")
05:54clojurebot5
05:57Olajydaite Tettinger, thanks
05:58TEttingerthanks to oddcully too!
05:58crocketIs (map list list-2 list-2) an ok way to zip several sequences?
05:59crocket(map list list-1 list-2 ...)
05:59TEttingeryeah, or mapcat, crocket
05:59crocket,(doc mapcat)
05:59TEttingerdepending on what you want for output
05:59clojurebot"([f] [f & colls]); Returns the result of applying concat to the result of applying map to f and colls. Thus function f should return a collection. Returns a transducer when no collections are provided"
05:59TEttinger,(mapcat list (range 10) (range 20))
05:59clojurebot(0 0 1 1 2 ...)
06:00TEttinger,(mapcat list (range 10) (range 10 20))
06:00crocketThis is not ideal
06:00clojurebot(0 10 1 11 2 ...)
06:00TEttinger,(map list (range 10) (range 10 20))
06:00clojurebot((0 10) (1 11) (2 12) (3 13) (4 14) ...)
06:00crocket,(doc zipmap)
06:00clojurebot"([keys vals]); Returns a map with the keys mapped to the corresponding vals."
06:02TEttinger,(zipmap (range 5) (range 10 15))
06:02clojurebot{0 10, 1 11, 2 12, 3 13, 4 14}
06:03crocketzipmap doesn't scale beyond 2
06:03crocket,(map list [1 2 3] [4 5 6] [7 8 9])
06:03clojurebot((1 4 7) (2 5 8) (3 6 9))
06:03TEttingeryeah
06:03crocket,(doc vector)
06:03clojurebot"([] [a] [a b] [a b c] [a b c d] ...); Creates a new vector containing the args."
06:03crocket,(map vector [1 2 3] [4 5 6] [7 8 9])
06:03clojurebot([1 4 7] [2 5 8] [3 6 9])
06:03TEttinger,(mapv vector [1 2 3] [4 5 6] [7 8 9])
06:03crocket,(map seq [1 2 3] [4 5 6] [7 8 9])
06:03clojurebot[[1 4 7] [2 5 8] [3 6 9]]
06:03clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (3) passed to: core/seq--4116>
06:04TEttingerlist is the fn used to create seqs, oddly -- seq converts a collection to a seq if non-empty, returns nil otherwise
06:10crockethttp://dpaste.com/1R82TJ9 hangs
06:10crockethttp://dpaste.com/1R82TJ9 hangs on line 15.
06:10crocketwhy?
06:10clojurebotbecause that's not how macros work
06:15OlajydTEttinger, say after getting the index of the character in the string, we want to replace that character with another character?
06:15TEttingercrocket: http://clojuredocs.org/clojure.java.shell/sh#example-542692d6c026201cdc3270e7
06:15TEttingerOlajyd: off the top of my head, I don't have an answer, but there is likely something in the Java String API.
06:16OlajydI’m not sure it this is the right approach but this is what I have in mind (assoc "alphabet" (.indexOf "alphabet" “p”) "s")
06:17TEttingerthat sounds like a better fit for regexes.
06:17TEttinger,(clojure.string/replace "alphabet" #"p" "s")
06:17clojurebot"alshabet"
06:18TEttingerthat does all of the occurences though.
06:18TEttinger,(clojure.string/replace "alphabet" #"a" "o")
06:18clojurebot"olphobet"
06:18TEttinger,(.replaceFirst "alphabet" "a" "o")
06:18clojurebot"olphabet"
06:19TEttingerhere's that documentation https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#replaceFirst(java.lang.String,%20java.lang.String)
06:19crocketTEttinger, My code hangs and does nothing.
06:19TEttingercrocket: for 1 minute after when it may have exited?
06:20TEttingerif that's the case, it's related to using futures without calling a specific function to shutdown agents
06:21TEttinger(I also don't know if ffmpeg is getting the args it wants)
06:21TEttingerhttp://clojuredocs.org/clojure.core/future#example-542692c9c026201cdc326a7b
06:22crocketTEttinger, If I execute shell/sh in REPL, it works fine.
06:23TEttingerI wonder if it's getting bad args somehow, like just "-" which some programs interpret as "read from stdin until you get an EOF"
06:25crocketwhat
06:25TEttingerwondering if ffmpeg is, in the program version, receiving the wrong args
06:26crocketAs you can see on https://github.com/clojure/clojure/blob/master/src/clj/clojure/java/shell.clj#L128 , futures are resolved.
06:26TEttingertry printing *command-line-args*
06:26crocket*command-line-args* is not used yet.
06:27TEttingeryou saw the line above that, right?
06:27TEttingerexit-code (.waitFor proc)
06:28crocketSomehow shell/sh just hangs.
06:28TEttingerif ffmpeg isn't returning, it will hang
06:29TEttinger3:30 AM. g'night
06:29crocketok
06:32crocketYou're right
06:32crocketshell/sh hangs for some reason.
06:32crocketffmpeg returns
06:43drwinI have defined a defrecord, and I want to implement my own IPrintWithWriter, how to override defrecord's default one?
06:44crocketTEttinger2, shutdown-agents solves the waiting problem.
06:56crocketoh
06:56crocket^"[Ljava.lang.String;" (into-array cmd)
06:56crocketWhat is this?
06:56crocketA type hinting?
07:10opqdonutcrocket: yes
07:11opqdonut[Ljava.lang.String; is to the jvm what java.lang.String[] is to java, i.e. an array of Strings
07:11crocketHow confusing
07:12opqdonutyeah the syntax could be better
07:28varniegood day.
07:29varnienewbie here. can you help me to figure out why ":require some.lib" doesn't work in case I use it directly in myProgram.clj file and run it through lein repl using (load-file ...)? But it works if I put the whole library name into that file and remove that ":require"? I can provide a sample of code I am talking about.
07:31varnieit gives me "CompilerException java.io.FileNotFoundException: Could not locate ..." error
07:36snowellAre you running the lein repl from the directory that contains the project.clj? That's the way to ensure that dependencies are loaded on the classpath
07:40varniehmm, no, but if I remove that :require it works fine. I provide the full path to the project.clj in (load-file ...)
07:43varniewell, here're two samples, the first one works, the second one does not:
07:43varnie1) http://pastebin.com/xQZtxFnG
07:43varnie2) http://pastebin.com/aJdYku9n
07:44snowellHonestly I've never used (load-file)
07:44varniehuh, okay. ;)
07:46snowellWhat if you try this: http://pastebin.com/daE0VCDv
07:46varniethen I have the same error
07:46snowellTaking :require out of the ns and having it as its own statement
07:46varniewait, I'll rerun lein repl and try again...
07:47varniesame problem.
07:48schmirvarnie: why don't you use require instead of load-file?
07:48snowellI find it hard to believe that specifying the full namespace of the function works but having a (require) doesn't
07:49snowellNot saying I don't believe you :)
07:49varnieschmir, what do you mean?
07:49varniesay, I want to test out my little function, which is written in foo.clj, it (that function) requires some libraries. where should I 'require' them?
07:50varnieI suppose it would be sane to require them in that file.
07:50varniewhy not?
07:50schmirvarnie: using load-file is unusual. normally you define your functions inside a .clj file for a single namespace and load that file with (require my-namespace.foo) instead of load-file
07:50varnieschmir, ah, I didn't know. Thank you.
07:52varnieschmir, can you please show how should my code snippet look then?
07:54schmirhttp://pastebin.com/aJdYku9n looks fine (besides the namespace should have at least 2 components...i.e. it should be something like foo.core)
07:55schmirin your REPL, you can then (require 'foo) and either call foo/print-extension or switch to the namespace with (in-ns 'foo)
07:55schmirvarnie: are you using an IDE?
07:56varnieno, I do not.
07:56varnieFileNotFoundException Could not locate foo__init.class or foo.clj on classpath: clojure.lang.RT.load (RT.java:443)
07:56varnieI should run lein repl in the directory where my clj file is?
07:56schmirwhere your project.clj is
07:56schmirvarnie: did you create a project?
07:56varnieI have only one file, get-extension.clj.
07:56varnieno
07:57schmirok. that explains a lot!
07:57varniethat's exactly what I am trying to understand ;)
07:57varnieis it possible to have a single clj file without project?
07:58schmiryes, you can then use load-file to load the file from the REPL :)
07:58schmirbut you shouldn't do that
07:58varnieokay, then why the second example does not work: http://pastebin.com/aJdYku9n ?
07:58schmir(at least not now, since you said your a beginner)
07:59schmirI think load-file doesn't like the namespace declaration
07:59gjrigvarnie: for sure. The main reason people use fancy projects & build toold (if you ask me) is because the line to run a single .clj file looks ugly. http://stackoverflow.com/questions/7656523/how-can-i-run-a-clj-clojure-file-i-created has good answers
07:59schmirvarnie: you really should set up a project
07:59varnieis there any way I can use "short cut/alias" for that long library name in my second example?
08:00varnieI understand what you guys say, but I find it a bit awkward that I have to create project only for testing some simple function...
08:01schmirvarnie: without the namespace declaration the require looks like (require '[org.apache.commons.io.FilenameUtils :as FileNameUtils])
08:01gjrigHi! I'm writing a program where users will be able to add plugins, which are also written in Clojure. I would like to have some sort of security, so that users can't do bad things like write to disk, run a shell or call arbitrary Java code. Is there some way to ONLY expose functions that have no side effects? Then their plugins can be pure functions, and I can be sure no malicious code is run
08:02varnieschmir, then I have another error: "'Found lib name 'org.apache.commons.io.FilenameUtils' containing period with prefix 'quote'. lib names inside prefix lists must not contain periods"
08:03varnieoh, wait...
08:03oddcullywouln't an import here more appropriate?
08:03oddcullys/here/& be/
08:04varnieno matter what I try, I end up with "CompilerException java.lang.ClassNotFoundException ..."
08:05schmirvarnie: you really want a dedicated project, since you use apache commons
08:05varnieokay, thank you all.
08:05schmirvarnie: boot scripts may be another option: https://github.com/boot-clj/boot/wiki/Scripts
09:34justin_smithvarnie: that's not a namespace, that's a class
09:35varnieyup
09:35justin_smithso you've sorted it out then
09:37justin_smithvarnie: the main reason to use lein or boot (or even maven) is to set up your class path, once your dependencies grow beyond a few items
09:38varniejustin_smith, do you agree that for my purpose I should create a new project?
09:39justin_smithvarnie: it depends, if you only have the one dependency, you might be able to get by without a tool like lein, but the more deps you have, the easier it is to just use lein
09:40varnieI see.
09:40justin_smithjust don't assume that "not having a project" is in any way simpler - it really isn't. It just means you have to do all the classpath and configuration stuff it could do for you, by hand.
09:42varnieyes, that was my initial misunderstanding.
09:50d0kyhello has anybody experience with https ? i try to setup it using less-awful-ssl but do not know to generate ca.crt used in this readme at ssl-context https://github.com/aphyr/less-awful-ssl any help please ?
09:51xemdetiad0ky, the idea of the ca.crt is you getting it signed from someone else
09:51xemdetiaif you don't care about it being valid to your browser just use a self signed cert
09:51xemdetia(in that list of instructions)
09:52tdammersor, the middle ground, create your own CA and install its cert on all the devices you care about, via a trusted out-of-band channel
09:52tdammersthen you can use that CA to sign your own certs
09:52xemdetiaeither way that instruction list is needlessly confusing for a one-off test
09:52d0kybut i did all what was in instructions and worked only test-ssl but ca.cert was not generated
09:53xemdetiaI assume it is from that CA.pl file
09:55d0kyi so should i generate one more certificate as it is in that instructions ? because when i looked here http://immutant.org/documentation/current/apidoc/guide-web.html#h5315 there is also ca.crt but i have no experience with ssl and that library needs 3 files
09:56d0kyespecially function ssl-context not that library
09:59xemdetiad0ky, do you need your certificates to be things you can validate
09:59xemdetiait's easier to just self-sign a cert from the keystore
10:00xemdetiakeytool -genkey -keyalg RSA -alias selfsigned -keystore keystore.jks -storepass password -validity 360 -keysize 2048
10:00xemdetiaand just use the first option
10:00d0kymany thanks :) i will try it
10:00xemdetia(from the immutant docs)
10:12Guest58141\quit
10:58troydmhey guys, can u guys sugest best book to start Clojure with?
10:59timvishertroydm: have you worked through Clojure for the Brave and True?
10:59timvisherso slf4j doesn't implement fatal. this faq implies that they don't think you need it because of the Marker interface. can i use that from clojure.tools.logging? http://www.slf4j.org/faq.html#fatal
11:00troydmtimvisher: no, is this book game oriented?
11:00timvishertroydm: nope. http://www.braveclojure.com/
11:00timvishertroydm: if you want a book on lisp and games, try The Land of Lisp
11:01timvisheryou'll glean much from it despite it not being about clojure directly
11:01troydmtimvisher: I mean is it something like Land of Lisp book
11:01timvishertroydm: oh, then no :)
11:01timvishernot at all
11:01troydmtimvisher: ic, I was somehow confused
11:01troydmtimvisher: I thought I've seen a book that describes Clojure from perspective of programming a game
11:02troydmtimvisher: I guess I was confused because I though that Clojure for the brave and true was that book
11:03troydmtimvisher: ahh, I know why I was confused because "Clojure for the Brave and True" on amazon has a title like a book describing games
11:03troydmI mean title cover
11:05timvishertroydm: so if you make it through CftBaT, i'd probably recommend Programming Clojure and then The Joy of Clojure after that.
11:07troydmtimvisher: I though that if u'll read Joy of Clojure there is no need to read Programming Clojure
11:08timvishertroydm: imo, they're somewhat, but not entirely, orthogonal
11:08timvisherothers may disagree
11:09timvishercertainly i found programming clojure to more approachable, but i think joy of clojure is the best book on the philosophy of clojure there is.
11:09timvisherprogramming clojure is more practical in that sense
11:10troydmtimvisher: from what I see in Clojure for The brave, it's not too detailed, rather it's like beginners book, I was thinking of something more advanced that would describe how to use namespaces, lein and nrepl
11:10tdammersfrankly, I found Clojure For The Brave annoyingly silly with all the hobbit examples and such
11:10justin_smithtroydm: lein and nrepl are just tooling, a book shouldn't even be covering them
11:11justin_smithany more than a C book should have chapters on make and pkgconfig
11:12troydmjustin_smith: yeah I know, but atleast a book about how to structure Clojure project and how to correctly use namespaces and concurrency or atleast something that is close to that
11:12troydmjustin_smith: also tooling is also important aspect of using programming language, and I think it needs some more spotlight
11:12justin_smithtroydm: I think Clojure Programming is the book you want
11:13troydmjustin_smith: ic, okey thanks
11:13justin_smithtroydm: the problem is that tooling moves too fast for books to be a good source - I doubt there's any books on boot yet, and if there are any about lein, I assure you they are out of date already
11:14justin_smithI guess this also reflects where clojure is in its lifecycle
11:16troydmjustin_smith: ic, that's a good point
11:25timvishertroydm: no book will do a good job of covering the tooling
11:25timvisherthe tooling's documentation barely does an adequate job of covering the tooling. :)
11:25timvisherbest place to come for tooling questions is usually here, in all honesty
11:26justin_smithtimvisher: the slack channel is becoming a better and better option I think, more's the pity because I like IRC a lot better and have been too lazy to set up slack via IRC
11:26timvisherjustin_smith: wait, there's an official slack channel now?
11:27justin_smith#clojurians
11:27justin_smithquite active!
11:27timvishersuck :(
11:27timvisherslack is eating all that is beautiful. :)
11:27timvisherhow does one sign up for said channel?
11:27tdammersquestion here: why is the default license for a new lein project the Eclipse Public License? Wouldn't "All Rights Reserved" make more sense?
11:27justin_smithtimvisher: trying to recall how I did it, one moment...
11:28justin_smithtimvisher: get your invite here http://clojurians.net/
11:28justin_smithtdammers: because technomancy is a free-software-hippy
11:29justin_smithtdammers: in all seriousness, I think it's a subtle nudge to consider open sourcing your code (see also how well clojars works out of the box...)
11:29tdammersdon't get me wrong, I'm pretty set on software freedom myself, but I still think this is wrong
11:30tdammersif you default to "All Rights Reserved", the worst that can happen is that you accidentally don't grant people a license
11:30wamaraland more people would complain about that
11:30tdammersno problem, just change the text, push, there you go, open source
11:30tdammers"All Rights Reserved" is the default anyway (legally speaking)
11:31tdammersbut when you default to some other license, then it can (and probably does) happen that you accidentally grant licenses that you don't intend to grant
11:31tdammersand you can't really fix it either once someone has accepted such a license
11:34amalloytdammers: feel free to release a build tool that expresses this opinion, or even just for lein. or add a new lein template
11:34amalloy*fork
11:46tdammersamalloy: "patches welcome"?
11:46coredjustin_smith: thanks for the hint on clojurians
11:46justin_smithcored: np
11:47coredjustin_smith: it wasn't that hard to st it with weechat and now I have everything in the same place
11:47coredthe only downside of using Slack through irc is that you won't get all the magic as with their client
11:47amalloywell, that particular patch is probably not welcome. but technomancy has the right to do whatever he wants with leiningen, and you have the right to wish he would do something else
11:47tdammersamalloy: sure
11:48justin_smithcored: yeah, I use the client, I'm happy to live without the magic (except for eg. at work where I need the magic to get work done)
11:48coredI'm using the irc client for everyting
11:48troydmme too
11:48coredstill can't think of a use case that I really need the magic soo bad
11:48coredI mean, I see annuncements in weechat too
11:49justin_smithcored: my team uses documents uploaded to slack for things like "help me debug this stack trace"
11:49justin_smithor is that something you can use via irc
11:49coredwell
11:49coredyou will see a link and when you follows that link you will get the file
11:50coredit works for me
11:50justin_smithwhat about creating documents?
11:50tdammersmy team mainly communicates using reactiongifs served by a bot
11:50tdammersthat doesn't quite work over IRC
11:50justin_smithtdammers: haha, yeah, good luck making that work on IRC yeah
11:51tdammersit "works", but it's extremely clumsy, because you're basically opening a browser tab for every message
11:51coredjustin_smith: well, I don't do that normally I just sent a private gist
11:51tdammersmight as well use it in the browser in the first place
11:51coredtdammers: what I see is stuffs like ::emoticon::
11:51justin_smithcored: yeah, it's easier to just use the same flow, instead of being the one guy who does something the weird way
11:51coredand then again, I don't care about that too much, but I agree is not the same experience
11:52justin_smithmy team uses the emoji-reactions for things like voting too (like how many people clicked smiley reaction vs. blow-everything-up reaction)
11:52coredjustin_smith: sure, maybe I'll switch if everybody is doing stuffs through Slack entirely. The downside for me is having too many tabs opens for each Slack channel
11:52justin_smithright
11:53justin_smithcored: I'm sure I could make it all work, but in terms of playing nicely with the team, I don't want to be the one guy that forces you to do everything differently
11:53justin_smithhumans have API conventions too :)
11:54coredyes
11:54coredI guess I'm waiting for that moment in which everything is getting done through Slack
11:55coredeven coding itself ;-P which probably will happen at some point
11:55coredpeople love Slack's ui
11:55justin_smith"hey guys, good news! we're using slack instead of git now"
11:55coredhehe
11:56coredyes
11:56coredprobably along those lines
11:56tdammerscored: yeah, no, those are doable, but people trigger the bot's plugins to have it serve reaction gifs
11:57coredoh yes
11:57coredthat's one of the things that I can't do with irc
11:57coredlike sending /commands
11:57oddcullydystopia...
12:14pflanzeHello. How do you turn a list holding 2*n items into a list holding n sublists of 2 items each? (a 1 b 2) -> ((a 1) (b 2)) or ([a 1] [b 2])
12:14justin_smithpflanze: partition, or partition-all
12:15justin_smithdepending on what you want to do with any potential remainder
12:15justin_smith,(partition 2 '(a 1 b 2))
12:15clojurebot((a 1) (b 2))
12:15justin_smith,(partition-all 2 '(a 1 b 2 c))
12:15clojurebot((a 1) (b 2) (c))
12:15justin_smith,(partition 2 '(a 1 b 2 c))
12:15clojurebot((a 1) (b 2))
12:16pflanzeThanks! What about the second case (which it seems is commonly needed for macros)?
12:16justin_smithif you need vectors? you'll likely have to map vec over the result
12:17justin_smith,(map vec (partition 2 '(a 1 b 2 c)))
12:17clojurebot([a 1] [b 2])
12:17pflanzeAlright.
12:17justin_smithyou could also use transducers for this I think
12:17justin_smith,(into [] (comp (partition 2) (map vec)) '(a 1 b 2 c))
12:17clojurebot#error {\n :cause "Wrong number of args (1) passed to: core/partition"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (1) passed to: core/partition"\n :at [clojure.lang.AFn throwArity "AFn.java" 429]}]\n :trace\n [[clojure.lang.AFn throwArity "AFn.java" 429]\n [clojure.lang.AFn invoke "AFn.java" 32]\n [sandbox$eval121 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbo...
12:17justin_smithI guess not
12:18justin_smith,(into [] (comp (partition-all 2) (map vec)) '(a 1 b 2 c))
12:18clojurebot[[a 1] [b 2] [c]]
12:18justin_smithinteresting, partition-all has a transduce but partition does not. Makes sense, I guess.
12:19pflanzeWhy do you think it makes sense?
12:20justin_smithbecause handling the straggling items is the general case, and you can derive the dropping behavior from that. It's still a bit weird I guess.
12:22justin_smithalso somewhat interesting, you can't access the step arg as a transducer
12:22justin_smith,(partition 2 1 [:a 0 :b 1])
12:22clojurebot((:a 0) (0 :b) (:b 1))
12:23pflanzeBTW SRFI-1 from Scheme has "partition" for a different purpose: partition pred list -> [list list]
12:23pflanzePeople can never agree on such fundamentals.
12:24justin_smithpflanze: yeah, we call that split-with
12:24justin_smith(doc split-with)
12:24clojurebot"([pred coll]); Returns a vector of [(take-while pred coll) (drop-while pred coll)]"
12:24amalloyjustin_smith: sure? i'd guess it's more like (juxt filter remove)
12:25pflanzehttp://srfi.schemers.org/srfi-1/srfi-1.html#FilteringPartitioning
12:25pflanzeI think amalloy is right.
12:25justin_smithyeah
12:26justin_smith((map (group-by pred l)) [true false])
12:26justin_smithnot quite
12:26pflanzeAnyway, I'm finding myself needing the (partition 2) case so often, that I'm probably just going to write and name my own :o.
12:26justin_smith,(map (group-by even? (range 20)) [true false])
12:26pflanzeAlso, one that errors out when there is a superfluous item.
12:26clojurebot([0 2 4 6 8 ...] [1 3 5 7 9 ...])
12:27pflanzeNow I just need a name that nobody agrees on.
12:28pflanzePerhaps just list->alist
12:29justin_smithoh man, alists
12:30pflanzeWell, Clojure removes the ambiguity of whether the pairs are dotted ones or not!
12:31pflanzeBut I guess Clojurians just use maps instead?
12:31pflanzeAre maps ordered?
12:32{blake}pflanze: Maps are not ordered, but that is a less meaningful statement than it might be in another language.
12:33pflanzeWhy?
12:33clojurebotWhy is the ram gone is <reply>I blame UTF-16. http://www.tumblr.com/tagged/but-why-is-the-ram-gone
12:41clojerWhat's the best way to include in a Clojure project java files downloaded directly from github, ie. not from Maven?
12:42{blake}pflanze: Because the data is the thing, not the container. I mean, maps aren't sorted but you can sort maps.
12:42{blake}This is sort of the perversity of OO: It teaches you to value the container more than the data.
12:43{blake}(With all due respect to Alan Kay, who had nothing of the sort in mind when he coined the term "object oriented".)
12:43pflanzeWhat does this have to do with containers or OO?
12:44pflanzeSometimes, e.g. argument parsing, it's important whether the same key appears again, and in which order. I want to maintain that.
12:45{blake}pflanze: You asked if a map was ordered. It's not. And it will have no duplicate keys.
12:46pflanzeYes, the duplicate keys really is a step beyond.
12:47pflanzeStill not sure what you meant with the valuing of the container.
12:47{blake}Arguments come in as a vector, I believe, which is ordered.
12:47{blake}pflanze: Sorry, I'm in a "teaching beginners" headspace which also includes a "re-evaluating my own notions" headspace.
12:47{blake}When I started with Clojure, I was positively offended that I could pass in a vector and get back a list.
12:48{blake}Now I blithely flip between list, vector, set and map.
12:48{blake}I basically don't care, until I do.
12:50pflanzeOkay. Well, as a Schemer, I'd agree that Clojure looks like having too many data types, which is more OO philosophy than lisps had. (But then I don't really care either.)
12:50{blake}So, e.g., I start with a list of words in a book. Then I maybe put it into a set to find the number of unique words, or roll back to a map of frequencies of words use. And if I sort my map, I get a list again.
12:52pflanzeOk. Sorting a map into a list is not the same as having a sorted map in the case where you need to add or remove items incrementally, complexity wise.
12:52{blake}Elucidate.
12:52pflanze(Unless Clojure goes crazy OO here and has SortedMap underneath really.)
12:53pflanzeWhat I mean is that as long as a map is a map, you can add and remove items efficiently. Once you've sorted it, you lose that property.
12:54pflanzeUnlike a sorted map implementation which stores the items sorted but efficiently addable/removable.
12:55justin_smithpflanze: we also have sorted-map
12:56pflanzeOkay, fine.
12:56justin_smithpflanze: though I think what you are describing is just a sequence of two element vectors (since you want to preserve ordering and duplicates)
12:56{blake}justin_smith: It's not a data structure, though, right?
12:56justin_smith{blake}: it is a data structure
12:56justin_smith,(type (sorted-map :a 0 :b 1))
12:56clojurebotclojure.lang.PersistentTreeMap
12:58{blake}justin_smith: Oh! Interesting.
13:00{blake},(type (array-map [0 1 2] [3 4 5]))
13:00clojurebotclojure.lang.PersistentArrayMap
13:00justin_smithpflanze: I'd argue that even if clojure's proliferation of data structures is "oo nonsense", it's "oo nonsense" that effectively implements functional ends, since we have structures that can effectively share internal structure rather than doing deep copies on every operation
13:01bcaccclojer: try looking up lein-localrepo
13:02clojerbcacc: Thanks
13:02{blake}These are Java classes specifically created for Clojure.
13:04pflanzejustin_smith, hey, I'm not claiming it's nonsense :). The unusual part for a Lisper/Schemer is really just that they are also used in the language syntax.
13:05pflanzeWell, vec is. Not sure about the others.
13:05justin_smithahh, right
13:05pflanzeAlso, missing dotted lists.
13:05justin_smithpflanze: yeah we have {} for maps, [] for vectors, #{} for sets
13:06justin_smithand in terms of syntax {} is used for metadata
13:06pflanzeOk.
13:06justin_smithtrying to think of a language feature that uses #{} though...
13:06justin_smithoh, {} is also used for function preconditions and postconditions
13:07amalloyi don't really understand the idea of "missing" dotted lists. what do they give you semantically that just using a vector or a list doesn't?
13:07justin_smithamalloy: throwing an error if you try to conj onto it I guess?
13:08justin_smithmaybe not even that
13:08justin_smithmemory is fuzzy - errors for some list operations certainly
13:11pflanzeamalloy, e.g. Scheme uses them for argument parsing: the dotted element slurps up the remaining arguments.
13:11amalloysure, but that's just a syntactic thing, not data structures. (foo [x & xs]) serves just as well there
13:12pflanzeamalloy, this is nicer than having special syntax for it; your code will work with them pretty much transparently.
13:12pflanzeWell, data structures are syntax are data structures.
13:14amalloythat's true, but there are very different priorities for things that happen at runtime vs at compile time
13:14amalloydata structures that perform well matter at runtime, and convenient syntax matters at compile time
13:15pflanzeIt's not about speed, but about convenience/beauty.
13:15pflanzeSince Lisp is about having compile time at run time, this arguably matters.
13:18pflanzeNot even Schemers fully understand it though: the SRFI-1 library has comments about a discussion on this topic, and the decision was taken to ignore dotted lists for this library.
13:18pflanzeWhich is fair in some situations (better error reporting if dotted lists can't happen), but a hindrance in others (processing such syntax).
13:19pflanzeSo I guess over time, the use of dotted lists has been diluted increasingly, not only in Clojure, but already before.
13:19pflanzeI think it's a pity. But whatever.
13:20pflanzeThe only thing I'm thinking is that if you're increasingly moving away from linked lists for syntax, you'll end up with ML/Haskell in the end.
13:21pflanzeWhich is fine, too, of course, but, again, "whatever".
13:21sg2002Hi all. I've been playing around with cider debugger. It seems to be progressing well. And now I have the most obvoius idea ever - to make debug-on-exception work. Since it's so obvious there's probably someone here who already did this. So what would be the easiest way?
13:21wasamasasg2002: you should prod its author, you know
13:22wasamasasg2002: and no, that line of reasoning is faulty
13:23justin_smithsg2002: iirc the debugger only works if you have a separate debugging vm that connects and controls the process. The extra step I guess would be a global exception handler in the debugged vm that invokes some procedure in the debugging one?
13:25expezhow does core.test change the metadata of a namespace?
13:26expezalter-meta! ?
13:29justin_smithexpez: do you mean clojure.test? and how does it alter namespaces? I know it uses metadata on functions to find tests...
13:29{blake}So, if sorted-map gets you speed when dealing with ordered data, what does array-map get you?
13:29justin_smithfaster lookup and insertion
13:29expezjustin_smith: I was just wondering what function to use to mutate metadata in place. alter-meta! seems to do the trick to simulate what core.test does
13:30justin_smithexpez: again, do you mean clojure.test?
13:30expezjustin_smith: yes, sorry
13:31{blake}justin_smith: OK. At what cost?
13:31justin_smithexpez: I think this is it https://github.com/clojure/clojure/blob/master/src/clj/clojure/test.clj#L649
13:32justin_smith{blake}: I am not sure, I guess you could benchmark them? my naive assumption is that since both ordered and unordered maps / sets work, that the unordered ones must be fastest for insertion / removal and perhaps also lookup, but the ordered versions might be faster than repeatedly sorting the contents by hand
13:33{blake}justin_smith: Yeah. They must have some tradeoff or we'd just always use array-map. I notice that Mongo returns array-maps.
13:33justin_smith{blake}: also array-maps are an impl detail - they auto-promote to hash-maps when they have enough items in them
13:33pflanze{blake}, also, trees are O(log n), whereas hash tables are O(1). Although Clojure's hashtables will also have a O(log n) subcomponent due to them using trees to implement arrays.
13:34justin_smithpflanze: yeah, that was my question mark about lookup - though I bet in practice that's the smallest perf difference of the ones present
13:35{blake}Yeah, I thought all was trees, and that's how immutability works. =P
13:37sg2002justin_smith: Since we need the stack frame, just a global exception handler won't work, I was thinking more towards wrapping every function call be it with changes to the reader, or maybe iterating over visible functions and replacing them with a debuggable versions.
13:37pflanze{blake}, there's a paper about the vectors that Clojure uses, it should give the reasoning. Something like "better amortized" than in normal trees I suppose.
13:37justin_smithsg2002: on yeah that's messy
13:38pflanze{blake}, probably trading memory for speed
13:41{blake}pflanze: That'd be my guess, too.
13:46pflanze{blake}, it might also be feasible to use generation counters and mutation and only allocate new tree elements once the existing ones have run out of space, which should be more practical to implement with hashtables than normal trees.
13:46pflanzeI'm sure that paper could be found again, I'm just a bit too lazy.
13:46justin_smithpflanze: hyPiRion 's series of blog posts on clojure's vector impl is great
13:48firevoltdoes anyone have any good resources for learning clojurescript/om?
13:48justin_smithfirevolt: have you checked out "modern cljs" on github?
14:01{blake}firevolt: I don't, but I'd be interested in same.
14:06sdegutisGood news everyone, I upgraded to Clojure 1.7 successfully. Only had to rename our function `update` to `update-attrs`.
14:07sg2002Debug-on-exception got me thinking how awesome it would be if clojure had a reachable generic exception handler hook. For example we have an obscure state-related bug somewhere in our app that happens when calling (fn val-a val-b). In our handler we expand variables to their states, pack the expanded form into exception info and then pass it up.
14:07{blake}sdegutis: I just ignore those messages.
14:08sdegutis{blake}: that's one optino
14:08sdegutis*OPTION
14:08sdegutisOkay reading Datomic changelog now.
14:15sdegutisOnly 565 lines to read.
14:17amalloysg2002: more than ex-info/ex-data?
14:19sg2002amalloy: That's what I meant when I said "exception info".
14:22seangroveHey all, getting this warning re: nrepl stuff, and not understanding why https://www.refheap.com/108381
14:23seangroveI have cider-nrepl 0.9.1 in my project.clj, as well as refactor-nrepl 1.0.5
14:40expezseangrove: usually these deps are added in profiles.clj and you have to add them as plugins, not dependencies.
14:41expezseangrove: so a minimal profiles.clj for cider would be {:user {:plugins [[cider/cider-nrepl "0.9.1"]]}}
14:42expezThere are instructions for boot in the readme too, if that's how you roll
15:08sdegutisCognitect is pretty brave in putting their Datomic changelog out there so plainly like that.
15:08sdegutisLot of bug fixes in there that horrify me.
15:09BronsaI take you never read any other changelog then
15:10sdegutisOnly on common third party Clojure libraries like Compojure etc.
15:11sdegutis... none of which are maintained by highly profitable corporations like Cognitect/Relevance
15:12Bronsahttp://www.postgresql.org/docs/9.4/static/release-9-4-4.html https://dev.mysql.com/doc/relnotes/mysql/5.6/en/news-5-6-26.html https://raw.githubusercontent.com/antirez/redis/3.0/00-RELEASENOTES https://docs.mongodb.org/v3.0/release-notes/2.6-changelog/
15:13Bronsabreaking news: software requires bug fixes
15:13sdegutisBronsa: Those are all free (gratis) open source projects. Huge difference.
15:13sdegutisBronsa: Datomic is financially supported
15:13sdegutisand closed-source
15:13preyaloneHow do I install specific Clojure versions with Leiningen, so that clj is added to $PATH?
15:14Bronsaright, and mysql is developed by volunteers
15:14preyaloneI want to use leiningen like rvm
15:14sdegutispreyalone: Just put the Clojure version as a dependency
15:14Bronsawtf are you talking about sdegutis
15:14sdegutispreyalone: it won't put anything in your $PATH though, you'd still use Clojure via `lein`
15:14preyalonethere's no project, just leiningen and random scripts
15:14sdegutisBronsa: never mind, you can't understand
15:14Bronsawhat has being open source or not have anything to do with bug fixes?
15:14sdegutispreyalone: maybe you're looking for lein-exec?
15:14Bronsasdegutis: fuck off.
15:14sdegutisBronsa: ok
15:15justin_smithpreyalone: that's not what leiningen is intended for - it's a build tool and dependency manager
15:15preyalonethanks all
15:15sdegutisBronsa: I don't mean to insult you. You just aren't understanding what I'm saying, and I suck at explaining what I'm thinking.
15:15hiredmanBronsa: I'd suggest using /ignore
15:15sdegutisBronsa: So there's no use trying to communicate it further.
15:15justin_smithpreyalone: if you know the exact jar you want to use, java -cp clojure-version.jar clojure.main
15:16justin_smithpreyalone: bonus, that will start faster than lein
15:17sdegutisBronsa: sure or you can go hiredman's route and ignore me I guess
15:17sdegutisI've been /ignore'd by hundreds of people on IRC over the past 15 years, who dismiss me as a troll. What's one more?
15:19preyalonei don't always organize my code into well-defined projects. sometimes i just have random shell scripts, and it would be nice to have an equivalent to rvm for quickly switching between clj versions in the current shell / process
15:19justin_smithpreyalone: there's nothing to switch
15:19justin_smithpreyalone: just tell the java command which clojure jar to use
15:19sdegutisThat's the nice thing about Clojure compared to Ruby: it's not a global command, it's just a Java library.
15:20sdegutisThat said, you may run into problems if you need different versions of Java JDK.
15:20sdegutis(I think?)
15:20justin_smithsdegutis: I have like 6 different jvms installed
15:20sdegutisHaha I didn't know you could do that.
15:21justin_smithof course only one is mapped in my default shell to "java"
15:21justin_smithbut they are all there and ready to use
15:22sdegutisMaybe I have more than one also then.
15:23sdegutisI really don't understand the JVM ecosystem at all.
15:24justin_smithsdegutis: ls -l $(which java) may be informative
15:24sdegutisHeh, "/System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/java"
15:25justin_smithsdegutis: and I assume you can guess what may or may not be found under that Versions/ directory in the middle there
15:25sdegutisYeah it's only 1.6 but a bunch of symlinks to 1.6 for things like 1.4, 1.3, 1.5, etc
15:25sdegutisweird
15:26justin_smithif you went and installed 1.7 and 1.8 they would likely end up neighbors
15:27sdegutisWell `lein repl` says I have 1.8 installed right now and it's using it.
15:27preyalonecool, just pushed a simple docker container with leiningen installed. https://github.com/mcandre/docker-leiningen
15:27sdegutispreyalone: Docker scares me.
15:27sdegutisWe just use shell scripts to update stuff.
15:28justin_smithpreyalone: making build machines? ideally your app servers would not have leiningen installed - it's a build tool
15:29preyalonejustin_smith: aye, only jvm and the specific clojure / jar deps would be on the app servers
15:29sdegutisRight use `lein uberjar` instead it's super useful.
15:29justin_smithpreyalone: you don't even need the deps, if you use an uberjar
15:29justin_smithpreyalone: the app is a single jar containing clojure and all needed libs along with the app
15:29sdegutisAnyone know if Clojure 1.8 is going to have those big performance improvements based on optimizing pre-loading of clojure.core vars or whatever that was?
15:30preyaloneneat
15:30sdegutisBecause I'd really enjoy always having a faster start-up Clojure time.
15:33puredangerThe downside of delayed var loading is that every var invocation for the rest of your runtime is 50% slower
15:34sdegutispuredanger: can't it memoize it after the first run, so that it's only the first access?
15:34sdegutisBut obviously if that was a good idea, you guys alread y thought of it.
15:35puredangerHow do you know it's the first time? That implies a condition and conditions have a cost and hurt inlining
15:36puredangerInvokedynamic actually does have a guard condition that does this
15:36sdegutisAh.
15:36sdegutiscool
15:37puredangerI do not know if Rich has any plans to work on this for 1.8
15:37sdegutisok
15:37sdegutisWell if Clojure's dynamic nature inherently requires this slowness and no optimizations can be done, then so be it.
15:38sdegutisIT WORKS! Just upgraded Clojure 1.5.1 -> 1.7, and Datomic 0.8.4218 -> 0.9.5206 ... and it seems to work!!
15:38puredangerWhy wouldn't it? :)
15:39sdegutisHaha good point.
15:48donbonif_in what way is (map inc) different from (partial map inc) ?
15:49sdegutisdonbonif_: I wondered the same thing yesterday. The answer I was given was to read the entire Transducers page on the official website.
15:49sdegutisdonbonif_: I could be misremembering though -- there might be nothing relevant on that page.
15:50hiredman(map inc) returns a function that transforms a reducing function, (partial map inc) returns a function that takes a collection and returns a seq
15:54donbonif_so a transducer never operates on a function directly? only trough transduce/into/etc ?
15:55hiredman,(reduce ((map inc) conj) [] (range 10))
15:55clojurebot[1 2 3 4 5 ...]
15:56justin_smith,(into [] (map inc) (range 10))
15:56clojurebot[1 2 3 4 5 ...]
15:57hiredmanthe terminology around transducers (like reducers before them) is not super clear, because there isn't a clojure.lang.Transducer, just a bunch of stuff delivered as "transudcers"
15:57donbonif_ok, I understand that. I guess I have yet to find somewhere to properly apply transducers
15:58donbonif_to fully use understand and use them
15:58sdegutisYeah I don't fully understand the use-case of them either.
15:58hiredmanso which things in the collection of code that is called "transducers" get the name Transducers isn't obvious, so people refer to different parts of the machine as transducers
15:59hiredmanwhich makes it hard to have an exact conversation about
16:16sdegutisIs there a way to show your dependency graph via Leiningen?
16:17sdegutisAh, lein deps :tree
16:57BinaryResultHi Guys, just in case anyone missed it we are currently hiring remote full-stack clojure developers. See the full description here http://discomelee.com/jobs/ Hope to hear from you!
17:10ed-gIt looks like when I call (ring.util.response.redirect "/") it redirects to the absolute location of the server on localhost:5000, rather than the Location that the client is accessing it by. Is there a way to change that setting?
17:30rhg135is there a constant time way to get a random key from a map, usually I'd use (comp rand-nth keys), but that's O(n).
17:32gfredericksrhg135: I doubt it
17:32rhg135I thought so. sadness
17:33gfredericksrhg135: I'm sure the impl could support such a thing if it wanted to
17:33rhg135I think so too
17:34rhg135I'll keep a pair of vector of keys and a map
17:35rhg135persistent structures mean little wasted memory
17:35rhg135just all the nodes
17:38amalloyrhg135: and how would you efficiently maintain that vector of keys?
17:39gfredericksI'm guessing it's static
17:39amalloywhat, all maps are static? rhg135 is asking for a random key from a map
17:39rhg135amalloy: generally I couldn't. but in this domain the map is not changed
17:40gfredericksI'm guessing based on the fact that that solution was suggested at all :)
17:40amalloyoh, you said "i'll"
17:40amalloyi thought we were talking about how the impl could support such a thing still, and read "i'd"
17:40gfredericksnow all of our reactions make sense
17:41rhg135On a vector rand-nth is O(1), right?
17:43gfredericks,(let [v (vec (range 1000000))] (time (rand-nth v)))
17:44clojurebot#error {\n :cause "Java heap space"\n :via\n [{:type java.lang.OutOfMemoryError\n :message "Java heap space"\n :at [java.lang.Long valueOf "Long.java" 577]}]\n :trace\n [[java.lang.Long valueOf "Long.java" 577]\n [clojure.lang.LongRange reduce "LongRange.java" 233]\n [clojure.lang.PersistentVector create "PersistentVector.java" 65]\n [clojure.lang.LazilyPersistentVector create "LazilyPersis...
17:44gfredericks&(let [v (vec (range 1000000))] (time (rand-nth v)))
17:44lazybot⇒ "Elapsed time: 4.866386 msecs" 828650
17:44gfredericksseems like a lot of milliseconds
17:44gfredericksI'm guess you'll want to write your own rand-nth
17:44gfredericksrand-nthv
17:45rhg135,(source rand-nth)
17:45clojurebotSource not found\n
17:45rhg135meh!
17:45justin_smithhttps://github.com/clojure/clojure/blob/clojure-1.7.0/src/clj/clojure/core.clj#L6938
17:46feijjaWhat is the opposite of map? I have a value (in this case a char), and I want to run it thru every function in a list.
17:46rhg135seems legit
17:46gfredericksfeijja: (map #(% v) fns)
17:47rhg135that's still map
17:47amalloyfeijja: alternatively, you have a list of functions, and you want to run each of them over a value (in this case a char-
17:47sdegutisHow do you work around cyclical dependencies in your own namespaces?
17:47rhg135(map #(% v) ..)
17:47feijjagfredericks: that was simple! Thank you >.>
17:47rhg135require
17:47amalloyas O(1) as anything else on a vector, rhg135
17:48gfredericksamalloy: why did your lazybot take four whooole milliseconds to retrieve an item
17:48sdegutisIs the convention to just require the namespace inside the function call that requires it?
17:48amalloycosmic rays
17:48gfrederickssdegutis: I think most people restructure namespaces
17:48gfredericks&(let [v (vec (range 1000000))] (time (rand-nth v)))
17:48lazybot⇒ "Elapsed time: 4.655652 msecs" 699246
17:49rhg135yes
17:49gfredericksamalloy: two cosmic rays!
17:49sdegutisgfredericks: I'll keep trying that. Been at it for 10 minutes though and not seeing a clear solution.
17:49amalloygfredericks: seriously though rand-nth is as fast as it can be, afaik
17:49rhg135cyclycal deps are usually a warning
17:49amalloy~def rand-nth
17:49gfredericksamalloy: I looked at the impl so I believe you, but 4msecs is pretty weird
17:49gfredericksmy repl did it in 0.05 msecs
17:50gfredericksmaybe lazybot uses Really Slow Vectors
17:50amalloysandboxing? i dunno
17:50gfredericks~mystery
17:50clojurebotmystery is http://p.hagelb.org/mystery.gif
17:50Bronsa&(time 1)
17:50lazybot⇒ "Elapsed time: 4.441412 msecs" 1
17:50gfrederickshaha
17:51gfredericks,(let [t1 (System/nanoTime) t2 (System/nanoTime)] [t1 t2])
17:51rhg135what
17:51clojurebot[20961776023440845 20961776023441278]
17:51gfredericks,(let [t1 (System/nanoTime) t2 (System/nanoTime)] (- t2 t1))
17:51clojurebot473
17:52gfredericksweerd
17:52amalloygfredericks: my guess is, lazybot is doing i/o during that time, because it is saving *out* to put it in a stringwriter
17:52rhg135clojail isn't time sensitive is it?
17:52rhg135or that
17:52sdegutisdb.connect requires db.schema for setup-schema, db.schema requires db.helpers for create-attribute, so db.helpers can't require db.connect for the live-connection
17:52rhg135either way timing things in a sandbox is a bad idea
17:53rhg135db.state ?
17:53justin_smith,(reductions - (repeatedly #(System/nanoTime)))
17:53clojurebot(20961916921858597 -489693 -20961916922987536 -41923833845509226 -62885750768060913 ...)
17:53sdegutisMaybe the schema shouldn't be a gigantic def inside a single file?
17:53sdegutisMaybe each file should add to the schema itself instead.
17:54gfrederickssdegutis: what does create-attribute do?
17:54sdegutisMutability!
17:54rhg135oh dear
17:54sdegutisgfredericks: forget that, a better reason is that db.schema requires tons of files that export database attributes, which use db.helpers to set up those attributes
17:54sdegutisdb attributes are basically like table definitions if this were sql
17:55sdegutisand who wants to hand-write sql?
17:55rhg135me
17:55sdegutisMaybe mutability is the answer?
17:55rhg135no
17:55rhg135it hardly ever is
17:56amalloy&(map (partial apply -) (partition 2 1 (repeatedly 10 #(System/nanoTime))))
17:56lazybot⇒ (-2627774 -2575106 -2567565 -2959637 -2595812 -2377417 -2389713 -2383616 -2446741)
17:56amalloy,(map (partial apply -) (partition 2 1 (repeatedly 10 #(System/nanoTime))))
17:56clojurebot(-98835 -155731 -130121 -60025 -57765 ...)
17:56sdegutisIt seems strange to have the schema namespace require every namespace it needs for building the schema itself.
17:56sdegutisDoesn't it?
17:56amalloyoh i bet i remember
17:56amalloylazybot does really slow sandboxing around interop calls
17:56amalloyand time macroexpands to such a call
17:57rhg135,(map (fn [_] (Thread/currentThread))) (repeat 10 nil))
17:57clojurebot#object[clojure.core$map$fn__4537 0x676641fb "clojure.core$map$fn__4537@676641fb"]
17:57rhg135eh
17:58hiredmansomeone should write an interpreter over tools.analyzer's ast
17:58sdegutis##(map (partial apply -) (partition 2 1 (repeatedly 10 #(System/nanoTime))))
17:58lazybot⇒ (-2151029 -2107115 -6504619 -2099165 -2079598 -2091383 -2063970 -2106716 -2094827)
17:58sdegutis&(map (partial apply -) (partition 2 1 (repeatedly 10 #(System/nanoTime))))
17:58lazybot⇒ (-2183474 -2074782 -2074559 -2051653 -2126746 -2092625 -2066550 -2101132 -2103594)
17:58sdegutiswha
17:59rhg135tej?
18:00gfredericksnow that CLJS is self-hosted does that mean it'd be easy to write a browser repl that can format values as arbitrary html?
18:00sdegutisSchema setup probably shouldn't be responsible for building the schema by searching the entire application.
18:00sdegutisgfredericks: it is??
18:00lazybotsdegutis: Definitely not.
18:00hiredman(because interpreters are generally more reusable and easier to retarget to do other things, like analysis or sandboxing than compilers)
18:00gfrederickssdegutis: sorta
18:00amalloyhiredman: but then we'd have to edit all those blog posts that say "clojures is NOT an interpreted language"
18:01rhg135compiling should be a optimization iirc
18:01sdegutissure it is
18:01hiredmanamalloy: an interpreter can be turned in to a compiler :)
18:02rhg135otoh clojure the language is very much wed to the jvm imo
18:02rhg135thats why clj /= cljs, ever
18:07{blake}Oh, that's interesting. I'd say Clojure uses the JVM for convenience and acceptance, and it'd be just as home...anywhere.
18:11rhg135you're right. it's only slightly.
18:15{blake}We have a large library we're looking to port to CLJS, and it doesn't seem like there's much reliance on the JVM.
18:20sdegutisIs ClojureScript on Node.js a reasonable option for web apps now?
18:23rhg135somewhat
18:24feijjasdegutis: Yes, I'd say so. But why would you do that, rather than JVM Clojure?
18:24rhg135^
18:25sdegutisThe tooling around Node/Io.js feel a little more refined and loved.
18:25rhg135you COULD, but why
18:25sdegutisFor all that sucks about JavaScript, those guys sure do like having good tools.
18:25feijjaVery true. Go ahead :). If you wrap JS libs in CLJS, make sure to share your libs!
18:26slaterr,((1 2 3)(4 5 6))
18:26clojurebot#error {\n :cause "java.lang.Long cannot be cast to clojure.lang.IFn"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.Long cannot be cast to clojure.lang.IFn"\n :at [sandbox$eval25 invokeStatic "NO_SOURCE_FILE" 0]}]\n :trace\n [[sandbox$eval25 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval25 invoke "NO_SOURCE_FILE" -1]\n [clojure.lang.Compiler eval "Compiler.java" 6943]...
18:26slaterrwhy doesn't that work?
18:27rhg135,(1)
18:27clojurebot#error {\n :cause "java.lang.Long cannot be cast to clojure.lang.IFn"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.Long cannot be cast to clojure.lang.IFn"\n :at [sandbox$eval145 invokeStatic "NO_SOURCE_FILE" 0]}]\n :trace\n [[sandbox$eval145 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval145 invoke "NO_SOURCE_FILE" -1]\n [clojure.lang.Compiler eval "Compiler.java" 69...
18:27sdegutisfeijja: will do :)
18:27hiredmana literal list is function application in lisps
18:28feijjasdegutis: just remember that JS is single-threaded, and Clojure is pretty neat when doing concurrent stuff.
18:28hiredmanif (+ 1 2) is appling the + function 1 and 2, and (- 1 2) is appling the - function to 1 and 2, what function is (1 2 3) applying?
18:28rappaportfeijja: like what?
18:29feijjaI'm writing a function that will return a vector of functions. Every call to (fn [] ()) returns a new function, with a new 'id'. How can I use `=` in my unit tests, to compare my list-of-functions-returning function against a predefined list?
18:29feijjaThe function returns [(fn [x] (x)) (fn [y] (y))], and each fn gets a new 'id'
18:29slaterryeah I got confused by the error message. I thought it was related to nested lists, and not missing ' by mistake
18:30slaterrwhich i didn't even notice
18:30feijjarappaport: Clojures core.async has very nice ways to do concurrency - it's available in CLJS too. But in Clojure things will run at the same time in different threads. In CLJS things will never be able to run at the same point in time
18:30rappaportI'm not Rappaport.
18:31amalloyfeijja: you can't really compare functions for anything but pointer equality. if you want to test that you get back a function that behaves a certain way, all you can do is call it with some inputs and verify you get the output you wanted
18:31rhg135on node, you could get threads
18:31rappaportfeijja: Ahhh i see
18:31feijjaamalloy: I see... Was afraid of that.
18:31rappaportOn io.js too I bet
18:31rhg135but thats hacky
18:32rappaportI've been caring less and less whether something's hacky lately as long as it gets the job done long-term
18:32rappaportgranted, most "hacky" things won't, but I think that's just a coincidence
18:32rhg135s/hack/not pre done/
18:32rhg135laziness
18:33rappaportIt's thundering and it smells wonderful outside.
18:34rhg135core.async does have a pluggable executor
18:49rhg135KeySeq is unfortunately linear it seems
19:34domokatoWhat is the clojuresque way of implementing a function that, given an integer, returns an infinite list of integers sorted by distance from that integer. For example, given 5, returns (5 6 4 7 3 8 2 9 1 10 0 11 -1 12 -2 13 ...)?
19:37domokatoi noticed the pattern of +1, -2, +3, -4, +5, etc., in the output, leading me to consider loop/recur, but that's not lazy
19:37amalloy,((fn [x] (map #(+ % x) (rest (mapcat (juxt + -) (range))))) 5)
19:37clojurebot(5 6 4 7 3 ...)
19:37amalloywould be my first effort
19:40domokatojuxt, i was not aware of that function, thx!
19:40domokatoi gtg for the moment, but will read the logs when i get back
19:41domokatoanother wrinkle in my problem is that i want to omit values that are above a specific number or below another specific number
19:41domokatobrb
20:01slaterrhow to do this? "one two three" => "one - two - three"
20:02slaterrwhat do I do after (str/split "one two three" #" ")?
20:02slaterrto insert " - " in between each element and then concat them all together
20:03amalloy&(doc clojure.string/join)
20:03lazybot⇒ "([coll] [separator coll]); Returns a string of all elements in coll, as returned by (seq coll), separated by an optional separator."
20:05rfmindslaterr: I think you should use replace to replace " " with " - "
20:05slaterrthere could be more than one space
20:11rfmindslaterr: (clojure.string/replace "one two three" #" +" "-")
20:15slaterrwhat does putting # in front of string literal do btw? it makes a regex literal?
20:15rfmindyes
20:16rfmind#" +" basically says => one or more space(s)
20:16rhg135\s+
20:17rfmindrhg135: thanks :D
20:18rhg135np
21:03domokatoamalloy: ah, I should be able to just surround your code with filter to get the job done
21:04amalloydomokato: wellllll, kinda. eventually all values will be either above the first number or below the second, and your filter will be discarding all elements
21:04justin_smithyeah, a take-while might be helpful there?
21:05amalloyjustin_smith: it's a little complicated though, if you want to take-while at least one condition is true but filter items where either condition is false
21:07domokatooh, filter causes infinite loop when you try to access later elements, huh
21:08justin_smithdomokato: well it's looking for the next item meeting your predicate
21:08justin_smithdomokato: which is why I suggested take-while
21:08justin_smithbut as amalloy mentions that's still not simple
21:08domokatoah yes
21:10domokatocouldn't i filter between top and bottom and then take top minus bottom?
21:11justin_smithwell, I think you want something that avoids looking for the next element meeting your condition once you know no element can...
21:11justin_smithbecause the filter is too stupid
21:19domokatojustin_smith: doesn't that do it, though? For example, if my bottom is 0, my top is 5, and my x is 3, then it would take 5, resulting in (3 4 2 1 0), and no other elements meet the conditions
21:19justin_smithdomokato: why does filter know that "no other elements meet the conditions
21:19justin_smith"
21:20domokatoit doesn't, but i know, which is why i take only that many
21:20justin_smithahh, which means you can use take or take-while
21:20domokatohm, what would my condition be for take-while, though?
21:22amalloydomokato: you provably can't solve this with a pure predicate to take-while, because it only gets to look at one element at a time and you need to know about two different items at once in order to make the decision to stop
21:23domokatoyeah, that's my understanding
21:39gfredericksluxbock: your test.check question is just gen/elements I think
21:43amalloygfredericks: the difference being that gen/elements grows towards selecting later elements and shrinks towards earlier ones, where gen/one-of doesn't grow with size but does shrink?
21:43gfredericksuhms
21:43amalloyalso gen/one-of requires a generator instead of a value, but he had already made that
21:44gfredericksyeah looks like one-of does not grow through the list
21:44gfredericksbut....
21:44gfredericksneither does elements
21:44gfredericksmaybe I didn't examine the question closely enough, was growth a requirement?
21:45gfredericksreading the question closer it isn't clear if luxbock is intentionally distinguishing growth from shrinking or not
21:45amalloygfredericks: well no, the question was about shrinking, but he wasn't testing shrinking at all
21:45gfredericksright
21:46gfredericksit's never occurred to me to use the word "growth" w.r.t. generators but it makes sense
21:46amalloygfredericks: i just made it up now. do you want a license?
21:46gfredericksyes thanks
21:51gfredericksI think the most surprising misconception I encountered when talking to people at clojure/west about test.check was they assumed growth and shrinking were related
21:51gfredericksonly surprising to me because I had been living in the impl for a while
21:51gfredericksotherwise is a totally reasonable thing to guess
21:56amalloyif you caught me unaware and asked me i would probably say that they are
21:56seangroveCan't seem to figure out how to get clj-time to work with a #inst literal
21:56gfredericksit takes effort
21:57gfrederickslet me think
21:57seangroveI suppose I need to coerce it with from-date
21:57gfredericksto print it?
21:57gfredericksif you want everything to be awesome you have to do both printing and reading
21:57seangroveYeah, just want to print it. Probably should have just looked up the Java methods
21:58gfredericksI'll find how I do it
21:59gfredericksseangrove: https://www.refheap.com/108392
21:59gfredericksnow that I look at it there's probably a less wasteful way to do it
21:59gfredericksbut that at least works
22:00gfredericksthe i prefix there clojure.instant
22:00gfredericksis*
22:36sdegutisWhat's a good way to run swap! only once for a given atom with the given args?
22:36sdegutisI assume something to do with memoize right?
22:39crocketWhy is it faster to load a script via clojure.jar than to load it as part of a leiningen uberjar?
22:39gfrederickssdegutis: I'm pretty sure if you want to do that it means you shouldn't be using an atom; what about agents?
22:40sdegutiscrocket: Leiningen loads the JVM a few times usually.
22:40crocketleiningen uberjar takes 4 seconds to load.
22:40sdegutiscrocket: there are some hacks to avoid it, like trampoline, but they come at their own costs and caveats
22:40sdegutisgfredericks: Both are probably the wrong way actually.
22:40gfrederickssdegutis: it doesn't sound like leiningen is part of the startup here, the question is about running jars
22:40sdegutisgfredericks: I'm trying to load my schema in reverse-dependency order.
22:40crocketsdegutis : Do you know what an uberjar is?
22:40justin_smithcrocket: the time spent by lein uberjar is mostly spent putting all the stuff in a file on disk, or do you mean the time running the resulting jar?
22:41gfrederickssdegutis: why is your schema spread around your project?
22:41crocketloading a simple script
22:41sdegutisgfredericks: Before, I'd have the schema namespace require a declarative var out of every single namespace that declares one, manually, and build the schema that way. It's stupid though.
22:41sdegutisgfredericks: Why? Hmm. Because I want the user attributes in the user.clj file, etc.
22:42sdegutisgfredericks: It allows me to keep things organized a little nicer.
22:42crocketI mean the startup time of a simple script is faster as a standalone than in an uberjar.
22:42justin_smithsdegutis: I use an agent instead of an atom for the top level component in my system, because I don't want retries between start / stop, I want a linear sequence
22:42sdegutisjustin_smith, gfredericks: hmm I'll refresh my memory on what agents are again thanks
22:42gfredericksjustin_smith: I think he's just trying to organize his code in cyclic sorts of ways
22:43justin_smithwell that's just silly
22:43sdegutisBut I think what I probably want is to declare partial schemas like this: (def ^:schema users-attributes [...])
22:43sdegutisAnd then just search my codebase for vars with :schema in the metadata, and use those.
22:43sdegutisjustin_smith, gfredericks: Actually I don't think that's what I'm trying to do.
22:44sdegutisjustin_smith: I'm trying to make it so that my schema is declarative while still being push-onto rather than pull-onto, if that makes sense.
22:44justin_smithsdegutis: can a schema specify that elements need to implement some protocol? if so the schema and protocol definition can be at the very bottom of your dependency stack
22:44sdegutisjustin_smith, gfredericks: In other words, I don't want some centralized location having to require the entire codebase just to build a schema. I'd rather have each part build up anonymously, in a decentralized manner.
22:45sdegutisjustin_smith: Sorry which way is bottom/top again?
22:45justin_smithsdegutis: the bottom is required by others but requires nothing
22:45justin_smiththe top requires others, required by nothing
22:45sdegutisAh.
22:45sdegutisHmm let me think.
22:46justin_smithsdegutis: the idea would be, the schema specifies "things that implement such and such protocol go here", and then users of the schema could go ahead and implement protocol as they like
22:46sdegutisjustin_smith: I'd like my partial-schemas to live in the middle of the stack, i.e. within the context of the code which makes use of it, like users.clj and account.clj etc
22:46tmtwd(defn divisble [x n] (if (= (mod x n) 0) true false)) : how come this function doesn't work?
22:46justin_smithor write code that calls methods of that protocol, using the instances some other code filled in
22:47tmtwduser> (divisible 40 10) => nil
22:47justin_smithsdegutis: middle is a weird place to put your fundamental definitions
22:47amalloytmtwd: as written that function looks fine. are you sure you're not calling some other function?
22:47amalloylike, re-paste the definition and eval it again
22:47sdegutisjustin_smith: they're not quite fundamental... they're a level undernearth the web interface, but a step up above the helper functions which they use
22:48tmtwdoops
22:49sdegutisjustin_smith: the circle I was encountering earlier is that the db.helpers namespace (where db helper functions live) were building the schema and requiring the mid-level namespaces containing schema-attributes, but these mid-level namespaces were requiring the db.helpers namespace for the functions that help build up a schema
22:50justin_smithI think it's weird for schema definitions to use db helpers
22:50sdegutisI suppose they could be mere data that I could translate later.
22:50justin_smithI think a schema should be a shape with no implementation details
22:50sdegutisThat's not a terrible idea.
22:50sdegutisRight now I have like (make-one-attr :foo/bar :db.type/string) turn into a full-fledged Datomic install-attribute line suitable for putting into a transaction.
22:51sdegutisI guess I could turn that into [:make-one-attr :foo/bar :string] and transform that at consume-time.
22:51sdegutisBut that still doesn't quite solve the bigger issue, which is where this is stored, and how to get it into the schma.
22:52sdegutisWhat I want to move away from, is where db.schema requires [features.user :refer [user-attributes]] and so on, x20, since that's backwards.
22:53sdegutisWhat I'm trying to figure out how to move towards, is where features.user tells db.schema that he has some user-attributes to add to what's already there (but only once of course).
22:53sdegutisThe stupid solution I have, and justin_smith you will probably hate this, is (swap! db.schema/schema concat user-attributes)
22:54sdegutisBut it's usable for the most part. Just need to turn it into assoc :user-attributes user-attributes and it fixes the reloading problem.
22:55sdegutisIt's just... mutable. That feels gross.
22:55justin_smith*slightly* more sane would be a promise - at least that can only be realized once
22:55justin_smithbut I've already voted for what I think the real solution is
22:56sdegutisThanks justin_smith for your feedback.
22:56sdegutisI guess in order to maintain my (crazy?) stack order, I have to do it this way.
22:56sdegutisOtherwise I like your idea best.
23:43sdegutis,(->> [] (conj 2) (atom) (def foo))
23:43sdegutis,foo
23:43clojurebot#error {\n :cause "java.lang.Long cannot be cast to clojure.lang.IPersistentCollection"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IPersistentCollection, compiling:(NO_SOURCE_FILE:0:0)"\n :at [clojure.lang.Compiler$InvokeExpr eval "Compiler.java" 3661]}\n {:type java.lang.ClassCastException\n...
23:43clojurebot#object[clojure.lang.Var$Unbound 0x33ffc978 "Unbound: #'sandbox/foo"]
23:43sdegutisThat should have worked right?
23:43sdegutisWhat am I doing wrong?
23:43justin_smithnope
23:43sdegutisIs def super-special and won't allow that or something?
23:43Bronsa,(macroexpand '(->> [] (conj 2)))
23:43clojurebot(conj 2 [])
23:43rhg135the answer to a lot of things seems to be "data it"
23:43sdegutisOops.
23:43justin_smith,(-> [] (conj 2) atom (->> (def foo)))
23:43clojurebot#'sandbox/foo
23:43sdegutis,(->> [] (cons 2) (atom) (def foo))
23:43clojurebot#'sandbox/foo
23:43sdegutisfoo
23:44sdegutis,foo
23:44clojurebot#object[clojure.lang.Atom 0x21cdeae0 {:status :ready, :val (2)}]
23:44justin_smithcheater, that makes it a list
23:44sdegutishahahaha
23:44sdegutis:D
23:44justin_smithmy version made it still a vector
23:44sdegutisThe main thing was (def foo) at the end of a ->>
23:44sdegutisI think I'll do all my defs that way from now on.
23:45rhg135it certainly helps in a repl
23:45sdegutisNever considered that! Good idea rhg135
23:46rhg135neither had I till a month ago
23:46rhg135it was a joyous day
23:46sdegutis:D
23:46sdegutisYou should have put it in /r/lifeprotips for me
23:46sdegutis*us
23:47rhg135I should use reddit first of all lol
23:48sdegutisYeah I just found it the other day.
23:48sdegutisIt's absolutely terrible.
23:48justin_smith(->> reddit (.com) :r/clojure (map upvote))
23:48sdegutisjustin_smith: nice touch with the .com metho
23:48sdegutisd
23:48rhg135so java interop
23:48sdegutisand the :r/ namespace!
23:49sdegutisI bet all the people who have me on ignore are really confused why justin_smith wrote that lol
23:49sdegutisWhat's better for in a test, with-redefs or binding?
23:49rhg135if this chan was a namespace what would it be?
23:49justin_smithsdegutis: I like to spew really random stupid stuff on here, and assume most people will just think I am responding to someone they ignore
23:49sdegutisjustin_smith: haha
23:49rhg135binding or neither
23:50Bronsathey don't do the same thing
23:50sdegutisrhg135: why not with-redefs?
23:50justin_smithrhg135: :freenode/#clojure obviously
23:50sdegutisBronsa: oh?
23:50rhg135race conditions
23:50sdegutisjustin_smith: is that legal!?
23:50sdegutisjustin_smith: I think it's not cuz #
23:50sdegutisreader-hinter thing
23:50justin_smith,:foo/#bar
23:50clojurebot:foo/#bar
23:50sdegutis!
23:50rhg135justin_smith: I would think ::stuff is :freenode.clojure/stuff
23:50justin_smithsdegutis: so many stupid keywords that should not be legal, are anyway
23:51Bronsa,:a/1
23:51clojurebot#<RuntimeException java.lang.RuntimeException: Invalid token: :a/1>
23:51Bronsa,:1/a
23:51clojurebot:1/a
23:51justin_smith,:f''ooo/#b'#'ar
23:51clojurebot:f''ooo/#b'#'ar
23:51rhg135,:freenode.#clojure/a
23:51clojurebot:freenode.#clojure/a
23:51rhg135huh
23:51sdegutisjustin_smith: like this? ##(keyword "")
23:51lazybot⇒ :
23:51sdegutis##:
23:51rhg135live and learn they say
23:51sdegutis##(do :)
23:52sdegutishaha I broke lazybot
23:52justin_smith,((juxt namespace name) (keyword "well that's cheating, but this keyword / is worse"))
23:52clojurebot["well that's cheating, but this keyword " " is worse"]
23:52rhg135oh dear
23:52Bronsa&*clojure-version*
23:52lazybot⇒ {:major 1, :minor 7, :incremental 0, :qualifier "alpha1"}
23:52rhg135imagine it as a literal
23:52Bronsauff
23:53Bronsa,:foo/bar/baz
23:53clojurebot:foo/bar/baz
23:53BronsaIIRC (name :foo/bar/baz) returned something in 1.5 and something different in 1.6
23:54rhg135:this.is.a.very.very.very.very.very.very.very.very.long/keyword
23:54sdegutisWould it be bad on performance to swap a ref's value every 1 second?
23:54rhg135probably
23:54sdegutisHmm.
23:54sdegutisI was planning on doing that with my database value.
23:54rhg135if you're doing so odds are it's not an efficient alogrithm
23:55sdegutisWas gonna put (swap! database constantly new-database) inside my insert and update functions.
23:55sdegutisEr, (reset! database new-database)
23:55justin_smithsdegutis in real life: http://gfycat.com/SecondAdmiredKilldeer
23:56sdegutisWow. so accurate
23:56rhg135you program on a surface??
23:56lazybotrhg135: Uh, no. Why would you even ask?
23:56justin_smithit's the flapping paddle-hands that really captures his essence
23:56Bronsasurprisingly accurate indeed.
23:57rhg135that reminds me of me when I'm tired
23:57rhg135"no thinking, just type faster!"
23:57sdegutisBronsa: it was funny when justin_smith said it because he was being friendly and fun; you're just insulting and that kind of ruins the humor
23:58sdegutisjustin_smith: do you seriously recommend against doing that tho?
23:58justin_smithso you actually meant an atom not a ref I guess
23:59sdegutisI haven't determined which one yet.
23:59sdegutisThe main point is a thing that I can swap out within the context of Compojure handlers (but deeper in the call stack, since it's inside my update/insert functions).
23:59justin_smithif you had something wrapping a connection, and each interaction with the db returned a new one, I would consider something like that I guess