#clojure log - Jul 26 2014

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

0:19 razum2um: why there is a clojure.lang.PersistentList$EmptyList and no clojure.lang.PersistentArrayMap$EmptyMap ?

0:20 bbloom: razum2um: both are / would-be implementation details

0:20 razum2um: why do PersistentArrayMap even exist? in source is written that "only appropriate for _very_small_ maps"

0:20 bbloom: ,(class {})

0:20 clojurebot: clojure.lang.PersistentArrayMap

0:20 benedikt: http://lpaste.net/4733493919461933056 # this wont work, but i swear it worked just a few minutes ago

0:20 bbloom: ,(class {:x 1 :y 2 :z 3})

0:20 clojurebot: clojure.lang.PersistentArrayMap

0:20 bbloom: ,(class {:x 1 :y 2 :z 3 :a 4 :b 5 :c 6 :d 7 :e 8})

0:20 clojurebot: clojure.lang.PersistentArrayMap

0:21 razum2um: bbloom: yep, still a small map?

0:21 bbloom: ,(class {:x 1 :y 2 :z 3 :a 4 :b 5 :c 6 :d 7 :e 8 :f 9 :g 10 :h 11 :asdf 123 :xxx 535835})

0:21 clojurebot: clojure.lang.PersistentHashMap

0:21 bbloom: razum2um: it's faster to do a linear scan of a small array than to bother hashing elements

0:21 once you get past a certain size, that stops being appropriate

0:21 razum2um: bbloom: I think it's strange to have different (but similar) classes based on size

0:22 bbloom: razum2um: it's not strange at all, it's half the reason for interfaces in the first place

0:22 (doc array-map) ; probably a design error that this exists

0:22 clojurebot: "([] [& keyvals]); Constructs an array-map. If any keys are equal, they are handled as if by repeated uses of assoc."

0:22 razum2um: bbloom: I see they implement the same

0:22 bbloom: just use hash-map

0:22 or the {...} notation

0:23 razum2um: it's about performance

0:23 but it's an implementation detail

0:24 razum2um: ok, but i think PersistentList$EmptyList is also for that reason, why not similar like PersistentHashMap$ArrayMap

0:24 bbloom: razum2um: no, it's an implementation detail

0:24 just write ()

0:24 razum2um: bbloom: ok then :S

0:24 bbloom: ,(class ())

0:24 clojurebot: clojure.lang.PersistentList$EmptyList

0:30 razum2um: bbloom: btw i see int HASHTABLE_THRESHOLD = 16 in source. it there any explanatin for that choice?

0:30 bbloom: razum2um: empirical testing

0:31 clojurescript sets that value lower: 8

0:31 blur3d: Hey guys, I’m trying to update an atom value, but it’s a nested hashmap, with a hashmap key, uses destructuring. It’s not as complex as it sounds, but I am trying to avoid having to use assoc-in and update-id together

0:31 bbloom: again, from measuring

0:31 blur3d: http://pastebin.com/V76nE8Nu

0:31 basically, is there a better way to write (swap! app-state assoc-in [:sensors] (update-in (:sensors @app-state) [{:kind :temperature :label-id 1}] conj [99.9 1]))

0:32 bbloom: blur3d: so you're right to be worried, but not about the assoc-in/update-in combo... should be worried when you see a @ and a swap! like that together

0:32 the point of a swap is that it's atomic, so when you read with @ you may get two inconsistent values (in a concurrent situtation)

0:32 blur3d: haha, yeah.. that was also concerning

0:33 if I can somehow use :sensors in the update-in destructuring, then it should be ok

0:33 bbloom: just use fn

0:34 blur3d: but I get an error trying to mix [:sensors {:kind :temperature :label-id 1}]

0:34 bbloom: (fn [{:keys [sensors]} ....)

0:34 (fn [{:keys [sensors]}] ....) ; imean

0:34 oh, huh? what error are you seeing?

0:35 blur3d: im not great with destructuring yet, so how would that fit in?

0:35 bbloom: (swap! app-state update-in [:sensors {:kind :temperature :label-id 1}] conj [99.9 1]))

0:35 that doesn't work?

0:35 blur3d: with something like this (swap! app-state update-in (:sensors @app-state) [:sensors {:kind :temperature :label-id 1}] conj [99.9 1])

0:36 UnsupportedOperationException nth not supported on this type: PersistentHashMap clojure.lang.RT.nthFrom (RT.java:857)

0:36 but obviosuly still as @ as well

0:36 bbloom: blur3d: re-read the doc strings for swap! and update-in

0:36 you're giving it bad arguments

0:36 (doc swap!)

0:36 clojurebot: "([atom f] [atom f x] [atom f x y] [atom f x y & ...]); Atomically swaps the value of atom to be: (apply f current-value-of-atom args). Note that f may be called multiple times, and thus should be free of side effects. Returns the value that was swapped in."

0:36 bbloom: (doc update-in)

0:36 clojurebot: "([m [k & ks] f & args]); 'Updates' a value in a nested associative structure, where ks is a sequence of keys and f is a function that will take the old value and any supplied args and return the new value, and returns a new nested structure. If any levels do not exist, hash-maps will be created."

0:38 bbloom: swap! and update-in play nice together usually, but two things here 1) when you're learning, get it right without state first, then add state as you need it

0:38 and 2) you generally want to keep your "thinking" and "acting" separate anyway

0:38 blur3d: replacing an atom value is fairly obvious, but I get tricked up over the updating part

0:38 ok

0:38 bbloom: (def an-app-state {:sensors ...}) ; no atom

0:38 and try update-in on that

0:39 let me know when you have that working

0:39 blur3d: I did play around with it a bit, but the hashmap has changed also

0:39 ok

0:47 bbloom: I think I got it all working for the simple case with an atom… thanks for your help

0:47 (def app2 (atom {:sensors {{:kind :temperature :label-id 1} [[21, 0]]}}))

0:47 (swap! app2 update-in [:sensors {:kind :temperature :label-id 1}] conj [1 1])

0:47 bbloom: blur3d: yup

0:47 blur3d: :)

0:47 bbloom: generally, it's a very good idea to have very few swap! calls

0:48 or at least if you have a whole bunch of swap! calls, they should use pure functions defined elsewhere

0:48 this way you can test the pure functions!

0:48 blur3d: this is for a clojurescript app, that will be sent data via websockets… so its for the app-state

0:48 ok, sounds good

2:39 razum2um: clojure is cool at metadata, which can be bound to functions too, but is there any way to get function's (anonymous) metadata inside the same function. e.g. own metadata?

2:56 Bronsa: razum2um: ##(^:foo (fn x [] (meta x)))

2:56 lazybot: ⇒ nil

2:56 Bronsa: wut

2:56 ,(^:foo (fn x [] (meta x)))

2:56 clojurebot: {:foo true}

2:56 Bronsa: oh well.

2:58 hiredman: what's with the 10 locals limit for hoisting?

3:04 allenj12__: hey does anyone here have experience using overtone? is there a recommended editor for it?

3:11 alexyakushev: allenj12__: I haven't used Overtone, but I suspect https://github.com/overtone/emacs-live is what you are looking for

6:22 Ro_: I have a general question, do not know where to ask.. How triplets relate to graph?

6:44 alexyakushev: So I am trying to AOT-compile Clojure sources using a slim JAR and I get this: https://www.refheap.com/88608

6:46 This happens when the compiler gets to gvec.clj:122, where print-method is defined for ::VecSeq

6:49 boxed: Ro_: triplets? graph?

6:49 Ro_: you might need to give some more context

8:10 Ro_: no context ;)

8:11 I was searching for an answer how does triples relate to graph, how can they be converted from one to another

8:12 is it possible to create hypergraph with tripplets

8:16 and etc.

8:44 katratxo: Ro_: e.g. http://www.snee.com/bobdc.blog/2014/01/storing-and-querying-rdf-in-ne.html

9:15 formaggio: hi 'veryone

9:53 john2x: question about Luminus. what is this `servlet-context` in the generated templates? they seem to be blank when running the dev server. Are these meant for production?

10:12 deathknight: What is a great recent tutorial that builds a web app?

10:16 boxed: “web app” is a bit vague… the readme on https://github.com/weavejester/compojure does a fairly good job at the basics

10:17 xeranas: hello, Clojure is new thing to me. I trying to find way to redefine static variables for test. But probably fail to understand concept. Here how I tried: https://gist.github.com/xeranas/2bb3fd9b1508448ffd76

10:18 Fare: xeranas, by the time you call B, it has already been evaluated

10:18 maybe you want (defn B [] A) instead?

10:24 xeranas: Fare: hmm, defn would do a trick. I probably should stick for defn while still learning

10:26 kandinski: hi, I'm new to clojure and emacs. I have installed cider following the instructions on braveclojure.org, but when I start the cider repl, I get this message: http://paste.ubuntu.com/7865976/ . Emacs packages do not include cider-nrepl. What am I doing wrong?

10:29 ProTip: Hi guys, I'm wanting to use rickshaw or d3js in a clojurescript project and I'm a bit confused on the current best way of doing this..

10:29 Do I need to generate and externs file?

10:33 deathknight: what is the name of "@" in clojure? having a hard time searching up what that means on google

10:34 i.e. (let [post @upcoming-post-queue] ...)

10:34 H4ns: deathknight: deref

10:35 deathknight: thank you h4ns

10:47 itruslove: kandinski: add the cider-nrepl plugin to your ~/.lein/profiles.clj - see https://github.com/clojure-emacs/cider-nrepl

10:49 kandinski: itruslove, thanks

10:56 ProTip: Is this the prefered way to create externs? https://gist.github.com/Chouser/5796967/download#

11:07 dnolen_: ProTip: https://github.com/federico-b/d3-externs

11:08 ProTip: you can sometimes use the library itself as the externs file, http://swannodette.github.io/2014/03/14/externs-got-you-down/

11:08 ProTip: if you only use a couple of functions, writing the externs file is pretty simple.

11:09 ProTip: thx :D

11:09 I've found out too that I can just use the library with the js explicitly loaded in the html page

12:22 reduced: Hey

12:22 Is anybody in there

12:28 sjouke: It's been awhile since I've looked at Clojure. IIRC, there was something about clojure which struck a chord with me: "a uniform API for accessing and manipulating data structures"

12:29 Is this correct, would someone be willing to give me a search term, so I can look further into it?

12:32 jeremyheiler: sjouke: have you read through http://clojure.org/data_structures ?

12:33 actually, this one: http://clojure.org/sequences

12:33 the sequence abstraction is what you're talking about

12:33 is what i think*

12:34 sjouke: jeremyheiler: i haven't, i'll take a look at both :)

12:34 reading the sequence one first of course, thanks jeremyheiler

12:34 jeremyheiler: np!

12:40 deathknight: how can I, in the REPL, (require ') a file called example.clj in ~/proj_dir/test/clj-facebook-graph/example.clj?

12:42 noidi: deathknight, http://grimoire.arrdem.com/1.6.0/clojure.core/load/

12:43 deathknight, http://grimoire.arrdem.com/1.6.0/clojure.core/load_DASH_file/

12:43 deathknight: Thank you noidi. Why does my computer lock up for about 10 seconds whenever someone mentions my name in the smuxi client?

12:47 sjouke: https://programmers.stackexchange.com/questions/214425/why-does-clojure-neglect-the-uniform-access-principle

12:48 see last answer

12:48 i'm a young programmer, i've been thinking private methods are security feature for languages

12:49 tbaldridge: sjouke: security...no. In Java you can access any private field via reflection

12:49 sjouke: then what's the point?

12:49 tbaldridge: sjouke: and if all data is immutable it doesn't matter, no one can change it

12:49 that's just it, Rich is right, uniform access is a un-wanted "feature"

12:49 bbloom: tbaldridge: in theory you can disallow java code from using reflection w/ the security system, but nobody does really

12:50 tbaldridge: the uniform access principal is about fields/properties/methods, not about private/public

12:54 sjouke: it seems private methods are for communicating to programmers using your code which functions they should use and which ones are implementation details

12:54 that seems logical

12:59 devong: is it possible to execute common lisp in clojure? I'd like to be able to convert org-mode documents in html for this clojure app I'm writing.

13:00 jeremyheiler: devong: i suppose you could shell out

13:01 devong: hmm, that doesn't really seem like what I'm looking for. I think I'm going to need to just do more googling, this seems like something someone has probably already solved.

13:01 jeremyheiler: what are you asking for than?

13:01 then*

13:01 devong: I don't really need to call common lisp, what I really need is to find a clojure library for parsing org-mode documents

13:01 :)

13:01 jeremyheiler: oh, well, that's different

13:02 devong: I just found a common lisp library, and thought, maybe there is an interopt somewhere

13:02 jeremyheiler: any sort of interop would likely just shell out

13:03 a quick search turned up this: https://github.com/gmorpheme/organum

13:03 devong: I think maybe something like this http://nakkaya.com/static.html

13:04 * devong bows to jeremyheiler

13:04 devong: your google foo is better than mine

13:04 this morning

13:04 thanks!!

13:04 jeremyheiler: lol "clojure org mode parser" ;-)

13:04 devong: IDK man, I had googled that

13:04 and wasn't coming up with anything

13:04 something must have been just a little different

13:05 haha, oh well

13:05 jeremyheiler: heh. i suppose with google searches aren't consistent

13:05 anyway, i hope that works out for you

13:06 devong: regardless, thanks

13:06 jeremyheiler: np

13:11 sjouke: nobody disagreed

13:11 i wasn't expecting that :)

13:12 11:51 < sjouke> it seems private methods are for communicating to programmers using your code which functions they should use and which ones are implementation details

13:12 11:51 < sjouke> that seems logical

13:13 jeremyheiler: sjouke: documentation can also do that

13:14 sjouke: sometimes it's not readily apparent which fns are impl details and which aren't

13:14 nobodyzzz: privacy is overrated - ask NSA :D

13:18 jeremyheiler: sjouke: specific to clojure, lets say you have a helper function that you want private and need in two namespaces. are you going to copy paste that function in both, combine the namespaces, or make it public in a util namespace?

13:38 sjouke: jeremyheiler: that makes sense

13:45 vdmit11: Hi folks. Given an existing object, can I add an implementation of some protocol to this object? I mean, I would like to morph an object, before morphing it doesn't support a certain protocol, after the morphing - it does. Is there some way to do this?

13:46 bbloom: vdmit11: you want to define a protocol on a particular instance, not on all objects of that type?

13:47 vdmit11: yes, on a particular instance

13:47 bbloom: clojurescript has the "specify" macro

13:47 but nothing like that on the jvm

13:48 if you have a small number of protocols to implement, i suggest using reify to create a delegating object

13:48 or, back up a step and explain why you need this. there may be a better solution

13:55 vdmit11: Well, I'm writing a little music-related program, I need to represent music somehow, so I decided to add a bunch of types like Note, Chord, Phrase, stuff like that, they have some properties in common like pitch or duration and they need to handle them in a different way, so I decided to write a bunch of protocols for such properties. Now, I need to "compose" some music, so I would like to add certain "effects" to those objects, like "vibrato". There must be a

13:58 Actually these things like Note or Chord are abstract data types, they determined not by the name, but by a set of protocols they satisfy. I use reify to create them and satisfies? to check whether an object can behave like what I want, kinda duck typing. In the code, I can reify what I want from scratch, but in the runtime I would like to create improved version of existing instances, so I have this problem.

14:00 Now I guess there is no better solution than runtime polymorphism, so I'm going to re-implement this stuff using multimethods and hashmaps.

14:01 Jaood: marco

14:09 ambrosebs: bbloom: any ideas on how to chaperone a deftype to add contracts to its methods? so far the best idea I have is to use java.lang.instrument to intercept the bytecode before it's defined and add pre/post things to the methods.

14:09 bbloom: ambrosebs: ha! you're getting crazy now :-P

14:10 ambrosebs: yes this is stupid

14:10 bbloom: i know nothing about java's instrumentation capabilities

14:10 other than it's pretty good at it, as far as these things go

14:10 it's important for profilers

14:10 ambrosebs: ahk. worth a try :)

14:11 bbloom: would be quite a feat if you make it work

14:11 good luck :-)

14:12 ambrosebs: thanks!

14:17 schmee: how do I combine `with-open` and recursion? just call the function instead of using `recur`?

14:19 bbloom: schmee: presumably you don't want to open a file on each go of the recursion...

14:20 but in general, if you want to recurse out of a catch or finally block, clojure/jvm can't promise constant stack space, so you need to call the function by name instead of recur, which enforces a tail call

14:21 in your case, you probably just want to put a loop form inside your with-open

14:22 schmee: I solved my problem by splitting the function in two, but thanks for the help!

14:22 bbloom: schmee: yeah, that's essentially what loop would let you do w/o the split

14:22 schmee: http://clojure.org/special_forms#Special Forms--(loop [bindings* ] exprs*)

14:23 ambrosebs: what do you need to add to methods for "chaparones" ?

14:23 chaperones, rather

14:23 schmee: bbloom: I tried using loop at first, that's when I got the error

14:24 bbloom: schmee: loop *inside* your with-open ?

14:25 schmee: bbloom: yep

14:25 bbloom: would have to see it

14:27 ambrosebs: bbloom: basically pre/post conditions that blame the correct party, also to add delayed checks to the return value of a method.

14:27 schmee: bbloom: I probably did something retarded, but either way it works now :)

14:28 bbloom: ambrosebs: i don't know anything about AspectJ, but it might be worth looking at

14:28 ambrosebs: bbloom: yes, having a glance. Not sure if I can get away with just using ASM, since it's already on my classpath.

14:30 bbloom: ambrosebs: logging is the only example anybody ever uses for aspect oriented programming :-P

14:30 ambrosebs: hehe

14:33 verma: in context of clojure async, when I do (<!! (timeout 3000)) my repl waits for 3 seconds, but when I do (<!! (go (timeout 3000))), it doesn't, it seems to me that even go runs in a different "thread" the <!! should still block the currrent threadn, it returns a ManyToManyChannel instead

14:33 s/even go/even if go/

14:33 bbloom: verma: read the doc string for go

14:34 or maybe (<!! (<!! (go (timeout 3000)))) will be illustrative

14:35 verma: bbloom, I did read the docs, so go is returning the channel returned by (timeout 3000)

14:35 oh

14:36 bbloom: verma: no

14:36 go is returning a channel that will receive the timeout channel

14:36 it's a channel of channels

14:36 or a channel of channel. singular, ie a "promise"

14:36 verma: bbloom, hmmm, thinking ...

14:37 bbloom, ok makes sense now

14:37 thanks

14:37 (inc bbloom)

14:37 lazybot: ⇒ 39

14:40 bbloom: ambrosebs: what if you only chaperone functions?

14:40 ambrosebs: that is, do you really need to blame at method boundaries?

14:40 ambrosebs: or would it be sufficient to redefine functions?

14:40 drguildo: how do i debug a nullpointerexception?

14:41 or debug exceptions in general

14:41 the error messages i get aren't very useful

14:41 bbloom: drguildo: *e in your repl

14:41 try (pst) too

14:41 or (clojure.repl/pst)

14:42 ambrosebs: bbloom: yea I'm asking the same questions. Need to reread some papers.

14:42 schmee: bbloom: this function keeps recurring even when I type "quit", any idea why?

14:43 bbloom: ambrosebs: but http://www.eclipse.org/aspectj/doc/released/progguide/starting-aspectj.html does seem useful

14:44 schmee: if the function is running, the repl isn't listening... try ctrl-c

14:44 drguildo: bbloom, thanks but that doesn't really give me any more information than i get already. how would i go about tracking down what it is that's being called in the fn to trigger the exception?

14:44 bbloom: drguildo: you follow the stack trace... it should have file/line information in it

14:45 drguildo: bbloom, it does but i'm having trouble finding out what it is on that line that's generating the exception. i'm a complete clojure beginner.

14:46 bbloom: drguildo: experiment with subexpressions in your repl

14:46 drguildo: i'm used to liberally peppering my code with print statements to track down bugs :-/

14:46 so i'm quite stumped

14:46 bbloom: drguildo: what's stopping you from doing that?

14:47 drguildo: bbloom, ignorance, i guess. i'm new to functional languages.

14:48 bbloom: drguildo: clojure is not pure, just use prn

14:48 ,(let [x nil y :not-nill] (prn x y) :result)

14:48 clojurebot: nil :not-nill\n:result

14:48 bbloom: ,(def dbg [x] (prn x) x)

14:48 clojurebot: #<CompilerException java.lang.RuntimeException: Too many arguments to def, compiling:(NO_SOURCE_PATH:0:0)>

14:48 bbloom: ,(defn dbg [x] (prn x) x)

14:48 clojurebot: #'sandbox/dbg

14:48 bbloom: ,(inc (dbg 5))

14:48 ambrosebs: bbloom: it does. do you know if that redefines entire classes or magically just swaps out a method?

14:48 clojurebot: 5\n6

14:49 bbloom: ambrosebs: the wikipedia article lead me to believe that it uses java.lang.instrumentation and does byte code "weaving"

14:49 drguildo: like i just added a bunch of println to the fn before the line that causes the exception

14:49 but when i execute the problem function in the repl, nothing gets printed

14:49 ambrosebs: bbloom: ah. niiice

14:50 drguildo: i just get the exception like before

14:50 same if i use prn

14:50 jeremyheiler: drguildo: did you reload the function?

14:51 drguildo: jeremyheiler, i think so. i did ctrl-c ctrl-k and also ctrl-x e

14:52 ambrosebs: bbloom: one thing that made me sad is that you can't hook into a primitive array get/set

14:52 at least, no one has implemented it yet afaik

14:52 bbloom: ambrosebs: hook the aget and aset functions

14:53 schmee: bbloom: yeah, ctrl-c works, but I still don't understand why typing "quit" doesn't

14:53 bbloom: schmee: repl == read, eval, print, loop

14:53 schmee: typing "quit" in with a print added will print "running? false"! https://gist.github.com/schmee/7128ad47b35576187e86

14:53 bbloom: it was doing eval/print, it hadn't looped back to read yet

14:54 schmee: oh, i thought you were talking about the repl, not your custom socket thing

14:54 drguildo: https://www.refheap.com/88616

14:54 what am i doing wrong?

14:54 ambrosebs: bbloom: yea I might consider that. would be nice to actually have a guarantee of some sort, instead of hoping the array doesn't get passed to evil java worlds

14:55 I'm erring on the all-or-nothing for now :)

14:55 bbloom: drguildo: you might be being bitten by laziness

14:55 drguildo: story of my life

14:55 bbloom: heh

14:55 drguildo: how do i get around it?

14:56 bbloom: drguildo: map is lazy, side effects in the transformation function aren't promised to run at any particular time

14:56 drguildo: i use do or something like that?

14:56 bbloom: it just means that your function isn't running

14:56 ,(first (map println [1 2 3]))

14:56 clojurebot: 1\n2\n3\n

14:56 bbloom: notice all three run

14:56 but:

14:56 ,(first (map println (range 100)))

14:56 clojurebot: 0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n24\n25\n26\n27\n28\n29\n30\n31\n

14:56 bbloom: only 32 run

14:57 there's no promise of how much of the lazy sequence will be visited

14:57 which means your exception is coming from somewhere else

14:57 boxed: w00t, got clj-time to use my midje-readme plugin

14:58 bbloom: ambrosebs: isn't the entire point of blame to handle flexible boundaries between verification techniques?

14:58 drguildo: bbloom, so how do i find out where?

14:58 bbloom: drguildo: heh, more print statements

14:58 drguildo: :-(

14:59 bbloom: drguildo: what's the matter, you said you like print statements?

14:59 you learned somethign when NOTHING was printed: you learned that your map code isn't being traversed anywhere

14:59 that means your NPE is happening before the result of map is used

14:59 you've narrowed the search space

14:59 keep going :-)

15:02 schmee: how is it possible to have (when running (prinln running)) print "false"......

15:05 bbloom: (prn (class false))

15:05 or rather (prn (class running))

15:05 drguildo: so why is the exception triggered on that line?

15:05 and doesn't that make clojure really hard to debug?

15:05 ambrosebs: bbloom: java arrays seem like the bane of my existence for the last few years. I'll have to think about that.

15:06 bbloom: drguildo: have you tried printing all the the variables that are inputs to that line?

15:06 ambrosebs: why?

15:06 drguildo: bbloom, i'm pretty sure i've tracked down the problem; i'm just asking a question about clojure in general

15:06 gfredericks: ,(def my-false (Boolean. false))

15:06 clojurebot: #'sandbox/my-false

15:07 gfredericks: ,(when my-false (println my-false))

15:07 clojurebot: false\n

15:07 bbloom: drguildo: small, pure functions are much much easier to debug than large stateful rats nests

15:07 schmee: running class java.lang.Boolean <-- good or bad?

15:07 gfredericks: schmee: running it?

15:07 ambrosebs: bbloom: array types in core.typed still don't really work

15:08 schmee: gfredericks: huh?

15:08 bbloom: schmee: are you using zmq?

15:08 gfredericks: schmee: ooh sorry I think I misinterpreted

15:08 bbloom: ,(identical? false false)

15:08 clojurebot: true

15:08 ambrosebs: bbloom: I experimented with bivariant arrays and ... still experimenting

15:08 bbloom: ,(identical? false (Boolean. false))

15:08 clojurebot: false

15:08 bbloom: schmee: maybe the library you're using is giving you a bad boolean ^^

15:09 gfredericks: schmee: yeah compare it to `false` using `identical?` as bbloom suggested

15:09 ,my-false

15:09 clojurebot: false

15:09 gfredericks: ,(identical? my-false false)

15:09 clojurebot: false

15:09 gfredericks: ,(identical? (Boolean/valueOf my-false) false)

15:09 clojurebot: true

15:09 bbloom: drguildo: also all your data being printable/readable makes it *very easy* to inspect intermediate results with a pretty printer

15:09 gfredericks: ,(identical? (boolean my-false) false)

15:09 clojurebot: true

15:10 gfredericks: schmee: you can pass a dirty Boolean to the boolean function to get back a good value; not sure how you ended up with such a thing

15:10 drguildo: bbloom, so in general is clojure easier, the same, or more difficult to debug?

15:10 like is it just a case of me getting used to it

15:10 bbloom: gfredericks: probably from a broken socket library

15:10 drguildo: i find it dramatically easier to debug, but it requires a very different workflow

15:11 drguildo: that doesn't mean that things like stepping debuggers are never useful, and there are some cases where tooling in clojure is far from sufficient

15:11 schmee: I don't think it's boolean, but something with the recursion in this function isn't right... https://gist.github.com/schmee/7128ad47b35576187e86

15:11 drguildo: bbloom, is there anything i can read that will help or is it just a case of experience?

15:12 bbloom: drguildo: mostly experience, but people can give specific hints

15:12 in general, just get used to working in your repl and evaluating forms from your buffer

15:13 you'll write better code that way too, b/c you'll write & test smaller bits of code at a time

15:13 and if you type test expressions in to your buffers instead of your repl, then you'll have extra test cases lying around to try when something goes wrong

15:14 drguildo: cool. thanks.

15:17 onr: could you recommend a concise resource for java standard library?

15:17 bbloom: concision isn't really java's thing...

15:21 jeremyheiler: onr, are you looking for the javadocs?

15:23 onr: jeremyheiler: oh javadocs seems to be what i need

15:23 gfredericks: schmee: the recursion looks fine; what about the first call to the function?

15:23 jeremyheiler: onr, i usually get to them by searching "java 7 api" and optionally the class i care about

15:24 schmee: gfredericks: I've added it to the gist: https://gist.github.com/schmee/7128ad47b35576187e86

15:24 I start by typing `join "user"` in the REPL

15:25 onr: jeregrine: did you read a java for getting started using java std lib?

15:25 gfredericks: schmee: are you planning on making this more complex? as it stands the `running` arg is a bit redundant isn't it?

15:25 jeregrine: onr :)

15:25 jeremyheiler: onr, not sure what you mean

15:26 onr: jeremyheiler i mean :)

15:26 oh, i intended to ask, did you read a java *book* to learn about java standard library

15:27 schmee: gfredericks: well, in the REPL I can just ctrl-c out, but I need a way to quit if I'm not running it from the REPL

15:27 and I still don't get why it just doesn't work

15:30 gfredericks: schmee: replace line three with (prn [running (class running) (identical? running false)]) and let us know what it prints

15:30 jeremyheiler: onr, not really.

15:30 onr, mostly learned by doing

15:33 schmee: gfredericks: waaaaaaiiiit a minute... when (msg-loop socket user false) has returned, will the execution resume from that point?

15:33 gfredericks: schmee: oh whoops. yes it will.

15:34 schmee: oh snap

15:34 how do I avoid that?

15:34 gfredericks: (if (= msg "quit") (do ...) (do ...))

15:38 schmee: gfredericks: worked perfectly, thanks a ton!

15:50 is it idiomatic in clojure to use `future` instead of spawn a new Thread, even if the function doesn't return a value?

15:50 *spawning

15:51 weavejester: schmee: I tend to do it - I don’t believe there are many disadvantages to the approach

15:51 It uses a thread pool, but not one that can be exhausted

15:52 schmee: so (doto (Thread. (client sock true)) (.start))

15:52 and (future (client sock true))

15:52 are basically interchangable?

15:53 weavejester: Yessss… They do different things under the hood

15:53 future uses a thread pool, IIRC

15:53 erdos: hello, i am looking for a way to serialize a long seq, buf pr-str, print-str, print, pprint/pprint all cut my list after 100 elems. any ideas? thank you.

15:53 weavejester: But for most purposes I believe they can be used interchangeably.

15:54 schmee: weavejester: great, thanks

15:54 weavejester: erdos: pr-str does? I know that REPLs can limit the number of elements, but pr-str shouldn’t be affected…

15:54 jeremyheiler: weavejester, schmee futures use the same threadpool as send-off uses for agents,

15:55 weavejester: jeremyheiler: Yeah

15:55 jeremyheiler: so blocking activity is cool

15:55 weavejester: erdos: http://clojuredocs.org/clojure_core/clojure.core/*print-length*

15:56 jeremyheiler: schmee: with futures you get a higher level api from clojure to manage them.

15:56 erdos: weavejester, thank you. the docs says, "The root binding is nil indicating no limit."

15:56 weavejester: erdos: Yeah, *print-length* does affect pr-str. Are you seeing “…” at the end of your printed data?

15:57 TimMc: hyPiRion, technomancy: OK, OK, I've picke dup Hyperion from the library. :-P

15:58 erdos: weavejester: exactly

15:58 weavejester: erdos: You might want to check the value of *print-length* in your REPL

16:00 erdos: weavejester: thank you. it was bound to 100.

16:01 weavejester: erdos: Mystery solved :)

16:21 gfredericks: is it weird that clojure doesn't have a simple mechanism to start a function after a delay?

16:21 I assume (future (Thread/sleep ...) ...) is unideal

16:22 _clearwater: hi. learning programming. what language/core library will I like if i like the simplicity and light-weightness of javascript, but for the server. i can't wrap my head around async and clojure has simple syntax but too heavy to install

16:22 gfredericks: _clearwater: clojure is heavy to install?

16:24 _clearwater: i have no idea how java works. not a CS major, so don't know about threads etc. but would like to.

16:24 jeremyheiler: gfredericks: there is clojure.core/delay

16:24 it doesn't give you a timeout, tho

16:26 gfredericks: jeremyheiler: that's completely different

16:27 I'm talking about scheduling

16:27 _clearwater: okay, well I can't imagine clojure being much more difficult to "install" than anything else. You need to install a JDK and then download the leiningen script.

16:30 jeremyheiler: gfredericks: i didn't mean timeout, sorry. either way, i see what you mean. i suppose something nice coudld be wrapped around java.util.concurrent.ScheduledExecuterService with j.u.c.Delayed

16:31 gfredericks: well if you have an executor service you don't really need anything else

16:31 a scheduled executor service rather

16:31 ,(java.util.concurrent.Executors/newSingleThreadScheduledExecutor)

16:31 clojurebot: #<DelegatedScheduledExecutorService java.util.concurrent.Executors$DelegatedScheduledExecutorService@99823>

16:32 gfredericks: ,(def my-pool (java.util.concurrent.Executors/newSingleThreadScheduledExecutor))

16:32 clojurebot: #'sandbox/my-pool

16:32 gfredericks: ,(def my-num (atom 0))

16:32 clojurebot: #'sandbox/my-num

16:32 gfredericks: ,(.schedule my-pool #(swap! my-num + 42) 2 java.util.concurrent.TimeUnit/SECOND)

16:32 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to find static field: SECOND in class java.util.concurrent.TimeUnit, compiling:(NO_SOURCE_PATH:0:0)>

16:33 gfredericks: ,(.schedule my-pool #(swap! my-num + 42) 2 java.util.concurrent.TimeUnit/SECONDS)

16:33 clojurebot: #<SecurityException java.lang.SecurityException: no threads please>

16:33 gfredericks: clojurebot: sure okay thamks

16:33 clojurebot: No entiendo

16:33 schmee: if I want to store messages in a chat server, should I use an atom or an agent?

16:34 gfredericks: schmee: my guess is an atom is fine

16:36 jeremyheiler: gfredericks: i meant that it could be nicely hooked into deref and whatnot

16:36 oh, maybe not necessary . i see j.u.c.Future is special cased

16:37 gfredericks: yep; you gotta be careful with that interface though

16:38 the reflector likes to guess wrong between the Runnable/Callable choice

16:39 jeremyheiler: heh. what happens when it guesses wrong?

16:39 gfredericks: a future that returns nil

16:43 jeremyheiler: ah, that makes sense.

17:29 hyPiRion: (inc TimMc)

17:29 lazybot: ⇒ 64

17:48 expez: https://www.refheap.com/88618 when you're interatively building up the result of a macro, is this the way to go?

17:52 jeremyheiler: expez: what do you want the macro to do, ultimately?

17:57 expez: if you want it to return a constant that is the sum of nums, then you're not doing that. but if it's just illustrative for larger problem, then i'm not sure what you're asking.

17:57 expez: The actual macro I'm writing is instrumenting some functions, so it takes a seq of fns and then should expand to a bunch of (add-hook #'fn some-hook) along with some other stuff

17:57 jeremyheiler: ah, ok.

17:58 expez: I was wondering how I would go about building up the list of ((add-hook...) ...) that I would later splice into the macro result

17:58 jeremyheiler: use for

17:59 ,(for [f [inc dec]] `(~f 1))

17:59 clojurebot: ((#<core$inc clojure.core$inc@ffdb99> 1) (#<core$dec clojure.core$dec@3c67e> 1))

17:59 jeremyheiler: it takes a seq and returns a seq

18:00 expez: right, that is way more elegant

18:00 thanks

18:00 jeremyheiler: it's also lazy, so keep that in mind

18:01 expez: Won't the compiler realize it for me at macro expansion time?

18:02 jeremyheiler: with out trying it out myself, i'm not sure.

18:07 timsg: Is there a predicate to test whether something’s seq-able?

18:08 jeremyheiler: ,(doc seq?)

18:08 clojurebot: "([x]); Return true if x implements ISeq"

18:08 jeremyheiler: ,(doc sequence?)

18:08 clojurebot: No entiendo

18:08 jeremyheiler: ,(doc sequential?)

18:08 clojurebot: "([coll]); Returns true if coll implements Sequential"

18:09 jeremyheiler: hmm

18:10 gfredericks: timsg: there's an interface called Seqable but that misses a few special cases

18:10 timsg: ,(clojure.set/intersection (ancestors (type {})) (ancestors (type '())))

18:10 clojurebot: #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.set>

18:10 gfredericks: like nil, strings, arrays

18:10 probably something else I'm not thinking of

18:11 timsg: oops, new to this repl. Is it possible to refer to another namespace?

18:11 gfredericks: ,(def my-list (doto (java.util.LinkedList.) (.add 3) (.add 99)))

18:11 clojurebot: #'sandbox/my-list

18:11 gfredericks: ,(seq my-list)

18:11 clojurebot: (3 99)

18:11 timsg: gfredericks, jeremyheiler: clojure.lang.Seqable looks promising

18:12 gfredericks: I'm checking the java source now for all the exceptions

18:12 nil, Iterable, Array, CharSequence, and Map

18:12 timsg: ^

18:13 timsg: gfredericks: thanks. What’s the ^?

18:15 jeremyheiler: it's kind of a bummer that there isn't a predicate for this

18:17 timsg: gfredericks: ah, caret as in yes Seqable :-|

18:18 gfredericks: timsg: the caret was pointing to the previous thing I had said

18:19 hyPiRion: TimMc: I can't PM you without being logged in.

18:20 timsg: gfredericks: yup, thanks :)

18:20 gfredericks, jeremyheiler: here’s an old implementation: http://clojuredocs.org/clojure_contrib/clojure.contrib.core/seqable_q

18:20 gfredericks: ,(defn seqable? [x] (or (nil? x) (.isArray (class x)) (condp instance? x clojure.lang.ASeq clojure.lang.LazySeq clojure.lang.Seqable Iterable CharSequence java.util.Map)))

18:20 clojurebot: #'sandbox/seqable?

18:21 gfredericks: ,(map seqable? ["okay" () nil 7 :foo])

18:21 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: No matching clause: 7>

18:22 gfredericks: that's definitely not how to use condp

18:23 jeremyheiler: lol

18:25 hyPiRion: (some #(instance x %) [...]) instead

18:25 although I never remember the ordering

18:26 jeremyheiler: http://dev.clojure.org/jira/browse/CLJ-401

18:30 TimMc: hyPiRion: Huh, OK. I thought most people were registered. Let me fix that.

18:31 hyPiRion: TimMc: Right, I am, just temporarily unable to login for some reason

18:36 * gfredericks voted for CLJ-401

18:41 jeremyheiler: as did i

18:41 left a comment... seems like the contrib version differs only slighly than RT.seqFrom

19:26 wildnux: hi

19:26 what is the best way to check for root access in linux in clojure

19:48 TimMc: wildnux: It's not going to be Clojure specific. You'll either use some library or issue shell calls.

19:51 (So broaden your search to Java libraries as well.)

20:01 wildnux: TimMc: doing that.. but so far i just found out only either reading current user (which could be change using jvm option) or using shell or process to run "$uid".. but it also does not give me the correct solution.. it does not give effective uid

20:23 TimMc: Why do you need it, by the way?

20:28 vdmit11: Hi folks, is there an idiomatic way for naming "getter" and "setter" methods. For example, I define getter as: (fn [map] (:key map)) and "setter" as: (fn [map val] (assoc coll :key val), how should I name these functions?

20:29 jeremyheiler: vdmit11: why do you want to name them?

20:30 the bodies are very idiomatic and succinct.

20:30 vdmit11: because they are abstract method names; and there are several implementations of these methods, some of them do things more complex than get/assoc

20:30 jeremyheiler: oh, sorry. you literally meant methods.

20:31 why not just get-foo and set-foo?

20:32 using "set" is kind of weird for the persistent structures tho

20:33 vdmit11: yes, also it may confuse you if you reverse the name like foo-get foo-set foo-delete, etc, you may think that the foo-set is a data structure

20:34 that is why I'm asking

20:34 perhaps there is a convenient way

20:34 conventional

20:36 TEttinger: well set-foo would just return a new foo

20:36 it wouldn't change the old one

20:38 TimMc: "with" is a prefix I've seen used for builder methods in Java

20:40 vdmit11: all "set" occurrences in the clojure APIs are about side effects or sets (data structures), so I think the "set" will be a bit confusing

20:42 whigmaleerie: possible: (defn assoc-key [map value])

20:42 vdmit11: "with" is usually used by macros, I think it is a bit confusing too

20:42 whigmaleerie: whatever key might be

20:43 vdmit11: I'd like assoc, but doesn't it implies "associate something with something", like I must pass both key and value?

20:44 function and variable names are always painful for me :)

21:21 ProTip: I had a hell of a time figuring out that I missed the :require-macros in the om tutorial. All the error's pointed to .js files and nothing seemed to indicate the issue was with the "go" macro not existing...

21:21 Am I doing something wrong?

21:21 In regards to debugging that is, haha

21:43 kristof: vdmit11: This is a weird dilemma to have.

21:43 vdmit11: What are your data structures, anyway?

21:52 gfredericks: ProTip: what sort of error msg was it?

22:25 ruzu: (newbie q) if one was to design a pet language for the jvm, is clojure well suited to building the compiler?

22:27 TEttinger: ruzu: strongly typed or dynamic?

22:27 clojure is good for making clojuresque languages

22:28 but the core data structures are a certain way, and you might have to work around them if your language wasn't close to clojure

22:28 XText looked interesting

22:28 $google eclipse xtext

22:28 lazybot: [Xtext - Language Development Made Easy! - Eclipse] http://www.eclipse.org/Xtext/

22:28 ruzu: mm

22:28 i was thinking something ml-esque

22:30 lpvb: do swap! compare-and-set! and !reset block?

22:31 gfredericks: yep

22:34 ruzu: is xtext akin to antlr?

22:36 TEttinger: ruzu, I have looked at it, it makes an IDE plugin for you with syntax hightlighting and autocomplete. you can make your own language in whatever and hook it up to that

22:36 it also has a basic compiler it generates I think

22:37 jeremyheiler: gfredericks: internally atoms use an AtomicReference. this is inherently non-blocking, no?

22:40 gfredericks: wat?

22:41 jeremyheiler: why would AtomicReference be non-blocking?

22:41 http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicReference.html#compareAndSet%28V,%20V%29

22:41 ^ says nothing about being non-blocking

22:43 nathan7: gfredericks: I'm pretty sure that's implemented as a single CAS pointer set in assembly-land.

22:43 gfredericks: If so, no, it wouldn't block.

22:43 gfredericks: maybe we're confusing terminology

22:43 I mean that it does everything it's going to do before it returns

22:43 and swap! in particular can sit there spinning arbitrarily long

22:43 jeremyheiler: ah, ok, then yes. i meant what nathan7 said. it doesn't use locks

22:44 nathan7: oh, yeah

22:44 gfredericks: so I might be using "block" loosely

22:44 nathan7: swap! is CAS in a loop

22:44 gfredericks: it's certainly not async like send

22:44 is really all I meant

22:44 nathan7: well, send does some kind of atomic queue addition

22:44 the queue addition is blocking

22:44 probably also involving some atomic CAS in a loop

22:45 but the loop doesn't include the supplied fn, no

22:45 gfredericks: right

22:45 the fn gets called on another thread

22:45 jeremyheiler: nathan7: that's for agents, tho

22:45 nathan7: jeremyheiler: what else does send accept?

22:46 jeremyheiler: because over here, send's first arg is ^clojure.lang.Agent a

22:46 jeremyheiler: right, the fns in question originally were for atoms. was confused.

22:59 rs0: what would constitute a purely functional, dynamically typed programming language?

23:00 suppose you had a Clojure-like language where referential transparency and the lack of side effects were enforced at runtime. if you attempted to, say, access the disk or generate a random number outside of a function whose name ended in a ! (even transitively), it was a runtime error. would that be a purely functional language?

23:09 TEttinger: rs0: a truly pure language is one that has no ability to modify the world outside it, not even the console or repl. does that sound useful to you?

23:12 benkay: is this (https://groups.google.com/forum/#!topic/datomic/UX4kNT0kaqg) still the best way to get empty attrs out of datomic?

23:15 Fare: I see a documentation page for cond-let, but its github file seems to be disappeared.

23:15 I know it's only a 3-line macro, but is there a standard place it has moved to?

23:15 benkay: is if-let the new hotness?

23:17 Fare: cond-let chains several if-lets

23:17 without having to nest heavily

23:18 otherwise, I suppose some kind of nesting macro could do it. Maybe a <- reply to -> ?

23:23 csd_: Hello. How do I change the default directory where Lein creates new projects?

23:26 Fare: (defmacro <- "Nesting macro" ([] nil) ([x] x) ([x & y] `(~@x (<- ~@y)))) ;; like UIOP:NEST in CL

23:31 rs0: TEttinger: Haskell is generally described as a purely functional language. do you think the term "purely functional" is well defined?

23:32 jeremyheiler: csd_: "lein help new" shows you how ;-)

23:33 rs0: TEttinger: (personally, I have the sneaking suspicion that "purely functional" is no more rigorously defined than "object oriented", but I might be wrong)

23:34 csd_: jeremyheiler: I see that I can set --to-dir when creating a project, but is there any way to put it into a profile so it's automatic?

23:34 TEttinger: rs0, I think it's generally accepted that true purity is a program that makes your CPU warmer and prints nothing. Haskell lets you break out of purity with monads, and it obviously is a usable language, so I think "purely functional" more refers for the ability to verify whether a function will have side effects

23:34 like in C, there's just no way to tell if a program will mutate outside state or not

23:35 rs0: TEttinger: yes, that's what I'm getting at. I'm starting to think that the use of the IO monad in Haskell is just an elaborate type-oriented scheme for being able to determine whether functions have side effects or violate referential transparency

23:35 TEttinger: in clojure, it's easier if you stick to pure clojure... but there are still java interop things and even stuff like ##(rand-nth [1 2 3])

23:35 lazybot: ⇒ 2

23:37 rs0: another idea in Haskell is pervasive non-strict evaluation. it appears to be one of the problems with unsafePerformIO--that, and the fact that the compiler is liable to perform incorrect optimizations when unsafePerformIO is used, and you have to use a bunch of pragmas and the like to try to ensure that your side effects don't get CSE'd out in a way you didn't intend or expect

23:38 so in Haskell all these ideas are combined, and I think it's an interesting thought experiment to try to cut Haskell up into pieces and recompose the pieces in different ways, asking, "is this purely functional? how about now?"

23:38 TEttinger: indeed!

23:39 jeremyheiler: csd_: hmm, there doesn't appear to be any other way

23:39 the code just pulls that option from the arglist and that's it

23:40 csd_: hrm ok

23:42 jeremyheiler: csd_: the code binds a *dir* var before it applies the template, so you may be able to create a custom template that overrides that behavoir? but that seems like a little much.

23:43 csd_: just curious, do you choose to let it clutter up your home directory or use the flag each time

23:44 jeremyheiler: i just cd to the dir i want the project to be in.

23:44 csd_: ok thanks

23:44 jeremyheiler: np

Logging service provided by n01se.net