#clojure log - Jan 29 2015

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

0:33 Draggor: Am I missing something? How do I make the lein script not download clojure every time.

0:35 amalloy: it will only download clojure if the project you're building requires a version of clojure that you don't already have downloaded

0:40 Draggor: How do I install clojure so that lein sees it? I've got the zip downloaded and extracted.

0:40 linux platform

0:41 rhg135: It downloads it from maven central

0:43 Draggor: I get that, but it seems to do it every time I issue a lein command.

0:44 rhg135: Is ~/.m2 there?

0:44 Draggor: Yep

0:44 how long should it take to get into lein repl?

0:45 rhg135: ~1s for me

0:45 clojurebot: I don't understand.

0:46 Draggor: About 6s here.

1:16 amalloy: Draggor: are you inside a lein project when `lein repl` appears to download clojure? if so, can you gist its project.clj?

1:19 Draggor: amalloy: So it seems to not be downloading it, but still has a very slow startup time of 6 seconds when I'm inside of a lein project.

1:21 or apparently longer, that one was 15s

1:21 amalloy: lein's startup time is legit pretty terrible. there are some things you can do to speed it up, but also you don't have to start lein very often; you can leave a repl or an nrepl session up for a long time

1:23 like i start up lein repl ~never (i use an emacs interaction plugin instead). the emacs plugin takes a silly amount of time to start too, but i only start it once or twice a day and then live in it for the rest of the day, so that awfulness is not such a big deal

1:26 mgaare: you can also use this https://github.com/ninjudd/drip

1:26 Draggor: I'm poking at getting vim + fireplace going

1:27 The documentation for it all is not the best I suppose.

1:28 * Draggor might venture back into trying emacs

1:32 amalloy: vim is fine

1:33 if you prefer vim to emacs, you don't need to switch just to use clojure

1:39 Draggor: amalloy: well, in terms of getting a slime like thing going, one of this is clearly way more effort than the other, heh.

1:39 amalloy: which one?

1:40 Draggor: vim + fireplace and the rest

1:41 wgwgzsdfwe: ,(.shiftLeft 2 (biginteger 8))

1:41 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: No matching method found: shiftLeft for class java.lang.Long>

1:41 wgwgzsdfwe: This once worked.

1:48 ,(.shiftLeft (biginteger 8) 2)

1:48 clojurebot: 32

1:48 wgwgzsdfwe: Oopsies.

1:54 Draggor: Where did I put all my old clojure projects... How hard is upgrading from around 1.0.0 to current?

2:02 sm0ke: never heard someone using 1.0.0

2:03 wow must be very old

2:14 devn: Draggor: It's not the end of the world.

2:14 Draggor: why do you need to upgrade?

2:14 I realize you want to, just asking why you *need* to.

2:15 A particular library, new development on the project, just making it work?

2:19 clj123: What is the best way to concat more than 2 lists for eg. ['a' 'b' 'c'] + ['d' 'e' 'f'] + ['g' 'h' 'i'] => ['a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i']

2:30 bucketh3ad: clj123: concat takes more than one argument, so that should work just fine

2:31 ianhedoesit: ,(into [] (concat [\a \b \c] [\d \e \f] [\g \h \i]))

2:31 clojurebot: [\a \b \c \d \e ...]

2:32 ianhedoesit: ,(into [] (concat ['a' 'b' 'c'] ['d' 'e' 'f'] ['g' 'h' 'i']))

2:32 clojurebot: [a' b' c' d' e' ...]

2:33 ianhedoesit: clj123: note that the quote is not used as a character literal

2:33 clj123: ok thanks

2:34 should have been double quote. clojure treats single quote differently

2:35 ianhedoesit: when trying to run my tests (`lein test` or `lein midje`), I'm getting a 'FileNotFoundException: Could not locate <project>/handler__init.class or <project>/handler.clj on classpath: , compiling:(<project>/core/handler_test.clj:1:1)'

2:36 I can't figure out what is different about this project vs the last project I had which works fine and runs tests fine. the structure is the same as far as I can see.

2:38 Draggor: devn: no real reason, I just haven't tried running the old code with the latest version.

2:47 ianhedoesit: never mind me. I made a silly mistake.

3:39 Empperi: cfleming: debugging works again, at least mostly. let values are not shown and evaluate expression is broken

3:41 cfleming: Empperi: When you say let values are not shown, what do you mean?

3:41 Empperi: Which version of IntelliJ are you using?

3:42 Empperi: 14, latest

3:42 just updated today

3:43 and I mean that they are not shown in the debugger as values

3:43 only function parameter values are

3:43 same problem with custom macro parameters

3:43 that I kinda understand though

3:43 but the thing I'm missing most is the evaluate expression

3:44 I want to stop the execution to specific point, then evaluate some expressions when the application is in certain state

3:44 eg. right now I have a bug in my code which integration tests showed

3:44 but for it to happen my database has to be in certain state

3:44 which my tests do initialize

3:45 now, when evaluate expression worked all I had to do was to place a breakpoint to certain part of my code, then when the execution stops I could query the state of the database via evaluate expression

3:45 since the tests use in-memory H2 there would be all kinds of hassle to make it persistent

3:46 can be done, but would be so much easier :)

3:46 cfleming: Empperi: So evaluate expression should work in 0.1.44. Do you get any exceptions in the log when you try it?

3:47 Empperi: cfleming: no, I can evaluate a single value but not a clojure expression

3:47 it doesn't show the clojure logo in the evaluate expression window which I think it did before

3:47 it seems to be an ordinary java expression evaluation

3:48 cfleming: Empperi: I use it myself, it works fine for me. Let values should be shown, but there's one issue - if the value you want is closed over (i.e. you're in an anonymous fn of some kind) they will be shown as fields on 'this'

3:48 Empperi: well, not showing here :(

3:48 cfleming: Empperi: If that's not the case, can you send a screenshot of the locals view?

3:48 Empperi: I'm kinda used to checking the value of this by now

3:48 sure

3:48 cfleming: Actually, of the locals view and the code around the stopped line.

3:49 When you try to evaluate a Clojure expression, what happens? Do you get an error?

3:49 Empperi: yes

3:50 eg it breaks on foo-bar at -

3:50 which would indicate it's using java evaluation

3:50 cfleming: Empperi: Yeah, it might be getting confused about the context somehow.

3:51 Empperi: I'm trying to fix some bugs in expr eval in 13.1, but 14 has always worked well so far. Interestingly, the 13.1 bug is that it seems to be using a Java context - might be the same bug

3:51 Empperi: I do see the Clojure icon by the eval text field though

3:53 Empperi: not here :/

3:54 cfleming: sent mail

3:55 idea says plugin version is 0.1.44

3:55 cfleming: Empperi: Thanks - you're stopped at the line marked in red there?

3:55 Empperi: yes

3:56 cfleming: Empperi: That is very strange. Is this a work project? Can you send it to me so I can try to reproduce?

3:57 Empperi: unfortunately yes, this is a work project

3:57 cfleming: Empperi: If not, I'll try to fix the 13.1 bug, since that might actually be the same cause.

3:57 Ok

3:57 Empperi: so can't send the source code

3:57 cfleming: When I have this other bug fixed I'll send you a build to try to see if it fixes your problem.

3:57 Empperi: nice

3:58 cfleming: Empperi: If you keep stepping in from that line, do you ever see the locals appear?

3:59 Empperi: sometimes

3:59 but only in function parameters

3:59 never with let locals

3:59 cfleming: Empperi: See, there's a problem - JDI debugging is line based. So there's at least three points that you might be stopped on at that line - update-in, map, or fn

3:59 Empperi: but I can access all of them from evaluate expression just by typing the name

3:59 but can't type clojure code there

4:00 cfleming: Empperi: That is really weird, I have no idea how that's working

4:00 Empperi: and yeah, I've already got used to having to keep stepping several steps forward before I get my locals in view

4:00 this used to work just fine

4:00 cfleming: Empperi: You get all the weird ones :/

4:00 Empperi: hehe, sorry for being such a pain in the ass :)

4:01 cfleming: Empperi: Hehe, no worries - hopefully this other bug will turn out to be the same

4:01 Empperi: would be nice :)

4:01 cfleming: If I'm lucky I'll get that fixed tonight - will let you know

4:01 Empperi: but anyway, I have this problem both on windows and mac

4:01 cfleming: Ok, thanks

4:01 Empperi: so this time it's not operating system related

4:01 cfleming: I've been working on the other one this afternoon, I might have to consult JetBrains on this one

4:02 Empperi: no worries, you're doing a great job

4:02 and even more awesome I have this direct feedback link to you :D

4:03 cfleming: oh, btw the exact Idea version number is 14.0.3

4:04 cfleming: Empperi: Ok, thanks. It mostly matters whether it's 13.1 or 14, since in 14 they changed a bunch of stuff in the debugger

4:04 Empperi: yeah, the debugger worked fine in 13.1

4:05 at least as far as I remember

4:05 been using 14 since it came out

4:06 cfleming: Empperi: Well, the debugger got broken in Cursive, in 0.1.43, then I fixed it up for 0.1.44. For almost everyone it's now way better than it was :)

4:07 Empperi: cfleming: :)

4:07 cfleming: Empperi: Looking at your screenshot, it's executing update-in since your top thread frame is still mark-double-xmls, not some anonymous fn

4:09 Empperi: You're not doing anything that would change bytecode, right? A JVM agent or anything like that?

4:09 Empperi: no

4:09 this is just plain ol' clojure

4:09 cfleming: Empperi: Because the locals display is all IntelliJ, I actually want to change that but I can't

4:09 Empperi: running on top of http-kit normally, but in this case through clojure.test

4:10 opened a repl via leiningen

4:10 cfleming: So if it's not showing the locals, it's because IntelliJ isn't finding them in the stack frame context

4:10 Empperi: directly from idea

4:10 cfleming: I don't get to do anything till long after that

4:10 Empperi: so no remote connections or such things from terminal launced lein

4:11 then I just execute the tests from the active namespace to repl

4:11 and debugger gets caught but doesn't show anything

4:15 m00nlight_: What's the right way for an require library to access its own resource file? I can do it in the library's repl, but when I use the library in another project, it report an "Not a file" error of the resource file

4:15 I use the io/resource to access the file under "resources/" directory

4:20 tomjack: m00nlight_: you're trying something like: file at project-a/resources/foo/bar.txt, then in project-b, (io/resource "foo/bar.txt") ?

4:21 m00nlight_: tomjack: No, in fact, I only require the library, the library itself will need the "resources/file.dict" of its own

4:22 tomjack: but when I require the file in another project, it report an error like "Not a file: jar:file:/home/m00nlight/.m2/repository/clj-cn-mmseg/clj-cn-mmseg/0.1.2/clj-cn-mmseg-0.1.2.jar!/CNCharacter.freq, compiling:"

4:23 I use (io/file (io/resource "file.freq")) in the library code, I want to know is it the right way?

4:25 tomjack: what do you want to do with the file?

4:25 you're not going to be able to call io/file on that

4:26 m00nlight_: It's just an dictionary for language processing

4:26 so only (io/resource "file.dict"), you mean?

4:27 tomjack: right

4:28 clgv: m00nlight_: you can open inputstreams from URLs returned by io/resource

4:28 tomjack: you can e.g. (slurp (io/resource path))

4:28 or, yeah, (io/input-stream (io/resource path))

4:28 (io/reader (io/resource path))

4:29 m00nlight_: So maybe the doc here https://clojuredocs.org/clojure.java.io/resource need update?

4:29 What's the difference? Why use io/file will cause not a file error on another project?

4:29 tomjack: yes, that's a bad example

4:29 clgv: m00nlight_: more use cases could be added, but it is not wrong

4:29 tomjack: well, sure

4:30 but say you uberjar and run in production

4:30 boom?

4:30 clgv: the use of a global var for the file is horrible anyway

4:32 tomjack: m00nlight_: the difference is that, in the example, it is assumed that "hello.txt" is on the classpath because you're inside the project, and the project's files on the filesystem are directly on your classpath

4:32 so io/resource will return a file:/ URL, from which the path can be extracted to get a File

4:33 but e.g. (io/resource "clojure/core.clj") will return a jar:file:/ URL, which a File can't represent

4:34 egli: tomjack: so how do I pack schema files that I need for schema validation. Can't I put them in resources?

4:35 tomjack: you can

4:35 egli: tomjack: you are saying that (StreamSource. (io/file (io/resource schema))) is not going to work in an uberjar?

4:35 tomjack: right

4:36 use (StreamSource. (io/input-stream (io/resource schema))) or (StreamSource. (io/reader (io/resource schema))) I guess

4:36 m00nlight_: tomjack: (slurp (io/resource "file.dict")) also work, right?

4:37 egli: tomjack: thanks, I'll try that

4:38 tomjack: ,(apply str (take 30 (slurp (clojure.java.io/resource "clojure/core.clj"))))

4:38 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: No implementation of method: :make-reader of protocol: #'clojure.java.io/IOFactory found for class: nil>

4:38 tomjack: shucks

4:38 it should work for you :)

4:39 m00nlight_: tomjack: Thanks a lot, I will try it

4:53 tomjack: Solved, Much thanks

4:53 clj123: what is the purpose of '@' in clojure. While using one http lib I see code like (:status @response) (:body @response). When I try using '@' using a test hash table it doesn't work.

4:54 sm0ke: clj123: ##(doc deref)

4:54 lazybot: ⇒ ------------------------- clojure.core/deref ([ref] [ref timeout-ms timeout-val]) Also reader macro: @ref/@agent/@var/@atom/@delay/@future/@promise. Within a transaction, returns the in-transaction-value of ref, else returns the most-recently-committed value of... https://www.refheap.com/96621

4:54 sm0ke: clj123: it is applicable only on @ref/@agent/@var/@atom/@delay/@future/@promise

4:55 you cant do ## @{:a 1}

4:55 lazybot: java.lang.ClassCastException: clojure.lang.PersistentArrayMap cannot be cast to java.util.concurrent.Future

4:55 sm0ke: just a ## (:a {:a 1}) ; should be enough

4:55 lazybot: ⇒ 1

4:56 clgv: clj123: as long as you getting started and are not learning about atoms/refs/etc... just forget about @ ;)

4:58 sm0ke: how do i `install` test namespaces?

4:58 clj123: I see. thanks.

4:58 sm0ke: #leiningen is out of my timezone it seems

4:58 grrr time

4:58 clgv: huh?

4:59 sm0ke: you want to load a test namespace?

4:59 sm0ke: clgv: well i want to be able to use it from a different project

4:59 clgv: mainly some utils namespaces in test

4:59 clgv: sm0ke: make it separate lib that is in the :dev dependencies

4:59 sm0ke: regular helper functions for test i wrote, not (deftest..) etc

5:00 clgv: sm0ke: other approaches will be hacks.

5:00 sm0ke: wth

5:01 cant i force lein to do that?

5:01 clgv: one of these hacks: you could have the "test" directory as additional "source" directory instead of a test directory

5:01 or a third source directory "test-utils"

5:02 i.e. source dirs "src", "test-utils" and test dir "test"

5:03 sm0ke: hurmm can i add a single file to source? let me check the epic sample lein project.clj

5:03 clgv: but the separate lib is probably the best choice since you will be wanting those tools in other projects as well

5:03 sm0ke: nope. you need a directory

5:03 sm0ke: ouch

5:04 how bad can packaging a test dir be?

5:04 egli: tomjack: it works! I owe you a beer!

5:04 (inc tomjack)

5:04 lazybot: ⇒ 3

5:04 clgv: sm0ke: well then just add it as source directory

5:05 sm0ke: hurmm is that a trap?

5:05 i wonder if deftest will expand at runtime and start running tests every time the jar is loaded

5:05 perplexa: are there any alternatives to clj-time?

5:05 clgv: no. but if you want to include it in the jar, thats an option

5:05 sm0ke: perplexa: joda

5:06 Glenjamin: perplexa: what problem are you having that makes you seek an alternative?

5:06 clgv: sm0ke: what? even if it did you would have to load the namespace first

5:06 sm0ke: clgv: hurmm i hate that lein does not allow classifiers

5:06 clgv: Glenjamin: the optimal solution for sm0ke would be a separate test-utils lib added as :dev dependency in the projects he needs it

5:07 Glenjamin: i agree

5:07 sm0ke: i would other wise just publish the "test" dirs with a classifier "test"

5:07 clgv: sm0ke: but afaik deftest results in a function definition

5:07 perplexa: Glenjamin: the periodic time stuff is broken here, i keep getting "No matching method found: multipliedBy for class org.joda.time.Period" and apart from that, its author is an arrogant jerk, who rather choses to rant about being contacted instead of fixing his stuff ;P

5:07 clgv: sm0ke: midje is not and runs the test when the namespace is evaluated

5:07 Glenjamin: perplexa: :s

5:08 sm0ke: perplexa: harsh words

5:08 Glenjamin: can you link to the github issue?

5:09 perplexa: sm0ke: i wrote to him directly and he called me a 'disrespectful dip shit' for not using the mailing list and followed it up with "I will never pay any attention to any issue you report."

5:09 way to go.

5:10 clgv: interesting.

5:10 sm0ke: hurmm

5:10 clgv: perplexa: is the library that good that you will continue using it?

5:10 perplexa: no i will ditch it over this

5:10 sm0ke: clgv: thats not the point

5:11 Glenjamin: Joda is the best lib on java i know of, and with clj-time wrapping joda i suspect your only alternative is interop to joda directly =/

5:11 sm0ke: i wonder if you should directly write to an unknown person asking to fix stuff

5:11 Glenjamin: sm0ke: even if not, the sensible response is "please repost this to ML / github issues"

5:11 perplexa: if he doesn't want to be contacted he shouldn't put his mail in public places

5:11 sm0ke: i agree

5:11 clgv: sm0ke: from a practical point of view that would be a major descion argument for me

5:12 sm0ke: the other one being: can I fix and maintain it myself ;)

5:12 Glenjamin: fork: friendly-clj-time

5:12 sm0ke: there are 61 contributors to the lib

5:12 be one

5:13 clgv: ah it's clj-time? well, I hardly use that one. only formating timestamps so far ;)

5:16 I wonder whom he did write. I would guess not one of the top contributors

5:16 perplexa: Glenjamin: gonna look into https://github.com/dm3/clojure.joda-time ;p

5:16 oh 'build failing'

5:19 http://perplexa.be/Screen%20Shot%202015-01-29%20at%2011.16.42.png

5:19 i wonder what's wrong with that guy :D

5:21 clgv: perplexa: why dont you use clj-time instead?

5:21 sm0ke: perplexa: no use getting personal, did you file an issue?

5:21 clgv: i think he is talking about it ony

5:22 perplexa: clgv: yeah using it and it's behaving weird ;p

5:22 sm0ke: well since the author told me right away that he's gonna ignore any reported issues, there's probably not a point in it.

5:23 sm0ke: there are 61 authors someone will respond.

5:23 Glenjamin: That's not the point, getting a response like that from a project lead would put me off right away

5:24 clgv: perplexa: one of the top contributors of clj-time gave you that response?

5:25 perplexa: clgv: yes, it came from michael klishin.

5:26 clgv: hard to believe judging from the stuff I read from him. maybe a bad day...

5:28 perplexa: just create an issue on the project and describe the problem properly. with that many contributors it'll get a fix provided it is not out of the scope of that library

5:31 algernon: fwiv: https://twitter.com/michaelklishin/status/560741014525472769

5:32 cfleming: Ummm... so that's not very cool either.

5:33 algernon: it's not very cool from either side.

5:33 acron^: Ouch

5:33 cfleming: Agreed

5:34 sm0ke: i feel like i am back in highschool

5:34 perplexa: :P

5:36 hellofunk: this is pretty funny: https://github.com/landondyer/kasm/blob/master/LICENSE

5:36 cfleming: hellofunk: Yeah, I had a little smile at that too

5:37 acron^: lol

5:37 why the hate on RMS ?

5:37 cfleming: Who knows?

5:37 hyPiRion: no idea

5:37 sm0ke: haha thats just sadist

5:40 well RMS is the father of open source (?) and he make a license for his open source project which is not for RMS

5:40 acron^: get it?

5:41 acron^: i get it

5:41 but why doesn't he want RMS to use it

5:41 sm0ke: :/

5:41 acron^: is he trying to be ironic?

5:41 sm0ke: yea

6:06 zarkone: hello all. Does anybody use clojurescript and cider nrepl? cannot get it work propery..

6:09 Jahkeup_: zarkone: you'll have to connect to a brepl (browser repl)

6:10 zarkone: take a look at something like https://github.com/cemerick/austin

6:10 mavbozo: zarkone: what library do you use?

6:11 hellofunk: zarkone: you can use cider and clojurescript together for many tasks, but the REPL is not a part of cider if you need that

6:13 zarkone: cider includes clojure repl, and also lots of cider features work in both clojure and clojurescript. figwheel and weasel are the popular clojurescript repl choices (though personally i rarely need a cljs repl even when working in cljs all day)

6:23 cfleming: Empperi: So this bug I'm fixing is almost certainly not your problem

6:34 zarkone: Jahkeup_: hellofunk thank for response, sorry that i've missed it >..< I start cider-nrepl middleware with ring server. That i start figwheel. Than I connect to the repl and eval this: (piggieback/cljs-repl :repl-env (weasel/repl-env :ip "" :port 9001))). It works quite ok, reload the code, etc. But source maps do not work properly -- my CIDER go-to-symbol uses old source location, wich was wirst build with cljs... I see, that

6:34 source maps are changing in out/ dir. But i cannot understand -- is my browser does not relod maps on fly or is it cider issue? in browser debugger->sources i see old maps =(. cljs options :source-map and :source-map-timestamp are true, :optimization :none

6:34 sorry for the long story >..<

6:36 hellofunk: zarkone: i don't know. i just use lein cljsbuild auto all day and never open a repl or deal with that stuff. i've always been happy with my workflow but am not using these more advanced features (and thus not dealing with their problems)

6:36 zarkone: oh, i get used to source docs, param highlight, jump to source...

6:37 i miss it so much)

6:37 hellofunk: zarkone: i must be an odd one, but the incredible consistency between clj and cljs allows me to do all my repl experiements in clojure while actually writing cljs code.

6:38 zarkone: hellofunk: actually, may be it's even better, because e.g. wrong arity is just warning, sometimes i do not see it

6:39 in cljs

6:39 justin_smith: hellofunk: funkhello

6:40 hellofunk: zarkone: yeah i've learned to just read the errors if any that get spit at the chrome console, perhaps i've gotten rehearsed at writing error-free cljs most of the time, though early on i had to figure them out. i don't think perfect source maps would save me any time now.

6:40 justin_smith: word

6:45 justin_smith: so, turns out Acid Mothers Tempple are playing during Clojure/West, we should make an outing https://www.youtube.com/watch?v=QSJnhpmuuhc

6:49 hellofunk: justin_smith: that band reminds me of Ozric Tentacles

6:50 justin_smith: there are some similarities

6:51 hellofunk: in reading the comments it appears i'm not the only one to make that comparison

6:51 zacts: huh, I wonder where an actual manual / guide for overtone is

6:51 I don't see one on the homepage

6:52 hellofunk: zacts: there are some demo source files somewhere, let me see if i can find them

6:52 justin_smith: hellofunk: also much like Gong

6:55 zacts: hey I also found this https://github.com/overtone/overtone/wiki

6:55 I guess the wiki is a work in progress documentation for it

6:56 also I found this http://vimeo.com/22798433

6:57 which is the intro to doing overtone live coding

6:58 hellofunk: hey cool, yeah that could be useful

6:59 cfleming: justin_smith: Wow, that's... pretty freaky.

7:01 zacts: justin_smith: https://github.com/scheme/scsh

7:02 ^ it seems someone may be maintaining scsh a bit

7:02 justin_smith: fascinating

7:02 zacts: but theres a bunch of code that could probably be converted into clojure

7:02 clojurebot: Excuse me?

7:02 zacts: silly bot!

7:02 :-)

7:02 justin_smith: clojurebot: you're excused

7:02 clojurebot: No entiendo

7:04 cfleming: clojurebot: Porque eres tonto

7:04 clojurebot: I don't understand.

7:04 cfleming: Obviously

7:05 justin_smith: haha

7:06 cfleming: I shouldn't mock the bot, when the singularity happens I'll be first against the wall

7:07 justin_smith: cfleming: in that case, midje users are in trouble

7:07 * justin_smith hides.

7:07 cfleming: justin_smith: Ba-doom *tschhhh*

7:08 clgv: cfleming: when the singularity happens clojurebot will choke on an unbalanced paren resulting in a RuntimeException ;)

7:08 so no danger from it

7:08 :P

7:08 hellofunk: ah, singularity, the great imaginary doom that will never happen but still scare everyone anyway

7:09 cfleming: By the time the singularity happens, I suspect clojurebot will have figured out how to temporarily disable paredit :-)

7:09 clgv: cfleming: are you saying he is secretly using cursive with paredit? ;)

7:09 cfleming: clgv: Shhhhh

7:10 He will be when he gets smart enough, at least ;)

7:13 hellofunk: zacts: https://github.com/mgandin/lightning-talk-clojure-overtone

7:17 zacts: oh cool thanks hellofunk

7:48 arav93: Does persistent hash set have a data type of its own? Or do we mention all as merely set itself?

7:48 Sorry about asking the same question in #typed-clojure channel as well!

7:48 justin_smith: ,(class #{})

7:48 clojurebot: clojure.lang.PersistentHashSet

7:49 justin_smith: arav93: oh, you mean in the typed clojure sense? I don't know that part

7:53 clgv: arav93: does your program need to verify that distinction? (better not)

7:53 arav93: clgv: I was trying annotate clojure.set.

7:54 I wasn't quite sure whether to use persistenthashset or just the normal set

7:55 justin_smith: "normal set"?

7:55 clojure.set is a namespace with operations on PersistentHashSet

7:55 or do you mean java.util.Set or something?

7:59 clgv: justin_smith: he probably means PersistentTreeSet

8:00 ,(type (sorted-set))

8:00 clojurebot: clojure.lang.PersistentTreeSet

8:00 clgv: ok, the distinction of sorted vs unsorted could indeed be valid to some functions

8:09 yocapybara: guys this is not a clojure problem really, but say I'm using java 7 watcher stuff and I get a message that a file is created, any way to definitively tell it isn't being written to short of repeatedly checking its bytes and declaring it finished after a certain period of time? I've tried Files.move atomic move to rename, but it seems a file can be renamed while still being copied. I've tried opening it for random access reading and

8:09 that seems to be permitted also when the file is being copied too.

8:11 have been using interop to do the stream reading and Files.move stuff... but can't find a reliable approach. Will likely try to sidestep the problem but would be nice to resolve it!

8:12 justin_smith: yocapybara: what OS?

8:12 yocapybara: justin_smith: hi there - developing on osx, deploying to ubuntu

8:12 justin_smith: yocapybara: for example, on a Linux system you can move a file while it is being written without interrupting write

8:13 as long as the move is to the same file system

8:13 clgv: yocapybara: does the java api support locks on files?

8:13 yocapybara: justin_smith: yup, I didn't know what would happen and found that to be true :) shoud have perhaps looked it up!

8:13 clgv: yocapybara: so if you control both you could coordinate via file locks

8:14 yocapybara: clgv: I think Java 7 supports locking files, though I thought that was only inside JVM, do the locks interoperate with the OS somehow for this?

8:14 justin_smith: yocapybara: in fact, you can delete a file that another program is using, and the file is still usable by that program until they exit or close the file

8:14 yocapybara: justin_smith: that got me confused the first time I deleted a tomcat log!

8:14 justin_smith: yocapybara: this is also how they hide the video files that make video streaming possible, to prevent keeping a local copy of the video

8:15 yocapybara: justin_smith: that I had no idea of, clever but annoying

8:15 clgv: justin_smith: "security" by obscurity? :P

8:15 Glenjamin: i once zeroed a deleted logfile via /proc because i didn't know how to safely restart an app

8:16 the /proc stuff is crazy magic

8:16 yocapybara: clgv: aaah from java.nio.channels.FileLock 'This file-locking API is intended to map directly to the native locking facility of the underlying operating system. Thus the locks held on a file should be visible to all programs that have access to the file, regardless of the language in which those programs are written.'

8:16 clgv: this looks worth a try

8:16 clgv: yocapybara: yeah, but you need to control the writer and the renaming process and force them to aquire the log

8:17 justin_smith: clgv: the issue is that everything is accessible on Linux (it's an open system), so DRM stuff is always a sloppy hack

8:17 clgv: justin_smith: DRM is broken by design ;)

8:17 justin_smith: clgv: right, but they can fake it better on closed systems

8:18 yocapybara: clgv: in my case I'm getting large files ftp'ed in - now I can try to configure the ftp server, but I wanted a reliable fallback to see if I can just find if a file is finished. So my plan was watcher API to give me create events, then run off a go block that establishes if it is finished periodically, and then fire the file off to its destination once done

8:18 justin_smith: $mail andyf are there known issues with eastwood arity checking and clojure.java.jdbc/insert! or is it an issue with this codebase?

8:18 lazybot: Message saved.

8:18 justin_smith: anyone else is free to offer an answer, of course :)

8:18 clgv: yocapybara: well, then the file lock might proof useless

8:19 yocapybara: clgv: you don't think the ftp server would lock the file when it was being transferred?

8:19 Glenjamin: I didn't realise you could do that, that's pretty awesome

8:19 clgv: justin_smith: isn't this part of the custom :arglists discussion?

8:20 yocapybara: I don't know, hence the "might" in the statement ;)

8:20 yocapybara: clgv: no worries :)

8:21 justin_smith: clgv: oh, that bullshit

8:21 yeah

8:21 probably

8:22 Glenjamin: yocapybara: this is also why env vars are inherently insecure

8:22 you can read any process' env via proc

8:22 (don't tell 12factor)

8:22 yocapybara: hahaha

8:23 Glenjamin: justin_smith: if you have perms for that, you'd be able to read config files too?

8:23 yfeng: hi all

8:24 justin_smith: Glenjamin: encrypted properties file, assign the password to nil once you have it decrypted, assign creds to nil once you are authenticated

8:24 Glenjamin: but as we know, there are no reliable methods to reassign env vars inside the jvm

8:24 not portable at least

8:25 Glenjamin: how do you pass in the decryption key?

8:25 justin_smith: ugh, I had this worked out once...

8:25 haha

8:25 clgv: Glenjamin: there is a monkey sitting in the server that is trained to type in the password on server reboots ;)

8:26 Glenjamin: yeah, so i need the same or higher perms than the process owner to read its env var

8:26 justin_smith: Glenjamin: anyway, at the very least, the env isn't any more secure than other methods of providing the creds (though of course keeping them in git is bad)

8:26 Glenjamin: i don't think env vars are any more insecure than other methods

8:26 clgv: or a banana to bribe the monkey

8:26 Glenjamin: ^^

8:31 justin_smith: Glenjamin: in all seriousness though, a higher priveleged (and more locked down / more restricted use) account can provide the credentials for unlocking a properties file, and unlike an env var, the jvm process can assign these things to nil once they are unused. This is probably more vigilance than most apps need though.

8:32 Glenjamin: what this does is make it harder for a random takeover of the server process itself to get access to credentials.

8:32 Glenjamin: justin_smith: i'm still not sure how the privileged process can pass the data safely down before it drops perms

8:32 yeah, i can see how that would be preferrable

8:32 oh, stdin is safeish?

8:33 justin_smith: Glenjamin: it wouldn't drop perms, it's a separate service. I think things like PAM are designed for this sort of thing.

8:33 Glenjamin: yeah, or even a pipe

8:33 because there is no persistence of what passes through the pipe

8:33 but this is all james-bond stuff, beyond what most of us need to worry about :)

8:34 Glenjamin: yeah, to do automated ops stuff it's realistically going to end up in a file somewhere

8:34 justin_smith: but minimizing the spread of credentials, minimizing scope of permissions, etc. are good things to keep in mind regardless

8:34 Glenjamin: mm

8:34 justin_smith: Glenjamin: right, it's in a file, but the account that has access to that file has very little functionality

8:34 little functionality = small surface of attack

8:34 fewer things that can break

8:35 Glenjamin: isn't it the contents of the file that we're trying to protect?

8:35 i've lost track a bit :D

8:35 justin_smith: as opposed to my webapp that runs a turing complete compiler at runtime :)

8:35 Glenjamin: like I said - the account that can access the master file does very little

8:35 it does not run a compiler

8:35 it is not turing complete, and we can prove it

8:36 Glenjamin: oh, interesting

8:36 justin_smith: the process running a compiler at runtime only gets those credentials under very specific circumstances, controlled by the other process

8:37 none of this is unbreakable I am sure, but you have degrees of breakability

8:37 Glenjamin: yeah, i like the general idea

8:39 justin_smith: but I think we have to be a little more careful, since we have full access to a compiler at runtime

8:54 dysfun: or we just defer compile time to runtime

8:54 depending on how you look at it

9:05 nort_: Hi, I have a .nar file that I want to use from Clojure, but leiningen doesn't seem to support it atm. I found someone with the same problem here, explaning how he could work around it https://groups.google.com/forum/#!topic/maven-nar/d9BjwT_u2h8 . But I really don't understand how it's solved, or whether I can also do that. Does anyone have an idea how I can easiest access .nar-file from Clojure?

9:05 I don't have much experience with leiningen, so I wanted to ask here before I dig deeper and risk going in a wrong direction..

9:08 justin_smith: nort_: you may have more luck on #leiningen

9:08 clgv: nort_: projects like overtone directly include native dependencies in subfolders afaik

9:08 justin_smith: nort_: it seems like this wouldn't be a hard thing to add to lein though

9:09 clgv: but do they use the nar file abstraction? I don't know if that is a specific requirement here I guess.

9:10 clgv: justin_smith: I think they do not. so my workaround suggestion would be to extract the nar and build a jar working in leiningen

9:11 justin_smith: clgv: well, a nar is just a renamed jar, but the tooling knows you can't use it without extracting it to disk (since the OS needs to access the contents)

9:11 that's my understanding at least

9:11 not hard to hack, but it would be nice to do it the normal way

9:11 clgv: well the jar setup also extract the native dependencies

9:12 justin_smith: ahh, OK, I did not realize that was automatic

9:12 clgv: but I never used it myself...

9:15 nort_: Ok, I will try in that channel also. But if I understand correctly, it should be possible to extract the .nar, create a .jar from it, and then use that instead?

9:17 clgv: nort_: I guess so. you just have to find an example how clojure projects with native dependencies set this up

9:19 nort_: Ok, thanks

9:35 justin_smith: nort_: actually, it may be as simple as renaming .nar to .jar, I think the naming just indicates it should be handled differently (automatically extracted) and there is no difference in actual structure of the artifact from a jar

9:41 R0B_ROD: Morning

9:41 nort_: justin_smith: Oh, that would be awesome! I will try it out :-) Thanks

9:41 justin_smith: ~UGT

9:41 clojurebot: UGT is Universal Greeting Time http://www.total-knowledge.com/~ilya/mips/ugt.html

9:42 justin_smith: R0B_ROD: UGT to you as well

9:43 R0B_ROD: justin_smith: :) Hey there

9:46 clgv: UGT is **** ;)

9:46 (don't insert "awesome" for the stars) :P

9:49 R0B_ROD: justin_smith: I learned something new. UGT to you

9:49 ;>

9:49 Im doing the koans

9:50 Like you advised the first time I logged in here

9:50 I am aka as brainacid

9:50 maio: how would I write macro which takes function as an argument? simplified example (which doesn't work): (defmacro foo [f arg] (f arg))

9:50 R0B_ROD: but after learning more about open-source and true programmers I decided to use a shortened version of my name

9:50 lol just talking out loud

9:50 clgv: maio: what exactly is the overall goal? what should the macro do with the function?

9:50 * R0B_ROD seeks more knowledge

9:51 maio: clgv: I want to call that function (in compile time)

9:52 michaniskin__: i once saw a great chart that showed a graph of clojure collections and the protocols they implement

9:52 maio: (defmacro foo [f arg] ((eval f) arg)) seems to work, but is that OK?

9:52 michaniskin__: does anyone know how i can find it again?

9:52 clgv: maio: ah. macros do not work that way. you do not get the function but the symbol referring to the function when the macro is expanded

9:53 maio: are you sure that you do need a macro. it looks pretty much like you want an higher order function

9:53 ?

9:53 maio: clgv: I think I need macro. My real code is here https://github.com/maio/defns/blob/master/src/defns.clj

9:54 clgv: maio: what is that code supposed to do?

9:54 justin_smith: maio: a macro needs to return at compile time the code for run time

9:55 maio: justin_smith: sure but I want/need to do some stuff at compile time (call some function in this case)

9:56 clgv: maio: but you do not know the function when defining the macro? that is a pretty rare use case - hence the question whether you are sure that is really a solution to your problem

9:56 justin_smith: maio: well, if you want to call the function at compile time, then yeah, there you go

9:56 clgv: justin_smith: you can just use (some-> some-fn-symbol resolve deref) to get hold of the function

9:57 maio: ^^

9:57 maio: clgv: It's up to the user to specify which (custom) function to use. For example in tests I need different function than in production code (https://github.com/maio/defns/blob/master/test/defns_test.clj)

9:58 clgv: maio: I sense a weird hack lurking there

9:58 maio: :)

9:58 It's just some experiment :)

10:15 melipone: hello, I need to save a java random object to a file and read it back (since there is no getSeed() in java for that). How can I do that with Clojure?

10:17 justin_smith: melipone: you should be able to use the serialization stuff via interop

10:17 melipone: how random of an object?

10:17 could it be replaced by eg. an edn map or a properties file?

10:18 hyPiRion: justin_smith: the java.lang.util.Random kind

10:18 melipone: justin_smith: Just (Random. 143123)

10:18 justin_smith: melipone: why not just store the number part?

10:18 hyPiRion: justin_smith: because there's no getSeed()

10:18 I'd just do reflection on the object, fetch its seed and put it on disk.

10:18 justin_smith: melipone: ahh, now I get it, sorry

10:19 yeah, reflection may be the easier way, compared to the default serialization methods

10:19 Glenjamin: heh, i read it as "an arbitrary object" too

10:19 justin_smith: glad I'm not alone

10:22 clgv: melipone: do you want to continue the random number sequence from an intermediate state? since seeds are usually preprocessed that wont be possible like that, even with getSeed

10:23 tcrayford____: justin_smith: here's a cool clojure learning for me from today (:or (:cached-thing foo) (expensive-computation foo)) is an amazing fuckup (it always runs the expensive computation, but because it's just caching, things *seem* fine)

10:23 hyPiRion: melipone: You could use serialization if you want some kind of guarantee that reflection doesn't blow up.

10:23 tcrayford____: (it should be (or (:cached-thing foo) (expensive-computation foo)))

10:23 clgv: melipone: you could store the initial seed and count the invocations. a nasty reflection is probably possible as well

10:23 justin_smith: tcrayford____: haha, so you meant to use or

10:23 lol

10:23 tcrayford____: yeah haha

10:23 clgv: melipone: why exactly do you want to do that?

10:23 tcrayford____: but it worked fine!

10:23 been in production for a year like that!

10:24 haha :(

10:24 justin_smith: oh shit!

10:24 Glenjamin: is that because you're not using the value of the expression?

10:24 justin_smith: caching for side effects I guess

10:24 clgv: tcrayford____: sell it as well crafted performance improvement ;)

10:24 tcrayford____: the caching happens outside that code

10:24 justin_smith: Glenjamin: ahh, it's because keyword takes a second, default arg

10:24 gfredericks: ~(:or (:cached-thing foo) (expensive-computation foo)) is an amazing fuckup

10:24 clojurebot: Ok.

10:24 Glenjamin: oh right

10:24 justin_smith: Glenjamin: since the first thing had no :or key, the second part is run and returned

10:25 Glenjamin: yeah, i see

10:25 ouch

10:25 gfredericks: ~an amazing fuckup

10:25 clojurebot: Titim gan éirí ort.

10:25 tcrayford____: I mean, I say "expensive", it's like a sha256 call over a relatively small string haha

10:25 justin_smith: ,(:or (:blah {:blah "OK"}) (:expensive {:expensive "OK"})) ; this is what he did

10:25 clojurebot: "OK"

10:26 gfredericks: tcrayford____: that one-use-of-keyword linter mightacaughtit

10:26 justin_smith: the right return value, but the wrong source

10:26 melipone: clgv: I want to continue the computation later with the same random seed to be able to compare results

10:26 tcrayford____: gfredericks: the one in eastwood?

10:26 I literally just started using eastwood yesterday haha

10:26 (it didn't catch it)

10:26 justin_smith: tcrayford____: aye, that is the one linter we have matey

10:26 but the keyword linting is not on by default

10:26 clgv: melipone: why not just store the initial seed for comparison?

10:27 tcrayford____: justin_smith: yeah, I turned *all* of the linters on yesterday and went through em, then turned off the ones that were super noisy

10:27 clgv: melipone: usually you just specified a concrete seed at the beginning of the computation

10:27 tcrayford____: the keyword one is *fun* with bootstrap and hiccup: "found :div.span6, did you mean :div.span3" etc

10:27 justin_smith: haha

10:28 tcrayford____: I have https://gist.github.com/tcrayford/0a82713cfb821eeca269 on and my build fails if I create more errors than the current allowed limit

10:29 gfredericks: tcrayford____: yeah eastwood

10:29 tcrayford____: (there are 38 linting errors eastwood spits out on my ~10k lines of code that are incorrect/wrong)

10:30 gfredericks: tcrayford____: if the keyword linter allowed a regex as a whitelist that could fit your html purpose I imagine

10:30 tcrayford____: yeah, that'd be dope

10:30 (related: I *wish* kibit let you customize what linters you had on in project.clj)

10:31 melipone: clgv: yeah, I know

10:31 tcrayford____: I have a whole loada code that explicitly does (if thing bar nil), because I wanna remind myself that `nil` comes out of this conditional, don't want it sneaking around

10:32 gfredericks: melipone: this might not help immediately but I've been working on alternative RNGs that would let you do this

10:33 tcrayford____: gfredericks: perf benchmarks for yeller's api handler after eliminating that stupid :or thingy: https://gist.github.com/tcrayford/90756c22354d9ad19783

10:33 easiest perf win I've ever done haha

10:33 gfredericks: tcrayford____: christmas is saved!

10:34 justin_smith: very nice

10:34 gfredericks: melipone: it also wouldn't be too hard to copypasta the Random.java file from openjdk and adapt it to be serializable

10:35 https://github.com/openjdk-mirror/jdk/blob/jdk7/jdk7/master/src/share/classes/java/util/Random.java

10:35 it does implement Serializable but I don't know what that means :/

10:36 tcrayford____: (lmao if your api's response time isn't measured in hundreds of microseconds)

10:38 melipone: gfredericks: But java.util.Random IS serialiazable

10:39 gfredericks: so how can I write a serializable java object to file in clojure?

10:39 hellofunk: when running lein cljsbuild, how does it know which profile to use in project.clj?

10:39 justin_smith: hellofunk: dev is the default profile

10:40 well, it's a sum of profiles, and you get like user+dev if you specify nothing else

10:40 you can provide them as arguments to lein with-profile

10:40 lein test activates :test, of coruse

10:40 *course

10:40 mmitchell: ugh, why doesn't this macro eval the (get names :foo) arg so that the resulting def is FOO? ... https://gist.github.com/mwmitchell/2db95d5b2f5264102f3e

10:40 hellofunk: if i have two different cljsbuild profiles, how do i specifiy to lein cljsbuild which one to use?

10:41 daniel__1: lein with-profile profile1 cljsbuild auto

10:41 for example

10:41 hellofunk: daniel__: ah cool, thanks

10:42 justin_smith: actually cljsbuild takes profile args too

10:42 lein cljsbuild auto profile-name

10:42 hellofunk: oh cool

10:43 justin_smith: which specify keys under :builds

10:43 daniel__1: cool justin_smith, didnt know

10:43 hellofunk: forgive my ignorance but where did you look this up exactly justin_smith?

10:43 gfredericks: melipone: googling suggests you want to use ObjectInputStream and ObjectOutputStream

10:43 justin_smith: it's right above "repl support" in the readme

10:43 https://github.com/emezeske/lein-cljsbuild

10:43 gfredericks: melipone: and likely the best clojure way to do it is using interop and doing whatever you would do in java

10:43 zacts: http://mitpress.mit.edu/books/structure-and-interpretation-classical-mechanics-2

10:43 ^ a new edition of SICM next month

10:44 justin_smith: hellofunk: most of my skill as a dev is a direct outgrowth of my dungeons and dragons hobby as a kid, and learning to be the one that was best at looking up rules :)

10:44 (if you are the best at looking up rules quickly, you can make sure rules that help you are always looked up, and you can "overlook" the ones that don't)

10:44 melipone: gfredericks: okay, I have already a function in Java to do that. I thought there would be something like that built-in in Clojure.

10:45 hellofunk: justin_smith: interesting what you describe would be a build id, while what daniel__ describes would be a profile. i guess they do similar things?

10:45 justin_smith: hellofunk: good point - I may have sidetracked us with the profile thing (or maybe they are related in some way I don't quite know) - but build ids are clearly documented to work

10:46 most things in lein will be parameterized by profile

10:46 hellofunk: justin_smith: most project.clj files i see for cljs development use profiles not build ids, which is why i wondered how they were getting accessed

10:46 justin_smith: aha

10:46 so we all learned something today

10:47 hellofunk: after i get it working, then i'll be able to say i learned something :)

10:52 clgv: melipone: Clojure interop is built-in and you can use it to implement reading/writing with the object streams

10:53 hellofunk: so if your lein profile is :dev you'd pass dev with no colon to lein with-profile ?

10:57 justin_smith: hellofunk: :dev is the default, you don't need :with-profile for that

11:01 hellofunk: justin_smith: daniel__ there must be more to the story. i have a profile as :prod but running lein with-profile :prod and lein with-profile prod cljsbuild auto both result in Warning: profile not found

11:03 clgv: hellofunk: don't use the colon on th command line

11:03 multiple profiles are separated via comma

11:04 daniel__1: hellofunk: think you'll have to gist your project.clj, second command looks ok

11:04 but unfortunately i have to go

11:05 hellofunk: daniel__ clgv : https://www.refheap.com/96634 but i run this it says :prod not found: lein with-profile prod cljsbuild auto

11:07 justin_smith: hellofunk: the key is :profiles

11:07 hellofunk: not :profile

11:07 clgv: :D

11:07 justin_smith: hellofunk: showing my work https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L155

11:08 hellofunk: that example project.clj is a good place to look whenever some config you put in lein is not behaving the way you expected

11:08 hellofunk: ah geez profile vs profiles. yikes how ridiculous.

11:09 * hellofunk jumps out the window

11:09 justin_smith: hellofunk: easy mistake, lein is very willing to accept invalid keys without complaint

11:09 hellofunk: ...which it has indeed been doing for along time for me

11:10 clgv: justin_smith: because they are not necessarily invalid but meaningless to leiningen ;)

11:10 justin_smith: clgv: indeed

11:10 clgv: but some plugin may use them

11:11 justin_smith: right, it just makes the helpfulness that strictness might provide unattainable

11:11 clgv: but a test-mode to list unknown options (for leinigen) would probably help debugging

11:12 justin_smith: clgv: if it was combined with an API to ask each plugin for the keys it considered interesting...

11:13 that actually wouldn't be too hard, though it would require a lot of cooperation to do it retroactively of course

11:14 hellofunk: leiningen is a big black magical box to me that i've never really looked inside for fear of... well, it's so much a box that i don't even know what my fear of it is

11:15 justin_smith: reminds me of that old weird movie, "the cube" - it was a good sci fi / horror kind of thing

11:15 * hellofunk adds the cube to his list. no, not the nextgen machines

11:15 justin_smith: oh no they made "the cube 2, hypercube" - probably fucking terrible

11:17 * hellofunk adds the second cube to his list to see if it is fucking terrible as justin_smith suspects

11:26 bacon1989: Was wondering, what would be the best non-relational database I could use with clojure?

11:27 Datomic looks interesting, is that one hard to adopt outside of clojure?

11:27 tbaldridge: bacon1989: Java support for Datomic is pretty solid

11:27 justin_smith: bacon1989: datomic has extensive docs for usage from other languages at datomic.com

11:28 bacon1989: Oh neat

11:29 Wait... Datomic uses Groovy in it's shell?

11:29 justin_smith: bacon1989: the docs show how to use Groovy

11:29 and I guess maybe the default shell is Groovy?

11:30 bacon1989: Is there a C API for Datomic, or is it strictly in the JVM?

11:30 I see a ruby implementation

11:31 justin_smith: that is likely via a server connection

11:31 so you could likely use a TCP lib to use it from C I guess?

11:31 tbaldridge: bacon1989: datomic does provide a REST interface, the Ruby version uses that, or JRuby can use the JVM API

11:31 {blake}: justin_smith: Actually Cube 2 and Cube 0 are both pretty good, but nowhere near the original.

11:32 bacon1989: tbaldridge: I see, that would make sense

11:32 justin_smith: {blake}: good to know!

11:32 bacon1989: Maybe i'll try out Datomic, anyone here familiar with the free nature of Datomic?

11:32 I don't really understand the restrictions

11:32 tbaldridge: bacon1989: sure. although #datomic is probably a better place for this conversation

11:32 justin_smith: bacon1989: I'd ask on #datomic about that

11:32 heh

11:32 bacon1989: Ah, good idea

11:33 justin_smith: also, since it is a commercial project, I am sure you could email support and expect a helpful response

11:37 sveri: Hi, which middleware do I have to apply to parse query-params in get requests?

11:39 justin_smith: sveri: ring.middleware.params/wrap-params

11:39 nkoza: sveri: ring.middleware.params

11:39 justin_smith: they show up as :query-params on the request map

11:39 and also in :params (merged with :form-params)

11:41 sveri: justin_smith: nkoza hm, that was my guess too, but somehow the uri is not parsed, maybe the uri is wrong? /user/login?next=/user/admin

11:41 query-params is just empty

11:41 jneen: hello! does anyone know of a clojure interface to truffle / graal? or have an opinion on whether making one is worth it?

11:42 sveri: oh, wait, I guess I made a mistake here, obv. I have this uri when rendering the login page, but obv. not when sending the login form to the server

11:42 jneen: its api is based mainly on annotated classes with overloaded methods, so it'd stretch java interop quite a lot i think

11:42 justin_smith: jneen: yeah, annotation is possible, but not simple

11:43 (from clojure that is)

11:43 jneen: hm yeah that's what i gathered

11:43 justin_smith: jneen: how many annotated things do you need?

11:43 you could make some small java shims that call out to clojure

11:43 jneen: well

11:43 arbitrarily many

11:43 one per node type

11:43 so, defined by the language implementer

11:43 ideally through some sort of macro...

11:44 but i think that means a lot of funky class generator stuff

11:44 justin_smith: a macro that generates your :gen-class invocation could be doable

11:44 jneen: can gen-class do class annotations?

11:44 sveri: justin_smith: nkoza thank you, I just had my brain think in the wrong direction

11:44 jneen: i've been looking through the docs and haven't found anything

11:45 justin_smith: jneen: yes, gen-class can do annotations

11:45 jneen: oh!

11:45 um

11:45 ...how...?

11:46 justin_smith: oh wait! deftype can do it

11:46 https://gist.github.com/richhickey/377213

11:47 from the man himself ^

11:47 jneen: actually that looks quite a bit easier than I had imagined

11:47 jneen: oh nice

11:47 haha i ended up on the same gist

11:47 cool

11:48 justin_smith: that gist deserves the high page-rank it clearly has

11:48 llasram: jneen: Are the annotations involved runtime annotations?

11:49 jneen: llasram: compile-time i believe

11:49 (disclosure: i am not very well versed with java stuff)

11:49 llasram: Yeah, so using them with deftype won't help you much

11:49 jneen: yeah but i'd guess gen-class does it?

11:49 llasram: nope

11:49 jneen: aww

11:50 i thought gen-class was compile-time

11:50 justin_smith: llasram: what is the distinction here?

11:50 stuartsierra: Annotation support isn't really documented anywhere, but you can find examples in the Clojure language tests.

11:50 jneen: hence the requirement for AOT compilation

11:51 justin_smith: llasram: is this about annotation preprocessors for java code generation?

11:51 because yeah, doing that in clojure would be a bit pointless

11:51 llasram: justin_smith: Yah

11:51 jneen: hm

11:52 i figured gen-class would do that :\

11:52 maybe it's not possible then

11:52 justin_smith: jneen: well you see, clojure does not generate java code

11:53 it compiles to jvm bytecode with no java step

11:53 jneen: so the annotations are syntactic?

11:53 justin_smith: so if the point of the annotation is to pre-process java source, clojure can't help you do much useful with it

11:53 jneen: i figured that was what they were doing

11:53 justin_smith: jneen: not sure, llasram says they are

11:53 jneen: hrm

11:54 llasram: I'm not sure the one's of interest here are -- it's something to be aware might be the case though

11:54 jneen: yeah i figured they generated bytecode for other classes, but if they generate actual java syntax for other classes it could be weird

11:54 justin_smith: http://lampwww.epfl.ch/~magarcia/graal/replacements-tutorial.html would this be the relevant documentation?

11:55 it's talking about stuff happening during compilation, which would mean no-clojure

11:56 jneen: well

11:56 it's also compiler infrastructure

11:56 justin_smith: jneen: you could likely define a transform that uses clojure via interop

11:56 jneen: so you could use calls to clojure to assist in the compilation

11:56 that is feasable

11:56 jneen: so like, graal is compiling other lang's code

11:56 justin_smith: right

11:57 and you want graal to use clojure in the process of generating other lang code

11:57 R0B_ROD: Any resources available focusing on Introductory programming with Clojure??

11:57 lazybot: R0B_ROD: Uh, no. Why would you even ask?

11:57 * R0B_ROD ponders on lazybot's smart ass

11:57 justin_smith: R0B_ROD: yeah, aphyr's clojure info is very introductory

11:57 https://aphyr.com/posts/301-clojure-from-the-ground-up-welcome

11:57 R0B_ROD: I have seen his site, not interesed.

11:57 justin_smith: haha

11:57 it's a good guide though

11:58 seangrove: $seen bbloom

11:58 lazybot: bbloom was last seen quittingQuit: Textual IRC Client: www.textualapp.com 5 days and 13 hours ago.

11:58 seangrove: He's gone, he's gone.

11:58 R0B_ROD: Thats ok I have seen the data but not compatible with his implementation and organizing of info.

11:58 .. but I am not ...

11:58 godd2: R0B_ROD Clojure for the Brave and True

11:59 R0B_ROD: godd2: Also aware but my poor a** is too broke to pay for information at the moment.

11:59 OK. I will continue my current workflow

11:59 {blake}: R0B_ROD: I, personally, did not find any of the introductory works to be sufficient.

11:59 godd2: R0B_ROD you can just read it online: http://www.braveclojure.com/getting-started/

12:00 {blake}: R0B_ROD: I went to Aphy, B&T, got some videos, listened to youtube lectures, bought everyone's book...

12:00 R0B_ROD: {blake}: Indeed I am agreeing but I am not a programmer just a computer enthusiast. I dont even have a specific domain of interest. Just trying to develop some kind of skill-set

12:01 godd2: Ah very nice! #Thanks!

12:01 {blake}: R0B_ROD: And I still had to ping-pong around between all of those, plus clojure koans, plus 4clojure, and develop some simple game logic.

12:02 R0B_ROD: On the plus side, as you get accustomed to the grammar, Clojure is not a world of secrets or assumptions.

12:02 justin_smith: yeah, clojure lacks magic in many respects, and things are generally explicit though concise

12:02 hiredman: /win 19

12:02 justin_smith: (one of my favorite things about it actually)

12:02 {blake}: R0B_ROD: Also, this chat is indispensible. =P

12:03 R0B_ROD: {blake}: You are the second to be very chatty with me. #!Thanks. First: justin_smith

12:03 {blake}: justin_smith: Me, too. So far every big sticking point I've had was easily resolved by digging into the code--and I've never had to dig deep, because there's generally not a lot of "deep".

12:04 R0B_ROD: {blake}: Thanks for your sequence. I do have the koans but not 4clojure. I will be here so we can share in the future as well.

12:04 {blake}: R0B_ROD: My pleasure. I'd have been in trouble without this group so if I can pay it forward, I will.

12:04 R0B_ROD: {blake}: Very nice attitude. I am glad you will pay it forward.

12:05 {blake}: R0B_ROD: Also, it's fun.

12:06 R0B_ROD: My experience is a little: Haskell, Racket, Python2, Perl, Linux Shell Scripts, basic C/x86_64 Assembly, Arch Linux config and install.

12:06 Played with classical FORTRAN just at the surface

12:07 {blake}: R0B_ROD: If you've got Haskell, Clojure should be easier for you than it was for me. I had studiously avoided functional programming (even in Smalltalk, which has quite a few HOFs).

12:07 ToxicFrog: Yeah, a lot of the clojure concepts should be familiar with that background.

12:08 R0B_ROD: BUT this is all at the syntactic and result level, the art of programming or better-said, the systematic methods of creating software is what I want to learn before learning a language

12:08 results as in building basic calculators or some very basic text manipulations

12:09 ToxicFrog: Fundamementally, that's something you learn by writing a lot of programs.

12:09 R0B_ROD: I enjoy the combination of Clojure so Im going to try and focus on developing my foundations and learn Clojure to solidify my findings.

12:10 ToxicFrog: Reading and debugging a lot of code is also a missed portion of learning fundamentals

12:11 ToxicFrog: R0B_ROD: I file that under "writing programs". You're going to be doing a lot of reading and debugging as part of that process.

12:11 justin_smith: good luck writing working programs without debugging or reading code!

12:11 ToxicFrog: Although I should probably have been more general: you become a better programmer by programming.

12:11 R0B_ROD: ToxicFrog: I dont believe that creation, design and implementation are an all-in-all for everyone. Im not ery creative but very tinkere/disassembler type.

12:11 benmoss: are these warnings something that should be fixed by the libraries maintainer? via (:refer-clojure :exclude [protocol?])?

12:11 https://gist.github.com/benmoss/19231a7f5d4b53e973e7

12:12 R0B_ROD: ToxicFrog: Yes I agree with you in your general statement. No doubt

12:12 justin_smith: benmoss: yeah

12:12 benmoss: that should be a very easy PR to do if you feel like giving back :)

12:12 R0B_ROD: ToxicFrog: I mean: I enjoy someone else telling me how to help instead of me creating something useful from scratch

12:12 benmoss: justin_smith: cool, i thought so, i just wanted to verify there wasn’t some reason they weren’t before going ahead and making the PR :)

12:13 ToxicFrog: R0B_ROD: yeah, that's fair. Which is part of why, on reflection, I think that "by programming" is the better formulation.

12:14 Since "programming" is a lot broader than "writing programs"

12:14 R0B_ROD: Indeed ToxicFrog ;) :D xD :P

12:14 Im just here guys... I dont have any other outlet to the outer-world

12:14 godd2: ToxicFrog here's a pretty good list of the things that programming encompasses (plus some more) http://plato.stanford.edu/entries/computer-science/

12:15 R0B_ROD: I dont have friends-in-flesh... Trying to tap into IRC and make bytecode-friends

12:15 ;>

12:17 benmoss: justin_smith: ah, i realize now my instinct was correct, these warnings are coming from installing Ultra yesterday (https://github.com/venantius/ultra) which has some stuff that adds fns to clojure.core, including `protocol?`

12:17 ToxicFrog: That sounds familiar. My wife and I are trying to rebuild our social lives after basically losing track of everyone we knew in meatspace.

12:17 benmoss: justin_smith: mentioned here https://github.com/venantius/ultra/wiki/Java

12:17 justin_smith: benmoss: oh, that's weird and kind of evil

12:18 benmoss: justin_smith: yeah makes me inclined to remove it

12:19 ToxicFrog: We still have IRC-friends, but sometimes you just want someone to help bake a cake and then snuggle with.

12:19 R0B_ROD: ToxicFrog: I just live in a town where there isnt real:down2earth folk. Its all superficial, 'oh-what-car-u-drive?', 'got $$$' type culture

12:19 justin_smith: benmoss: you know something about that project was setting off my spidey senses already, now that I am reminded which one it was

12:19 benmoss: "smells like rubby"

12:19 R0B_ROD: ToxicFrog: I hear you. I just got seperated from my wife because she just didnt want to snuggle.

12:20 ToxicFrog: Im trying so hard to build a skill-set so I can find work using computers and linux. :|

12:20 I have a feeling Clojure will help too!

12:21 devll: How to setup -Xss option for Clojure ?

12:21 justin_smith: devll: are you using lein?

12:21 devll: yes

12:21 justin_smith: :jvm-opts [ ... ]

12:21 devll: I am getting stackoverflow exceptions from a previously working code.

12:22 justin_smith: you may need the ^:replace metadata to override the defaults

12:22 ToxicFrog: R0B_ROD: erk. My condolences.

12:22 devll: justin_smith: thanks

12:22 justin_smith: devll: I know you need ^:replace to specify the -server option for example

12:22 ToxicFrog: I graduated, and then we moved, and then we had a baby, and that kind of nuked our social life -- we've basically got my family (hers lives hours away), my ex, and an old friend of hers from uni she just reconnected with, and that's it :/

12:25 devll: OK. thx

12:29 R0B_ROD: ToxicFrog: My condolences. Glad you graduated. Im a father too. I feel you on social life for a married young couple. Im 30 y/o

12:31 ToxicFrog: R0B_ROD: hah! I'm 29.

12:32 She's starting to make friends at the baby's swimming lessons, but I'm at work all day. And neither of us are really good at meeting new people.

12:33 ggherdov: ,(into {} '(("a" "b") ("c" "d")))

12:33 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Map$Entry>

12:33 justin_smith: ggherdov: it needs vectors

12:34 ggherdov: justin_smith: ah thanks

12:34 justin_smith: ,(into {} '(["a" "b"] ["c" "d"]))

12:34 clojurebot: {"a" "b", "c" "d"}

12:34 ggherdov: I see thanks

12:34 justin_smith: though that message mentioning String - that's messed up actually

12:34 R0B_ROD: ToxicFrog: Nice;>

12:34 justin_smith: it should have complained about list not string, right?

12:35 ggherdov: justin_smith: it got me very confused. I still am not sure what the error is about.

12:36 justin_smith: ,(into {} '((["a" 1] ["b" 2]] [["c" 3] ["d" 4]]))

12:36 clojurebot: #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: ]>

12:36 ggherdov: I'd have guessed that vectors and lists has interchangeable interfaces

12:36 justin_smith: ,(into {} '((["a" 1] ["b" 2]) (["c" 3] ["d" 4])))

12:36 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.util.Map$Entry>

12:36 justin_smith: wat

12:36 that's a bug in the error message

12:37 because vectors definitely can be cast to map$entry

12:37 ggherdov: justin_smith: what is a map$entry ? The key, the value or the key-value pair?

12:37 csd_: Can anyone suggest a library for mocking sockets?

12:38 justin_smith: ggherdov: key/value pair

12:38 ggherdov: ok

12:38 justin_smith: ,((juxt type identity) (first {:a 0}))

12:38 clojurebot: [clojure.lang.MapEntry [:a 0]]

12:38 justin_smith: they even print identical to vectors

12:38 ,((juxt type identity vector?) (first {:a 0}))

12:38 clojurebot: [clojure.lang.MapEntry [:a 0] true]

12:38 ggherdov: I see.

12:38 justin_smith: they even count as a vector

12:39 anyway, off to add a bug report on the tracker

12:39 mahinshaw: ,(into {} '([:a 1] [:b 2]))

12:39 * ggherdov learns about clojure.core/juxt

12:39 clojurebot: {:a 1, :b 2}

12:44 R0B_ROD: godd2: Hey I check the Clojure Brave and True site but I think thats more for quiche eaters.

12:45 godd2: R0B_ROD well I don't know what a quiche eater is supposed to be, other than someone who eats quiche, which I can't really see as an insult, so can you clarify?

12:47 R0B_ROD: godd2: Just a little humor. Quiche-eater is reffered to someone with sensitive programming requirements, Pascal programmers, or other "easy-structured" language. Its folk tradition in Unix culture. The Story of Mel < google

12:48 godd2: I've read the story of Mel. He was pretty hardcore though

12:48 R0B_ROD: godd2: Yup

12:49 godd2: I commented on the site of 'brave' and true, he remmoved it, lol. Constructive critisism

12:50 Oh well... in this age of free and bloated functionality there is nothing less I expect. The future is doomed

12:50 {blake}: R0B_ROD: Huh. By that def, I'm a quiche eater, but I didn't find Brave & True that helpful.

12:51 * R0B_ROD wishing he could rant in front of thousands of people about the f*kd nature of our current reality

12:51 godd2: R0B_ROD you can feel free to be pessimistic. In the future, I'll remember not to offer you any recommendations to try and help :)

12:51 R0B_ROD: {blake}: LOL

12:51 {blake}: Actually, I've been fretting over it for a while. I'd like to produce some really great beginner's stuff.

12:51 R0B_ROD: godd2: Nah man, I didnt mean it that way, chill

12:51 {blake}: Can I help?


12:52 {blake}: godd2: lol

12:52 noonian_: from the story of mel: “If a program can't rewrite its own code”, he asked, “what good is it?”

12:52 R0B_ROD: godd2: ugh, Im a bad parser

12:52 {blake}: R0B_ROD: Maybe some day. Writing good beginner's stuff is an odd balance of having mastery over the material with the memory of what it's like to not know anything.

12:53 godd2: R0B_ROD its okay, that's something computers are good at. I hear if you learn a LISPy language, you can make a parser easily. I wonder which one you could choose...

12:53 R0B_ROD: lol {blake}

12:53 {blake}: I'm usually pretty good at it, but it can be especially difficult when the thing you're doing changes your brain. =P

12:53 csd_: Can anyone suggest a library for mocking sockets or suggest how to test without one?

12:54 R0B_ROD: godd2: Not sure, too soon to tell. So much for me to learn

12:54 godd2: R0B_ROD ah then may I suggest that you hold your criticisms until you learn more

12:54 Glenjamin: csd_: midje has some stuff built-in, with-redefs is in core, there are libs on clojars called "bond" and "q" which do some stuff

12:54 oh

12:54 sockets

12:54 godd2: in that it would be in your best interest

12:55 Glenjamin: i didn't see that bit

12:55 cddr: Is there a name for the concept of tree which is a copy of another tree but with some nodes transformed or removed

12:55 csd_: yeah :-/

12:55 Glenjamin: ignore everything i just said

12:55 csd_: haha

12:55 Any alternatives?

12:57 R0B_ROD: godd2: To my memory I havent critizied anything. I suggested a web site an improvement.

12:57 godd2: That is an example of a criticism

12:57 I mean, do what you want, it was just a suggestion

12:58 word to the wise, if you will

12:58 R0B_ROD: Ok :)

12:58 * R0B_ROD lips are sealed

12:58 godd2: when in clojureland do as the clojurans do

12:58 clojans?

12:58 R0B_ROD: Oh I dont do as anyone

12:58 noonian_: i think its Clojurians or Clojurists

12:58 R0B_ROD: Sorry this might be the wrong plce for me

12:59 godd2: but definitely not Clojuristas

12:59 csd_: is there maybe someway to shadow ServerSocket so that particular method calls return exactly what I want?

12:59 @Glenjamin

12:59 godd2: Clojurinianists

12:59 uptown: clojet cases

13:00 justin_smith: csd_: sounds like a good case for making a proxy or reify

13:00 csd_: implementing the same interfaces ServerSocket does, with dummy method impls

13:01 csd_: i'll give that a shot

13:02 justin_smith: csd_: another option is to rewrite your code to use a protocol (which you extend ServerSocket for) and pass in the impl

13:02 so for the test you pass in the test impl

13:02 noonian_: thats my recomendation

13:03 csd_: sorry i don't understand that justin, can you explain a bit further

13:04 justin_smith: csd_: you would define a protocol that does all the things you need your ServerSocket to do, and then extend ServerSocket to that protocol

13:04 csd_: what's the advantage of that? seems like it would be easier to use reify?

13:04 justin_smith: then you define a record that extends that same protocol, with testing impls of all the protocol methods

13:04 csd_: if it is easier to use reify, that is your answer

13:04 protocols are helpful when you abstract a bit more from the concrete jvm class

13:05 csd_: i'm guessing. i don't have experience doing any of these things before

13:05 justin_smith: csd_: if your functionality that you want to wrap is just the core functionality of ServerSocket, I would just proxy ServerSocket and override the applicable methods, or reify the interfaces ServerSocket uses

13:06 csd_: ok

13:06 thanks

13:06 justin_smith: and then you have a small refactoring to pass in the impl rather than creating a ServerSocket every time

13:06 but that part should be straightforward

13:18 {blake}: So, if I'm using ring in my ns, but it isn't in my dependencies list, that means I'm using whatever version some other lib (compojure, say) is pulling in, yes?

13:18 justin_smith: {blake}: yeah, if you run "lein deps :tree" it will show you where ring is coming from

13:19 {blake}: justin_smith: Thanks! I had forgotten that!

13:19 (inc justin_smith)

13:19 lazybot: ⇒ 177

13:20 {blake}: And this is bad, because we end up with hidden, unspecified dependencies. Or could it be good in some cases?

13:22 justin_smith: {blake}: it's good form to explicitly depend on it if you use it directly

13:22 {blake}: justin_smith: I guess the "good" is if you don't rely on it directly you're not required to care.

13:24 pandeiro: is there anywhere that clojure's roadmap WRT to java version compatability is outined?

13:26 justin_smith: pandeiro: anything 1.5+ will work, there has been talk about raising that limit though

13:26 pandeiro: but I don't know that there is any concrete plan to upgrade the required version

13:26 pandeiro: justin_smith: is that documented anywhere, eg for clojure 1.7?

13:26 justin_smith: pandeiro: it should be somewhere on clojure.org or maybe even the main clojure project README

13:27 pandeiro: justin_smith: yep, http://clojure.org/getting_started

13:27 says 1.6

13:27 justin_smith: ho ho!

13:29 clgv: pandeiro: it probably stays with Java 6 for Clojure 1.7

13:30 Java 6 is required since Clojure 1.6

13:30 {blake}: I've been using Java 8.

13:30 clgv: that's ok ;)

13:31 {blake}: Appears to be!

13:33 hyPiRion: doc <

13:33 (doc <)

13:33 clojurebot: "([x] [x y] [x y & more]); Returns non-nil if nums are in monotonically increasing order, otherwise false."

13:33 hyPiRion: ^ what's up with `non-nil`? I thought it always would return true.

13:34 Glenjamin: ,(<)

13:34 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core/<>

13:34 justin_smith: ggherdov: I created a bug report on the Clojure jira for that issue http://dev.clojure.org/jira/browse/CLJ-1651

13:34 Glenjamin: ,(< 1)

13:34 clojurebot: true

13:34 Bronsa: hyPiRion: yeah doesn't look like it will return anything else

13:34 Glenjamin: But I guess it's allowed to in future.

13:34 justin_smith: Bronsa: did you see that? I found it a bit amusing.

13:35 Glenjamin: Or maybe did in the past?

13:36 Bronsa: justin_smith: I never understood that error message

13:36 justin_smith: Bronsa: "PersistentVector cannot be cast to Entry" ohh reeeealy???

13:36 lazybot: justin_smith: How could that be wrong?

13:37 hyPiRion: Glenjamin: yeah, but that would mean you cannot do (sort < [3 2 1]) for instance

13:37 Bronsa: (dec lazybot)

13:37 lazybot: ⇒ 36

13:38 Bronsa: ,((ancestors (class [])) java.util.Map$Entry) ;; justin_smith

13:38 clojurebot: nil

13:38 justin_smith: aha

13:38 {blake}: ancestors hould never return nil. Just turtles.

13:38 justin_smith: so it's technically true, though not helpful

13:39 🐢

13:39 Bronsa: justin_smith: I actually thought that PV implemented AMapEntry too

13:39 ,((ancestors (class (first {1 1})) java.util.Map$Entry)

13:39 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

13:39 Bronsa: ,((ancestors (class (first {1 1}))) java.util.Map$Entry)

13:39 clojurebot: java.util.Map$Entry

13:40 Bronsa: ,(first {1 1})

13:40 clojurebot: [1 1]

13:40 Bronsa: ^ I guess this is why it confused us both

13:40 ,(class (first {1 1}))

13:40 clojurebot: clojure.lang.MapEntry

13:40 justin_smith: so the issue is that if you pass in a vector, it can be specialized to a map entry

13:40 and a map entry is a vector

13:41 so really, it should complain that it can't be coerced to vector

13:41 Bronsa: I just accepted that conj on maps is weird

13:41 justin_smith: heh

13:41 Bronsa: an try not to use it

13:41 justin_smith: but into is so handy

13:41 hyPiRion: ,(let [f (juxt key val)] (-> {1 2} first f f))

13:41 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.util.Map$Entry>

13:41 Bronsa: assoc/merge for maps, conj/into for vectors

13:41 hyPiRion: ,(let [f (juxt key val)] (-> {1 2} first f))

13:41 clojurebot: [1 2]

13:42 Bronsa: justin_smith: I believe that if the PV enhancement proposed by ztellman gets into 1.8, we will be able to unify PV with MapEntry

13:43 justin_smith: cool

13:43 Bronsa: since we will have a concrete type for a 2-element vector

13:48 llasram: Huh. Clojure at one point had a FixNum class

13:49 hyPiRion: I was hoping software archaeology would reveal that the numeric comparison operators once returned the larger/smaller value on truth, but no -- that docstring is just wacko

13:50 gfredericks: what was FixNum? a wrapper around Long to mess with hash codes?

13:50 hyPiRion: (< 1 2) → :hi-there

13:52 llasram: gfredericks: https://github.com/clojure/clojure/blob/b58d5badd4ed397f0f6e9be306ac12311c7049d9/src/jvm/clojure/runtime/FixNum.java

13:52 gfredericks: `int` apparently

13:54 TimMc: hyPiRion: (< 1 2) → false ;; false is non-nil

13:54 hyPiRion: TimMc: hah, that's an even better example

13:54 justin_smith: (< 1 2) -> false "am I on crazy pills?"

13:55 hyPiRion: (inc TimMc)

13:55 lazybot: ⇒ 87

14:02 csd_: it doesn't look like reify will work after all. reify only works on java interfaces, and ServerSocket only has the interfaces Closeable and AutoCloseable, which don't help me

14:02 @ justin_smith

14:02 justin_smith: csd_: that's where proxy comes in

14:02 you can proxy ServerSocket itself

14:03 csd_: i see

14:03 justin_smith: also, failing that, this is where coding to a clojure protocol wins

14:03 csd_: whatever the outcome, learning a lot

14:04 justin_smith: csd_: the way clojure likes to do things, coding against interfaces and protocols, works out really nicely I think

14:05 csd_: do any of you use erc? very frequently the nick auto-completion doesn't acually end up in my submitted text, even though i see it before i hit return... very strange

14:05 protocols and interfaces are basically the same thing, just one is for java and the other for clojure, correct?

14:06 justin_smith: csd_: weird - I switched to irssi so I could leave irc logged in on my vps, but I never had that issue with erc

14:06 csd_: protocols are backed by an impl interface

14:06 but they define some extra stuff too

14:07 kind of like with defrecord defining a class, but giving you some stuff for free

14:14 cddr: I tried java 8 but ran into problems with the new date package. It may have been me being stupid though and I didn't have time to investigate much

14:18 justin_smith: cddr: I have had zero issues with java8

14:20 TimMc: Good, because Java 7 is apparently end of life.

14:20 No more public security patches (at least on Oracle side.)

14:21 hyPiRion: only protected ones.

14:21 justin_smith: hyPiRion: so you need to be in Larry Ellison's will to have any hope of a patch?

14:21 * justin_smith hides.

14:22 hyPiRion: justin_smith: you must just extend him.

14:22 justin_smith: haha

14:23 am I allowed to use the rack?

14:25 sveri: cddr: IIRC the new date package is taken from joda-time which is pretty awesome

14:37 cddr: Yeah it might have been a clojure lib trying to pull in joda-time and getting collisions.

14:37 csd_: proxy is giving me "method not found in class errors

14:39 shouldn't at least one of these work? https://www.refheap.com/96652

14:39 justin_smith: csd_: do your arg counts match?

14:39 Bronsa: csd_: proxy unlike reify/deftype doesn't require an explicit "this" arg

14:40 csd_: and ServerSocket/accept takes no args

14:41 csd_: you can't define new methods using proxy, reify or deftype, only override already existing ones

14:45 csd_: what should i do if i want to pass a ServerSocket into a function, and have it return an overridden (.getHostName (.getInetAddress socket))

14:46 getHostName is part of the InetAddress class, not ServerSocket

14:46 justin_smith: csd_: override (.getInetAddress socket) to return a reify / proxy that covers .getHostName

14:47 or, write a protocol that does (.getHostName (.getInetAddress socket)) for a socket, and returns a string for your test impl

14:47 csd_: but I'm creating the socket via (ServerSocket. port)-- how would the InetAddress get wrapped in?

14:48 oh i think i see what you're suggesting

14:48 proxy getInetAddress, and have the proxied version return the overriden function

14:48 justin_smith: .getInetAddress returns an InetAddress describing a port on localhost

14:48 right

14:49 csd_: is this a the point yet where it would be easier to write a protocol

14:49 justin_smith: yeah, that way you don't need to use reify or proxy, and you don't need to replicate deeper structure of types of methods

14:50 so I would say yes

14:50 csd_: ok

14:50 justin_smith: but the exercise of doing it with a proxy is worth it :)

14:50 and will be useful another time I am sure

15:00 sdegutis: What's an impeccable technique for taking a list and getting a map of all duplicated items like {item => times-found} where times-found is more than 1?

15:01 justin_smith: sdegutis: frequencies

15:01 wait, more than 1?

15:01 ,(frequencies [1 2 3 2 3 3 4])

15:01 clojurebot: {1 1, 2 2, 3 3, 4 1}

15:02 justin_smith: hmm, could be clearer ##(frequencies [:a :b :c :b :c :c :d])

15:02 lazybot: ⇒ {:a 1, :b 2, :c 3, :d 1}

15:02 justin_smith: I guess you can then filter it to remove 1

15:03 ,(into {} (remove #(= (val %) 1) (frequencies [:a :b :c :b :c :d])))

15:03 clojurebot: {:b 2, :c 2}

15:04 sdegutis: Well that is impeccable I suppose. But what about an immaculate method?

15:04 csd_: so proxy returns a new class. it seems like i can't use it as a constructor though. e.g. (def foo (proxy ... )); (foo. bar) isn't valid

15:05 justin_smith: csd_: (.newInstance (class foo))

15:05 hiredman: proxy turns an instance of the class

15:05 not a class

15:06 csd_: how do i tell it what the constructor params are?

15:06 hiredman: ,(doc proxy)

15:06 clojurebot: "([class-and-interfaces args & fs]); class-and-interfaces - a vector of class names args - a (possibly empty) vector of arguments to the superclass constructor. f => (name [params*] body) or (name ([params*] body) ([params+] body) ...) Expands to code which creates a instance of a proxy class that implements the named class/interface(s) by calling the supplied fns. A single class, if provided, mus...

15:06 justin_smith: csd_: why do you need to construct it?

15:06 why not just use the result of proxy directly?

15:06 csd_: i'm going to construct in my tests file the extended socket, and then pass that into my test functions

15:07 justin_smith: csd_: why not directly use the result of proxy? or wrap it in a function that returns the proxy if you must

15:07 I mean newInstance will work, but it seems odd

15:08 csd_: i misunderstood how to call proxy. it looks like I do (proxy [class & args] ...). Didn't realize the args followed the class name

15:08 hiredman: they don't

15:08 csd_: oh

15:09 gfredericks: (proxy [class & interfaces] [args] ...)

15:16 csd_: https://www.refheap.com/96659

15:17 Anything noticeably wrong?

15:18 sdegutis: Thanks for your help, dynamic typers.

15:18 Especially justin_smith.

15:19 amalloy: csd_: that error message is saying that the no-arg constructor for InetAddress is not public

15:20 and indeed there are no public constructors at all

15:20 so you can't subclass it in any way i can think of

15:20 csd_: it's a method of ServersSocket, which is public http://docs.oracle.com/javase/7/docs/api/java/net/ServerSocket.html#getInetAddress()

15:21 amalloy: csd_: the objection is to the proxy of InetAddress, not ServerSocket

15:21 you simply cannot proxy that class

15:21 because you cannot subclass it

15:22 you would get the same error from just: ##(proxy [java.net.InetAddress] [] (getHostName [] (println "foo")))

15:22 lazybot: java.lang.ClassCastException: clojure.lang.Var$Unbound cannot be cast to clojure.lang.DynamicClassLoader

15:22 amalloy: well, okay, except some lazybot weirdness i guess

15:22 ie, reading the docs for serversocket will not help you at all, because your problem is not in serversocket

15:22 csd_: I want to override InetAdress.getHostName given a ServerSocket. Is my only option left to try extending via a protocol or is that ruled out too now?

15:23 reason for this is I'm trying to find a way to mock sockets for testing

15:23 amalloy: csd_: no, just return something which isn't a proxy

15:23 use the static methods in InetAddress

15:24 csd_: how would you mock sockets personally?

15:25 amalloy: i don't really understand what you're trying to do. i don't know why i would mock a socket at all. just create a real socket bound to localhost and talk to it

15:27 csd_: i think that's the route i'll take

15:44 {blake}: Options for using MS's jdbc interface for MS-SQL? I can set up a repository, do stuff with Maven...but can't I also just put the JAR somewhere on my CLASSPATH? (I mean, I guess I can't 'cause I tried that, but maybe I'm just doing it wrong.)

15:44 lein can't find the JAR when I put it in /targets.

15:45 justin_smith: {blake}: mvn install

15:45 sdegutis: Do most of you prefer to use core.typed in most of your code?

15:45 Or do you prefer the freedom and danger and excitement of dynamic typing?

15:46 ToxicFrog: sdegutis: I would love to use core.typed in most of my code, but historically I've had issues with it choking on things like command line parsers.

15:46 At that point I spend more time fighting the type checker than I gain in up-front bug detection, so I shelve it for another half year.

15:47 {blake}: sdegutis: "I’m not against types, but I don’t know of any type systems that aren’t a complete pain, so I still like dynamic typing."

15:47 bodie_: this feels like a dumb question, but how would you write a function that does nothing but eval to the same value no matter what?

15:47 justin_smith: bodie_: constantly

15:47 bodie_: ok. thanks

15:47 {blake}: justin_smith: Wow...can I kiss you if that works? Or, send a designated hot female (or male, your choice) to kiss you?

15:47 sdegutis: {blake}: which ones have you tried?

15:47 justin_smith: ,(map (constantly 42) [:a 2 "hello" nil []])

15:47 clojurebot: (42 42 42 42 42)

15:48 justin_smith: {blake}: no need, but it will work

15:48 sdegutis: {blake}: I'm curious especially if you've tried Haskell and found it to be problemsome, since I'm looking into Haskell myself.

15:48 {blake}: sdegutis: Clojure is my first functional language.

15:49 sdegutis: But I've coded in Basic, Pascal, PL/I, C, C++, Java...that may be it for statically typed systems. Wait, does Javascript count? I sorta don't think so. Actionscript is statically typed, and I do that.

15:50 bosky101: does anyone know of a http client that prints that stops just short of sending data over the socket, and instead returns the binary data . eg “GET / HTTP/1.1\r\n..."

15:50 justin_smith: {blake}: hindely-milner (as ml and haskell use) is a completely different experience compared to most static typing

15:50 {blake}: sdegutis: Then there's Smalltalk, PHP, Perl, Python and Ruby. I feel a little uneasy in Ruby sometimes, but I actually haven't had any issues with typing.

15:51 justin_smith: {blake}: hindley-milner type systems don't require type annotations at all, as long as the types are unambigous based on binding or usage

15:51 amalloy: bosky101: just use a real http client, and an http server on your own machine that prints out what it gets, or wahtever

15:51 {blake}: justin_smith: I'll check it out. The more I don't use typing, the less I miss it. And, again, big Pascal guy here. (And PL/I which would happily convert anything to anything with the gentlest of warnings about it. Then you'd get killed on your CPU-cycles bill.)

15:52 justin_smith: Wait, does that count, then? =P

15:52 justin_smith: {blake}: no, the typing is quite strict, with few implicit conversions (ml won't even force into to float)

15:52 tomjack: I think they just don't require type annotations at all, unless the type inferred is not the type you want?

15:53 justin_smith: you just don't need to declare the type if the logic engine can prove what type the binding has to be

15:53 tbaldridge: {blake}: I used to do some work on a Pascal/Delphi system. It's a crime C won mindshare over Pascal. it's really a wonderful language.

15:53 {blake}: justin_smith: But strict <> static. Smalltalk is strict.

15:53 justin_smith: {blake}: strict and static

15:53 {blake}: but does not need explicit declarations

15:53 {blake}: tbaldridge: It is, though Delphi has become more and more Java-C#-esque.

15:53 sdegutis: {blake}: wow those are some unpleasant languages you named

15:54 tomjack: I prefer something which generally requires type annotations because inference is undecidable, but where annotations can be omitted whenever the system happens to be able to infer the type

15:54 {blake}: justin_smith: Well, so...let's say it's inferred one thing from use, then you do something that makes it infer something else...Well, I guess that's still static, but yeah, that'd be a horse of a different color.

15:54 sdegutis: tomjack: like Haskell?

15:54 tomjack: no, like Agda

15:54 sdegutis: Oh cool.

15:55 justin_smith: {blake}: if there is no unification of the inference possible (because it would need to be two different types, or no usage makes the type clear) you get a compilation error

15:55 {blake}: but in practice, almost always, usage makes the type clear

15:55 tomjack: e.g. omitting annotations on most defns is a non-goal for me, because the first thing I probably want to do when writing a defn is to specify the type

15:56 otherwise, how will I know that the implementation is correct? :)

15:56 {blake}: sdegutis: I liked all of them except C and C++. Perl makes me woozy, but for what it is and what it does, it's tough to beat.

15:56 I forgot REXX! No typing at all in REXX. Everything is a string. =P

15:56 OOREXX is ...well, it's just ... a thing to be experienced.

15:57 Also, while I rather enjoy PHP, working in it usually means unravelling some awful framework.

15:57 justin_smith: OOREXX is the sound I make when a language turns my stomach

15:57 {blake}: (I consider it a dangerous toy, sorta like Basic.)

15:58 justin_smith: That's what happens on an all-string diet.

15:58 justin_smith: lol

15:58 {blake}: REXX's big thing was the principle of least surprise. That was its guiding consideration. It is the most surprising language I've ever worked with.

15:59 Mis-spell "DOG" that you're using as an integer counter as "DOGG" and add one to it...I think you get "DOGG1"?

16:00 Awesome batch language, tho'.

16:04 I guess assembler is the ultimate dynamically typed language.

16:05 justin_smith: {blake}: untyped, which is different

16:05 in dynamic typing, eventually, at runtime, you check the type

16:05 untyped is like, OK, it's bytes, that checks out, chuck 'em in

16:06 because everything is just some quantity of bytes

16:06 {blake}: justin_smith: And, really, isn't that always true? (True, but not helpful, as you noted earlier.)

16:07 justin_smith: {blake}: types are of course the fiction of some language. But it's a fiction that helps us ensure correctness.

16:07 it's a constraint that isn't intrinsic to the machine, but in practice makes programming so much easier...

16:12 {blake}: Back to Maven install...is there a maven repository for each lein project? Is that the deal? So if I install a JAR with maven install for project A, it must be done again for Maven B?

16:12 er project B?

16:12 justin_smith: {blake}: no, there is one repo per user

16:12 so unless you have a different user for each project, it only needs to be installed once

16:23 {blake}: justin_smith: So I think I've installed it. mvn reports success. Do I need to specify a repository in project clj or install with lein or...?

16:24 justin_smith: {blake}: if mvn installed it, you require it like you would any other lib in project.clj

16:24 [group/dep-name "version"]

16:24 s/require/depend on it/

16:38 {blake}: So if it's not working for me, I probably have the name wrong somehow.

16:38 justin_smith: {blake}: what coords are you trying to use?

16:39 {blake}: justin_smith: Well, I installed it as "com.microsoft.sqlserver/sqljdbc4".

16:40 (That's the group ID/artifact ID.

16:40 justin_smith: OK

16:40 and what does the entry in project.clj look like?

16:40 {blake}: Version 4.

16:40 justin_smith: ?

16:40 {blake}: [com.microsoft.sqlserver/sqljdbc4 "4.0"]

16:41 The path is \.m2\repository\com\microsoft\sqlserver\sqljdbc4\4.0\sqljdbc4-4.0.jar

16:41 justin_smith: that all looks right

16:42 and when maven installed it, did it also install a pom?

16:42 {blake}: Yes. Same path, just .pom

16:43 Wait, I'm describing this wrong.

16:44 I apologize. My lein deps is fine. It's showing up in the tree.

16:44 I just can't seem to actually use it.

16:44 justin_smith: {blake}: recall that the object package is not always (or even usually?) the same as the package coords

16:45 how are you trying to access the classes in the jar?

16:45 {blake}: justin_smith: I was trying to require it.

16:45 justin_smith: {blake}: you can only require clojure code

16:45 {blake}: And I just don't need to do that. It just has to be there for clojure.java.jdbc.

16:45 Right. Dumb.

16:46 It's installed. Thanks.

16:46 justin_smith: glad you got it sorted out

16:46 {blake}: I'm allergic to ODBC.

16:49 So...I can only require Clojure code...but I can import whatever?

16:50 justin_smith: {blake}: right

16:50 and the jvm autoloads things from the classpath as they are accessed

16:50 import is just a syntactic convenience

16:50 {blake}: justin_smith: For?

16:51 Manually loading stuff?

16:51 justin_smith: for not having to type out the full package name

17:02 gfredericks: ,["symbol" 'keyword :string]

17:02 clojurebot: ["symbol" keyword :string]

17:03 justin_smith: gfredericks: that's like that test where the words for the colors are written in other colors

17:03 seangrove: justin_smith: I was thinking the same thing

17:03 justin_smith: https://faculty.washington.edu/chudler/words.html

17:04 "the stroop effect"

17:06 gfredericks: ,[(atom "ref") (ref "agent") (agent "atom")]

17:06 clojurebot: [#<Atom@622f497c: "ref"> #<Ref@5fbc8330: "agent"> #<Agent@ce82bd7: "atom">]

17:06 gfredericks: oh even better

17:06 ,[(atom ref) (ref agent) (agent atom)]

17:06 clojurebot: [#<Atom@2718561f: #<core$ref clojure.core$ref@9e0e83d>> #<Ref@caf01dc: #<core$agent clojure.core$agent@66bfb2c5>> #<Agent@3371d836: #<core$atom clojure.core$atom@5d111be2>>]

17:06 justin_smith: and now I am thinking of stroopwafels.... mmmmm stroopwafels

17:06 gfredericks: ,(atom (ref (agent atom)))

17:06 clojurebot: #<Atom@45ba6928: #<Ref@514de4db: #<Agent@50ec0f90: #<core$atom clojure.core$atom@5d111be2>>>>

17:08 gfredericks: ^ concurrency protip

17:08 amalloy: gfredericks: ##(map #(% %2) (partition 2 1 [atom ref agent atom]))

17:08 lazybot: java.lang.SecurityException: You tripped the alarm! agent is bad!

17:09 justin_smith: gfredericks: I'd like to see a single swap! call that rearranges all those contents (maybe changes their nesting)

17:09 maybe throw a delay or a promise in there too

17:10 gfredericks: ,(->> [atom ref agent delay future] (rand-nth) (fn []) (repeatedly 10) (reduce #(%2 %1) 42))

17:10 clojurebot: #<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/delay, compiling:(NO_SOURCE_PATH:0:0)>

17:10 gfredericks: aw snapchat

17:10 ,(->> [atom ref agent] (rand-nth) (fn []) (repeatedly 10) (reduce #(%2 %1) 42))

17:10 clojurebot: #<Ref@4531bbc1: #<Agent@441d9f64: #<Agent@74cb812b: #<Agent@5c8d69f4: #<Agent@482741a4: #<Agent@9469afe: #<Agent@7a699e73: #<Ref@2c21cece: #<Ref@5f904d04: #<Ref@7ab0729f: 42>>>>>>>>>>

17:10 justin_smith: it's like a rat-king of concurrency containers

17:11 gfredericks: and then you mutate the bottom one to contain the top one

17:11 TimMc: &(let [a (atom nil)] (reset! a a) a)

17:11 justin_smith: gfredericks: or put a promise at the very bottom, and deliver the top one to it

17:11 lazybot: java.lang.StackOverflowError

17:11 seangrove: ,(let [b (atom nil) a (atom (ref (agent b)))] (reset! b a) (loop [v a c 10] (recur (deref v) (dec c))) :unprintable)

17:11 clojurebot: Execution Timed Out

17:12 seangrove: ,(let [b (atom nil) a (atom (ref (agent b)))] (reset! b a) (loop [v a c 10] (when (pos? c) (recur (deref v) (dec c)))) :unprintable)

17:12 clojurebot: :unprintable

17:12 seangrove: icanclojurez

17:19 slipset: what would be the idiomatic way to interupt a go-loop in a repl?

17:20 justin_smith: slipset: one option is to make a "poison pill" channel that askes the loop to stop

17:21 slipset: justin_smith: thanks, I've used an atom, like this:

17:21 (go-loop []

17:21 (handle-output cfg (<! messages))

17:21 (when @continue

17:21 (recur)))

17:22 But it would be nice to be able to kill the thing without restarting the repl

17:22 justin_smith: slipset: here's a poison channel example from danneu http://www.reddit.com/r/Clojure/comments/2ka3na/how_do_you_organize_your_coreasync_code/cljqzwb

17:24 slipset: justin_smith: thanks for the link, very nice approach

17:30 justin_smith: in http://www.reddit.com/r/Clojure/comments/2ka3na/how_do_you_organize_your_coreasync_code/

17:30 it is mentioned that

17:31 (go-loop [m (<! messages)]

17:31 (handle-output cfg m)

17:31 (recur (<! messages)))

17:32 will terminate once messages closes

17:33 but I can't read that out of the docs for neither go-loop, loop nor recur

17:33 ~loop

17:33 clojurebot: loop is https://www.refheap.com/90332

17:35 slipset: crap, my bad, didn't read the whole code

17:35 he had a when in there.

17:35 (go-loop [v (<! in)] (when v (println v) (recur (<! in)))

17:38 tomjack: justin_smith: are the natural numbers fictional? :)

17:39 xyz_: Hello, using clj-time/clj-time, how do I import DateTime ? I have a check like that : (condp = x DateTime (...)) and I (:require [clj-time.core :as t] [clj-time.format :as f])

17:40 justin_smith: tomjack: of course, they are a mental construction

17:40 TimMc: xyz_: To refer to DateTime without the full package prefix, you need to :import it.

17:40 This is just like in Java -- "import" is an unfortunate term.

17:41 slipset: xyz_: (:import [java.net URLEncoder])

17:41 xyz_: TimMc: I see. And it is in core then I guess? so I should use t/DateTime ?

17:41 TimMc: so this would be like (:import (org.joda.time DateTime))

17:42 xyz_: TimMc: Oh ok. Thank you!

17:42 slipset: TimMc: but with the square breackets, yes?

17:42 s/breackets/brackets/

17:42 TimMc: I use lists instead of vectors there. I think it actually specifies that but will accept either.

17:43 xyz_: The foo.bar/baz syntax is for vars, which are a Clojure thing. DateTime is a class. While it could have been defined by something in clj-time.core, it isn't a var.

17:43 justin_smith: (doc import)

17:43 clojurebot: "([& import-symbols-or-lists]); import-list => (package-symbol class-name-symbols*) For each name in class-name-symbols, adds a mapping from name to the class named by package.name to the current namespace. Use :import in the ns macro in preference to calling this directly."

17:44 TimMc: (In this case it is defined by joda, but to the same effect.)

17:44 justin_smith: It says list, so I use lists. Also, the first element is distinguished. :-)

17:44 justin_smith: yes, just checking what the doc actually said

17:45 xyz_: TimMc: ok this clears the fog a bit now. And to import the joda jar? Is it in leiningen ? (I've only imported clojars)

17:45 justin_smith: xyz_: you don't import jars

17:46 and import doesn't open things or make them accessible, it just makes it syntactically simpler to refer to them

17:46 the fact that the thing is on the classpath (as lein sets it up) is what makes the class available

17:46 TimMc: xyz_: Both joda and clj-time are jars. Clojars is a repository of jars. leiningen is a build tool that (among other things) pulls down jars from repositories.

17:47 More correctly, clj-time is an *artifact* -- a specification of dependencies along with an actual jar. Since it specifies joda as a dependency, when you ask leiningen to get clj-time, it also fetches joda and makes it available to you.

17:48 xyz_: timMc / justin_smith: not sure I get it yet : how will it find org.joda.time ?

17:48 justin_smith: xyz_: because it is in the classpath

17:48 xyz_: timMc / justin_smith: shoudl I look for importing from maven with lainingen ?

17:48 sobel: hi, i have a question about use of loop/recur. i'll be parsing a quasi-CSV file that has variable record types and some light rules about nesting. i thought i would just pass parse state as the loop variables. is that generally the worst use of memory or what?

17:48 justin_smith: it is in the classpath because lein set up your classpath, and downloaded it if it was not on your machine yet

17:49 xyz_: import doesn't make the class accessible, it's just a shortcut for referring to the class. The classpath makes the jar (and its classes) available.

17:49 xyz_: TimMc: ok that makes sense.

17:50 justin_smith: sobel: passing the object to the next loop doesn't use any more memory than any other way of leaving it accessible would

17:50 xyz_: justin_smith: I get it now thank you. And now, if I wanted to re-export DateTime from a namespace so that it becomes available, how would I do that? (:import [org.joda.time DateTime]) (def DateTime DateTime) doesn't work

17:50 justin_smith: sobel: clojure does very little copying, because most things we use are typically immutable anyway

17:51 xyz_: that's not how it works. If DateTime is on the classpath, any namespace can use it.

17:51 xyz_: why would you def?

17:52 def creates vars, DateTime is a class.

17:52 xyz_: justin_smith: yes but the second namespace has to import it also ? Sorry if I'm unclear I can re-explain just say so.

17:52 sobel: justin_smith: so i don't have to worry about it behaving like a real stack, which would grow proportionally with the loop count

17:52 justin_smith: xyz_: namespaces don't contain classes, they contain vars

17:52 xyz_: packages contain classes

17:52 sobel: no, there is no stack to loop

17:52 TimMc: xyz_: You specify [clj-time/clj-time "1.2.3"] or whatever in your project.clj. Leiningen asks Clojars (and other repos) "do you have that"? One says "yes, here is the jar for it and here's what it depends on". Leiningen continues to download dependencies until they're all in your ~/.m2 directory. Then when you start your program, all those jar files are included on the classpath. Any classes in those jars can simply be refe

17:52 sobel: justin_smith: thx

17:52 tomjack: justin_smith: I think the universe needs _at least_ primitive recursion to function, whether there are minds in the universe or not :P. I don't think I had noticed this ontological perspective on the 'church vs curry types' distinction before... thanks.

17:52 amalloy: sobel: loop/recur uses jump instructions, not call

17:53 xyz_: TimMc / justin_smith: thank you for your help !

17:53 TimMc: xyz_: That part is basically identical to how Maven works with Java programs.

17:54 justin_smith: tomjack: sure, but the natural numbers don't need to exist as a reified thing, and as a description of our reality, they need not obey our mathematical axioms regarding the natural numbers

17:54 tomjack: we can find the mapping from our mathematics to how things in the world work useful, of course

17:54 sobel: ok, probably going to write an amazingly elegant clojure statement to do some file parsing then recode the whole thing in java for realsies (deployment) because i don't (yet) work in a clojure shop

17:54 justin_smith: but it's a model imho

17:54 xyz_: TimMc: unfortunately I did some java quite some time ago, and never used Maven... but I get the idea (similar to npm in node). Thank you!

17:55 justin_smith: xyz_: the namespaces with vars vs. packages with classes thing is a tricky one

17:55 xyz_: but it's better than the situation would be if we just used packages / classes for everything I think

17:58 xyz_: justin_smith: I trust it is :) I was confused indeed.

18:15 TimMc: xyz_: Better for now not to think too much about how vars and namespaces interact with classes and packages. The one interaction you need to know of is that namespaces *can* define classes, so you'll occasionally need to :require a namespace before you can use the classes it defines (by any name.)

18:19 xyz_: TimMc: I'll probably have to take some time to play with it before understanding that, so your simplification is welcome

18:23 TimMc: xyz_: WHen you :require a namespace you are actually causing it to be loaded, compiled, and made available for use (if it hasn't been already.) That includes side-effects like defining classes. :-)

19:28 arohner: I'm getting "Could not find artifact net.mikera:mikera-pom:pom:0.4.0 in clojars.org' when I add [net.mikera/core.matrix "0.32.1"]

19:29 and AFAICT, I haven't modified my :repositories settings

19:29 and it looks like that pom is in mvn central

19:30 aha, it says it couldn't find it in clojars

19:30 but that version isn't in clojars

19:31 0.0.4 is the latest in clojars, 0.4.0 is the latest in mvn

19:31 amalloy: well, does it eventually find it in maven central?

19:31 arohner: amalloy: no, it errors out with a big stacktrace

19:31 amalloy: honestly though i don't understand how pom-only artifacts work, or parent poms

19:39 arohner: sigh. replacing my :repositories order fixed it

19:40 this looks like a maven bug, because there are old net-mikera/mikera-pom versions on clojars, but not the version I asked for

20:09 andyf: justin_smith: Which version of Eastwood are you using? Version 0.2.1 has some code where I tried to eliminate incorrect arity warnings specifically for clojure.java.jdbc/insert!

20:13 justin_smith: andyf: oh, my version is 0.1.5, that must be ancient by now

20:13 thanks

20:13 andyf: version 0.2.0 and earlier do have known issues with incorrect warnings there. If you see them with 0.2.1 I would appreciate if you could file an issue with whatever details you can provide

20:13 Only 4 months or so

20:14 justin_smith: andyf: that fixed it, thanks!

20:14 (inc andyf)

20:14 lazybot: ⇒ 25

20:14 justin_smith: (inc eastwood)

20:14 lazybot: ⇒ 8

20:15 andyf: Cool

20:19 xyz_: Hello, I'd like to get some help on my merge/validate maps code. I made it work for simple nested maps, but it fails in the case of an array as a value inside the map. I'm not sure how I can attack the problem yet. Any ideas? I can post the full code if needed.

20:19 justin_smith: xyz_: for vectors, get-in / update-in can use a numeric index

20:20 ,(get-in {:a [:b {:c 0} :d]} [:a 1 :c])

20:20 clojurebot: 0

20:20 justin_smith: xyz_: unless you really mean arrays - not sure if it works with those

20:21 xyz_: justin_smith: good to know. I'm not sure how I can use that though. I used the flatten-map idea to list all the keys, so I should modify it ?

20:22 justin_smith: xyz_: you can update your flattened-map to descend to each numeric index of the vector separately

20:22 xyz_: I mean things like {:a [{:b "b" :c "c"}]}

20:22 justin_smith: xyz_: ##(get-in {:a [{:b "b" :c "c"}]} [:a 0 :c])

20:22 lazybot: ⇒ "c"

20:23 xyz_: justin_smith: to be honest I don't quite get the code yet. I took it from amalloy's answer there http://stackoverflow.com/questions/21768802/how-can-i-get-the-nested-keys-of-a-map-in-clojure/21769786#21769786

20:24 justin_smith: I'll experiment with the get-in / update-in and numeric indexes then (does it work for assoc-in too? I'm using that right now), and then try to modiy the fletten function.

20:24 justin_smith: xyz_: you would change the (if (map? m) ...) to a (cond (vector? m) ... (map? m) ...) and in the vector case you would iterate descending to each numeric index

20:24 xyz_: yes, assoc-in should also follow the numeric indexes

20:25 xyz_: justin_smith: thank you for the tip ^^ I'll probably be back again then :)

20:26 justin_smith: xyz_: another option, if you know the schema statically, is to replace [a b c] with {0 a 1 b 2 c}, which would generate the right keys in the output vec to work with get-in / update-in / assoc-in

20:28 TEttinger: ,(zipmap [:a :b :c] (range))

20:28 clojurebot: {:c 2, :b 1, :a 0}

20:28 justin_smith: TEttinger: opposite order, but yeah, great point

20:28 TEttinger: ,(zipmap (range) [:a :b :c])

20:28 clojurebot: {2 :c, 1 :b, 0 :a}

20:28 TEttinger: yeah just realized

20:28 xyz_: justin_smith: the schema is a parameter, so I guess it's not static ?

20:29 justin_smith: xyz_: in fact, you could just update the code you have now to do what TEttinger just did if you hit a vector, and then treat it the same way you would a map

20:29 TEttinger: yup

20:29 justin_smith: hrm

20:29 ,(keys [:a :b :c])

20:29 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.util.Map$Entry>

20:29 justin_smith: aww, shucks :)

20:30 TEttinger: ,(sequential? {:a 1})

20:30 xyz_: TEttinger / justin_smith: I really appreciate the help thank you! I'll try that first

20:30 clojurebot: false

20:30 TEttinger: ,(sequential? [:a :b])

20:31 clojurebot: true

20:31 TEttinger: ,(zipmap (range) '(:a :b :c))

20:31 clojurebot: {2 :c, 1 :b, 0 :a}

20:31 TEttinger: ,(sequential? '(:a :b :c))

20:31 clojurebot: true

20:31 TEttinger: good

20:32 I'm not sure if there's a better test of "collection that isn't a map" here

20:33 justin_smith: ,(map (every-pred (complement map?) coll?) [[] () #{}])

20:33 clojurebot: (true true true)

20:33 metellus: anything wrong with (not (map? ..

20:34 justin_smith: TEttinger: (every-pred (complement map?) coll?) catches one coll yours does not

20:34 (of the most common sorts)

21:10 tcrayford____: is there a way to specify multiple type tags on a local?

21:10 e.g. I wanna say "this type is both clojure.lang.Counted and clojure.lang.IMeta", without two locals or involving reflection on either

21:21 TEttinger: tcrayford____: do you mean type hints? you could probably make an interface that implements both? I'm not sure what the way to do this is

21:21 I'm not sure if Counted is an interface or class, tbh

21:27 tcrayford____: TEttinger: turns out you can just do (let [^clojure.lang.Counter ^clojure.lang.IMeta a thingy] …)

21:27 I think anyway

21:27 TEttinger: woah nice

21:27 tcrayford____: nope

21:27 maybe not

21:27 haha

21:27 it compiles

21:27 but it doesn't work ;)

21:28 lang.Counted is an interface ;)

21:28 TEttinger: ,(let [^clojure.lang.Counted c [1]] (meta c))

21:28 clojurebot: nil

21:35 turbofail: ,(meta '^clojure.lang.Counted c)

21:35 clojurebot: {:tag clojure.lang.Counted}

21:36 turbofail: anyway the proper thing to do is not have to do that at all

21:36 but instead define separate functions that call the methods that you care about

21:36 each with their own relevant type hint

21:38 and then hope those functions get inlined by the JVM

21:39 but in practice as long as you're not hitting reflection, you're probably in decent shape performance-wise even with the function calls

21:41 tcrayford____: turbofail: this is for *extremely* performance sensitive code, and I know what I'm doing (mostly)

21:41 (in this case: trying to eliminate the conditional inside clojure.core/meta in clj-tuple's calling of it)

21:42 though I suspect the JIT's prolly ahead of me here

21:42 (on the other hand: http://cl.ly/image/2Z1G2f0e3d2A)

21:53 TimMc: tcrayford____: Yeah, multiple ^foo.Bar will just overwrite each other.

22:26 ambrosebs: ,(= (Boolean. false) false)

22:26 clojurebot: true

22:26 ambrosebs: ,(if (Boolean. false) 1 2)

22:26 clojurebot: 1

22:27 ambrosebs: ,(if (first [false]) 1 2)

22:27 clojurebot: 2

22:27 justin_smith: that's some weird ass shit

22:27 ambrosebs: ,(if (first [(Boolean. false)]) 1 2)

22:27 clojurebot: 1

22:27 ambrosebs: So my question is, does `false` get boxed once it gets inserted into a vector?

22:28 justin_smith: wait, there is such thing as unboxed false?

22:28 ambrosebs: I'm highly ignorant here

22:28 tomjack: Boolean/FALSE

22:28 Boolean. is a nono in clojure

22:29 ambrosebs: is Boolean/FALSE an object?

22:29 tomjack: clojure pretends it doesn't exist to make the non-insane case have better perf

22:29 right

22:29 justin_smith: http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html yeah, looks like boolean can actually be unboxed, TIL

22:29 ambrosebs: ah so the primitive boolean is something different?

22:30 justin_smith: yeah, the "true false" has only one possible instance

22:30 and if you make new falses, they are not actually truly false

22:30 in fact they are instead falsely true!

22:30 ambrosebs: so I get this right, Boolean/FALSE is a boxed primitive false?

22:31 justin_smith: ,(get {Boolean/FALSE 42} false)

22:31 clojurebot: 42

22:32 justin_smith: that either auto-boxed, or established that Boolean/FALSE is boxed

22:32 ,Boolean/FALSE

22:32 clojurebot: false

22:32 tomjack: `public static Boolean FALSE = new Boolean(false)`

22:32 er, final too

22:32 ambrosebs: oh I see.

22:33 tomjack: (with a `private final boolean value;`)

22:33 ambrosebs: I guess clojure uses pointer equality to test against FALSE

22:33 tomjack: clojure wants (identical? FALSE x) though

22:33 yeah

22:34 ambrosebs: when we type (Boolean. false), is that a nested boxed boolean anyway?

22:34 ,(= Long/NaN)

22:34 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to find static field: NaN in class java.lang.Long, compiling:(NO_SOURCE_PATH:0:0)>

22:34 justin_smith: ambrosebs: do you want Double/NaN ?

22:35 ,(= Double/NaN)

22:35 clojurebot: true

22:35 ambrosebs: thx :)

22:35 for a twitter snark

22:35 justin_smith: ,(get {Double/NaN 42} Double/NaN)

22:35 clojurebot: nil

22:35 justin_smith: haha

22:36 ambrosebs: ,(= Double/NaN Double/NaN)

22:36 clojurebot: false

22:36 ambrosebs: never gets old

22:44 danielszmulewicz: Is there an idiom to write a function that does x if its argument is a map, and does the same x for each map when the argument is a sequence of maps?

22:44 tomjack: no

23:17 gfredericks: this bytecode is super weird

23:18 I just compiled (defn foo [x] (def bar x))

23:18 justin_smith: if someone had said "someone on #clojure discovered something super weird" I would have put a $100 bet on "gfredericks", no hints needed.

23:18 gfredericks: and the bytecode creates a map in the static initializer

23:18 an IPersistentMap

23:18 justin_smith: woah

23:19 gfredericks: and stores it in a static field for good deffings later

23:19 this is all normal

23:19 justin_smith: what does the map do?

23:19 gfredericks: it's got the metadata for the def

23:19 line number and such

23:19 justin_smith: ahh, of course

23:19 gfredericks: but

23:19 the type of the static field is........

23:19 clojure.lang.AFunction

23:20 then at runtime it pulls the map out of that static field and checkcasts it back to a persistent map

23:20 O_O

23:20 afaik there's nothing that is both an IPersistentMap an an AFunction

23:20 so I believe this bytecode is impossible

23:20 (it checkcasts it as AFunction on the way in as well)

23:21 justin_smith: this isn't related to creating the var bar?

23:21 gfredericks: the var itself is created in the static initializer

23:21 (not at runtime)

23:22 justin_smith: oh, right

23:22 TEttinger: what is AFunction? different how from IFn?

23:22 gfredericks: it's a class, not an interface

23:22 AFunction is an IFn

23:23 justin_smith: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/AFunction.java

23:23 gfredericks: extends AFn

23:23 gfredericks: sure

23:23 justin_smith: implements Fn

23:23 gfredericks: AFn implements IFn though so by extension...

23:24 justin_smith: well it's an abstract class, so technically does it implement anything? not sure of those distinctions

23:24 gfredericks: yes

23:24 justin_smith: OK

23:24 gfredericks: I mean it's not instantiable

23:24 but if you have something that is an AFn then it is definitely those other things as well

23:25 anyhow we can at least agree that ##(instance? clojure.lang.AFunction (hash-map 3 4))

23:25 lazybot: ⇒ false

23:25 TEttinger: that's extremely odd, yeah

23:25 gfredericks: AFunction is the superclass of any given function literal

23:26 ,(supers (class #()))

23:26 clojurebot: #{clojure.lang.AFn clojure.lang.Fn java.util.concurrent.Callable java.lang.Runnable clojure.lang.IFn ...}

23:26 TEttinger: ,(clojure.string/join " " (supers (class #())))

23:27 clojurebot: "class clojure.lang.AFn interface clojure.lang.Fn interface java.util.concurrent.Callable interface java.lang.Runnable interface clojure.lang.IFn interface clojure.lang.IMeta interface java.util.Comparator class java.lang.Object interface java.io.Serializable class clojure.lang.AFunction interface clojure.lang.IObj"

23:27 TEttinger: ,(clojure.string/join " " (supers (class {})))

23:27 clojurebot: "interface clojure.lang.IEditableCollection interface clojure.lang.ILookup class clojure.lang.APersistentMap class clojure.lang.AFn interface clojure.lang.MapEquivalence interface clojure.lang.IHashEq interface java.lang.Iterable interface java.util.concurrent.Callable interface clojure.lang.IPersistentMap interface clojure.lang.Associative interface java.lang.Runnable interface clojure...

23:28 gfredericks: AFn is in there, but AFunction shouldn't be

23:29 TEttinger: ,(re-seq #"\w+ (.+?AFunction)" (clojure.string/join " " (supers (class {}))))

23:29 clojurebot: nil

23:29 TEttinger: ,(re-seq #"\w+ (.+?AFn)" (clojure.string/join " " (supers (class {}))))

23:29 clojurebot: (["interface clojure.lang.IEditableCollection interface clojure.lang.ILookup class clojure.lang.APersistentMap class clojure.lang.AFn" "clojure.lang.IEditableCollection interface clojure.lang.ILookup class clojure.lang.APersistentMap class clojure.lang.AFn"])

23:29 gfredericks: oh wait

23:29 I lied

23:29 it stores it as an AFn

23:29 TEttinger: heh

23:29 crisis averted!

23:30 gfredericks: indeed

23:30 clojure is saved

23:30 also now I know exactly what happens when you def something in a function

23:31 TEttinger: what's your reason for doing this, gfredericks?

23:31 are you doing optimizations on clojure's core?

23:31 gfredericks: oh heck no

23:31 just making a talk on vars

23:32 justin_smith: gfredericks: wait, what is stored as an AFn?

23:32 gfredericks: justin_smith: the metadata map

23:32 justin_smith: fascinating

23:32 gfredericks: but a map is an AFn so it's okay

23:32 weird but okay

23:33 seems to necessitate extra checkcasts

Logging service provided by n01se.net