#clojure log - Aug 28 2014

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

0:00 amalloy: uh, yeah. because you made the claim you can control what happens when you divide by 0 in C

0:00 ifiht: http://2.bp.blogspot.com/_Ku6SPRq8054/TGnWBQfBKJI/AAAAAAAAAvM/5bwQGaKCneo/s1600/divided+by+zero.jpg

0:00 amalloy: which is obviously false: the language definition says you get undefined behavior

0:01 ifiht: I can't control it. 'S why I'm using clojure :)

0:01 TEttinger: ifiht, you should define your own /

0:01 ifiht: with a conditional to handle 0/0

0:02 TEttinger: you can have it do whatever you want

0:02 ifiht: ?

0:02 that's what I was considering

0:03 technomancy: just doseq over all the functions in ns-map of ns-all, and do alter-var-root on them with a function that catches the divide-by-zero error.

0:03 boom.

0:03 TEttinger: I believe namespacing should prevent it from being used by core lib functions, but you may need to make sure no one uses your custom / . it would be a good idea to change the name

0:03 and yeah try catch could be used too

0:03 (not sure if inc or dec technomancy)

0:04 technomancy: https://gist.github.com/technomancy/0568b638542bc90f32ef

0:04 actually wait

0:04 that should catch Throwable just to be safe

0:05 sm0ke: nice to hear that

0:05 ugh not above, TEttinger the game thing

0:06 technomancy: no I'm pretty sure sm0ke thinks this is a great idea

0:06 going to quote you on that

0:06 TEttinger: that's filthy, technomancy, but because you put some effort in,

0:06 (inc technomancy)

0:06 lazybot: ⇒ 133

0:06 arrdem: TEttinger: glad I'm not the only one here who thinks this is vile

0:06 (dec technomancy)

0:06 lazybot: ⇒ 132

0:06 * arrdem hides

0:06 amalloy: technomancy doesn't need your pity points

0:06 (inc technomancy) have some spite points

0:06 (inc technomancy) ; have some spite points

0:06 lazybot: ⇒ 133

0:07 * arrdem greps the logs for (dec technomancy)

0:07 sm0ke: (inc technomancy) ; for leiningen

0:07 lazybot: ⇒ 134

0:07 TEttinger: (dec dec)

0:07 lazybot: ⇒ 0

0:07 sm0ke: (inc inc)

0:07 lazybot: ⇒ 10

0:07 technomancy: just juxt inc and dec =)

0:07 arrdem: oh gods it's only me

0:07 TEttinger: $karma amalloy

0:07 lazybot: amalloy has karma 163.

0:07 amalloy: technomancy: and make you into a pair? the world doesn't have enough room

0:08 arrdem: amalloy: I'd inc for that but I want technomancy to catch up in karma some day

0:08 technomancy: arrdem: since you have the logs handy... am I the only one who says "you monster." or are there other occurances?

0:08 occurrences

0:08 amalloy: technomancy: i do it

0:08 arrdem: technomancy: my logs don't go back far but I'll look

0:08 amalloy: arrdem: two other people have dec'd technomancy

0:08 * technomancy takes notes

0:09 arrdem: technomancy: maximumpanda, didi, a7a and you are the only offenders I see

0:09 amalloy: i prefer the phrasing "you're a monster"

0:09 * arrdem greps

0:09 technomancy: didi came here? cool.

0:09 amalloy: seangrove apparently dec'd technomancy in october just to keep his ego in check

0:09 arrdem: amalloy: only you and trptcolin

0:10 amalloy and Raynes have more extensive logs than I do :/ mine only go back to like january

0:10 TEttinger: this is why we need my insane lucene search for lazybot. with my heavily modified, messy seen plugin, you can try: `last-with-n monster 3

0:10 clojurebot: Excuse me?

0:10 amalloy: and hyPiRion actually came up with a clever way to inc+dec technomancy in 2012

0:10 [15:11:27] hyPiRion: ,(list (rand-nth '[inc dec]) 'technomancy)

0:10 [15:11:29] clojurebot: (dec technomancy)

0:10 [15:11:29] lazybot: ⇒ 37

0:10 TEttinger: nice

0:10 arrdem: amalloy: but mutual recursion on bots is no longer possible :P

0:11 TEttinger: ,(list (rand-nth '[inc dec]) 'technomancy)

0:11 clojurebot: (dec technomancy)

0:11 amalloy: arrdem: sure, but you just need to add one extra human step

0:11 the interpreter, if you will

0:11 TEttinger: I guess you lucked out this time, with the ignore

0:12 arrdem: meh. I'd just bug Raynes for a patch that allows lazybot to "see" only inc and dec forms from clojurebot :P

0:12 that or do it myself with beer this weekend

0:12 sm0ke: (identity technomancy)

0:12 lazybot: technomancy has karma 134.

0:12 sm0ke: wow

0:13 amalloy: hey, when did that get added. that's cute

0:15 sm0ke: (map inc [ technomancy amalloy ])

0:15 :P too much to ask for

0:16 ##(map inc [ 'sm0ke ])

0:16 lazybot: java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to java.lang.Number

0:17 sm0ke: ok that makes no sense

0:18 arrdem: sm0ke: karma isn't actually executed as clojure code. it's its own interpreter that looks like clojure for humor's sake

0:19 technomancy: you can tell because it has troublesome identity/value conflation that would never actually happen in cloju--oh wait

0:20 sm0ke: ##(prn lazybot.plugins.karma/limit)

0:20 lazybot: java.lang.SecurityException: You tripped the alarm! lazybot.plugins.karma is bad!

0:25 sm0ke: lazybot: playing

0:26 i wonder how to use this https://github.com/Raynes/lazybot/blob/master/src/lazybot/plugins/rotten_tomatoes.clj

0:27 playing?

0:27 arrdem: $movie starwars

0:27 lazybot: 2005 - Star Wars: Episode III - Revenge of the Sith 3D | rating: 80 | consensus: | link: http://www.rottentomatoes.com/m/star_wars_episode_iii_revenge_of_the_sith_3d/

0:28 arrdem: $playing

0:28 sm0ke: radar?

0:29 Jumblemuddle: I have a sequence of items, which I need to find a specific item where it's :name property equals a certain name. In order to get the name of the first one I do (:name (:data (first sequence))) What would be the best way to loop through these. (Recursion?)

0:30 amalloy: Jumblemuddle: best would be to not store the things in a dang list, but in a hash-map indexed by name

0:30 then you can just look it up in O(1)

0:30 Jumblemuddle: Well, I'm getting it from neo4j (database).

0:30 I guess I should probably do all this work on the database side...

0:30 amalloy: but if you had it in a list, you could write (first (filter (comp #{"mike"} :name :data) sequence))

0:31 but yes, you should let the database do this

0:32 Jumblemuddle: I guess I'll try to find some more documentation on the database stuff. Thanks for the example though. I don't have any experience with 'filter'.

0:36 ifiht: ,(defn trouble [a] (if-let [a (compare a 5)] (1) (a)))

0:36 clojurebot: #'sandbox/trouble

0:36 ifiht: ,(trouble 5)

0:36 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>

0:36 sm0ke: neo4j is property graph right? graph.getVertices(:name,"abc") should do it

0:52 blorgon: ,"cljbot rules"

0:52 clojurebot: "cljbot rules"

1:47 blorgon: All Clojurians are sleeping?

1:47 arrdem: the sun never sets on the clojure empire

1:49 schmir: good morning!

2:07 arrdem: technomancy: http://blog.mattgauger.com/blog/2014/08/19/atreus-my-custom-keyboard/

2:10 beamso: is that keyboard easier or harder to use with the control keys all along the bottom?

2:18 blorg: ,(clojurebot? 0)

2:18 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: clojurebot? in this context, compiling:(NO_SOURCE_PATH:0:0)>

2:19 blorg: ~clojurebot?

2:19 clojurebot: clojurebot is the cloud

2:19 lpvb: do delays ever get garbage collected after they are derefd?

2:20 blorg: clojurebot?

2:20 clojurebot: clojurebot is amazing

2:20 arrdem: if nothing else is holding the delay reference, then yes it should be GC'd

2:22 blorg: ,(def x 2)

2:22 clojurebot: #'sandbox/x

2:23 blorg: Hmm

3:23 Kneiva: ,x

3:23 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: x in this context, compiling:(NO_SOURCE_PATH:0:0)>

3:38 TEttinger: ,(def it-will-expire 2)

3:38 clojurebot: #'sandbox/it-will-expire

3:38 TEttinger: ,it-will-expire

3:38 clojurebot: 2

3:40 SagiCZ1: yesterday i understood how refs work.. that you always work with the snapshot of the value at some point of time, not necessarily the latest version of it.. so what is it for? lets say the ref points to a map: {:a 0 :b 1}. One thread wants to increase all values by one.. so it reads the map and starts increasing.. at the same point another thread wants to mutiply each key of the map by five.. it starts with the same version {:a 0 :b 1

3:40 how is that useful for anythiing?

3:43 TEttinger: SagiCZ1, hm?

3:44 if they're at the same point, you don't want partial updates

3:44 SagiCZ1: multiple threads share a ref.. and they want to propagate their changes to it..

3:44 TEttinger: so refs have dosync around them whenever they're updated

3:44 SagiCZ1: and dosync waits for other threads to finish writing?

3:45 TEttinger: dosync will wait for writes, not reads

3:45 SagiCZ1: thats the difference between a lock and dosync right?

3:45 TEttinger: you can deref with @ at any point to see the value before the dosync has completed (and without its changes if it isn't done, IIRC)

3:46 SagiCZ1: i see.. so what about atoms which are not used inside transactions?

3:46 TEttinger: I only used refs a little, they aren't common in clojure unless serious concurrency is needed

3:46 atoms are thread-local if I remember it right...

3:46 SagiCZ1: no.. vars are

3:47 TEttinger: I need to pull out the clojure book :)

3:48 Atoms are an efficient way to represent some state that will never need to be coordinated with any other, and for which you wish to make synchronous changes (unlike agents, which are similarly independent but asynchronous)

3:49 SagiCZ1: i want to make synchronous changes but dont need it to be coordinated? does not make much sense to me

3:49 TEttinger: coordinated with other mutable state

3:49 SagiCZ1: would a use case help?

3:49 TEttinger: yeah.

3:50 ,(let [a (atom 10)] (dotimes [n 5] (swap! a inc)) @a)

3:50 clojurebot: 15

3:51 TEttinger: they're the easiest way to handle mutable-like state in clojure

3:51 SagiCZ1: lets say i have this list of creatures.. each living in its own thread.. these creatures interact with their environment and as a result of that change their internal state (mood lets say). I need to have an overview of all the creatures and their moods. So they would share a ref (or something else?) and propagate their changes to the ref. What should i use?

3:52 TEttinger: I actually did something similar with an (atom {:cat (atom {:cat :stuff}) :dog (atom {:dog :stuff})})

3:53 with that approach you can change the whole thing or take out one creature and pass it around, changing it, and pass it back

3:53 SagiCZ1: i see

3:53 that didnt occur to me

3:53 did it work fine?

3:54 TEttinger: the other way is to keep state as little as possible, and only change things by returning a different list of creatures and passing it into something else that uses it.

3:54 that's play-clj's approach

3:54 the atoms worked fine, a bit verbose compared to the rest of clojure

3:55 play-clj's approach is probably safer in larger programs, but needs some glue I think

3:56 SagiCZ1: yeah seemed a little verbose... i think i could just go through the creature-list sequentially and not use threads at all .. thus incorporating pure functional programming but this application is very suited for paralel computation as the creatures are very independent of each other..

3:56 two questions..1) when u used ur atom(atom thing.. was some sort of global variable? or how did you access it?

3:56 2) what is play-clj?

3:57 TEttinger: pretty much everything in clojure is "global" with namespaces. play-clj is a thick abstraction over a java game library to make using it more clojure-y

3:58 https://github.com/oakes/play-clj

3:58 SagiCZ1: so global "variables" are not frowned upon?

4:00 TEttinger: variables in general are tried to be used less. global functions and constants are fine.

4:00 SagiCZ1: i understand that.. but the atom(atom structure could be considered "variable" right?

4:02 TEttinger: the idea is to keep mutable state to a minimum, and use immutable things passed around with slight changes instead. atoms are as close to conventional variables as clojure gets, and they're certainly fine to start with. you may decide to try to rewrite later to take better advantage of the immutable data's persistence

4:02 that's what I did, pretty much, for my messy clojure game

4:02 the rewrite used play-clj, and it was much smoother

4:03 SagiCZ1: yeah i think my first project will be some game-y evolutionary algorithm crap and i expect it to be messy.. i dont want to use extensive libraries that would make it too easy though

4:04 TEttinger: ok, I gotta get to bed. if you're doing a game, try NightMod! I am curious how it is but it looks good. https://nightmod.net/

4:05 being able to edit during a game seems ideal for repl-style clojure dev

4:05 SagiCZ1: thanks for the tip and the other stuff

4:06 see you tomorrow

5:10 bcm: hi

5:10 do many people here use emacs

5:11 mpenet: yes

5:44 kqr: hey! rich hickey talks warmly about using queues to send messages between things rather than having them call each other directly. can anyone expand on how this works in clojure?

5:46 glorbon: better yet can rick hickey become the pope?!

5:47 so we can all do ayearly pilgrimage and ask him our deepest most perplexing questions!?!

5:48 schmee: kqr: core.async is great for that

5:48 kqr: schmee, i'll have a look!

5:50 schmee: kqr: so instead of having A communicate directly with B, stick a channel in between and make a put thing on the chan and B take things of it

5:50 make A put things on the chan, I mean

5:50 kqr: yeah I understood that

5:50 I have some experience with erlang and chans in haskell so it makes sense to me

5:51 schmee: ahh, then you should feel right at home with core.async

5:52 glorbon: wow.. evry1 here knows haskell .. only i dont?

5:54 schmee: glorbon: I don't know it either, I've tried it a few times but it wasn't my cup of tea

5:59 SagiCZ1: glorbon: i know nothing about haskell.. but some people say it's pretty

6:02 does having some kind of logger call inside a pure function make it unpure? since its technically a side-effect?

6:05 glorbon: define : call inside

6:06 SagiCZ1: (fn [args]

6:06 do something...

6:06 log(message))

6:08 kqr: SagiCZ1, yes, it does

6:08 SagiCZ1, but if you pass the logger function as an argument to your function, it's pure enough to be testable at least

6:09 SagiCZ1: and is that the common way how to log something in clojure?

6:15 kqr: I don't know

6:19 glorbon: personaly ilek the second option more

6:19 *liek

6:19 but idk about purity and such

8:07 lvh: Hi :)

8:07 Some questions about being a good Clojure citizen.

8:08 1) Is there a serialization protocol in Clojure that I should extend instead of writing my own (defprotocol SerializationScheme ...) ?

8:08 2) (hash-fn msg :salt (.getBytes "xyzzy")), or (hash-fn msg {:salt (.getBytes "xyzzy")})

8:10 beamso: lvh: for 1, what about edn?

8:10 lvh: beamso: I intend to implement it with edn, yes

8:10 beamso: does edn have a generic protocol?

8:11 beamso: i'm unsure what you mean by 'generic protocol'

8:12 lvh: beamso: a protocol for serialization, as in defprotocol

8:17 vijaykiran: lvh - what do you want to serialise ?

8:18 lvh: vijaykiran: arbitrarily composed maps, vecs and sets with fairly simple keys and values (ints, strings, byte arrays), the usual

8:18 EDN seems like the natural choice :)

8:19 I am the only consumer/writer of this data, so I don't care if the format is poorly supported outside of clojure (nippy)

8:19 beamso: there doesn't appear to be a protocol (as in defprotocol)

8:21 swi: Hello. I'm choosing a book to read about clojure (after some blind play with language at 4clojure) to understand it's better. I'm choosing from 'Clojure programming' by Emerick and 'Programming Clojure' 2nd by Halloway. Which one is better for begin (i have a very little FP background)?

8:22 beamso: i preferred emerick's book

8:22 hyPiRion: swi: I have heard that 'Clojure programming' is better

8:23 swi: :)))

8:23 hyPiRion: I think that's the general consensus in this channel as well

8:23 beamso: a current o'reilly discount code is 'B2S4'.

8:23 lvh: I liked joy of clojure

8:23 but tbh I liked most of those books :)

8:23 (maybe I just like clojure :))

8:23 beamso: tha discount code was for ebooks

8:24 *that

8:24 glorbon: wait.. emrick is the concensus?

8:25 hyPiRion: lvh: yeah, but I felt JoC is for Clojure programmers with some experience

8:25 glorbon: (also is it necassary or can one skip to joy of clojure without miising much?)

8:27 mpenet: just read 1 and then get your hands dirty

8:27 they all repeat more or less the same stuff

8:28 TimMc: I don't think any of them are a *bad* choice. :-)

8:31 glorbon: ,"want to sleep"

8:31 clojurebot: "want to sleep"

8:51 swi: Thanks a lot, so let it be Emerick :)

8:56 justin_smith: glorbon: (Thread/sleep (* 1000 60 60 8)) ; get 8 hours of sleep

8:57 glorbon: u need to put a comma before that

8:57 otherwise i dont respond, silly

9:11 justin_smith: "i dont respond" is a funny response

9:13 glorbon: u have defeated my logiacally. *bows*

9:13 *me

9:32 https://www.kickstarter.com/projects/1751759988/sicp-distilled

9:34 virmundi: hello. I’m trying to embrace the dynamic typing of cloure. I have an api that allows a user to create a collection on a remote server. There are a lot of little options that can go into creation. There are other points in the api where a collection name is needed such as when a user wants to get a document from the collection.

9:34 in clojure is it common to have a value in a map be either a string or another map?

9:35 I was thinking {:collection “name”} for things like getting a document or {:collection {:name “name” :option1 …}

9:35 Is that a good fit for the language?

9:36 teslanick: Depends on the details of your use case, but either is appropriate

9:36 Not sure how that relates to dynamic typing, though.

9:38 virmundi: teslanick: Java would normally not have collection be an Object.

9:38 most of the time the value would be statically typed to a string or another configuration object.

9:42 kqr: teslanick, in a static type system you'd want a sum type for that usage

9:43 virmundi, also if you haven't seen it yet, one day this might be useful: https://github.com/cemerick/clojure-type-selection-flowchart

9:44 virmundi: kqr: thanks. I’ve just started Clojure. I need a good driver for a db. Figured this would be the best way to learn the language.

9:44 kqr: yeah i've just started myself

9:45 i currently have one place where I need a sum type, and I've simply made a record out of it

9:45 teslanick: Things in clojure have types, they just fall into a few simple constructs rather than highly-specialized objects. The value of a highly-specialized mutable types goes away when you don't have methods on objects to call.

9:45 kqr: so say if I want to return either an ID string or a record, i'd return either {:id "2891378"} or {:full-record {:name "sarah" :age 27}}

9:45 and so on

9:46 teslanick: But you can do runtime structural validation. Prismatic has a bunch of useful utilities to that end.

9:46 justin_smith: kqr: a protocol or interface can effectively be used as a sum type under the jvm's system

9:46 ToxicFrog: teslanick: I'm not sure I buy that; even with immutability and no object methods, type checking is still worthwhile to catch arg/return type mismatches before runtime.

9:46 kqr: this means I don't have to dispatch on type which might be weird, but I don't know what's idiomatic

9:47 justin_smith, I haven't looked into protocols yet, but I'm excited for when I do

9:47 justin_smith, from the sound of it, they seem awesome

9:47 justin_smith: kqr: the idea is that instead of defining a sum type and enumerating in one place all it's possible values, you define a protocol, and enumerating in one place all the functions implemented on it

9:48 teslanick: ToxicFrog: Not saying that types aren't useful, but they're less useful than a robust collection api (like the one clojure provides). It's possible to have both, but that's not where clojure is right now.

9:48 justin_smith: then add the values piecemeal

9:48 teslanick: I'll defer to justin_smith, because he's smarter/more-experienced than I am.

9:48 justin_smith: kqr: all the same functionality you get with a sum type, but the specification is sort of inside out

9:49 kqr: justin_smith, i've heard they are similar to typeclasses

9:49 justin_smith: teslanick: defer to me on what?

9:49 teslanick: W/R/T approaches to data typing

9:50 "typing" in big scare-quote-things

9:52 justin_smith: I haven't tried core.typed, but one thing I miss in clojure is the ease of refactoring with a typechecker

9:52 you just make a couple of changes, and then fix things until it compiles

9:53 tbaldridge: aka, flail around until stuff works :-P

9:53 justin_smith: tbaldridge: well, not so much flailing as being lazy, and trusting that the compiler will point out the remaining cases that need to be updated

9:54 but sure, it's no replacement for having a great design in the first place

9:55 kqr: well, yeah. with a great design the type system is by some sort of definition useless

9:56 the issue is that people suck at creating great designs from the start

9:57 hyPiRion: kqr: Sure, a type system is useless when you already have working software.

9:57 kqr: exactly

9:57 mpenet: hyPiRion: until you need to refactor things

9:58 hyPiRion: mpenet: but then it's not working

9:58 at least not as intended.

9:58 mpenet: well, extending something that's working happens often !

9:59 hyPiRion: mpenet: right, that's what I was trying to get at :p

9:59 kqr: but if the design doesn't take into account the new specs it's not a great design anymore

9:59 which is why I think "a type system is no replacement for a great design" is a trivial statement

10:00 mpenet: having choice between the 2 would be nice

10:00 reminds me of https://github.com/mikera/kiss

10:00 kqr: i'm trying to understand how that'd work

10:00 mpenet: who knows one day

10:01 kqr: ah, you probably meant something other than what I think

10:01 clojurebot: Excuse me?

10:02 justin_smith: kqr: point being, yes, using a type system to drive refactoring can be seen as flailing until stuff works, but designs that start perfect are the exception, and something that drives our confusion and disorganization toward something that works again is valuable

10:03 kqr: ah sure

10:03 justin_smith: though without a type checker we can get very far with well designed tests, and hammock driven development - making sure we have a really strong mental model going in

10:04 sritchie: justin_smith: the type system provides some rigor and guidance around what constitutes a strong mental model

10:04 mpenet: well, even with perfect design we make errors when implementing

10:04 glorbon: justin_smith: are you rick hickey?

10:05 justin_smith: glorbon: definitely not

10:05 sritchie: AND the “strong mental model” you have may not be obvious to someone else reading the code later

10:05 mpenet: having warnings at compile time is definitly a +

10:05 justin_smith: glorbon: though I will take that as a compliment

10:05 sritchie: glorbon: :)

10:20 verma: would >! return a non-true value when the port is closed? or just the whole go-loop just dies?

10:23 this is what I am doing: https://www.refheap.com/89539

10:24 sveri: Hi, using datomic I have a lot of functions that start like this: (defn f [db-conn] (let [db-val (d/db db-conn)] (do-something-with db-val))). Is there a way to get rid of these (let [db-val (d/db db-conn)] part? maybe with a macro?

10:24 verma: I do see "What is love?" printed everytime I exhaust my "messages", but I am hoping to see it when the returned channel is closed as well.

10:26 when I close the chan, the program terminates but I never see the "What is Love" message

10:27 tbaldridge: sveri: you should only really need to call (d/db conn) in one place,

10:27 perhaps in a handler

10:28 verma: may be I should condense everything into one loop

10:28 not sure how its going to help

10:29 I guess I could use onto-chan and wait for it to finish as well

10:29 sveri: tbaldridge: and pass that through the entire application during a request? what If I do an update and want to read from the database the changed values, I would need to do (d/db db-conn) again then, however, it would be much more seldom

10:29 kqr: sveri, if you really mean to make a new connection (or whatever d/db does) every call, then yes, that's exactly what you have a macro for

10:32 tbaldridge: sveri: well (d/transact ...) hands you back db-after which is the DB after the transaction was applied. So you don't even need a (d/db conn) call after transact

10:32 kqr: sveri, or possibly just a function, depending on what you want the end result to be

10:33 sveri: kqr: thank you

10:33 tbaldridge: ok, that's right, I did not think of that

10:34 thank you both very much, I guess, creating a db-val once should be enough most of the times

10:40 noncom|2: hello

10:58 justin_smith: , (apply str (map (comp char #(+ 101 %)) [3 0 7 7 10]))

10:58 clojurebot: "hello"

10:59 verma: lol

11:03 borkdude: lol

11:05 sveri: , (apply str (map (comp char #(+ 101 %)) [7 10 7]))

11:05 clojurebot: "lol"

11:05 sveri: let the bots do the talking^^

11:12 justin_smith: ,(apply str (map (comp char #(+ 97 %)) (take 5 (map first (iterate (fn [[i p]] [(bit-and p 127) (bit-shift-right p 7)]) [7 29541764])))))

11:12 clojurebot: "hello"

11:13 verma: dafuq

11:13 justin_smith: this is so much more interesting than the database migration and template metadata updates so we get proper previews on social media sites

11:14 verma: I could have done that with 5 bits per char instead of 7

11:15 TimMc: &(let [r (java.util.Random. 15057100)] (apply str (map #(char (+ 16r61 %)) (take 5 (repeatedly #(.nextInt r 26))))))

11:15 lazybot: ⇒ "hello"

11:16 justin_smith: TimMc: OK, that's pretty awesome

11:16 TimMc: &(let [target (map #(- (int %) (int \a)) "hello")] (loop [seed 0] (let [r (java.util.Random. seed), result (take 5 (repeatedly #(.nextInt r 26)))] (if (= result target) seed (recur (inc seed))))))

11:17 lazybot: Execution Timed Out!

11:17 justin_smith: I figured it had to be something like that :)

11:17 TimMc: Anyway, that's how I got it.

11:19 justin_smith: TimMc: if you changed the static \a to be any target offset, and instead searched for 5 ints with the right relative difference, it would probably get a result much quicker

11:19 TimMc: mmm, true

11:19 Patches welcome.

11:20 It doesn't take very long on my REPL as is, though.

11:20 10.6 seconds

11:21 justin_smith: yeah, but that's exponential with length of the string

11:21 even the relative offset checking is only a constant multiplier on that exponential basis of the algorithm

11:22 , (apply str (map (comp char #(+ 97 %)) (take 5 (map first (iterate (fn [[i p]] [(bit-and p 31) (bit-shift-right p 5)]) [7 470372])))))

11:22 clojurebot: "hello"

11:22 justin_smith: 5 bit version

11:23 so much more interesting than social media friendly meta tags

11:23 verma: my >! never really returns anything other than "true", when I close the channel, my go-loop blocks (I think), shouldn't >! be returning a non-true value?

11:25 tbaldridge: verna: code? >! will return falsey if the channel is closed

11:26 verma: tbaldridge, sure, give me a second

11:26 tbaldridge, doing something on these lines: https://www.refheap.com/89539

11:27 instead of the sent? stuff I just refactored stuff out into a function now

11:27 tbaldridge, basically I get a list of IDs which I send down the channel, if the channel is closed I want to stop doing that, and not recur any further, inside the inner or the outer loop

11:28 tbaldridge, I could have used async/onto-chan, but that doesn't really tell me if the completion was because of exhaustion or because the channel closed

11:29 tbaldridge: code style looks good, I'd double check that sent? and next-token are what you are expecting

11:30 toxmeister: hey guys. Can someone pls help my memory and by any chance remember the link to an (possibly not so recent) article which contained some great visualisations about various CSP/core.async transforms? e.g. merge, split, throttle, pubsub, map etc. Rings a bell?

11:30 verma: tbaldridge, when the list exhausts, things look good, let me post the code where I am consuming it

11:31 tbaldridge, this is the go-loop which consumes values: https://www.refheap.com/89543

11:33 tbaldridge, may be there are pending elements in the channel which haven't been consumed :/

11:34 tbaldridge: well (>! will return false whenever the close! happens, but there could still be items in the channel.

11:35 verma: tbaldridge, hmm, that's what I thought, so I added (while (<! ch)) and it seems to have returned cleanly :/

11:35 tbaldridge, is there a drain on close? :P

11:37 tbaldridge: no, but feel free to write your own ;-)

11:43 alandipert: clojars feels down, anyone else noticing issues?

11:43 Bronsa: alandipert: the web ui or the whole repo?

11:44 verma: tbaldridge, sure thanks for your help

11:44 (inc tbaldridge)

11:44 lazybot: ⇒ 9

11:45 noniwoo: why when I put single line (future (prn "Stop?")) into a file, then run it, clojure never ends running? should thread not end after printing value?

11:45 alandipert: Bronsa: ui doesn’t work for me, deps have been flaky

11:45 mdrogalis: alandipert: Maybe we should cheer it up.

11:47 Bronsa: alandipert: wrt the site, that's a known bug that only affects the homepage

11:49 alandipert: https://clojars.org/login if you login, the site will be fine

11:49 mdrogalis: Yeah, on a serious note - it seems alright to me, Bronsa / alandipert.

11:50 alandipert: thanks

11:50 still spotty for me but it’s likely my side

11:50 Bronsa: https://github.com/ato/clojars-web/issues/235

11:57 cursork: noniwoo: Try (shutdown-agents) after your (future ...) call

11:57 melipone: hello! I am having problems capturing the output of a java program to stdout. I tried everything I found on the web but nothing worked. What to do?

11:59 llasram: Wow, everything?

12:00 TimMc: melipone: Capturing the output of the entire JVM process, or redirecting from inside the JVM?

12:00 noniwoo: cursork: ok, it worked. where can I read more about this, and behavior of (future)?

12:01 TimMc: Bear in mind that shutdown-agents is permanent.

12:02 melipone: TimMc: Dunno exactly. I am calling a function from a java library and it works fine but I can't capture the output from System.out.println

12:02 TimMc: Again, what do you mean by capture?

12:03 Like, `java -jar foo.jar >output.txt` in your shell?

12:03 melipone: TimMc: I would like to write out the output to a file for example

12:03 TimMc: Yes exactly

12:04 TimMc: If that doesn't work, perhaps it is printing to stderr instead?

12:04 melipone: TimMc: I have the source code of the program and it's printing to stdout

12:06 justin_smith: melipone: what about System/setOut ?

12:06 if you want to set the target of all output from within the jvm

12:06 melipone: justin_smith: Okay, I haven't tried that. how do you use that?

12:07 justin_smith: http://docs.oracle.com/javase/7/docs/api/java/lang/System.html#setOut(java.io.PrintStream)

12:07 in clojure, the syntax would be (System/setOut stream)

12:07 where "stream" is an apropriate output-stream object

12:08 melipone: justin_smith: I'll try that and report.

12:08 justin_smith: or, more accurately, as the docs show, a PrintStream

12:08 TimMc: What I don't know is how one would set it back again.

12:08 mping: hi guys

12:08 melipone: TimMc: that's true

12:08 TimMc: System/setOut seems likea really good way to break everything.

12:08 justin_smith: TimMc: bind *out* before doing it, then call setOut again later?

12:08 TimMc: mmm

12:09 melipone: TimMc: this occurs so often, I'm surprised a solution hasn't been found yet

12:09 justin_smith: actually - this is clojure, isn't *out* available for thread-local binding? why not use that?

12:10 melipone: justin_smith: I tried that (binding (*out* ...)) did not work

12:10 rstandy: *out*

12:10 justin_smith: the syntax is (binding [*out* ...] ...)

12:10 melipone: justin_smith: whatever ...

12:10 justin_smith: unless that was just a typo above

12:11 mping: what is the standard way to return json errors from a ring app? I'm using validateur, but I would prefer to do something like rails and add a errors field to every validatable attribute; but json serialization doesn't allow for this

12:11 melipone: justin_smith: a lisp slip

12:11 justin_smith: melipone: that feels like a line from a dr. seuss poem :)

12:12 melipone: justin_smith: don't get me started :)

12:13 justin_smith: mping: can't you populate :errors on the applicable attributes before doing the json conversion?

12:15 that can just be a reduce with assoc on each error, if the errors are in any kind of sane format

12:16 melipone: I like tee for sending all output to a file, while also preserving real time console output - but that is yet again a solution from outside the jvm

12:19 TimMc: justin_smith: If the output is being written directly to System.out, binding *out* won't help.

12:20 mping: justin_smith: error are sane, I was wondering if is a common way of representing errors on an obj that will be json'ified

12:21 kqr: what is wrong if when I start "lein repl" I get two nasty stack traces? (one starting with Exception in thread "nREPL-worker-0" java.lang.NoSuchMethodError: clojure.tools.nrepl.StdOutBuffer.length()I)

12:21 mdrogalis: kqr: Known issue, fixed on master.

12:21 kqr: oh

12:22 does it affect anything other than being a nasty error message?

12:22 justin_smith: mping: right (reduce (fn [result error] (assoc-in result (get-error-path error) (get-error-contents error))) result errors) -- get-error-path and get-error-contents should be trivial to write

12:22 mdrogalis: kqr: I don't think so, no. Should be good to go.

12:22 crelix: this is probably a silly question but why do i keep getting an unbound function error when trying to call clojure from java?

12:22 melipone: justin_smith: I'm looking now at clojure.tools.logging

12:22 kqr: mdrogalis, the reason I'm asking is that according to (http://clojure-doc.org/articles/tutorials/vim_fireplace.html) lein repl should create a target file with information on the repl – this does not seem to happen. (and vim complains about not being connected to the repl)

12:23 justin_smith: melipone: how will that help if the java code is calling System.out.println?

12:24 mdrogalis: kqr: Not sure, I'm not a Vim guy. technomancy, any idea?

12:24 technomancy: kqr: that's a bug with 2.4.3 running outside a project; need to either downgrade to 2.4.2 or stay inside a project

12:25 hiredman: I am sort of shocked at the number of people in here complaining about that

12:25 kqr: technomancy, ah. but you're supposed to be able to connect to a repl outside of a project?

12:25 hiredman: I never use lein outside of a project

12:26 melipone: justin_smith: I read that it has a way to capture *out* and redirect it to logs

12:26 justin_smith: hiredman: clearly many of us do though

12:26 hiredman: justin_smith: why?

12:26 Bronsa: puredanger: ping

12:26 technomancy: hiredman: if it affected regular repls I would have stayed up late to fix it despite being in the middle of a move, selling my house, etc

12:26 hiredman: technomancy: sure

12:26 puredanger: Bronsa: eh?

12:27 Bronsa: puredanger: is there any interest in a fix for http://dev.clojure.org/jira/browse/CLJ-1232 ?

12:27 kqr: hiredman, I commonly start up a new session in a separate workspace when I want to figure stuff out that's more general and not immediately related to my project

12:27 technomancy: it's an easy fix, but unfortunately it disproportionally affects people who are less likely to know the fix

12:27 Bronsa: I can write a patch, but if Rich's stance is that it's not an issue I won't bother

12:27 kqr: hiredman, i like blank slates

12:27 justin_smith: hiredman: I like having a "generic" repl for experimentation, etc., that is not tied to a particular project and its deps. Can't speak for everyone else of course.

12:28 hiredman: I guess

12:28 bdruth: morning ... quick question about let bindings, if anyone has a moment?

12:28 hiredman: I mean, if I want a repl I java -jar clojure.jar (the actually path the clojure jar in my checkout of clojure is somewhere in my shell history)

12:28 puredanger: Bronsa: I think Rich's opinion was clear in the comments and that was: should be fully-qualified if not in the auto-imported set

12:29 kqr: hiredman, does that repl play well with fireplace/vim?

12:29 puredanger: Bronsa: perhaps a patch that error'ed on use of non-fully-qualified return type not in the auto imported set would be ok

12:29 bdruth: I have two functions that have to construct an identical set of let bindings ... wondering if there's a way of extracting them to another function?

12:29 hiredman: kqr: no, it is bare bones no editor integration, no history, etc

12:30 justin_smith: hiredman: fair enough, but lein repl also gives me an automatic nrepl port

12:30 kqr: hiredman, so that's why I don't use it for experimentation ;)

12:30 technomancy: cave man clojure =)

12:30 bdruth: e.g.: (let common-bindings ...)

12:30 Bronsa: puredanger: I'm ok with throwing an error, I just don't like the current behaviour. It's not documented and confusing

12:31 hiredman: bdruth: consider using a map instead of let bindings

12:31 Bronsa: puredanger: at the same time though I don't understand why letting the compiler auto-qualify the class symbol is out of the question

12:31 bdruth: hiredman: true, I could do that

12:31 puredanger: Bronsa: I also find it confusing. :)

12:31 bdruth: hiredman: thx

12:32 puredanger: Bronsa: in other words, I agree with you :)

12:33 justin_smith: bdruth: I don't know if it's really worth going so far, but flatland/useful has keyed, and that in combination with :keys destructuring could let you abstract out the common binding logic

12:33 https://github.com/flatland/useful/blob/develop/src/flatland/useful/map.clj#L8

12:33 Bronsa: puredanger: I'll make two patches then, one that auto-qualifies and one that throws on non-qualified&non-default-import

12:36 hiredman: justin_smith, bdruth: there thing is, the only reason the same set of bindings makes sense is if you are doing in the same thing, then so if you pull out the same use in to a function, you have one place for the bindings, but still need to communicate them to the function some how, so a map

12:37 gzmask: hello all, how do I load an bitmap image into a 2D array in clojure ?

12:37 justin_smith: yes, using a map directly is probably more reasonable

12:37 TimMc: gzmask: Same way you'd do it in Java. :-)

12:38 hiredman: well, the jvm doesn't have 2d arrays

12:38 TimMc: For most purposes you can pretend it does.

12:38 gzmask: i saw "clojure.core/to-array-2d" though

12:39 gfredericks: ,(doc to-array-2d)

12:39 clojurebot: "([coll]); Returns a (potentially-ragged) 2-dimensional array of Objects containing the contents of coll, which can be any Collection of any Collection."

12:39 TimMc: What a funny little fn.

12:39 gfredericks: gzmask: it just means a nested array

12:39 bdruth: hiredman: justin_smith: yeah, I have a 'deploy' function that puts a bunch of stuff in certain places, and then an 'undeploy' that basically needs the same locations to know where to remove them

12:39 gfredericks: thus "potentially-ragged"

12:39 bdruth: I think a map will work

12:39 hiredman: gzmask: what people colloquially refer to as a 2d array on the jvm is an array of arrays

12:40 gfredericks: ,(to-array-2d ['(hey this list has 6 items) #{:foo}])

12:40 clojurebot: #<Object[][] [[Ljava.lang.Object;@213dbd>

12:40 TimMc: hiredman: What environments *do* have true 2D arrays?

12:40 hiredman: TimMc: fortran maybe?

12:40 I dunno

12:40 gfredericks: what's that new language with the female name

12:40 gzmask: nested vector? like [[1 1 1][2 2 2][3 3 3]] ?

12:40 hiredman: julia?

12:40 gfredericks: yeah

12:40 justin_smith: it might make more sense to use an array of (* w h) size, and just write accessors that convert column / row numbers into direct indexing

12:40 TimMc: gfredericks: Swift. :-)

12:40 hiredman: gzmask: arrays and vectors are different

12:40 gfredericks: it either has 2d arrays or it just has 1-indexing

12:41 I know the latter is true, just not sure if I'm confusing it with the former

12:41 hiredman: gzmask: [] is a clojure vector, arrays are a jvm primitive

12:42 gzmask: i see. what are the situations that I should use array instead of vectors ?

12:42 gfredericks: interop mostly

12:42 hiredman: gzmask: sure, I would definitely use an array instead of a vector for image data in many cases

12:42 gzmask: you should google java ImageIO

12:43 justin_smith: gzmask: sometimes makes sense in tight loops, where the array a local that is not used by any other code (especially not any other threads)

12:43 gzmask: so there is a performance difference between array and vector?

12:43 justin_smith: yes - just use the array that ImageIO returns to you

12:43 unless you need to do anything fancy, or share the data

12:44 hiredman: gzmask: yes, the big difference is generally with vectors you will end up with boxing (there are some primitive vectors but maintaining the primitiveness well performing operations can be tricky) while arrays can hold primitives very easily

12:45 justin_smith: well ImageIO will return some class that wraps an array

12:45 justin_smith: gzmask: actually, iirc maybe ImageIO gives you a buffer, which you can then put into an array, or just read from and use as you go

12:45 hiredman: bufferedimage

12:45 justin_smith: hiredman: right

12:46 gzmask: hmm, so this buffer is something like an 1D array?

12:46 hiredman: but unless you are doing something very custom, the java image stuff likely has some facilities you'll want to take advantge of

12:46 gzmask: what buffer?

12:46 justin_smith: gzmask: it wraps the act of getting the pixels left to write and top to bottom - you can then put that in an array, or just use it as you go if you don't need to persist the input

12:46 hiredman: gzmask: http://docs.oracle.com/javase/7/docs/api/java/awt/image/BufferedImage.html is what you will get from ImageIO

12:46 justin_smith: *left to right

12:46 http://docs.oracle.com/javase/7/docs/api/javax/imageio/ImageIO.html

12:48 gzmask: i see, I will look into the java stuff more I guess. sometimes just can't get myself "java-clean" :"(

12:48 justin_smith: well, to be more precise - you can get a stream from a file / network socket / whatever - you can pack that stream into a bufferedimage which lets you access the data as needed, and then refer back to it as if it were a collection all along, or an iterator that lets you loop over them as they come in from the source

12:49 gzmask: the model is very flexible, but not all that intuitive at first to be sure

12:50 ie. you don't need to save the network data to disk, or even have the whole thing in RAM, before you get the pixels. You don't need to load the whole thing if you just want the first pixels the file format provides to a reader. etc.

13:08 gzmask: the whole java eco-system feel so alien to me now. I think I need to relearn it

13:09 it's not like everything useful is inside *.swing back in 2005 anymore

13:10 TimMc: heh

13:43 gzmask: (javax.imageio.ImageIO/read (java.io.File. "sample_logos/superman.jpeg")) and I got an error. what's wrong with this java interop?

13:44 TimMc: "an error", you say?

13:46 gzmask: "clojure.lang.Compiler$CompilerException: javax.imageio.IIOException: Can't read input file!"

13:46 verma: tbaldridge, you think this is a resonable implementation for a drain close? https://www.refheap.com/89551

13:46 tbaldridge, I realize its not clojurescript compatible

13:47 tbaldridge, actually the docstring is incorrect

13:47 ok, fixed, https://www.refheap.com/89551

13:47 gzmask: (ns day01.main-screen (:import (javax.imageIO))

13:47 (ns day01.main-screen (:import (javax.imageIO))

13:48 (ns day01.main-screen (:import (javax.imageIO))

13:48 (ns day01.main-screen (:import (javax.imageIO))

13:48 (ns day01.main-screen (:import (javax.imageIO))

13:48 (ns day01.main-screen (:import (javax.imageIO))

13:48 I imported it as (:import (javax.imageIO))

13:48 slpsys: namespace bomb

13:48 gzmask: sorry, I am struggling with this lighttable and kiwiirc combo

13:49 llasram: gzmask: "Can't read input file!" seems like a pretty clear error to me

13:49 gzmask: what's its default reading location? not /resource?

13:50 llasram: What? No

13:50 Current working directory of the process, just like in any other language

13:50 If you want a resource from the classpath, you can use the `clojure.java.io/resource` function to get a URL

13:50 TimMc: gzmask: (do (slurp (java.io.File. "sample_logos/superman.jpeg")) nil) should produce a similar error

13:51 llasram: "URL"

13:51 gzmask: that fixed it

13:51 llasram: TimMc: Yes?

13:52 gzmask: immersed myself in the framework too long and resources became my root XD thanks guys

13:54 ok now I have this "java object" and it's immutable to pprint. how do I observe it?

13:54 TimMc: llasram: I seem to recall some escaping problems.

13:55 gzmask: I don't think you mean "immutable" there.

13:56 gzmask: im·mune*

13:56 TimMc: Use the API docs to find out how to interact with it. Find snippets online to get an idea of how people use it. The usual way. :-)

13:56 justin_smith: gzmask: there are methods that get values out of the BufferedImage - http://docs.oracle.com/javase/7/docs/api/java/awt/image/BufferedImage.html

13:56 gzmask: awww, java, can't you just let me stay in the REPL ;P

13:57 technomancy: gzmask: there are various inspector tools you can use to reflect on the methods of a given class

13:57 from the repl

13:58 gzmask: technomancy: what are those nice things?

13:58 justin_smith: you likely want to use getData, which gives you a Raster

13:58 TimMc: gzmask: I use org.timmc.handy.repl/show to reflect on classes from the command line. Doesn't give you javadocs, though.

13:58 justin_smith: gzmask: http://docs.oracle.com/javase/7/docs/api/java/awt/image/Raster.html

13:59 the Raster represents a rectangle of pixels

13:59 TimMc: gzmask: What is your ultimate goal with this image?

13:59 justin_smith: so (-> image .getRaster (.getPixel x y))

13:59 gzmask: Tilemap from bitmap for a game

13:59 technomancy: gzmask: the one I used was called javert, but I make no claim as to it being the best or good or anything

14:00 justin_smith: TimMc: he wants to get a pixel value

14:00 technomancy: *the one I made

14:00 justin_smith: gzmask: oh, that's not what you said before - but OK

14:01 in that case you can likely ignore Raster and just directly use the image as your tile via whatever API the game is using

14:01 gzmask: basically a bitmap read into an array, then use some specific color value as invisible collision bodies, some other value as other tile stuff like trees etc.

14:02 justin_smith: gzmask: there are classes in imageIO that have collision detection and such built in. I think you will save yourself a lot of work and trouble by exploring the javadoc.

14:02 gzmask: yea, I just need to get the num value for specific pixel

14:03 justin_smith: gzmask: why test an individual pixel when the class already has a collision detection method?

14:03 gzmask: the collision detection is done is box2d

14:04 so the bimap are used as information storage for collision bodies

14:05 [[1 1 1][1 0 1][1 1 1]] i.e this is a room

14:05 where 1s are the collision aabbs

14:06 anyway, I guess I just need digging into the javadoc now

14:13 acagle: cornspinbikeginrupafishbachbock

14:15 mi6x3m: hello clojure, what what you call a function as part of object's metadata which returns the source of the object

14:15 :get-src ?

14:20 arrdem: we already have the :src key...

14:21 mdrogalis: arrdem: How are your fingernails holidng up?

14:21 mi6x3m: arrdem: well this is different, it's a function returning the source

14:22 technomancy: arrdem: we do?

14:22 * arrdem digs in clojure.repl

14:22 Bronsa: arrdem: huh?

14:22 , (->> (ns-map *ns*) vals (map meta) (filter :src))

14:22 clojurebot: ()

14:22 Bronsa: , (->> (ns-map *ns*) vals (map meta) (filter :source))

14:22 clojurebot: ()

14:22 arrdem: apparently I'm confusing Grimoire implementation details and clojure.core

14:22 I'll just go gibber in the corner

14:23 mi6x3m: arrdem: the function you are looking for is clojure.repl/source probably

14:23 Bronsa: tools.reader adds a :source key

14:23 (if you use the indexing reader)

14:25 arrdem: mdrogalis: still hanging in there

14:25 mdrogalis: arrdem: I share your discomfort.

15:00 ed-g: hello everyone. I'm having a heck of time setting up my new Emacs 24.3.1 to use cider 0.8.0 with my new clojure 1.6.0 project. it keeps telling me that "WARNING: CIDER's version (0.8.0-snapshot) does not match cider-nrepl's version (not installed)" but I can't figure out how to install cider-nrepl, it's not in MELPA.

15:01 rweir: did you remove all the nrpel stuff

15:02 cbp: ed-g: cider-nrepl is a clojure repo, not emacs

15:02 maybe you have an outdated version in your profiles.clj and forgot about it

15:02 or if it says not installed i guess you have to install it

15:03 in your profiles.clj in :plugins [cider/cider-nrepl "0.8.0-SNAPSHOT"] or something

15:03 ed-g: rweir: yes I have

15:04 cbp: ahh, it looks like cider-nrepl 0.8.0-snapshot does not exist. will try with 0.7.0

15:06 justin_smith: ed-g: I would use the 0.7.0 version of both cider and the cider middleware - but I haven't been brave enough to try to upgrade yet

15:07 ed-g: cpb: thanks, it all makes sense now ;-)

15:07 justin_smith: ok, i'll try living on the edge and see how I fare

15:12 bbloom: cemerick: did something change recently with nrepl? suddenly today i noticed that https://github.com/greglook/whidbey is showing results in double quotes....

15:25 grisevg: Sorry to bother you guys with a simple question. I'm trying to read variable "mytest" from config https://github.com/grisevg/refheap/blob/dev_tmp/src/refheap/views/paste.clj#L35 but I can't figure out what i'm doing wrong. Config loader: https://github.com/grisevg/refheap/blob/dev_tmp/src/refheap/config.clj Config itself: https://github.com/grisevg/refheap/blob/dev_tmp/config.clj

15:26 hiredman: grisevg: pastebin the stacktrace?

15:27 grisevg: my guess is however your are packaging and running the app it cannot find the config file

15:29 grisevg: hiredman: I run it with leiningen ring. There is no errors in console/ring. I'm thinking this is how I'm supposed to access the config https://github.com/Raynes/refheap/blob/4f6fe9ada70b0663935dd6cbc9fcfaaea76d997f/src/refheap/models/login.clj#L50. You think it fails to load file?

15:30 trevorlandau: Does anyone know where the slides are for this prezzo from Rich Hickey? http://vimeo.com/100518968 Implementation details of core.async Channels

15:30 hiredman: grisevg: yeah, I dunno what clj-configs behaviour is then, it may jsut return an empty map

15:30 justin_smith: grisevg: can you slurp the file?

15:30 grisevg: does (.getCanonicalPath (java.io.File. ".")) return the directory you expect?

15:31 cemerick: bbloom: 0.2.4 went out recently, but nothing that would affect printing of values IIRC.

15:31 bbloom: cemerick: i realized that it's caused by adding cider-nrepl 0.7.0 to my profile

15:32 cemerick: bbloom: sounds good to me ;-)

15:33 bbloom: cemerick: i realize that you prefer when it's somebody elses problem, but you're one of my favorite people to ask to fix things while i sit on my ass and do nothing

15:33 :-)

15:33 cemerick: heh

15:33 I'm largely out of that business, at least for the foreseeable future

15:33 The yaks will run free and shaggy

15:33 hiredman: wasn't renaming nrepl.el supposed to cut down on that kind of thing?

15:34 grisevg: hiredman: justin_smith: ok, clearly my clojure knowledge is not good enough to answer the questions, but thanks for your help guys. I was hoping it's something simple.

15:34 justin_smith: grisevg: I pasted code you can run

15:34 grisevg: and slurp is literally like this: (slurp "config.clj")

15:35 or whatever the file name was

15:35 grisevg: justin_smith: yeah I tried, but it doesn't print anything in the console. I guess it's because it's running through "ring"

15:36 justin_smith: grisevg: well, if you aren't in a repl, it won't print anything unless you print it

15:36 (println (slurp "config.clj"))

15:36 if that fails, (println (.getCanonicalPath (java.io.File. ".")))

15:36 you can run either of those wherever you are loading the config

15:37 grisevg: justin_smith: oh sweet, it works. Prints the file.

15:37 justin_smith: OK, so that eliminates one potential point of failure

15:37 grisevg: justin_smith: is that a correct way to read a property? https://github.com/grisevg/refheap/blob/dev_tmp/src/refheap/views/paste.clj#L35

15:41 justin_smith: grisevg: if config.clj has something like :mytest "language" in it, that looks abot right

15:43 schmee: can someone help me extract the similarities between these two functions? https://gist.github.com/schmee/b60bb0285a3773f3c683

15:43 justin_smith: grisevg: but it would probably be more helpful to see a paste of some of your code, instead of someone else's (presumably working) code

15:43 schmee: they're almost the same, but the extra argument to f in the first function is throwing me off

15:43 hiredman: justin_smith: he is trying to run refheap

15:44 grisevg: justin_smith: I forked the repo and pushed the code https://github.com/grisevg/refheap/tree/dev_tmp

15:45 justin_smith: grisevg: OK, then if old doesn't have a :language key, or the session doesn't have a :last-lang, then "Clojure" should be the value that comes through

15:46 grisevg: justin_smith: yeah, but when I run it, it's "Python" that gets through =/

15:47 justin_smith: and are you sure that "Python" is not coming from :language or :last-lang ?

15:47 grisevg: justin_smith: yes... if I change it to "PHP" or any other, it changes

15:48 justin_smith: is import correct - https://github.com/grisevg/refheap/commit/40445a4602cc0cf532212770a6ae8955c75804fd#diff-afbf3ad3fac423146695e989f1a948f8R3 ?

15:49 justin_smith: or do I need to run/initialise the config ?

15:49 justin_smith: grisevg: yeah, all that looks right. Note that config is only loaded from the file once, when the refheap.config ns is first loaded

15:49 https://github.com/grisevg/refheap/blob/master/src/refheap/config.clj

15:50 config is defined when the ns is loaded, based on the contents of that file

15:52 grisevg: justin_smith: thank you! all i had to do is restart server.

15:52 justin_smith: I realise it's a bit selfish to ask for help with little understanding of the language myself. thank you a lot.

15:53 justin_smith: once again "have you tried turning it off and then off again?" would have made the whole thing so much simpler

15:53 grisevg: justin_smith: :D

15:53 justin_smith: I'm used to the fact that python/ruby servers run every single time without caching stuff like that in memory

15:58 justin_smith: oh - so a new one gets spawned for each request or something?

15:59 amalloy: justin_smith: that's pretty common for python/ruby/php. a new interpreter instance for each request

15:59 justin_smith: I guess you would need a saner language for something like a pool to be reliable

16:08 arrdem: mdrogalis: ambrosebs has apparently heard

16:08 mdrogalis: arrdem: Ooo

16:09 arrdem: so emails are en route somewhere

16:10 mdrogalis: Im out. Booo

16:10 Good luck arrdem!

16:10 arrdem: cheers! I fully expect to join the pitty party in a minute

16:11 mdrogalis: Hah

16:12 ambrosebs: yep count me out too

16:12 mdrogalis: "No one is speaking this year!"

16:15 * arrdem irritated that clojure-conj.org/schedule is still unnamed

16:18 bridgethillyer: My money says arrdem is a yes

16:19 mdrogalis: Si. He's held out so long.

16:19 bridgethillyer: Big money for you?

16:19 SegFaultAX: Talks being accepted?

16:19 bridgethillyer: mdrogalis: :)

16:19 SegFaultAX: Is that what you guys are talking about?

16:19 mdrogalis: bridgethillyer: Awww yis. Congrats :)

16:20 SegFaultAX: Yeah

16:20 bridgethillyer: mdrogalis: Oh, no

16:20 ambrosebs: bridgethillyer: congrats!

16:20 bridgethillyer: mdrogalis: I have not heard yet

16:20 ambrosebs: oh :)

16:20 mdrogalis: Oh, heh.

16:20 bridgethillyer: mdrogalis: But I also haven’t been rejected yet!

16:20 ambrosebs: haha

16:20 mdrogalis: I'm just gonna start the rumor that you got in. If not, you can just show up and say you were misinformed.

16:20 melipone_: TimMc: I found a solution

16:21 justin_smith: I found a solution

16:21 SegFaultAX: bridgethillyer: What was your proposal?

16:21 bridgethillyer: mdrogalis: lol.

16:21 melipone_: TimMc: The problem was that *out* in the repl is not the same as System.out in java

16:21 SegFaultAX: Or, what *is* your proposal, since it's not yet confirmed.

16:22 justin_smith: meliponeso what was the solution?

16:22 melipone_: TimMc: I just used System/setOut in a macro so that I restore it when I'm done

16:22 mdrogalis: "Immutable State is for the Weak" #rejectedconjtalks

16:22 melipone_: justin_smith: The problem was that *out* in the repl is not the same as System.out in java

16:22 SegFaultAX: mdrogalis: Was that yours?

16:23 justin_smith: melipone_: well not always, at least

16:23 melipone_: justin_smith: I just used System/setOut in a macro so that I restore it when I'm done. Phewwww

16:23 bridgethillyer: SegFaultAX: I did two

16:23 mdrogalis: SegFaultAX: Deep dive on a platform I'm open sourcing soon.

16:23 bridgethillyer: SegFaultAX: data exploration with Clojure as that is what I am working on atm

16:23 melipone_: justin_smith: the repl does show two different print streams

16:24 justin_smith: mdrogalis: "process level concurrency for fun and profit"

16:24 amalloy: reiddraper: do you know if anyone's written test.check generators for Thrift objects? seems like they have enough metadata that you could do it without a ton of effort

16:25 mdrogalis: "Installing the JRE - the Hard Way"

16:25 justin_smith: bridgethillyer: arrdem: mdrogalis: they should use puffs of smoke like they do when selecting a pope

16:25 reiddraper: amalloy: i dont' know, but agree it probably shouldn't be too difficult

16:25 bridgethillyer: justin_smith: That’s what will happen when Rich Hickey passes and a new Clojure pope must be elected

16:26 justin_smith: mdrogalis: "evolutionary algorithms via inconsistencies in randomized configuration of deploy environments"

16:26 mdrogalis: I think we can start our own worst-conference-ever

16:28 tbaldridge: mdrogalis: there are some who would like to start a conference filled with people speaking about tech that you should never use.

16:28 justin_smith: "arrogant evangelism, foul-mouthed mysogyny, blatant racism: pick two -- protecting your programming community from outsiders"

16:28 tbaldridge: the problem would be finding speakers willing to show up.....

16:28 mdrogalis: tbaldridge: Hah, yeah. Tough sell.

16:28 bridgethillyer: justin_smith: Ha! I could totally give that talk

16:34 technomancy: I attended a "terrible ideas you should never do" talk at a rubyconf once and it was amazing

16:34 mdrogalis: technomancy: Was it related to Ruby, or just in general?

16:34 technomancy: http://www.zenspider.com/presentations/2009-rubyconf.html

16:34 ruby-specific

16:34 mdrogalis: I think I could do an hour on the general side, for sure

16:40 technomancy: I think my "catch all the things" post from yesterday may have been subconsciously inspired by https://rubygems.org/gems/neversaydie

16:40 shanemhansen: wow. There are so many jokes to be had with a talk named "terrible ideas you should never do" at a ruby conference.

16:40 technomancy: "NEVER SAY DIE lets you rescue from segmentation faults. Got a SEGV, don't worry about it anymore! Just rescue an exception and get on with life. Who cares about getting a SEGV anyway? It's just memory. I mean, when I was in school, I didn't need 100% to pass the class. Why should your memory need to be 100% correct to get the job done? A little memory corruption here and there doesn't hurt anyone."

16:40 mdrogalis: bridgethillyer arrdem: Have you heard of anyone getting in yet? :P

16:41 bridgethillyer: mdrogalis: Yep. A few

16:42 mdrogalis: bridgethillyer: :)

16:42 arrdem: mdrogalis: ambrosebs: not talking

16:42 ambrosebs: bl

16:42 arrdem: bridgethillyer: congrats!

16:43 bridgethillyer: arrdem: Ha ha I did not say that I got accepted

16:43 arrdem: o

16:44 mdrogalis: bridgethillyer: My plan in action right there ^

16:44 Just show up. Trust me.

16:44 bridgethillyer: Take a look at Twitter - a few people have said they are speaking

16:44 mdrogalis: Ha haha

16:44 arrdem: (inc justin_smith)

16:44 lazybot: ⇒ 68

16:45 bridgethillyer: mdrogalis: I could totally pull it off. Just get up on stage whenever… hmmm… whose spot should I take?

16:46 mdrogalis: bridgethillyer: "What? You don't see my name on the schedule? But, but. Check Twitter. -Everyone- says it's my turn."

16:46 Tweeted by hundreds of users named asdf2837587

16:46 bridgethillyer: good stuff

16:46 technomancy: someone's bound to not be able to make it

16:47 arrdem: twitter based conference scheduling... interesting idea

16:52 * zacht is playing Gerald Sussman videos in the background, you know, to relax.

16:53 dagda1_: is there anyway I can use apply with take....I'm trying to do (apply take 3 (range 10)) but obviously that is not right

16:54 amalloy: dagda1_: you just want (take 3 (range 10))

16:54 dagda1_: amally I want the list split into 3 groups of 3

16:55 amalloy: &(partition-all 3 (range 10))

16:55 lazybot: ⇒ ((0 1 2) (3 4 5) (6 7 8) (9))

16:55 amalloy: take is not really relevant to your goal; trying to use apply with it doesn't make sense

16:56 dagda1_: amally: I mean, I want ((0 1 2) (3 4 5) (6 7 8) (9)) is this possible with apply or what could I use

16:57 amalloy: i literally just showed you an expression that evaluates to that. also, your irc client will surely tab-complete usernames

17:00 dagda1_: amalloy: I'll never understand why people need to give responses like that. Don't answer if it annoys you

17:00 justin_smith: dagda1_: he answered your question already, it's fair to point that out

17:01 &(partition-all 3 (range 10)) ; dagda1_ this has the result you wanted

17:01 lazybot: ⇒ ((0 1 2) (3 4 5) (6 7 8) (9))

17:01 rhg135: ,(take 3 (-> (range 10) (partition-all 3)))

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

17:02 rhg135: meh

17:02 my clojure is weak today

17:03 justin_smith: ,(take 3 (->> (range 10) (partition-all 3)))

17:03 clojurebot: ((0 1 2) (3 4 5) (6 7 8))

17:03 justin_smith: which is the same as partition would have returned

17:07 kzar: Best library for outputting some XML from some EDN in Clojure?

17:07 TimMc: technomancy: Have you looked at the Maltron keyboard layout? (Their custom alternative to qwerty and dvorak.)

17:08 kzar: (Nothing fancy required)

17:12 technomancy: TimMc: haven't looked at it, no

17:15 TimMc: technomancy: http://maltron.com//images/stories/layout_diagrams-current/USA/3D%2090/DM11N2X-US_Issue%20A.jpg

17:16 technomancy: wild

17:16 if I were starting from scratch I'd probably go the colemak route

17:16 dgleeson: hello all. I'm trying to rig my ring app up to an authentication service that requires me to use the java interopt. The problem is that I need direct access to the HttpServletRequest. Is there a way to do this inside compojure?

17:16 technomancy: I'm on dvorak now, but afaik colemak is less work to learn without being less effective.

17:17 TimMc: Their idea is to have the most-used keys on the home row.

17:18 justin_smith: dgleeson: this is something that would be in the ring api, not in compojure, if it exists

17:18 amalloy: it's probably in the ring request map somewhere

17:19 technomancy: TimMc: yeah, dvorak and colemak shoot for that too

17:19 justin_smith: dgleeson: http://mmcgrana.github.io/ring/ring.util.servlet.html this looks promising

17:19 technomancy: there are so many things you can optimize for with a layout; it's boggling

17:20 TimMc: I think basically as long as you get off qwerty you quickly get into the land of diminishing returns though.

17:20 TimMc: heh

17:20 mdrogalis: bridgethillyer & arrdem: Thought of another gem. "What Clojure can learn from PHP"

17:21 dgleeson: I think this is what I ended up really needing :) http://stackoverflow.com/questions/2806548/using-a-javax-servlet-filter-with-compojure

17:21 thanks justin_smith!

17:22 justin_smith: no problem - though it looks like you found that on your own

17:26 technomancy: TimMc: I read about someone who tracked his every keystroke and re-optimized his layout every week to reduce finger travel.

17:26 justin_smith: as opposed to the rest of us, that keep the same layout for a lifetime to reduce cognitive load

17:28 amalloy: i discovered recently that i usually hit the spacebacr with my right index finger, not with a thumb as i assumed

17:30 bridgethillyer: mdrogalis: I think that is a totally valid proposal

17:30 TimMc: technomancy: Madness.

17:31 I'm surprised it would change much, anyhow.

17:32 technomancy: TimMc: https://xkcd.com/1095/

17:32 mdrogalis: bridgethillyer: I sort of realized that a minute later. I definitely didn't intend for it to be at useful. :P

17:34 grisevg: I have a friend, who never uses "Shift" key. He toggles "CapsLock" instead, every time, even for a single letter.

17:35 zacht: grisevg: head asplode

17:35 amalloy: grisevg: how does he type ?

17:35 grisevg: he's a developer :D just toggles capslock all the time

17:35 amalloy: no, i mean the character '?'

17:36 mdrogalis: Heh

17:36 tuft: i'm slowly tracking towards using my DataHand, which will hopefully make layout irrelevant =)

17:36 grisevg: that's a good question... i'll take a look next time he's around :D

17:36 tuft: today's task is to eliminate function key usage, as they're a pain on the DH

17:37 technomancy: tuft: oooh how long have you had that?

17:37 TimMc: give me give me give me

17:37 arrdem: hyPiRion: so... what HDL was your Lisp FPGA in?

17:37 tuft: technomancy: months but haven't gotten fast on it yet

17:37 TimMc: I only learned aobut it today and alreayd I want it so bad.

17:37 technomancy: I only use function keys for controlling music, so I usually just use the internal kbd for that

17:37 tuft: technomancy: been on the kinesis contour keyboards for years, and lately i'm training on DH, identifying what needs to change, and rebinding the kinesis to move towards it

17:38 amalloy: datahand looks like an incredible amount of work

17:38 TimMc: tuft: Did you see someone is working on developing a replacement?

17:38 tuft: TimMc: no that's awesome -- where?

17:38 technomancy: the design doesn't seem very amenable to hobbyist hacking

17:38 TimMc: tuft: http://geekhack.org/index.php?topic=41422.0

17:39 And the thing was released in like... 1995, so maybe the patents will have run out?

17:39 tuft: sweet

17:39 yeah, last i heard they were still trying to find a manufacturer

17:40 TimMc: I hope they fix the "doesn't work in bright light" problem. :-P

17:40 tuft: i guess they're hard to machine up for

17:40 haha i hadn't heard about that, makes sense

17:40 technomancy: oh wow, it's the ergodox guy

17:40 tuft: i want a datahand injection molded to casts of my hands

17:41 finger dangle isn't quite perfect on any setting

17:41 settings are kinda hackish anyway

17:41 technomancy: or he's helping out at least

17:51 verma: I have structure like this: {:parts [{:stuff "hello" :parts [{:more-stuff "hello"}]}]}, how can I get all the parts flattened out from this recursive structure?

17:52 hiredman: (doc tree-seq)

17:52 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."

17:52 verma: hiredman, nice, checking

17:54 that function is making my head spin

17:55 ok, think I get it a little bit may be, caffiene overdrive is not helping

17:57 rhg135: ,(tree-seq :parts (comp seq :parts) {:parts [{:stuff "hello" :parts [{:more-stuff "hello"}]}]})

17:57 clojurebot: ({:parts [{:stuff "hello", :parts [{:more-stuff "hello"}]}]} {:stuff "hello", :parts [{:more-stuff "hello"}]} {:more-stuff "hello"})

17:58 rhg135: thats a start

17:59 ,(filter seq? (tree-seq :parts (comp seq :parts) {:parts [{:stuff "hello" :parts [{:more-stuff "hello"}]}]}))

17:59 clojurebot: ()

18:01 verma: thanks rhg135 I feel I am getting it

18:06 zenspider: hiya. helping a friend. is there a built-in or packaged clojure equiv to xexprs? google is falling short

18:06 mostly pointing to irc logs, actually :)

18:07 something like xexpr->xml or somesuch

18:07 justin_smith: zenspider: you mean this kind of xexpr? http://www.w3.org/TR/xexpr/

18:08 zenspider: hah! ew. no. I didn't even know that existed.

18:08 xml <-> xexp <-> sexp

18:08 justin_smith: we have clojure.data.xml for getting edn out of xml

18:09 zenspider: here's a racket example, afaik, almost every lisp has some equiv: http://rosettacode.org/wiki/XML/Output#Racket

18:10 the clojure example ... prolly my lack of clojure reading skills

18:10 http://rosettacode.org/wiki/XML/Output#Clojure

18:10 doesn't look equivalent, but it might be?

18:10 justin_smith: zenspider: https://github.com/clojure/data.xml check some of the examples here

18:10 TimMc: justin_smith: OMG that had better be an April Fools post...

18:11 justin_smith: TimMc: inorite

18:11 zenspider: yeah, that is equivalent - it's turning standard clojure data literals into xml

18:12 zenspider: ok. I'm just not experienced in clojure literals I guess

18:12 amalloy: justin_smith, TimMc: it says right there that this is not endorsed by the w3c, just being published by them as an acknowledgement that someone sent them this note

18:12 zenspider: justin_smith: that url is perfect. thanks.

18:13 justin_smith: it's actually more fluent than the racket example, since we have associative literals that map nicely to tag / value in xml

18:17 TimMc: amalloy: Phew.

18:18 I'm used to "Status of This Document" just saying "this is a work in progress forever".

18:18 justin_smith: TimMc: just think how much better macros would be if they were all done in the form of xml transforms

18:20 hyPiRion: arrdem: VHDL

18:20 arrdem: http://hypirion.com/pdf/igor.pdf

18:20 I didn't do anything on that project though

18:35 arrdem: hyPiRion: hum okay thanks I'll check it out.

18:36 picking up Verilog in the next few days for a class.

18:46 hyPiRion: aha

18:49 Try to get in some lisp for me and I'll be happy

18:49 I was unable to =(

18:51 adereth: technomancy: I haven't had access to my hackerspace since I moved a couple months ago, but I'm still committed to completing the keyboard I modeled in Clojure

18:53 Matt Gauger has made some progress building his own single hand chording keyboard in Clojure using my dactyl library

18:54 technomancy: adereth: awesome. you have free access to a 3D printer, right?

18:54 seems like that makes experimenting with case layout a lot more practical

18:54 adereth: I did, but don't for now. Should have it back in a month.

18:54 Yeah, I'm kinda stuck without it.

18:54 technomancy: when you're paying for time, a 3D printer is way too expensive vs a laser

18:55 adereth: Agreed. I was shocked at the rates the Makerbot store was charging.

18:56 https://github.com/adereth/dactyl if anyone wants to play with it

18:57 technomancy: adereth: you're still hand-wiring everything, right?

18:57 oh right; with the curved design that's the only option =)

18:57 adereth: Yes. It's nuts.

18:57 technomancy: it's not so bad with only 21 switches per side =)

18:58 do you have any photos of the matrix?

18:58 adereth: Yeah, not too bad. Also, with some refactoring, I was able to easily print a few nice utility pieces for doing the wiring.

18:58 beamso: is it difficult to get used to the control keys being along the bottom of the keyboard?

18:59 adereth: https://twitter.com/adereth/status/463810293705883648/photo/1

18:59 technomancy: adereth: cutting these is the worst part ime http://p.hagelb.org/stripped.jpg

18:59 (sfw)

18:59 adereth: https://twitter.com/adereth/status/460903377409675265/photo/1

18:59 technomancy: cool

19:00 beamso: it really doesn't take long

19:00 adereth: Yes, that looks very familiar :p

19:00 technomancy: beamso: you get used to that part a lot faster than the columnar layout

19:00 adereth: man, all those primary colors makes it look like a google office or something

19:01 adereth: I used the colors nobody else was interested in. Figured I'm going to spray paint or plastidip the whole thing at the end anyway.

19:02 technomancy: adereth: I haven't fired up any CAD myself, but I might do it soon in order to support matias switches alongside cherry.

19:02 but that's a pretty simple modification to the current design

19:04 adereth: My dream is to have the design fully parameterized to the point that someone could enter the dimensions of their hand and get a custom keyboard STL or SVG. Switch style as another parameter.

19:04 Obviously leading to KaaS.

19:04 SegFaultAX: Like cars that adjust the seats and mirrors based on who is driving?

19:05 technomancy: haha nice

19:05 yeah, I'm always on the go, so I've gotta optimize for portability and sturdiness.

19:05 wei: transit question. trying to serialize a #uuid and get Uncaught Error: Cannot write. do I have to add that type somehow?

19:05 technomancy: but that'd be pretty sweet for a desk setup

19:06 SegFaultAX: Makes me think of the cars from Demolition Man.

19:06 c3w: if you regularly pair programmed with someone, with one of you taking the right-hand keys and the other taking the left-hand keys, you could finally have an ergonomic solution

19:07 technomancy: TimMc: you saw adereth's design, right?

19:08 SegFaultAX: adereth: Your dream is already a reality for mice, basically. Check out the R.A.T. 9

19:08 Fully configurable gaming mouse.

19:09 adereth: That's nuts. I wasn't going for anything adjustable. You enter the parameters and get a design that can be printed or laser cut for you.

19:10 technomancy: adereth: you can't laser-cut a curved design like that though, can you?

19:11 adereth: I have two approaches that I've tried. One is to do it layered, which gets you different heights, but not all the right angles.

19:11 The other is to cut pieces that are meant to be heated and bent.

19:11 Along with stencils for cutting out jigs that let you do the bending precisely.

19:11 technomancy: hm; interesting

19:12 I could you do the jigs in acrylic too, or would it need more heat-resistance?

19:12 adereth: That was what I used the analemma library for. I started with Inkscape then moved to clojure.

19:12 I was going to go with wood.

19:12 technomancy: huh

19:12 SegFaultAX: That second one seems neat, but impractically difficult to automate, no?

19:12 technomancy: I still <3 laser-cut wood for the case material

19:12 adereth: Yes, no automation here. It would be a kit.

19:12 technomancy: I keep building these wooden boards and sending them out, and feeling mildly jealous

19:13 SegFaultAX: I mean automating the design based on your specifications to get an SVG or whatever.

19:14 adereth: I don't think so, but I may be missing something or making some simplifying assumptions that I'm not communicating.

19:15 A lot of trig, but it all becomes possible when you have accurate measurements of everything.

19:17 For instance, the model I have for this: https://twitter.com/adereth/status/472380239881175040/photo/1

19:17 technomancy: adereth: is the distance of the thumb cluster similar to the ergodox?

19:18 adereth: The parameters are things like how much to offset the columns for each finger in Y and Z, what the spacing should be vertically and horizontally, what the overall angle should be.

19:18 technomancy: looks like a bit of a stretch from the photos

19:18 elarson_: is there a way to create a map from a sequence using for?

19:18 technomancy: elarson_: no, for is lazy

19:18 adereth: Those versions were spaced too far. Don't have photos of the tighter versions, but yes.

19:18 technomancy: you have to (into {} (for ...))

19:19 elarson_: technomancy: ah ok. I didn't realize it was lazy. that is very helpful, thanks!

19:22 is thera simple way to time an operation in the repl?

19:23 *is there a

19:23 ah (time $exp) worked

19:23 justin_smith: elarson_: for better microbenchmarking, there is also criterium

19:40 sabernethy: Follow up question to elarson_'s ... Is there a shortcut way to turn a sequence 'as' into a lookup map where the key is generated by 'f' ? I find myself doing (into {} (map (juxt f identity) as) a lot

19:41 *an existing shortcut

19:42 amalloy: sabernethy: if you write that a lot, make it a function

19:42 sabernethy: :) after I wrote the question I knew I was going to get that answer.

19:42 amalloy: ok. thx. :)

19:43 hiredman: have you seen group-by?

19:45 justin_smith: yeah, that looks exactly like group-by

19:45 amalloy: it's not *exactly* group-by

19:46 group-by gives you a map whose values are lists

19:46 justin_smith: yeah - it will replace rather than vectoring keys

19:46 sabernethy: hiredman: yeah. but. when the grouping function returns a single item for the whole seq... i don't want the map val to be nested in a seq

19:46 justin_smith: sabernethy: having two different kinds of return types increases the complexity of every caller of the code

19:46 and has very few if any advantages

19:48 * tuft is so sick of doing integrations.

19:48 tuft: .. and not the calculus kind

19:48 turbofail: it'd be something like index_by from rails activesupport

19:48 which replaces instead of vectoring

19:48 sabernethy: justin_smith: i lost you, sorry. do you mean that group-by shouldn't have two return types... i wasn't asking for that.

19:49 turbofail: yeah exactly like that

19:49 i just wondered if it was in core and i'd missed it

19:49 justin_smith: sabernethy: you said "when the grouping function returns a single item for the whole seq... i don't want the map val to be nested in a seq" - I took that to mean you wanted individual values under some keys, seqs under others

19:50 turbofail: anyway i don't think there is any shortcut like that in core

19:50 justin_smith: I think I misinterpreted you

19:50 sabernethy: justin_smith: ok. no. no problems. :)

19:50 justin_smith: ,(map (fn [[k v]] [k (pop v)]) (group-by int "hello world!"))

19:50 sabernethy: turbofail: ok. now i know what to call my custom implementation though, thx.

19:50 clojurebot: ([101 []] [119 []] [104 []] [32 []] [108 [\l \l]] ...)

19:50 justin_smith: ,(into {} (map (fn [[k v]] [k (pop v)]) (group-by int "hello world!")))

19:50 clojurebot: {101 [], 119 [], 104 [], 32 [], 108 [\l \l], ...}

19:51 justin_smith: oops

19:51 ,(into {} (map (fn [[k v]] [k (peek v)]) (group-by int "hello world!")))

19:51 clojurebot: {101 \e, 119 \w, 104 \h, 32 \space, 108 \l, ...}

19:51 justin_smith: or you could just look at the source of group-by - it's a 6 line reduce

19:53 sabernethy: i think i'll stick with (defn index-by [f as] (into {} (map (juxt f identity) as))

19:59 numberten: what's the idiomatic way of adding an optional keyword option at the end of a function, like (foo x y :bar true)

20:00 amalloy: numberten: don't do it, just take an optional map argument: (foo x y {:bar true})

20:00 numberten: but that doesn't look as pretty :(

20:00 rhg135: what i've done is to just have a map argument

20:00 and a optional mapless variety

20:01 amalloy: numberten: the freefloating keyword args look prettier until you smash your monitor in rage because it makes your function hard to work with

20:01 numberten: haha

20:01 fair enough :)

20:09 elarson_: I wrote some code to parse cache control headers and I'm curious if there are any obvious improvements: https://www.refheap.com/89560 I'm just learning clojure and would love any tips

20:13 amalloy: elarson_: that is a lot of calls to map - there's gotta be a clearer way

20:13 bbloom: elarson_: probably worth learning about ->, ->>, and for

20:13 amalloy: i also don't understand what (nth entry 1 1) is supposed to be about

20:14 bbloom: i'm rewriting it; i bet i end up using for but not any arrows

20:14 elarson_: bbloom: I'll take a look, thanks!

20:16 amalloy: the nth call grabs the nth item in the list and allows setting a default. so in this case if you get a string like "public, max-age=60" you'd get a vector that looks like {:public 1, :max-age "60"}

20:16 amalloy: okay, i knew that's what it did, i was just surprised that 1 was a good default

20:16 thought you might be misusing it

20:16 bbloom: is that an http spec thing? or maybe you want a boolean?

20:17 amalloy: elarson_: https://www.refheap.com/afc396efc83810a16084c62d1 is a fairly boring rewrite

20:17 a and b are obviously bad names, but i don't know what to call them since you didn't give them names

20:18 elarson_: amalloy: ah, so if you do a for on a list and the item doesn't have enough values to fill in the arguments, it will just use nil?

20:18 * elarson_ is coming from python so that would throw an exception

20:19 amalloy: elarson_: no, you're not understanding what destructuring on a list does

20:19 (for [[x y] [1 2 3 4]] ...) is an error, because the elements of the list are numbers, not pairs

20:19 for always goes over a list exactly one item at a time

20:20 (for [[x y] [[1 2] [3 4]]] ...) would be okay

20:20 bbloom: elarson: is that 1 just supposed to be something truthy? in clojure, only false and nil are logical false

20:20 amalloy: oh, you mean if you destructure a list

20:20 bbloom: ,(boolean 0)

20:20 clojurebot: true

20:20 amalloy: yes, that is true

20:21 elarson: bbloom: I'm porting some code I wrote in python that used a 1, but yes, a boolean is the better choice.

20:21 justin_smith: elarson: another option is a keyword describing what that value means

20:21 which would be both truthy and informative

20:22 bbloom: justin_smith: iirc the cache control header has a number of flags that may or may not be present

20:23 justin_smith: bbloom: in that case, :present is a more informative value than 1 is

20:23 or maybe :provided

20:24 bbloom: justin_smith: meh

20:24 i appreciate the concern about boolean blindness, but it seems perfectly reasonable here

20:26 justin_smith: bbloom: I only suggested it because at least one intelligent person read the code and didn't intuit what "1" meant there, or its significance as a default

20:27 bbloom: amalloy: would you have been confused if it were `true` instead of `1` ?

20:27 lodin: Is there any way to unload a class/type once created via deftype?

20:27 amalloy: no. i was confused because the 1 was right next to another 1, and it looked like he was trying to do some sort of 2d indexing

20:27 or possibly just typed too excitedly!!1

20:52 danielszmulewicz: OK, after a month of hard work (as hard as it gets with computer work, not much), I've finished a prototype for a toy project. The purpose was twofold: do something fun, do something to experiment with the "immutable stack". The result is here: http://videos.tuppu.net/

20:53 You create playlists with youtube videos.

20:53 Mine is here: http://videos.tuppu.net/user/daniel.szmulewicz

20:54 Feel free to log in with a google account, and create your own videowall.

20:54 Feedback welcome, of course.

20:57 It has been fun to do, and it's interesting to see if it goes anywhere.

21:02 Lessons learnt: Om was great to work with. Core.async helps a lot on the client. Datomic was probably overkill.

21:08 mdeboard: danielgl_, Was it clojure front and back end

21:08 catern: n o i c e

21:10 danielszmulewicz: mdeboard: yes, the whole stack.

21:10 catern: thanks!

21:12 mdeboard: REST API with Liberator, messaging with Langohr (RabbitMQ), persistence with Datomic, Om and Sente on the client-side.

21:13 mdeboard: danielszmulewicz, how did you go about sorting how to organize your code

21:14 danielszmulewicz: mdeboard: trial and error. Lots of sweating, starting from scratch with a better design than the previous one.

21:15 mdeboard: reading projects by other people and assembling the pieces that made sense to me.

21:15 mdeboard: danielszmulewicz, Yeah that's a sore point in clj+cljs tooling IMO

21:15 danielszmulewicz: It's new territory.

21:19 mdeboard: Thing is there is a real payoff to persistence. But it's not obvious and the road can be painful.

21:20 mdeboard: Yeah well when I'm starting a new project I don't wanna have to wrestle with how I organize the files. I'm sure someone will come up with a template for it eventually

21:24 danielszmulewicz: mdeboard: One thing I had to unlearn was my tendency to split up files like in OO, one per class. With functional programming, it can be counterproductive to have many files with many different namespaces. Not necessary, actually. I had to learn how to use imenu in Emacs to navigate bigger namespaces.

21:24 mdeboard: oh was this your first clj project?

21:25 danielszmulewicz: mdeboard: no, but the first web project full Clojure stack.

21:25 mdeboard: cool

21:32 TimMc: technomancy: Thanks, I'll take a look at the design tomorrow. I think I'll just switch to dvorak for now. :-)

22:02 andrewchambers: anyone here played with llvm in clojure?

22:02 arrdem: $google halgari mjlinr llvm clojure

22:03 * arrdem smacks lazybot upside the head

22:03 justin_smith: $google halgari mjlinr llvm clojure

22:03 arrdem: https://github.com/halgari/mjolnir/

22:03 spelled it wrong anyway

22:04 justin_smith: clearly you have never played nethack

22:04 arrdem: this is true

22:10 andrewchambers: arrdem: yeah read abuot mjolnir

22:10 i wanted to convert llvm modules into an edn representation

22:10 and was just wondering if anyone else is interested

22:11 so its not using llvm, but allowing clojure to consume some compiler output in a friendly way

22:11 for analysis etc

22:11 arrdem: when would you ever be using Clojure as an analysis engine?

22:12 andrewchambers: umm, it has datalog and other things for running queries

22:12 When would you ever use C++ for doing this sort of work :/

22:13 what would you suggest then?

22:14 I even think core.logic might be interesting for prototyping whole program analysis

22:17 arrdem: eh. core.logic and other querying systems won't be able to add anything to a whole AST traversal unless you flatten your AST into some {id node} representation where nodes hold each-others ids and upon which you can do indexing (say node type etc)

22:17 andrewchambers: um

22:17 llvm is not an ast

22:17 its a flat assembly

22:18 e.g. x = add y z

22:19 which is exactly what you just described

22:19 ?X where instruction ?X and opcode ?X :add

22:19 or whatever.

22:20 ?X where Call ?X and Target ?X SQLVulnerable

22:20 etc etc

22:21 then you can add more advanced rules like

22:23 complex deductive rules on whether a value may have come from untrusted source

22:23 then query for possible buffer overflows based on that

22:24 arrdem: that's just taint analysis, which is a well known whole program closure fixed point operation. no need for a fancy logic engine here.

22:24 andrewchambers: The point is that it simplifies things for prototyping

22:25 sdegutis: Hi.

22:25 andrewchambers: arrdem: it also makes things much easier to compose

22:25 e.g. compose taint anaylsis with a bunch of other analysis would be easier in datalog queries than in C++ code

22:25 sdegutis: For a small web store that gets a max of 4k views per day, which does mostly reads but some writes, does using SQLite3 make sense?

22:26 andrewchambers: sdegutis: I think sqlite3 can handle that, it really depends on your code

22:26 sdegutis: Oh.

22:27 andrewchambers: You might be better off asking the sqlite people though, they answer that in the faq

22:28 sdegutis: "Generally speaking, any site that gets fewer than 100K hits/day should work fine with SQLite. The 100K hits/day figure is a conservative estimate, not a hard upper bound. SQLite has been demonstrated to work with 10 times that amount of traffic."

22:28 http://www.sqlite.org/whentouse.html

22:28 sdegutis: Ah I read that too.

22:28 Thanks :)

22:29 andrewchambers: I was trying to decide a similar thing myself

22:29 settings up an sqlserver vs just using sqlite

22:30 arrdem: Do you work on compilers at all?

22:31 or code anaylsis tools

22:31 arrdem: andrewchambers: long story short yes, but my llvm isn't especially strong.

22:32 http://github.com/oxlang/oxcart <- my summer project

22:32 andrewchambers: cool

22:32 how long did that take you?

22:33 arrdem: that's more or less my whole summer. I was a GSoC student.

22:33 andrewchambers: sweet

22:34 arrdem: http://arrdem.com/2014/08/05/of_oxen,_carts_and_ordering/ <- end of project results post

22:35 andrewchambers: Thats pretty cool

22:35 sdegutis: arrdem: neat

22:35 arrdem: it was a project but to be honest it's pretty trivial. All I really had to do was use set/reach set/taken as value analysis

22:36 *fun project

22:36 andrewchambers: you are just emitting java bytecode?

22:37 arrdem: yeah. I basically forked Bronsa's class AST emitter, customized it, and then used his class AST to bytecode transforms

22:37 http://github.com/clojure/tools.emitter.jvm/

22:37 where I left off I was forking clojure to try and purge RT.java and Compiler.java so that Oxcart programs could be entirely static

22:38 but that's where I started questioning the utility of the project for myself and kinda lost inertia.

22:38 andrewchambers: yeah

22:38 its easy to get burnt out

22:38 300+ commits is a good effor

22:38 t

22:39 I was just thinking of working on two projects

22:40 bacon198`: Hey, I was wondering why i'm not seeing the right output on this https://www.refheap.com/89566

22:40 andrewchambers: one is a compiler

22:40 bacon198`: I was expecting [10 20 Object], but it's [10 null Object]

22:40 andrewchambers: but not for a lisp or anyhting

22:40 bacon198`: (it's clojurescript)

22:44 arrdem: andrewchambers: if you're looking for a project and interested in language design I could use some help http://github.com/oxlang/oxlang :P

22:44 justin_smith: bacon198`: put your :as form in {} instead of []

22:48 ,((juxt (fn [& {:keys [a b] :or {a 10 b 20} :as more}] [a b more]) (fn [& {:keys [a b] :or [a 10 b 20] :as more}] [a b more])) :a 10)

22:48 clojurebot: [[10 20 {:a 10}] [10 nil {:a 10}]]

22:51 akj: hello! is there a function for seq that is equivalent to clojure.string/split? partition-by comes close but I wonder if there is something that works just the same as split

22:52 justin_smith: akj: what would qualify as "just the same as split" that partition-by does not do?

22:52 bacon198`: thanks justin_smith

22:53 akj: split does not return the character that is used to split with

22:57 compare (partition-by #(= % \-) '(\f \i \r \s \t \- \n \a \m \e)) with (partition-by #(= % \-) '(\f \i \r \s \t \- \n \a \m \e))

22:57 sorry, compare (partition-by #(= % \-) '(\f \i \r \s \t \- \n \a \m \e)) with (clojure.string/split "first-name" #"-" -1)

22:58 justin_smith: ,(letfn [(p [x] (zero? (mod x 3)))] (apply conj (reduce (fn [[coll sub] e] (if (p e) [(conj coll sub) []] [coll (conj sub e)])) [[][]] (range 10))))

22:58 clojurebot: [[] [1 2] [4 5] [7 8] []]

22:59 justin_smith: not quite it - but its a start

22:59 maybe wrap it in a (remove empty? ...)

23:04 akj: justin_smith: what was that looong line? Lol, I hope that wasn't addressed to me

23:06 ,:5

23:06 clojurebot: :5

23:09 justin_smith: akj: it's an expression that does what you want (almost)

23:09 though it would be better to have a lazy version - playing with that now

23:11 akj: justin_smith: would it make sense to alter the source for partition-by and create a new function

23:11 justin_smith: that leaves out the "separator"?

23:21 justin_smith: akj: yes - notice that there are no multiples of 3 in the output

23:21 though there are some empty vectors

23:23 ,(defn split-seq [pred coll] (remove #(pred (first %)) (partition-by pred coll)))

23:23 clojurebot: #'sandbox/split-seq

23:23 justin_smith: ,(split-seq #(zero? (mod % 3)) (range 10))

23:23 clojurebot: ((1 2) (4 5) (7 8))

23:23 justin_smith: akj: I think that's the better answer

23:24 akj: you could write a modified version of partition-by instead, of course

23:24 andrewchambers: lol, clojure and rust started similar times. Rust 30k + commits, clojure 2.5k commits

23:24 one is a production ready language

23:24 :P

23:24 though i guess its cheating since clojure didnt write the jvm

23:24 justin_smith: andrewchambers: very different development models

23:25 well the other doesn't use a vm does it?

23:25 andrewchambers: then again

23:25 rust uses llvm

23:25 which itself has 100k + commits

23:25 for its backend

23:26 It's not really a totally fair comparison, but its fun to think about

Logging service provided by n01se.net