#clojure log - Jun 09 2014

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

0:01 technomancy: danielcompton: weird, on some machines there is very little difference. thanks for the input.

0:02 seems like this will have to delay the release further =(

0:04 danielcompton: technomancy some faster, some slower, some the same?

0:04 technomancy: no, some a handful of ms slower, some ~500ms slower

0:04 none faster

0:04 but I wouldn't block a release over <10ms

0:06 danielcompton: Isn't https://www.refheap.com/86389 faster on the new version?

0:07 technomancy: oh crap, yeah

0:08 didn't notice that

0:10 danielcompton: can you move ~/.lein/profiles.clj out of the way and try again?

0:12 oh, I see what the difference is

0:12 2.2.0 -> 2.4.0 is slower but 2.3.4 -> 2.4.0 isn't

0:13 except for cbp

0:13 he somehow has outrageously fast 2.3.4 invocations??

0:13 lazybot: technomancy: Uh, no. Why would you even ask?

0:13 danielcompton: technomancy https://www.refheap.com/86390

0:14 technomancy: curious

0:14 http://p.hagelb.org/mystery.gif

0:15 cbp: teach me your secrets

0:15 hellofunk: can anyone enlighten me on the difference between (take! ...) and (go (<! ...)) -- both are async takes; assuming you don't have a complex go body that requires continued "parking," is there a difference between these?

0:18 technomancy: danielcompton: is your `lein` command a symlink to a git checkout of lein?

0:19 danielcompton: I'm using homebrew, it looks like that I think

0:21 My /usr/local/bin is a symlink to /usr/local/Cellar/leiningen/2.3.4/bin/lein

0:21 My /usr/local/bin/lein is a symlink to /usr/local/Cellar/leiningen/2.3.4/bin/lein

0:21 and that is a git repo

0:21 technomancy: oh gotcha. would it be too much trouble to try against a manual lein install?

0:22 justin_smith: I don't think homebrew for lein is a loss, using straight lein is actually simpler and easier to manage versions / upgrade

0:22 *homebrew for lein is a loss, that is

0:26 danielcompton: technomancy not at all, I'll do that now

0:29 justin_smith how is it any different using homebrew? It means I have a consistent way of upgrading packages

0:30 justin_smith: but lein handles upgrades and versions better than homebrew does - thus homebrew introduces an abstraction layer that in this case improves nothing in its indirection

0:31 same problem (if not worse) using the linux apt package for lein

0:33 cbp: technomancy: dat ssd man

0:34 technomancy: this wouldn't be the first time homebrew screwed up their lein packaging

0:34 wouldn't be the second either

0:34 hellofunk: three times is a charm

0:36 technomancy: justin_smith: if it's coming from apt then at least there's a single file on my system I can add it to so that I can bootstrap a fresh machine to have everything I need on it (assuming a relatively recent version)

0:37 but with brew you can't even do that

0:38 justin_smith: so how is the nixos project coming along anyway? I wonder

0:38 http://nixos.org/

0:39 benkay: in the context of compojure routes, how does one set up a destructuring bind for params while preserving the URL param? (GET "/thinger/:stuff" [{params :params} stuff :as req]) isn't working for me

0:40 justin_smith: that :as clause is misplaced

0:40 it uses standard destructuring syntax

0:41 ,(let [stuff {:a 0 :b 1 :params "ok"} {params :params :as req} stuff] params)

0:42 clojurebot: "ok"

0:42 justin_smith: if something works in a let destructure, it should work in a compojure destructure, and visa versa

0:43 benkay: destructuring is not my strong point. thanks for the tips.

0:43 justin_smith: benkay: I never made sense of it until I experimented for a while with let in the repl

1:09 danielcompton: technomancy here's my results with a manual lein install https://www.refheap.com/86391

1:14 ddellacosta: did we figure out a way to test code involving core.async?

1:15 danielcompton: ddellacosta yes but it requires Rich Hickey's toenails and eye of newt

1:15 ddellacosta: danielcompton: damn, that shit is pricey too

1:16 I guess I can probably expense it though

1:17 danielcompton: ddellacosta stranger things have been put on a company card

1:17 ddellacosta: danielcompton: not sure I want to know...

1:17 Hodapp: o_O

1:18 ddellacosta: huh, I guess one approach is to mock the receiving channel

1:18 but does that mean I have to have a test in a go block? blech

1:18 "integration tests: yer doing it wrong." *sigh*

1:19 danielcompton: ddellacosta yo dawg

1:19 https://groups.google.com/d/msg/clojurescript/OlyylM4LMEk/u3LLyBLLQmQJ

1:20 ddellacosta: okay, so apparently it's hard in CLJS although I know clojurescript.test supports it now, but apparently using <!! provides an answer? Thanks for the clue danielcompton

1:20 * ddellacosta goes off to investigate

1:20 danielcompton: ddellacosta how do you verb yourself in IRC?

1:21 ddellacosta: danielcompton: oh, you mean the "ddellacosta goes off to investigate thing?" just type /me and then the thing you want to say

1:21 * tolstoy runs the /me command

1:21 * ddellacosta watches tolstoy run the /me command

1:21 * danielcompton learns something new today

1:21 * ddellacosta gives danielcompton a high five

1:22 * tolstoy hits Alt-F4

1:22 tolstoy: I fell for that once.

1:22 ddellacosta: tolstoy: now I'm scared, what does that do?

1:22 tolstoy: One Windows (I think), it closes the app.

1:22 ddellacosta: tolstoy: ah, okay

1:23 http://knowyourmeme.com/memes/alt-f4

1:23 gotcha

1:23 mean

1:23 tolstoy: Hah! Wow.

1:23 ddellacosta: I know, it's amazing what folks will do

1:23 danielcompton: What are peoples thoughts on (= nil nil) being true

1:24 Coming from a SQL background where that isn't the case it caught me out a few times

1:24 ddellacosta: danielcompton: well, it makes sense, why? I mean, nil is equal to nil

1:25 danielcompton: ddellacosta I guess nil could also mean undefined so two undefined values compared should = ?

1:26 ddellacosta I think I like it still, though I do ponder it every now and then

1:26 ddellacosta: danielcompton: well, except it is explicitly not undefined in Clojure, it's nil (is I guess what I would respond with)

1:26 * danielcompton ponders the depths of nil

1:26 ddellacosta: heh

1:27 danielcompton: ddellacosta: you're right, that's why it makes sense

1:27 ddellacosta: danielcompton: for me this is meaningful useful when I'm using it with multi-methods or protocols, for example--I can define behavior based on nil

1:27 *meaningfully useful

1:27 ye good olde nil object pattern

1:28 er, null rather

1:55 justin_smith: the sooner everyone upgrades from nil to proper option types the better

1:56 danielcompton: justin_smith how do you do that in Clojure?

1:56 *with Clojure

1:58 justin_smith: with static typing :P

2:00 danielcompton: justin_smith typed clojure?

2:01 justin_smith: maybe one can do option types with core.typed, I haven't used it actually

2:02 I've just been learning some stronger typed languages lately, and enjoy the absence of unexpected nil values (instead getting an error for non-exhaustive value matching)

2:07 ddellacosta: justin_smith: agreed that ADTs are the way to go here

2:08 justin_smith: a Null Object is kind of a poor imitation of doing it properly w/ADTs

2:08 justin_smith: that is one way to look at it, yeah

2:09 do adts predate null in plt history?

2:11 ddellacosta: justin_smith: I can't answer that, good question. I suspect not

2:12 ambrosebs: do ADTs predate null in PLT history? I figure you may know. ;-)

2:12 d'oh, not around perhaps

2:15 dbasch: I believe pointers are from the 60s and ADTs were formalized in the 70s

2:16 justin_smith: ahh and pointers in practice pretty directly lead to a nil / null value

2:16 ddellacosta: right, makes sense

2:16 justin_smith: adts are from simula67, according to this paper http://www.cs.utexas.edu/users/wcook/papers/OOPvsADT/CookOOPvsADT90.pdf

2:17 ddellacosta: was just going to ask, thanks

2:17 huh, so ADTs are *post* OOP? interesting

2:17 justin_smith: well, that description makes them sound parallel

2:17 ddellacosta: ah

2:17 justin_smith: (the description in that paper)

2:18 ddellacosta: justin_smith: right, gotcha. Very interesting, sounds like it's been an ongoing dialogue between the two "camps" if they can be described as such

2:19 very nice, thanks for that paper

2:19 justin_smith: np

2:20 ddellacosta: I guess the lesson is that these things rarely spring fully formed from someone's mind; they are the result of ongoing discussion and attempts at implementations along the way, as well as new theoretical frameworks that come about

2:20 dbasch: in the late 90s I was a TA for Jeannette Wing, who liked to rant about how Java was all wrong regarding types

2:21 * ddellacosta goes to look up Jeannette Wing

2:21 ddellacosta: ah, CMU bigshot!

2:21 dbasch: wow, that must have been super educational

2:21 dbasch: yes, she was very sharp

2:21 ddellacosta: dbasch: huh, she's partially responsible for Liskov substitution principle, didn't realize that

2:22 justin_smith: I've been learning ats, which is ml-derived and has a type system that a) only exists at compile time, reverting to an untyped runtime fully compatible with c in the compiled code and b) generalizes typing to verification arbitrary static properties (ie. guarantees that the code cannot write off the end of a given array)

2:22 ddellacosta: justin_smith: so it's kind of like a type-safe C pre-processor?

2:23 justin_smith: ddellacosta: exactly, while also extending what "type-safe" can mean via proof constructing in the typechecker

2:23 ddellacosta: interesting, will check it out

2:23 justin_smith: also it is weird and kind of a pain in the ass and very experimental :)

2:23 it has its ups and downs to be sure :)

2:23 ddellacosta: haha...fun. :-)

2:24 dbasch: curious what she said about Java though, although I already had a strong intuition that Java's typing was pretty crap

2:24 justin_smith: the author have very odd naming conventions - ie. a second order function has the type "-<cloref1> a" which is just stupid naming

2:25 ddellacosta: justin_smith: wat

2:25 justin_smith: yeah, I know

2:25 oh, sorry, that's a closed over function, my bad

2:25 but still, the name doesn't help me remember which is which :)

2:26 ddellacosta: justin_smith: yeah, it's really not clear what's going on there regardless

2:26 justin_smith: but on the other hand, ml syntax and semantics compiling to raw c, which is kind of awesome

2:27 dbasch: ddellacosta: obviously she didn’t like the fact that the Liskov substitution principle didn’t hold in Java

2:27 justin_smith: and not your typical "my compiler generates a tangle of convoluted inefficient c", but actual like n gc or type tags or size field on the array c code

2:27 ddellacosta: dbasch: ah, haha

2:29 justin_smith: reading about liskov substitution, it seems like hoare logic (from which that is derived) also informs the kind of theorem proving type system ats uses

2:30 many times ats types will actually look like an argument, plus a type, plus arbitrary pre-conditions like you would see in a clojure :pre block

2:31 * ddellacosta needs to take a PLT course

2:32 hellofunk: pilates? good for the muscles

2:32 * ddellacosta hits a rimshot for hellofunk

2:35 * hellofunk goes to the hospital. that shot hit me in the eye

2:35 justin_smith: I read "java concurrency in practice" recently, and one thing I noticed was how often they talked about things that must be invariant but could not be expressed directly in the language

2:35 which smells funny, to be sure

2:37 gws: if i'd like to call a method in one namespace on something created via deftype in another namespace, is the idiomatic way to do that just dot-notation?\

2:39 justin_smith: gws: yeah, and use import in the other namespace

2:40 gws: the exception being if you implement a protocol, then you should use require to bring the protocol functions into scope, and use those

2:40 but for regular methods just use dot notation

2:43 gws: justin_smith: ah, thanks! i am implementing a protocol, actually... though simply requiring the type's constructor (e.g. ->MyType) without the imports (which works). when i try to require the protocol functions into scope, i get "no such var"

2:43 however dot-notation works

2:44 justin_smith: how are you doing the require?

2:45 gws: [myns.mail :as mail] in an ns form, then mail/mymethod - is it necessary to :refer?

2:46 justin_smith: no, that should all work

2:47 myns.mail is where you define the protocol, correct?

2:47 gws: alright, thanks. let me check again. if i can't make it work, i'll reduce it and put the code up somewhere

2:47 justin_smith: the protocol functions need to be pulled in from the ns that defines the protocol, not the one where you define the type implementing the protocol

2:48 gws: this is code that I haven't refactored properly so they are not yet separate namespaces. is that my problem?

2:49 in other words, deftype and defprotocol are in the same ns

2:49 justin_smith: nope, that would even prvent this problem

2:50 one moment, let me try to find a place on github in one of my projects that demonstrates this stuff

2:51 gws: sorry i missed it - yes, myns.mail is where both defprotocol and deftype are

2:52 justin_smith: https://github.com/caribou/caribou-c3p0-plugin/blob/master/src/caribou/plugin/c3p0.clj here is an ns implementing a protocol (using a defrecord)

2:52 https://github.com/caribou/caribou-plugin/blob/master/src/caribou/plugin/protocol.clj here is where the protocol and the convenience function that implements it for that record are defined

2:53 both quite small namespaces, so it should be pretty straightforward to see what is being done

2:53 ddellacosta: a macro that defines helper functions and an instance of a type in a namespace: ugly? Is there a better strategy for configuring a set of easy-of-use helper functions?

2:53 *ease-of-use

2:54 justin_smith: ddellacosta: the annoying part is when I try and use that namespace, and look for the definitions of said instance and convenience functions

2:55 ddellacosta: justin_smith: yeah, that's my reservation too. But I should be more clear--this would be something the user of the lib would call in their own application

2:55 justin_smith: so they'd do something in my.ns like (init-lib! arg1 arg2 arg3 arg4)

2:55 justin_smith: and then they'd be able to call my.ns/helper1, my.ns/helper2

2:55 justin_smith: hmm

2:56 seems like it is just passing the buck, because their code ends of having said problem

2:56 ddellacosta: justin_smith: to give a bit more explanation, what I'm trying to avoid is that the user calls the lower-level fns every time with four args

2:56 two or three of which may never change during the lifetime of that lib user's application

2:57 justin_smith: it's passing the buck in one sense, but it's also try to avoid them typing redundant crap all the time

2:57 justin_smith: I'm just really not sure how to structure this so that the user can set up these defaults in a clean way, and have them available consistently

2:57 justin_smith: what about making the functions so that they return the params as an options map, such that they can be chained?

2:58 ddellacosta: justin_smith: sorry, I don't follow--how would that avoid having the user have to call the functions with those args every time?

2:59 justin_smith: oh, I misunderstood, sorry

2:59 I thought you meant multiple functions taking the same args

2:59 but you mean multiple calls with the same args

2:59 ddellacosta: justin_smith: oh, yeah, exactly

3:00 amalloy: ddellacosta: instead of passing the same four args to N functions, they could pass one map to the N functions, i think is what justin_smith was suggesting

3:00 justin_smith: well, then in that case you can have them use a configuration map - see how the connection data is in a map as the first arg to just about every clojure.java.jdbc function

3:00 yeah, pretty much

3:00 ddellacosta: amalloy, justin_smith: yeah, maybe a config/option map is really the right way to do this

3:01 it seems a bit uglier, but I'm wary of macro magic

3:01 justin_smith: an options map is easy for a user to wrap if they find it cumbersome

3:01 by defining a partial for example

3:02 ddellacosta: justin_smith: yeah

3:02 justin_smith: but better that than scratch my head over where something is even defined, IMHO

3:02 ddellacosta: agreed

3:02 okay, thanks!

3:09 gws: justin_smith: thanks for the code. i reduced it to an example which is very similar to mine, and it does work as I expected - so I've got bigger problems

3:09 http://pastebin.com/e1Npfhtt

3:09 justin_smith: i'll dig in to this, but good to know it works as I originally thought :)

3:10 justin_smith: so is the pasted one the one that works?

3:10 gws: yep

3:11 which is how i expect it to work

3:15 i think your point about needing to pull in the ns in which the protocol is originally defined was my problem

3:15 I've got a second deftype in there which implements a protocol from a different ns

3:15 ugh

3:15 so that's the issue

3:15 got it now, thanks

3:16 justin_smith: np

3:24 dfg888: selling intim

3:41 allenj12: has anyone compared hoplon vs reagent vs om?

3:46 it seems hoplon is much more mature than om

3:46 and reagent to for that matter

3:46 michaniskin: allenj12: i can answer any questions you have about hoplon

3:48 allenj12: michaniskin: ok well let me put it like this i was going through the om tutorials, and to be honest they kinda sucked it was hard to tell what om was doing alot of the time. i guess my questons are is hoplon mature? does hoplon have better docs than om? and is hoplon easy?

3:49 michaniskin: like literally oms advance tutorial was a blank page, it was quite sad

3:49 michaniskin: allenj12: you should look at http://hoplon.io/#/getting-started/

3:50 that will give you an idea of what it's like

3:50 allenj12: michaniskin: just am now it looks way better already, im assuming its more popular than om?

3:50 michaniskin: i don't know if it's exactly "easy", but i think it's pretty simple

3:51 there aren't a lot of things to know about it, really, but it is kind of weird

3:51 once you get over how weird it is i think it's pretty straightforward

3:52 i think it's a lot less popular, but it's hard to tell

3:53 allenj12: michaniskin: o really? im assuming you prefer it tho? and theres good reason to?

3:53 justin_smith: allenj12: om is a specific lib for optimizing re-rendering of dynamic changes to pages, I think it can be used inside hoplon even

3:53 michaniskin: i'm one of the guys working on it :)

3:53 kzar: allenj12: There definitely was quite a bit of coverage of Om on hacker news a while back and I've heard less hype about hoplon. But more hype does not better technology make. (I regretfully still haven't tried either in earnest.)

3:53 I think both are worth giving a try

3:53 justin_smith: allenj12: you will probably figure things out faster if you start without om and then start using it if you need its features

3:54 michaniskin: allenj12: you might want to look at the demos: https://github.com/tailrecursion/hoplon-demos

3:54 allenj12: hmm alright it seems so far html files arent rly used here? interesting

3:54 michaniskin: we're adding things all the time (whenever i do something new for work and i can open source it i throw up a demo there)

3:55 allenj12: michaniskin: oo cool

3:55 michaniskin: allenj12: we have a contrib library now, with some libraries you can use: https://github.com/tailrecursion/hoplon/tree/master/contrib

4:00 allenj12: michaniskin: boot development dosnt work for me, is there a way to fix that?

4:00 michaniskin: allenj12: what happens? exception?

4:01 allenj12: no its just not a command...

4:01 kzar: Is there a good static site generator like Jekyll written in Clojure?

4:01 allenj12: michaniskin: does it matter im in windows now?

4:02 michaniskin: allenj12: ah, windows. did you try this: https://github.com/tailrecursion/boot#windows ?

4:03 we need to work on windows support for boot, it's on the list

4:03 allenj12: michaniskin: hate windows :p cant wait till i re image my slackware, yea im trying it now

4:04 michaniskin: allenj12: you may need to do `java -jar boot.jar ...`

4:04 it's executable in unix or if you have cygwin

4:04 are you using cygwin?

4:06 allenj12: michaniskin: its pretty much a fresh windows now. had to re image

4:07 michaniskin: i think its working tho :p

4:08 michaniskin: allenj12: awesome

4:11 allenj12: michaniskin: dam how long is it suppose to take tho

4:13 michaniskin: allenj12: how long to do what? it should take maybe 20 sec to compile the first time

4:13 allenj12: michaniskin: im at 5 min

4:13 michaniskin: then after that if you're using the watch task it'll be fast

4:14 do you see like a stopwatch with elapsed time ticking?

4:14 allenj12: michaniskin: well its just printing the time like ever so sub seconds

4:15 michaniskin: i think it's done :)

4:15 when it finishes compiling it prints the elapsed time since the last compile

4:15 i sometimes don't trust it that it really recompiled my application, so i like being able to see when the last time it compiled was

4:15 allenj12: michaniskin: oooo hahahha im silly :)

4:16 michaniskin: belt and suspenders

4:16 lol

4:16 allenj12: so the last thing i should see before all those prints is compiling clojurescript....

4:16 michaniskin: right

4:17 allenj12: gotcha

4:17 michaniskin: if you are using the local jetty server you will see some stuff about it starting that

4:28 allenj12: michaniskin: do you know how to add highlighting to lighttable for hoplon? i tried http://stackoverflow.com/questions/21793023/clojure-how-to-associate-hl-files-to-clojure-syntax-highlighting-in-light-tabl and a solution on the group but neither worked for me

4:29 michaniskin: allenj12: hm, i dunno, i think that worked for me, but it was a little while ago

4:30 allenj12: michaniskin: hmm alright

5:13 michaniskin: hey i just wanted to let you know the tutorial was great! im pretty brand new to web dev (mostly just an ai guy) and this actually taught me alot other libraries didnt but had included.

5:14 michaniskin: allenj12: thanks :) what kind of ai?

5:15 allenj12: michaniskin: well im doing my masters in cognitive science right now and do alot of social modeling using cognitive architectures, in almost all other times when im not working on that, im doing machine learning of some kind. i also hope to move into the field of AGI and research generalizid systems

5:16 machuga: althought AGI is kinda a joke right now :)

5:18 btw out of curiosity no one here would happen to be a lawyer right?

5:23 mi6x3m: allenj12: do you need one?

5:24 allenj12: mi6x3m: well eventually i just have some questions about what defines gambling. its related to what im working on right now and picking up web dev :)

5:24 mi6x3m: i did some research and i think im in the clear but i just wanted to make sure

5:25 michaniskin: allenj12: that sounds exciting and mysterious

5:25 mi6x3m: allenj12: which jurisdiction?

5:26 allenj12: new jersey.

5:27 michaniskin: haha i yea im pretty much chose the path of acadamia forever, so i wanted to start this company while i did my masters etc... im pretty excited for it :)

5:28 mi6x3m: allenj12: oh, that's quite far

5:28 allenj12: mi6x3m: far from where?

5:28 mi6x3m: europe

5:28 allenj12: mi6x3m: o lol

5:28 mi6x3m: aren't there some official guidelines of what to be aware?

5:29 allenj12: mi6x3m: ehh i mean we would just kinda be in a grey area it seems, its hard to tell from what we read so far

5:52 mping_: hi

6:11 ddellacosta: mping_: hi

6:16 mping_: can you guys help me out? I'm trying to debug a ring app with cursive clojure

6:16 (ddellacosta: it's funny I'm using your lib for oauth2)

6:17 cfleming: mping_: what's happening?

6:17 mping_: I would like to debug a running ring app with step by step debugging (a la java et al)

6:17 cfleming: Ok

6:17 mping_: I'm still quite new in clojure land

6:17 I configured ring to start an nrepl server

6:17 cfleming: No worries :-)

6:17 ddellacosta: mping_: cool. :-)

6:18 mping_: and I've managed to connect cursive clojure to it

6:18 I'd like to set up a breakpoint in the ide

6:18 and hit an url, and debug from there

6:18 but I guess that's not the way things work hehehe

6:18 cfleming: Hehe

6:19 So you're starting the REPL outside of Cursive, and then connecting to it using a remote run configuration for your REPL?

6:19 mping_: yep

6:19 i've got this in a lein profile:

6:19 :dropbox {:ring {:handler friend-oauth2-examples.dropbox-handler/app :nrepl {:start? true :port 3333}}}

6:20 cfleming: Ok, so Cursive normally assumes that you're starting the REPL within Cursive itself, then if you start it in a debug config it can start the JVM in debug mode

6:20 To debug the JVM you need some system properties at startup

6:20 So you should be able to add those properties manually and connect a remote debugger to it

6:20 Try this:

6:21 Run->Edit configurations

6:21 Create a Remote debug configuration

6:22 mping_: ok

6:22 cfleming: Under Command line arguments for running remote JVM it gives you some system properties to copy and paste

6:22 You'll need to add those to lein, so the JVM gets started in debuggee mode

6:22 The next step is to cross your fingers :-)

6:22 mping_: *fingers crossed*

6:23 duh! I tried this before but tried to connect as lein remote app

6:23 its working :)

6:23 cfleming: Nice :-)

6:23 mping_: thanks!

6:23 cfleming: The debugger is still a little flakey from time to time

6:24 I need to fix it up

6:24 (Cursive dev here, BTW)

6:25 mping_: hey, since you are a cursive dev: what's with the backspace key? it doesn't normally delete things...

6:25 john2x: does (.method instance "foo") return the instance if the method returns void?

6:25 cfleming: That'll be the structural editing (like paredit) mode.

6:25 mping_: I must have configured it badly. it seems like I'm using vim or something

6:25 aah....

6:25 danielcompton: cfleming is the debugger specific to cursive or can it be used elsewhere too?

6:26 cfleming: mping_: check https://cursiveclojure.com/userguide/paredit.html

6:26 You can turn it off if it annoys you, but it's worth getting used to it

6:26 danielcompton: it's mostly just the built-in IntelliJ debugger.

6:26 danielcompton: cfleming I suspected as much

6:27 cfleming: It has some customisations for Cursive, but not many at the moment. I'm planning to add a lot more.

6:27 Instead of the Java-style expression evaluation I'm going to add a debug REPL

6:28 danielcompton: cfleming: so you could pause and expect the environment at any point?

6:28 cfleming: and execute arbitrary clojure code?

6:29 cfleming: Yeah

6:29 You can already do that, but the evaluation is flakey right now

6:29 I need to fix the symbol resolution there.

6:30 I'm still not sure how customisable the debugger is, I think it's pretty flexible.

6:30 Currently you can't access closed-over locals, which is a pain

6:31 For some reason the debugger is incredibly slow with Clojure too, I don't know why

6:31 danielcompton: cfleming, that's where it would be most handy too

6:32 cfleming: danielcompton: yeah, it's still really useful though. I couldn't get through the day without it.

6:32 Since I'm essentially working with a huge ball of someone else's code.

6:33 danielcompton: cfleming do you use tools.trace?

6:33 cfleming: I tend to use that for my debugging/reasoning about a program most of the time

6:33 cfleming: danielcompton: No, I haven't.

6:34 danielcompton: cfleming: but I haven't learnt how to use the debugger so I don't know what I'm missing on that side

6:34 cfleming: My problem is generally that the code that I don't understand isn't mine, and is Java

6:34 (the IntelliJ platform)

6:36 danielcompton: cfleming mmm, I'll bet your java interop skills are pretty good!

6:37 cfleming: how much of cursive is clojure vs java code (that you've written)?

6:37 cfleming: danielcompton: Yeah, sadly

6:37 danielcompton: nearly all of what I write is Clojure now, unless I'm taking + customising code from IntelliJ

6:38 danielcompton: but Clojure's interop is lacking some features I need, so I still write a lot of Java shims then call into Clojure

6:39 danielcompton: hahaha I just wrote defn- main, instead of defn -main

6:39 that was a headscratcher

6:39 cfleming: did you come from a java background?

6:40 cfleming: danielcompton: Yeah, I worked with Java (and IntelliJ) for about 10 years or so

6:41 danielcompton: cfleming were you developing plugins for intellij or using it as your IDE?

6:41 cfleming: danielcompton: using it as my IDE, and I wrote a few small plugins

6:41 danielcompton: I started one for Scheme, and a few smaller things

6:42 danielcompton: cfleming neat!

6:44 mping_: do you guys recommend any ring app for me to study? I've dabbled in clj but still don't have a solid idea on how things should look

6:44 things like validation, etc

6:47 mi6x3m: is there a variant of defmulti allowing you to specify multiple dispatch values?

6:50 cfleming: mping_: No sorry, I've never done any web dev in Clojure. I think clojars might be open source.

6:50 mi6x3m: I've never tried it, but I think you could dispatch on a vector of values

6:52 kzar: :o just had a phone interview for a clojure job *waits of an email*!

6:53 mi6x3m: kzar: grats :)

6:53 kzar: for*

6:53 Thank

6:53 mi6x3m: what kid of job / location / specifics?

6:53 kzar: mi6x3m: Arg can't type this morning, I meant to say "Thanks, but let's see!"

6:54 Feel shy to talk specifics to be honest

6:55 Has anyone used the stasis static site generator library here? (Is it any good?)

6:57 mi6x3m: is there a clojure function consuming arguments and doing nothing?

6:58 kzar: mi6x3m: identity?

6:58 ,(identity 2)

6:58 clojurebot: 2

6:58 mi6x3m: ,(identity 2 3 4)

6:58 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (3) passed to: core/identity>

6:58 mi6x3m: nope

6:58 kzar: ,(apply identity [2 3 4])

6:58 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (3) passed to: core/identity>

6:59 kzar: whoops sorry, dumb idea

6:59 CookedGryphon: ,((constantly nil) 1 2 3)

6:59 clojurebot: nil

6:59 kzar: mi6x3m: When you say "doing nothing" do you mean returning what you've passed in as a sequence?

6:59 mi6x3m: no, returning nil

6:59 kzar: oh

7:00 mi6x3m: just a black hole for stuff

7:00 tnx CookedGryphon

7:00 kzar: mi6x3m: Something like (fn [& args]) ?

7:01 ,((fn [& args]) 1 2 3 4)

7:01 clojurebot: nil

7:01 mi6x3m: yes

7:01 kzar: (May I ask, why yo would want such a thing?)

7:01 you*

7:02 mi6x3m: I am writing a library extending seesaw with some exotic components

7:02 so I need all types of weird gizmos :)

7:02 kzar: OK

7:02 say no more heh

7:05 gfredericks: mi6x3m: (constantly nil)

7:06 unless by "consuming arguments" you mean something related to laziness

7:06 mi6x3m: gfredericks: yes this is what I was needing :)

7:06 cfleming: so about this vector thing for multimethods

7:07 (defmethod mymethod [[dispatcher-1] [dispatcher-2]] ....

7:07 i was imagining something like that

7:09 cfleming: I think you can only have one dispatcher, but it can be (fn [x] [(dispatcher-1 x) (dispatcher-2 x)])

7:10 Again, I think - I've never tried this

7:10 Don't see why it wouldn't work though.

7:10 mi6x3m: ah

7:10 a function dispatcher

7:10 i see

7:11 cfleming: Sorry, I meant that would have to be the dispatcher function that you would use with defmulti

7:11 mi6x3m: yeah, I understand

7:11 cfleming: In fact, the example here is what you want, right? http://clojuredocs.org/clojure_core/clojure.core/defmethod

7:12 I guess it does work :-)

8:45 jcidaho: hi - some macro magic needed. Is it possible to get the name of a surrounding fn?

8:51 TimMc: jcidaho: Hmm, I remember a conversation about this last week.

8:51 Bronsa: jcidaho http://sprunge.us/RgMd

8:52 jcidaho: nice :-) Good hackery, thanks

8:52 Bronsa: jcidaho needles to say, don't use this in Real Code™

8:52 jcidaho: yeah right ;-)

8:53 mi6x3m: hey, what is a way to stop the namespace expansion in syntax quote?

8:53 for instance to avoid arguments being expanded

8:53 or is it safe to expand arguments?

8:53 Bronsa: '`~'a

8:53 ,`~'a

8:53 clojurebot: a

8:54 Bronsa: mi6x3m: though you porbably want to use the auto-gensym feature

8:54 ,`(do a# a#)

8:54 clojurebot: (do a__49__auto__ a__49__auto__)

8:56 mi6x3m: Bronsa: here's my code for clarity http://pastebin.com/zdpGC5Me

8:57 it generates a native java Adapter instance from a set of requested events

8:57 Bronsa: mi6x3m: yeah, relace ~' with e#

8:57 mi6x3m: event-fn should have ~' though, no?

8:57 only e should be #

8:58 Bronsa: mi6x3m: it looks like event-fn should be unquoted though, I don't see how that'd work otherwise

8:59 TimMc: Bronsa: Man, where were you last week? THat's a much better solution. (The thisName thing.)

9:04 no7hing: does anybody know of a vector math library for clojurescript ?

9:06 mi6x3m: Bronsa: yeah well technically 'e' doesn't need the gensym, but it doesn't hurt having it

9:06 since e is an indepedent parameter name, but i see your point

9:06 thanks works nicely :)

9:11 Bronsa: TimMc: it will work only for (fn name [] ..) though, I don't think it will for (defn name [] ..)

9:11 even though there should be a way to make that work too

9:13 TimMc: Bronsa: I don't see why it wouldn't work.

9:13 Bronsa: TimMc: defn expands to (def x (fn [] ..))

9:14 TimMc: Huh, I would have expected it to fill in the function name.

9:16 Bronsa: looks like if you want it to work with defn yoo you have to use .name and do some unmunging

9:16 hyPiRion: TimMc: That would've destroyed all the (alter-var-root #'foo memoize) calls out there

9:18 ,(defn fib [n] (if (< n 2) 1 (+ (fib (- n 1)) (fib (- n 2)))))

9:18 clojurebot: #'sandbox/fib

9:18 hyPiRion: ,(alter-var-root #'fib memoize)

9:18 clojurebot: #<core$memoize$fn__5097 clojure.core$memoize$fn__5097@1ab7a89>

9:18 hyPiRion: ,(fib 70)

9:18 clojurebot: 308061521170129

9:23 TimMc: hyPiRion: Ah, interesting point!

9:27 hyPiRion: yeah, I found it out when I tried to memoize a recursive anonymous function =(

9:30 roppongininja: Hello! Can someone help me me out?

9:30 (ns miw-projekt-2.core

9:30 (:require [clojure.java.io :as io]))

9:30 (def data-file (io/file

9:30 (io/resource

9:30 "dane1.txt")))

9:30 (defn -main []

9:30 (println (slurp data-file)))

9:30 Exception in thread "main" java.lang.IllegalArgumentException: No implementation of method: :make-reader of protocol: #'clojure.java.io/IOFactory found for class: nil

9:32 bcarrell: you don't need io/file, io/resource gives you an instance of java.io.File, which you can slurp

9:35 roppongininja: I still get Exception in thread "main" java.lang.IllegalArgumentException: No implementation of method: :make-reader of protocol: #'clojure.java.io/IOFactory found for class: nil

9:37 Glenjamin: what does (io/resource "dane1.txt") give you?

9:39 TimMc: roppongininja: Please use a pastebin next time you want to share code. (e.g. refheap.com)

9:41 mdrogalis: TimMc: I kind of wish we had one named ParenBin

9:43 TimMc: mdrogalis: Buy the domain and fork refheap. :-P

9:45 mdrogalis: TimMc: ParenPool. Oh, I'm full of it today.

10:28 ddellacosta: can someone tell me what is going on here?

10:28 ,(map repeat (repeat 3) [1 2])

10:28 clojurebot: ((1 1 1) (2 2 2))

10:29 ddellacosta: if map applies f (repeat in this case) to each value of each collection in turn, what is it taking from the infinite sequence produced by (repeat 3) ?

10:29 and how does that produce two instances of the values from the last collection [1 2] ?

10:33 roppongininja: does anyone here have a few minutes (more like 10-20) for a total noob?

10:34 ddellacosta: roppongininja: if you have some questions just put 'em out there

10:34 are you actually in Roppongi, btw?

10:34 roppongininja: nope

10:34 unfortunately no

10:35 are you? ;)

10:35 ddellacosta: roppongininja: coincidentally, I may go there tomorrow to work. :-)

10:35 roppongininja: this is an awesome workspace, on the 49th floor of Mori tower: http://www.academyhills.com

10:35 roppongininja: but I digress

10:35 roppongininja: ddellacosta: nice man! I'm happy for you.

10:35 ddellacosta: roppongininja: what was your question?

10:36 roppongininja: yeah, I have no complaints. :-)

10:36 roppongininja: Would you mind talking via private messages because those are some real dumb ass questions

10:36 ddellacosta: roppongininja: well, that's totally cool but you shouldn't feel embarrassed, and others may benefit from your questions

10:36 roppongininja: that I have for you :P

10:36 ddellacosta: but sure. :-)

10:36 mping_: roppongininja: that way the rest of us won't learn

10:37 ddellacosta: roppongininja: see, what did I say? ^

10:37 ;-)

10:37 mping_: ddellacosta: any suggestion on how to use multiple oauth2 providers with friend-oauth2?

10:37 roppongininja: mping_: I assure you that you won't learn anything from me!

10:37 ddellacosta: mping_: er, I'm working on it. :-(

10:37 mping_: eheheh :)

10:37 ddellacosta: mping_: so unfortunately not as of yet...

10:38 roppongininja: I was given this assignment "For the data in the file it daneXX.txt 1 Suggest a linear parametric model and then specify the parameters of the model using the least squares method."

10:38 I know how to do it in java, but I want to learn clojure so I thought that I'll just do it in clojure

10:38 ddellacosta: roppongininja: dude, I thought you were going to ask a Clojure question...haha

10:38 mping_: haha

10:38 ddellacosta: oh well, I may give this a go: https://github.com/oauth-io/oauthd

10:39 keep up the good work though

10:39 roppongininja: I basiclly skimmed a book on clojure in 3-4 hours and now have little to no idea how to start actually xD

10:39 ddellacosta: mping_: let me know how it goes!

10:39 mping_: I need to make this work with multiple providers...*sigh*...soon

10:40 roppongininja: well, unfortunately my math is a bit crap so I may not be able to help too much with the specifics

10:40 roppongininja: I know the math

10:41 ddellacosta: roppongininja: so, that's good. Then I guess the question is, what is the first thing you know you need to do?

10:41 roppongininja: wow sorry freenode kicked me out for some reason

10:41 ddellacosta: d'oh, dunno if you saw my last message:

10:41 "so, that's good. Then I guess the question is, what is the first thing you know you need to do?"

10:42 roppongininja: anyway I know the math and I have already implemented this program in java, now I just want to translate it to clojure (thats not required by my course) in hopes of learning something

10:42 maybe not something, but clojure :D

10:42 ddellacosta: roppongininja: oh, okay. So, are you familiar at all with Java interop stuff? http://clojure.org/java_interop

10:43 roppongininja: one approach I can suggest would be to do the "naive" translation from Java to Clojure using interop

10:43 roppongininja: and then you can throw it in a gist/refheap or what not and let folks on IRC take a look

10:43 roppongininja: ddellacosta: familiar is not the right word, but I have skimmed through that

10:44 ddellacosta: I don't want to translate anything from java and I want to use as little java as possible

10:44 ddellacosta: roppongininja: I mean, unfortunately I think it's actually rather hard to learn Clojure the way you're proposing--it's actually easier to start out by writing "Clojure-esque" Clojure, if you know what I mean

10:44 roppongininja: yeah, I think that's probably a good idea

10:44 roppongininja: are you using a lot of 3rd-party libs in your Java code?

10:45 roppongininja: ddellacosta: the idea is not to do this assignment but to actualy learn something by doing it, because I just can't stand reading books, even on my ADD medication

10:45 ddellacosta: ha

10:46 so, re: 3rd-party libs ^ ?

10:46 roppongininja: ddellacosta: I am not using any

10:46 ddellacosta: roppongininja: okay, that should make it simpler. Do you want to put the Java in a gist or something so we can take a look?

10:47 roppongininja: ddellacosta: sure I can but I don't want you to write a solution if you know what I mean :P I'm not asking for doing my homework

10:47 ddellacosta: roppongininja: no, not at all! It's more that, I'm having a hard time figuring out how to suggest you should try things in Clojure without having a sense of what you're working on

10:48 roppongininja: I mean, I can give you some general tips, like--think about the data structures you're using and restructure them as Clojure immutable data structures. That's probably the big one.

10:49 roppongininja: ddellacosta: ok just a second I'm changing the variable names to english :P

10:49 ddellacosta: ahaha, okay

10:49 what language were they in originally, if you don't mind me asking?

10:50 roppongininja: polish

10:50 aka russian with latin letters

10:51 ddellacosta: roppongininja: haha, okay. Yeah, I would have been useless with that. :-)

10:52 gavilancomun: ,(map #(list %1 %2) (repeat 3) [1 2])

10:52 clojurebot: ((3 1) (3 2))

10:53 ddellacosta: gavilancomun: is that based on what I posted above, perchance?

10:53 gavilancomun: sure

10:53 ddellacosta: gavilancomun: do you know what is going on with the (repeat 3) there? I'm a bit stumped

10:54 gavilancomun: map is taking the first element of each coll, then the second of each coll

10:55 Those pairs are then fed to the first repeat in your example

10:55 ddellacosta: oh, I see, in that case repeat is just producing an infinite sequence of 3s, huh

10:55 I guess then what I don't understand is what the first repeat is doing here:

10:55 ,(map repeat (repeat 2) [1 2 3])

10:55 clojurebot: ((1 1) (2 2) (3 3))

10:55 gavilancomun: Yes, the (repeat 3) is lazy, so as there are only 2 elements in the vector [1 2] it only contributes two 3s

10:56 ddellacosta: gavilancomun: ah, so, I guess the infinite sequence of 2s that (repeat 2) produces becomes the first argument to repeat, which generates a partial, which then gets applied to the values in the [1 2 3] ?

10:57 gavilancomun: ,(doc map)

10:57 clojurebot: "([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & ...]); Returns a lazy sequence consisting of the result of applying f to the set of first items of each coll, followed by applying f to the set of second items in each coll, until any one of the colls is exhausted. Any remaining items in other colls are ignored. Function f should accept number-of-colls arguments."

10:58 gavilancomun: Not sure you need to involve the notion of a partial...

10:59 ,(map #(list %1 %2) (repeat 2) [1 2 3])

10:59 clojurebot: ((2 1) (2 2) (2 3))

11:00 gavilancomun: map makes the pairs which then get fed to repeat

11:01 ddellacosta: gavilancomun: right, I see, I was misreading it. Thanks!

11:01 gavilancomun: np :-)

11:02 ,(map list (repeat 2) [1 2 3])

11:02 clojurebot: ((2 1) (2 2) (2 3))

11:02 gavilancomun: There you go, no need for the %

11:37 agarman: anyone have an opinion on congomongo v. monger?

11:41 roppongininja: why does clojure.java.io/reader work and (:require clojure.java.io)) with just reader doesnt

11:42 cbp`: roppongininja: those are two different things. Can you explain better what's not working?

11:43 roppongininja: something like this works http://pastebin.com/qUmgkWsG

11:44 justin_smith: roppongininja: require does not bring symbols into scope, use or :as do

11:44 roppongininja: something like this doesnt

11:44 http://pastebin.com/fcYinAGp

11:44 (sorry for flooding : /)

11:44 justin_smith: (:require [clojure.java.io :as io]) ... (io/reader ...)

11:45 cbp`: roppongininja: the first one working is a fluke

11:46 roppongininja: you want what justin_smith wrote or (:require [clojure.java.io :refer [reader]])

11:49 roppongininja: Ok thanks guys :)

11:52 justin_smith: csound devs are working on Clojure integration http://csound.github.io/site/news/2014/06/09/score_library_clojure.html

11:59 deathknight: Is there a zero-to-hero guide regarding clj-http (or its alternatives) and making API calls with google apps?

12:02 roppongininja: I have a file, which in each line has 2 doubles (2 values). How do I read that file and write first values in each line into one map and second values in each line into another map?

12:03 cbp`: roppongininja: how big is the file?

12:03 roppongininja: small

12:04 4kb

12:04 deathknight: I'm interested in the answer to this also *_*

12:06 dbasch: roppongininja: what are the keys and values of each map?

12:07 roppongininja: it should be the row number (line number) but insted of a map you can use a list as well

12:07 if that'll be easier

12:08 dbasch: 1) slurp the file (because it’s small)

12:08 2) split it by \n

12:09 3) map split by space to each line

12:09 that will give you a 2 x n matrix of strings representing doubles

12:10 CookedGryphon: or get an io/reader on the file and use line-seq rather than slurp and split by \n

12:10 dbasch: yes, it makes no difference for a 4k file though

12:11 then you can do apply map vector to the result, and now you have an n x 2 matrix

12:11 justin_smith: https://www.refheap.com/86402 alternately, line-seq

12:12 dbasch: justin_smith: faster to write than to explain :P

12:13 although that’s not what he wanted

12:13 deathknight: I can't wait until that refheap is like english

12:14 justin_smith: https://www.refheap.com/86402 updated to key in the maps by line number

12:15 dbasch: I think that's what he wanted now, I just went ahead before the spec was fully described knowing it would be easy to adapt

12:28 roppongininja: how do I split a string containing two doubles into two doubles? :)))

12:29 gfredericks: the haxy way is

12:29 ,(def s "3.14 6.28")

12:29 clojurebot: #'sandbox/s

12:29 justin_smith: roppongininja: see my paste, it is in there (map (partial read-string) ...

12:29 gfredericks: ,(read-string (str \[ s \]))

12:29 clojurebot: [3.14 6.28]

12:30 justin_smith: ,(map (comp (partial map read-string) #(string/split % #" ")) "1 2")

12:30 clojurebot: #<CompilerException java.lang.RuntimeException: No such namespace: string, compiling:(NO_SOURCE_PATH:0:0)>

12:30 justin_smith: ,(map (comp (partial map read-string) #(clojure.string/split % #" ")) "1 2")

12:30 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Character cannot be cast to java.lang.CharSequence>

12:30 justin_smith: ergh

12:30 dbasch: roppongininja: https://www.refheap.com/86405

12:30 justin_smith: ,((comp (partial map read-string) #(clojure.string/split % #" ")) "1 2")

12:30 clojurebot: (1 2)

12:30 justin_smith: there we go

12:31 mindbender11: justin_smith: those are not doubles

12:35 dbasch: https://www.refheap.com/86406

12:36 justin_smith: mindbender11: fair point

12:36 ,((comp (partial map read-string) #(clojure.string/split % #" ")) "1e0 2e0")

12:36 clojurebot: (1.0 2.0)

12:36 mindbender11: ,((comp (partial map read-string) #(clojure.string/split % #" ")) "1.0 2.0")

12:36 clojurebot: (1.0 2.0)

12:37 dbasch: I’m sure it could be prettier, but my paste does what roppongininja asked

12:38 justin_smith: dbasch: definitely prettier than the piece of shit I pasted :)

12:40 dbasch: justin_smith: still my last line is pretty ugly

12:57 TimMc: justin_smith: Now do that to "NaN Infinity"

12:58 justin_smith: ,((comp (partial map read-string) #(clojure.string/split % #" ")) "NaN Infinity")

12:58 clojurebot: (NaN Infinity)

12:58 justin_smith: OK

12:58 that's cheating, those are symbols :)

12:58 TimMc: &(-> "NaN" read-string class)

12:58 lazybot: ⇒ clojure.lang.Symbol

12:59 TimMc: &(-> "NaN" (Double/parseDouble) class)

12:59 lazybot: ⇒ java.lang.Double

12:59 justin_smith: right

12:59 if you really know it is all doubles parseDouble is clearly better

13:00 TimMc: That means EDN is not good for round-tripping floats. :-(

13:01 Bronsa: TimMc: just use tools.reader and that should work :D

13:06 ticking_: am I missing something or is there no good way to get a predicate matching element from a sequence and have the item and rest of the sequence returned?

13:06 cieloesazul: hi, how can I run all of the tests in the clojure repo?

13:06 justin_smith: ,(group-by even? (range 10)) ticking_:

13:06 clojurebot: {true [0 2 4 6 8], false [1 3 5 7 9]}

13:07 justin_smith: cieloesazul: if it is set up properly, lein test should do it

13:08 ,(group-by #(= % 1) (range 5)) ticking_: if you only expect one match, it would look like this

13:08 clojurebot: {false [0 2 3 4], true [1]}

13:09 ticking_: justin_smith: yeah but I want only one element aka `some` like behaviour similar to ,(let [{t true f false} (group-by even? (range 10))] [(first t) (concat (rest t) f))

13:10 sorry, ,(let [{t true f false} (group-by even? (range 10))] [(first t) (concat (rest t) f)])

13:11 tbaldridge: cool news - https://twitter.com/richhickey/status/476048628289925121

13:11 Bronsa: wooo!

13:12 cieloesazul: justin_smith: to be clear, I'm asking about the clojure source code, not a lein project. btw, I tried lein test and it complained there was no project.clj.

13:12 justin_smith: ,((juxt #(first (filter even? %)) identity) (range 4))

13:12 clojurebot: [0 (0 1 2 3)]

13:12 ticking_: ,(let [{t true f false} (group-by even? (range 10))] [(first t) (concat (rest t) f)])

13:12 clojurebot: [0 (2 4 6 8 1 ...)]

13:12 justin_smith: cieloesazul: then you need to set up your classpath properly, load all the namespaces manually, and then call clojure.test/run-tests

13:12 ticking_: tbaldridge: wow awesome

13:12 justin_smith: cieloesazul: setting up a lein project is easier

13:14 ticking_: cieloesazul: clojure without lein = madness unless you have a really really really good reason

13:14 justin_smith: tbaldridge: wow, that is huge

13:14 bbloom: tbaldridge: haha awesome

13:17 ticking_: am I the only one for whom the name field does not work -.-

13:18 hyPiRion: oh man, awesome that you now can sign the CA online

13:18 Raynes: You can?

13:18 Dear God

13:18 The 21st century

13:18 Feels good

13:19 cieloesazul: ticking_: looks like you have to fill in the signature first and it autofills the name

13:20 bbloom: i like the official legal term "Rich Hickey Contributor Agreement"

13:20 ticking_: cieloesazul: seems so, feels still broken to me ^^

13:20 bbloom: like we're contributing to the six million dollar man or something

13:21 justin_smith: he should offer hickey-bonds

13:21 danneu: i've been using the RHCA on my own projects

13:22 pjstadig: the RHCA is just the Sun CA with some names changed

13:22 danneu: it's a nice rate limiter for the hordes of contributers my projects attract

13:22 pjstadig: (which was the intent with the Sun CA)

13:29 cieloesazul: ticking_, justin_smith, I should have looked at the dev.clojure.org site before asking. I did `mvn test` and it worked. thanks

13:29 justin_smith: cieloesazul: do you have a pom.xml then?

13:29 silasdavis: I'm using a zipper, I need an efficient way to go from a zipper location of a node (say loc(node)) to (loc(child)) given that I have the child

13:30 I could (-> node-loc zip/down zip/right ...)

13:30 where zip/right gets me to the appropriate child

13:33 cieloesazul: justin_smith: yes. it's the clojure language source code from github. it contains a pom.xlm file

13:33 justin_smith: ahh, OK

14:27 amalloy: ticking_: i think you want drop-while: (let [[first-matching & more] (drop-while (complement pred) coll)] ...)

14:30 reading the scrollback more carefully, it looks like you don't want to drop the non-matching items, but rather surgically remove the first matching item from the middle of the sequence and keep all the rest? that's not a very good access pattern for sequences; maybe you can use a set or a multimap or something that supports efficient removal from the midd

14:30 ticking_: amalloy: not quite, other should contain everything that came before the match as well but you just gave me an idea

14:33 amalloy: yeah, that is the thing I'm looking for, you're probably right as for the access pattern :)

14:34 I thought I could do this with split-with but that wouldn't work either

14:40 dbasch: ticking_: why won’t split-with work?

14:43 ticking_: dbasch: you would need to inverse the predicate for the take and drop wait a sec I'll write it down

14:45 dbasch: hm yeah I think you're right

14:46 silasdavis: is this a strange/bad thing to do: https://www.refheap.com/86413

14:47 as in I just want to use Java's binary search, but have it compare using a particular function, but Java comparator expects a comparator to act between the same type

14:47 I'm assuming that java.util.Collections/binarySearch is a fair bit faster than a pure clojure implementation

14:48 ticking_: dbasch: yeah you are right :) , I got mixed up in the negation

14:48 ,(let [coll (range 5) pred #(= 2 %) [t d] (split-with (complement pred) coll) other (concat t (rest d)) match (first d)] [match other ])

14:48 clojurebot: [2 (0 1 3 4)]

14:49 llasram: silasdavis: That is totally the way to go

14:50 S11001001: silasdavis: there exists a type containing all values

14:52 amalloy: silasdavis: you might also benefit from putting this into a sorted data structure to begin with, instead of doing binary search on a vector

14:53 silasdavis: I'd put in in a BST

14:53 but i'm using it with a zipper

14:53 and I have written a down function that zips down to the nth child

14:54 and that implementation wants a vector or equivalent

14:54 actually I'd use a sorted-map

14:54 ticking_: amalloy: I just realized that "have you tried a different datastructure" is clojures equivalent to "have you tried to turn it off and on again" ^^ thanks for the reminder :D

14:55 justin_smith: silasdavis: what about something like a sorted-set or sorted-set-by that maintains its own tree and sorts on insertion?

14:55 p_l: ticking_: well... it *IS* the basic thing to consider, IMO :P

14:55 silasdavis: perhaps I should reverse a bit: from a node in zipper, I need to jump to a child of that zipper without scanning all the children

14:55 and get the child loc

14:56 I need a way of looking up the child quickly by a key, which is easy enough, but then I need a way to jump directly to the appropriate child

14:56 ticking_: p_l: yeah I completely agree, clojures seq concept is bot a gift and a curse, because most operations will leave you with it, and one is tempted to keep using it

14:56 amalloy: have you uh...considered whether you need a zipper? it's vanishingly rare to have a good reason to use zippers

14:56 silasdavis: I was able to modify zip/down to jump to the nth child

14:57 well it makes my implementation of trie fairly nice

14:57 justin_smith: (inc amalloy) - unless this is just a "how do I use a zipper" exercise

14:57 amalloy: the fact that you're modifying zip/down to go to some nth child, rather than the first one, screams that you don't really want zippers

14:57 p_l: ticking_: One thing I was taught in general is that one should always first look at data, then at algorithm, then think about implementation :P

14:58 silasdavis: hm

14:58 amalloy: you certainly don't need zippers to implement a prefix trie. they'll just get in the way

14:58 nested maps, update-in, get-in, are all you need

14:58 ticking_: p_l: yeah, but you don't really want `into`s all over the place either

15:00 p_l: I feel that clojure.core shouldn't contain all the seq stuff, there should be clojure.core clojure.seq and clojure.reducers, so that you don'h, always go to seqs as the default

15:00 p_l with reducers the `into`s wouldn't be that bad

15:01 * p_l wonders if this is clojure's variant of "everything is a list" meme

15:01 ticking_: p_l: well everything is a seq

15:02 p_l: ah no keywords arent ^^

15:02 justin_smith: ,(seq? 'everything)

15:02 clojurebot: false

15:02 justin_smith: :)

15:02 ticking_: touche

15:02 ^^

15:02 p_l: ticking_: a friend of mine had "lisp" class in uni. We told him to bring a banner saying "you're wrong" :D

15:03 * p_l is a CL person, rarely used lists except when he actually needed a list...

15:03 ticking_: lol

15:03 justin_smith: ,(map seq? [:everything 'everything "everything" ::everything])

15:03 clojurebot: (false false false false)

15:04 ticking_: ,(seq "everything")

15:04 clojurebot: (\e \v \e \r \y ...)

15:04 ticking_: though ^^

15:04 silasdavis: amalloy, hm yeah I might have a rethink, thanks

15:04 justin_smith: ,,(map (comp seq? seq name) ["everything" :everything ::everything 'everything])

15:05 clojurebot: (true true true true)

15:05 ticking_: justin_smith: yeah I feared that name gets called automatically on keywords and symbols ^^

15:05 thus my inital statement ^^

15:08 amalloy: i don't think it conveys anything to put ^^ after every sentence ^^

15:11 exobyte: Any resources for Java programmers leanring Clojure other than Rich Kickey's videos?

15:11 technomancy: amalloy: I know, right. (PLEASE RT)

15:11 SegFaultAX: exobyte: http://www.clojurebook.com/ and Joy of Clojure are excellent.

15:12 ticking_: amalloy technomancy: doesn't harm either, and it has proven to lessen the cance of the convesation partner feeling offended (some sentences sound harsher without facial expression) by a significant margin

15:12 SegFaultAX: And they're agnostic of your background.

15:12 exobyte: My advice to you is to learn Clojure /the Clojure Way/, as opposed to trying to fit Clojure into your existing Java mental model.

15:13 exobyte: SegFaultAX: fair enough

15:13 numberten: is there a strict version of repeatedly?

15:14 justin_smith: exobyte: my small nugget of wisdom: information hiding doesn't buy you much when everything is immutible, the "final" status of the datastructures is usually all the encapsulation you need

15:14 SegFaultAX: numberten: (repeatedly n fn)

15:14 amalloy: SegFaultAX: he said strict

15:14 numberten: no

15:14 exobyte: SegFaultAX: I also know C, JS, and python; my issue, and this was with learning python, is lots of resources spend too much time trying to teach me to program.

15:14 numberten: alright thanks

15:15 amalloy: generally "the strict version of X" is not included, because you can easily make anything strict if you want, with doall or dorun or whatever

15:15 justin_smith: exobyte: joy of clojure if anything assumes you are too competent, it is not a book that talks down to the reader or assumes you are not a programmer

15:15 exobyte: justin_smith: well that's amost like my java code!

15:15 justin_smith: exobyte: well that's a great start then :)

15:15 clojure just makes that approach easier, more default

15:15 SegFaultAX: But doall on repeatedly without a size is a bad idea.

15:15 exobyte: justin_smith: I'd rather have *too* competent.

15:16 justin_smith: exobyte: many clojure newcomers find joy of clojure baffling, but it is a good book, and if you don't want your hands held do check it out

15:16 SegFaultAX: exobyte: In some sense you're going to have to re-learn how to program. Or at least, you're going to have to re-learn certains ways of modeling problems in your head.

15:16 exobyte: justin_smith: the author of a python book I read said he never found regexes or composite dict keys to be worth learning. cringes.

15:16 justin_smith: wow

15:16 SegFaultAX: exobyte: :( What book was this?

15:17 gtrak: no composite keys, omfg.

15:17 justin_smith: exobyte: python culture can be pretty aggressively mediocre sometimes

15:17 exobyte: SegFaultAX: checking... Idomatic Python, was really good, though

15:17 numberten: amalloy: if i understand correctly, the only difference between dorun and doall is that the former doesn't retain the head?

15:18 SegFaultAX: How good can it be if the author doesn't see value in something as basic as composite dict keys?

15:18 gtrak: admittedly, I'm pretty bad at regexes, saying they aren't worth learning is like saying compilers shouldn't exist.

15:18 exobyte: SegFaultAX: "Learning to Program Using Python." I should have paid more attention to the title

15:18 mdeboard: everyone's so crusty in here today

15:18 cbp`: hrm sorted-set doesn't print in sorted order in clojurescript

15:18 mdeboard: grizzled vets everywhere

15:19 danielcompton: cbp` in clojurescript set sorts you

15:19 justin_smith: cbp`: wow, that is weird

15:19 sounds like a bug

15:20 cbp`: ,(sorted-set 6 92 1 2 3 4 5 1 0 2 39 4)

15:20 clojurebot: #{0 1 2 3 4 ...}

15:20 exobyte: justin_smith: I saw that mediocrity at a former job, too. a lead dev on a major website didn't like decorators because he couldn't figure out the stact traces.

15:20 cbp`: #{0 1 39 4 92 6 3 2 5} in cljs

15:20 SegFaultAX: exobyte: ... what does that have to do with decorators?

15:21 justin_smith: SegFaultAX: decorators can lead to stack traces that don't look like your code, I guess

15:21 not nearly as bad as what laziness does to stack traces though...

15:21 exobyte: SegFaultAX: it was like he said "decorators are too hard"

15:22 SegFaultAX: justin_smith: Decorators are just syntactic sugar. @foo def bar(): ... == def bar(): ... bar = foo(bar)

15:22 justin_smith: see also the official reasons for not supporting the elimination of the GIL back when that was done, and for not having real lambdas

15:22 exobyte: justin_smith: it's too hard(tm)

15:23 SegFaultAX: Removing the GIL /is/ too hard, though.

15:23 technomancy: ticking: oh, I read it as "see the above line"

15:23 exobyte: justin_smith: coming from java, python's VM is a joke.

15:23 SegFaultAX: when you don't have a proper concurrency or memory model, yes.

15:23 SegFaultAX: Considering just about every library (including the standard library) is not built to be thread-safe, the rammifications of removing the GIL would be dire.

15:23 justin_smith: SegFaultAX: they did it once, and nobody supported that branch of the code

15:23 well yeah, there is that

15:24 SegFaultAX: justin_smith: It has been done mulitple times by multiple people.

15:24 justin_smith: but hell, they can't even update libs to version 3

15:24 SegFaultAX: interesting, I had no idea

15:24 SegFaultAX: Yea, much less make them thread safe.

15:24 justin_smith: If you're interested in learning more about the Python GIL: https://www.youtube.com/watch?v=Obt-vMVdM8s

15:25 justin_smith: I think with its culture, python is stuck with "intuitive" as a hard constraint, which pretty much rules out doing concurrency right

15:25 exobyte: What was funny was because of the GIL, we couldn't run the webapp as a single process, so the local in-memory cache got cloned.

15:25 cbp`: guido is still crusty about being forced to put lispy things inside python

15:25 justin_smith: cool, thanks SegFaultAX

15:26 SegFaultAX: justin_smith: Great talk in general, even if you never use Python IRL.

15:26 cbp`: like anonymous functions

15:26 SegFaultAX: cbp`: And map, filter, reduce.

15:26 amalloy: it's funny because of all the things that are in python *anyway* that were pioneered by lisp

15:27 exobyte: amalloy: all the cool parts that people like

15:27 justin_smith: SegFaultAX: clearly because these fp concepts are not accessible

15:27 exobyte: amalloy: the class system was bolted on

15:27 justin_smith: not *intuitive*

15:27 SegFaultAX: If we played "remove all the things lisp invented from Python", Python would cease to exist as a language.

15:28 justin_smith: I think GvR drinks from the same koolaid bowl as the Pike et al.

15:28 (The golang team, that is)

15:28 exobyte: Python people do love Go

15:29 cbp`: It's nice that it makes async things possible i guess

15:29 SegFaultAX: Well I just mean in terms of language design. Pervasive mutability, imperativeness, etc.

15:29 I'm not making a value judgement about whether that's good or bad. Just pointing out that the languages are similar in that respect.

15:32 If and when Go ever gets parametric polymorphism, I'll give it a more serious look.

15:33 But for me personally, for the style of programming I enjoy doing and the types of applications I tend to write, lack of PP and other FP-enabling tools makes it a non-starter.

15:33 justin_smith: I have hella respect for pike, he is a very smart man, even if he is often wrong

15:33 amalloy: cbp`: are you sure about that sorted-set? the sorted-set code looked fine to me in cljs source, so i tried running your example, and it prints ordered for me with latest cljs

15:35 oh, actually, i bet i'm not in a cljs repl. it's been ages since i tried to use that project

15:36 okay, whew. even in a cljs repl: https://www.refheap.com/86415

15:37 cbp`: amalloy: I guess I should update first..

15:40 amalloy: jesus, does repljs still require you to type :cljs/quit to quit? i'm certain i sent a patch that lets C-d exit

15:40 deathknight: :O

15:41 amalloy: http://dev.clojure.org/jira/browse/CLJS-167

15:43 wei: is there a way to write a middleware handler that knows whether its inner routes matched or not?

15:44 use case: I must return 401 for routes that matched, but nil otherwise so the matcher can fall through

15:46 justin_smith: (fn [handler] (fn [request] (if (should-401 request) (assoc request :status 401) (handler request)))) something like this, if you want to short circuit all previous handlers to be preempted

15:47 cbp`: amalloy: no clue https://www.refheap.com/86416

15:47 going out to eat for an hour though

16:40 expez: Any good places to read about error handling in clojure?

16:40 joegallo: well, what do you want to know?

16:40 and how well do you already understand java exceptions?

16:40 expez: I write Java profesionally :(

16:41 Java forces you to think about every exception, so the first question is how do I even find out what can go wrong when I'm calling a clojure function?

16:41 bbloom: expez: javadoc

16:41 joegallo: ah, simple

16:41 anything can go wrong

16:42 expez: Reading through source of the entire stack beneath me doesn't seem like a good idea

16:42 joegallo: basically forget about checked exceptions, they're all just runtime exceptions now

16:42 stuartsierra: As some well-known JVM designer once put it, checked exceptions are a fiction of javac.

16:42 joegallo: stuartsierra: well quoted

16:43 TimMc: And they're typed wrong.

16:43 They're not even a *consistent* fiction.

16:43 http://james-iry.blogspot.com/2010/08/on-removing-java-checked-exceptions-by.html

16:44 expez: The clojure books I've read only deal with exceptions in terms of java interop, but I'm sure some of the clojure functions people write can fail too :)

16:44 justin_smith: expez: many things in clojure are very easy going, and just return nil. If you want to enforce some invarients check out :pre and :post conditions

16:44 bbloom: TimMc: the clojure internals call that "sneaky throw"

16:44 TimMc: expez: You get (try ... (catch ...)) and so forth if you need it.

16:45 And slingshot can be a nice library to use if you want a bunch of exception types without creating classes for all of them.

16:45 bbloom: expez: if you're calling java code that expects you to catch exceptions, that sucks... but it works the same as in java

16:45 technomancy: expez: the only clojure-specific thing about exceptions is ex-info/ex-data

16:45 bbloom: expez: otherwise, just avoid throwing/catching exceptions unless you expect to crash

16:46 by that i mean, crashing is a fine thing to do if you get an unexpected exception

16:46 expez: absolutely

16:48 Has anyone written a library for modularizing a system into components that can crash on their own and then be restarted?

16:48 gfredericks: java.lang.JVMNotAvailableException

16:48 sjl: expez: if you want a common-lisp-condition-system-like lib check out http://docs.caudate.me/ribol/

16:49 gfredericks: expez: I've played around with different approaches to stapling that kind of stuff onto stuartsierra/component, but I didn't feel good about any of them

16:49 TimMc: gfredericks: You twerp, you made me go look that up.

16:49 gfredericks: (inc java.lang.JVMNotAvailableException)

16:49 lazybot: ⇒ 1

16:49 bbloom: all: please don't suggest random libs to new comers who have foundational questions

16:50 gfredericks: I am a newcomer to this conversation and don't know who is a newcomer :P

16:50 stuartsierra: bbloom: amen

16:50 expez: gfredericks: in terms of building it on top of component or the actual approach of restartable / isolated components?

16:50 gfredericks: expez: the former I think

16:51 TimMc: bbloom: Probably a good idea if those situations can be identified.

16:51 gfredericks: coordinating failure in general has been hard; erlang has this nice feature of forcing a group of processes to crash together

16:51 expez: mhmm

16:52 stuartsierra: I've been thinking about ways to make 'component' support error handling and restarts. But it's very hard.

16:52 bbloom: expez: the short answer is: avoid exceptions unless java forces them on you. then pretend it's just like java. get a baseline of experience w/ clojure

16:52 gfredericks: stuartsierra: I've ended up implementing error channels and similar things a few times

16:52 for batch jobs: a promise that gets delivered with nil on success or a throwable on error

16:53 expez: bbloom: thanks, that sounds like good advice. Errors and function composition go poorly together :p

17:26 Glenjamin: i've been playing around with a component-like system that attempts to minimise closures - in theory this would make it more resiliant to errors

17:28 although that wasnt my goal when building it

17:28 bbloom: Glenjamin: by minimize closures, you mean avoids capturing mutable state in closures?

17:28 Glenjamin: or any state really, yeah

17:29 bbloom: well i guess there really isn't any other kind of state, besides mutable

17:29 Glenjamin: i was annoying at having to rebuild all app state when changing a function

17:29 *annoyed even

17:29 especially when my app took ~10s to load up its state

17:29 so i'm trying to use vars in a way that doesn't break tools.namespace/refresh

17:30 which basically means my ring handler is a very small clojure that calls find-var

17:31 closure even

17:31 it's really hard to type closure in this channel

17:38 justin_smith: Glenjamin: isn't this what passing #'handler to ring already does?

17:38 Glenjamin: yes, but i had an additional constraint

17:39 justin_smith: oh, ok

17:39 Glenjamin: in order to inject the other bits of my system into the ring handler without clojures

17:39 i'm assoc-ing them into the request map

17:39 i expected #'handler to work, but for some reason it can be broken with tools.namespace/refresh

17:39 so i do (find-var 'handler) instead

17:40 where handler is in another namespace

17:40 this is still fairly trial and error, i intend to poke into what clojure is actually doing under the hood and maybe write this up as a blog post

17:41 justin_smith: I wonder what the cases are for using find-var vs. resolve

17:41 Glenjamin: it seems like a var can end up pointing at the old value when tools.namespace destroys and rebuilds a namespace

17:41 amalloy: Glenjamin: i bet t.n/refresh doesn't just re-def the vars; it deletes the namespace wholesale and starts over

17:41 Glenjamin: it does, yes

17:41 ,(doc resolve)

17:41 clojurebot: "([sym] [env sym]); same as (ns-resolve *ns* symbol) or (ns-resolve *ns* &env symbol)"

17:42 amalloy: right, so naturally the old var still exists, and a new one with the same name is created

17:42 vars aren't interned by name like keywords are

17:43 so ring still has a handle on the old var, which is pointing to the same function it always did

17:43 Glenjamin: hrm, seems like (ns-resolve) should do roughly the same thing as (find-var)

17:43 sounds right amalloy

17:43 justin_smith: Glenjamin: yeah, they seem similar, which makes me wonder what would indicate one vs. the other is appropriate

17:43 amalloy: i don't understand your point re ns-resolve vs find-var

17:44 Glenjamin: from my limited understanding, they seem to do the same thing

17:45 justin_smith: Glenjamin: well, one difference is resolve does not require that its arg be fully qualified

17:52 ,(/ 2) TIL

17:52 clojurebot: 1/2

17:53 justin_smith: handy

18:00 Raynes: mdeboard: We both use rdio <3

18:00 We're rdibros

18:03 mdeboard: Raynes: lol

18:25 danielcompton: Any spotifriends out there?

18:54 catern: What is the idiomatic way to iterate through a sequence with a function, passing a state variable along?

18:55 technomancy: catern: reduce?

18:55 catern: Ahhh right yes

18:57 justin_smith: pedantically it's not state and its not a variable - its an argument to a function that gets a new binding on each iteration

18:57 (unless you also make it be an atom or something)

18:59 technomancy: hm; I don't see how it's not state

18:59 justin_smith: it's a local, non-mutable, non-shared, per-execution state I guess

19:00 but one usually doesn't describe eg, the value of x inside (fn [x y] (+ x y)) as being a state or a variable

19:00 it's a binding

19:00 technomancy: it seems to match the mathematical definition of a variable

19:01 justin_smith: yeah, but that's kind of overloaded with some other implications in programming

19:01 technomancy: I just take it as a given that the other definitions don't apply because they can't apply.

19:02 amalloy: wait, when did (str (range)) change to be non-terminating? it used to just return "clojure.lang.LazySeq@1234567" or similar

19:02 turbofail: how could (str ...) return a lazy sequence?

19:03 oh nm

19:03 justin_smith: turbofail: the string form of a lazy sequence was just an opaque object, and did not realize or reveal the contents

19:03 Bronsa: ,(str (range 10))

19:03 clojurebot: "clojure.lang.LazySeq@9ebadac6"

19:03 amalloy: but now the way it tries to hash the collection apparently involves realizing all its elements

19:04 justin_smith: ,(str (range))

19:04 clojurebot: #<OutOfMemoryError java.lang.OutOfMemoryError: Java heap space>

19:04 justin_smith: yeah, that seems like a regression

19:04 amalloy: i think this was actually in like 1.4 or 1.5. it's not super-recent

19:05 Bronsa: amalloy: just checked with 1.3.0, same behaviour

19:05 amalloy: 1.2?

19:05 Bronsa: ditto for 1.2

19:05 amalloy: man, i don't wanna be crazy. i'm sure this wasn't always the case

19:05 but 1.2 is when i started

19:06 Bronsa: amalloy: looks LazySeq's hashCode always depended on the realized seq

19:09 amalloy: would it be crazy to reimplement toString on LazySeq to be like: {return "clojure.lang.LazySeq@" + System.identityHashCode(this);} ?

19:09 so that you can at least print the damn things

19:10 technomancy: amalloy: right, I always assumed the "clojure.lang.LazySeq@9ebadac6" representation was specifically there to allow them to be str'd without realizing them

19:10 Bronsa: same here

19:11 amalloy: stuart s noticed this three years ago, and nobody cared: https://groups.google.com/forum/#!topic/clojure-dev/F68GRPrbfWo

19:18 anyway, i re-realized this because i ran into a scala collection that has a non-terminating toString, and i wanted to herald clojure's moral superiority, because i know (str (range)) doesn't suck. but it turns out i was wrong

19:23 {blake}: OK, I've forgotten how to do this: "(defn myproc [parm & more] ... (myproc (first more) (rest more))..." The "rest more" creates a list but so does the & in the parm list. How do I stuff the remaining params back into the proc without ending up with a nested list?

19:24 turbofail: apply

19:25 (apply myproc (first more) (rest more))

19:25 {blake}: turbofail, Yeah, I was trying to figure out how to fit apply in there.

19:25 amalloy: (apply myproc more)

19:25 {blake}: turbofail, OK, so I was thinking of trying to de-listify rather than ... lemme see if I got that...

19:26 turbofail: yeah actually amalloy's version is equivalent

19:26 amalloy: although, really, consider making myproc just take a list of params, instead of &args params

19:27 {blake}: amalloy, OK...but let's say--oh, that makes sense yeah. And if it's not "(first more)" but "(someothervaluederivedfromfirstmore)", I could put that into the list...

19:27 For the purposes of this exercise, I have discrete items, not a list.

19:28 skinkitten: is there a shorter/simpler way of doing this? http://cryptb.in/zkEf#afb8d04ad2702274261bd938ca252d99

19:29 justin_smith: for the impl? (repeat 1)

19:29 ,(repeat 1)

19:29 clojurebot: (1 1 1 1 1 ...)

19:30 {blake}: (because I remembered amalloy recommending using lists as parameters from last week.)

19:32 skinkitten: justin_smith, nice. thank you.

19:42 justin_smith, how about this? http://goo.gl/JS5Dxh

19:42 mdeboard: What is the proper syntax for `require` in the repl?

19:43 Is there any reason to not just use `use`?

19:44 AWizzArd: mdeboard: (require 'com.example.ns)

19:44 justin_smith: mdeboard: use leads to harder to refactor code, but in a repl there is often reason to just do use

19:44 AWizzArd: Or (require '[com.example.ns :as exns])

19:44 Raynes: mdeboard: (require '[foo.bar :refer [things]]); (require 'foo.bar); (require '[foo.bar :as barness])

19:44 justin_smith: or (require '[com.example.ns :as ex])

19:44 Raynes: mdeboard: There is every reason to not use `use`.

19:45 mdeboard: what about :refer :all

19:45 Raynes: require is now a superset of `use`'s functionality.

19:45 technomancy: Raynes: eh; even in the repl?

19:45 mdeboard: When I try to use that I get an error, e.g. (require '(foo.bar :refer :all))

19:45 AWizzArd: Innocent question, storm of answers (:

19:45 Raynes: You should almost never use that anyways.

19:45 technomancy: Yes, even in the repl.

19:45 :refer :all

19:45 technomancy: I still use `use` in the repl because it's short

19:45 Raynes: There is not one single good reason to use that god forsaken function.

19:45 mdeboard: it's shorter

19:45 Raynes: That's not a reason.

19:45 mdeboard: that's a good reason

19:45 technomancy: no one has to know

19:46 mdeboard: I put on my wizard robe and hat

19:46 Raynes: I pick up my rifle.

19:46 * AWizzArd read somewhere “wizard”.

19:46 Raynes: I see where this is going.

19:46 amalloy: (use 'require)

19:48 AWizzArd: I think we now have a clear winner.

19:48 amalloy: can you also require use?

19:48 amalloy: you can, but it's not required

19:49 technomancy: granted the only thing I use is clojure.pprint

19:49 because I know exactly what's going to happen

19:50 justin_smith: what about clojure.repl?

19:50 technomancy: personally I would never do that

19:52 but if you're not an emacs user it might make sense

19:53 amalloy: clojure.reflect is about as reasonable as clojure.pprint, probably

19:54 technomancy: basically any time I do a use, it's because nrepl-discover doesn't work yet.

19:56 Bronsa: I still (use 'clojure.repl) from slime because I never remember how to do apropos otherwise

19:57 AWizzArd: Best way to get (into (sorted-map-by-val) some-map)?

19:58 {:b 2, :c 3, :a 1} ==> {:a 1, :b 2, :c 3}

19:58 {:b 2, :a 3, :c 1} ==> {:c 1, :b 2, :a 3}

19:59 Not really possible I guess.

20:01 amalloy: maps sorted by value are not really a thing. you don't address what to do in the case of value collisions, for exampl

20:02 but for many cases where you think you want a map sorted by value, a priority queue can suffice

20:02 metellus: ,(= {:a 1 :b 2} {:b 2 :a 1}) ;; there's also the fact that this is true

20:02 clojurebot: true

20:02 metellus: you could go from a map to a seq sorted by keys within the map

20:02 Bronsa: isn't that like a priority map?

20:03 https://github.com/clojure/data.priority-map

20:03 AWizzArd: amalloy: I just wanted this for testing purposes. My classifier outputs a map with tons of classes and without sorting it’s not possible to visually match the winner. I’ll go with (sort-by val #(compare %2 %1) (classify …)) now.

20:04 Bronsa: looks good.

20:13 Shayanjm: What do you guys think of the clojure for the brave and true book?

20:17 catern: i read it to learn clojure! very recently! it was pretty good I think

20:17 but I already knew Lisp from SICP

20:18 also, I thought it needed an appropriate soundtrack with that kind of title, so I listened to https://www.youtube.com/watch?v=atM3ZhF8MVs all throughout

20:18 Shayanjm: haha cool :) This is my first venture into any functional programming so I figured I'd litmus test some opinions.

20:20 AWizzArd: ,(key "foo")

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

20:22 AWizzArd: catern: I will follow that youtube link now but surely hope it’s not the 10-hour version of the Nyan cat!

20:33 justin_smith: skinkitten: another thing I noticed as I was closing that tab just now: if you bind the lazy sequence in a def, that holds onto the head and it can't be collected unless you clear the var. If you instead call (repeatedly 1) at the place in code where you need the sequence, the values are not bound or held so they can be cleaned up immediately

20:34 skinkitten: IOW don't bind to the head of a lazy sequence if it is that cheap to generate

20:38 skinkitten: justin_smith, how about this (def ones (repeat 1))

20:39 catern: AWizzArd: no, much more appropriate, don't you think?

20:39 now I listen to it often when I clojore-code

20:39 it puts me in the mindset of the parenkin - Lispborn!

20:40 skinkitten: justin_smith, what's "clear the var"?

20:41 AWizzArd: catern: yes is good. I typically listen to brown noise: http://simplynoise.com/

20:42 justin_smith: skinkitten: the problem is that if someone uses 1000000 values from 1s, then that var now holds that long a sequence

20:43 skinkitten: if, instead, you just use (repeat 1) inside any call where you need (1 1 1 1 ...) then you never need more than chunksize to exist at any time, and they can be garbage collected

20:43 clearing the var would be reassigning it so the previous value can be reclaimed

20:44 turbofail: though for this particular example it doesn't really matter

20:44 skinkitten: justin_smith, wow yeah. totally makes sense.

20:44 thanks

20:44 turbofail: but if you were doing say (reduce + (take 10000000 ones)) then you'd probably want to do as he says

20:45 justin_smith: turbofail: yeah, it's the general principle of the thing

20:46 any unbounded lazy seq tied to a var should be treated as a potential memory leak (see also line-seq from some reader, etc.)

20:46 skinkitten: justin_smith, (take 10 (repeat 1)) returns '(1 1 1 1...) ? I might have read you incorrectly, I had imagined it would just return 1

20:47 justin_smith: ,(take 10 (repeat 1))

20:47 clojurebot: (1 1 1 1 1 ...)

20:49 skinkitten: ,(take 10 1)

20:49 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long>

20:49 nullptr`: ,(take 10 [1])

20:49 clojurebot: (1)

20:50 amalloy: justin_smith: chunksize? i don't see how that's relevant to the discussion

20:51 repeat isn't chunked, after all. but even if it were, introducing chunking is just a distraction to someone who's just learning how to deal with lazy sequences. (to be honest, it's a distraction to almost anyone, since chunking so rarely matters)

20:51 justin_smith: amalloy: with some other lazy sequences, I imagine that would be a lower bound on how much would be realized at a time, even if you did not hold onto the head

20:52 amalloy: fair point

20:53 amalloy: justin_smith: chunk size can vary across seqs, actually. for example, filter preserves chunkiness, but produces chunks of varying size according to your predicate

20:53 if the incoming sequence has a chunk size of 32, and only 5 elements of that chunk pass your predicate, then the chunk that comes out will have a chunk size of 5

20:56 skinkitten: in racket I made it this way (define ones (lambda () (cons 1 ones))). Whats the direct translation of that in clojure?

20:57 hiredman: skinkitten: well it looks like user error

20:57 gratimax: (repeat 1)

20:57 hiredman: skinkitten: what are you trying to create with that?

20:58 amalloy: hiredman: i mean, you can cons a number onto a lambda, and that's not a totally crazy way to represent lazy sequences in racket

20:58 hiredman: amalloy: right, but it doesn't seem likely to be what he meant to do

20:58 which is why I asked

20:59 skinkitten: well before reading streams in clojure docs, I use to call that function a stream but I'm unsure of naming it that, here is the output from racket '(1 . #<procedure:ones>)

20:59 hiredman: seqs

21:00 streams in clojure are a historical expirement that never made it in to the language

21:00 skinkitten: right, so it creates a pair of a 1 and a function that returns a pair …

21:01 skinkitten: is your intent to use that to represent what is logically an infinite list of 1?

21:01 skinkitten: hipsterslapfight, yes

21:01 gratimax: like I said, (repeat 1)

21:01 ,(take 5 (repeat 1))

21:01 clojurebot: (1 1 1 1 1)

21:01 amalloy: hahaha. a new nickname for hiredman

21:01 gratimax: ,(take 10 (repeat 1))

21:01 clojurebot: (1 1 1 1 1 ...)

21:02 hiredman: :|

21:02 skinkitten: ,(take-nth 10 (repeat 1))

21:02 clojurebot: (1 1 1 1 1 ...)

21:02 skinkitten: ,(last (take 10 (repeat 1)))

21:02 clojurebot: 1

21:03 gratimax: (repeat 1) is just an infinite list, done with lazy-seq

21:03 it behaves like a list

21:04 a more transparent translation of your code would be something like (def ones (cons 1 (lazy-seq ones)))

21:04 justin_smith: skinkitten: so the point I was trying to make above, is if you had (def ones (repeat 1)) then somewhere else did (last ones), you would not only waste a bunch of CPU cycles, you would also run out of heap space. If instead of (last ones) they did (last (repeat 1)) you only waste CPU and don't fill up the heap because the elements can be reclaimed as they are used

21:06 allenj12: anyone here familirar with hoplon?

21:07 amalloy: ~anyone

21:07 clojurebot: anyone is anybody

21:07 hiredman: ~laugh

21:07 clojurebot: ha ha

21:07 cbp: (inc clojurebot)

21:07 amalloy: hiredman: is it possible to nuke these definitions that get in the way of useful canned responses?

21:08 mynomoto: allenj12: people gather on #hoplon to talk about hoplon...

21:08 amalloy: iirc "forget anyone |is| anybody" doesn't help, because he's inferring it from some other stupid path

21:08 allenj12: mynomoto: o kk thanks

21:08 dbasch: ~everybody

21:08 clojurebot: everybody looks good in a sheinhardt

21:09 hiredman: amalloy: I just have to remember to look in to next time I crack the database open

21:10 skinkitten: ,(last (repeat 10 1))

21:10 clojurebot: 1

21:10 skinkitten: justin_smith, is that space/cycle saving way to call it?

21:11 justin_smith: the trick is not binding the head of the sequence

21:11 skinkitten: so without (def ones (repeat 1)) ???

21:11 justin_smith: right, just use (repeat 1) in place where you need the sequence

21:12 and as others have noted, this likely isn't a big deal here, but it is good to be in the habit of not binding the head of indeterminate lazy things

21:13 skinkitten: justin_smith, what about here? http://goo.gl/JS5Dxh

21:13 it isn't infinite. so thats ok?

21:14 mdeboard: If (use) is so freaking terrible then why is the syntax of require so inconsistent in the repl?

21:14 fook the king

21:15 amalloy: inconsistent in the repl? how is it any different from in ns, or from use? the only difference is that in ns it doesn't want a quote

21:15 mdeboard: If I want to refer all symbols from clojure.core.match namespace, how would I do that in the repl?

21:16 I've been trying variations on (require '[clojure.core.match :refer :all])

21:16 justin_smith: skinkitten: that is hypothetically unbounded, but if you know you are only using only the first N you have the excuse that the elements have some computational cost you are minimizing

21:16 amalloy: what you just typed. right there. that's hwo you do it

21:18 mdeboard: Sure now it works.

21:19 skinkitten: justin_smith, thanks

21:20 I'm going to redact the factorial implementation

21:22 amalloy: i just noticed something interesting about treating Iterable objects as if they were seqs: one more element than necessary is requested from the iterator. https://www.refheap.com/86424

21:24 justin_smith: skinkitten: one option for factorial would be to make a function using iterate, perhaps memoizing it

21:25 amalloy: will a memoized function have the same heap usage issues as a lazy seq with the head held onto, or is it able to drop memoizations after a certain memory pressure?

21:25 dbasch: amalloy: that’s probably because hasNext needs to know

21:27 amalloy: justin_smith: just read the source for memoize. i'm pretty sure you're experienced enough to answer that question with just a quick scan

21:27 dbasch: i actually am not quite sure what's going on. it turns out that (.next (.iterator (tricky))) also throws

21:28 justin_smith: OK yeah, it will actually be more expensive memory wise than just binding the lazy seq would be (but faster for grabbing a specific result)

21:29 dbasch: amalloy: (.hasNext (.iterator (tricky))) returns true

21:29 amalloy: yeah

21:30 dbasch: so probably .next makes it so that (.hasNext (.next …)) needs to be evaluated

21:32 Bronsa: justin_smith: core.memoize offers some smarter implementations

21:32 amalloy: it shouldn't, in theory though, right? if you can call first, you ought to be able to call next

21:32 mdeboard: What is meant by a "transient set" as opposed to a "new set" in the docs for disj/disj!

21:32 amalloy: or rather, .next

21:33 justin_smith: Bronsa: yeah, that's probably what I was thinking of

21:36 amalloy: but that's more a question of how LazySeq/iterator is implemented, whereas i was hoping to find something out about how iterating over other iterable works

21:40 dbasch: amalloy: next “Returns the next element in the list and advances the cursor position.”

21:41 amalloy: dbasch: okay, but the cursor could be pointing at (lazy-seq (throw (Exception.))) without exploding until you actually call .next or .hasNext

21:42 dbasch: amalloy: yes, in theory it should

21:42 amalloy: but in reality, what happens is lazy-seq delegates to (.seq this) for most of its methods

22:19 DomKM: Does Leiningen try to compile my-project.main even if a :main key isn't specified in project.clj?

22:21 I'm getting FileNotFoundExceptions when trying to compile cljx because it is trying to compile a main namespace first, which requires the generated clj namespace.

22:45 Shayanjm: weird

22:45 I'm using Lighttable and working through the brave clojure book

22:46 I'm at the part where it discusses multiple namespaces & refer

22:46 I passed :only into my refer, but for some reason I'm able to access other vars from inside a different namespace in my repl

22:46 any ideas why?

22:49 pcn: Shayanjm: http://clojuredocs.org/clojure_core/clojure.core/refer refer doesn't prevent you from explicitly naming variables in other namespaes.

22:50 It only prevents all of the names from an required namespace from being bound in the current ns. Does that answer your question?

22:50 Shayanjm: I'm not sure if I understand correctly - I'm a bit new to clojure sorry haha bare with me

22:51 So if I have ns1 and ns2, ns1 has thing1 and thing2 defined

22:51 i switch in to ns2, and do something like

22:51 (clojure.core/refer 'ns1 :only ['thing1])

22:52 intuitively - I would think that clojure only referred thing1 out of the entire ns1, therefore thing2 should be inaccessible from ns2, right?

22:52 this also seems to be the behavior that the book depicts, though doesn't seem to be the case when I run it in my own REPL

23:00 dbasch: Shayanjm: refer just created a mapping for thing1, which you can see in (ns-map ‘ns2)

23:00 Shayanjm: but you can still use ns1/thing2

23:01 Shayanjm: dbasch: my point is that it thing1 and thing2 are both usable from ns2

23:01 so it looks like both got a mapping

23:01 catern: Yes, they should be even if you didn't refer them

23:02 Shayanjm: Why's that? I thought thing1 and thing2 are stuck in their ns until I refer them?

23:03 and if I explicitly only refer thing1, thing2 should still be stuck in its ns (still usable via ns1/thing2, but not as thing2 from ns2)

23:03 catern: Yes, but you're addressing them by a full namespace path thing

23:03 Oh

23:03 Shayanjm: nope

23:03 catern: Misunderstood you then

23:04 Shayanjm: Sorry haha - let me try to be clearer

23:04 ns1 contains: thing1, thing2. I switched in to ns2, refered -only- thing1

23:04 when i call thing1 from ns2, works as expected

23:04 but then I realize I can also call thing2 from ns2 as is, without using the full namespace path

23:04 even though I only referred thing1

23:04 catern: Have you tried restarting your repl and getting the issue down to a few commands?

23:05 Shayanjm: yup. Granted, I've been working within the lighttable repl

23:05 let me try with lein repl

23:07 ah, works in lein repl

23:07 weird

23:07 so must be a lighttable bug

23:08 pcn: That makes sense. That would be a good bug to fil.

23:09 Shayanjm: http://puu.sh/9mOvq/4e0d594002.png

23:11 amalloy: Shayanjm: are you sure ns2 doesn't already have namespace mappings in it, eg from requiring a .clj file? if this works for two namespaces that didn't exist previously, that would indeed be a bug in light table

23:11 Shayanjm: amalloy: this is a clean instaREPL in light table & I created (and checked) both namespaces in the repl itself

23:12 granted I'm also really really new to Clojure, so I'm not sure if I just did something stupid or if this is actually a bug

23:12 either way I'll open up an issue w/ lighttable and see if it gets sorted, or if I get flamed for being a noob ;)

23:14 amalloy: Shayanjm: i'd recommend (a) using refheap.com instead of a screenshot, and (b) including some evidence that the namespaces are clean before you started doing stuff (eg, above all of this other stuff, going into ns2 and showing that evaluating thing2 leads to an exception)

23:14 Shayanjm: gotcha.

23:25 amalloy: https://github.com/LightTable/LightTable/issues/1520

23:25 I started just copying the commands to refheap, but I realized that I could illustrate the inconsistencies easier (IMO) via screenshots

23:25 but its only a grand total of maybe 4 commands, so easy to replicate even without copy-pastable code.

23:27 catern: Is light table not using JVM backed Clojure or something?

23:28 Shayanjm: not a clue tbh

23:32 locks: light table is clojurescript

23:34 but it should be using regular clojure for the eval, i think

23:38 PigDude: what's the name of a binding like [arg] as opposed to a let-style binding [name val]?

23:38 for documentation purpose?

23:39 for creating a macro like (with-some-resource [some-name] BODY...)

23:39 andyf: In defn and defmacro, such things are sometimes called the argument vector or arg vector

23:40 PigDude: i don't see them used much elsewhere

23:40 andyf: Not sure if that applies as well to your example.

23:40 PigDude: yea, definitely

23:40 andyf: Where does the value for some-name come from in your example?

23:41 PigDude: not from the code user

23:41 (value supplied by library)

23:41 andyf: Could there be more than one in the vector?

23:41 PigDude: no, never

23:41 andyf: Then why a vector?

23:41 PigDude: as the macro's semantics are for selecting one thing at a time (looping)

23:42 i have a funky test suite right now and i wanted to run the same tests over different inputs

23:43 so i was using a macro for a convenient way to define these tests, which are automatically tested against several implementations

23:43 andyf: and some-name will occur one or more times in BODY?

23:44 PigDude: come to think of it, it wouldn't, i just was hoping to come up with something cleaner than what i have now: a macro that creates a 'deftest' which runs the body over different implementations

23:44 it does this using (binding), and an agreement that test utility functions use the bound name

23:45 ugly. Ugly!

23:45 at least they are effective tests

23:48 if anyone has ideas for improving my tests, i greatly appreciate it, because this organization is not ideal

23:49 andyf: Just looking for anything similar in clojure.core -- haven't found anything quite like it, especially if the name is not used for anything.

23:49 PigDude: yea, it was a stupid idea, sorry :)

23:49 andyf: You can do loops inside of a deftest, if you think that would help.

23:50 justin_smith: PigDude: any function can call test/is, and if that function is called in a deftest during test time, the is call does the right thing

23:50 andyf: e.g. (doseq [f [fn1 fn2 fn3 ...] (test f here))

23:50 justin_smith: PigDude: so you don't need macros for this, you can just define some functions and call them in your tests

23:51 PigDude: don' you lose locality on test failure then

23:51 like you do in most languages when composing tests w/o macros

23:51 justin_smith: PigDude: nope, it tells you which test failed

23:51 and the line number points the the function, called in that test

23:51 PigDude: hm OK, will give that a try, thanks justin_smith !

23:53 wish i could find more on testing w/ clojure tools, some stuff i see jumps right into generative testing/property-based stuff

23:54 justin_smith: PigDude: for me, the big revelation was that if your code is functional, all you need to do is check inputs and outputs

23:55 no need for mocking, scaffolding, yadda yadda

23:55 because you know that stuff won't affect what the function actually does

23:56 PigDude: you know the only reason i do (binding) in these tests is because use-fixtures has no way to send parameters to the test? or am i missing something?

23:56 i mean the nuts & bolts, having worked in erlang a lot i know how to write decent tests, but erlang has very good test tools and i miss them

23:57 common test, stuff like that?

23:57 i find in-depth material on property-based testing, and shallow material on ordinary unit testing :( no big deal, but i'm happy for suggestions

23:59 not being able to access "fixture" data except via dynamic variables is by far my biggest pain point in clojure right now

Logging service provided by n01se.net