#clojure log - Nov 21 2014

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

0:00 justin_smith: kenrestivo: what about using update-system, with a predicate to restart the specific component?

0:00 that would get the component system to do its "magic" I think

0:03 kenrestivo: fascinating. i found the problem: my stop function does a dissoc which returns a map, not a Foo record. and start doesn't know how to dispatch to the component protocol on a map

0:04 so it just silently shrugs

0:04 justin_smith: OOPS!

0:05 kenrestivo: and yeah, maybe update-system when stopping would avoid that. trying.

0:06 it doesn't. it can't. he must be doing some magic somewhere, it's only one page of code, reading some more.

0:07 justin_smith: kenrestivo: I often find when using stuartsierra libs that I am a bear of very little brain, and there is a clear and simple way to use this thing which is totally beyond me

0:08 kenrestivo: haha, yeah everyone's libs have their own unique flavor.

0:08 zach's libs are the ones that make me feel like i've gone through the rabbit hole.

0:11 i think this might be by design though! maybe it's not intended to be possible to restart components, only systems?

0:12 justin_smith: kenrestivo: regardless of the answer, it would be nice if it were documented

0:13 erikcw: I have a clojurescript function that is using core.async. How do I retrieve the return value of the go macro? I don’t want to wrap it in another go macro to use <!

0:14 justin_smith: erikcw: you can use <!! outside a go block

0:15 kenrestivo: ahah!

0:15 justin_smith: erikcw: see the walkthrough https://github.com/clojure/core.async/blob/master/examples/walkthrough.clj

0:15 kenrestivo: (dissoc this :foo) is baaaaaaad..... (assoc this :foo nil) is gooooooddd

0:15 it's protocol/record weirdness

0:16 dissoc'ing an essential field of a record turns it into a map

0:16 justin_smith: kenrestivo: returning a different data type because of dissoc is so weird...

0:16 right

0:16 kenrestivo: yeah

0:16 now i know why certain people 'round here avoid records/protocols like the plague

0:16 justin_smith: I wonder what the awesome use case is that makes that featuer worth it?

0:16 kenrestivo: i recall the words "broken reload semantics" being bandied about. now i understand why.

0:17 justin_smith: hey, don't drag protocols through that :P

0:17 kenrestivo: oh protocols in cljs are awesome

0:17 justin_smith: protocols just act weird when you redefine them

0:17 kenrestivo: yeah "broken reload semantics". anyway, i'll consider this mystery solved. onward

0:18 danielcompton: kenrestivo: component will only work on records that implement the component protocols. The maps don't so when you dissoc the key and get a map, component can't start it

0:18 justin_smith: danielcompton: yeah, we discovered this and are now griping about it

0:18 kenrestivo: yep

0:19 erikcw: justin_smith: so (prn (<!! (go (let [from-chan (<! chan)] “testing 123”)))) shoud print “testing 123” right?

0:19 kenrestivo: i'm just whining about the surprising behavior of records. but i guess thinking about it, it makes some sense. just didn't expect it.

0:19 justin_smith: erikcw: when the go block returns

0:19 <!! won't return anything until the go block is done

0:20 erikcw: justin_smith: it will just block, right?

0:20 danielcompton: kenrestivo: as far as unexpected corner cases go, Clojure is pretty good compared to other languages

0:20 justin_smith: erikcw: right

0:21 Jaood: danielcompton: but JS now has flow

0:21 kenrestivo: danielcompton: i agree.

0:21 justin_smith: danielcompton: I expect assembly to baffle me and core dump, and the track record is pretty good :)

0:23 danielcompton: justin_smith: yeah, when you get deeper into Clojure you really do need to understand the JVM. But the language itself separated from the host platform doesn't have too many surprises

0:23 justin_smith: it's true, I was just making a silly about "expectation"

0:24 danielcompton: ha

0:34 realyze: Hey there! Is this the right place to ask about "core.typed"?

0:35 technomancy: not only that, it's also the right place to ask about asking about core.typed

0:36 danielcompton: ~ask

0:36 clojurebot: The Ask To Ask protocol wastes more bandwidth than any version of the Ask protocol, so just ask your question.

0:37 danielcompton: #typed-clojure is another good place

0:37 realyze: Cheers guys. So I'm trying to introduce core.typed to my project and I'm epically failing on type checking timbre

0:37 danielcompton: Based on what's come out so far, what are people's favourite Clojure Conj talks? https://www.youtube.com/watch?v=BNkYYYyfF48&list=PLZdCLR02grLoc322bYirANEso3mmzvCiI&spfreload=10

0:38 realyze: With Cannot invoke type: t/Any

0:38 (t/ann ^:no-check taoensso.timbre/info [t/Any * -> t/Any])

0:39 But maybe I'm just holding it wrong.

0:39 ambrosebs: realyze: is there a line number with that type error?

0:40 realyze: Type Error (habanero/activity/jira.clj:34:3) Cannot invoke type: t/Any in: (taoensso.timbre/levels-scored s1__1088__auto__)

0:40 ambrosebs: can you show me the code?

0:40 realyze: I'll create a gist

0:40 ambrosebs: what's the type for levels-scored?

0:40 realyze: he project is private I'm afraid

0:41 (t/ann taoensso.timbre/levels-scored t/Any)

0:41 just BTW - do I really have to annotate all the timbre functions myself?

0:44 here's a snippet of what I'm doing https://gist.github.com/realyze/78d8b972b2b0bad2b3aa

1:09 luxbock: for anyone who has watched Hickeys new transducers talk, in the source snippet he has for transduce

1:10 inside the let form, there's a line like this: (let [xf (xform f), ret (reduce coll xf init)] ...)

1:10 the expression for ret is not right, or maybe I'm missing something?

1:11 TEttinger: (doc reduce)

1:11 clojurebot: "([f coll] [f val coll]); f should be a function of 2 arguments. If val is not supplied, returns the result of applying f to the first 2 items in coll, then applying f to that result and the 3rd item, etc. If coll contains no items, f must accept no arguments as well, and reduce returns the result of calling f with no arguments. If coll has only 1 item, it is returned and f is not called. If val is supplied, returns t

1:11 TEttinger: perhaps

1:11 I'd think coll would go last

1:12 luxbock: it was not the actual source for transduce but a simplified version, so I think it's possible he made a typo there

1:12 https://www.youtube.com/watch?v=4KqUvG8HPYo

1:13 this is the talk in case people reading want to watch it without typing things into a search box

1:15 ah I think know the reason now

1:15 clojure.core.protocols/coll-reduce dispatches takes its arguments in that order because it needs to dispatch on the type of the collection

1:19 ambrosebs: realyze: yea you need to get the annotations from somewhere.

1:19 levels-scored needs a better type

1:21 realyze: ambrosebs: so just doing dummy any -> any won't cut it? That's a pity :-)

1:22 I guess that's just the pains of bolting a type system onto a dynamic lang though

1:25 ambrosebs: that could be a nice use case to have in the docs - using core.typed on a project with timbre

1:26 I'm pretty sure someone else will have the same trouble as I'm having now in the future.

1:26 ambrosebs: realyze: yea, in fact core.typed uses timbre internally so I'll probably be next :)

1:29 realyze: haha well you're definitely the right person anyway :-)

1:31 FriedBob: I've made some progress on my app, but now I am getting "Paramter declaration def should be a vector" and then it is pointing to https://github.com/llowder/run-nerd-miner/blob/master/src/run_nerd_miner/core.clj#L20 can someone help me see what I did wrong?

1:32 luxbock: it's the form below the highlighted line

1:33 `defn` is for defining named top level functions, so it needs an argument vector

1:33 FriedBob: I thought it might be that function, but wasn't sure. Thanks

1:33 luxbock: so they way you use it, you need to add [] in there

1:33 TEttinger: which can be [] yeah

1:34 luxbock: you shouldn't use `def` inside a function body though

1:34 TEttinger: if you're doing your def's inside a function, they will be defined at runtime

1:34 which is sometimes what you want, but not often

1:35 err, not just at runtime, only if the fn is called

1:36 FriedBob: For the time being, that is fine, but I eill keep that in mind as I makethis actually do things.

1:40 luxbock: so I take this `educe` thing is completely new? I tried to search for it from clojure.core and on its Github repo but couldn't find anything

1:43 TEttinger: educe or reduce?

1:43 luxbock: educe

1:43 TEttinger: what does it do?

1:43 luxbock: it was introduced in this talk

1:44 it takes a transducer and a collection and returns a recipe for doing the work, but doesn't actually do it yet

1:44 I'm not sure if I'm the best person to explain it so I would recommend watching the talk :P

1:46 TEttinger: haha

1:46 luxbock: I think the point of them is that you can compose these recipes together

1:46 TEttinger: yep

1:46 luxbock: without creating intermediate values in between

1:47 ohh, there's no function called `educe` but there's `eduction`

1:47 that's why I didn't find it

1:47 but it is there

1:49 TEttinger: I'm thinking my next big project to be hopefully distributed to endusers may be in F#, since the JVM install base seems to be not great for the average user, and it may get much easier to bundle .NET now that it's all getting open sourced. I am certain I will use clojure as a preprocessing tool though, and as a data analysis technique

1:52 gizmo385: !clojurebot help

1:52 seancorfield: TEttinger: but at least the JVM is cross-platform - F# will limit you to Windows for the time being.

1:53 And even later, Linux and Mac won't have .NET by default - so you'll have the JVM problem again.

1:55 TEttinger: seancorfield, mono is distributed with F# now

1:56 and mono is currently the main way of bundling a CLR

1:56 seancorfield: I've had zero luck with F# stuff on Mac (unfortunately).

1:56 TEttinger: hm

1:57 seancorfield: I'm looking forward to that changing now that MS actually _cares_ about this stuff!

1:57 TEttinger: yep!

1:57 my project should take long enough that it will be the mid 2015 target for linux and mac .NET

1:58 seancorfield: Yeah, next year will be interesting. I'd love to see F# be truly cross-platform and reliable enough to build all sorts of apps.

2:05 TEttinger: when did you try F# on Mac? I think someone I know was using it on linux very recently

2:15 seancorfield: Last year. In preparation for Lambda Jam. I signed up for the F# workshop.

2:15 Worked great on Windows (which was what I ended up using).

2:24 schrotti: ljjjkkjjjk

2:24 wups wrong window ^^

2:46 TEttinger: ,(let ["wat"])

2:46 clojurebot: "wat"

2:50 kenrestivo: IllegalArgumentException let requires an even number of forms in binding vector

2:53 TEttinger: but it returned!

2:53 what sorcery

2:55 ,(let ["even number of forms, eh?" "let's make it even" "or not"])

2:55 clojurebot: "let's make it even"

2:57 TEttinger: ,(let ["even number of forms, eh?" "let's make it even" "or not"])

2:57 clojurebot: "or not"

3:09 rritoch: Opinion question, which name is better for (comp first filter) first-filter or filter-first?

3:14 marchdown: What do I have to do before C-c and C-z in emacs work as expected?

3:15 Load the code into repl, that is.

3:27 Glenjamin: rritoch: i've seen that called find / detect in other stdlibs

3:30 rritoch: Glenjamin: I suppose find-first would probably be a better name, there's already a clojure.core/find

3:35 Glenjamin: Thanks though, I'll try that if my first-filter commit gets reverted

3:36 Glenjamin: I work in a very hostile environment when it comes to common libraries... Even a small addition like this could lead to weeks of disputes.

3:36 Glenjamin: sounds fun :s

3:37 rritoch: Glenjamin: It's amusing, I usually try to stay out of common areas as much as possible, but (first (filter.... shows up in these codes a lot so it really needs to be in a common area.

3:39 Glenjamin: i saw an interesting talk recently that suggested that abstraction is only warranted if it reduces bugs

3:39 and that saving a bit of typing isn't a strong enough reason

3:40 in that vein, (first (filter... might not be problematic enough to be worth the effort (in scenarios where it takes effort to put into stdlib)

3:42 rritoch: Glenjamin: It's not the typing I'm worried about, its the column width. (first-filter vs (first (filter saves one column

3:42 Glenjamin: you can omit the space

3:42 :p

3:42 rritoch: Glenjamin: Really? I wasn't aware of that,

3:43 Glenjamin: ,(first(filter even? (range 4))

3:43 rritoch: ,(first(filter #(>% 2) '(1 2 3 4 5))

3:43 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

3:43 #<RuntimeException java.lang.RuntimeException: EOF while reading>

3:43 Glenjamin: oh, maybe you can't

3:43 :D

3:44 rritoch: That seems odd though

3:44 ,(def first(filter 1)

3:44 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

3:45 rritoch: ,(first(filter #(> % 2) '(1 2 3 4 5))

3:45 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

3:45 rritoch: ,(first(filter #(> % 2) '(1 2 3 4 5)))

3:45 clojurebot: 3

3:45 Glenjamin: oh, you can - i just can't count

3:45 rritoch: Glenjamin: Nah, your right, I missed a parenthesis

3:45 Glenjamin: heh

3:46 not that i'd particularly recommend omitting the space

3:46 rritoch: Glenjamin: Thats cool though, I thought the space was needed, but if it wasn't then it could be used as part of identifiers which would be extremly confusing

3:48 ,(first(first (cons '(foo) '())))

3:48 clojurebot: foo

3:48 TEttinger: dude have I not pasted my super condensed clojure in here?

3:48 rritoch: TEttinger: I haven't seen it

3:49 TEttinger: ##(clojure.string/join" "(repeatedly 998(fn[](apply str(concat(rand-nth[[(rand-nth["B""D""G""C""F""T""K"])(rand-nth["r"""""""""])][(rand-nth["S""L""Th""Ch""Sh""L""Y""W""Z""V""M""N""T"])]])(take(+ 2(rand-int 3))(interleave(repeatedly #(rand-nth["a""o""e""i""u""a""o""e""i""au""oi""ou""oo""ai""ee"]))(repeatedly #(rand-nth["s""p""t""n""m""b""mb""rd""g""st""f""rt""sp""ch""rl""x""sh""y""ng"])))))))))

3:49 lazybot: ⇒ "Zootosp Lasheet Terlo Kerl Soipish Namba Vomee Kochoo Wist Diyoi Dreexoot Tes Manup Thoxoo Bag Fauy Boibo Trib Tax Krart Toosesp Chomb Lipard Dangaig Bos Cesu Naixi Shourdau Maumof Fooboomb Gaumang Tafourl Croboub Los Zipat Kungi Zeerlai Shan Fraita Surtemb Coch Gra... https://www.refheap.com/93714

3:49 rritoch: Either way, I didn't know I could drop the spaces, that is very helppful in some cases

3:49 TEttinger: star wars name generator

3:49 you can drop spaces all over

3:49 like between strings or before vectors

3:49 or after vectors!

3:50 rritoch: Well, that's very helpful when trying to stay in 80 cols

3:51 TEttinger: this one was trying to stay in 420 or so characters, freenode's limit is around there

4:13 kungi: Why am i highlighted?

4:13 SagiCZ1: because you are you?

4:14 kungi: Interesting never thought about it :-)

4:31 amalloy: kungi: TEttinger's "random star wars character" name generator appears to have generated your nick

4:31 TEttinger: haha

4:31 SagiCZ1: :D

4:31 TEttinger: I just noticed that as well

4:32 daniel___: i get highlights any time someone says nick

4:32 TEttinger: I'm sure Croboub was highlighted too, or would be if he was real

4:32 kungi: amalloy: I am a Star Wars Character! *swoosch*

4:32 SagiCZ1: my client only highlights my nick

4:32 TEttinger: mine highlights too much

4:32 daniel___: i use irssi, seems to highlight lines with 'nick' in orange

4:33 TEttinger: my nick alert isn't a beep though, it's https://dl.dropboxusercontent.com/u/11914692/guitarsolo.wav

4:35 I'll use the greek generator next time

4:35 &(clojure.string/join" "(repeatedly 2000(fn[](apply str(concat[(rand-nth["rh""s""z""t""k""ch""n""th""m""p""b""l""g""phth"])](take(+ 2(* 2(rand-int 2)))(interleave(repeatedly #(rand-nth["a""a""o""e""i""o""au""oi""ou""eo"]))(repeatedly #(rand-nth["s""p""t""ch""n""m""b""g""st""rst""rt""sp""rk""f""x""sh""ng"]))))[(rand-nth["os""is""us""um""eum""ium""iam""us""um""es""anes""eros""or""ophon""on""otron"])])))))

4:35 lazybot: ⇒ "rheotus sartorkum phthartangophon bashum rhorkeros nocheoseros gorkium zosanes zoipaubotron lomiam kachoxotron mepaushon meseum mobasperos phthochouxotron thoishum geobixanes thiniam peobingor zoshingiam sispanes goshum seongor tausis baspotron morkiam kongophon bau... https://www.refheap.com/93717

4:35 TEttinger: mobasperos: a place in which league of legends and dota are played

4:36 * ucb waves

4:36 ucb: I have a question: I have a macro that takes a body, and then uses this as key into a map to fish out some state to pass it

4:37 e.g. (my-macro (the body here))

4:37 that'd fetch something like (get @state '(the body here))

4:38 clearly that's not great, since this doesn't work: (let [a 1] (my-macro (do-stuff a)))

4:38 I mean, I can't do things like (doseq [n (range 5)] (my-macro (do-with n)))

4:38 since now the 5 versions of whatever the macro returns will share state, when in reality I'd like them not to

4:38 thoughts? solutions?

4:41 jmnoz: newbie question: I modified a clojure library and installed it into ~/.m2 with lein install. Still, the changes made don't show up when I run the project that depends on it. Why is that?

4:41 SagiCZ1: jmnoz: did you run lein deps?

4:41 jmnoz: yes

4:42 rritoch: jmnoz: Does your libraary rely on macros? If so they won't typically get re-expanded until you do a clean/compile

4:43 jmnoz: not sure

4:43 I tried to do clean in my project

4:45 I did check in the .jar to see that the changes were installed. I am sure I am missing something obvious here.

4:46 SagiCZ1: there is also a command to "refresh project" in my IDE, not sure what it translates to

4:46 rritoch: jmnoz: What does your :depends line look like?

4:48 TEttinger: jmnoz, what version did you lein install?

4:48 are you depending on that version?

4:48 rritoch: jmnoz: The reason I assk is that I believe to pull from localrepo deps like [blah/blahapp "0.1.0-SNAPSHOT"] need to be changed to [blahapp "0.1.0-SNAPSHOT"]

4:51 jmnoz: TEttinger: yup same version

4:52 rritoch: okay, it's just called blahapp... et c, no first part.

4:52 TEttinger: that might be why?

4:52 rritoch: jmnoz: Well the only other thing I can think of is check the output of 'lein classpath

4:52 TEttinger: there's a package and an artifact id, you just have the id

4:53 I guess that works, nvm

4:53 getting sleepy here

4:53 SagiCZ1: i would like to run 'distinct' with my own equality check, is there a way to do that?

4:53 jmnoz: TEttinger: wow that's a lot of paths

4:53 I mean rritoch

4:54 rritoch: Yeah, well do you see your dep in there, and is it pulling from where your update installed?

4:55 jmnoz: it's there

4:56 rritoch: jmnoz: Than it's using your new code, something else must be wrong

4:56 jmnoz: the thing I'm trying to modify is part lein plugin

4:57 it's two twings I guess, lein-figwheel and figwheel

5:20 rritoch: When clojure code is run from Java, such as a java servlet, is there some way to get leiningen to interpret a project.clj file to extract things such as the compile-path? Since the code is run from Java there won't be any profiles selected so other than manually parsing the project.clj file I'm not sure if there is a better way.

5:25 clgv: rritoch: you won't even have access to any leiningen functions except if you add leiningen as dependency

5:26 rritoch: if you only need attribute values, you can supply them to the manifest file through leiningen - not sure if that is your use case

5:27 rritoch: clgv: Sorry, my X is useless right now so I had to switch machines

5:28 clgv: Anyhow, I know I'd need to import leiningen as a dependency, any ideas how I deal with the profile issue?

5:28 clgv: rritoch: you won't even have access to any leiningen functions except if you add leiningen as dependency. if you only need attribute values, you can supply them to the manifest file through leiningen - not sure if that is your use case

5:28 rritoch: what exactly do you need from your leiningen profiles?

5:29 rritoch: clgv: I need the classpath

5:29 clgv: I'm basically trying to chroot a servlet using pomegranite

5:30 clgv: I have a configuration file in WEB-INF/projectref.clj which has a pointer to the absolute path of the project.clj file

5:30 clgv: So I need to extract the real (calculated) paths to add to the classpath

5:31 Currently I'm doing it manually with (str/replace x "%s" blah) but there's no guarantee of future compatiblity so I'd like to pull in leiningen to do it for me

5:35 clgv: I don't need the deps though, just the source, resource, and compile-paths, a plugin copies all the deps to WEB-INF/lib for me

5:35 yocapybara: guys is there any alternative to time that will return millis instead of print them out as a side effect?

5:37 rritoch: clgv: But that does give me an idea, I'm generating that projectref.clj file from leiningen, so I guess I can just pre-compute all the paths and avoid reading the project.clj file all-together.

5:47 yocapybara: Why not just use with-out-str ?

5:47 ,(with-out-str (time (+ 1 1)))

5:47 clojurebot: "\"Elapsed time: 0.013901 msecs\"\n"

5:49 yocapybara: rritoch: aaaah due to complete ignorance, I didn't know with-out-str existed! Thanks! I looked at the source of time to see what it was doing and also realised I could make something very similar that returned - or build in the timing to my own functions

5:49 thanks!

6:00 kungi: Can someone please have a look at this gist and help me decifer the exception in the comment? https://gist.github.com/Kungi/4008221dc26b60225a25

6:00 I am trying to make a multipart post

6:01 clgv: rritoch: can't you add those paths to the manifest when leiningen builds your project?

6:01 that'd be a pretty simplistic approach

6:02 rritoch: clgv: There will be no manifest, the point of this construction is to be able to make hot-changes.c

6:03 So putting the project into the classpath should make it possible to make changes and have them reflected in real time

6:03 clgv: rritoch: and thosechanges are not via units like jars but single source files?

6:04 rritoch: clgv: Yes, previously I was "pushing" all of the code to the webroot, but copying the compiled binaries from target/* to webroot/WEB-INF/classes

6:04 clgv: I'm trying to add hot-development support so changes are reflected in real time

6:05 clgv: rritoch: so wait, is there a fixed root directory where you push those?

6:06 rritoch: clgv: Yes, I have tomcat setup with a webroot of ~username/public_html

6:06 clgv: But since these projects are hosted on GIT I need to develop elseware which is why this construction will be helpful

6:07 clgv: rritoch: so you plan to push the whole leiningen project directory to such a root directory and then you want to create a classloader that includes the needed paths of that project on the classpath?

6:07 rritoch: It is basically how things are done in the Yii framework, the sources aren't in the webroot

6:08 clgv: No, I'm replacing the system which would push all the code to the webroot, with a system that pushes the project classpaths into the servlet using pomegranite

6:09 clgv: The only thing getting pushed to the webroot now are the dependencies and a configuration file which the servlet can use to locate the project

6:09 clgv: At least that's the theory, I haven't tested it yet

6:10 clgv: rritoch: so you could use leiningen on the project.clj and your problem is that you cant determine with which profiles the project.clj needs to be evaluated?

6:12 rritoch: clgv: Yes, basically

6:12 kungi: dakrone: I hope you are the right onl to ask. I am using clj-http to create a multipart upload and get the following weird exception (https://gist.github.com/Kungi/4008221dc26b60225a25) could you please have a look at the attached code and help me decifer what's happening there?

6:12 clgv: rritoch: how about just defining one as convention?

6:13 rritoch: profile :servlet-dev or similar

6:14 kungi: keyword: minimal viable examples - can't you narrow it down to the single call?

6:15 kungi: clgv: let me see

6:16 rritoch: clgv: I guess that is an option, but for now to simplify the issue I'm just going to push the paths into the projectref.clj file when it's generated, that way developers are free to use whatever profile/configurations they choose without the system being dependent on specific profile names.

6:17 The source code that generates it is @ https://github.com/rritoch/clj-grid/blob/master/src/leiningen/grid/tomcat_deploy.clj , so if I just cache the paths ahead of time I don't need to calculate them at runtime.

6:18 Developers will just need to make sure they have the correct profiles active when they do a lein grid tomcat-deploy path ....

6:19 And to update it again anytime they change the paths established in the project.clj file

6:20 clgv: rritoch: devs could define their own arbitrary profiles and provide the :servlet-dev profile as a composite profile (https://github.com/technomancy/leiningen/blob/stable/doc/PROFILES.md#composite-profiles)

6:21 the degenerate case being a simple alias

6:24 kungi: clgv: I was able to minimize it a bit bit, but a single call is not possible as far as I see.

6:25 clgv: kungi: ah, due to the login

6:25 kungi: clgv: yep

6:26 clgv: kungi: since you do not pass any java objects in there explicitely, it must be a configuration error or a library error

6:27 zot: i have a sequence of vector where sometimes adjacent pairs need to be merged into a single item; is there a better way than using partition-by + concat?

6:28 clgv: zot: "better" with respect to what? code size? runtime performance?

6:29 zot: clgv: readability; namely is there an idiom that might match it better than this "construct->deconstruct" model?

6:29 rritoch: clgv: I guess that solution would be much cleaner, have the servlet use profile :servlet, and have the servlet provide some kind of default value for it if it's not defined in the project.

6:30 clgv: zot: hard to judge the readability of "invisble" code ;)

6:30 zot: clgv: i'm still writing that version! :)

6:31 marchdown: Where do -> and ->> macros come from (what is the reasoning behind them), and why aren’t there corresponding <- and <<- macros?

6:31 SagiCZ1: marchdown: they just make the code more readable somteimes

6:32 dm3: marchdown: try creating some hypothetical examples with <- and <<- and see if that's more readable :)

6:32 SagiCZ1: marchdown: it avoid nesting too much

6:33 dm3: anyone got some experience with boot-clj already?

6:33 clgv: zot: then finish it and ask again with a gist. the other option is to ask fur an idiomatic implementation providing input and output examples

6:34 zot: clgv: fair. will post when mine is working. :)

6:34 clgv: marchdown: they are pretty useful if the logic of your code is similar to a pipeline. e.g. (->> some-list (filter some-pred?) (map some-fn) (reduce other-fn init--val))

6:35 marchdown: to the second part, why is there "every?" and not "?yreve" ?

6:37 marchdown: Which one is more appropriate here? All three versions work, all seem clumsy to me: https://github.com/marchdown/contest/blob/45cf1ecb2ab70b37cb4d4eb07a247fb19da6fb10/codewars/square-every-digit.clj

6:39 clgv: marchdown: line 7 looks good

6:39 marchdown: clgv: You could argue that it’s unnatural, yet we still sometimes have to reason about function composition going right-to-left?

6:39 clgv: marchdown: line 13 is horrible

6:39 marchdown: no, I didn't have any idea what you intention with the reversed macros is

6:40 marchdown: clgv: that is exactly my point. It is horrible. And some of that horribleness appears on line 10 as well. What is the right compromise here?

6:41 clgv: marchdown: line 10 is perfectly fine. you could improve it minimally, by defining the function explicitely as (defn square ...) in advance, but in this example it is not really a big improvement

6:42 CookedGryphon: zot: partition-by might solve your problem

6:42 if you make a function closing over a bit of state to track the last item

6:43 oh wait, you suggested partition-by, so you don't want them out as a lits

6:43 list*

6:44 it sounds like a plain old reduce to me

6:45 clgv: CookedGryphon: he'll be back with his first try ;)

6:45 marchdown: clgv: But it’s all the same! -> version looks horrible because there are too many inline lambdas used to work around bad parameter ordering, and, presumably, with long enough piplines you get to do that all the time no matter if you pick -> or ->>.

6:45 clgv: marchdown: for sequences you almost alway pick "->>"

6:46 TimMc: marchdown: So use as->

6:46 clgv: whcih works quite well when you write your functions such that sequential collections are always the last parameter. which is a clojure guideline btw

6:47 marchdown: usually there is a low threshold for pipelines. if they get too long, it gets hard to track what they are actually doing

6:49 TimMc: marchdown: http://conj.io/1.6.0/clojure.core/as-%3E/

6:50 clgv: TimMc: oh a shortcut to grimoire :P

6:54 cityspirit: anyone know how to do an INSERT IGNORE with korrma?

6:54 clgv: oh the clojure/conj talks are really there already

6:58 rritoch: clgv: I see that if I use leiningen.core.project/read it is going to add the dependencies to the classpath, which I don't want. Should I be able to load the project with read-raw and and set :eval-in :servlet before calling init-project to bypass altering the classpath, or is there a big risk that it will break the plugins?

6:59 clgv: rritoch: uh, no idea

6:59 rritoch: clgv: The problem is the servlet itself is usually provided by a dependency so it needs to be available before any of this code gets run, it is a chicken-and-egg problem

7:00 clgv: Well, it is a step forward, I'll try it and may just need to deal with any unwanted side-effects

7:01 clgv: rritoch: the idea I had in mind was, just to read the merged (wrt. profiles) project map and go from that

7:05 inad922: Hello

7:07 Is there a templating library for clojure which resembles Jinja or Django templates in functionality so basically it's html based with some tags for if/else or forloop control structures? Also if there is such does it work in clojurescript?

7:08 marchdown: TimMc: as-> looks great, thanks!

7:11 Glenjamin: inad922: take a look at https://github.com/yogthos/Selmer perhaps

7:11 inad922: Glenjamin: Thanks

7:14 Glenjamin: Perfect! That's what I wanted. Thank you!

7:20 SagiCZ1: (doc as->)

7:20 clojurebot: "([expr name & forms]); Binds name to expr, evaluates the first form in the lexical context of that binding, then binds name to that result, repeating for each successive form, returning the result of the last form."

7:24 TimMc: clgv: Actually, grimoire now redirects to conj.io

7:24 SagiCZ1: Like -> or ->> but with explicit placement.

7:31 SagiCZ1: TimMc: sorry, but what do you mean by explicit placement? it will not append it as last nor append it as second but let you say where it should place the argument?

7:37 i mean nor last nor first

7:40 Frozenlock: What... cider now has javadoc support?!

7:41 TimMc: SagiCZ1: Here's an example: http://clojuredocs.org/clojure.core/as-%3E

8:01 justin_smith: as is the shit, especially embedded inside -> / ->> in the right place

8:01 as-> / as->> that is

8:02 wait, there is no as->>?

8:02 luxbock: how would it be different from as->?

8:03 justin_smith: luxbock: (->> coll (map foo) (as->> x (concat x x)))

8:03 luxbock: for usage inside a pipeline

8:03 clgv: O_o

8:04 justin_smith: clgv: as-> was originally intended for mid-pipeline usage, so why not a version that works inside thread-last?

8:05 ,(-> 1 inc (as-> x (* x x)))

8:05 clojurebot: 4

8:16 grandy: hello, anyone have a sense of how out of date this page is? http://en.wikibooks.org/wiki/Compojure/Core_Libraries

8:17 clgv: grandy: better look at the documentation on the github wiki of the project

8:17 justin_smith: grandy: I don't see defservlet - usually people use defroutes

8:18 grandy: and as that page says, this is what you actually want https://github.com/weavejester/compojure/wiki

8:18 grandy: Cool... anyone know of a good example of using forms?

8:18 justin_smith: and as clgv said

8:18 grandy: or handling the data posted?

8:18 thanks to both of you

8:18 justin_smith: grandy: look at any of the POST examples for that

8:19 grandy: justin_smith: trying to find thsoe

8:19 those

8:20 clgv: grandy: clojars.org uses compojure as well (https://github.com/ato/clojars-web)

8:20 maybe you find interesting examples there as well

8:20 grandy: clgv: perfect, was looking for a nontrivial project

8:21 justin_smith: grandy: POST definition from that repo https://github.com/ato/clojars-web/blob/master/src/clojars/routes/artifact.clj#L69

8:22 grandy: justin_smith: excellent

8:22 justin_smith: the PUT examples are good too https://github.com/ato/clojars-web/blob/master/src/clojars/routes/repo.clj#L84

8:22 clgv: justin_smith: is it common to have the implementation in the route definition?

8:22 grandy: any other open source compojure recs?

8:23 clgv: in one of my projects it is much better to have the implementation in separate namespace, then I can reload that namespace and see the results in the server instance I setup via repl (I can't use "lein ring" there).

8:23 rritoch: clgv: Is it possible to just include leiningen core as a dependency? depending on [leiningen "2.5.0"] is loading "the kitchen sink".

8:23 justin_smith: clgv: I think that is REST style - the main router just handles endpoints, and then each endpoint handles the various HTTP methods

8:23 zot: re: the previous question about merging adjacent values: https://gist.github.com/anonymous/0654ae82e81724b1ca2b

8:24 justin_smith: rritoch: leiningen is a kitchen sink

8:24 clgv: (inc leiningen) ;!

8:24 lazybot: ⇒ 7

8:25 zot: after writing it, i think it wisest to use group-by (instead of partition-by), and simplify the merging func. i wonder whether using a reduce function that refs the last value would also be smart, but this seems more natural

8:25 justin_smith: clgv: so it's not implemention in the route that that shows, it's sub-routing inside the implementation

8:26 rritoch: Ok, I think I found it [leiningen-core "2.5.0"] hopefully that's got less overhead

8:28 clgv: rritoch: 6 deps sounds reasonable http://crossclj.info/ns/leiningen-core/2.5.0/project.clj.html

8:31 rritoch: justin_smith: Working on adding the project to the classpath, I ran into a few stumbling blocks with leiningen and the project file but I think I now have a solution.

8:31 Running tests now to see if this is a viable solution to hot-updates

8:36 As long as tomcat is using the same runtime classloader when it initializes the servlet, as when it calles the doPost method for a web request, than this will work, otherwise I need to juggle classloaderss

8:48 SagiCZ1: java.util.Enumeration has no good interop in clojure?

8:49 clgv: ,(apropos "enum")

8:49 clojurebot: (clojure.core/enumeration-seq)

8:49 justin_smith: SagiCZ1: it can be used, it's just a little clumsy - in fact I forget how to use it off the top of my head

8:49 clgv: SagiCZ1: ^^

8:49 SagiCZ1: clgv: cool, thanks

8:49 (inc clgv)

8:49 lazybot: ⇒ 38

8:52 rritoch: Hmm, I'm starting to think using leiningen to read the project file was a bad idea, I''m checking the tomcat logs now and it's not just reading the project file, its loading all of the dependencies into the localrepo of the servers user account, it spammed my loggs.

8:54 clgv: rritoch: using a simple "read" function of leiningen's api does that? O_o

8:54 rritoch: clgv: Yeah, I didn't use read directly though

8:54 clgv: rritoch: what did you use?

8:54 rritoch: I'll commit what I have so far, but I have other issues now

8:55 Since some of my dependencies are in a private repository that needs authentication

8:55 It screwedd everything

8:55 clgv: leiningen.core.project/read-raw sounds reasonable from the docstring

8:56 rritoch: clgv: That doesn't load the profiles though

8:56 clgv: rritoch: ot loads them but it does not merge them, right

8:57 rritoch: Here is the code ... https://github.com/rritoch/clj-grid-core/blob/master/src/com/vnetpublishing/clj/grid/lib/grid/servlet/standard_servlet.clj#L31-L62

8:57 clgv: rritoch: you probably have to steal the parts you need from "init-project"

8:57 rritoch: It is virtually the same as read, accept I set the eval-in to :servlet to block leiningen from updating the classpath on its own

8:59 Well, right now I'm just removing my private repositories from the project, but this is still going to be complicated to maintain.

9:01 SagiCZ1: is there any way to force close all open io/readers even if i dont have their handles?

9:01 clgv: rritoch: btw there is a #leiningen channel

9:02 SagiCZ1: unlikely, just open them in a `with-open` block

9:02 SagiCZ1: clgv: i cant, i read them with lazy seq.. i need the reading to be lazy and close it when its done

9:02 rritoch: clgv: Well, I'm thinking of just releasing control to leiningen, if users add plugins that they expect to apply additional dependencies, everything leiningen's doing could be helpffful

9:03 clgv: SagiCZ1: process the lazyseq within the scope of the block

9:03 SagiCZ1: lazyseqs and io dont play nicely together

9:03 clojurebot: Huh?

9:04 edw: SagiCZ1: What you're dealing with is one of the most irritating parts of lazy sequences. You might want to give up laziness in this case.

9:04 clgv: rritoch: ok

9:04 SagiCZ1: edw: i would but the file wont fit in the memory :(

9:04 i guess i will have to pass the handles around

9:04 clgv: SagiCZ1: you can just reduce over the lazy-seq within the `with-open` block

9:05 edw: SagiCZ1: I think clgv speaks much wisdom.

9:06 SagiCZ1: edw: I don't doubt that hah

9:06 but i think i figured out a way to keep the task in the scope of the with-open

9:10 edw: SagiCZ1: this sort of problem is an huge hassle with SQL calls too. Make sure you grab row data before that result set gets closed! Ugh, horrible.

9:15 clgv: edw: but with sql, you sooner or later use pagination right?

9:16 edw: or load off calculations on the db (if possible)

9:21 Glenjamin: you could do a deftype to represent the file which implements .close and Seq

9:21 probably not worth it tho

9:22 clgv: Glenjamin: then better take the transducers approach ;)

9:30 hellofunk: anyone with enough experience with both core.logic and prolog care to comment on their differences?

9:32 rritoch: clgv: It looks like leiningen to load profiles is a dead-end. I'm going to revert all of this and just cache the paths I need. For some reason even using leiningen.core.project/read directly isn't loading plugins correctly. It was a learning experience but it opens up too many complicated vectors. Such as how to deal with passing credentials for tomcat to use with leiningen.

9:34 clgv: I suspect the problem is that the current working directory, isn't the project path, but I would just need to override too much leiningen functionality, making it unmaintainable.

9:34 clgv: rritoch: ok. do you provide a leiningen project for this code hot swap?

9:34 sorry, plugin not project

9:35 rritoch: clgv: Yeah, grid source @ www.github.com/rritoch/clj-grid/ and it's pushed to clojars

9:36 That's how I'm generating the backlink from the webroot to the project.clj file

9:36 When that's generated (via lein grid tomcat-deploy path) I can just cache the paths which need to be added from the classpath

9:37 clgv: rritoch: the plugin could offer a subtask to determine the needed paths and write them to a well-known file in the project folder - or is this how it works right now?

9:38 rritoch: clgv: That is basically what i'm saying. Right now the "well known file" (WEB-INF/projectref.clj) is just a map that contains the absolute path to the project.clj file (and is generated by the plugin).

9:40 clgv: So if I add the absolute paths that I need added to the classpath (source paths, resource paths, and compile path) to the projectref.clj generated file I won't need to runn leiningen from tomcat, saving a lot of headaches.

9:40 clgv: rritoch: yeah, that sounds solid

9:56 bcm: I'm so excited about the persistant data structures talk

9:57 Frozenlock: bcm: What is it about?

9:58 (what's the 'persistant' part?)

9:58 justin_smith: Frozenlock: http://en.wikipedia.org/wiki/Persistent_data_structure a specific implementation of immutible data that is more space efficient

9:58 bcm: I'm a huge fan of bitmapped vector tries

9:59 one of the cooler data structures imo

9:59 justin_smith: Frozenlock: the basic clojure data structures are persistent

10:00 Frozenlock: justin_smith: ah okay, I was wondering what I was missing there. ("wasn't it always like that?")

10:00 justin_smith: Frozenlock: clojure is somewhat unique in how much it uses these things

10:01 SirRobin: Hi all

10:01 I'm using cljs on node

10:01 Frozenlock: Yeah, it's magical for cljs react.js project... you can store states all you want and reuse the data.

10:02 bcm: Frozenlock: yep, for no space penalty

10:02 SirRobin: I recently updated my project file, and jumped core.async from 0.1.338.0-5c5012-alpha to 0.1.346.0-17112a-alpha

10:02 now when I try to use a go block I get "TypeError: Object #<Object> has no method 'setTimeout'" on cljsbuild-compiler-0/goog/async/nexttick.js:178:4

10:03 justin_smith: SirRobin: have you done a full clean since the dep change? sometimes a manual clean is needed when you swap versions

10:04 SirRobin: and, out of curiosity, why cljs+node rather than clojure+jvm?

10:05 clgv: they still got these awesome memorable version hashes :P

10:05 bcm: SirRobin: how is your startup time?

10:06 SirRobin: justin_smith: I removed the target folder & compiled from scratch, anything else I had to do?

10:06 justin_smith: bcm: well, if with cljs you either count compile time, and it's way long, or you don't, and it's decent. But compare apples to apples, and you get good startup time with clojure too, from an uberjar

10:06 SagiCZ1: so.. continuing from yesterday, how would i match the BOM in text file? (re-find \feff "string") ?

10:06 SirRobin: start up time is way better than jvm

10:07 justin_smith: SirRobin: what about "lein clean" ? I am not sure where cljs keeps all its compiled stuff actually

10:07 SagiCZ1: no need to use an re, you are matching a specific pair of bytes

10:07 SagiCZ1: so .replaceAll

10:08 SagiCZ1: justin_smith: and what do i replace? whats the match?

10:08 justin_smith: SagiCZ1: sorr, I meant replace https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#replace(java.lang.CharSequence,%20java.lang.CharSequence)

10:08 SagiCZ1: (char 0xfeff)

10:08 err, actually "\feff"

10:09 SagiCZ1: okay

10:09 thank you

10:09 SirRobin: justin_smith: same problem after lein clean

10:09 justin_smith: ,(.replace "hello" "l" "w")

10:09 clojurebot: "hewwo"

10:09 justin_smith: I would use a BOM in that example, but they are weird and annoying :)

10:10 SagiCZ1: justin_smith: thank you, and if i just wanted to see if there are any boms in the string?

10:11 justin_smith: SagiCZ1: https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#indexOf(java.lang.String)

10:11 ,(.indexOf "hello" "l")

10:11 clojurebot: 2

10:11 justin_smith: ,(.indexOf "hello" "q")

10:11 clojurebot: -1

10:11 SagiCZ1: thank you very much"

10:11 justin_smith: SagiCZ1: those javadocs are very useful btw

10:11 SagiCZ1: (inc justin_smith)

10:11 lazybot: ⇒ 141

10:12 justin_smith: and I recommend the "javadoc search pane" extension for chrome / firefox, it makes this stuff much easier

10:12 and knowing how to use it will make you look smart :)

10:12 SagiCZ1: justin_smith: i usually use the autocomplete for java, but for clojure it doesnt work that way so i am kind of stuck with the internet

10:13 clgv: justin_smith: you mean "javadoc lookup extension"?

10:14 justin_smith: "Javadoc Search Frame 1.5.1" is what my extension manager says

10:14 clgv: or is javadoc lookup extension better?

10:15 clgv: justin_smith: I have no idea. I just want to check it out ;)

10:15 justin_smith: clgv: this one gives auto-complete which updates with clickable links as you type, in a side frame

10:15 so you type in a class and it finds matches

10:16 SagiCZ1: justin_smith: \feff doesnt seem to work, or is it supposed to be in the quotes?

10:16 clgv: humm do you use the chrome one?

10:16 justin_smith: SagiCZ1: in the quotes, yeah, it takes string args

10:16 clgv: yeah

10:16 SagiCZ1: clgv: https://greasyfork.org/en/scripts/3758-javadoc-search-frame

10:16 clgv: I am looking for the firefox variant ;)

10:16 justin_smith: ,(str (char 0xfeff)) ; SagiCZ1

10:16 clojurebot: ""

10:17 SagiCZ1: clgv: yeah i cant seem to find it either

10:17 justin_smith: SagiCZ1: yeah, that looks very similar, and links to the chrome one I use

10:17 SagiCZ1: justin_smith: i need greasemonkey though?

10:18 its not like a regular extension

10:18 justin_smith: greasemonkey is cool, but I guess...

10:18 I just heard it was available for ff, had not found or used it for ff myself

10:18 btw, emacs tells me that str generated above contains a proper bom

10:19 clgv: works great

10:19 rritoch: clgv: Thanks for your assistance today. I was finally able to get it to work properly ... http://home.vnetpublishing.com:8080/~vwpdev/test.clj , My next project is to build a servlet to execute absolute refrences to .clj files instead of uploading the source, but this test proves the project resource is on the classpath.

10:19 justin_smith: clgv: cool, yeah, I have had great luck with that extension, even works with my downloaded javadocs

10:19 rritoch: (inc clgv)

10:19 lazybot: ⇒ 39

10:20 clgv: rritoch: great :)

10:20 justin_smith: I am using the greasemonkey script now

10:20 firefox search on javadocs is awful

10:21 rritoch: clgv: The only unfortunate behavior is that the project doesn't override dependencies, in this case my projects index.clj is ignored, because one of the dependencies provides it. http://home.vnetpublishing.com:8080/~vwpdev/ , the behavior is unfortunate, but I can live with it.

10:26 clgv: It is something I can probably resolve later by forcing the system to check these paths before checking for classloader resources.

10:37 geekyvin: Hi There, I am new to Clojure and need some help, basically I have vector [{:name max, :age 26} {:name Manpreet , :id 45} {:name Elexia, :age 82}]

10:37 and a function say createTree that takes one argument at a time and gives {:name Elexia :age 82 :child {:name Manpreet :age 45 :child {:name Max :age 26} } } when used with presumable apply or map. I have tried them but could not get it right. any help will be appreciated. thanks :)

10:38 the second one is :age not :id

10:41 justin_smith: geekyvin: do you know how to do this with one entry?

10:42 geekyvin: @justin_smith: the minimum is two entries as one is inside the other in the o/p

10:42 crash_ep: geekyvin: the `map` function probably won't help you, as it returns a new collection of the same size as the collection(s) you pass to it. Whereas you want to pass in a vector of maps and get back a single map.

10:42 geekyvin: yeah I can imagine how to do it in one/two arguments.

10:43 justin_smith: (reduce (fn [child parent] (assoc parent :child child))'[{:name max, :age 26} {:name Manpreet , :id 45} {:name Elexia, :age 82}])

10:43 ,(reduce (fn [child parent] (assoc parent :child child))'[{:name max, :age 26} {:name Manpreet , :id 45} {:name Elexia, :age 82}])

10:43 clojurebot: {:child {:child {:name max, :age 26}, :name Manpreet, :id 45}, :name Elexia, :age 82}

10:43 justin_smith: maps print their fields in a weird order, so that reads funny

10:44 but it's the right output

10:45 geekyvin: @justin_smith: will it work for any (number of) inputs

10:45 justin_smith: as long as each is the child of the next

10:45 yes

10:46 but you need something fancier if they are in an arbitrary order

10:46 kurstin: stop spamming <- technomancy

10:48 geekyvin: @justin_smith: @clojurebot @crash_ep : that is awesome guys. it works!!! thanks!!!

10:49 I never really explored reduce. thats y I was stuck I guess

10:49 thanks :)

10:49 verma: so I've been reading into why clojure startup time is slow, are there any more recent developments in this regard? projects out there which are trying to improve the situation?

10:49 crash_ep: geekyvin: reduce is an amazing function that takes a collection and transforms it into anything you want. Another collection of the same (or a different) size, a different kind of object altogether, or even just a number.

10:50 justin_smith: geekyvin: reduce is amazing

10:50 geekyvin: @justin_smith: this seems good for now I dont think I need fancy right now ;)

10:50 justin_smith: geekyvin: it gets even better with transducer / transducers

10:50 geekyvin: duely noted guys, I'll look into it.\

10:51 justin_smith: verma: technomancy has an awesome guide to fast startup time on the lein wiki

10:51 geekyvin: duely noted guys I'll look into reduce.

10:51 vladh_: Hey guys, I’m trying to use clojure-watch to monitor some files so I need my script to keep running — what’s the best way to not have a script die when it reaches the end?

10:51 justin_smith: verma: one moment, I will find it - it brought repl startups down from like 30 secs to 3 secs for me(!)

10:51 verma: justin_smith: nice!!

10:52 justin_smith: verma: https://github.com/technomancy/leiningen/wiki/Faster

10:52 verma: justin_smith: I was at a meetup yesterday, and one guy used clojurescript -> js -> rhino -> bytecode workflow to get a 50ms startup time for an android app

10:52 justin_smith: I thought it was incredible

10:52 justin_smith: verma: wow

10:53 verma: justin_smith: the google closure compiler had already thrown out everything that wasn't needed by the time bytecode compilation started

10:53 justin_smith: verma: in particular, LEIN_FAST_TRAMPOLINE worked nicely for me, (as does using clojure.main instead of nrepl, when I am not using a networked client)

10:54 verma: justin_smith: taking a look, thanks

10:54 justin_smith: LEIN_FAST_TRAMPOLINE=y lein trampoline run -m clojure.main <- the second time you run this, it will start crazy fast

10:55 though I need to use rlwrap with that

10:55 so its LEIN_FAST_TRAMPOLINE=y rlwrap lein trampoline run -m clojure.main

10:55 verma: what's rlwrap?

10:55 justin_smith: crazy fast startup after the second time

10:55 verma: provides readline wrapping

10:55 verma: trying

10:55 nice

10:55 justin_smith: and unlike nrepl doesn't take 10 seconds to start up :)

10:55 crash_ep: justin_smith: I don't see any tradeoffs to turning LEIN_FAST_TRAMPOLINE on, I wonder why it's not just the default behavior?

10:56 justin_smith: crash_ep: it's new?

10:56 crash_ep: I agree, it's great

10:56 crash_ep: may have issues with bad caching, so may need some usage testing to establish that it really works consistently

10:57 * crash_ep nods

10:57 justin_smith: (think of the various bugs that have been work-around dealt with using lein clean... similar issues)

10:57 verma: man, this is super nice!

10:57 justin_smith: isn't it though?

10:57 ~fast-lein is https://github.com/technomancy/leiningen/wiki/Faster

10:57 clojurebot: 'Sea, mhuise.

10:58 justin_smith: ~fast-lein

10:58 clojurebot: fast-lein is https://github.com/technomancy/leiningen/wiki/Faster

10:58 justin_smith: now I just need to make sure I remember what I called it :)

11:00 verma: justin_smith: I've asked him to write up a blog post and then may be it'd be fun to play with it

11:01 justin_smith: verma: yeah, an easy way to do clj on android would be awesome

11:01 (with good startup time that is :))

11:01 verma: nice, why not everywhere?

11:01 justin_smith: heh

11:01 true enough

11:02 well, I think interop is a *little* harder to do in rhino, is it not?

11:02 so that workflow may not be universal

11:02 verma: yeah it is, kind of weird syntax, but I feel its a tooling problem, I an (:import ...) could be translated to rhino interop calls, I would hope

11:03 hellofunk: can anyone suggest a more elegant version of this line: (if (> (count name) 10) (str (apply str (take 9 name)) "...") name)

11:03 verma: s/an/mean/

11:04 justin_smith: hellofunk: (str (subs str 0 9) "...")

11:04 err

11:04 hellofunk: justin_smith that will add ... to all strs

11:04 verma: btw, here's the twitter thread sort of: https://twitter.com/samberan/status/523929208595025920

11:04 justin_smith: ,(str (subs "hello my name is bob nice to meet you" 0 9) "...") ; hellofunk

11:04 clojurebot: "hello my ..."

11:05 justin_smith: hellofunk: sorry, at first I used a bad generic var name of "str", my bad

11:06 hellofunk: it is nicer justin_smith.

11:06 justin_smith: hellofunk: bonus, string ops are much faster than seq ops on a string followed by constructing a string

11:10 &(format "%.9s..." "hello my name is bob nice to meet you") ; hellofunk - another option

11:10 lazybot: ⇒ "hello my ..."

11:11 justin_smith: whether to use that or subs may depend on whether the numbers are ever args passed in, or whether you prefer format style to str building style

11:13 hellofunk: (inc justin_smith)

11:13 lazybot: ⇒ 142

11:13 hellofunk: no doubt, son! thanks!

11:13 justin_smith: heh, np

11:14 hellofunk: of course, i'm actually doing this in cljs so performance considerations may be different than you describe

11:14 justin_smith: ahh, OK

11:14 I wonder if format works in cljs...

11:14 hellofunk: but your subs syntax is surely better than my deconstruct/reconstruct

11:15 vladh_: does anyone know how to keep a clojure script running after it reaches the end? I’m trying to watch some files

11:15 hellofunk: 90% of the time, shorter code is likely faster code, it seems.

11:16 justin_smith: hellofunk: I think that regardless, the amount of allocation going on in breaking a string into chars, and then reassembling a subset of those chars (or one letter strings as in the case in js) will be more expensive than a proper substring function on either platform

11:16 hellofunk: clojure makes an effort to make the easy thing the fast thing (though clarity / determinism trumps that still)

11:17 vladh_: clojurescript or a program "script" written in clojure?

11:17 vladh_: justin_smith: sorry, just regular clojure

11:17 justin_smith: vladh_: in jvm clojure I would spawn a future with a while loop

11:17 vladh_: or maybe even use a proper fs watcher

11:17 vladh_: justin_smith: I’m using this https://github.com/derekchiang/Clojure-Watch

11:18 justin_smith: vladh_: cool. yeah, put that in a future

11:18 clojure will keep running until all the futures / agents are done

11:18 futures are super easy to use

11:19 vladh_: justin_smith: futures it is. thanks!

11:25 justin_smith: sketchy and rash decision: using my template rendering lib on some sql files instead of adding a yesql dep, or using my own home grown map-relational-model dsl tool

11:27 clgv: hmm clojure-watch is not listed on crossclj.info...

11:28 theseb: just curious...what is left to develop in core clojure runtime since it uses Java libraries?

11:28 is there much developer activity?

11:28 clgv: theseb: improvements ;)

11:28 theseb: clgv: besides speeding things up...what other kinds are there?

11:28 clgv: currently focus is on reusable computation in different contexts -> transducers

11:29 theseb: wow

11:29 clgv: and there is a branch for static function calls, but I have been told that it is unlikely to be part of 1.7

11:29 justin_smith: theseb: clojure does not use javac for most code, so it's own compiler has lots of ongoing work to do

11:30 clgv: technomancy: someone for your ban list "kurstin"

11:38 verma: clgv, what do you mean, that nick sent me awesome link

11:39 rylev: Is it possible (and an ok idea) to check if two functions are the same in a test? When I use midje autotest I get failures because the functions are different instances.

11:39 clgv: verma: :P

11:39 justin_smith: rylev: there is no general solution for function equality besides identity, at least not in clojure

11:40 clgv: rylev: you can compare their classes - but if the code of the function is reloaded between the creation of both instances, even the classes wont be equal

11:40 justin_smith: rylev: to give you an idea of how hard this is, it isn't even possible in haskell :)

11:41 rylev: Well if it's not possible in Haskell it's not worth doing! ;-)

11:41 justin_smith: just saying, they are super mathy and would love to have that predicate, but gave up on implementing it

11:41 Glenjamin: surely `deriving Eq` does it.

11:41 justin_smith: Glenjamin: solve the halting problem first, sure

11:41 Glenjamin: oh, functions

11:41 i didn't read properly

11:41 justin_smith: :)

11:42 EvanR: justin_smith: you cant check if a function is equivalent to identity either

11:42 justin_smith: EvanR: I mean the identity of the function

11:42 Glenjamin: if functions have the same identity, they are equal

11:42 EvanR: oh

11:42 justin_smith: ,(let [f (fn [])] (= f f))

11:42 clojurebot: true

11:42 EvanR: Glenjamin: but not only if

11:42 justin_smith: ,(= identity identity)

11:42 clojurebot: true

11:42 justin_smith: haha

11:42 clgv: justin_smith: only in that case ;)

11:43 justin_smith: ,(= identity (identity identity))

11:43 clojurebot: true

11:43 justin_smith: ,(= identity (identity identity) (identity (identity identity))))

11:43 clojurebot: true

11:43 rylev: now you're just having too much fun

11:43 justin_smith: :)

11:43 rylev: :-D

11:43 clgv: ,(defn f [g h] (= g h))

11:43 clojurebot: #'sandbox/f

11:43 clgv: ,(f map map)

11:43 clojurebot: true

11:43 clgv: damn. there is some case where this fails. probably not that minimal

11:43 justin_smith: ,(f map #(apply map %&))

11:43 clojurebot: false

11:44 rylev: I can only get it to fail when I reload code

11:44 clgv: ,(f map (with-meta map {:fail true}))

11:44 clojurebot: false

11:44 clgv: ah great ^^

11:44 justin_smith: rylev: yeah, reloading would make that happen reliably

11:45 rylev: you could store and compare the var, which should only get made once

11:45 EvanR: theres several ways to describe equality for functions, but as far as functions defined with algorithms on possibly infinite domains, no dice

11:45 rylev: justin_smith: we don't that in one code base of ours. Makes the code slightly uglier but it's ok

11:45 s/don't/do

11:46 justin_smith: quick demo of what I meant here: https://www.refheap.com/93724 but it sounds like you get the idea

11:46 EvanR: and equality predicates and predicates suck as a basis for reasoning anyway

11:47 justin_smith: EvanR: well, clojure equality testing (which tends to be structural equality not identity based) is often better than the normal method at least

11:48 EvanR: i noticed that

11:48 but = seems to default to pointer equality?

11:48 justin_smith: not at all

11:49 EvanR: just for functions

11:49 justin_smith: &(= [1 2 3] '(1 2 3))

11:49 lazybot: ⇒ true

11:49 justin_smith: EvanR: well, that's the only predicate any lang will give you for functions

11:49 sdegutis: Has anyone using Speclj run into this bug? https://github.com/slagyr/speclj/issues/113

11:49 EvanR: id be ok with not having an equality for functions

11:50 rather than possibly mixing things up

11:50 ,(= identity 3)

11:50 clojurebot: false

11:50 EvanR: bleh

11:51 justin_smith: haha

11:51 ,(= Double/NaN Double/NaN)

11:51 clojurebot: false

11:51 EvanR: ,(not= Double/NaN Double/NaN)

11:51 clojurebot: true

11:51 EvanR: er

11:51 sdegutis: Insane.

11:51 clgv: (.compare Double/NaN Double/NaN)

11:51 sdegutis: (doc not=)

11:51 clojurebot: "([x] [x y] [x y & more]); Same as (not (= obj1 obj2))"

11:51 clgv: ,(.compare Double/NaN Double/NaN)

11:51 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: No matching method found: compare for class java.lang.Double>

11:52 sdegutis: (source not=)

11:52 clgv: ,(.equals Double/NaN Double/NaN)

11:52 clojurebot: true

11:52 justin_smith: sdegutis: EvanR: it's required by the floating point spec that NaN not be equal to itself

11:52 so .equals is buggy here

11:52 sdegutis: justin_smith: is it required that it be not= to itself also?

11:52 EvanR: right, but i was expecting false for all comparisons for some reason

11:53 justin_smith: ,(< Double/NaN Double/NaN)

11:53 clojurebot: false

11:53 justin_smith: ,(> Double/NaN Double/NaN)

11:53 clojurebot: false

11:53 justin_smith: EvanR: hmm, I wonder

11:53 sdegutis: ,(>= Double/NaN Double/NaN)

11:53 clojurebot: false

11:53 sdegutis: Whatever, I like Swift.

11:53 EvanR: "not equal" might not be a floating point thing

11:53 justin_smith: another silly one: ##(= Double/NaN)

11:53 lazybot: ⇒ true

11:54 EvanR: ok, wtf is up with that one :|

11:54 clgv: no special case in its definition

11:54 justin_smith: EvanR: clojure short circuits, one arg to = always returns true

11:54 it's a special case in =

11:54 clgv: everything is equal to itself, well except ...

11:54 EvanR: why

11:54 justin_smith: $source =

11:54 lazybot: = is http://is.gd/8CTFcB

11:54 clgv: ,(=)

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

11:54 clgv: :(

11:54 justin_smith: EvanR: so that (reduce = coll) makes sense

11:55 ,(reduce = [])

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

11:55 EvanR: what

11:55 justin_smith: ,(reduce = [1])

11:55 clojurebot: 1

11:55 EvanR: reduce uses arity 1 ?

11:55 justin_smith: you want that to be true, right?

11:55 clgv: ,(reduce (fn [a,b] (println "called!") b) nil [1])

11:55 clojurebot: called!\n1

11:55 clgv: ,(reduce (fn [a,b] (println "called!") b) [1])

11:55 clojurebot: 1

11:55 justin_smith: EvanR: wait, I am wrong

11:55 clgv: justin_smith: ^^ ;)

11:56 justin_smith: Evanr it is the recur in =

11:56 EvanR: the recur needs the one arg base case

11:56 EvanR: uhg

11:56 clgv: justin_smith: in reduce with a collection of 1 element and no seed, the function does not get called ;)

11:56 legittalon: I understand (>) but what does (>>) do?

11:56 justin_smith: clgv: right, I was wrong on that

11:57 legittalon: where do you see >> ?

11:57 do you mean ->> ?

11:57 legittalon: yeah

11:57 my bad

11:57 justin_smith: $grim clojure.core/->>

11:57 lazybot: http://grimoire.arrdem.com/1.6.0/clojure.core/->>

11:57 EvanR: good thing i never accidentally use the right number of args minus 1, or that would be annoying

11:57 justin_smith: legittalon: above link has docs and examples

11:57 EvanR: haha

11:57 clgv: why did the incanter devs think maps would be a good representation for table rows... it's blowing the heap again for a 400MB file :(

11:58 sdegutis: I like Hiccup, but I don't like that I can put random code in a Hiccup template.

11:58 I really value logic-less views as a way of enforcing separation of view and model, and encouraging using presenters, like mustache would have.

11:58 justin_smith: sdegutis: selmer is logic-less right?

11:59 sdegutis: At the same time, Hiccup is very valuable since it's highly readable and pure code, so it can be manipulated with very little effort, e.g. partials can just be plain old Clojure functions, and you already get looping on collections and such for free.

11:59 justin_smith: sdegutis: at least, selmer doesn't support arbitrary code, only explicitly passed in helpers

12:00 sdegutis: I use the in-house caribou tool (caribou/antlers) which is quite similar to selmer, mustache style syntax, pass in helpers to the render function

12:00 EvanR: logic-less is a new word for me, i immediately thought it meant no if statements and for loops in the template, but i guess logic is a word to mean something like "business logic"

12:01 justin_smith: EvanR: yeah, more like "not turing complete"

12:01 sdegutis: EvanR: Right, it has very very limited logic, only what's absolutely needed for turning your pre-processed data and template into the final intended view.

12:01 justin_smith: EvanR: "logicless templates, they allow paridoxical definitions!"

12:01 EvanR: i still dont know whats going on

12:02 sdegutis: justin_smith: That sounds very tempting, but what Hiccup has going for it is the very expressive and easy syntax specifically intended for outputting HTML/XML.

12:02 Glenjamin: hiccup doesn't escape by default

12:02 sdegutis: justin_smith: With mustache and friends, you have to put "<div>{{ bla }}</div>" manually in there and it quickly gets verbose and tedious.

12:02 Glenjamin: which is a big gotcha imo

12:02 sdegutis: Glenjamin: Oh, I didn't know that. Good thing we don't allow any user content in our website.

12:03 justin_smith: sdegutis: yeah, depends on workflow though - we had frontend guys who didn't do clojure, so they preferred mustache style over hiccup data structures

12:03 Glenjamin: it's possible to get hiccup syntax and safe-by-default escaping, but the current implementation doesn't make that easy

12:04 EvanR: html should have just had "functions", taking care of the 1000 not-essentially-different-from-html template languages that also failed to realize this. function here does not mean an implementation of bubblesort with mutable arrays, or sending email

12:05 substituting a text variable, or even a list of text into.. text.. isnt enough

12:06 templates are functions

12:11 sdegutis: I think there could be value in having a Clojure templating language that's got the expressiveness, succinctness, and structure of Hiccup, but without necessarily using Clojure data structures, in order to remain friendly to designers who don't know Clojure.

12:12 It would resemble Hiccup in its syntax, but drop a little of what's only necessary for the "it's just plain Clojure data" principle, like this: "html\n body\n span Foo bar" would result in <html><body><span>Foo bar</span></body></html>

12:13 tbaldridge: yay, replace hard Clojure syntax with invisible whitespace!

12:14 xemdetia: This is kind of a random question, but for GTK emacs is there a nice way to change the double-click select rules? To make them closer to a term/putty?

12:14 sdegutis: One benefit of not having pure Clojure syntax would be to limit what kind of logic is allowed.

12:15 It's all too easy to throw raw Models right into a Hiccup template and manipulate them in there, instead of creating a Presenter layer first and passing that into the Hiccup template.

12:15 justin_smith: xemdetia: #emacs may be able to help there

12:16 xemdetia: I tried to do M-x describe-key followed by double-click to see what gets run, but it only captured the first click

12:17 xemdetia: justin_smith, I was running into the same issues- it's in mouse.el I guess but I don't even know if there is an infrastructure to plug into there. I was hoping that someone messing around with clojure modes would have figured it out. :)

12:18 sdegutis: Plus there is value in having maps which are otherwise stringly typed be checked for valid keys, which raw Clojure code can't do (without a wrapper) and which a template language could.

12:18 justin_smith: xemdetia: heh, who knows, but if anyone does #emacs or #clojure-emacs will

12:18 technomancy: the #emacs channel will just make fun of you for using the mouse

12:18 justin_smith: haha

12:18 sdegutis: I started using the mouse more often lately ever since Emacs was causing me to have damaging injuries to my left hand earlier this year continuing to this day.

12:19 RMS is in denial for thinking his RSI wasn't caused by his own creation.

12:19 justin_smith: yeah, emacs has nice features but those bindings will fuck you up

12:20 technomancy: I used to get RSI from using the mouse

12:20 well, it might not have been RSI; the pain was worse in my shoulders

12:20 sdegutis: Was that with those 80s mice?

12:20 technomancy: technically a trackball

12:21 it was just the movement off the keyboard to the not-keyboard

12:21 justin_smith: trackballs are better than most mouse-like things rsi wise

12:21 and being able to put it between your hands makes it even better

12:22 that's what I have, half my keyboard on each side of a trackball

12:22 I can use the ball left or right handed, with many possible clickable hand-positions

12:23 takes the "r" out of rsi if you have multiple comfortable positions available (and use them)

12:23 FriedBob: I'm still holding out for somethgn that'll let the cursor track my eye movements.

12:23 justin_smith: FriedBob: oh nice, popups that cause bugs in my code :)

12:23 technomancy: panning around virtual desktops via tracking head movement plz

12:23 justin_smith: I use mouse-to-type in my wm

12:24 I've had pair-programming scenarios where someone moves my mouse, causing me to type code into random windows...

12:25 xemdetia: justin_smith, are you sure you just weren't part of a psychology experiment?

12:25 justin_smith: haha

12:25 canweriotnow: lesterthx I'd sue the IRB that approved that.

12:26 justin_smith: in their defense, they did not comprehend the concept of mouse to focus, so they expected moving the mouse not to effect what I was doing

12:26 SpaghettiCat: Hello, I have a noob question and I'm hoping someone will condescend to answer. I want to learn Clojure because it's novel, but, e.g., if I want to create a small, desktop GUI utility, is clojure a bad choice because of the time it takes to load JVM and how much memory it takes up?

12:27 Is clojure only for big apps and backend, powerful stuff?

12:27 justin_smith: SpaghettiCat: for longer running programs it should be OK - the startup time is much better for an uberjar compared to what you would get from lein

12:28 SpaghettiCat: justin_smith: : I'm new to the JVM world so I can't appreciate what you said

12:28 clgv: why do people complain about startup time for clojure gui applications? non-trivial applications always need at least some seconds to start up...

12:28 +GUI

12:29 pmonks: SpaghettiCat: might be worth trying it out and seeing for yourself if it's a bad choice? Hard to know what that means for your use case.

12:29 technomancy: Emacs boots in ~900ms

12:29 justin_smith: SpaghettiCat: the jvm is just a part of what makes clojure slow, and with a compiled project (not dev mode using lein) you can eliminate a substantial part of that overhead.

12:30 SpaghettiCat: Hmm I see

12:30 justin_smith: *slow to start up

12:30 pmonks: SpaghettiCat: plus you get to play with really nifty libraries like seesaw: https://github.com/daveray/seesaw

12:30 justin_smith: really, jvm is a big part of what makes clojure fast :)

12:30 clgv: technomancy: that's a second :P

12:30 canweriotnow: technomancy depending on how many packages you're preloading :)

12:30 SpaghettiCat: If I write a Python script and executed it, the startup time is very, very fast. But I get the feeling that it's not the same when you have to load up JVM

12:31 I know that JVM is fast at executing, what I'm worried about is memory footprint and startup time

12:31 justin_smith: SpaghettiCat: the jvm default is to trade larger preload / startup delay, for faster runtime performance

12:31 clgv: JVM is pretty fast as well, Clojure itself is kinda slow on startup atm

12:31 justin_smith: SpaghettiCat: it is optimized for long-lived processes

12:31 clgv: where is that link from the last days?

12:31 SpaghettiCat: Hmm I see, thank you for the info

12:31 technomancy: clgv: yeah, but emacs is like seventeen different apps

12:31 clgv: Why is Clojure bootstrapping so slow?


12:32 technomancy: yeah emacs is an OS ;)

12:32 I skip the editor joke.

12:32 ups title and not link :P

12:32 http://nicholaskariniemi.github.io/2014/02/25/clojure-bootstrapping.html

12:33 justin_smith: SpaghettiCat: if you want persistent data structures, and functional programming, plus smaller heap usage and faster startup, you could consider racket or ocaml

12:33 SpaghettiCat: So I guess Clojure is aimed at enterprise apps, big/powerful programs (like an XML editor) and backend stuff?

12:33 technomancy: clgv: it's not actually a joke though

12:33 SpaghettiCat: the JVM was created by a company that sold server hardware

12:33 SpaghettiCat: justin_smith: My 2nd choice would be haskell: it compiles to native

12:33 justin_smith: SpaghettiCat: yeah, I find it is great for big server side stuff that stays running for months at a time

12:33 SpaghettiCat: so do ocaml and racket

12:34 SpaghettiCat: and they make smaller and at least in ocamls case, faster starting executables

12:34 SpaghettiCat: justin_smith: They seem to be less popular

12:34 clgv: SpaghettiCat: you can do a lot of different stuff with clojure: web dev, data analysis, machine learning, optimization algorithms

12:34 justin_smith: SpaghettiCat: yes, they are

12:35 pmonks: SpaghettiCat: I've had good success with CLI apps that only run for short periods (a minute or two). I think it all boils down to how long your total runtime is, and therefore how much you can amortise the startup time.

12:36 SpaghettiCat: I like lightweight programs on my desktop

12:36 which is why I have avoided Java apps. I don't have any installed except for LibreOffice

12:36 clgv: what is a lightweight program?

12:37 SpaghettiCat: clgv: Low memory footprint, fast startup, doesn't peg the CPU

12:37 clgv: SpaghettiCat: whast exactly is "low"?

12:38 pmonks: LibreOffice isn't a Java app.

12:38 (except, IIRC, for the MS Access alternative)

12:38 justin_smith: SpaghettiCat: clojure wants the opposite of all of those (it wants to peg every CPU available because that gives you the result faster, and it optimizes away from the other time because that gets more results from the same amount of cpu usage). You may be happier with a differently designed lang.

12:39 SpaghettiCat: High memory footprint for me is >100MB. I remember installing JDownloader and it took up 200MB-300MB, which is massive overkill

12:39 justin_smith: s/other time/other two/

12:40 clgv: SpaghettiCat: set the -Xms and -Xmx appropriately...

12:40 SpaghettiCat: Ahh, now I see

12:40 clgv: But what is the minimum the JVM can take up?

12:41 clgv: SpaghettiCat: you'll see. it depends on what the program does

12:41 justin_smith: more important is the minimum that clojure can take up - it can't run without initializing a large number of persistent data, and loading its full compiler.

12:41 a java hello world is a lot smaller than a clojure hello world

12:42 AimHere: It is?

12:42 justin_smith: (in memory at runtime that is)

12:42 AimHere: by orders of magnitude

12:42 AimHere: Well that's kindof a given

12:43 justin_smith: I mean the clojure code for hello world is "hello world" much smaller than java, but the size of the runtime to implement that...

12:43 AimHere: java comes with a lot, but is lazy about loading needed classes into heap

12:44 AimHere: but clojure needs many those classes to bootstrap itself, and it's own internals are large

12:44 AimHere: Sure. I only queried in the first place, because you didn't say you were referring to runtime memory

12:44 justin_smith: gotcha

12:44 AimHere: I thought you just meant source size

12:44 justin_smith: AimHere: the conversation was about runtime memory usage

12:45 AimHere: I never read up more than 3 lines in the scroll buffer

12:45 Life's too short!

12:45 clgv: "lein repl" in one of my projects with 15MB (-Xmx) fails and with 20MB succeeds to start

12:46 hellofunk: a function literal would be better to test for equality, woudln't it?

12:46 ,(= (fn [x] (inc x)) (fn [x] (inc x)))

12:46 clojurebot: false

12:46 clgv: so I guess it is "lightweight" ;)

12:47 justin_smith: clgv: you could get that smaller with LEIN_FAST_TRAMPOLINE=y rlwrap lein trampoline run -m clojure.main

12:47 hellofunk: but = does not see the literal

12:47 hellofunk: it sees the compiled function

12:47 clgv: justin_smith: interesting. I just wanted to have a rough number for the repl there ;)

12:47 hellofunk: exactly ,which is why function equality is hard to achieve

12:48 justin_smith: clgv: sure, but lein repl loads nrepl, which is relatively big - the above literally just gives you a repl

12:49 Bronsa: hellofunk: even comparing functin literals, = would still be useless. (fn [x] x) vs (fn [y] y)

12:49 clgv: justin_smith: sure. the only memory concern I have is with dataset rows as clojure PHMs in incanter. that's just horrible and I need to find a way around it

12:50 Bronsa: unification! :D

12:50 justin_smith: I hope I don't sound like I am badmouthing clojure. I think clojure is great, I use it for everything I can, but it doesn't optimize for low heap usage, in any way at all

12:51 Bronsa: clgv: then (fn [x] (inc (dec x))) vs (comp inc dec) :P

12:51 hellofunk: Bronsa yes that was my point, to show that fn equality is not available. because (= map map) returns true which is misleading, hence the literal example

12:51 justin_smith: I even went and got a laptop with 32g ram so I could use clojure and just not think about heap usage until it deploys

12:51 clgv: Bronsa: sure

12:51 EvanR: hellofunk: you can check syntactic equality, even accounting for renaming variables. but this isnt a general form of function equality

12:52 technomancy: justin_smith: on the other hand, I haven't upgraded from 4GB so I can still feel the pain of users =D

12:52 justin_smith: technomancy: you are a saint

12:52 (inc technomancy)

12:52 lazybot: ⇒ 159

12:52 clgv: technomancy: very emphatic of you :D

12:52 justin_smith: you could of course upgrade, and develop in a vm

12:52 EvanR: i have 8G and im feeling the pain of datomic

12:53 clgv: 16GB and I feel the pain of using incanter to load up a 400MB dataset :(

12:53 justin_smith: hilariously, I run a super lightweight wm for UI reasons, and for a client project I have a SuSe install running with the default kde desktop in a vm

12:53 technomancy: that's not actually why; I'm just waiting for my Novena to arrive

12:53 EvanR: nobody will need more than 640k

12:53 justin_smith: technomancy: well use a ram limited jail and you can hold onto your purity

12:54 clgv: are we telling urban legends already?

12:54 technomancy: justin_smith: yeah, but until recently that would have meant downgrading my screen

12:54 justin_smith: technomancy: I may just want a novena too though... that looks awesome

12:54 verma: Just posted this on the mailing list based on what I was talking about earlier: https://groups.google.com/forum/#!topic/clojure/foeLiIDx4q8

12:54 technomancy: I can always SSH into more ram if I need it; I can't SSH into a better screen

12:54 justin_smith: true that

12:54 clgv: haha :D

12:55 justin_smith: verma: cool, bookmarking that thread to follow it

12:57 Glenjamin: the novena google results are an odd mix of FLOSS and catholisism

12:57 verma: yeah, totally threw me off

12:57 technomancy: Glenjamin: https://www.crowdsupply.com/kosagi/novena-open-laptop is the best one

12:58 pmonks: (inc EvanR)

12:58 lazybot: ⇒ 5

13:00 sdegutis: What would cause (macroexpand) to behave differently at two different times?

13:01 Bronsa: ,(defmacro x [] (rand))

13:01 clojurebot: #'sandbox/x

13:01 sdegutis: Sometimes it seems to work as macroexpand-1 should. Is it possible that someone could have redefined it?

13:01 Bronsa: ,(macroexpand '(x))

13:01 clojurebot: 0.5872319973633218

13:01 Bronsa: ,(macroexpand '(x))

13:01 clojurebot: 0.9289759698202612

13:01 technomancy: justin_smith: did you ever come across prescheme?

13:01 justin_smith: technomancy: no, but the wikipedia on it looks very interesting

13:01 technomancy: what about it?

13:02 technomancy: justin_smith: I'm tempted to try to get it compiling to avr

13:02 I can't find evidence of it being used for anything but the s48 VM, but it looks awesome, especially the type system

13:03 justin_smith: oh yeah, it seems like a nice compilation target or IR - or I guess you could suck it up and program scheme without closures manually :)

13:03 technomancy: just wondered if you had come across it in your exploration

13:03 justin_smith: nope, not at all

13:03 technomancy: well if the alternative is C...

13:03 justin_smith: yeah scheme without closures can beat C, especially if the overhead is low enough

13:03 which it seems it could be...

13:04 technomancy: that's the claim

13:04 seeing a hello world would help

13:05 that's scheme for you; they'd rather write a beautifully-typeset 11-page paper than a simple getting started readme =)

13:06 justin_smith: hah

13:06 technomancy: anyway once the dust settles from the atreus announcement I might give it ago

13:08 erikcw: Is it corect that <!! isn’t available in the clojurescript version of core.async?

13:08 justin_smith: technomancy: have you looked at the scheme48-doc that is available from apt?

13:09 technomancy: justin_smith: I've just been looking through a checkout of the source, but I also found http://mumble.net/~campbell/darcs/s48-refman/prescheme/

13:09 verma: erikcw, it isn't because there are no real threads

13:09 technomancy: haven't gotten a chance to read through the tex manuals yet

13:09 justin_smith: technomancy: oh, texi, I love info docs (making me one of a very small number likely)

13:10 technomancy: justin_smith: I'm a fan too; gotta have my hyperlinks

13:10 justin_smith: ps-as-scheme.texi looks right

13:10 erikcw: verma: So what is the correct way to consume the channel returned from a go block? Basically — how do I leave core.async land?

13:11 technomancy: justin_smith: were you looking for stuff for microcontrollers too or just general low-level langs?

13:11 justin_smith: technomancy: for embedded (recent example, using a cell phone chip without an OS)

13:11 technomancy: cool

13:12 justin_smith: technomancy: that board even theoretically could support desktop ram

13:12 so - gigs of ram - no OS

13:12 lol

13:12 technomancy: ._.

13:12 justin_smith: too bad mirage is vm-only, that would be interesting

13:13 technomancy: this is for DSP, so there are valid reasons to skip an OS if possible, and to have as much working ram as you can afford

13:13 technomancy: oh sure; makes sense

13:14 reasons to skip a GC too, maybe?

13:14 justin_smith: right, or use a gc that is optimized for worst case rather than average case

13:14 verma: erikcw, what are you trying to do?

13:14 erikcw, would be nice to see some code

13:15 justin_smith: technomancy: because a DSP that hangs ever is worse than one that is a little more limited power wise

13:15 hangs meaning fills a buffer 1ms too late

13:15 technomancy: ep

13:15 *eep

13:16 justin_smith: technomancy: time domain output, any irregularities ruin the result

13:16 aka - the audience can hear a glitch happen, or your analysis is fucked because an artifact snuck in, or whatever

13:17 but I am still a dabbler with this stuff - I have played with things getting close to it, and read about it for a while, but this is the first time I have had good access to custom built hardware to do it in anger

13:19 erikcw: verma: http://pastebin.com/S1j3X2YD

13:20 verma: Kind of a mess since I’ve been moving stuff around a bunch trying to get this to work

13:20 verma: Basically, I’m trying to get the dimensions of an image file from and HTML file input

13:21 verma: It involves 2 layers of nested callbacks, 1 for the js/FileInput object, and one for the js/Image object

13:22 justin_smith: technomancy: hrm, the docs that come with scheme48 on my system have no mention of prescheme

13:23 hellofunk: i'm watching this video where William Byrd suggests that MiniKanren (and thus core.logic) are all the pure parts of Prolog, with the impurities cut out. Best comparison I've heard yet of the two.

13:23 technomancy: justin_smith: it's treated as an implementation detail

13:23 justin_smith: technomancy: makes sense. Much like the weird lisp dialect hidden inside gcc

13:23 technomancy: haha, yeah

13:23 justin_smith: technomancy: I wanted to play with that, until I discovered that they intentionally made it hard to use directly

13:24 technomancy: those anti-corparate security via obscurity shenanigans!

13:24 sdegutis: justin_smith: there is!?

13:24 justin_smith: "let's cripple this open source software's pluggability, so that corporate users don't subvert our licensing by extending it internally"

13:25 sdegutis: yes, there is. But using it directly is likely a dead end.

13:25 sdegutis: so weird

13:25 What is it used for?

13:25 justin_smith: sdegutis: basically, once your code is parsed, and they have an ast, they have a lisp for doing optimizations

13:26 {blake}: Greenspun's revenge!

13:26 justin_smith: because lisp is great and rearranging and interpreting asts, as we know

13:26 sdegutis: Why don't they just use a plain struct-based AST like a normal person?

13:26 krsto: Would anyone happen to know if leinigen has an included Node-Webkit project template? I've found some but not an official one.

13:26 justin_smith: {blake}: I think they were intentionally greenspunning here

13:26 sdegutis: because that's much weaker than a lisp

13:26 sdegutis: :|

13:27 justin_smith: sdegutis: and they are a bunch of lisp-loving weenies

13:28 sdegutis: ASTs are excellawesome

13:28 C structs too

13:28 Glenjamin: but you'll want a set of standard functions to manipulate them

13:28 might as well be in lisp :D

13:28 justin_smith: yeah, and why not aim for lisp, right

13:29 Glenjamin: this one? http://gcc-melt.org/

13:30 justin_smith: Glenjamin: I forget the name, but so far that looks like it. There was some controversy when it came out that they intentionally made it weaker / harder to use in order to prevent end-runs around the GPL.

13:31 jmontleon: how hard would it be to change building something with leiningen to clojure-maven-plugin. is this a pom file change for plugins, or something bigger?

13:31 justin_smith: Glenjamin: this looks recent enough that it could be a restart to make it more accesible (perhaps inspired by clang)

13:32 sdegutis: How ironic. The GNU people are so strictly opposed to proprietary works that they effectively make their own software proprietary so that nobody can bypass its "openness".

13:32 The most backwards and counterproductive mindset if I ever saw one.

13:32 justin_smith: jmontleon: you would need to make a pom with all your deps in it, right? or does clojure-maven-plugin know how to load project.clj?

13:32 sdegutis: yes, I was very annoyed to see how that played out

13:33 sdegutis: GNU has literally become its own enemy.

13:33 jmontleon: justin_smith, I do not know, but you can create a pom using leiningen, right?

13:33 Glenjamin: i always thought the GPL having specific technical distinctions between compiling and linking was odd

13:33 justin_smith: jmontleon: right, but if you were migrating from lein, you would then need to update the pom manually, I assume

13:34 jmontleon: justin_smith, ya, I'm not opposed to creating a pom using lein each time. The backstory is that we have a build system where we are able to use maven, but not lein

13:34 justin_smith: ahh

13:34 jmontleon: so if I want to build the clojar and I can do it with maven in the build system my life is happy

13:36 justin_smith: jmontleon: regarding plugins, I don't think any lein plugins will run without lein, so you would hopefully have a build that does not rely on plugins

13:38 jmontleon: justin_smith, I'll take a look

13:38 justin_smith: jmontleon: you may get better info from #leiningen too

13:38 jmontleon: thanks, i can ask there too

13:41 * sdegutis is looking up compojure.core/let-request

13:42 sdegutis: I'm all for emphasizing the "core" namespace as long as you think of it as "core vs extras" rather than "core vs exterior/shell"

13:45 justin_smith: sdegutis: compojure.tl-dr

13:45 sdegutis: justin_smith: did you just now come up with that?

13:45 justin_smith: yes, just now

13:45 sdegutis: justin_smith: because that's actually the perfect name for the primary namespace of any lib

13:45 justin_smith: may replace some .core with .tl-dr now

13:45 sdegutis: It's so incredibly accurate and conveyish.

13:46 justin_smith: my-proj.use-this-namespace

13:49 Glenjamin: you can have both myproject and myproject.other-stuff as namespaces with stuff in

13:49 technomancy: I'm a fan of breaking up the name of your project

13:49 slamhound -> slam.hound

13:50 use syllable boundaries if you have to

13:50 Glenjamin: any particular reason, or just for kicks?

13:50 justin_smith: s.l.a.m.-.h.o.u.n.d

13:50 technomancy: just don't make me load yet another "core" namespace uuuuugh

13:50 "core" means the opposite of "entry point"

13:50 justin_smith: via the above method, you can have a proper trie of available namespaces

13:51 Glenjamin: (:require [slamhound slamhound.misc]) ; works

13:51 so core isn't really needed, if you're ok with that

13:51 technomancy: Glenjamin: it's supposedly problematic if called from java

13:51 Glenjamin: ah

13:51 justin_smith: Glenjamin: that kind of breakup is annoying when using automated tools to find usages (ie. grep)

13:52 sdegutis: justin_smith: you have just solved the namespace problem for everyone

13:52 technomancy: only if you're thinking of an apple

13:52 justin_smith: sdegutis: I am glad that you appreciate this

13:52 sdegutis: justin_smith: I mean the .tl-rd namespace

13:52 justin_smith: right, OK

13:52 sdegutis: huh?

13:52 Glenjamin: :require myproject.dot

13:53 sdegutis: technomancy: core [noun]: "the central OR most important part of something" (emphasis mine)

13:53 The public interface is arguably the most important part of something because without it the library cannot be used effectively.

13:53 Glenjamin: :require myproject.public

13:54 technomancy: "interface" implies "outside" while "core" implies "inside"

13:54 Glenjamin: :require myproject.shell

13:54 justin_smith: myproject.fascia

13:54 Glenjamin: :require myproject.to-be-loaded

13:55 sdegutis: proj.entry, proj.public, proj.gateway

13:55 hyPiRion: sdegutis: perhaps one example: the core of a planet is not its outside

13:56 sdegutis: hyPiRion: Yes, there is the whole apple/planet definition of "core", but that's not the only meaning.

13:57 technomancy: it's the meaning used by clojure.core

13:57 Glenjamin: :require myproject.crux

13:57 sdegutis: technomancy: A word can be used in different ways at different times.

13:57 core: "[ often as modifier ] the part of something that is central to its existence or character"

13:57 The public interface is central to the character of a lbirary.

13:57 *libary

13:58 justin_smith: I think the usage of .core is meaningful in that it carries an ontological payload: we aren't about information-hiding, the core is the part you should care about

13:58 of course we can like using clojure without having to agree

13:59 sdegutis: justin_smith: From what I've seen of libraries, the "core" namespace almost always depends on private functions (granted they're all encapsulated within the core ns).

13:59 technomancy: sdegutis: that's because `lein new` is stupid

13:59 justin_smith: right, they are not using "core" they way clojure.core does I don't think

13:59 sdegutis: ok

13:59 TimMc: I agree, it's a bad default name.

14:00 justin_smith: I was referring to the intentional choice (the one clojure core devs made), not the unthinking usage of a default

14:00 TimMc: (Question: Does a good default name *exist*?)

14:00 Glenjamin: (ns changeme)

14:00 sdegutis: I like "gateway" personally. It's the way you get into the library.

14:00 technomancy: TimMc: I'm actually kind of tempted to change it to mylib.public

14:00 TimMc: Glenjamin: (ns FIXME)

14:00 justin_smith: TimMc: my-project.i-am-too-lazy-to-rename-my-primary-namespace

14:00 coming soon to a lein new pr

14:00 technomancy: for apps it should be .main of course

14:01 TimMc: justin_smith: Ooh, that's a good one! It'll annoy people into changing it.

14:01 sdegutis: technomancy: now let's not go crazy

14:01 TimMc: technomancy: I would also argue that lein new should not create a lib by default.

14:01 hyPiRion: Perhaps we should remove the default then

14:02 (no, I'm not serious)

14:02 sdegutis: fwiw I am using (macroexpand-1) to figure out how to stop using this library's DSL.

14:02 justin_smith: TimMc: maybe there is something that would draw the parallel to people you can tell are n00bs in an online game, because they don't do the most sensible customizations and use silly defaults

14:02 technomancy: TimMc: that ship has sailed, unfortunately

14:02 at least it tells you about the difference

14:02 hellofunk: what do you mean by lein new creating a lib?

14:02 technomancy: fixing it would invalidate tons of tutorials

14:03 hyPiRion: hellofunk: `lein new foo` is equivalent to `lein new lib foo`

14:03 TimMc: technomancy: shipit

14:03 justin_smith: haha, myproject.shipit would work

14:03 hellofunk: what does the actual lib do?

14:03 jkj: hellofunk: as not an app.. the default thing does not have main function

14:03 hellofunk: so you cannot directly run it as a program

14:04 hellofunk: jkj isn't that good? to not make an assumption that it should be run with a main entry point?

14:04 justin_smith: hellofunk: in case it is unclear, this is a template for making a new lib

14:04 jkj: you can start a REPL or you can make it a jar and use it as a dependency in another program

14:04 hellofunk: it think it is good

14:04 justin_smith: hellofunk: the dispute is about the default naming (and the annoyance of using libs that don't change that default naming)

14:04 hellofunk: it was suggested earlier that lein new should *not* make it a lib

14:05 justin_smith: I don't think so, I did not see that suggestion at all

14:05 TimMc: because new-comers are probably not making libs

14:05 newcomers?

14:05 hellofunk: justin_smith naming as in, the naming of the files?

14:05 TimMc: n00bs

14:05 justin_smith: ahh, I missed it

14:05 hellofunk: naming of namespaces

14:05 hellofunk: now I see where TimMc said that

14:06 hellofunk: if it was not a lib by default, then you just mean it would add a main function for app entry with every lein new project?

14:06 jkj: well.. entry point is something that app has but lib doesn't.. so isn't lib as the lowest common thing, a reasonable default for an amorphous blob of code that might become an app or something else later

14:07 hellofunk: jkj i agree.

14:07 jmontleon: justin_smith, that worked. thank you: Uploaded: file:///tmp/output/puppetdb/puppetdb/0.0-dev-build/puppetdb-0.0-dev-build.jar (70 KB at 23089.2 KB/sec)

14:07 hellofunk: by namespace defaults, are you referring to the single XX.core namespace generated?

14:07 jmontleon: traditionally it is built with leiningen

14:08 justin_smith: jmontleon: cool

14:08 hellofunk: yes, the whole .core thing

14:09 hellofunk: it becomes a sort of noise, and the more times it is not changed, the more it looks like a convention, rather than a silly default

14:09 hellofunk: justin_smith i see

14:09 seems like a trivial issue to me, especially considering how easy is it to change

14:09 jkj: se we should dump the core? (pun intended)

14:10 justin_smith: hah

14:11 jkj: mdfind -name core.clj|wc -l .... 278 ... argh

14:11 sdegutis: "I've tried on every programming opinion I've found, which is why I'm so confident that the few I still hold to are correct." lol

14:17 {blake}:

14:20 xeqi: Bronsa: /quit

14:46 sdegutis: Are all Compojure/Ring request keys likely and/or guaranteed to be keywords?

14:48 noonian: i think the default top-level ones are, but any middleware you are using can modify the request so no guarantees

14:49 sdegutis: Dang.

14:54 TimMc: My middleware converts all keywords into dynamically generated enums.

14:55 * justin_smith cites poe's law

14:56 amalloy: and eg the map under :headers will have string keys

14:58 gfredericks: oh that headers map is sooper weird

14:58 I can't remember if it's the jetty lib or clj-http but one of them uses a special case-agnostic map for headers

14:58 justin_smith: I would more likely believe jetty there

14:59 gfredericks: I think it was clj-http actually

14:59 it was a clojure thing, not jetty proper

14:59 probably used mister tellman's lib for making weird maps

15:00 amalloy: gfredericks: never attribute to ztellman that which can be explained by garden-variety madness

15:00 justin_smith: gfredericks: potemkin?

15:00 gfredericks: yeah

15:00 justin_smith: amalloy: gfredericks: potemkin https://github.com/dakrone/clj-http/blob/master/src/clj_http/headers.clj#L105

15:01 gfredericks: it's string/keyword agnostic too looks like

15:01 I had a super weird time figuring out why headers didn't roundtrip for my vcr-clj lib

15:01 justin_smith: ztellman made the gun, dakrone pulled the trigger

15:02 gfredericks: I'm curious if you folks think that was a good decision, or if an explicit (get-header req header-name) function woulda been better

15:02 justin_smith: gfredericks: I think this is designed for the case where add-header could be misused

15:03 or modify-header even

15:04 amalloy: gfredericks: i think it was a bad decision. i like the way ring does it: on the way in, headers are keywordized and downcased (and kebab-cased?), and on the way out i forget what happens but it's some kind of reasonable thing

15:04 justin_smith: gfredericks: oh, never mind, the comment explicitly says it is about lookup

15:04 amalloy: er no, headers aren't keywordized. i was thinking of stuff like :scheme

15:10 jmontleon: justin_smith, little more complex, but not by much: http://www.dotkam.com/2014/07/02/pom-pom-clojure/

15:11 i realized i was just getting a jar, not an uberjar; seems that can be fixed though too

15:11 justin_smith: jmontleon: cool

15:11 hellofunk: amalloy i thought Ring made all headers into keywords, weren't you right the first time?

15:11 justin_smith: jmontleon: I am bookmarking that for sure

15:12 hellofunk: not in my experience

15:12 hellofunk: perhaps one of your middleware is doing that

15:12 hellofunk: justin_smith oh maybe I do have something in their. i'm using Friend, perhaps that's involved somehow

15:12 mgaare: is there a clojure equivalent to java's import package.whatever.*

15:13 justin_smith: mgaare: no

15:13 amalloy: mgaare: it's discouraged in java anyway

15:13 justin_smith: mgaare: makes using some libs kind of annoying, right (opengl I am looking at you)

15:13 mgaare: sure does

15:18 arrdem: .away

15:26 sdegutis: I'm using [compojure "1.2.1"] but it still fails claiming "compile-route is not public" -- what gives?

15:28 justin_smith: sdegutis: are you sure that's the version that's getting loaded? you may want to check the output of "lein deps :tree"

15:28 noonian: sdegutis: might check if lein deps :tree | grep compojure returns any other versions

15:29 justin_smith: noonian: well, without the grep he would also see the "conflicting versions" warnings at the top :)

15:29 or am I imagining those

15:29 *misremembering

15:29 noonian: heh, i get overwhelmed when my terminal scrolls wildly :P

15:29 sdegutis: I only see compojure "1.2.1" in here.

15:29 But I see a lot of "overrides" on the line before it.

15:30 justin_smith: sdegutis: there is also "lein cp"

15:30 see what version shows up in there

15:30 also - if you are very unlucky, one of your lib deps is aot'd with an old verison

15:30 sdegutis: 1.2.1

15:30 :(

15:31 noonian: sdegutis: are you using any ring lein plugins?

15:31 sdegutis: Don't think so.

15:31 Only plugin I can see is Speclj.

15:36 Is compojure["1.2.1"].core/compile-routes public for anyone else?

15:38 Are good programmers also typically good at chess?

15:40 justin_smith: sdegutis: when I load compojure 1.2.1 compojure.core/compile-routes seems not to exist, public or not

15:40 and I have verification from alembic that 1.2.1 was the version I got

15:40 sdegutis: Whoa, this is getting pretty twilight zone up in here.

15:41 justin_smith: wait

15:41 clrnd: sdegutis, not that I know of

15:41 justin_smith: compile-routes or compile-route

15:41 clrnd: maybe imperative programmers ;)

15:41 sdegutis: compile-route sorry

15:41 justin_smith: sdegutis: yeah, that is private

15:42 sdegutis: but the source does not mention it being private

15:42 somethig else must set it private manually

15:42 (I am looking at the same jar I have loaded, it is using defn, not defn-)

15:42 sdegutis: justin_smith: Or he might have accidentally uploaded the wrong artifact?

15:43 justin_smith: sdegutis: no, opening the jar and reading the source, it is public, checking in the repl, that loaded the same jar (with verification) it is private

15:43 sdegutis: Oh.

15:43 Weird!

15:43 justin_smith: unless he deployed a class file that is stale...

15:44 no, I see no class files in there

15:44 dbasch: justin_smith: compile-route is public

15:44 sdegutis: A jar is just a zip file, right?

15:44 gfredericks: I use `unzip foo.jar` all the time


15:44 ,'test

15:44 clojurebot: test

15:44 justin_smith: dbasch: not in my version - I can share a paste verifying this

15:45 technomancy: gfredericks: not C-x C-f foo.jar?

15:45 dbasch: justin_smith: in 1.2.1

15:45 not in 1.2.0

15:45 justin_smith: OH!

15:45 never mind

15:45 dbasch: my mistake

15:45 I misread the alembic output

15:45 sdegutis: oops, just unzipped a .jar onto my Desktop

15:45 justin_smith: sdegutis: I was getting the wrong version, missed it in some boilerplate printout

15:45 haha

15:45 sdegutis: what editor do you use? emacs can browse / edit jar files

15:47 sdegutis: justin_smith: shell + tree

15:47 justin_smith: sdegutis: you use shell + tree as a text editor?

15:48 gfredericks: technomancy: zomg

15:48 justin_smith: vim can read jars too, it's not an emacs only thing

15:48 sdegutis: hi

15:48 gfredericks: (inc technomancy)

15:48 lazybot: ⇒ 160

15:49 justin_smith: gfredericks: awesome, huh

15:49 timvisher-xubunt: technomancy, gfredericks: http://xkcd.com/1053/

15:50 justin_smith: timvisher-xubunt: clearly, "emacs opens jar file contents" is something every adult should know :)

15:51 (not that my sarcasm undermines the point at all)

15:51 timvisher-xubunt: justin_smith: ^_^

15:53 technomancy: timvisher-xubunt: a magical moment indeed!

15:53 sdegutis: So what's making compile-route private?

15:53 justin_smith: sdegutis: I bet you didn't really get the version you thought you did

15:53 dbasch: sdegutis: why don’t you paste your project.clj somewhere?

15:54 sdegutis: dbasch: it's proprietary

15:54 justin_smith: technomancy: which novena did you order, and when does it show up?

15:54 sdegutis: justin_smith: all tests everyone has suggested have passed

15:55 daGrevis: hello, lispers! what's the best way to get a random item out of vector and return the item AND new vector (without that item)?

15:55 justin_smith: sdegutis: here's another possible test: temporarily move ~/.m2/repository/compojure/compojure/ somewhere else, run lein deps, see which version actually downloads

15:55 sdegutis: can I just rm -rf ~/.m2 ?

15:55 justin_smith: sdegutis: if you want to do a bunch of downloads and break things that rely on local installs, sure!

15:56 xemdetia: you can just use dired in emacs to look in .jar files :(

15:56 sdegutis: daGrevis: split-at and first maybe?

15:56 justin_smith: xemdetia: that makes you sad?

15:56 xemdetia: justin_smith, I just started working in a vim shop

15:56 {blake}: heh

15:56 justin_smith: xemdetia: vim can open jars though right?

15:57 xemdetia: I don't know, I pretend I am using vim and use emacs instead

15:57 daGrevis: sdegutis, how would I get back the new vector? by concating those splitted parts back together?

15:57 sdegutis: daGrevis: or you can just do (let [c (drop n coll)] [(first c) (rest c)])

15:58 technomancy: justin_smith: I got the desktop one. supposedly arrives in December?

15:59 sdegutis: justin_smith: I just opened "core.clj" inside "~/.m2/repository/compojure/compojure/1.2.1/compojure-1.2.1.jar" and it is not private.

15:59 andyf: If someone knows how to make an emacs compilation-mode buffer with a file name that looks inside a jar, I'd like to know

16:00 justin_smith: ,(defn extract-rand [v] (let [n (rand-int (count v))] [(get v n) (into [] (concat (take n v) (drop (inc n) v)))]))

16:00 clojurebot: #'sandbox/extract-rand

16:00 justin_smith: ,(extract-rand [1 2 3 4 5 6])

16:00 clojurebot: [2 [1 3 4 5 6]]

16:01 andyf: I tried /path/to/file.jar:path/in/jar.clj without success , even though that works with c-x c-f

16:01 justin_smith: ,(extract-rand [42 420 666 "☃"])

16:01 clojurebot: [42 [420 666 "☃"]]

16:01 justin_smith: daGrevis: ^

16:01 sdegutis: sure, that's why I suggested setting aside the whole dir, and seeing what get's downloaded

16:02 daGrevis: wow, cool, justin_smith. real nice!

16:02 sdegutis: still not public

16:02 :/

16:02 justin_smith: technomancy: cool

16:02 sdegutis: what version did it say it was downloading?

16:02 daGrevis: anyway, i must ask. why isn't something like that in standard lib? it's a normal thing to want in clojure, right?

16:02 justin_smith, sdegutis ^

16:03 justin_smith: daGrevis: I've never had to do it before

16:04 amalloy: daGrevis: it's not made easy because vectors aren't a good data structure for this access pattern

16:04 sdegutis: 1.2.1

16:04 justin_smith: daGrevis: part of why it is not in stdlib is taking something out of the middle of a seq has no efficient implementation for the standard clojure datatypes, and implementing things that don't have good efficient algorithms is avoided in core

16:04 sdegutis: daGrevis: I never needed it, no.

16:04 andyf: daGrevis: Shuffle is in core, which is not what you asked for, but might suit your purposes

16:04 daGrevis: amalloy, hmm, interesting. what data structures should I be using instead?

16:05 justin_smith: daGrevis: just because it is inefficient doesn't mean you have to change - depends how often you do it. But core is fastidious about providing things that are fast, for the most part.

16:05 amalloy: even a sorted map from integer to value would not be unreasonable

16:05 daGrevis: thanks for the answers. i need to experiment with this a bit, i'll be back

16:06 amalloy: or a heap with a comparison function that's effectively random, eg based on hashcode

16:07 justin_smith: technomancy: I look forward to hearing about your awesome arm machine sometime in december then

16:08 technomancy: justin_smith: hoping to blog about it

16:08 though ... yeah. that might take a while since I'm planning a big move

16:09 justin_smith: I like that the laptop version uses OTS rc battery packs

16:10 sdegutis: How do you call a private macro in Clojure?

16:12 amalloy: sdegutis: you can't, really, without making a copy of the var and putting it somewhere public. are you sure you want to? would it be better to drive to the author's house and harangue him instead?

16:13 sdegutis: There's a macro, foo.core/bar, and I would normally call it (bar quux), but it's private. So I have (#'foo.core/bar quux) but it says wrong number of arguments.

16:13 technomancy: just run clojure.repl/source on the macro, do a string replace to get rid of ^:private, and pass it to read-string+eval

16:14 easiest thing in the world

16:14 amalloy: sdegutis: right, like i said, you can't do that

16:15 sdegutis: Okay.

16:16 {blake}: I'm trying to AJAXify a form created in my Ring/Compojure/Hiccup/Bootstrap web app. If I were writing the Javascript directly, I would do something like this: http://stackoverflow.com/questions/425095/submit-form-using-ajax-and-jquery

16:16 So my question is: Do I shoehorn that in, or is there a more Clojure-y way?

16:17 sdegutis: technomancy: that's genius actually

16:17 amalloy: technomancy: now look what you've done

16:17 technomancy: sdegutis: http://gif-central.blogspot.com/2013/07/nope-badger.html

16:19 sdegutis: too late im doin it

16:19 {blake}: What could possibly go wrong?

16:20 amalloy: sdegutis: if you are determined to wall-hack your way in, i recommend my approach over technomancy's: copy the var with something like (def ^:macro my-macro @#'private-macro)

16:20 {blake}: Maybe I just gotta bite the bullet and go full Clojurescript.

16:21 justin_smith: amalloy: damn, you shouldn't publish a macro that does that in a lib called wall-hack, but it would be disgustingly awesome if you did

16:21 arohner: justin_smith: https://github.com/arohner/clj-wallhack

16:21 mavbozo: {blake}: jquery usage is fine

16:22 arohner: justin_smith: but mine works on java privates, not clojure privates

16:22 {blake}: mavbozo: What does that mean?

16:22 amalloy: justin_smith: the name is borrowed from uh, i think clojure.reflect?

16:22 justin_smith: ahh, OK - or the thing arohner linked above

16:23 amalloy: nah, i've never seen that before, so i can't have stolen the name from there

16:23 arohner: amalloy: hiredman originally named it, in old contrib

16:23 justin_smith: amalloy: he got it from hiredman / contrib

16:23 arohner: it comes from a common hack in quake 1 multiplayer

16:23 amalloy: ah, that's right. not the current clojure.reflect, but the old one in contrib

16:24 mavbozo: {blake}: if you use javascript only to submit form, then use jquery

16:24 {blake}: mavbozo: Oh, okay, thanks.

16:30 sdegutis: amalloy: hmm

16:31 {blake}: that's /never/ the answer

16:31 {blake}: sdegutis: What's /never/ the answer? It's not violence, is it? Because I find violence is usually the answer, in the proper magnitude.

16:31 sdegutis: {blake}: that's a recycled joke

16:32 {blake}: I can literally see the newspaper article it was made from sticking out the end of it

16:32 {blake}: sdegutis: What is? I'm new here, I don't know from recycled.

16:32 sdegutis: {blake}: your nick hurts my pinky for holding shift

16:32 {blake}: you stole that joke from jack handey

16:32 "deep thoughts with jack handey" which are quite good

16:33 {blake}: sdegutis: Oh! Possibly. I've been guilty of unconscious plagiarism before. And I even stole =that= from George Harrison.

16:33 sdegutis: So, what is /never/ the answer, again?

16:34 sdegutis: hi

16:43 justin_smith: is there a version of pmap that doesn't preserver order?

16:43 ucb: is there any way in which I can eval some parameters passed to a macro and not others?

16:43 justin_smith: because I have a bunch of parallel tasks, and I don't care about the order, I just want all the results...

16:43 ucb: e.g. (let [a 1] (my-macro a)) means my-macro will see 'a and not 1

16:44 ideally, I'd be able to have my-macro see pre-evaled values

16:44 (I can provide my actual use case if it'll make it easier to answer the question)

16:44 justin_smith: ucb: why would it be a macro?

16:44 ucb: ah, here we go, ok, this is what I'm trying to do

16:44 I have a bunch of fns that operate on state

16:44 and I'm trying to keep this state across redefs of these fns

16:45 so I'm using the body of the fn as the key into a hashmap

16:45 and the state as the value

16:45 now, that's fine in principle

16:45 and it works

16:45 dbasch: justin_smith: ma(dca)p

16:45 ucb: the problem is that it doesn't work in the case of (doseq [n (range 10)] (the-macro n))

16:45 because the 10 different versions will share or trump each other's state

16:45 makes sense?

16:46 justin_smith: dbasch: heh, the results are useful regardless of ordering (they carry enough data to put them where I need them)

16:46 ucb: and the reason why this is a macro is because I want to create fresh new state when the body of the fn changes

16:47 but re-evaling these definitions creates new fns, so I can't have it as a function

16:47 justin_smith: dbasch: oh, wait, looking at the source of pmap - since I won't return until I hve all results, and the operation is very time-expensive, this may be one of the few cases where pmap is the right answer

16:47 jeremyheiler: justin_smith: i think you'd have to do something custom so that each map function call reports when it's done so that it can be returned into a lazy seq

16:47 justin_smith: jeremyheiler: I don't even want laziness though

16:48 I just want all the results to evaluate in parallel as much as they ar able

16:48 danielcompton: justin_smith: you could use something like reducers or core.async to work on things in parallel?

16:48 justin_smith: danielcompton: there is no reduction step, all results are independent of one another, and core.async doesn't want io in go blocks, and this is io heavy...

16:49 danielcompton: justin_smith: https://clojure.github.io/core.async/#clojure.core.async/pipeline

16:49 justin_smith: https://clojure.github.io/core.async/#clojure.core.async/pipeline-blocking

16:49 justin_smith: danielcompton: oh, pipeline-blocking my just be the thing, thanks!

16:52 danielcompton: justin_smith: or you could make your own reducing function which combines multiple results,

16:52 justin_smith: like I said, no reduction stage, the results are all independent but also all needed

16:52 danielcompton: justin_smith: sorry that wasn't clear, all the reduce would do is concat the results

16:53 justin_smith: sql query results, queries on mulitiple tables, with no inter-query logic

16:53 ahh! interesting

16:54 danielcompton: so map in parallel, reduce (fold) in parallel to concat, and you'll get back a collection of results but not in order

16:54 justin_smith: right

16:55 well in-order is fine, but not needed :)

16:55 dbasch: justin_smith: so why don’t you spawn a bunch of futures that put the results in a queue?

16:56 justin_smith: dbasch: that would totally work, yeah

16:56 danielcompton: justin_smith: it's worth benchmarking, and it may be a wash with your external IO, but I'd expect reducers to be faster

16:57 justin_smith: OK - I'll benchmark a few versions pmap,reducers,pipeline,future+queue and either get rate-limit kicked out by my db or have an interesting answer by the time it is done :)

16:58 is there a program that forwards a local port and simulates realistic network latency? because that would be kickass for benchmarking this

16:58 danielcompton: tc can do latency

16:59 justin_smith: danielcompton: oh, nice, checking it out, thanks

16:59 ucb: justin_smith: no thoughts then? :)

16:59 danielcompton: justin_smith: you could make a second loopback interface and run tc on that only

17:00 justin_smith: danielcompton: yeah, I would definitely not want to mess with my latency overall :)

17:00 danielcompton: justin_smith: that would give some confusing results

17:00 justin_smith: ucb: sorry, bot wrapped up in my own work

17:00 ucb: no worries :)

17:00 justin_smith: *bot

17:00 *Got

17:00 wow

17:01 ucb: let me know if anything comes to mind as to how to better solve this

17:01 justin_smith: using macros for state feels really weird... I don't know what to say beyond that

17:03 ucb: heh

17:03 well, I'm happy to change approaches

17:03 as this is clearly not working out

17:10 justin_smith: if you don't mind me asking, how would you handle this?

17:12 sdegutis: Wait, compojure.core/compile-route is a function that returns code as data???

17:12 lazybot: sdegutis: Yes, 100% for sure.

17:19 annelies: I think I have my AWK library kinda working.

17:19 Still not sure on state management though. You currently can't keep any state.

17:20 danielcompton: I'm working on a leiningen plugin which depends on a library for it's main function (kibit). I've followed the instructions to checkout kibit in lein-kibit, and add .lein-classpath in my test project, but the checkout changes in kibit don't seem to be picked up.

17:20 Are checkout dependencies supported in leiningen plugins?

17:23 technomancy: danielcompton: you have to add everything to .lein-classpath

17:23 sdegutis: annelies: FP and state aren't friends

17:23 technomancy: you can't just add lein-kibit and have it pick up kibit

17:23 annelies: State is very useful when reading text files in certain formats.

17:24 danielcompton: technomancy: ahh, I assumed the checkout dependencies would be picked up instead

17:24 annelies: You'd usually keep it with recursion but I want my library to do the recursion for you.

17:25 danielcompton: technomancy: are checkouts only used when you're working directly in that project?

17:25 justin_smith: annelies: what about letting the user return any state in a map at each loop step? perhaps as an option arg to a return function

17:25 technomancy: danielcompton: right

17:25 annelies: Yeah I was thinking about that.

17:25 technomancy: danielcompton: there's a lot less magic going on than you probably think

17:26 annelies: Instead of returning a sequence you'd return [some-sequence new-state]

17:26 technomancy: for some reason this is a feature that everyone overcomplicates in their head. it's like ten lines.

17:26 justin_smith: ucb: what about giving each function a keyword that maps to its state? at least that would be intelligible and persistent

17:26 danielcompton: technomancy: do you mind if I pull request the documentation for plugins about this?

17:26 technomancy: danielcompton: sure

17:27 ucb: justin_smith: I thought of that, and I'm reconsidering. I initially had it like that, but the problem is that these have to be unique, and repeatable, and I will have quite a few ...

17:27 justin_smith: but I might just have to bite the bullet

17:27 justin_smith: by repeatable I mean that I just can't use gensym

17:28 justin_smith: ucb: something derived from the namespace / name of the function? a macro could help there

17:29 ucb: right, yes, but then I have top-level functions that take some form of config and return the actual function

17:29 perhaps include the config in there as well

17:29 fwiw, these fns are riemann streams

17:29 (in case you're familiar with them)

17:31 sdegutis: arohner: wait aren't you usually in #clojure?

17:31 arohner: sdegutis: I am in #clojure

17:31 sdegutis: arohner: I thought I remember you're often in #clojure talking and saying stuff and writing libs

17:32 justin_smith: ucb: it seems like you want to be able to reliably look up the functions, in that case I would give up on using them directly, and either pass around their vars (which are used via lookup) or put them in a map where you grab them via keyed lookup

17:32 ucb: justin_smith: https://gist.github.com/4f9e5490fc872789d535 <- this is the most basic building block actually

17:32 arohner: sdegutis: yeah?

17:32 sdegutis: arohner: so when did you get into Swift?

17:32 arohner: sdegutis: aha

17:32 sdegutis: arohner: it was just a surprise seeing you in there is all

17:32 ucb: justin_smith: not the functions, but rather the state they'll work with

17:32 arohner: working on a native app that talks to a clojure server

17:32 started in August-ish

17:33 sdegutis: arohner: for OS X?

17:33 justin_smith: ucb: well that's easier isn't it? store their state outside the function, and define the function such that it knows how to look it up?

17:33 arohner: sdegutis: yep

17:33 sdegutis: arohner: sounds fun, is it open source?

17:33 ucb: justin_smith: that's exactly what I'm doing. I just updated the gist.

17:33 arohner: sdegutis: no, but it's related to: https://app.getflowmeter.com/blog/productivity.html

17:33 sdegutis: arohner: gonna sell it?

17:33 ucb: justin_smith: you'll see I'm using the function's body as key, but that breaks badly because macros and eval

17:33 arohner: sdegutis: yep

17:33 ucb: justin_smith: I'll have to abandon the body-as-key approach it seems ;_;

17:34 justin_smith: ucb: yeah, I would use something more explicit than the function body as a key

17:34 godd2: that's a nice line of vertical semicolons

17:34 sdegutis: arohner: oh :)

17:34 ucb: it's a pity, because the resulting DSL was very nice to work with

17:34 godd2: err, colons

17:34 ucb: it had a slight problem: IT WAS BROKEN

17:34 sdegutis: arohner: how do you like Swift so far compared to Clojure?

17:34 arohner: I don't like it very much

17:34 justin_smith: ucb: with a good macro, you should be able to achieve that elegance, especially if you had it once

17:34 arohner: it's better than objc though

17:34 sdegutis: arohner: why do you hate it so much?

17:35 arohner: I didn't say hate :-)

17:35 justin_smith: ucb: for example, have the macro use the namespace / name of the function (easy to get based on the body) as the lookup / storage key

17:35 ucb: + whatever config it might be passed on

17:35 sdegutis: arohner: well what do you "not like" about it?

17:35 danielcompton: technomancy: is .lein-classpath a multiline or single line file? what's the separator between entries?

17:35 ucb: recall that I have many top-level functions that generate these functions

17:36 but yeah, something like that

17:36 arohner: sdegutis: it's a nice improvement on objc. The big downsides are: 1) no repl 2) C compilation model

17:36 sdegutis: 3) weak datastructures

17:36 sdegutis: arohner: i took it to Swift-Lang for on-topic-ness

17:36 arohner: no, I'm not going to complain about swift in #swift

17:36 justin_smith: haha

17:36 ucb: justin_smith: where would I go and read more about finding the ns an fn has been defined in, and its name, and so on?

17:37 justin_smith: ucb: in a macro, the ns will be *ns*

17:37 for the name - you can provide that as part of the form

17:37 ucb: *nod*

17:37 thanks!

17:37 justin_smith: ,((fn named [] 1))

17:37 clojurebot: 1

17:37 justin_smith: ucb: you could even assert that the name part is there in the fn, with an informative message, from inside the macro

17:38 ucb: yeah, good idea

17:38 justin_smith: since you are looking at the form

17:38 ucb: not sure I'll be able to get named fns

17:38 justin_smith: wait, where are they coming from?

17:38 ucb: they'll come as body

17:39 e.g. (some-predicate arg1 (some (seq ...)))

17:39 justin_smith: oh - the inside part

17:39 that' a problem

17:39 ucb: where some-predicate is a macro that eventually becomes (defstream ...)

17:39 yes, it is!

17:39 oyvinrob: hyPiRion: regarding https://github.com/technomancy/leiningen/issues/1765

17:40 justin_smith: ucb: I'll get back to you, I do need to make progress on this query thing, sorry

17:40 ucb: justin_smith: no rush, it's zzz time here anyway

17:40 oyvinrob: hyPiRion: if you're referring to the stacktrace being logged, that has already been fixed

17:40 ucb: thanks for paying attention to my sillies

17:41 sdegutis: arohner: what do you mean by weak datastructures

17:44 oyvinrob: hyPiRion: I think, at least

17:46 kenrestivo: what's that link to that cool interactive clojure source browser that lets you search for every usage of a function/protocol/namespace, etc?

17:46 i think it pulls in every clojure project off of github and indexes it.

17:47 xemdetia: grimoire

17:47 kenrestivo: that's it, thanks!

17:48 no, it was crossclj, that's what i was thinking of

17:49 oyvinrob: hyPiRion: also, I just realized this isn't #leiningen

17:51 sdegutis: arohner: anyway i havent used swift yet, and im only on chapter 3 of the swift book, so i truly have no idea what ur talkin about

17:55 justin_smith: kenrestivo: that one takes submissions, it doesn't spider

17:55 though spidering would be cool

17:56 kenrestivo: /msg *status ClearBuffer #clojure

17:56 technomancy: we wrote a plugin at seajure that runs the tests for all libs that depend on you

17:56 so you can see if a change you're considering breaks your users

17:57 (like all seajure projects, it was more of a poc)

18:00 EvanR: is it possible to implement a protocol for the java array class

18:01 Bronsa: EvanR: yeah, (extend-protocol p (Class/forName "[B") (f [_] ..)) for example

18:02 EvanR: is there a way to cover that array and vectors at the same time

18:03 Bronsa: EvanR: no you have to extend each class on its own

18:04 EvanR: though if you use `extend` you can reuse the impl

18:04 EvanR: class/interface right, IPersistentVector

18:04 Bronsa: like, (def impl {:f (fn [_] ..)}) (extend Class1 impl Class2 impl ..)

18:04 I meant (extend g ..)

18:05 EvanR: ,(Class/forName "[B")

18:05 clojurebot: [B

18:05 EvanR: whats B

18:05 justin_smith: it's the name of the class for byte-array

18:06 ,(class (byte-array 0))

18:06 clojurebot: [B

18:06 EvanR: im not sure if thats the java array i was thinking of

18:07 Bronsa: EvanR: it was just as an example

18:07 justin_smith: which one are you thinking of?

18:07 EvanR: ,(type (make-array Object 0))

18:07 clojurebot: [Ljava.lang.Object;

18:07 EvanR: L?

18:07 ,(type (byte-array 0))

18:07 clojurebot: [B

18:08 Bronsa: EvanR: yeah it's different for object arrays vs primitive arrays

18:08 EvanR: the internal name is [<<primitive class name>> or [L<<fully qualified class>>;

18:08 EvanR: do i need a different implementation for every possibly object array

18:09 or can i just implement it for [Ljava.lang.Object;

18:11 Bronsa: EvanR: http://sprunge.us/VeFe?clj

18:12 EvanR: basically no

18:12 Bronsa: correct

18:12 EvanR: sweet

18:12 Bronsa: EvanR: the only "catch-all" type is Object

18:12 EvanR: you could extend Object and test for (.isArray this) in the impl

18:13 (.isArray (class this)) rather

18:13 EvanR: would that clobber my implementations for non array classes, interfaces, and deftypes?

18:13 or just classes

18:16 is this [Foo pattern the same for all java generics?

18:20 justin_smith: EvanR: generics have no existence in the jvm, it only exists in the compiler for type checking

18:20 EvanR: it's called "type erasure"

18:21 EvanR: erm

18:21 but we have [Lsomeclass

18:22 so either this is not generics or type erasure means something else

18:22 justin_smith: EvanR: arrays are not generic

18:23 EvanR: they are special?

18:23 justin_smith: there is a separate class for an array of each primitive

18:24 which is manually created, not using any kind of generic feature

18:24 EvanR: i dont care about those i only care about array of class X

18:24 justin_smith: EvanR: class X can only be Object

18:24 wait...

18:24 let me double check that :P

18:24 EvanR: ,(type (make-array java.util.Date 0))

18:24 clojurebot: [Ljava.util.Date;

18:25 justin_smith: don't mind me...

18:25 EvanR: if it could only be object that would be awesome

18:27 justin_smith: EvanR: so sorry, thought I new this stuff but clearly got myself tripped up

18:27 EvanR: it appears that in java, arrays cant use generics, so they are something else

18:28 justin_smith: OK, good to know I was at least right on this count

18:28 TimMc: Arrays are friggin' weird, I don't even know what they are.

18:28 EvanR: it has to do with subtyping crap

18:28 ArrayList however is apparently generics

18:29 irrelevant to me so im not going to see if you can implement a protocol for it

18:29 but this is certainly confounding to my design

18:29 justin_smith: "The reference type of the Java virtual machine is cleverly named reference. Values of type reference come in three flavors: the class type, the interface type, and the array type. "

18:29 http://www.artima.com/insidejvm/ed2/jvmP.html

18:30 so arrays are a separate thing, parallel with interfaces and classes

18:30 EvanR: nice, the triple entente

18:32 * EvanR puts some if statements in in case an array shows up

18:38 TimMc: &(make-array Void 1 2 3 4)

18:38 lazybot: ⇒ #<Void[][][][] [[[[Ljava.lang.Void;@19ff188a>

18:39 justin_smith: FUN

18:39 EvanR: the hell is java.lang.Void

18:39 justin_smith: "The name of an array's class has one open square bracket for each dimension plus a letter or string representing the array's type."

18:39 TimMc: It doesn't matter, you can't have one.

18:40 &(apply make-array Void (repeat 100 1))

18:40 lazybot: ⇒ #<Void[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][] [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[... https://www.refheap.com/93740

18:40 EvanR: The Class object representing the pseudo-type corresponding to the keyword void.

18:40 o_O

18:41 TimMc: not to be confused with null

18:41 amalloy: EvanR: used in reflection. if you ask what the return type of System.out.printin is, you need Void to exist

18:41 TimMc: &(class (apply make-array Void (repeat 10000 1)))

18:41 lazybot: java.lang.IllegalArgumentException

18:41 TimMc: hmmm

18:41 andyf: Huh. I never noticed before that you could start comments with #! in Clojure. Useful for executable files that have that as first line on unixes

18:42 justin_smith: yupyup

18:42 TimMc: &(class (apply make-array Void (repeat 255 1)))

18:42 lazybot: ⇒ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[Ljava.lang.Void;

18:42 andyf: But looks like it can be anywhere in file

18:42 TimMc: &(class (apply make-array Void (repeat 256 1)))

18:42 lazybot: java.lang.IllegalArgumentException

18:42 amalloy: andyf: indeed that's what it's for

18:42 EvanR: ,(Void.)

18:42 clojurebot: #<CompilerException java.lang.IllegalArgumentException: No matching ctor found for class java.lang.Void, compiling:(NO_SOURCE_PATH:0:0)>

18:42 amalloy: EvanR: there's no way to instnatiate it

18:43 TimMc: *No* way?

18:43 EvanR: so the class itself is used as the value

18:43 so java/something has first class classes?

18:43 amalloy: TimMc: i mean, you can use reflection to get around the access controls. but it has no public constructors, and no private constructors that are ever used

18:43 EvanR: classes are certainly first class

18:43 EvanR: in clojure

18:44 amalloy: and in java

18:44 EvanR: oO

18:44 a class is an object of class Class or something?

18:44 amalloy: EvanR: exactly, yes

18:44 EvanR: and Class is class Class?

18:44 amalloy: &(class String)

18:44 lazybot: ⇒ java.lang.Class

18:44 amalloy: &(class Class)

18:44 lazybot: ⇒ java.lang.Class

18:45 TimMc: ,(let [c (first (.getDeclaredConstructors Void))] (.setAccessible c true) (.newInstance c (object-array [])))

18:45 clojurebot: #<Void java.lang.Void@1ad6d84>

18:45 TimMc: ^ that right thur is a Void instance

18:45 amalloy: TimMc: well like i said, you can cheat

18:45 TimMc: I sure can.

18:45 * justin_smith hides from The Thing That Should Not Be

18:46 justin_smith: the Void has come! IA!

18:46 TimMc: If they *really* wanted there to not be an instance, they could have put a throw in the constructor.

18:46 EvanR: call the destructor on it

18:46 TimMc: ,(def void (let [c (first (.getDeclaredConstructors Void))] (.setAccessible c true) (.newInstance c (object-array []))))

18:46 clojurebot: #'sandbox/void

18:47 TimMc: (.finalize void)

18:47 clojurebot: Gabh mo leithscéal?

18:47 TimMc: ,(.finalize void)

18:47 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: No matching field found: finalize for class java.lang.Void>

18:47 TimMc: Oh, it's protected. That makes sense.

18:47 EvanR: if the gc encounters a Void it will cause a full collapse of the universe

18:49 TimMc: I'm guessing having an instance doesn't actually alow you to cause any shenanigans.

18:49 You could declare that your method returns Void and return an instance, but whatever.

18:50 EvanR: in this sense void or Void is basically the unit type

18:51 TimMc: Not even.

18:51 void methods can't return null

18:51 I think null is more like Unit.

18:51 amalloy: TimMc: no, void is like unit

18:51 EvanR: null doesnt have a type

18:52 amalloy: in scala, i believe void methods actually do return unit, like in clojure they return nil

18:52 TimMc: amalloy: You wouldn't say that a Java type declaration of String is a union type of the String class and the null "class"?

18:52 EvanR: null doesnt fit in

18:52 amalloy: TimMc: i don't see how an answer to that question is related to whether void is like unit

18:53 TimMc: fair

18:53 EvanR: in ruby nil is a NilClass

18:53 amalloy: java's String is indeed like a `Maybe String`, which is equivalent to a union of String and ()

18:53 TimMc: amalloy: Aren't you supposed to be able to get an instance of Unit?

18:54 amalloy: TimMc: i don't think type theory trouble itself with "instances"

18:54 dbasch: TimMc: the one and only instance of Unit

18:54 amalloy: a method which returns nothing is the same as a method which always returns the same thing

18:54 TimMc: hrmf :-)

18:54 amalloy: it provides the same amount of information

18:55 EvanR: does java stop you from assigning the result of a void function to a variable

18:55 amalloy: yes

18:55 dbasch: EvanR: there is nothing to assign

18:55 EvanR: small favors

18:56 dbasch: well, except an instance of Void ;)

18:56 dbasch: EvanR: a void method doesn’t return Void

18:56 EvanR: it doesnt return anything, i was talking about hypothetically

18:57 Void exists and it can be instantiated despite documentation saying otherwise

18:57 * TimMc wishes the Java folks would go ahead and make String? a delcaration you can use and incorporate nil into the type system.

18:57 dbasch: EvanR: you said void, not Void

18:57 EvanR: "nullable" is annoying

18:57 TimMc: EvanR: "can be" is relative, here

18:57 EvanR: use a sum type to wrap whatever type

18:57 TimMc: Any code with setAccessible is cheating.

18:58 EvanR: let null pointers go

18:58 {blake}: I inspected Void once. It inspected me back.

18:58 technomancy: nulls: literally the worst thing in programmering languages

18:58 dbasch: {blake}: you’re thinking of Abyss

18:58 TimMc: "What are you doing?"

18:58 "Programmering."

18:59 dbasch: the gaze method of Abyss takes a callback parameter

19:00 {blake}: Which one cannot help but pass.

19:00 EvanR: does it implement the null object pattern

19:00 dbasch: long gaze()

19:00 TimMc: I don't see a callback there!

19:01 It knows where you live.

19:01 andyf: technomancy: People get so worked up over nothing :-)

19:01 {blake}: My address is a global variable.

19:01 * TimMc mutates {blake}'s address

19:01 {blake}: Great. Now how am I going to get home?

19:02 dbasch: {blake}: home is where the heart was assigned

19:03 {blake}: dbasch: (ns range) (def home :heart)?

19:03 EvanR: in addition to null i would like everything listed here http://hl7.org/implement/standards/fhir/null-flavor.html

19:04 TimMc: NINF and PINF seem like they don't belong there

19:04 EvanR: you dont encode infinity as a null?

19:04 jeez

19:05 TimMc: both of them

19:05 positive null and negative null

19:05 ,(with-meta nil nil)

19:05 clojurebot: #<NullPointerException java.lang.NullPointerException>

19:06 EvanR: i cast "Null Pointer Exception" at the darkness

19:07 dbasch: NullPointerException is one of the least exceptional exceptions

19:08 EvanR: more like NullPointerRule

19:08 TimMc: snrk

19:11 amalloy: NullPointerTedium

19:12 at least it's a pointer in java. in c#, they need to put up with the extra syllable in NullReferenceException

19:12 EvanR: its so different from java

19:12 http://c-faq.com/null/

19:14 everything you never wanted to know about null pointers

19:16 TimMc: public class NullAgain extends RuntimeException

19:16 Even Noooooo would be shorter

19:23 clojer: In Rich Hickey's Clojurescript launch video he stresses that to get the benefits of advanced compilation you have to know how to write code that is optimised for the Google Closure compiler. Anyone have any details or pointers to what's involved?

19:25 dbasch: amalloy: imagine if someone built a jvm that showed ads in exception stacktraces, that would replace the tedium with rage

19:30 TEttinger: (dec oracle)

19:30 lazybot: ⇒ -1

19:30 justin_smith: seriously?

19:31 (dec oracle)

19:31 lazybot: ⇒ -2

19:31 kenrestivo: this crossclj is the most amazing thing

19:31 Bronsa: (inc crossclj)

19:31 lazybot: ⇒ 7

19:31 justin_smith: kenrestivo: isn't it though? if only they had the help of a UX person

19:31 the featuers are there, but can be a little hard to find

19:32 kenrestivo: best thing ever for deciding what libraries to use. it's got everything: the dependencies (so i can see any hairballs before they happen), the full source, cross refereced, the docs, it's great

19:32 TEttinger: home is 607 mb apparently

19:32 kenrestivo: even shows the lein-pedantic outdated dependencies

19:32 sorry, lein-ancient

19:33 TEttinger: I downloaded one earlier revision of my previews repo where I store files, "home" and it's 608 MB

19:33 kenrestivo: and... the docs/readme shown is from the *released* artifact,instead of what's in HEAD. which is what i want anyway.

19:33 justin_smith: kenrestivo: we should all remember to submit libs we want other people to use, so crossclj will be sure to crossref them

19:33 kenrestivo: who made this thing?

19:33 technomancy: it's ironic that we have find-usages in a web app but not in nrepl yet =\

19:34 justin_smith: technomancy: haha, I know it

19:34 dbasch: the link to 1.7.0-alpha4 here is wrong http://clojure.org/downloads

19:52 danneu: clojer: check this out https://developers.google.com/closure/compiler/docs/api-tutorial3

19:54 clojer: for example, closure leaves strings untouched but will munge property access. so you sometimes need to change (.-foo thing) to (aget thing "foo"). aka thing.foo to thing["foo"]

20:00 {blake}: So, I'm AJAXifying my compojure form which, and the response to the AJAX request should be a map of names and values specifying what I should update. But I think I have to pass a string, right? So...would I serialize a hashmap or...?

20:01 justin_smith: {blake}: the j in AJAX is json

20:01 use cheshire to turn a map into a json string

20:03 dbasch: justin_smith: you made me check ajax to see if the J had changed from javascript to json :)

20:03 justin_smith: dbasch: OK, maybe we should be talking about ajaj

20:03 hah

20:04 {blake}: if you are returning a map, it's more likely json we should be dealing with rather than xml

20:04 DomKM: Anyone know how to generate an attribute key without a val in hiccup? Specifically, I don't know how to generate <div itemscope >

20:04 dbasch: justin_smith: we should use ajaj in cloxure

20:04 justin_smith: heh

20:05 {blake}: justin_smith: Cheshire! Thanks!

20:05 (inc justin_smith)(

20:05 (inc justin_smith)

20:05 lazybot: ⇒ 143

20:10 justin_smith: is there a straightforward way to avoid using a templating language to create a prepared statement if I want to use jdbc to run a statement querying a variable number of fields?

20:11 I would be using a templating lib to insert the ?? in the statement, and then providing the args in order

20:11 but it still feels weird

20:21 hyPiRion: oyvinrob: It was pretty messy on master – I tried ~1 hr before I wrote that ticket. But I'll have to see if I can repro the case, because it wasn't "no network", it was simply "bad network"

21:31 crash_ep: should transducers avoid side effects?

22:49 FriedBob: I'm trying to implement the ret-xml-data function from http://drknucklehead.wordpress.com/2012/06/28/pulling-data-from-clojure-data-xmlparse/ but when I run the code, it it is telling me "wtong number of args (4) for core/if-not" My code is at https://github.com/llowder/run-nerd-miner/blob/master/src/run_nerd_miner/core.clj#L18

22:50 Been googling some, but I can't figure out what I did wrong

23:04 dbasch: FriedBob: your code shouldn’t compile, it’s not valid clojure

23:04 https://github.com/llowder/run-nerd-miner/blob/master/src/run_nerd_miner/core.clj#L23

23:04 defn should have a parameter vector

23:04 (and you shouldn’t have defs inside a function)

23:04 justin_smith: two different kinds of should there

23:05 dbasch: (which won’t cause compilation to fail but it’s not idiomatic)

23:05 yes, defn *requires* a parameter vector

23:07 FriedBob: dbasch: I fixed that, just haven't pushed yet

23:08 dbasch: FriedBob: post the code you’re running, because the problem you mention is not apparent there

23:08 FriedBob: Need to get my kid to sleep,

23:09 dbasch: heh, mine just fell asleep

23:10 FriedBob: This where the current error is - ignore the other functions. Will push when I can

23:10 https://github.com/llowder/run-nerd-miner/blob/master/src/run_nerd_miner/core.clj#L13-L21

23:10 justin_smith: the error isn't there in that code

23:10 FriedBob: Line 18, the if-not line

23:11 dbasch: FriedBob: that ‘if-not’ shouldn’t fail

23:11 justin_smith: that's not the error

23:11 dbasch: it has three arguments, not four

23:12 FriedBob: Hmm, it's running now and not giving te error.

23:12 Must need more caffeine or morer scotch, or both

23:13 dbasch: you probably had something extra inside the parentheses

23:13 justin_smith: FriedBob: so about the def thing - def creates globals, using def in function logic is almost guaranteed to break if you have more than one thread

23:13 FriedBob: also, if two functions use the same var name, they will break one another

23:14 dbasch: btw, (if-not condition something nil) is the same as (when-not condition something)

23:16 justin_smith: dbasch: if you ever want to have an argument about style in clojure, say that to technomancy

23:16 FriedBob: Ok, infant is asleep. Only took one AC/DC and part of one Motley Crue song

23:16 dbasch: note I didn’t say one is better than the other :P

23:17 but I much prefer the latter

23:57 marcuscreo: Evening!

23:57 Anyone at the Conj?

23:59 cfleming: kenrestivo: Francesco Bellomi makes CrossClj, which is indeed fantastic

Logging service provided by n01se.net