#clojure log - Dec 09 2014

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

0:00 dwysocki: well, my project depends on antlr and asm

0:00 rritoch: For my personal projects I'm trying to get away from gen-class dependence

0:00 dwysocki: perhaps those are the real issues

0:00 as they're 100% java libraries

0:01 I think I'm just going to settle for marginalia here

0:01 rritoch: justin_smith: btw, I was able to implement custom numeric types

0:02 dwysocki: I would rather use codox, but it's not really important

0:02 rritoch: justin_smith: It is giving me problems with my unisgned types though since the minus function uses negate

0:02 dwysocki: this was just me trying to add nice documentation onto a school project

0:02 rritoch: justin_smith: So I'm now working on adding, or re-adding, real minus support

0:05 justin_smith: Consensus is that clojure numeric type support of any kind is a hotly-debated topic, so this is probably going to be the point where this becomes a hard-fork.

0:06 justin_smith: I wonder if it would be easier to use signed types of at least twice the size. Since we have BigNum and all. And convert to the bitwise unsigned representation at the boundaries of the system as needed.

0:06 rritoch: justin_smith: Though this code does come at a price, my wife is really mad that I've been staying up till 5am coding

0:07 justin_smith: Internally that is what my signed types are doing

0:08 justing_smith: But I added a INumber interface, so when this version of clojure sees that interface, it knows to call those methods instead, to get the results to the various methods defined by Ops

0:09 justin_smith: I've only found 2 bugs so far, the first with with the lt function, so I added a gt function to deal with it, that only is used when dealing with NumberOps

0:09 justin_smith: The second issue is with minus using negate, since unsigned numbers can't be negated

0:10 justin_smith: Other than that, it works fairly well

0:10 justin_smith: ,(map (juxt + - * /) (range 3))

0:10 clojurebot: #<ArithmeticException java.lang.ArithmeticException: Divide by zero>

0:10 justin_smith: err

0:10 ,(map (juxt + - * /) (range 1 3))

0:10 clojurebot: ([1 -1 1 1] [2 -2 2 1/2])

0:17 rritoch: Can anyone explain the difference between add and addP, I'm really not sure what all these fP's are for

0:19 justin_smith: addP checks for overflow

0:19 add does not

0:19 rritoch: justin_smith: Ok, thanks :)

0:19 justin_smith: and it looks like addP promotes to BigInt

0:19 so there we go

0:19 P is promote I bet

0:19 the difference between +' and +

0:19 $source +'

0:19 lazybot: +' is http://is.gd/OEoK2h

0:20 justin_smith: yup - notice that +. calls addP

0:20 err +' calls addP

0:20 but + just call add

0:21 ,(+' Long/MAX_VALUE 1)

0:21 clojurebot: 9223372036854775808N

0:21 justin_smith: ,(+ Long/MAX_VALUE 1)

0:21 clojurebot: #<ArithmeticException java.lang.ArithmeticException: integer overflow>

0:21 rritoch: justin_smith: Hmm, well for my u1, u2, u4, promotion won't make any seense, so I'll probably unnimplement them, currently I just have them calling their non-promotional counterpart.

0:21 justin_smith: that's the difference

0:21 I think not implementing them is better than implementing but not promoting

0:23 rhg135: anyone have a clue why leiningen.vcs is not picking this up https://www.refheap.com/94599 and it's in :plugins to load it in lein right?

0:24 justin_smith: rhg135: "leinenge.vcs.hg"

0:24 you probably want another n in there

0:25 * rhg135 facepalms

0:25 rhg135: thank you

0:25 justin_smith: eastwood is really good for finding errors like that

0:25 rhg135: man, i shouldn't be typing

0:25 justin_smith: though that one would likely get caught by lein check too

0:26 but anyway, eastwood is great, it will find stupid mistakes and save you a lot of time

0:26 s/stupid/trivial - the stuff that is easy to automatically detect but not always easy to see

0:26 rhg135: ill add it to my profiles.clj now :(

0:27 justin_smith: I keep meaning to add "lein do check, eastwood" as commit hooks for my clojure projects

0:27 FriedBob: Still need to clean my source texts up a bit, and tweak my algorith, but thenew one is coming along nicely.

0:27 (34 : Fluttershy: But I think of FIPS 140-2 compliance with the generated by the gaunt, lone creature was failing test for parsedfile provider instance.)

0:28 justin_smith: markov chain?

0:28 FriedBob: Yeah

0:28 Found a more scalable example that what I first tried

0:28 rhg135: now i need to either fork leiningen quick or do some stuff with robert.hooke

0:29 lein pom is hardwired to git for vcs

0:29 FriedBob: I'm not done compilnig my source texts, and it's already around 7 mb

0:30 justin_smith: "Along remember which she wood was onceived happy the wolf, butter to the brought living, "Good turned and dedicated in that from behind here, by the people, shall have thus father, who struggled her while Little Red Riding the earth.

0:30 that's from my markov generator

0:33 But, in a larger screased dead shall measure of the does you have a portion the gave come and these honored world with here highly resting Hood knocked at the people, for her grandmother forth of the portion might here highly resolve thus far so well and so nobly advanced. It is altogether.

0:35 FriedBob: Ihav a bunch of commit messages in mine, and it line wrapped (hard) to 80 chars, sogave me a lot of briken stuff,

0:35 So I am having to clean that up to get better resules

0:36 I also still need to add 3 seasons of MLP:FiM transcripts still

0:36 justin_smith: mine builds the corpus on every run. It's actually very fast.

0:36 haha, nice

0:36 mine was Little Red Riding Hood and the Gettysburg address

0:37 (for that example, it takes the files to use as command line args)

0:39 FriedBob: I'm using the Cthulhu Mythos, transcripts from MLP:FiM, MLP:EG, git commits to various Puppet Labs repos, and (sanitized) Jira ticket descriptions from said projects

0:39 justin_smith: oh, are you the one doing the lovecraft puppet labs tumblr?

0:39 that is fucking hilarious

0:39 FriedBob: No

0:39 justin_smith: oh, OK

0:39 FriedBob: That's Branan, but he inspired me

0:40 I'm using some of the same corpus as him ( the it and jira bits)

0:40 justin_smith: Puppet Labs actually hosts the Clojerks meetups

0:40 FriedBob: We host quite a few. I wish I was in Portland so I could attend more

0:40 justin_smith: are you nearby?

0:40 FriedBob: Springfield, MO

0:40 Sonot really.

0:40 justin_smith: oh, haha

0:40 FriedBob: But I'll be in Portland next week

0:41 justin_smith: there should be a Clojerks meetup next week

0:41 at Puppet Labs downtown I bet

0:41 FriedBob: I'll try to make sure I go

0:42 Assuming it doesn't conflict with one of mty already scheduled after work work outings

0:42 justin_smith: also Voodoo Donuts is way overrated, but if you must go the one on the east side is nicer than the one downtown

0:43 FriedBob: I've not been there in any of my trips.

0:44 I had already figured out they were basically a tourist trap and there were better places to get maple bacon donuts

0:44 (not that I actually had a ahcne to visit said places)

0:58 rritoch: Any suggestions on how to present these custom numeric types to clojure-dev once they are resolved, there are going to be at least 3 commits that all relate to this issue

0:58 I'm thinking I should create a separate branch for this feature, which only has one commit to produce it

0:59 Probably not important since it has a low probability of acceptance

1:01 Which is really too bad because when it comes to vector operations, this system will make it possible to automate GPU and/or coprocessor accelleration.

1:04 FriedBob: Cleaned up sources some more. Makes a huge difference.

1:04 (12 : Applejack: Wha! Wha... huh? The other friends are either checked in validation, and an internal security)

1:04 It's almost getting to look real

1:07 amalloy: justin_smith: i like king james programming better

1:17 FriedBob: Twilight Sparkle: I need to extend Windows::Handle from access the new code for the other hand, even though there is a colossal bats that nil resource fails the SQL query subtree of well-known group resources

1:18 It's knida amazing what a difference just tweakinmg the formatting of the source makes

1:21 rritoch: amalloy: What exactly is king james programming? I did some googling on it and all I find is bible quotes, but some are interesting https://news.ycombinator.com/item?id=7305122

1:21 dwysocki: for some reason marginalia only pulls out my doc strings for some functions and not others

1:22 I can't find anything explaining why

1:22 amalloy: you followed the link from that ycomb page to http://kingjamesprogramming.tumblr.com/ and thought everything there was bible quotes?

1:22 rritoch: dwysocki: Double check that your doc string is before the parameters, and not after

1:22 dwysocki: rritoch: whooaa

1:23 amalloy: We would like a procedure that expresses the concept of summation itself rather than only with particular sums — for example, (f 84 96) — it performs the work of the LORD

1:23 dwysocki: you just blew my mind, rritoch

1:23 it didn't even occur to me that I could put the docstring before the parameters

1:23 except I've been doing it anyway in multi-arity functions

1:25 rritoch: amalloy: Didn't even pay attention to the tublr post

1:25 amalloy: Anyhow, I've never really thought to apply the bible to programming, I know it's been done in physics with great success

1:27 amalloy: Anyhow, this quote here "All things come from God, through God, and return to God" Is clearly demonstrating a disign pattern, but I think it is a mistranslation. There are different words for God in the original language of the bible, so if I can find a better translation for that part I'm sure it gives some hints as to a good design system

1:29 amalloy: Either way, it seems to be referring to a function comprehension, like (comp God2 God1)

1:30 amalloy: I suppose it could be a function comprehension with itself, like (comp g g) but that deign pattern would be extremly difficult to apply

1:32 dwysocki: I've been down that road many times. That is why I always double-check my docs to make sure I didn't miss any docstrings, and to ensure the docstrings are in the right place.

1:35 Has anyone other than me noticed that just as you near completing a project, computer crashes are more likely? It isn't quite murphy's law, but this seems to happen to me very often.

1:36 rhg135: Its the, I call it, law of life

1:36 FriedBob: Pretty sure that falls under one of Murphey's many laws

1:42 dwysocki: I think my project is finally complete

1:43 this is probably the greatest thing I've ever created

1:43 :')

1:43 rhg135: Link?

1:43 dwysocki: 1 sec

1:43 just pushing everything to git

1:49 ok, more than 1 sec

1:49 lol

1:50 FriedBob: justin_smith: Just got this one.. (73 : Info: Loading facts in Fillydelphia.)

1:52 rritoch: Finally, the subtraction is working properly for custom (unsigned) types, and only had a minor computer crash.

1:53 rhg135: MCA are fascinating

2:02 dwysocki: ok, here it is

2:02 my greatest work ever

2:02 https://github.com/dwysocki/mini-java

2:03 others before me have done the same thing

2:03 but I'm still impressed I pulled it off

2:04 rritoch: dwysocki: Heh, Oswego... Trying to get a job at IBM?

2:05 dwysocki: right now I'm applying for grad schools in computational astrophysics / astroinformatics

2:05 rritoch: dwysocki: Well your not far from the home of IBM

2:06 rhg135: Did it hurt?

2:06 dwysocki: rritoch: where exactly is that?

2:06 rhg135: it was less painful than I'd expected

2:06 rritoch: dwysocki: It's in endicott.

2:07 rhg135: I applaud you

2:08 dwysocki: rritoch: that's about as far as any other part of new york :P

2:08 rhg135: thank you :)

2:08 rritoch: dwysocki: My mothers, cousin's father (not sure what that makes him to me) was one of the original IBM execs, thats how I'm so familiar with IBM and their way of thinking

2:08 dwysocki: do they have any clojure devs?

2:08 rritoch: dwysocki: Hmm, really? I thought Oswego was only about an hour from elmira

2:08 Err, endicott

2:09 rhg135: dwysocki: I haven't even finished my lambda calculus compiler

2:09 rritoch: Maybe it's elmira I was thinking of

2:09 dwysocki: eh, only 2 hours actually

2:09 not as far as I thought

2:10 rritoch: dwysocki: Oh, nm, I really was thinking of elmira. Your near syracuse, but it still looks like your only about an hour and a half away

2:10 dwysocki: rhg135: now I have a strong desire to write a simple lisp compiler in C

2:10 rritoch: yeah, syracuse is the closest city

2:11 rhg135: Goodness

2:11 Goodness

2:11 Oops

2:11 rritoch: dwysocki: Actually, your not far from a major internet hub, I don't remember the name of it

2:11 dwysocki: rochester?

2:11 wait

2:11 you mean a city or a building?

2:12 rritoch: dwysocki: I honestly don't remember, I just remember I was invited to the grand opening and just ignored the invitee because a 3 hour trip to visit a bunch of racks didn't exactly excite me.

2:12 dwysocki: lol

2:16 rritoch: Anyhow, I guess my clojure source hacking is coming to it's end. https://github.com/rritoch/clojure now supports dynamic namespaces and custom numeric types. There really aren't any other features I need right now.

2:20 TEttinger: nice rritoch

2:21 dwysocki: alright, it's past 2am

2:22 time to get some much needed sleep

2:22 'night all

2:24 rhg135: dynamic namespaces?

2:25 rritoch: rhg135: Yes, one moment, I'll get you a link with detalis

2:25 err, details

2:29 Sorry had to post to clojure-dev first, I wish I could edit posts there though, the typo in my latest post is painful to look at

2:29 rhg135: https://groups.google.com/forum/#!topic/clojure/O7xTmtsmKAE

2:30 rhg135: Thx

2:30 rritoch: The thread contains some implementation notes

2:30 Is it possible to moderate/delete your own post on google groups?

2:31 This typo is painful

2:31 > For review: Custon numeric types :(

2:38 rhg135: That's great

2:39 rritoch: rhg135: Well, I need it to facilitate unsigned support in clojure

2:40 rhhg135: Unfortunatly, from what I hear, there is a lot of drama surrounding support for numeric types so chances are this fork is going to be a hard-fork.

2:40 err, rhg135:

2:41 rhg135: I

2:41 I've heard it's lengthy to get merged

2:42 rritoch: The support for the namespace isolation, even in this room, is limited, so if you like the features, try them out, and add your support for them in the forums so Rich Hickey will consider adding them to clojure.

2:44 I only posted the custom numeric types to clojure-dev though, and it takes about a day (with a signed contributor agreement) to get approval.

2:44 https://groups.google.com/forum/#!topic/clojure-dev/QF8P7_DK0rc

2:44 rhg135: I'm not on any yet, also I'll try it tomorrow

2:44 rritoch: Sorry about the typo, it's so painful *sniff* *sniff*

2:44 rhg135: Will later today :-)

2:47 The only problem I see is (blob) + (blob)

2:47 People be crazy

2:47 rritoch: Anyhow, I appologized for the typo, it isn't the first time I've added verbal garbage to something that will be permanently recorded in internet history, but at least this way it may show up in searches correctly.

2:48 gwenloh: Hello

2:48 rhg135: Hi

2:49 rritoch: rhg135: Hmm, actually that is possible, you just need to extend the Blob type and implement the INumber interface, though it only works from this fork unless this gets added to the official version of clojure.

2:50 rhg135: Actually, now that I think about it, you need to wrap the blob type, since Blob's aren't numeric.

2:50 rhg135: I know, rritoch. I meant how people do crazy things with operator overloading

2:51 Except clojure has none :x

2:51 rritoch: rhg135: Yeah, well adding blobs would be an awesome feature since blobs require a lot of trivial code to work with.

2:52 rhg135: I meant it as a placeholder...

2:52 rritoch: rhg135: oh, lol

2:52 rhg135: I'm clocking off now

2:53 Its too late for logic

2:53 rritoch: rhg135: I was thinking of https://docs.oracle.com/javase/7/docs/api/java/sql/Blob.html , even though it's an interface, the implementation will already provide it's own types for blobs which won't likely extend java.lang.Number.

2:54 rhg135: Ah

2:54 rritoch: rhg135: The way I coded the feature, it must still be a Number AND an INumber.

2:54 rhg135: Good

2:55 rritoch: rhg135: So it doesn't support unlimited crazyness.

2:55 rhg135: I once saw composition as + * and >>

2:56 Just pick one

2:56 Or better a comp function

2:58 rritoch: Hmm, well technically I would think the cons function would be a good function to do comp's

3:00 Since cons generally is used for applying one function to another, within macro's

3:01 rhg135: I think macros are the exception nobody mentions but all use

3:08 rritoch: Well, comp can can be written as ##(cons 'f (list (cons 'g (list 'x))))

3:08 lazybot: ⇒ (f (g x))

3:09 rritoch: Which was fairly common way of building structures in early LISP's

3:10 For anything fairly complex, I still use cons a lot in macros

3:10 Mostly because I haven't yet fully adopted the new clojure ways

3:10 rhg135: Hmm

3:15 amalloy: rritoch: really? even in CL i imagine you'd use ` and , to build most lists in macros

3:18 rritoch: amalloy: Well, all let bound variables are available when you build structures using cons, and since cons is a core function (as is list) your as close to the "metal" as you can get.

3:19 I should say "where" core functions, I don't recall any let*, but that doesn't mean it didn't exist. I couldn't make much sense of LISP source code back then.

3:19 amalloy: both of those statements sound like meaningless fluff to me. let-bound variables are all available in ` via the use of ~ or , (depending on flavor), and being close to the metal doesn't mean anything: you're just building lists one way or another

3:19 rritoch: err, were core functionss

3:20 Well, most code I saw back then used cons as aposed to `

3:21 I honestly don't recall ` existing, but this was a long time aago

3:23 If you find any LISP code from about 20 years ago, you'll see cons was one of the most commonly used functions.

3:24 This was in my college days, long before I knew anything about compiler design.

3:24 Anyhow, I have to run to the store. I'll probably bbl.

3:25 Raynes: Sure am gonna miss that kid

3:25 * Raynes wipes a tear off his cheek and tips his cowboy hat to cast a shadow on his face

3:51 kenrestivo: well the idea of doing an embedded project in clojure has been seducing me for years now, finally got to do one, and never again.

3:53 but i guess at least it was worth doing.

3:53 * kenrestivo waits 10 more minutes for lein trampoline repl to restart.

4:12 shem: kenrestivo: why never again?

4:13 kenrestivo: it's just not fun on a resource-constrained system.

4:15 10 minute, 15 minute repl restarts are the major pain point.

4:16 might try the "fastload" branch but it appears it was just dead-end experiments in may/june, doesn't seem to be any path towards it becoming released.

4:16 shem: ouch. i suppose new android phones are not quite that bad? i've been thinking of playing with neko when i get a new phone

4:17 kenrestivo: the android stuff might be further along. i'm not on android.

4:31 kr-: Hi, does anyone have any idea why the following tiny programs display function will print some output but not another to the repl? -> https://gist.github.com/KristoKoert/e09652bdda8acab8b214

4:35 jonathanj: is there convenient syntax for getting values for multiple keys from a map?

4:38 i guess something like (vals (select-keys ...)) is convenient enough

4:40 kr-: You could (for [key [:a :b :c]] (key my-map)) maybe?

4:46 jonathanj: since i need to pull certain values out maps in a seq i settled on (map #(map % [:a :b]) m)

4:48 schrotti: hm rich talks, in his talk simplicity matters about those hairballs

4:49 when I use leiningen i also have them hairballs :/

4:49 rhg135: jonathanj: try juxt :-D

4:49 It's so useful

4:49 Glenjamin: juxt?

4:49 clojurebot: juxt is usually the right answer

4:50 Glenjamin: does clojurebot have a botsnack?

4:50 rhg135: I don't think so

4:51 clgv: clojurebot: botsnack

4:51 clojurebot: Thanks! Can I have chocolate next time

4:51 rhg135: Hmm

4:51 I was wrong

4:51 Glenjamin: clojurebot: chocolate

4:51 clojurebot: actually I decided I prefer botsnacks after all.

4:51 Glenjamin: hahah

4:51 well played

4:52 clgv: :P

4:52 jonathanj: rhg135: niiice

4:53 clgv: we should give him an Eliza plugin ;)

4:53 jonathanj: i wish Clojure had some uuid stuff

4:53 java.util.UUID is kind of useless

4:54 rhg135: You could use machine learning and analyze this chat

4:54 clgv: schrotti: why? declarative dependency specification is great. lately I had to work through a scons build file which is actually python code that I either need to interpret myself or watch the output to see what it is doing. that's just horrible

4:54 jonathanj: and clj-uuid gives me a giant pile of warnings about how various things already refer to other various things

4:55 clgv: jonathanj: depending on which warnings you see you should probably :refer instead of :use it

4:55 ooops :require was what I meant

4:55 jonathanj: clgv: i think clj-uuid is using :use

4:55 WARNING: == already refers to: #'clojure.core/== in namespace: clj-uuid.bitmop, being replaced by: #'primitive-math/==

4:55 rhg135: Wow it's 4am already

4:56 jonathanj: i dislike :use for the same reason i don't do from X import * in Python

4:56 rhg135: Bye everyone

4:56 clgv: jonathanj: ah, so the warnings are within its implementation.

4:56 jonathanj: what it the problem with java.util.UUID?

4:58 kr-: Does anyone have any idea why the following tiny programs display

4:58 function will print some output but not another to the repl? I'm kinda stuck :/ .. ->

4:58 https://gist.github.com/KristoKoert/e09652bdda8acab8b214

4:58 jonathanj: clgv: all i really wanted was a v4 UUID and the hex representation of it, turning a java.util.UUID into that appears to involve a giant pile of code

4:58 clgv: kr-: because `for` is lazy

4:58 kr-: you want to use `doseq` instead

4:59 jonathanj: in Python it's uuid.uuid4().hex, with clj-uuid it's (to-hex-string (v4))

5:00 kr-: Many thanks clgv :)

5:01 clgv: jonathanj: you mean like that? ##(let [uuid (java.util.UUID/randomUUID)] (format "%X%X" (.getMostSignificantBits uuid) (.getLeastSignificantBits uuid)))

5:01 lazybot: ⇒ "2F45C495EE064E04ADF49F69AB4725F9"

5:05 jonathanj: clgv: yeah, i guess that is what i want

5:08 clgv: thank you

5:08 clgv: :)

5:09 jonathanj: clgv: is it possible to do that without the intermediate value?

5:10 the intermediate variable, i mean

5:10 clgv: jonathanj: the actual UUID?

5:10 jonathanj: without the let

5:10 clgv: why would you want that?

5:11 there is no performance penalty or similar on a let

5:11 jonathanj: i thought it might read better

5:11 clgv: just wrap that code in a function that fits your use case: (defn random-uuid [] ...) or (defn uuid->hex [uuid] ...)

5:15 someplace: for extracting a number based off a regex.. I have this mess of a line, can it be cleaned up?

5:15 (-> (re-seq #"\(\d+,\d+,(\d+)\)" (first split-level)) last last str->int)

5:15 cursork: jonathanj: What's wrong with ##(str (java.util.UUID/randomUUID))

5:15 lazybot: ⇒ "7a64bae2-c79b-4b89-8f74-08eb9220474e"

5:16 jonathanj: cursork: just cosmetics, i don't like the dashes in a URI

5:16 clgv: jonathanj: ah right, you should take care of leading zeros in the code above

5:19 jonathanj: ##(let [uuid (java.util.UUID/randomUUID)] (format "%016X%016X" (.getMostSignificantBits uuid) (.getLeastSignificantBits uuid)))

5:19 lazybot: ⇒ "617A39D4CBA24A718B37FAD8DFC71E7D"

5:20 clgv: jonathanj: ##(let [uuid (java.util.UUID. 47, 11)] (format "%016X%016X" (.getMostSignificantBits uuid) (.getLeastSignificantBits uuid)))

5:20 lazybot: ⇒ "000000000000002F000000000000000B"

5:26 SirRobin: Hi all

5:27 I'm using vim-clojure-static

5:28 and it sets iskeyword to match symbols in clojure

5:28 if I comment that, it breaks identation & coloration

5:29 is there a way to set iskeyword to something different for me, and let the plugin have its own?

5:30 (I'm just used to the default iskeyword and would like to use that when editing)

5:43 schrotti: clgv: because some deps require other deps, that will be downloaded with it

5:43 so you end up with all that extra stuff you don't even know

6:07 clgv: schrotti: so what? you dependencies need those and you don't need to care. it would be really bad if you had to download the deps of your deps yourself

6:09 schrotti: if you can decide between different libs you can use the number of transitive deps as criterium for the selection if you like

6:17 schrotti: clgv: i see your point with manually downloading it

6:52 dysfun: i'm getting this error: CompilerException java.lang.IllegalArgumentException: Parameter declaration should be a vector, compiling:(tk0/util/response.clj:46:43) but it's just standard multiple arity function syntax and it works fine if i paste it in a repl

6:52 it's at the top level in a namespace, everything is nested correctly etc., what am i missing?

6:52 clgv: dysfun: did you forget the parens?

6:53 dysfun: https://www.refheap.com/aff239e032c034fbc42298b82

6:53 clgv: dysfun: you need to provide a gist.

6:53 dysfun: i did not

6:53 heh, ahead of you :)

6:53 clgv: are you sure that this is the offending function?

6:54 dysfun: that's the line it's pointing at

6:54 the last line of that snippet

6:54 clgv: `assoc-in-smartly` is a function?

6:54 dysfun: it's definitely not a cacheing thing, i've inserted whitespace to change the line number

6:54 yes, it is

6:54 not a macro or anything

6:55 as i say, works fine at the repl

6:55 https://www.refheap.com/32d031d7cfd3b8ce283073369

6:55 clgv: did you restart the repl, already? (with lein clean in advance)

6:56 dysfun: of course :)

6:56 clgv: can you provide a minimal snippet that can be compiled and has the same error? otherwise there is no more help to offer

6:57 dysfun: let's see what i can do

6:57 clgv: I'd bet you find the error when trying to minimize the scenario ;)

6:57 dysfun: turns out that file has no external deps

6:58 so i can actually show it all to you, what with it being open source

6:58 https://www.refheap.com/8980afc3e6cee6780f8a3d1a1

6:58 but as you can see, there's nothing tricky in there at all

7:04 bonkers, if i make it a single-arity function, it doesn't like it either

7:04 clgv: dysfun: yeah

7:04 but all parens are matched correctly right?

7:04 dysfun: yes, first thing i checked

7:05 clgv: dysfun: if you comment `headers!` the error moves up to `status`

7:08 dysfun: clgv: which i commented out a minute ago :)

7:08 clgv: dysfun: try removing definitions from it until it stops throwing this error and then analyze the last thing removed and its effects on the remaining file

7:09 dysfun: *nod*

7:11 clgv: dysfun: if I comment out all after `headers!` it loads fine

7:11 so those line numbers seem to be wrong

7:11 dysfun: yes

7:11 it's session!

7:11 but how?

7:12 clgv: double string ;)

7:12 "Returns" ""

7:13 dysfun: ohhhh

7:13 right, thus leaving it all open

7:13 gotcha

7:13 thanks

7:13 thought i was going mad

7:13 clgv: no just an empty string in position of the expected vector

7:14 dysfun: or that too

7:14 * dysfun needs more coffee

7:19 dysfun: it's a real pity there isn't a friendly channel like this one where you can discuss c++. it *badly* needs it, horrible language

7:34 kungi: I just saw a video where emacs sorted the required libraries at the top of a clj file automatically. What .el is this?

7:35 dysfun: you might like to know there's #clojure-emacs for emacs-specific questions

7:36 CookedGryphon: kungi: slamhound

7:36 kungi: dysfun: CookedGryphon thank you

7:36 CookedGryphon: does a load of stuff like that, automatic imports, removing unused, organising what's there

7:38 clgv: dysfun: lately I have used clojure.de to articulate my feelings about c++ and certain libraries ;)

7:38 dysfun: clgv: one word: locales. Better known as hell.

7:38 clgv: dysfun: luckily none of my business ;)

7:39 dysfun: :)

7:39 wish it weren't mine

7:39 clgv: dysfun: did you also hate the vast amount of semicolons in c++ after coming back from clojure?

7:40 dysfun: not the semicolons per se, more the excessive syntax

7:40 clgv: the strange placement of parens in c++ is almost no problem but all those semicolons ;)

7:40 dysfun: I had the impression I was programming while crawling on my hands and feet ;)

7:41 dysfun: heh

7:41 you know what, the error case of some code should never be a segfault

7:41 period.

7:41 clgv: how I miss those stacktraces.

7:41 dysfun: have you seen how terrible LLDB is?

7:41 clgv: well, c++ is scheduled for later today. now it's clojure time ;)

7:42 nope. what is LLDB?

7:42 dysfun: the llvm debugger

7:42 clgv: ah ok. never used llvm

7:42 dysfun: i mean obviously it's far more important to list the assembly you spat out rather than tying it back to any c++...

8:17 jonathanj: is there anything i can do to improve the startup times of clojure applications? (like lein)

8:25 clgv: jonathanj: do you restart it that often during development?

8:31 jonathanj: i do

8:32 but perhaps there is some way to avoid restarting my ring server just to run new code?

8:33 weavejester: jonathanj: There are a few ways. You can just :reload, or use refresh from tools.namespace, or use a tool like Lein-Ring to refresh on file change.

8:34 jonathanj: as a more general curiosity, is likely that clojure applications will ever start up quickly? what's holding them back?

8:34 rritoch: When should I submit my clojure features to JIRA?

8:34 jonathanj: weavejester: when you say :reload, what do you mean?

8:34 Glenjamin: (doc require)

8:34 clojurebot: "([& args]); Loads libs, skipping any that are already loaded. Each argument is either a libspec that identifies a lib, a prefix list that identifies multiple libs whose names share a common prefix, or a flag that modifies how all the identified libs are loaded. Use :require in the ns macro in preference to calling this directly. Libs A 'lib' is a named set of resources in classpath whose contents define a library of

8:34 weavejester: jonathanj: You can reload a namespace in the REPL with (require namespace :reload)

8:34 Glenjamin: eugh, why is :reload not in the docstring :s

8:34 jonathanj: hrm, i'm running my ring server with `lein ring server-headless`

8:35 weavejester: jonathanj: But often you want to reload dependant namespaces as well

8:35 clgv: jonathanj: eager initialization of the whole clojure runtime causes the startup overhead

8:35 weavejester: jonathanj: That should automatically reload files when they're changed.

8:35 jonathanj: What isn't reloading?

8:36 jonathanj: weavejester: i'm reasonably sure that nothing was automatically reloaded, do i need to configure anything to make it work?

8:36 (i will check again in a moment when i'm back at my development machine)

8:37 weavejester: jonathanj: No, that should be the default.

8:39 clgv: jonathanj: my repls usually run for at least 1-2 hours

8:39 weavejester: jonathanj: If it's not working, it would be useful to know the version you're using of Lein-Ring, and whether you're doing anything unusual in terms of source directories, ns declarations, or loaded data.

8:39 clgv: jonathanj: only when deftypes/defrecords are modified, than restarts might be needed more often

8:39 *then

8:59 jonathanj: weavejester: is there any output when it reloads?

8:59 weavejester: jonathanj: Nope

8:59 jonathanj: Not unless you have a namespace that prints something when it loads

8:59 jonathanj: oh, maybe i overzealously reloaded my browser once and figured no output in the shell meant nothing happened

9:00 because i see now that it is reloading

9:00 sorry for being a dummy

9:01 (and thanks for writing wonderful software)

9:02 weavejester: jonathanj: No problem :)

10:05 simao: Is it possible to pass a map that is 'auto' destructured to a function that expects a map to destructure? for Example, I want to call f as (f mymap) where (defn f [{keys [a]}]) and mymap is {:a 1} instead of explicitly using (f :a 1)

10:06 justin_smith: ,((fn f [{:keys [a]}] (inc a)) {:a 1})

10:06 clojurebot: 2

10:07 simao: hm

10:07 I am doing something wrong then complains " No value supplied for key"

10:08 when {:a 1} is in a variable

10:08 justin_smith: that sounds like [& {:keys [a]}]

10:08 which is different

10:09 simao: yes that's what I am using

10:09 how is it different?

10:09 justin_smith: right, that's not what you want

10:09 simao: I also have a few params before the hash.. that's why I am using &

10:10 justin_smith: ,((fn f [& {:keys [a]}] (inc a)) :a 1)

10:10 clojurebot: 2

10:10 justin_smith: ,((fn f [a {:keys [b]}] (+ 1 a b)) 1 {:b 2})

10:10 clojurebot: 4

10:10 justin_smith: that's what you want

10:11 & + keys means you want keys as args, not in a map

10:11 lazybot: ⇒ #<core$_PLUS_ clojure.core$_PLUS_@bf35bad>

10:11 justin_smith: haah

10:11 but you see the difference, right?

10:11 simao: ah I thought & meant "optional arguments follow"

10:11 justin_smith: it does, but it interacts very oddly with {}

10:12 simao: ok now it works

10:12 justin_smith: ,((fn f [a & [{:keys [b] :or [b 42]}]] (+ a b)) 1)

10:12 clojurebot: #<NullPointerException java.lang.NullPointerException>

10:12 justin_smith: err

10:12 I got that :or wrong

10:13 dm3: ,(create-ns 'test-1)

10:13 clojurebot: #<Namespace test-1>

10:13 simao: but this means I will always have to use the {} braces

10:13 justin_smith: ,((fn f [a & [{:keys [b] :or {b 42}}]] (+ a b)) 1)

10:13 clojurebot: 43

10:13 simao: right?

10:13 I see

10:13 justin_smith: see above for optional

10:13 dm3: ,(binding [*ns* (find-ns 'test-1)] (def x 1))

10:13 clojurebot: #'sandbox/x

10:14 justin_smith: simao: the trick is making the map a single optional arg, and not all the optional args (via the surrounding vector)

10:14 dm3: can anyone explain why the above doesn't work? docs for def suggest it should intern the var in the current (*ns*) namespace

10:16 simao: justin_smith: but then I always have to pass a map, using {}, right?

10:16 justin_smith: simao: see my last example, no map was passed, and it used the default

10:16 ,((fn f [a & [{:keys [b] :or {b 42}}]] (+ a b)) 1)

10:16 clojurebot: 43

10:17 justin_smith: ,((fn f [a & [{:keys [b] :or {b 42}}]] (+ a b)) 1 {:b 12})

10:17 clojurebot: 13

10:17 simao: ,((fn f [a & [{:keys [b] :or {b 42}}]] (+ a b)) 1 {:b 20})

10:17 clojurebot: 21

10:17 simao: ,((fn f [a & [{:keys [b] :or {b 42}}]] (+ a b)) 1 :b 20)

10:17 clojurebot: 43

10:17 simao: hm

10:18 justin_smith: dm3: ##(meta #'ns)

10:18 lazybot: ⇒ {:macro true, :ns #<Namespace clojure.core>, :name ns, :added "1.0", :file "clojure/core.clj", :column 1, :line 5422, :arglists ([name docstring? attr-map? references*]), :doc "Sets *ns* to the namespace named by name (unevaluated), creating it\n if needed. referen... https://www.refheap.com/94615

10:18 justin_smith: it's not dynamic

10:18 binding isn't the trick

10:18 dm3: ##(meta #'*ns*)

10:18 lazybot: ⇒ {:added "1.0", :ns #<Namespace clojure.core>, :name *ns*, :tag clojure.lang.Namespace, :doc "A clojure.lang.Namespace object representing the current namespace."}

10:18 justin_smith: dm3: ##(:dynamic (meta #'*ns*))

10:18 lazybot: ⇒ nil

10:18 dm3: oh, yeah

10:18 justin_smith: sorry, forgot the earmuffs :)

10:19 dm3: thanks, the earmuffs confused me

10:19 simao: hm I was mssing [] arround {:keys ...}

10:19 argh this is confusing

10:19 justin_smith: simao: destructuring is a bit odd at first

10:19 simao: & [x] means "any number of args, the first one is called x"

10:20 & x means "any number of args, the collection of all args is called x"

10:20 lazybot: java.lang.RuntimeException: Unable to resolve symbol: x in this context

10:20 justin_smith: thanks, lazybot

10:20 simao: if you want to put it in one optional arg, then you are specifying one of the optional args, not the collection of all optional args

10:20 thus the need to do [{}]

10:21 to specify that {} is just one arg

10:22 &((fn [& [a b]] b) [1 2 3 4])

10:22 lazybot: ⇒ nil

10:22 justin_smith: err

10:22 &((fn [& [a b]] b) 1 2 3 4)

10:22 lazybot: ⇒ 2

10:23 simao: justin_smith: ah ok, that makes more sense now...

10:23 justin_smith: &((fn [& [[a b]]] b) [1 2 3 4])

10:23 lazybot: ⇒ 2

10:23 justin_smith: extra brackets say "I am destructuring this one arg, not the whole arglist"

10:25 destructuring in the arglist should be reserved for when you want to indicate to those calling your function the "shape" the data in the args should have

10:25 it's almost like a type signature

10:26 simao: I see. It's quite confusing to learn this

10:26 SagiCZ1: so if i specify [a b] after & and call the function with 1 2 3 4 everything but 1, 2 gets thrown away?

10:26 justin_smith: SagiCZ1: you can use :as

10:27 simao: justin_smith: thanks for your help

10:27 justin_smith: ,((fn [& [a b :as all]] [b all]) 1 2 3 4)

10:27 clojurebot: [2 (1 2 3 4)]

10:27 justin_smith: ,((fn [& [a b :as all :or {b 42}]] [b all]) 1)

10:27 clojurebot: [nil (1)]

10:27 dm3: justin_smith: interestingly, https://github.com/clojure/clojure/blob/clojure-1.6.0/src/jvm/clojure/lang/RT.java#L219 here the *ns* var is dynamic

10:28 justin_smith: maybe the metadata is lying?

10:28 Bronsa: yeah

10:28 justin_smith: dm3: ok I had more coffee

10:28 Bronsa: ,(isDynamic #'*ns*)

10:28 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: isDynamic in this context, compiling:(NO_SOURCE_PATH:0:0)>

10:28 Bronsa: ,(.isDynamic #'*ns*)

10:28 clojurebot: true

10:28 justin_smith: the issue is the code is compiled outside your binding block

10:28 Bronsa: ,(-> #'*ns* meta :dynamic)

10:29 clojurebot: nil

10:29 dm3: metadata is lying

10:29 yep, still need to set! in order to allow def'ing

10:29 as in `in-ns`

10:30 Bronsa: http://dev.clojure.org/jira/browse/CLJ-859 http://dev.clojure.org/jira/browse/CLJ-1057

10:30 justin_smith: ,(binding [*ns* (find-ns 'user)] (eval '(def a 1))) ;; will work in local repl

10:30 clojurebot: #'user/a

10:30 justin_smith: oh, and it works here too!

10:30 dm3: yep

10:30 thanks

10:30 I'll go with set!

10:31 justin_smith: yeah, better to avoid eval anyway

10:31 EvanR: ,(swap! (atom 0) inc)

10:31 clojurebot: 1

10:34 dm3: what's the custom here?

10:34 inc justin_smith

10:34 no

10:34 ,(inc justin_smith)

10:34 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: justin_smith in this context, compiling:(NO_SOURCE_PATH:0:0)>

10:34 dm3: oh well

10:35 EvanR: (dec dec)

10:35 lazybot: ⇒ -1

10:35 dm3: (inc justin_smith)

10:35 lazybot: ⇒ 155

10:35 justin_smith: dm3: it only looks like clojure code

10:35 it doesn't even respect the semantics (inc shouldn't mutate)

10:35 thanks :)

10:38 teslanick: Bug report: replace (inc ...) with (swap! user-name inc)

10:38 justin_smith: haha, that would be a good idea

10:38 EvanR: (swap! user-name (constantly 9999))

10:44 justin_smith: $mail rritoch replying to back scroll: I find crashes most likely when I am using some variety of Windows, or if my hardware needs replacing.

10:44 lazybot: Message saved.

10:55 justin_smith: shem: regarding some back scroll, I would hardly call android embedded. Android phones are more powerful than the desktop I learned to program on.

10:55 ppppaul: pprint in clojurescript?

11:00 brucehauman: cemerick: you here?

11:00 cemerick: brucehauman: yup

11:01 brucehauman: cemerick: I just filed an issue on cljsbuld https://github.com/emezeske/lein-cljsbuild/issues/345

11:01 cemerick: it’s not about the other thread

11:01 cemerick: yeah, I saw

11:02 brucehauman: cemerick: I’m planning on devoting time to look at this today

11:10 cemerick: brucehauman: replied

11:28 shem: justin_smith: yes indeed, didn't mean to imply that. just came to mind. and quite recently people moaned about slow repl starts there. but not in 15 min. category, more like one minute or so.

11:28 mkr00: Any idea how to transform "input" to "output", see https://gist.github.com/kremers/4d72fb02a05ad54081be

11:29 mdrogalis: What's a good way to execute a Clojure form before a Leiningen plugin runs? I need to make a call to (Class/forName ...) before running Joplin to get a JDBC driver registered.

11:30 mkr00: I tried to solve it with 'reduce' but holding the reference to the last element was itchy

11:30 llasram: mdrogalis: a "way" to probably do it (maybe not "good way") would be to unquoted-reference ~fully.qualified.ClassName in your project file

11:30 (assuming by "plugin" you are talking about something which runs in the Leiningen VM)

11:30 hiredman: /win 19

11:31 mdrogalis: llasram: Hmm. Could work. Icky indeed, though.

11:31 I wonder if I could pull it off with prep-tasks.

11:31 * Bronsa incs his hiredman-extra-space counter

11:31 llasram: Gotta keep track of those

11:33 clgv: lazybot can do that ;)

11:34 (inc hiredman-extra-space)

11:34 lazybot: ⇒ 1

11:38 hiredman: I donate all my extra space to the strategic space reserve

11:39 justin_smith: mkr00: how general does that need to be? how would the inputs vary?

11:40 do we generally want to "step in" to an :ol with an increase of hN and "step out" with a decrease? or is this a very specific sequence to work on?

11:41 mkr00: justin_smith: :ol :li output with hiccup

11:42 justin_smith: OK, I assumed hiccup, but I don't see any :li being made here, and I was asking about how general the transformation has to be

11:42 mkr00: justin_smith: the element output will be [:li [:a {:href (str "#" name)} title]] for each link nested in :ol

11:43 justin_smith: original input was {tag :tag [{{name :name} :attrs} title] :content} headings

11:43 I tried to simplify it for the example

11:43 justin_smith: OK

11:44 mkr00: I've tried a loop/recur solution but I can't get the structure right.

11:44 justin_smith: it's definitely doable with a reduce

11:46 mkr00: I tried it with reduce with a structure of [last_element result] as first parameter. Changing last_element to build the hierarchy.

11:47 justin_smith: mkr00: I am going to use the index of :hN in the h list to decide how deep to do the update-in conj

11:48 mkr00: justin_smith: and how to build up the vector then?

11:48 justin_smith: conj

11:51 mkr00: justin_smith: does update-in work with vectors?

11:51 justin_smith: yes

11:51 ,(update-in [[[]]] [0 0 0] conj :a)

11:51 clojurebot: [[[(:a)]]]

11:56 clgv: ,(update-in [[[]]] [0 0] conj :a)

11:56 clojurebot: [[[:a]]]

11:56 mkr00: ,(update-in [:ol [:ol [:ol [:ol [:ol [:ol ]]]]]] [0 0 0 0 0 0] conj [:li])

11:56 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to clojure.lang.Associative>

11:57 justin_smith: mkr00: one step too deep

11:57 take out one of those 0

11:57 clgv: off-by-one ;)

11:57 all of them those 0 ;)

11:58 ,(update-in [:ol [:ol [:ol [:ol [:ol [:ol ]]]]]] [1 1 1 1 1] conj [:li])

11:58 clojurebot: [:ol [:ol [:ol [:ol [:ol [:ol [:li]]]]]]]

11:59 mkr00: ahH!

11:59 justin_smith: mkr00: yeah, I think that gets you very close to your reduce based answer

12:00 you just have to make the indexes match up with the vectors you are creating

12:00 mkr00: ,(update-in [:ol [:li] [:ol [:ol [:ol [:ol [:ol ]]]]]] [1 1 1 1 1] conj [:li])

12:00 clojurebot: [:ol [:li {1 {1 {1 ([:li])}}}] [:ol [:ol [:ol [:ol [:ol]]]]]]

12:02 mkr00: hmmm. I don't get it.

12:03 justin_smith: mkr00: it's no longer index 1 that holds the next vector

12:03 mkr00: How do the indexes change if an item is added to the vector?

12:03 justin_smith: in fact, the pattern is that you are putting the next vector at the last index

12:03 because you keep putting the vector at the end

12:04 you could have put the vector first, and then it would always be at 0

12:04 clgv: that pattern does not seem to be an elegant solution to any problem. you probably want some recursive solution.

12:05 justin_smith: clgv: if you look at the initial data, he wants the depth of nesting to insert each input to be based on a part of that input

12:05 and yes, there would be easier ways to do this if the data were structured differently

12:06 mkr00: clgv: I tried to do it with loop/recur but I didn't manage to get the structure right. conj-ing reversed the nesting. cons destroyed the type vector needed for hiccup

12:08 justin_smith: mkr00: I think it would be easier to build as {:data [] :children []} and then extracting the nested vectors from that when you are done building

12:08 then you don't have the "magic index" problem any more

12:09 not coincidentially, that will look more like the initial hiccup data you had :)

12:10 mkr00: my recursive "try" https://gist.github.com/kremers/d568c164809355d112f9

12:10 compare_index is based on the last gist

12:11 println output is perfect, just can't get the vector constructed properly

12:22 triss: hey all. I'm wanting to do some 2d drawing on html5 canvas

12:22 justin_smith: mkr00: getting your wanted vector from this will be easy https://www.refheap.com/94620

12:22 triss: is monet everyone's favourite for this or are there other libraries i should check out?

12:23 ToxicFrog: triss: I've only used Kinetic, never heard of monet.

12:23 justin_smith: (updated the formatting just now)

12:23 triss: cheers ToxicFrog. I'll take a peek

12:26 justin_smith: mkr00: updated once more, to get rid of the noisey empty children

12:26 https://www.refheap.com/94620

12:27 mkr00: that has the exact shape you want, you just need to get vectors from those maps

12:28 eraserhd: ,(into {} '((1 2)))

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

12:28 eraserhd: ,(into {} '([1 2]))

12:28 clojurebot: {1 2}

12:29 justin_smith: eraserhd: map entries must be vectors

12:29 ,(vector? (first {:a 1}))

12:29 clojurebot: true

12:30 YKY: hello, I'm trying to RT.loadResourceScript to load a clojure source file using absolute path, but it doesn't work, why?

12:30 justin_smith: YKY: the word "Resource" in the name makes me think it needs a classpath relative path

12:31 resources are always relative to classpath

12:31 YKY: has it to do with the fact that my file is not a class?

12:31 justin_smith: no

12:31 a resource is looked up relative to classpath, not to the filesystem

12:31 YKY: so I just need to put the source file in the classpath's directory?

12:31 justin_smith: so if it's in src/foo/bar.clj ask for "/foo/bar.clj"

12:32 you need to add your source directory to the classpath, but lein does that by default

12:32 YKY: I'm using intelliJ

12:32 justin_smith: OK, intelliJ should also be setting up your classpath

12:33 also, if you are using cursive, (which you should), cursive will use lein

12:33 because literally 99% of us are using lein

12:33 (us being "devs in the clojure community")

12:34 TEttinger: there's a whole 1% not using lein somehow???

12:34 lazybot: TEttinger: Oh, absolutely.

12:35 justin_smith: TEttinger: I may have underistemated lein usage, for sure

12:36 kungi: What is the alternative to leiningen?

12:37 kenrestivo: this maybe? http://adzerk.com/blog/2014/11/clojurescript-builds-rebooted/

12:37 justin_smith: kungi: maven, manually constructing your classpath, letting a java IDE construct the classpath, boot

12:37 CookedGryphon: kungi: clojure itself and a few of the very very early projects still use maven

12:38 justin_smith: oh, even ant is an option

12:38 CookedGryphon: I don't see why you'd want an alternative to leiningen though, it's the best build system I've ever used, and I've used many

12:38 justin_smith: but would you want to?

12:38 CookedGryphon: I use it for my plain java projects now

12:38 justin_smith: YKY: ^^ advice to live by

12:38 leiningen is really good

12:38 kungi: Hmm I think I came the wrong way. I started using clojure for production before doing Java

12:38 kenrestivo: i did the same thing

12:38 justin_smith: kungi: me too

12:39 woo clojure-first-club high fives!

12:39 YKY: I use lighttable sometimes

12:39 kungi: justin_smith: ^5

12:39 YKY: but this is a scala + java project that calls clojure

12:39 justin_smith:

12:39 YKY: and the scala part caused me to use IntelliJ

12:39 kungi: I migrated from Perl for web development to clojure

12:40 justin_smith: YKY: you should be able to use cursive

12:40 YKY: sure, but scala tends to like intelliJ, that's what I found out

12:40 CookedGryphon: I'd probably in that situation, where you have a different build already set up that you want to use, just use leiningen to create a jar library, and pull that in

12:40 SagiCZ1: YKY: I strongly suggest to check out Cursive.. it is in its development stage but you can use it for free

12:40 CookedGryphon: presumably scala, you're using sbt under the hood

12:40 kungi: Wow my code is 10 Month old now :-) Just had a look at the initial commit.

12:41 uris77: my issue with cursive is deleting parenthesis. Sometimes it doesn't allow me to delete or add a parenthesis.

12:41 YKY: this dependency stuff is going to kill me...

12:41 uris77: i have to select and use c-x and c-c

12:41 SagiCZ1: uris77: it is because you have the paredit option turned on

12:41 justin_smith: uris77: turn off structural editing, or better yet learn how to love it :)

12:41 SagiCZ1: i suggest leaving it on and learn about paredit

12:41 YKY: I'll just compile the clojure stuff into a jar, which is known to work

12:41 SagiCZ1: uris77: btw the option is on the right side of the bottom bar

12:42 kungi: Off to peeling potatoes. \o/

12:42 uris77: oh, ok. Too many things to learn at once :) I decided to give clojure a go after a year with Light Table because my brain couldn't handle emacs.

12:43 will definetely read up on paredit

12:43 SagiCZ1: uris77: it makes a whole world of a difference.. without paredit you lose the advantages of homogenous-syntax language

12:49 sdegutis: What are two good words that describe a collection of items available to you and a subset of those which you possess? I'm thinking "library" for one of them...

12:50 SagiCZ1: sdegutis: library is a pretty common word for such a thing from a design stand point

12:51 sdegutis: I'm thinking from the end-user's perspective, they walk into a store and buy a book, and they bring it home and put it in their bookshelf. I've heard the bookshelves of rich people called their "private library".

12:51 So library could mean the collection of things you possess. But then I'm left wondering what to call the place you got them from.

12:51 SagiCZ1: sdegutis: i guess it would depend on the context and circumstances

12:52 uris77: hmmm, are you assuming the user will always purchase form a library?

12:52 can purhcase from a book store, convenience store, super market, online, etc...

12:53 sdegutis: Well specifically, I sell digital things from my Clojure web app. I want to call the collection of things you own your "library". Now I'm wondering what to call the page where you can see all the other things you can still buy.

12:53 SagiCZ1: store

12:53 shop

12:54 tool directory

12:54 uris77: pragprog calls it bookshelf: my bookshelf

12:54 and the main bookshelf is "The Pragmatic Bookshelf"

12:55 justin_smith: sdegutis: achievements, locked and unlocked

12:56 SagiCZ1: one does not buy an achievement.. one achieves it.. no?

12:56 justin_smith: show a grayed outline of the book with a ? on it

12:56 sdegutis: justin_smith: +1

12:56 justin_smith: you achieve it by sharing your credit card info :D

12:56 SagiCZ1: :D

13:00 EvanR: ,(let [x 'x] x)

13:00 clojurebot: x

13:01 EvanR: idea, for all symbols im expecting to use, def a variable with itself as the symbol value ;)

13:01 confusing maybe

13:01 justification, cant be arsed to put a '

13:03 Bronsa: EvanR: that's a poor man's keyword

13:03 EvanR: true

13:06 more justifications, symbols standout when syntax highlighted against a bunch of keywords that are already there

13:09 YKY: how can I compile just one clojure file in the project?

13:12 justin_smith: (doc compile)

13:12 clojurebot: "([lib]); Compiles the namespace named by the symbol lib into a set of classfiles. The source for the lib must be in a proper classpath-relative directory. The output files will go into the directory specified by *compile-path*, and that directory too must be in the classpath."

13:12 llasram: YKY: OOC, why do you want to do that?

13:12 justin_smith: YKY: like any other clojure function, it can be invoked via RT

13:12 YKY: I need the jar file to import to IntelliJ

13:13 I can't figure out how to do it in IntelliJ

13:13 justin_smith: YKY: you want "lein jar" or some equivalent

13:13 compiling clojure makes bytecode, not a jar

13:13 YKY: I can make the uberjar

13:13 and it works

13:13 justin_smith: that's all you need

13:13 YKY: but I'm not sure if the entire uberjar is needed

13:13 justin_smith: the compiling part is only needed if you want to use the classes without clojure.lang.*

13:13 you can make a regular jar then?

13:14 YKY: I also have the regular jar

13:14 I'll try if it works

13:14 I suppose I can even shrink it down to the one function I need

13:14 to put in the jar

13:15 I mean, it's one sub-package in my project

13:15 anyway, I will try if the regular jar works or not

13:15 the standalone jar is known to work

13:16 ghanima: hello all was wondering I could ask for assistance in reviewing the following clojure code... This code connects to a JAVA JMX port and queries for MBEANS defined in a YAML file.. I have searched this code as best I can, but can't find any evidence that is support the ability to pass user auth credentials for JMX access. Was wondering if soneone would be able to confirm my analysis. https://github.com/twosigma/riemann-jmx/blob/master/src/riemann_jmx_clj/

13:16 YKY: and the difference is 3.7Mb versus 37K =)

13:21 OK the regular jar doesn't work... the standalone jar is required

13:22 java cannot import clojure functions if I don't add the standalone jar

13:22 is that expected behavior?

13:22 justin_smith: clojure is compiled at runtime

13:22 so you need the libs it uses available at runtime

13:23 sdegutis: I compile half of my clojure at runtime

13:24 YKY: the loadResourceScript is actually not reading anything in the real directory

13:25 it's reading from the jar

13:25 justin_smith: right, because the jar is on the classpath

13:25 YKY: the path is inside the jar

13:25 justin_smith: if something on disk were in the classpath, it would look there too

13:26 bacon198`: was wondering, is there a quick and easy way to start testing code with clojrue? I hate having to start a new project when I just want to test code out in a repl

13:26 YKY: but in my project dir, the jar is nowhere to be found

13:26 I added it in IntelliJ

13:26 justin_smith: ghanima: I think with that code, the authentication details could be hiding in the yaml

13:27 ghanima: run-queries would find the user/pass or whatever and run each of those if present

13:27 YKY: and I don't know what is my classpath in intelliJ

13:27 TEttinger: bacon198`: you can run lein repl from any directory

13:27 justin_smith: ghanima: this is based on a quick glance though, I could be off base

13:27 ghanima: justin_smith: so the project has a reference example to the yaml: https://github.com/twosigma/riemann-jmx/blob/master/riemann-jmx.yaml.example

13:27 but I am not seeing how it would be set in the yaml

13:27 SagiCZ1: YKY: check out that the library is in the intellij external libraries tree

13:27 then use leiningen and its uberjar command

13:27 TEttinger: I have been known to /msg lazybot or clojurebot to eval code

13:28 bacon198`: TEttinger: so I can just start writing to a file? how do I eval it?

13:28 SagiCZ1: dont forget to set the main namespace, main function and set the namespaces to be :aot

13:28 bacon198`: do I just connect to the repl session or something

13:28 i'm using emacs

13:28 TEttinger: oh I meant just running the command lein repl, which could probably be done from a shell within emacs sure

13:28 justin_smith: ghanima: my guess would be to add the authentication data under the reimann key.

13:28 YKY: I don't know any of those

13:29 but it's running OK now

13:29 in my java code there is no namespace

13:29 SagiCZ1: YKY: oh.. i thought it was just clojure

13:29 justin_smith: ghanima: wait, it isn't even checking for or using credentials when doing run-configuration to create the connection

13:29 bacon198`: oh, I see

13:30 justin_smith: ghanima: so that's the part that needs patching - add the credentials to the yaml, and then change run-configuration / get-reimann-connection to use the username and pass

13:31 or maybe have a separate source of credentials outside that yaml file, but those functions would still need changing

13:31 TEttinger: I think cider doesn't really work right with projectless repls

13:31 dnolen_: bacon198`: lein repl + a lein user profile that includes cemerick's pomegranate

13:31 bacon198`: you can then start a lein repl from anywhere an try libs whenever

13:32 justin_smith: TEttinger: bacon198`: but you could use M-x inferior-lisp with lein repl without a project

13:32 no need for cider

13:32 (inc dnolen_)

13:32 lazybot: ⇒ 8

13:32 justin_smith: yeah pomegranate is the easy way to do that

13:32 (inc dnolen)

13:32 lazybot: ⇒ 18

13:33 ghanima: justin_smith: I could be wrong but I think the JMX magic happes at the function... (defn run-queries)

13:33 zB0hs: im trying to write a vector of hashmaps to a post response body using http kit... when i try to include a vector in the body it just gets return as a string of the elements. is there an easy way to fix this?

13:33 (send! channel {:headers { "Content-Type" "application/json" } :body [1 2]}))

13:33 ghanima: justin_smith: the run-configurations connections to another service that is not JMX based

13:33 zB0hs: returns a body of "12"

13:34 using numbers there instead of hashmaps but same idea

13:34 weaveje__: Does anyone happen to know a quick way of finding all values in a data structure that match a predicate?

13:34 TEttinger: (doc some)

13:34 clojurebot: "([pred coll]); Returns the first logical true value of (pred x) for any x in coll, else nil. One common idiom is to use a set as pred, for example this will return :fred if :fred is in the sequence, otherwise nil: (some #{:fred} coll)"

13:34 TEttinger: hm, that's first

13:35 sounds like you want a filter

13:35 weavejester: Oh, I should add that I want to do it recursively!

13:35 Bronsa: weavejester: recursively? walk + an atom

13:35 weavejester: That's kinda an important detail ;)

13:35 Bronsa: An atom? Yuck! :)

13:35 Bronsa: it works, it's easy

13:35 weavejester: I'd rather write a recursive search

13:35 justin_smith: weavejester: tree-seq + filter?

13:36 EvanR: you dont need an atom

13:36 justin_smith: (doc tree-seq)

13:36 clojurebot: "([branch? children root]); Returns a lazy sequence of the nodes in a tree, via a depth-first walk. branch? must be a fn of one arg that returns true if passed a node that can have children (but may not). children must be a fn of one arg that returns a sequence of the children. Will only be called on nodes for which branch? returns true. Root is the root node of the tree."

13:36 weavejester: Ah! tree-seq! I knew there was something like that

13:36 sdegutis: There have been 2 times when I thought I wanted tree-seq. Either it turned out I didn't, or it was sufficiently over-complicated and I just gave up and used something else. I forget which.

13:36 weavejester: Hm, might be tricky around maps...

13:37 justin_smith: branch? would need to return true for a map, and then children would need to return (seq m)

13:37 that should suffice right?

13:38 weavejester: Oh, or not, since a mapkey is a coll?

13:38 justin_smith: right, call seq, get a list of pairs

13:38 or if you only care about the vals, use vals of course

13:38 Bronsa: ,(require 'clojure.walk)

13:39 clojurebot: nil

13:39 Bronsa: ,(let [res (atom [])] (clojure.walk/prewalk #(do (when (number? %) (swap! res conj %)) %) {1 [2 #{3 4}]}) @res)

13:39 clojurebot: [1 2 4 3]

13:39 weavejester: ,(filter symbol? (tree-seq coll? seq {:a [1 2] :b {:c #{'d}}}))

13:39 clojurebot: (d)

13:39 ghanima: I have this defined function but having a hard type interpretting the following

13:39 justin_smith: weavejester: nice

13:39 ghanima: defn run-queries

13:39 [yaml]

13:39 Bronsa: ah, tree-seq

13:39 ghanima: (let [{:keys [jmx queries]} yaml]

13:39 I understand the 1st 2 lines

13:39 weavejester: (inc justin_smith)

13:39 lazybot: ⇒ 156

13:39 Bronsa: nice, I totally forgot about it

13:40 ghanima: Sorry wrong code

13:40 Bronsa: ghanima: use a nopate

13:40 weavejester: Bronsa: Yeah, I prefer to avoid local mutable state when I don't need it :)

13:40 Bronsa: nopaste*

13:40 justin_smith: ghanima: for multiple lines, please use refheap.com or similar

13:41 ghanima: Sorry everyone: https://www.refheap.com/94627

13:41 I understand the 4 lines

13:41 but I don't understand the 5th

13:41 what exactly is the 5th line

13:41 justin_smith: $doc ->>

13:42 $grim clojure.core/->>

13:42 lazybot: http://grimoire.arrdem.com/1.6.0/clojure.core/->>

13:42 Bronsa: weavejester: sure me too. But I'm not going to feel bad about it if no obvious pure solution comes to mind. in this case tree-seq is much nicer though, yeah

13:42 justin_smith: ghanima: see the above link for examples / doc / explanation of ->>

13:43 it's for chaining expressions without deep nests of parens

13:49 ghanima: justin_smith: so on line 5 of that function your saying that jmx/with-connection is being chained to run-queries

13:52 bacon198`: another question... how do I take a zipper, and turn it back into it's original structure?

13:53 I have an xml structure I want to use a zipper on, and then I want to modify and return the change xml document

13:53 justin_smith: ghanima: the whole (jmx/with-connection ...) is then fed to mapcat if I am reading it right

13:54 I would have used a let binding, since it is only feeding the one thing to the next

13:54 that's a little heavyweight for the inside of ->> for my tastes

13:55 sqd: is there a nice way to combine quil with core.async? i’d like to plot data that is frequently written to a channel

13:55 bacon198`: nvm, I found an article on xml/emit

13:55 sqd: i currently have a go-loop that updates an atom with the last read value, but i wonder if it can be done nicely without atoms

13:56 ghanima: justin_smith: so what is jmx_with-connection is that a function or a generic object

13:57 justin_smith: jmx/with-connection is at least a callable, or else clojure would reject it in that context

13:57 ghanima: in your repl, you could try (source jmx/with-connection)

13:58 ghanima: it is a macro, defined here https://github.com/clojure/java.jmx/blob/master/src/main/clojure/clojure/java/jmx.clj#L181

13:58 looks like crednetials would go in :environment if anywhere?

13:59 *credentials

14:02 ghanima: justin_smith: so credentials is an array right

14:02 if so would the yaml file look like this

14:03 environment : - [user, pass]

14:04 justin_smith: ghanima: not sure about that part

14:04 sqd: is there a non-blocking clojure.core.async/<!! that returns something if nothing is available?

14:05 justin_smith: sqd: you could use alts!! with something that would return after a short delay, but there may be a nicer way to do it

14:06 rhg135: anyone know if i can find usage of a namespace in cursive?

14:06 sqd: justin_smith: yeah, i prefer not using a delay there. want to call the function in the ‘update’ loop from quil (drawing library), which should be called every 15ms or so

14:08 wish i could easily use om in clojure (not in the browser) for realtime visualisation :-)

14:10 rhg135: it is a sad day when grep > ide

14:21 justin_smith: rhg135: I am 100% certain cursive can find namespace usages

14:21 I don't know exactly how though myself :)

14:22 SagiCZ1: alt+f7

14:23 mikos: if i have a list of strings, for example

14:23 if i have a list of strings, for example '("foo" "bar") and want to use those strings as parameters in a function call, would i be best off doing (eval (concat '(function-name parameter-1) '("foo" "bar")))?

14:24 SagiCZ1: eval is evil

14:24 mikos: i thought that might be the case, SagiCZ1 =)

14:24 SagiCZ1: dont u want apply?

14:24 (doc apply)

14:24 clojurebot: "([f args] [f x args] [f x y args] [f x y z args] [f a b c d ...]); Applies fn f to the argument list formed by prepending intervening arguments to args."

14:25 bbloom: i think github just added highlighting to diffs

14:26 but i think that also made yet another clojure color scheme change

14:26 mikos: i don't think so, SagiCZ1, the function i'm trying to call has a set number of arguments; in this case 3

14:26 i have the first argument, but the other 2 are in a list

14:27 SagiCZ1: u can still use apply

14:27 ,(apply (fn [a b c] (println a b c)) 6 [7 8])

14:27 clojurebot: 6 7 8\n

14:28 mikos: ah, of course!

14:28 let me try it, thanks =)

14:30 beautiful

14:31 thanks so much, SagiCZ1

14:31 SagiCZ1: apply unwraps any combination of lists and single parameters, just keep in mind that it unwraps just one level, so nested lists become lists

14:31 rhg135: justin_smith, i couldn't find it, it kept taking it as a package

14:32 mikos: good to know, thanks again

14:32 anyone using yesql 0.5.0-rc1 yet?

14:34 justin_smith: rhg135: hopefully someone knows. Cursive has the best clojure integration out there right now, so it *should* have a working find-usages.

14:36 rhg135: did you find C-Shift-A to look up commands by name?

14:37 you may be able to find the find-namespaces-usages function in that

14:48 rhg135: justin_smith, oh it works for symbols and keywords and packages

14:51 oskarkv: I'm using tools.namespace, and sometimes when I refresh and try to run my code, out of the blue, I get an error like "java.lang.IllegalArgumentException: No implementation of method: :start of protocol: #'game.common.core/Lifecycle found for class: game.client.hud.HudSystem" but it does have a start method, and just refreshing again gets rid of the error. Can anyone think of a reason for this?

14:52 amalloy: oskarkv: protocols and records hate being reloaded

14:52 oskarkv: hm ;(

14:53 amalloy so, what should i do? I want to use refresh, right?

14:53 amalloy: heck if i know. i certainly don't want to use refresh

14:53 oskarkv: hehe ok

14:53 amalloy: anyway, the issue is that you have an old object of type HudSysetm lying around, and reloading the namespaces doesn't delete it; but it implements the *old* Lifecycle protocol, not the new/reloaded one

14:54 because when you reloaded HudSystem and LifeCycle, you defined a brand new protocol and record class, unrelated to the ones in existence but with identical names

14:55 oskarkv: Hm, so I try to use the old object later? That's not supposed to happen...

14:55 amalloy: it's also possible that the namespaces are reloaded in the wrong order; i don't know how refresh works

14:55 but you'd see similar behavior even for new objects, if the record namespace were (incorrectly) reloaded before the protocol namespace

14:57 oskarkv: amalloy ok thanks, I will check if I mistakenly save something old.

15:02 nicferrier: I want to run a long running unix process from a clojure program, concurrently filter it's stdout inside the same program and catch it's exit when it finishes.

15:02 what's a good approach?

15:03 is core.async the right thing for that?

15:04 EvanR: theres this library... popen https://github.com/tebeka/popen i just googled

15:04 nicferrier: what did you type into google to get that?

15:04 EvanR: popen

15:04 nicferrier: fair enough.

15:05 EvanR: read its stdout until it closes?

15:05 then join to get the exit status

15:07 nicferrier: processbuilder is the necessary magic I guess.

15:07 amalloy: popen might be fine, but i've never heard of it and raynes/conch is sorta the standard one

15:08 or, well, that's an overstatement. the standard one is clojure.java.shell, but it doesn't have a lot of features, so if you want something fancier many folks use conch

15:08 justin_smith: processbuilder/process are not super hard to use

15:08 it gives you an outputstream, and inputstream, and an exitvalue when the proc is done

15:09 nicferrier: yeah, I was playing around with java.shell ... but it seemed like it was hard to get the process stuff from it

15:09 justin_smith: yeah, I don't think java.shell is meant for long running stuff where you want to act on output as it is available

15:10 nicferrier: I vaguely remember processbuilder from java

15:10 justin_smith: if you look at the API for Process, it is really tidy https://docs.oracle.com/javase/7/docs/api/java/lang/Process.html

15:10 not much complexity there

15:10 nicferrier: popen looks reasonable... conch looks "better" idiomatically.

15:10 stuartsierra: I asked a while ago if there was any way to do nonblocking I/O on a sub-process' STDIN/STDOUT from Java; nobody had any answers.

15:11 justin_smith: stuartsierra: I use Process with a thread doing blocking read. There may be a lighter weight option though?

15:11 amalloy: i don't think there is, stuartsierra

15:11 stuartsierra: Yeah, I was hoping not to have a dedicated thread per-subprocess.

15:12 nicferrier: I did this at work in scala and akka did a good job of making it easy. i don't know if akka was just making threads under the covers though.

15:12 justin_smith: stuartsierra: you could have a single thread that checks multiple sub-processes via checking .available on each of their outputStreams

15:12 nicferrier: I wanted to do the same thing in clojure.

15:12 EvanR: are threads a big deal?

15:12 justin_smith: EvanR: depends how many you need, it adds up

15:13 nicferrier: surely you can get an nio channel from a stream? can't remember any of that stuff.

15:13 ok. I'll fess up.

15:13 justin_smith: nicferrier: well, if you can get an nio channel from a stream, the Process will gladly give you a stream

15:13 nicferrier: I want to write a process supervisor

15:13 so the threads would be pretty useless.

15:13 stuartsierra: EvanR: 10s of threads, no problem; 100s of threads, not that big a deal; 1000s of threads can be a problem

15:13 nicferrier: but there wouldn't be that many I guess.

15:14 10x threads? basically screwed.

15:14 10x1000 I meant.

15:14 EvanR: yurg

15:14 im trying to find notes on the implementation

15:15 java threads?

15:15 rhg135: is it just me or does https://github.com/rhg/flutterbot/commit/4359477ee31bf5c87a5a4f225d9bb302ac85036c seem like a bad thing?

15:15 stuartsierra: Java threads are the same as native OS threads in most implementations.

15:15 EvanR: i mean is that what you get in clojure

15:16 nicferrier: and most OSes do a good job these days. but you're still asking a scheduler to do a job that is about multiplexing IO.

15:17 llasram: rhg135: not just you I'm afraid :-)

15:17 amalloy: haha that is pretty funny rhg135

15:18 did github change their styling again? this commit looks a lot prettier than clojure code looked on github a couple weeks ago

15:21 rhg135: amalloy, i didn't want to invest the effor when i'm planning to excise mongo all together

15:22 to do it properly i mean

15:22 llasram: rhg135: Sounds like the sort of thing to mention in the commit message!

15:22 justin_smith: rhg135: you can do a conditional (if (resolve 'somnium.congomongo/fetch) (this) (that))

15:22 no need for eval

15:23 or whatever thing you want to resolve

15:23 ,(resolve 'clojure.core/+)

15:23 clojurebot: #'clojure.core/+

15:23 justin_smith: ,(resolve 'does.not/exist)

15:23 clojurebot: nil

15:24 llasram: justin_smith: I think the point is that the library will be there, but the configuration may not be

15:24 justin_smith: OK, he can do the same trick with the config

15:24 oskarkv: stuartsierra I had a problem with "no implementation of method" while using tools.namespace, and I think that maybe this is very bad for tools.namespace, right? https://www.refheap.com/4fae4a68dd778d1e4baf7c4d0

15:24 justin_smith: eval is still not needed

15:25 stuartsierra: oskarkv: sorry, busy now, but please file a JIRA if you have a reproducible bug

15:27 justin_smith: nicferrier: maybe this? https://docs.oracle.com/javase/7/docs/api/java/nio/channels/Channels.html#newChannel(java.io.InputStream)

15:27 and then I think you can select on a group of those

15:27 akkad: nicferrier: you converting to clojure? :P

15:28 bacon198`: alright, i've run into a strange problem. i'm trying to find and replace something in an xml document using a zipper, but when I look at a node using zip/node, I end up losing my place in the xml document, as it bumps me up a level or something

15:28 nicferrier: justin_smith: yeah. I can't remember.

15:28 akkad: from what?

15:28 * akkad whispers elisp

15:28 nicferrier: akkad: ah. no.

15:28 rhg135: the idea is to carry on if mongo isn't available, but as i said i'm about to excise mongo

15:28 bacon198`: is this normal, and is there possibly an easier way to replace a value in a list given a certain search criteria?

15:28 oskarkv: stuartsierra Sorry, I was not very clear. What I did was I had an ns declaration without requires at the top of the file, and then a few lines later I had the "real" ns declaration with requires, to get around a problem with a java library. But I guess tools.namespace uses the first ns declaration, right?

15:29 nicferrier: akkad: I'm just working with people who think the jvm is an operating system.

15:29 rhg135: as said coloqually i give not a s***

15:29 justin_smith: rhg135: yeah, in that case I would wrap anything mongo-specific in an if that checks if something from that namespace resolves

15:29 and the apropriate noop if not

15:30 rhg135: justin_smith, i'd rather fire my neurons when adding datomic backed storage

15:30 bacon198`: I suppose I could map over the elements, and evaluate which ones to replace with a different value

15:30 stuartsierra: oskarkv: correct. tools.namespace only looks at the first `ns` declaration

15:30 oskarkv: ok thanks

15:30 amalloy: oskarkv: yeah, that looks like super-bad. why do you need multiple namespace declarations?

15:31 rhg135: justin_smith, also i did this to avoid editing callsites and jsut do a s&r

15:31 oskarkv: amalloy javafx does/executes something special when it is being imported, and that stuff does not work with clojure for some reason.

15:32 llasram: oskarkv: You can use the `import` macro

15:33 rhg135: it seems the bot still lives

15:34 hiredman: you can put multiple ns forms in a single file, but you cannot expect others to handle that with grace

15:37 rhg135: nevermind...

15:50 justin_smith: rhg135: if your plan is to do a proper replacement of mongodb for some other storage, what about starting by abstracting storage and retrieval, then pluggin in the new backend?

15:52 mindbender1: I'm looking for some good use of transducers.

15:53 justin_smith: mindbender1: invent a new source of data, then use transducers to get free impls of map, reduce, filter, etc. on that new datasource

15:53 SagiCZ1: does anybody know how to print clj-time? for example i want to print only the month like this "01_January"

15:54 mindbender1: justin_smith: okay I see. So this is mostly useful when I need to invent some new collection type.

15:55 weavejes_: SagiCZ1: Take a look at the clj-time.format namespace docs

15:55 justin_smith: or when you need optimum performance for composed operations on some data source

15:55 SagiCZ1: weavejes_: cant find the docs, only github readme

15:55 justin_smith: mindbender1: and I explicitly didn't say collection

15:55 it could be anything that gives you data

15:56 mindbender1: even a function?

15:56 weavejester: SagiCZ1: The readme has a section on clj-time.format.

15:56 SagiCZ1: And the API docs are linked from the README

15:56 justin_smith: mindbender1: sure. The point of transducers is not needing to turn things into collections in order to get those transforming operations

15:56 SagiCZ1: weavejester: thanks

15:57 EvanR: i thought transducers were for composing reducing-like functions

15:57 justin_smith: mindbender1: so hypothetically we could transduce over a network socket

15:57 rhg135: justin_smith, i've learned you can't abstract a logic engine

15:57 it's already abstracted enough

15:58 justin_smith: rhg135: transducers are about getting less abstract, and better performance, not about getting more abstract

15:58 sequences are already abstract enough, you are right

15:58 but sometimes you don't want to build a sequence

15:59 if that sounds pointless to you, you can of course avoid transducers, that's fine

15:59 rhg135: my goal is datomic but regardless, trying to abstract swl, nosql and others into one abstraction isn't worthwile

15:59 sql*

16:00 EvanR: (datomic results cant be streamed :()

16:00 mindbender1: justin_smith: sounds interesting to me

16:01 rhg135: justin_smith, i wasn't talking about transducers... which are awesome

16:01 justin_smith: rhg135: ahh, oops, conversation channels crossed, now I get it :)

16:01 stuartsierra: EvanR: just the datalog query results. There are streaming APIs for direct access to the indexes & storage.

16:01 rhg135: nbd

16:02 EvanR: stuartsierra: right.. which is precisely what would be convenient/performant to stream

16:02 rhg135: this is a bit ironic, i think, that the non hackish change is the one that broke it

16:03 mindbender1: justin_smith: are there some example somewhere on the internet that could help facilitate a deeper understanding. Or if you could offer them. I'd be glad.

16:04 justin_smith: mindbender1: I can't think of something specific off the top of my head. But I know the videos from rhickey are excellent

16:04 it might be informative to look at how core.async switched from map< filter< etc. to transducers with map, filter, etc.

16:05 mindbender1: justin_smith: where are the videos hosted?

16:05 justin_smith: youtube

16:05 top two hits for rich hickey video transducers

16:05 for me at least

16:05 mindbender1: okay. I'll search there.

16:06 Are there no downloadable links?

16:06 justin_smith: there are hacks to download youtube vids... dunno about any downloads

16:07 we should have torrents for all the important clojure vids

16:07 ToxicFrog: mindbender1: youtube-dl works fine, IME

16:07 ppppaul: how does one write tests using core.async?

16:07 mindbender1: ToxicFrog: is that a tool?

16:08 EvanR: you dont want to watch ads?

16:08 communist

16:09 ToxicFrog: mindbender1: yes, command line tool.

16:09 justin_smith: ppppaul: my approach was to make things as modular as possible so I could swap in a lambda with a Thread/sleep for any external thing that takes time. Then I make assertions that I get all the results I expect, that they each look sane, etc. I also have an atom with a "being served" count and a "max served" and update those values inside my dummy fn, and make assertions about the parallelism

16:11 ppppaul: maybe the clearer way to say it is: make your work function a thing you pass in, and replace it with something that records metrics and returns a plausible result

16:11 SagiCZ1: does anyone know what happens to files that get opened but never closed after reading? is it a very unsafe thing to do or just a bad practice?

16:12 justin_smith: then you test the work function separately, outside an async context

16:12 SagiCZ1: if they go out of scope, the jvm is allowed to close them

16:12 SagiCZ1: justin_smith: does it happen automatically then?

16:12 tuft: SagiCZ1: when they get finalized i assume some low level resources get released

16:12 justin_smith: eventually... finalization is weird, but eventually yeah the resources get reclaimed

16:13 tuft: SagiCZ1: .. but yeah, it's bad practice to leave this implici

16:13 implicit

16:13 EvanR: use a wrapper that opens and closes a file for you

16:13 justin_smith: this is part of why we avoid global bindings - it's easier to make sure things go out of scope

16:13 EvanR: like with-open

16:14 SagiCZ1: i would love to use with-open

16:14 but i read it with line-seq and i need to keep it lazy

16:14 EvanR: shouldnt that close it when its finished?

16:14 YKY: what's that form that lets you do one function and then another?

16:14 EvanR: (do one-function then-another)

16:14 SagiCZ1: EvanR: unfortunately it doesnt work like that.. the file gets closed immediately and the lazy-seq cant proceed

16:14 justin_smith: EvanR: the problem is that a lazy resource can leave the with-open scope, so the file the lazy seq relies on is closed, and ouch

16:15 SagiCZ1: YKY: do

16:15 YKY: thanks =)

16:15 EvanR: no no, not combining with file and line-seq

16:15 ,Doc line-seq

16:15 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: Doc in this context, compiling:(NO_SOURCE_PATH:0:0)>

16:15 justin_smith: YKY: also, fn, defn, let, when, while, etc. etc. etc. all have an implicit do inside them

16:15 SagiCZ1: (doc line-seq)

16:15 clojurebot: "([rdr]); Returns the lines of text from rdr as a lazy sequence of strings. rdr must implement java.io.BufferedReader."

16:16 SagiCZ1: if you return the lazy-seq from the with-open scope, the file gets closed

16:16 ToBeReplaced: SagiCZ1 do you need a LazySeq or is channel sufficient?

16:16 EvanR: when this sequence approaches its end, doenst it close the file

16:16 er... BufferedReader

16:16 justin_smith: EvanR: the file gets closed before the sequence is even read

16:17 ToBeReplaced: you could consider dumping to a channel and blocking until close inside of the with-open block

16:17 EvanR: justin_smith: are you talking about with-file? im not

16:17 SagiCZ1: ToBeReplaced: : i just need to avoid loading the whole thing in memory as it wont fit.. can i use channel?

16:17 justin_smith: EvanR: so you either need to eagerly realize the line-seq before leaving with-open, or not use with-open

16:17 EvanR: er with-open

16:17 justin_smith: EvanR: OK

16:17 EvanR: so line-seq isnt about files, nevermind

16:17 SagiCZ1: EvanR: it is just as justin_smith says, and line-seq IS about files

16:17 EvanR: its about BufferedReader

16:18 SagiCZ1: ok, that

16:18 EvanR: which doesnt have a close method

16:18 amalloy: bufferedreader doesn't have a close method??

16:18 lazybot: amalloy: Definitely not.

16:18 amalloy: lazybot: c'mon, man. that's demonstrably untrue

16:18 EvanR: actually it does

16:18 justin_smith: $javadoc BufferedReader

16:18 lazybot: Javadoc not found. Try http://docs.oracle.com/javase/6/docs/api/

16:19 SagiCZ1: ,(type (mapcat count ["hello" "bye" "word"]))

16:19 clojurebot: clojure.lang.LazySeq

16:19 justin_smith: $javadoc java.io.BufferedReader

16:19 lazybot: http://docs.oracle.com/javase/6/docs/api/java/io/BufferedReader.html

16:19 EvanR: therefore, line-seq should be able to call it near the end

16:19 rhg135: hmm

16:19 i should fix that

16:19 YKY: what's the difference between list? and seq?

16:19 SagiCZ1: EvanR: but it is long out of the scope of the macro when its near the end

16:19 YKY: I saw a list and it's a seq

16:19 EvanR: what macro?

16:20 SagiCZ1: EvanR: with-open

16:20 amalloy: YKY: list? is awful, never use it

16:20 EvanR: dont use with-open

16:20 amalloy: whereas seq? is awesome, always use it

16:20 SagiCZ1: YKY: http://www.braveclojure.com/core-functions-in-depth/#2__The_Sequence_Abstraction

16:20 YKY: drove me crazy...

16:21 SagiCZ1: EvanR: what else should i use?

16:21 rhg135: ah

16:21 i probaly should have slepti more

16:21 it's java.io hence it wouldn't be resolved

16:21 EvanR: SagiCZ1: it looks like line-seq does not do the close for you, after reading the source

16:21 which would be nice

16:22 llasram: You totally want `with-open`

16:22 SagiCZ1: llasram: ugh

16:22 llasram: Depending on complete processing a a lazy sequence to release resources is asking for tears

16:22 EvanR: that too

16:22 amalloy: EvanR: urgh. line-seq should definitely not close for you

16:22 rhg135: ^

16:22 justin_smith: Once the BufferedReader goes out of scope, the jvm is allowed to close it. Just manage your scope properly.

16:22 rhg135: darn lag

16:23 llasram: SagiCZ1: Alternatively, hiredman has some good ideas about using reducers: http://ce2144dc-f7c9-4f54-8fb6-7321a4c318db.s3.amazonaws.com/reducers.html

16:23 SagiCZ1: justin_smith: i am about to do that

16:23 amalloy: justin_smith: am i misunderstanding you? letting it go out of scope is not a solution

16:23 you need to call .close on it

16:23 SagiCZ1: amalloy: i dont think so

16:23 EvanR: lazy reading is the problem here

16:23 llasram: You can also use an explicit dynamic scope for resource lifetimes: https://github.com/pjstadig/scopes

16:23 EvanR: might as well go all out

16:23 amalloy: the jvm is *allowed* to close it, but by no means does it *promise* to close it

16:23 justin_smith: amalloy: if nothing has access to the underlying data source, the finalization should eventually take care of it, no?

16:24 amalloy: justin_smith: it might just not get GCed for hours

16:24 justin_smith: amalloy: fair enough. But it will get closed before having it open is a problem at least. Outside pathological systems like Windows.

16:24 sure

16:24 amalloy: justin_smith: that's just not true

16:24 SagiCZ1: gosh, reading a file lazily is such a basic concept, i dont understand why its not implemented in clojure correctly

16:24 justin_smith: interesting, what's a good counterexample?

16:24 amalloy: the GC operates in mysterious ways, and it can be days and days between major collections

16:24 SagiCZ1: have you never had a 100 GB file?

16:25 amalloy: if your file handles happen to say alive long enough to make it into oldgen

16:25 you could easily run out of file handles

16:25 http://blogs.msdn.com/b/oldnewthing/archive/2010/08/09/10047586.aspx is an article i think everyone should read

16:25 llasram: SagiCZ1: You can totally read a file lazily

16:25 EvanR: SagiCZ1: theres reading incrementally, and then theres treating the lines as a pure lazy sequence

16:25 which its not

16:25 llasram: SagiCZ1: The issue is that Clojure provides laziness as a data structure, not via lazy evaluation

16:26 SagiCZ1: llasram: what do you propose?

16:26 ToBeReplaced: llasram: i like that statement, and agree

16:27 EvanR: llasram: how would lazy evaluation help here?

16:27 llasram: SagiCZ1: You manually manage the resource scope, by using either `with-open`, reducers, or the pjstadig/scopes library

16:27 ToBeReplaced: SagiCZ1; two choices... a) use with-open, block inside of it... you can do this by doing your processing inside of it or dumping to a channel

16:27 SagiCZ1: couldnt i make my own 'line-seq' which would hold on on the file and close it when the last element evaluates?

16:27 ToBeReplaced: b) don't use with open, handle open/close outside of your processing

16:28 EvanR: SagiCZ1: or when an error occurs

16:28 llasram: EvanR: You know what -- you are totally right. I assumed languages with full lazy evaluation semantics would have a solution, but apparently even in e.g. Haskell the recommendation is to always explicitly manage resource lifetimes

16:29 EvanR: lazy evaluation makes sense for pure code, no IO

16:29 SagiCZ1: line-seq is a two liner so i can try to reimplemented it with my requirement and let you check it out

16:30 hiredman: llasram: haskell has iteratees

16:40 ghadishayban: bbloom: can you say more words about an IOC macro for reduced handling?

16:40 SagiCZ1: i can detect when someone used the whole lazy-seq but if someone does (take 10 lazy-seq) i can never know if i should close it or not

16:40 bbloom: ghadishayban: basically yield

16:41 ghadishayban: www.cs.indiana.edu/~sabry/papers/yield.pdf

16:41 YKY: I got a clojure list returned as java object, how can I iterate through it in java?

16:41 SagiCZ1: YKY: lists implement Enumaration

16:41 amalloy: YKY: do you remember the answers you got to this question yesterday? what is still giving you trouble?

16:41 SagiCZ1: busted!

16:42 bbloom: ghadishayban: although monadic yield, like go's handling of asynchrony, is dynamic in extent. where as python or C#'s yield, like core.async's go, is lexical in extent (push down machine vs finite state machines)

16:42 YKY: the result is a java Object

16:42 not a List

16:42 I don't remember yesterday's answer =)

16:42 SagiCZ1: YKY: yeah you have to cast it

16:42 YKY: oh I see

16:42 amalloy: it's a List; its static type is Object, so you need to cast it to tell java you're sure it'll be a List

16:43 yiati: If you are sure it will be a list*

16:43 SagiCZ1: yiati: we use this assumption all the time with any dynamic language dont we

16:44 justin_smith: yiati: he means List as in the java.util.List interface I think. which list / list* implement

16:44 but more importantly, seq, vector, cons

16:44 yiati: Right

16:47 bja_: has the jvm grown a divmod lately?

16:48 stompyj: Is anyone here using transit with a schema, embedding a schema within transit?

16:49 justin_smith: bja_: doubt it, but at least we can do this ##((juxt quot mod) 7 4)

16:49 lazybot: ⇒ [1 3]

16:50 EvanR: ,(quot -1 3)

16:50 justin_smith: stompyj: in order to send your schema to someone else?

16:50 clojurebot: 0

16:50 EvanR: ,(div -1 3)

16:50 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: div in this context, compiling:(NO_SOURCE_PATH:0:0)>

16:50 amalloy: justin_smith: quot goes with rem, not mod, generally

16:50 justin_smith: OK

16:51 EvanR: ,(rem -1 3)

16:51 clojurebot: -1

16:51 justin_smith: I forget what the point of rem is sometimes

16:51 EvanR: ,(mod -1 3)

16:51 clojurebot: 2

16:51 amalloy: the difference is something to do with negatiev numbers, as i think EvanR is trying to show

16:51 justin_smith: rem is java's % operator

16:51 justin_smith: got it

16:51 EvanR: whats div?

16:51 justin_smith: should be quot

16:51 stompyj: justin_smith: well, I have a js client, and a clojure back-end, and I want the js client be able to perform validation on it’s end. but ideally using a shared schema, so that logic doesn’t only live in the js world

16:52 EvanR: theres two interpretations for quotient when a or b is negative

16:52 corresponding with the two implementations mod and rem

16:52 stompyj: Transit keeps refering to “schema optional”, so I’m trying to figure out how people who want a schema would do such a thing

16:52 I’d prefer not to use avro or json schema

16:54 I just may be thinking about all this incorrectly, as well. heh

16:54 EvanR: but i cant find the other one

16:54 ,(divide -5 3)

16:54 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: divide in this context, compiling:(NO_SOURCE_PATH:0:0)>

16:55 EvanR: ,(unchecked-divide -5 3)

16:55 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: unchecked-divide in this context, compiling:(NO_SOURCE_PATH:0:0)>

16:55 TEttinger: ,(quot -5 3)

16:55 clojurebot: -1

16:55 EvanR: it could be -1 or -2, so i guess you can just add 1

16:55 TEttinger: ,(/ -5 3)

16:55 clojurebot: -5/3

16:56 upwardindex: ,(get-in (iterate 0 inc) [0])

16:56 clojurebot: nil

16:57 ppppaul: i'm using core.async with clojurescript. i'm finding that a lot of the example code i'm running into is specific to clojure. could someone help me out with CLJS links?

17:03 SagiCZ1: ToBeReplaced: i am going to try your method with channels, my idea was short-sighted.

17:07 is there any reason to use old fashioned java.concurrent.BlockingQueue over clojure.async channels? they seem more flexible and very simple to me

17:07 ToBeReplaced: good luck!

17:07 justin_smith: performance

17:08 SagiCZ1: justin_smith: is clojure.async slow?

17:08 justin_smith: compared to just using a BlockingQueue, it has more overhead for sure

17:08 ppppaul: i'm having a lot of trouble with core.async with cljs

17:08 SagiCZ1: i see

17:08 ToBeReplaced: nothing wrong with j.u.c

17:08 justin_smith: not saying any specific app would benefit from that switch, but it's an undeniable difference

17:09 ppppaul: i can use some of the api "go, go-loop, put!, <!, >!" but not really anything else i try

17:09 code examples tend to not work

17:09 EvanR: this blog claims that juc blocking queue has overhead that limits the total number of threads that can be used in practice http://clojure.com/blog/2013/06/28/clojure-core-async-channels.html

17:16 SagiCZ1: any good clojure.async video?

17:20 justin_smith: EvanR: it's a tradeoff - if your logic wants more async units of execution, the core.async pool is a win, if you want faster processing and can keep the thread count reasonably low, j.u.c will beat core.async

17:25 martinklepsch: what are some types that implement IPersistentList but not ISeq, and when would you want to use them?

17:28 gfredericks: &(re-matches #"[\Q\E^x]" "y")

17:28 lazybot: ⇒ "y"

17:32 gfredericks: &(re-seq #"[\Q\E^x]" "xyz^")

17:32 lazybot: ⇒ ("y" "z" "^")

17:32 gfredericks: &(re-seq #"[\Qb\E^x]" "xyz^")

17:32 lazybot: ⇒ ("x" "^")

17:32 gfredericks: ^ love this

17:34 nicferrier: has anyone written anything to pull clojure-docs into emacs?

17:34 seems like it would be a useful thing

17:35 kenrestivo: i'd love to have either grimoire or crossclj.info in emacs

17:36 nicferrier: that would be nice. but clojure-docs looks pretty good... it would be easy to make an eldoc or a C-h f like lookup thing with it inside emacs.

17:36 I am such an idiot. I love making work for myself.

17:37 * TimMc hands nicferrier a nice hairy yak

17:37 llasram: kenrestivo: cider has grimoire integration

17:38 kenrestivo: oh cool, thanks.

18:02 tuft: is there anything for interacting with clojure-docs from the repl? query, submit, etc.

18:02 enhancement for (doc ...)

18:04 amalloy: &(supers clojure.lang.IPersistentList)

18:04 lazybot: ⇒ #{clojure.lang.Seqable clojure.lang.Sequential clojure.lang.IPersistentStack clojure.lang.IPersistentCollection}

18:04 amalloy: &(ancestors clojure.lang.IPersistentList)

18:04 lazybot: ⇒ #{clojure.lang.Seqable clojure.lang.Sequential clojure.lang.IPersistentStack clojure.lang.IPersistentCollection}

18:05 amalloy: really? ISeq isn't in there?

18:05 martinklepsch: i'd be surprised to find such a type in the wild

18:07 rasmusto: how do I specify that I want java.sql.Timestamps instead of java.util.Dates from clojure.java.jdbc query results?

18:08 MrPopinjay: Hi guys. inside a defn function is there an implicit let or anything like haskell's where statement? I want to assign some intemediate values to a name, but it's be nice to avoid the extra ()s from a let function

18:09 amalloy: MrPopinjay: no

18:09 rasmusto: MrPopinjay: you can do destructuring in the arguments vector

18:09 but yeah, not for non-arguments

18:09 EvanR: use a let

18:09 amalloy: you're sorta stuck learning to love the parens

18:10 * llasram <3 ()

18:10 MrPopinjay: That's fine, just wanted to make sure I wasn't adding lots of stuff that wasn't needed! :)

18:10 Thank you guys

18:10 And I'm certainly liking them more now I've discovered paredit.vim

18:10 EvanR: now that adding them is easy

18:10 amalloy: yeah, paredit is a necessity

18:10 rasmusto: MrPopinjay: don't forget vim-sexp (as an alternative)

18:10 EvanR: they should invent something so i can read them

18:11 MrPopinjay: I was put off sexp as it has lots of alt bindings

18:11 amalloy: i like the saying that trying to write lisp without paredit is like writing java without autocomplete

18:11 MrPopinjay: Which is a big no no for me

18:11 EvanR: i only use the alt binding to swap expressions, occasionally

18:11 rasmusto: MrPopinjay: check out vim-sexp-bindings-for-normal-people (or something) by tpope as an alternative

18:11 MrPopinjay: <3 tpope

18:11 EvanR: though it did require i fix the alt key

18:11 MrPopinjay: <3 fireplace

18:11 amalloy: it sounds like he MrPopinjay is perfectly happy with vim-paredit. why is everyone pushing vim-sexp?

18:12 MrPopinjay: I'm open to new ideas!

18:12 What's the USP of sexp over paredit?

18:12 EvanR: none dont try it

18:12 rasmusto: it was just me, and only because I found it more vim-like

18:12 MrPopinjay: I'm mostly just like being able to delete a line without unbalancing the params

18:12 I'm not using much else I think

18:13 rasmusto: or that, yeah. it lets you be less "structured" about your editing, so paredit.vim is more pure

18:13 amalloy: i guess it was just you. for some reason it felt like a lot of people

18:13 rasmusto: amalloy: sorry, I've had caffiene today

18:13 MrPopinjay: I'll have to try it I suppose

18:14 EvanR: getting your alt key to work in vim is its own reward

18:14 MrPopinjay: I use it for window management, I don't want editors to use it

18:15 amalloy: MrPopinjay: obvious solution: let your editor manage your windows???

18:15 lazybot: amalloy: Oh, absolutely.

18:15 EvanR: i tried to use windows key for window management

18:15 MrPopinjay: How could vim manage my windows?

18:16 amalloy: MrPopinjay: it's not a real suggestion

18:16 MrPopinjay: Oh, haha

18:16 amalloy: i'm half-mocking the folks who do everything from emacs

18:16 MrPopinjay: That is pretty amazing

18:16 I should learn emacs + evil

18:16 And somehow embed firefox in it

18:17 EvanR: no

18:17 rasmusto: pentadactyl you mean

18:17 MrPopinjay: I use vimperator, but close enough

18:17 amalloy: MrPopinjay: i hear evil is pretty good. i never got any good at vim, but i know at least one person who was an emacs fanatic, tried vim, and then settled on evil

18:18 * rasmusto used to use pentadactyl nightlies, now uses chrome and a mouse

18:18 amalloy: i sure envy you guys your more composable navigation commands

18:18 MrPopinjay: I think that's the best mix. Vim is better for editing text, Emacs is a better editing enviroment

18:18 My RSI got too bad, had to ditch the mouse. Much happier with the keyboard alone now tbh

18:19 SagiCZ1: vim vs emacs, go!

18:19 MrPopinjay: Both are lovely

18:19 akkad: vi vs emacs

18:19 MrPopinjay: neovim vs emacs, go

18:19 EvanR: the only thing you need a mouse for is paint... and then most people prefer new fangled styli

18:19 amalloy: and also the ability to shout commands at someone you're pairing with: "just hit 4dd, mate"

18:19 akkad: "simple editor" vs "kitchen sink editor"

18:19 MrPopinjay: notepad vs nano, go

18:19 rasmusto: conversation starter: "have you heard of text objects?"

18:19 amalloy: EvanR: i tried a mouse-free editor, but the poor flash support was just not tolerable

18:19 akkad: simple editor without 14k scripts on vimscripts.org

18:20 EvanR: amalloy: text editor?

18:20 amalloy: er

18:20 browser

18:20 EvanR: ah

18:20 amalloy: http://conkeror.org/ was fun

18:20 EvanR: the only thing you need flash for is ads

18:20 MrPopinjay: I'd love to use dwb, but I found it too buggy. Really lovely interacting with it when it worked

18:20 Bronsa: flash and scrolling are 90% of what I use my touchpad for

18:21 EvanR: scrolling -> PgUp PgDn

18:21 MrPopinjay: Damn flash and it's focus stealing

18:21 I mapped j and k to 5j and 5k, and have a high key repeat, so I just use jk

18:21 amalloy: EvanR: ew. those aren't on the home row

18:22 MrPopinjay: Or just use /

18:22 * Bronsa regualrily uses the arrow keys to edit code

18:22 amalloy: even in chrome i use space and shift-space to scroll

18:22 EvanR: spacebar is not on the home row!

18:22 amalloy: Bronsa: go join Raynes in the corner

18:22 MrPopinjay: Hey, I didn't know you could do that

18:22 (What have I started?)

18:23 * Raynes mouses over to his Textual window

18:23 Raynes: Hi guys

18:23 :D

18:23 rasmusto: Raynes: did you have to click?

18:23 Raynes: I sure did.

18:23 rasmusto: <3

18:23 Raynes: <3

18:23 MrPopinjay: Soooo is it normal to start seeing all text in params as a function call after starting to learn Lisp?

18:23 Raynes: Oh, get this: I moused over to the Textual window FROM an ATOM TEXT EDITOR window containing COFFEESCRIPT code that I just wrote.

18:23 rasmusto: (I don't think so)

18:23 Raynes: I'm so far gone, guys.

18:24 EvanR: i hope not

18:24 SagiCZ1: i just use countour roller mouse and i feel almost as cool as yall

18:24 MrPopinjay: I find it really interesting how new syntax makes my brain react differently to mundane things

18:24 justin_smith: MrPopinjay: pretty much. The best variation of this I have seen is nethack - email addresses look scary if you have played nethack enough

18:24 amalloy: MrPopinjay: it's probably a variant on tetris syndrome

18:24 * MrPopinjay googles

18:24 justin_smith: exactly

18:24 amalloy: bahahaha. i can totally believe that, justin_smith

18:25 justin_smith: amalloy: it's like "oh shit, stuck in a corridor, and monsters on both sides as far as I can see...

18:25 "

18:25 amalloy: at least it's a corridor. nobody wants to fight all that out in the open

18:25 justin_smith: seriously

18:25 EvanR: never fight in a basement

18:25 justin_smith: EvanR: but the gnomish mines have some of the best early game armor

18:26 * EvanR engraves elbereth on this square

18:28 MrPopinjay: Right, night gang

18:28 Thanks for the help :)

18:29 bbloom: dnolen_: where did cljs land on the js/foo.bar.baz shorthand?

18:30 was it made officially supported? or dropped? or what?

18:31 Bronsa: bbloom: it's supported. I asked him about that for t.a.js

18:31 bbloom: ok cool thanks Bronsa

18:34 justin_smith: EvanR: I started the perhaps silly process of a lib that interacts with the nethack-lisp nethack UI backend (originally made for elisp, but sexps are sexps)

18:35 so instead of drawing to the screen, it sends sexps describing UI updates

18:35 and then your program can display that for the user as it wishes, or act as an AI replacement for a player, etc.

18:37 EvanR: so its the same game, but it renders by emitting lisp code?

18:37 justin_smith: right

18:37 and takes strings as input

18:37 it's just a display backend. But since all UI is via lisp, that makes making a nethack player AI that much easier.

18:37 EvanR: heh.

18:38 auto farming

18:38 slow it down and you have progress quest

18:38 justin_smith: yeah, that's the low hanging fruit - something that is pretty trivial to script

18:38 or launch 20 instances in parallel, repeatedly playing until you have a 10th level wizard with the identify spell and the magic missile spell

18:39 who cares how many times it fails, if it succeeds once in a reasonable time frame

18:39 EvanR: hook it up to that weird site that has everyone try to play at once

18:40 justin_smith: heh, yup

18:41 wait, do you mean twitch, or do you mean alt.org?

18:43 {blake}: I will be impressed if you can come up with an AI that can match "marvin".

18:43 justin_smith: I would be too :)

18:43 for now I will be satisfied when I have a nice high level clojure symbolic interface to nethack

18:44 so that you can attach whatever ai you like to it's api

18:44 kenrestivo: how would i clear a cancellation exception that is pollutiing map, can't access it because it has a future with some exception, touching it causes it to throw

18:44 {blake}: You could make an ultra-sophisticated "robot wars" type thing, where victory is higher Nethack scores.

18:44 triss: hey all. I've got a project that use both clojurescript and clojure

18:45 I#ve written a module called drummer-boy.pattern

18:45 kenrestivo: i.e. (println {:foo some-future-with-a-cancellation-exception}) => stacktrace every time

18:45 triss: its in src/

18:46 how do i use it from clojurescript file in src-cljs

18:46 just add something o :require?

18:46 justin_smith: kenrestivo: (try some-future-with-a-cancellation-exception (catch Exception e)) - that will give you nil as a val

18:46 you can throw whatever you want after e to return that instead

18:47 kenrestivo: that feels kind of cumbersome, but sure, will do that

18:48 justin_smith: you could make a macro (defmacro i-dont-even [& body] `(try ~@body (catch Exception e)))

18:48 you may want a more succinct name

18:52 rasmusto: is there a loop/recur styel syntax that'll make a lazy sequence?

18:52 style*

18:52 amalloy: rasmusto: if you don't mind pulling in useful

18:52 kenrestivo: naw, this works (swap! c update-in [:dead-future-with-cancellation-exception] future-cancel)

18:53 amalloy: https://github.com/flatland/useful/blob/develop/src/flatland/useful/seq.clj#L108, used like https://github.com/flatland/useful/blob/develop/test/flatland/useful/seq_test.clj#L93

18:53 rasmusto: amalloy: cool, thanks.

18:54 I still find loop/recur syntax to be more grokkable than reduce for the kind of stuff that I'm doing

18:54 amalloy: rasmusto: reduce can't produce a lazy seq anyway...?

18:54 the alternative is manual recursion, not reduce

18:55 rasmusto: amalloy: oh, right. Guess I forgot that

18:58 gfredericks: &(re-seq #"[a-e&\Q\E&c-g]" "abcdefgh")

18:58 lazybot: ⇒ ("c" "d" "e")

18:58 EvanR: reduce cant produce a lazy seq?

18:59 gfredericks: EvanR: not the naive way you originally want it to

18:59 EvanR: (doc cons)

18:59 clojurebot: "([x seq]); Returns a new seq where x is the first element and seq is the rest."

18:59 amalloy: EvanR: well, reduce can't lazily produce a seq. it can eagerly produce a "lazy-seq", but that's not very useful

19:00 justin_smith: EvanR: it can produce a lazy seq, but it cannot itself be lazy.

19:02 rasmusto: hm, I might be confusing myself

19:03 i have a map that I recur with, and I want a sequence within that map to be lazy... I think that's a chicken and egg thing, since the map won't be correct unless the seq is fully realized

19:05 EvanR: to create a "real" lazy sequence you need to use a built-in function like map right

19:05 or range?

19:06 amalloy: EvanR: no. you just need to use lazy-seq, or something that uses it

19:07 EvanR: (doc lazy-seq)

19:07 clojurebot: "([& body]); Takes a body of expressions that returns an ISeq or nil, and yields a Seqable object that will invoke the body only the first time seq is called, and will cache the result and return it on all subsequent seq calls. See also - realized?"

19:07 amalloy: map, filter, and all that stuff, "just" use lazy-seq

19:07 kenrestivo: is there a shortcut already in the language for #(when % (f %)) ? kind of like fnil that only runs a fn if the arg is not nil?

19:09 EvanR: interesting

19:09 gfredericks: kenrestivo: some-> is related

19:09 kenrestivo: some-> 'ed work, thanks

19:10 EvanR: essentially (defn ctor [] (cons X (lazy-seq (ctor))))

19:11 substituting X and the arguments to ctor to make any computable sequence

19:11 amalloy: EvanR: nuh uh

19:12 you can't build an empty sequence that way

19:12 EvanR: empty?

19:12 amalloy: or even one that ends

19:12 yeah. a list with no elements

19:12 EvanR: i wasnt trying to make one that ended

19:12 amalloy: you said "any computable sequence"

19:12 EvanR: ok... infinite sequence

19:12 amalloy: but () is obviously computable, and can't be built with that ctor

19:13 then sure. an unconditional cons around a lazy seq can build any infinite sequence

19:13 EvanR: finite sequences are boring subtypes of infinite sequences

19:15 could you make an infinitely nesting map

19:15 lazy tree, rather than a list

19:16 amalloy: well like...##(nth (iterate list (1)) 10)

19:16 lazybot: java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn

19:16 amalloy: well like...##(nth (iterate list '(1)) 10)

19:16 lazybot: ⇒ (((((((((((1)))))))))))

19:16 amalloy: just remove the nth, and you have an infinitely deep list

19:17 brucehauman: hey guys

19:17 is there a best way to read a namespace from a file?

19:17 EvanR: well being able to get useful info before you get to infinity would be cool

19:18 amalloy: &(nth (iterate (partial list 1) '(1)) 10)

19:18 lazybot: ⇒ (1 (1 (1 (1 (1 (1 (1 (1 (1 (1 (1)))))))))))

19:18 amalloy: it's not clear why you would want any of this. certainly not "useful" in real life

19:18 EvanR: oh of course not

19:19 another great idea goes out the window ;)

19:20 general lazily constructed structures happen a lot, just not always with nice language

19:25 cfleming: rhg135 justin_smith: actually Cursive's find usages has historically worked really well for everything except namespaces, for boring legacy reasons.

19:25 rhg135 justin_smith: I'm actually in the middle of an enormous yak shave to fix that and other related problems for the next build.

19:26 rhg135 justin_smith: I'd hoped that would be out today but it requires a lot of testing since it touches pretty much everything. Should be this week though.

19:33 Morgawr: I have a question.. is there some function/macro that I am missing that performs something like (something test-expr modifier data), if (test-expr) is true then it returns (modifier data) otherwise it returns data untouched

19:33 "something" is the name I'm looking for, if it exists

19:33 (otherwise it's trivial to make as a macro on top of (if )

19:35 amalloy: Morgawr: there's something like it in core now, i think test-> is it. but i prefer the version that's been in useful for years: (flatland.useful.utils/fix data test-expr modifier)

19:36 Morgawr: amalloy: what's the difference?

19:36 how big are the benefits for me to include something external instead of using test->?

19:36 (Also, thanks!)

19:37 amalloy: well, fix is a function. and it behaves differently if you have multiple test/modifier pairs

19:37 Morgawr: mmm.. I am using clojurescript and I can't find test-> on clojure 1.6.0, is it yet to be released and is only in the indev version?

19:37 amalloy: also, the tests in fix are functions of 'something, rather than being booleans themselves, which means you can write like (fix x even? inc)

19:37 maybe it's cond->? i forget what name eventually got decided on

19:38 ,(doc cond->)

19:38 clojurebot: "([expr & clauses]); Takes an expression and a set of test/form pairs. Threads expr (via ->) through each form for which the corresponding test expression is true. Note that, unlike cond branching, cond-> threading does not short circuit after the first true test expression."

19:39 Morgawr: amalloy: thanks, I'll check both :)

19:39 I'm trying to get rid of all the "if" statements in my code, I hate ifs

19:41 rhg135: thanks cfleming

19:42 ya it's so incredibly useful

19:44 rasmusto: hm, maybe my lazy-loop/lazy-recur needs to be a self-calling recursive function after all

19:44 amalloy: rasmusto: what are you trying to do?

19:45 rasmusto: amalloy: my loop/recur produces a vector at the moment, because I'm conj'ing things onto it

19:45 I want it to be a lazy sequence instead

19:45 amalloy: rasmusto: uh huh, that's what lazy-loop is for. replace (recur (conj acc x) foo) with (cons x (lazy-recur foo))

19:46 rasmusto: amalloy: ooo, that's what I was missing

19:46 thank you

19:46 amalloy: lazy-loop is just a pretty thin skin on top of a self-recursive function

19:47 adds the lazy-seq for you, lets you avoid making up a name for the helper function, and lets you write (lazy-loop [x 1] ...) instead of ((fn [x] ...) 1)

19:47 rasmusto: amalloy: ah, gotcha. I do like the style of it, especially because you don't have to do weird default function argument stuff, it's very explicit

19:55 cfleming: rhg135: No doubt, I don't know how anyone programs without it :-)

19:56 rasmusto: amalloy: lazyness just kicked in, this is AWESOME!

19:57 amalloy: rasmusto: i'm glad you're enjoying lazy-loop. i do also recommend trying to write the desugared form yourself, so you know what's really going on

19:57 rasmusto: amalloy: ok, will try that

19:58 amalloy: (lazy-loop [x 0] (when (< x 10) (cons x (lazy-recur (inc x))))) desugars out to just ((fn lazy-recur [x] (lazy-seq (when (< x 10) (cons x (lazy-recur (inc x)))))) 0)

19:58 ie, something it's very easy to have written yourself

19:59 rhg135: cfleming, me too

19:59 rasmusto: amalloy: ah, that's good to know

19:59 rhg135: red the commit msg, cfleming https://github.com/rhg/flutterbot/commit/800b0d3fed878e629f0ff821da6ee3723b8f7455

19:59 should of used cursive

20:00 and i am now

20:03 xeqi: cfleming: is this yak shave related to the find-usages bug I showed you?

20:10 cfleming: rhg135: Haha , so true

20:10 xeqi: It actually might be, although I haven't tested that case yet. I noticed another related bug when looking at the source of a dependency, so I'll investigate that.

20:11 xeqi: I'm up to 91 changed files, so you never know, I might have fixed it by accident :-)

20:24 xeqi: can't reproduce on master; must be fixed

20:25 cfleming: xeqi: Really? I haven't released a new version since the conj, although maybe you were on a previous version there?

20:26 xeqi: Anyway, I'll test it and see if I can fix it for this drop.

20:26 xeqi: cfleming: sorry, meant as a psuedo sarcastic issue closing comment

20:26 cfleming: xeqi: I may just use that :)

20:27 xeqi: cfleming: ala https://github.com/technomancy/leiningen/issues/1666

20:28 cfleming: xeqi: Lovely

20:29 xeqi: I actually need to do a round of issue triage and optimistically close a bunch of old ones reporting stack traces

20:31 rasmusto: amalloy: thanks again for the suggestions, I'm way more comfortable with laziness now

21:47 nonuby: just getting my head around macros (albeit very late), this works yet probably not idiomatic, any suggestions to cleanup? https://www.refheap.com/94654 - basically adding auth to compojure routes (rather avoid middleware)

22:19 justin_smith: nonuby: `(list ~@x) is just `~x

22:20 and based on the rest of it, I think you can just return routes2

22:21 hiredman: /win 15

22:21 rhg135: any obvious improvements https://www.refheap.com/94653

22:22 besides the unused step* i should remove

22:23 justin_smith: nonuby: also, best practices with macros is to do all your logic (or as much as possible) with a function, and only use the macro for custom syntax

22:24 and your macro should expand to a call to said function, of course

22:24 rhg135: sometimes you find you didn't need a macro

22:25 justin_smith: right, but he wants a magic syntax there

22:25 rhg135: ah

22:25 sounds bad

22:26 justin_smith: rhg135: it's par for the course for compojure though

22:26 rhg135: sadly yes

22:26 justin_smith: I don't know about "bad", but it does aspire to be a DSL for routing, so to idiomatically extend it you could use a macro to extend the DSL

22:27 rhg135: s/bad/painful and frustrating/

22:27 justin_smith: that said, making a macro because you would prefer to avoid middleware is like doing a cartwheel because you want to avoid walking

22:27 middleware is the simple option

22:27 rhg135: yes

22:28 they're just fns

22:28 at RUNTIME

22:28 (emphazis on that)

22:34 amalloy: justin_smith: i don't think (list ~@x) is like ~x very often, is it?

22:34 ,(let [x '(1 2 3)] `[~x (list ~@x)])

22:34 clojurebot: [(1 2 3) (clojure.core/list 1 2 3)]

22:35 amalloy: and the first of those two is something you rarely want to emit

22:35 justin_smith: ahh

22:35 right, that's true

22:45 nonuby: thanks guys, with regards to middleware different parts have different auth requirements, so unsure how to handle that, rather keep auth requirements near the specific handler

22:46 unless I start doing path based discrimation e.g. { "/users" ["admin" "superuser"] "/contacts" ["sales" "accounts" "admin" "superuser" } etc.. but seems a little fragile

22:58 rhg135: nonuby, authentication happens at runtime whereas macros run at compiletime so I don't think a macro would help you much

22:58 justin_smith: nonuby: middleware can wrap individual endpoints

22:59 nonuby: it can actually go just about anywhere along the request handling cycle

22:59 nonuby: but with compojure you get only one endpoint?

22:59 justin_smith: individual routes can have their own middlware

22:59 as can groups of routes, if you create those (I think compojure can do that one)

Logging service provided by n01se.net