#clojure logs

2012-01-02

00:00technomancyit means unless you want to go through a bunch of grunt work by hand you're limited to using clojure and no external libraries
00:01bitopstechnomancy: I may be misremembering, but I thought I had read that contrib was bundled with the clojure jar?
00:01technomancyno, contrib has been split up into a bunch of separate jars now
00:01bitopsright, I saw that from the link(s) above
00:02bitopsit's not an issue for me, I'm just trying to figure out what is the right way to get started and set up :)
00:03graphbumsince I am in the midst of shifting from 1.2 to 1.3, I saw the contrib modularization. so you need to grab numeric tower
00:03bitopsah okay
00:03graphbumyou can do that a number of ways....
00:04bitopsI'll go out on a limb and assume leiningen is the easiest way?
00:04graphbumthat's what technomancy was saying
00:04amalloyclojurebot: leiningen is always the easiest way
00:04clojurebotAck. Ack.
00:04bitopsif the right thing to do is having a "playground" project I'm all for that
00:04amalloybitops: yes, sounds good
00:05bitopsthat's sort of interesting, making the standard library a dependency you have to download. not knocking it by any means, just observing…could have useful applications
00:05graphbumso you'd like.... "lein new playground" somewhere
00:05bitopsgraphbum: what if I have some existing files I want to leiningenify?
00:06graphbumlein will make the structure for you and populate it with some stuff, namely a project.clj I believe
00:06graphbumyou can dump whatever you want in there
00:06graphbumin the directory
00:06bitopsah, just tried it. pretty painless
00:07graphbumyou set dependencies inside project.clj
00:07technomancyit's not really the standard library
00:07bitopswell geez, when's the pain going to start?! I was expecting a yak to show up any old time now.
00:07bitops:P
00:07technomancythe standard library is just clojure.set/xml/zip/test/etc that comes with the jar
00:07amalloyright. the standard library is the stuff that *does* come with clojure. functions like map, filter, reduce
00:09graphbumthere's some really useful shit in contrib though...
00:09graphbumuseful for me at least
00:10amalloythere's some really useful stuff in ring too, but that doesn't make it part of the clojure stdlib
00:13graphbumright....except some of that really useful shit from contrib did become part of the standard lib....because it was useful
00:14bitopstechnomancy: I hate to sound like a broken record, but how do I know which version of numeric-tower to import? https://github.com/clojure/math.numeric-tower isn't much help. :(
00:14technomancybitops: I usually try http://search.maven.org
00:16bitopstechnomancy: cool…I found it….but then what to type in the project.clj file? I'm sorry if that's a stupid question, it's not totally clear to me how it maps onto the Maven abstraction.
00:16technomancyif you do "lein help tutorial" it should have you covered
00:16technomancyyou can skim to the part about adding deps, but at some point you should read the whole thing
00:17bitopstechnomancy: ah okay, thank you, I'll do that
00:17bitopsthanks for all the help! much appreciated :)
00:17technomancysure
00:50graphbumdid the old repl-utils from clojure.contrib make it into the new modular stuff under 1.3?
00:50graphbumtrying to grab what used to be clojure.contrib.repl-utils/show
00:52amalloyclojure.reflect/reflect
00:52graphbumnice, thanks.
01:26graphbumwow...i did not realize how disruptive 1.3 would be against 1.2 projects I had
02:14replacatechnomancy: still around?
04:14tomojis there a better way than @(promise) to cause a thread to just do nothing
04:20amalloy(.wait (Object.))?
04:31tomojI just get an IllegalMonitorStateException
04:38woodzYou need to be in a Java 'synchronized' block to acquire an object's monitor and be able to .wait on it. Clojure provides access to this via the 'locking' macro, which has the advantage of releasing the monitor when the enclosed body of code finishes.
04:40tomojso (let [o (Object.)] (locking o (.wait o))) ?
04:41amalloywell @(promise) has got to be better than that
04:41Fossi:D
04:41woodzYes, except that that particular snippet will tie up whichever thread executes it, probably infinitely, as the new Object isn't available for another thread to signal
04:41amalloywoodz: that was the point
04:41tomojthat's the goal
04:42woodzI joined the conversation a bit late, so missed that bit :-)
04:42tomojif the thread dies, it will be reborn elsewhere automatically
04:42woodzok
04:42amalloyfwiw, @(promise) probably requires a bit more resources from the jvm than the .wait approach, but since what you're doing is killing off the thread i doubt it matters
04:44amalloy&(doc monitor-enter)
04:44lazybot⇒ "Special: monitor-enter; Synchronization primitive that should be avoided\n in user code. Use the 'locking' macro."
04:44amalloysuper-efficient! you can refuse to include the monitor-exit that (locking) would introduce :)
04:45amalloysaving 100% (and also 0%) of the cpu cycles that would be spent on that
04:48wiseenhttps://github.com/wiseen/core.observable - I wrote a .NET RX event handling library for clojure/clojurescript
07:31rangenwhy this says 'unable to find resource'? lein install org.clojars.gjahad/debug-repl "0.3.1" it should work right? http://clojars.org/org.clojars.gjahad/debug-repl refers to this info
07:32rangenfull error: [INFO] Unable to find resource 'org.clojars.gjahad:debug-repl:jar:0.3.1' in repository central (http://repo1.maven.org/maven2). it seems lein does not go to look for clojars repository in this case
07:35holohello
07:35holocan someone tell me a very simple case of use (actually useful) for "let" form?
07:41Chousukeuhh... any time you want a local variable?
07:41Chousukewhich is not that uncommon
07:42Chousukeor do you use only global variables and literals in your programs? :P
07:46Chousukeholo: let can also be used to create closures eg. (defn make-counter-fn (let [foo (atom 0)] (fn [] (swap! inc foo)))) <- now you can call the function returned by make-counter-fn and it will return the number of times it has been called.
07:47Chousukethough I guess that's a toy example, it's pretty common in actual code. it's just difficult to come up with good examples without actually having some sort of purpose in mind :P
07:47ChousukeI mean closures are common, not counters. :P
07:57holochousuke, I see. I am familiar with closures. I don't use globals or locals yet or anything at all in clojure. I'm just learning clojure from a tutorial
08:00ChousukeI'm sure you'll find lots of uses for let once you start writing code, then
08:02Fossifor me the most common occurrence is: (let [foo (some-"expensive"-calculation bar baz)] (dothis foo) (dothat foo))
08:03Fossiand expensive can also be hard/annoying to write twice ;)
08:05Fossihmm i guess: (let [foo (some-"expensive"-calculation bar baz) quux (some-transformation)] (dothis quux) (dothat foo)) is even used more often :)
08:05Fossias in saving something for later
08:09holoFossi, at the second example there is no reutilization of results
08:11holoOK, I guess its cleaner and there is an implicit "do" by using let
08:13Fossiups
08:14Fossii meant to write (some-transformation foo)
08:18holoI see, but for a language which returns an expression by being functional looks to have a strong imperative flavour
08:19Fossiwell, let isnt needed if your code is purely functional
08:19Fossiother than saving you lots of typing
08:20Fossioh, and save computation
08:20Fossibut not strictly needed, no
08:20raekif the value of one expression is needed in multiple expressions, you still need let in purely functional code
08:21Fossiyou can recompute it then
08:22raekholo: why does Clojure look to have a strong imperative flavour?
08:23Fossii think "let" does
08:24holoraek, when, do, loop (something more I may forget) forms are purpposely imperative. anyway this is just from the tutorial I am reading. it's not bad to have imperative constructs.. I mean, it just looks as if that is the idiomatic way of doing things. ultimately what matters is choice not to do it
08:25antares_hi. I have the following code with gen-class and no matter what I do, the compiler tells me there is no "state" field on the generated class: https://gist.github.com/3fd54c45bce5cdf9e345 — what am I missing?
08:27holoin caml, let in the toplevel would create global variables. if used inside something like those examples from Rossi, it would create local variables
08:29raekI think of the implicit do like this: what should (let [...] a b c) mean? (let [...] (do a b c)) is a fairly "natural" interpretation.
08:33Fossiraek: well, you could disallow that
09:29nickikI want to reset up my emacs. Witch is the best current tutorial to get emacs/Starter Kid/Clojre Mode/slime/swank working?
09:45CrazyWoodshow to use clojure to start a GUI project?
09:46vimjanickik: i used http://data-sorcery.org/2009/12/20/getting-started/ to get started
09:46benoystnickik: I've also found this one interesting: http://postposttechnical.com/2011/11/first-steps-with-clojure/
09:51benoystCrazyWoods: I've read a very exciting article a few days ago: http://blog.darevay.com/2011/12/a-seesaw-tutorial/
09:51benoystHope this helps.
09:53CrazyWoodsbenoyst, thank you
09:53Fossithat looks almost nice :)
09:54benoystindeed
10:01Fossidoes anyone know a tutorial on debugging java via emacs/swank? does that even work?
10:14ziltiDoes someone here use SQLKorma? What type does exec return for a select query?
10:35bhenryis there a way to use binding on something qualified as alias/var where alias is the last part of (require '[namespace :as alias])
10:38Raynesbhenry: If I understand your question right, then there is nothing stopping you.
10:47lypanovif i use someones library that has a line saying (def *vm-session-type* "gui")
10:47lypanovhow can i change the value for my usage of the library?
10:47lypanovi assume thats what its for..
10:49bhenrylypanov: &&(doc binding)
10:57ziltiNow that's a strange error: "IllegalAccessException Class clojure.lang.Reflector can not access a member of class lyrionch.util.Whirlpool with modifiers "public static final"" Why can't it access something marked public?
10:58skelternetis it accessing it for write?
10:59skelternetoh…Reflector
10:59ziltiI'm playing around in the repl and did a (def digest (Whirlpool/DIGESTBYTES))
11:01ziltiAny other try to access the class results in a "IllegalAccessError tried to access class lyrionch.util.Whirlpool from class lyrionch.models.usersys$eval699 lyrionch.models.usersys/eval699 (NO_SOURCE_FILE:51)" like error.
11:02raekzilti: what is DIGESTBYTES? a method or a field?
11:02ziltiA static field
11:02raekthen you should do this: (def digest Whirlpool/DIGESTBYTES)
11:03raekthe extra parens means method call
11:03ziltiHmm thanks. But I get the same error again: IllegalAccessException Class clojure.lang.Reflector can not access a member of class lyrionch.util.Whirlpool with modifiers "public static final"
11:08lynaghkHas anyone defined multimethods in ClojureScript before? I'm having some namespace troubles excluding clojure.core/+
11:08lynaghkhttps://gist.github.com/1551222
11:13ziltiPro-tip: Declare a class as "public" if you want to access it from another namespace...
11:16yoklovis there any slowdown associated with metadata
11:17yoklovactually no nevermind it'll still be way faster than the numerical calculations I'm doing.
11:21ziltiI have a Java class and I have a Clojure function accessing that class. Now I want to ensure that only one "instance" of the Clojure function is allowed to access the Java class at a time, forcing other instances to wait (because that Java class isn't thread save). What's the best way to achieve this?
11:32chouserpods, if only they existed.
11:42TimMcchouser: pods? A web search didn't reveal anything.
11:43chouseryeah, they don't exist
11:43lynaghkIt's a planned construct that Rich talked about at the Conj
11:43chouserhttp://kotka.de/blog/2010/12/What_are_Pods.html
11:43TimMcAh, got it. I took it to be something that existed in some other language.
11:48ziltiThat's a pity... But how should I do it? I'm quite new to concurrency, especially in Clojure
11:51TimMczilti: It's a single instance that you need to coordinate access to from multiple Clojure threads?
11:51TimMcMaybe you could send thunks to an agent that controls the instance.
11:52cemerickThat, or there's always `locking`. :-P
11:52TimMcPoint.
11:53raek(def foo-lock (Object.)) (defn foo [...] (locking foo-lock ...))
11:53ziltiBut wouldn't locking refuse the attempt to access the class? What I need is basically that the whole body of the function that accesses the java class is executed "atomically" so that there can't be a second call to the same function at the same time.
11:54ziltiSo I had something like a "queue" in mind that just puts the other threads trying to access in a "sleep" state
11:54TimMczilti: locking pauses the thread
11:55ziltiOk, then I'll do locking
11:55raekzilti: have you checked you java.util.concurrent.BlockingQueue?
11:55raekhttp://docs.oracle.com/javase/6/docs/api/java/util/concurrent/BlockingQueue.html
11:55raek*checked out
11:55TimMcIf you just need to send actions, an agent would be good. But if you need to read *and* write, locking is probably the best.
11:56ziltiYes, I'll use locking. I just thought locking would "cancel" a request made at the same time, but if it's pausing the concurrent thread it's ok
11:57jodaro`so i'm messing around with aleph/lamina/gloss stuff
11:57jodaro`using tcp-client to interact with a server that uses a binary protocol
11:57jodaro`i've specified a frame to handle the request
11:57cemerickzilti: `locking` uses a Java monitor, just like `synchronized`.
11:58jodaro`enqueue it on the connection
11:58jodaro`and receive-all the response
11:58jodaro`everything appears to work correctly but i'm noticing that my respone is also being decoded using said frame
11:58jodaro`which happens to work, but what if i wanted to use a different codec for the response
12:00jodarooh
12:00jodarolooks like i can specify an encoder and decoder
12:04dbushenkohi all!
12:04dbushenkowhat's the ultimate mongodb clojar?
12:08solussdwhen using clojure.xml/emit to print xml it turns all of my numbers and booleans in the :attrs map into strings, so when I read it back in using clojure.xml/parse, I have nothing but strings for my :attrs. What is the most straightforward way to detect, and convert into the appropriate type, these attributes?
12:11cemericksolussd: XML is textual; there's no reason to expect it to natively round-trip other data types.
12:12cemerickYou could speculatively parse attributes using clojure.walk
12:14solussdcemerick: hm. too bad clojure.xml/parse can't be fed a schema
12:16cemericksolussd: schemas aren't supported in the JDK IIRC.
12:17cemerickOK, so that's wrong.
12:17cemerickI should say, I think schemas can only be used to validate.
12:40solussdhow do you list all of the interfsaces/protocols a type implements?
12:47ScorchinI currently have a return value which looks like: (["h1. " "h1" ""]). To get the second element from the sequence, I'm doing the following: (second (first (["h1. " "h1" ""]))). Is there a better way to do the above?
12:49yoklovScorchin: if it's in a let or a function you could use destructuring
12:50Scorchinyoklov: thanks, I'll check that out
12:56yoklovScorchin: something like this ##(let [[[fst snd trd]] (list (vector "h1. " "h1" ""))] snd)
12:56lazybot⇒ "h1"
12:57yoklovthough, thats still somewhat awkward.
13:02flashingpumpkinhey guys. I'm curious if someone can quickly help me out. I'm running into java interop problems. I'm following this tutorial, but fail to init a new mesh. (Scroll down to the rendering a triangle bit) - http://code.google.com/p/libgdx/wiki/MyFirstTriangle and the ctor error: http://dpaste.com/680334/
13:05Chousukeflashingpumpkin: that sort of stuff usually happens when there are multiple similar constructors
13:06Chousukeflashingpumpkin: try typehinting the vertex argument, or force the integer literals to be ints with (int 3)
13:06flashingpumpkinChousuke, there are indeed multiple constructors. But, I'm just rewriting the Java example (that works) into Clojure.
13:06flashingpumpkinChousuke, ok, trying :)
13:08yoklovthat ctor has varargs in java, does that mean anything for the clojure interop/
13:09flashingpumpkinChousuke, nope. Both does not work. Here's maybe more context for the Mesh constructors: https://gist.github.com/153d4bc319da0b0f9efd
13:09yoklovtry putting the vertex in an array
13:10yoklov(to-array [vertex]) maybe?
13:11flashingpumpkinyoklov, nope
13:11Chousukelooks like it should work if you typehint the vertex
13:11Chousukedid you try typehinting it and forcing the 3s to ints at the same time?
13:12flashingpumpkinChousuke, yes
13:12flashingpumpkin(to-array [^VertexAttribute vertex])
13:14flashingpumpkinI had no idea there is such a thing as varargs in java.
13:14yoklovErr, I don't really know what I'm talking about so its totally possible that putting it in an array is the wrong thing to do.
13:15jodarook, another gloss question
13:16jodaroif i have something like
13:16jodarofoo\0bar\0baz
13:17jodarois (repeated (string :utf-8 :delimiters ["\0
13:17jodaro"]))
13:17jodarothe right way?
13:20TimMcI guess try it out?
13:20jodaroyeah
13:20jodaroits the 4 part of the protocol
13:20TimMcMy only question would be whether there is a final delimiter. I guess there has to be.
13:20jodarofourth part of a response, actually
13:21yoklovWhat's the difference between typehinting with #^type and ^type?
13:22amrois there a way to get more information out of "No value supplied for key: true"?
13:22TimMcyoklov: The latter is deprecated.
13:22yoklovotherwise they're the same?
13:22clojurebotI don't understand.
13:23TimMcamro: Are you trying to build a map?
13:23TimMcI mean, what is the context?
13:23mattmitchelljodaro: in your example, what is "string" ?
13:24clj_newbthis is an honest question; not an attempt at a flame war: I was reading about attmepts of clojure on llvm; and then all tend to mention that the llvm is bad at JIT ... this confuses me, what exactly does the JVM JIT do that the LLVM JIT does not do?
13:24TimMcyoklov: Wait, maybe it's the other way around...
13:24clj_newb(I was under the impression taht LLVM = the uber JIT, using the latest + best in research tech)
13:25amroTimMc: I was passing stuff to a lib, and wasn't sure how it was building a map out of it. was wondering if there's a way to get a representation of the map for debug, at the error
13:25TimMcyoklov: Right, ^ is the correct form.
13:25amroI fixed it since, but I'd still like to know for future reference
13:28TimMc&{:a 1 :b}
13:28lazybotjava.lang.RuntimeException: Map literal must contain an even number of forms
13:28jodaromattmitchell: its part of gloss
13:28TimMcSo, not that error...
13:28jodarohttps://github.com/ztellman/gloss/wiki/Introduction
13:28TimMc&(hahs-map :a 1 :b)
13:28lazybotjava.lang.RuntimeException: Unable to resolve symbol: hahs-map in this context
13:28TimMc&(hash-map :a 1 :b)
13:28lazybotjava.lang.IllegalArgumentException: No value supplied for key: :b
13:28TimMcamro: ^ that's what was happening in the lib.
13:28lypanovclj_newb: many people don't have much of a clue about it :)
13:29lypanovclj_newb: but using llvm would be a huge amount of work. it'd require custom optimization passes
13:29lypanovthe JVM does a crazy amount of stuff.
13:29sritchiehey guys, I'm running into what might be a bug with inlined functions
13:29sritchiehttps://gist.github.com/1551640
13:30TimMc&((fn [& {:keys [a b]}] nil) :a 1 :b) <-- amro: you were probably calling a function with keyword args like this one but missing a param
13:30lazybotjava.lang.IllegalArgumentException: No value supplied for key: :b
13:30sritchiethe environment seems to be interpreting ^bytes as a var, not a type hint
13:30jodarohrm
13:30sritchiebut only the second time I evaluate that form
13:31jodarothat "works", but the resulting byte buffers seem to be longer than i expect
13:31jodaroif i encode ["foo" "bar"]
13:31yoklovclj_newb: LLVM isn't always JIT compiled, it's just availiable as an option. I don't really know, but that at least leads me to believe that it might not be their strongest area.
13:31jodaroi guess i'd expect 8 bytes
13:33TimMcsritchie: "Can't type hint a local with a primitive initializer"
13:34clj_newblypanov , yoklov: so the core is: "JIT in Java is automatic. JIT in LLVM requires manual work." ?
13:34sritchieTimMc: yeah, hinting the original x and y doesn't pass through to the inline definition, unfortunately
13:34sritchieTimMc: can you think of any way to hint those arguments?
13:35TimMcsritchie: Never mind, that was my bad -- I was passing in junk.
13:35TimMcand I get the exception you see on the first call.
13:36TimMcsritchie: (java.util.Arrays/equals ^bytes ~x ^bytes ~y)
13:37TimMcsritchie: Also, you might use reduce.
13:38amroTimMc: thanks
13:38TimMcsritchie: The reduce idea might need work...
13:38amrobut it said true, not :true, so it was building a map with true as a key I guess?
13:38TimMcamro: That's my guess.
13:39TimMc&(hash-map true)
13:39lazybotjava.lang.IllegalArgumentException: No value supplied for key: true
13:39TimMc&(hash-map :true)
13:39lazybotjava.lang.IllegalArgumentException: No value supplied for key: :true
13:39amroyep, I just tried that
13:39amrowell, in any case I was misusing the API
13:41yoklovclj_newb: That could be it. If you really want more information, see if LLVM has an irc channel and ask them there. The clojure channel isn't likely to have many people who would know what optimizations LLVM does during JIT compilation.
13:42sritchieTimMc: that doesn't seem to pick up the type hint, unfortunately
13:44lypanovllvm has a irc channel on oftc
13:45lypanovclj_newb: pretty much, though i'd rather say JIT in JVM has 30 years worth of experience fixing crap code.
13:45lypanovclj_newb: llvm OTOH has very different goals. it is just an insanely great machine code generator.
13:46lypanovclj_newb: you might also want to try #rubinius some of the guys there have actual experience, i just have 2nd hand guesses ;)
13:51mattmitchellif i used an atom as a way to more easily change state of a map, in a non-multi-threaded program, would this be considered misusing an atom?
13:54jodaroi think it depends on why you need to do it that way
13:54TimMcsritchie: Hmm, how can inlining be debugged?
13:54sritchieI'm not sure, I don't really know the expansion rules
13:56clj_newbthis is starting to make sense now
13:56clj_newbI always wondered why such a brilliant langauge like clojure picked java
13:56clj_newbnow I get it: it makes impelmenting clojure much much easier
13:56yoklovversus llvm?
13:56clj_newbno need to implement a VM, a FFI, or a JIT
13:56clj_newbit's all provided by java
13:57yoklovOr the hundreds of libraries that come with java.
13:57TimMc":inline-arities >1?" <- wtf
13:57clj_newbThus, all the effort of implementing clojure goes into implementing the new ideas that clojure provides; rather than the bitch work of setting up the core of a basic language.
13:57mattmitchelljodaro: well, there is a function with a lot of nested conditions. I was going to use reduce, but using an atom made it clear since, I only update the map if all of these nested conditions are met by calling swap!
13:57TimMcOh, it's a private fn.
14:03lypanovclj_newb: there is a project called vmkit that if it were to be improved could offer all the advantages of JVM and llvm
14:03lypanovbut it'd be years of work
14:03lypanovand openjdk is okay ish now
14:03clj_newbCurrently asking in llvm on irc.oftc.net
14:04clj_newbI really like Clojure's approach to concurrency (immutability + vars + atoms + agents + stm); if only I could write programs that did not require the JVM like that ... :-)
14:06mattmitchellis there a built-in function for turning a collection of hash-maps into a hash-map, where the keys come from the values of the maps in the collection? Example: (some-fun [{:id 1} {:id 2}] :id) => {1 {:id 1} 2 {:id 2}} etc..
14:08TimMcmattmitchell: Ill-defined, what happens with key collisions?
14:08TimMcOr can you assume there are none?
14:08mattmitchellTimMc: it can blow up in that case
14:08mattmitchellyeah, there shouldn't be any
14:08mattmitchellI'm using reduce right now, but it seems too complex
14:08TimMcfor might be better
14:09lypanovclj_newb: you could, use clojurescript + v8 and implement it all on top of js "threading" concepts ;)
14:09TimMcmattmitchell: And maps are fine, no need to specify hash-maps.
14:09mattmitchellTimMc: ahh right
14:09mattmitchellTimMc: could you give me a hint on the "for" approach? :)
14:11jodarohrm, well, treating it as a single string and then splitting it on \x00 works for now
14:11TimMc&((fn [fk & ms] (into {} (for [m ms] [(m fk) m]))) :id {:id 1 :a 2} {:id 5 :b 4}) ;; mattmitchell
14:11lazybot⇒ {1 {:a 2, :id 1}, 5 {:b 4, :id 5}}
14:12mattmitchellTimMc: awesome thanks
14:12TimMcmattmitchell: I think you could sneak a juxt in there, actually.
14:13mattmitchelloh maybe juxt and zipmap?
14:13TimMc&((fn [fk & ms] (into {} (map (juxt fk identity) ms))) :id {:id 1 :a 2} {:id 5 :b 4}) ;; assumes focal key is a keyword or symbol or other IFn
14:13lazybot⇒ {1 {:a 2, :id 1}, 5 {:b 4, :id 5}}
14:13mattmitchellahh i see
14:20clj_newbbased on discussions on oftc llvm: ... Why is JITTing important to clojure? There are other scheme implementations, like Chicken ... that appear to be doing file while compiled. How exactly does Clojure use JITting?
14:25TimMcclj_newb: One cool thing is that with JIT, macros can expand in different ways depending on what libraries are available, or what version of Clojure is in use.
14:26clj_newbTimMc: how does macros related to JITTing?
14:26lypanovthat can be done without JIT if the system applies system wide opts.
14:26clj_newboh, macros can be done at _runtime_ ?
14:26clj_newbrather than multiple compilation passes?
14:27TimMcclj_newb: Yeah, JIT means you are distributing source, unexpanded.
14:27amalloyi think you two are confusing each other
14:27clj_newbamalloy: enlighten us
14:27TimMcoh no, an expert!
14:27amalloyTimMc is just saying that the compilation happens in the same environment where code is going to execute
14:27amalloyso you know what will be available
14:28clj_newbHow does this related to JITTing?
14:28raekThe oracle implementation of the JVM (Hotspot) uses JIT compilation to speed up the virtual machine.
14:28amalloyit's not related to java's JITing, but it is basically clojure's JIT: compile it Just In Time, before they run it
14:28amalloyclojure doesn't care at all about java's JIT; it just runs on the jvm and gets a performance boost for free
14:29TimMcYeah, I guess there's a jargon mismatch here.
14:29AeroNotixWhat's a good method for type checking in clojure?
14:29TimMcClj -> .class -> native machine code -- *both* of those steps are compilations.
14:30clj_newbamalloy: ah, the point you're getting at is (1) Just in Time macro expansion vs (2) Just in Time compilation + code execution ?
14:30amalloyno
14:30TimMc&(instance? String "AeroNotix")
14:30lazybot⇒ true
14:30AeroNotixThank you
14:30amalloythat's the point that is dividing you and TimMc
14:30AeroNotix@TimMC thank you
14:30TimMcAeroNotix: isa? can do some fancier stuff
14:30AeroNotixthanks, I'll get to google
14:30amalloyi guess maybe that's the point i was getting at also
14:31amalloybut it's not just "JIT macro expansion", because clojure really does compile all the code right before it runs. it has to expand the macros to do it, but...
14:34lypanovJIT implies continuous. clojure isn't continuous.
14:34lypanovthere is no "hotspot" detection in clojure's compiler. its just a compiler.
14:39clj_newbthe more I learn about clojure; the more brilliant I think it is
14:40clj_newbI bet there's even a good, perfectly valid reason, why clojure does not have a builtin (make-me-a-sandwhich :meats '(beef pepperoni) :vegetables '(pickles onions))
14:40AeroNotixclj_newb: It does?
14:41lypanovclj_newb: glad you get it now, i decided to go down the scala road a year back after a quick dive into clojure burnt me and deeply regret it. back again.
14:44clj_newblypanov: what did you like about scala / how did it burn you?
14:44lypanovclj_newb: i liked the fact that i could learn it fast as its similar to other things i've used and that it had a ton of cool language features.
14:44lypanovclj_newb: i was burnt my its complexity.
14:44lypanovby*
14:45lypanovi also simply couldn't deal with the compile times.
14:45lypanovits 2012!
14:45lypanov;)
14:55lypanovanyone else read lwn.net & have a kindle?
14:56lynaghklypanov; have you seen the Send-to-Kindle google chrome extension? It's pretty decent at extracting article text and formatting for Kindle
14:57lypanovlynaghk: i'd really like to have a .mobi with nice headers and a ToC etc
14:57lypanovi want to dissect whatever magic instapaper is performing is thats the format i'd like
14:59lynaghkAh, makes sense. I've used Amazon's standard html to mobi converter on a few projects with luck, so hopefully it won't be too difficult.
14:59lynaghkGood luck
15:01lypanovyeah probably going to use kindlegen for it if i can get it to produce the right file
15:01lypanovthank you :)
15:03AWizzArdWhen I eval *out*, a ^:dynamic var under Clojure 1.3, is that then equivalent to @#'*out*, from an efficiency point of view?
15:04AWizzArdI noticed that (time (dotimes [i 10000000] *out*)) and (time (dotimes [i 10000000] @#'*out*)) take the same amount of time, vs. (time (dotimes [i 10000000] "hi")), which is much faster (as I expected).
15:07holohello
15:09AWizzArdMy understanding is: as *out* and *err* are dynamic vars, Clojure needs to deref them at runtime, where deref means: look up the current thread-local value. And this should be equivalent to dereferencing a var. Yes/No?
15:10amalloyAWizzArd: it's probably similar, though i suspect *out* is a little easier to inline. why not write both functions, AOT-compile them, and look at the bytecode?
15:11AWizzArdamalloy: my background, why I came up with this question is that I want to write a logging function which can log to *out*, and one which logs to *err*. Both fns are 5-liners and are identical, with the exception of their arg to the .write method.
15:12AWizzArdSo instead it would be the right thing to have a factory fn instead, which gets called with those two args. But that of course would make those two logging functions statically log into whatever value *out* or *err* had when I called the factory.
15:13amalloyhuh? why of course? i don't think i understand you
15:13AWizzArd(def out-logger (make-logger *out*)) <-- out-logger always .writes to the same Writer.
15:13amalloy(make-logger #'*out*)
15:13AWizzArdExactly.
15:13AWizzArdThis would work.
15:14AWizzArdBut then: (.write #'*out* ...) doesn’t. Of course, because it expects a Writer, not a Var.
15:14AWizzArdSo I would have to deref the arg to make-logger.
15:14amalloyright
15:14AWizzArdAnd when I realized this I thought: will this be less efficient than writing explicitly (.write *out* ...)?
15:15AWizzArdThe dotimes micro benchmark from above indicates that it makes no difference at all.
15:15AWizzArdBut looking at the bytecode seems like a reasonable idea.
15:16amalloyAWizzArd: i'm doing that already, i'll let you know
15:16AWizzArdOh good, thx.
15:17simonadameitHi, can I add functions (maybe even private ones) to a deftype without implementing an interface?
15:18AWizzArdsimonadameit: but you still want polymorphism?
15:18AWizzArdBecause otherwise you could just write an ordinary defn or defn- for the private version, which expects one or more instances of a deftype.
15:18raeksimonadameit: if they do not participate in the protocol, you can just have them outside the defrecord form
15:18amalloyAWizzArd: @#'*out* has more obvious work in it: https://gist.github.com/1551956
15:18raekas ordinary functions
15:19simonadameitraek: you mean without specifying them inside the deftype form?
15:19raekyes
15:19AWizzArdamalloy: hmm I see
15:20raek(defn- foo [...] ...) (defrecord Bar [...] SomeProto (some-method [...] ... (foo ...) ...))
15:20amalloymainly because you have to actually call clojure.core/deref, i think
15:20amalloyas compared to just calling .get on the var
15:21AWizzArdamalloy: then I either have to 1) accept this extra work from deref, or 2) duplicte code and write out both fns explicitly or 3) write a macro
15:22simonadameitraek but they wont be implemented as methods directly defined in the class backing the deftype?
15:22raeksimonadameit: yes.
15:23raekthey will be implemented as a method in a function class instead
15:24raekthe reason you want to have protocol methods implemented as java methods is fast polymorphism
15:24simonadameitah, ok.. I dont need polymorphism for these functions
15:24raekbut for a private helper function that is only used in one implementation of the protocol you don't use any polymorphism
15:25raekexactly
15:28simonadameitthanks raek, .. I guess I will have to get used to this separation of function and data :)
15:29AWizzArdamalloy: interesting, it seems there is then no other way to parameterize on dynamic vars.
15:30amalloyhm? you could do .get on the Var with interop instead of using the more generic deref, since you don't need genericity
15:32AWizzArdamalloy: calling .get will probably also result in more code than what you got for (defn foo [] (println *out*)).
15:33amalloynot really. it should just add a single checkcast to that version
15:34amalloyand even that much shouldn't be necessary; if the compiler were able to detect that you only use the value once and always treat it as a Var it could do the cast once and forget it
15:36simonadameitwhat is the name of the protocol that conj is part of?
15:37amalloyit's an interface
15:37amalloyclojure.lang.IPersistentCollection/cons, i think
15:39raeksimonadameit: this can be useful: https://github.com/Chouser/clojure-classes/blob/master/graph-w-legend.png
15:40augustlis there a way to disable all of the built-in pages of noir? Such as the default 404 page for example.
15:41simonadameitraek thanks, thats great
15:43simonadameitis there a performance difference between using extend-type or defining the methods directly in a deftype`
15:43simonadameit?
15:44amalloyyes, but not one that's likely to matter if you're implementing something slower than hello world
15:49bweaverHello, does Clojure memoize regex pattern objects when they're written in the #"..." literal format? I'm writing a predicate function that uses re-matches and wonder if there's a performance advantage to declaring the regexp pattern separately vs using it inline.
15:53amalloythose are reader macros, so the objects should be embedded in the code
15:53amalloyie, no memoization is necessary
15:54raekbweaver: if you're wondering whether #"..." will only instantiate a Pattern once, then yes (IIRC)
15:54bweaverOk, thanks.
15:59Xenocorp_in emacs repl. If I shadow a built-in, how do I reset the repl?
16:03bweaverXenocorp_: You can `(use 'clojure.core)` to re-import all of the core bindings into your namespace. Does that help?
16:04Xenocorp_bweaver: That'll do :)
16:04Xenocorp_Thanks
16:15augustlis there a reference to all the syntax in clojure? Currently trying to find out what the ampersand in (defn foo [& something] ....) means
16:16bweaveraugustl: I find that the cheatsheet is helpful `http://clojure.org/cheatsheet`, most other reader stuff is documented in `http://clojure.org/reader`.
16:17bweaveraugustl: The amphersand captures the rest of the arguments. So in your example, it means `foo` will accept any number of arguments and they'll be bound into a list called `something`.
16:17augustlah that cheat sheet is useful
16:17bweaveraugustl: So, for example, calling `(foo 1 2 3)` will bind `something` to `(list 1 2 3)`.
16:17bweaveraugustl: Or maybe it's a vector.
16:17augustlI see, thanks
16:18amalloyneither, actually. but you get a sequential view of it, which is all that matters
16:19bweaverThanks amalloy :)
16:19amalloy&((fn [& args] (class args)) 1 2 3)
16:19lazybot⇒ clojure.lang.ArraySeq
16:19augustlfound the docs in http://clojure.org/special_forms
16:19augustlfor the record
16:19ScorchinIf I'm using clojure 1.3, how do I add clojure-contrib to my project?
16:22augustlScorchin: I'm using leiningen, I added [org.clojure/clojure-contrib "1.2.0"] to dependencies in project.clj
16:22Scorchinaugustl: is 1.2.0 the latest stable version? The website wasn't very clear on that
16:22technomancyclojurebot: what happened to clojure contrib?
16:22clojurebotIt's greek to me.
16:22technomancyclojurebot: what happened to contrib?
16:22clojurebotWell... it's a long story: http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go
16:22amalloyif you want old-contrib in a 1.3 project, step one is ritual suicide
16:23Scorchintechnomancy: <3
16:23augustlScorchin: don't remember how I found that version number, I remember struggling with that as well
16:30augustlgiven (def foo [:my :vector]) (def bar [:other :vector foo]), is there a way to make the value of bar [:other :vector :my: :vector] instead of [:other :vector [:my: :vector]]?
16:30amroin what case would (print (str (type x))) output nothing?
16:30Scorchininteresting, if I load up a plain repl and type: (clojure.string/split-lines "test \n string") it throws the following error: ClassNotFoundException clojure.string java.net.URLClassLoader$1.run (URLClassLoader.java:202)
16:30ScorchinAnyone what's going on there?
16:31technomancyScorchin: you haven't loaded the clojure.string namespace
16:32bweaveraugustl: `(vec (flatten bar))`?
16:32Scorchintechnomancy: thank you
16:33augustlbweaver: cool, thanks
16:33nick_sIs let free?
16:34bweaveraugustl: You could also use `concat` depending on whether you needed the intermediate nested vector for anything.
16:34nick_sAfter it's compiled that is. Does a let binding have a performance cost associated with it?
16:34amalloyif what you want is [:other :vector :my :vector], then your "given" (def foo [:my :vector]) (def bar [:other :vector foo]) means you started wrong
16:36mcrittenden-afknoir's built in server isn't meant to be used in production, right? and if not, then what are people using?
16:37mcrittenden-afkoh just realized it uses jetty which I assume would be fine in production. never mind.
16:37Xenocorp_apparently at my work we're using two toasters strapped together with an ethernet cord
16:40augustlpastie can't highlight lisps it seems, any suggestions? :)
16:40amalloy~paste
16:40clojurebotpaste is gist
16:40amalloyugh, really?
16:40amalloyclojurebot: forget paste |is| gist
16:40clojurebotI forgot that paste is gist
16:40amalloyclojurebot: paste is https://gist.github.com
16:40clojurebotc'est bon!
16:41technomancypaste is delicious
16:41augustlthanks
16:41ziltiamalloy: pastie.org can highlight Clojure: http://pastie.org/l
16:41augustlsince I don't know much about clojure, it seems to me that these calls would be identical https://gist.github.com/1552241
16:41augustlis there an easy explanation for a noob? :)
16:42augustljust seems to me that (vec (flatten head-extra)) evaulates to a vector, i.e. exactly the same as head-extra
16:42amalloyzilti: i have no opinion about pastie, but he asked for a good pastebin, and that's gist
16:42technomancyflatten?
16:42clojurebotflatten is rarely the right answer. Suppose you need to use a list as your "base type", for example. Usually you only want to flatten a single level, and in that case you're better off with concat. Or, better still, use mapcat to produce a sequence that's shaped right to begin with.
16:42amalloy~botsnack
16:42clojurebotThanks! Can I have chocolate next time
16:42bweaveraugustl: You might want to try appending head-extra instead of inserting it into the vector literal.
16:42ziltiamalloy: I prefer gist, too
16:43amalloybweaver: nah, that shouldn't matter
16:43augustlbweaver: it's nice to keep the literal structure when doing HTML..
16:44augustlanyhow, is "flatten" a special form of some sorts that makes stuff happen under the hood?
16:44amalloyno, flatten is a great evil sent by the devil
16:44bweaveraugustl: no, it's just a function
16:44amalloyincluded only to confuse people into using it when they shouldn't
16:44augustlstill don't quite grok the difference between the two calls, since vec evaulates to a vector (I guess)
16:45amalloyaugustl: the difference is, what if head-extra is [:foo [:bar [:baz]]]
16:45amalloyflatten turns it into [:foo :bar :baz]
16:45augustlthe only thing I can think of is that "flatten" sets some state under the hood that causes clojure to evaulate the vector differently
16:45augustlah we wouldn't want that..
16:46bweaveraugustl: for what it's worth, you might try using quasiquoted lists instead of vectors for representing markup
16:46bweaveraugustl: `(:head (:title "...") ~@head-extra)
16:46amalloybweaver: i have to wonder what position you're giving advice from. hiccup uses vectors
16:46augustlwonder if hiccup supports that
16:46augustlah, right
16:46bweaveramalloy: oh, didn't know that
16:47bweaveramalloy: I'm new to Clojure too and just find quasiquotes convenient. If there's a framework already, then that's definitely more convenient :)(
16:47bweaveramalloy: This is what I was thinking of: http://okmij.org/ftp/Scheme/SXML.html
16:47augustlthe value of head-extra in my case is ["Test test"], so I still don't understand how flatten helps me in this case :)
16:47augustlI do understand it will turn nested lists into flat lists
16:47bweaveraugustl: Sorry augustl, ignore me :)
16:47augustlnot how it "concatinates" vectors into other vectors, inline, sort of
16:47bweaveraugustl: I was assuming something different than what you're trying to do.
16:48amalloyit doesn't help you, flatten never helps, i wish i could remove it from clojure.core
16:48augustlit does actually help me in this situation, though
16:48augustlperhaps my head-extra vector doesn't have the value I think it does..
16:48amalloyno, it obviously doesn't, because (vec (flatten ["foo"])) ie still ["foo"]
16:49amalloyif your goal is to end up with the contents of head-extra dumped into the head, you want ##(doc into)
16:49lazybot⇒ "([to from]); Returns a new coll consisting of to-coll with all of the items of from-coll conjoined."
16:49amalloy(into [:head [:title ...] ...] head-extra)
16:49amalloyor if you prefer, `[:head [:title ...] ... ~@head-extra]
16:50augustlupdated https://gist.github.com/1552241, build-head-3 works and I understand it, so yay :)
16:50augustlamalloy: hmm that's interesting, I wonder why build-head and build-head-2 behaves differently then
16:50augustlthat's good to hear, at least, that means I did actually understand what flatten did ;)
16:50skelternetI've been building tables with hiccup.
16:51augustlamalloy: ah I'll look up the ~@foo syntax
16:51skelternetI noticed some of the tags seem to only respect one parameter the way I had been using them.
16:52technomancywarms my heart seeing all these folks learning Clojure for 2012 =)
16:52cgrayis there any way to get a clear picture of how much memory is actually being used by a clojure process? top just shows how much the jvm has allocated, which i guess is usually more than is used
16:53skelternetfor instance, I had a [:tr (for … (println something) [:td column] … and the td's weren't getting returned
16:53augustlodd, "Attempting to call unbound fn: #'clojure.core/unquote-splicing ", guess I need to import something
16:53skelternetDon't know if that helps, agustl,
16:53skelternetI'm still trying to wrap my head around it.
16:53augustlskelternet: hmm, you probably need to map instead of for looping?
16:53amalloyaugustl: you didn't include `
16:53augustlnot sure what a for loop that prints is doing inside a vector that's supposed to represent HTML :)
16:54skelternetwas just there while debugging…but it seemed to make things worse while it was there :|
16:54skelternetwhen I removed it, life was better
16:54augustlamalloy: include what? :)
16:55cgrayaugustl: the backtick symbol
16:55augustloh
16:55amalloy&(let [x 1] `(:foo ~x))
16:55lazybot⇒ (:foo 1)
17:04clj_newbI need to gain 6000 experience points to advance from clj_newb to clj_novice. What are good clojure codebases to read?
17:04cgrayclj_newb: core.clj is a pretty good place to do some learning
17:05cgrayclj_newb: sorry, I mean clojure.core
17:05amalloydownvote. core is interesting once you already know a lot
17:05amalloybut it contains a ton of stuff that is a Bad Idea in other code because it's bootstrapping
17:05cgraygood point
17:05cgraymaybe the second half of core or so
17:05pandeiroamalloy: anything you'd recommend?
17:06clj_newb"bootstrapping" <-- as in the code is not idiomatic, because clojure idioms requires things in clojure.core ?
17:06amalloyright
17:06clj_newbactually, that sounds awesome; I love understanding how things work
17:07amalloy*shrug* what you should read depends on what you want to learn
17:07clj_newbthe great thing about software, as opposed to hardware is that I don't have to put it back together
17:08clj_newbamalloy: this is an honest question. Why are you so well respexcted in this channel? Did you write some library in clojure.core or clojure.contrib?
17:09amalloyhaha no, it's because i spend a lot of time in here. i have more fun helping out than writing a magnum opus
17:09amalloybut a lot of www.4clojure.com is mine, if you're looking for an excuse to idolize me
17:10clj_newbI merely found it interesting how that whenever you disagree with someone, they just assume you're right. :-)
17:10clj_newbwhat does 4clojure have to do with cheap realestate?
17:10amalloyforeclosure
17:10amalloyit's a pun, you see. not my pun, thank god
17:11cgrayclj_newb: the damn thing is, he is right so much of the time... plus it's just a pretty respectful community in general
17:13augustlclj_newb: currently making a simple web page with Noir. Learning a lot from that.
17:13augustlI got about 200 experience points after a couple of hours!
17:14clj_newbaugustl: lol
17:15clj_newbamalloy: I have an exercise suggestion for 4clojure.com: "Input: a 3SAT formula. Output: in polynomial time, iether true or false, stating whether the formula is staifisable."
17:15amalloyi don't know what 3SAT is. but solve 50 4clojure problems, then you can submit that as a problem yourself
17:18amalloyhaha, were you trolling me? you: "output in polynomial time..." wikipedia: "3-SAT is NP-complete..."
17:22clj_newbamalloy: look up millenium prize -- a solution is worth 1 million dollars. Additionally, it's probably also worth a turing award. :-)
17:22amalloysure, i know. as a kid i figured i would win that prize by solving minesweeper
17:23clj_newbdamn, it is NP complete
17:23clj_newbamalloy: how old are you? the Clay prize isn't that old, and you mention "as a child ..."
17:24amalloyyeah, "kid"
17:24amalloyi must have been like 17 at the time. 26 now
17:46solussdis there something clojure more generic than (Long/parseLong "1367") ?
17:47solussdi.e. something that'll work on any number
17:47amalloy&(doc read-string)
17:47lazybot⇒ "([s]); Reads one object from the string s"
17:47solussd,(read-string "387429837492387492734923794729347923749")
17:47clojurebot387429837492387492734923794729347923749N
17:49wingieis clojure fine to script with?
17:49AWizzArdsolussd: I don’t know about the efficiency, but there is also a .parse method in http://docs.oracle.com/javase/7/docs/api/java/text/DecimalFormat.html available.
17:49wingiecompared to groovy
17:50solussd,(.parse "23984294832.23423")
17:50clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: No matching field found: parse for class java.lang.String>
17:51solussdoh, duh.
17:51AWizzArdYes, I think the String class doesn't provide such a .parse method.
17:53AWizzArdThis DecimalFormat class also provides parsing for some more exotic formats. Though as long read-string works fine I would surely prefer that one.
17:55AWizzArdhttp://docs.oracle.com/javase/tutorial/i18n/format/decimalFormat.html
17:56TimMcsolussd: Just be sure to (binding [*read-eval* false] ...) around that for security.
17:56TimMcwingie: If you don't mind the several-second startup time of the JVM, sure, it's fine to script with.
17:56solussdyeah, I think that's overkill for me. :)
17:57TimMcsolussd: Well, as long as you aren't reading user-generated strings, OK.
17:57solussdoh, you're referring to 'read-string'
17:57TimMcYeah, sorry.
17:58TimMcwingie: Compared to any other JVM language I know of, yes, Clojure is the best for scripting -- LISPs are great for extracting patterns.
17:59solussdTimMc, what could be fed to read-string that would result in evaluation?
17:59TimMc&(read-string "#=(+ 1 2)") ; solussd
17:59lazybotjava.lang.RuntimeException: EvalReader not allowed when *read-eval* is false.
17:59TimMcSemi-undocumented syntax.
18:00solussdyikes
18:00TimMcI've opened a ticket to document that in read and read-string -- it's an "unsupported feature", but the lack of documentation is outright dangerous.
18:00solussdwhat does #= mean exactly?
18:01TimMcsolussd: It means to use the results of evaluating the next form.
18:02TimMcsolussd: Put (read-string "[(+ 1 2) #=(+ 1 2)]") into a REPL.
18:03TimMcclojurebot is stupid, I can demonstrate here:
18:04TimMc,(binding [*read-eval* true] (read-string "[1 2 #=(- 7 4) 4]"))
18:04clojurebot[1 2 3 4]
18:04TimMcThe main use is serializing data structures that don't have literal support.
18:05solussdTimMc: whoa. So I could force evaluation of macro arguments when I pass them
18:05TimMcNot following that.
18:06TimMcSeriously, don't use #= in your code -- it's probably going away.
18:06chipdudeso #=() is a lift macro
18:07solussd(defmacro printform [form] `'~form)
18:07TimMcIt's reader syntax.
18:07wingieTimMc: is there any way to eliminate the startup time for java? (im new to java)
18:07chipdude[1 #=(prn 2) (x)]
18:07chipdude2
18:07chipdudejava.lang.Exception: Unable to resolve symbol: x in this context (NO_SOURCE_FILE:2)
18:08solussdthen I could (printform #=(+ 2 1)) to force it to pass 3
18:09chipdudeTimMc: what will replace it
18:14TimMcchipdude: Nothing official, I'm just guessing.
18:15TimMcI *think* it was mainly used for records, which now have their own (also undocumented!) literal syntax.
18:18TimMctechnomancy: Did you take a look at the no-AOT uberjar example I wrote?
18:24amalloyTimMc: i don't think #= is actually going away anytime soon, but it's definitely something to avoid anyway
18:24TimMcamalloy: Do you know what else it is used for?
18:24amalloy&(print-dup (sorted-set))
18:24lazybotclojure.lang.ArityException: Wrong number of args (1) passed to: core$fn--4023$fn
18:25amalloy&(binding [*print-dup* true] (pr-str (sorted-set)))
18:25lazybotjava.lang.SecurityException: You tripped the alarm! pop-thread-bindings is bad!
18:25TimMcAh, right.
18:25TimMcclojurebot won't mind
18:25amalloydamn it Raynes, can you just let the thread-binding stuff back into the list? he is crippled without binding
18:25amalloy,(binding [*print-dup* true] (pr-str (sorted-set)))
18:26clojurebot"#=(clojure.lang.PersistentTreeSet/create [])"
18:27TimMcamalloy: pop-thread-bindings is only found in the macro expansion -- does clojail really need to inspect the expansion results?
18:27TimMc(Or rather, why.)
18:28amalloy&(macroexpand '(clojure.lang.Compiler/eval foo))
18:28lazybotjava.lang.SecurityException: You tripped the alarm! class clojure.lang.Compiler is bad!
18:29augustlsomeone told me earlier what I had to do to enable ~@ (unquote-splicing), but I didn't grok what it was.. Anyone knows?
18:29augustlgetting "Attempting to call unbound fn: #'clojure.core/unquote-splicing"
18:29amalloyugh, whatever. the point is there are a lot of "special cases" where stuff doesn't look like a problem until it's expanded
18:29skelternetI might have it in a buffer, do you need it or need to grok it?
18:30TimMcamalloy: I see, lots of sugary stuff.
18:31TimMcdoto, etc.
18:31amalloyright. but you make an interesting point, i think
18:31augustlskelternet: need to grok it :)
18:31amalloyi (or Raynes?) just macroexpanded because it seemed like you could hide dangerous things inside a macro
18:32augustlneed to import `, not sure how to do that
18:32chipdudeTimMc: the record syntax is as found here? http://dev.clojure.org/display/design/defrecord+improvements
18:32amalloythere's nothing to import
18:33augustloh, I'm probably using it wrong then
18:33amalloyTimMc: actually i think memfn was the macro that makes it necessary to expand
18:33TimMcAh, right.
18:34TimMcSo you'd have to look at all the things that mess with names and calling. Ugh.
18:34TimMc&`[1 2 3 ~@(list 4 5 6) 7 8] ; augustl
18:34lazybot⇒ [1 2 3 4 5 6 7 8]
18:35technomancyTimMc: yeah, makes it sense
18:36technomancymaybe package it up as a plugin?
18:36TimMcI'm trying to think how exactly.
18:37TimMcThere's also the question of how to indicate that this is the desired behavior.
18:37technomancyif you had it read the main ns out of jar metadata, you could probably just make it a plain old dependency
18:37technomancywouldn't need to be a plugin
18:38TimMcI was thinking a resource like uberjit.properties
18:39TimMcBut no, that's silly -- there might be multiple.
18:40jmdevHi guys
18:40technomancyjar metadata lives in project.clj right next to :main; it makes sense to keep them together
18:41augustlI
18:41augustlerr
18:41augustlI'd appreciate if you could tell me how horrible my build-main-menu from https://gist.github.com/1552654 is, and how it could be better :)
18:42amalloy(defn ... (def)) is evil
18:42augustlI should inline it?
18:42raekaugustl: def is only for global constants
18:42amalloyno, you should never use def inside a defn
18:42amalloyyou want let
18:43augustlah
18:43augustla "minor" oversight..
18:43skelternetwould the inner def survive outside of the scope?
18:43skelternettag-attrs in this case?
18:43raekskelternet: it will mutate a global variable
18:43augustlI'm curious if my use of concat of vectors makes sense. Not used to functional programming and static collections
18:44augustland if having a build-main-menu-iter makes sense. Inspired by SICP which I just started reading ;)
18:44yoklovhaha i thought your code looked like scheme code
18:44yoklovbut wasn't going to say anything because mine does too lol
18:44augustlrecur is the only "trick" I learned so far ;)
18:45TimMcskelternet: The inner def would not become defined until that function had been called.
18:46amalloythe manual recursion looks a lot like a map or a mapcat or something
18:46skelternetI thought mutations to it were stacked and thread-specific. I must be thinking of bind
18:46amalloybut it's hard to tell because you wrote it as manual recursion and now it takes all this effort to read :P
18:46augustlguess I could use conj instead of concat-ing vectors
18:46augustlamalloy: hehe, the idea is that I need to pass active-menu to the calls to build-main-menu-item
18:46augustlseems that map only passes the item in the collection and doesn't support arbitrary params
18:47raekskelternet: yes, when using 'binding' and 'set!'
18:47arohnerusing clj-http, is there any way to set a lower timeout for a request? i.e. "throw if this request takes more than N seconds to finish"?
18:47augustlhmm seems conj isn't what I need
18:48skelternetdef will just mutate it…whenever def gets eval'd? that would be much more difficult to reason about
18:48raekbut 'def' is for those cases when you unconditionally want to change a global in all threads (unthreadsafely) -- nameley when fixing existing code
18:48amalloy(defn build-main-menu [active-menu] (mapcat #(build-main-menu-item % active-menu) main-menu-links))?
18:48raekskelternet: yes
18:48raekit should normally only be used on the top level
18:48skelternetsame for defn?
18:48raekyes
18:48augustlamalloy: ah, mapcat looks nice
18:49raekthink of 'def' as define global / repair broken global
18:49augustland #() is shorthand for a lambda/anon function right?
18:49yoklovyes
18:50raekskelternet: (defn foo ...) is just a shorthand for (def foo (fn ...))
18:50yoklovyou can also use fn which is the same as lambda.
18:50raekit's a macro
18:50augustlhah, awesome
18:51skelternet(dreaming of swapping out implementations of a protocol mid-execution)
18:51augustlnow it's just https://gist.github.com/1552654
18:51augustltime to open The Joy of Clojure and grok what the % does :)
18:51yoklovit's the parameter for the #() function shorthand.
18:52TimMc%`#(+ %1 %3)
18:52TimMc&`#(+ %1 %3)
18:52lazybot⇒ (fn* [p1__14814__14817__auto__ p2__14816__14818__auto__ p3__14815__14819__auto__] (clojure.core/+ p1__14814__14817__auto__ p3__14815__14819__auto__))
18:52augustlupdated it to use just map (still https://gist.github.com/1552654)
18:52skelternetit's almost built-in obfuscation
18:53amalloyyeah, the mapcat was (i think) replicating what you were doing but didn't make sense to me
18:53raek,(* (+ (+) (+) (+)) (+ (+) (+)) (+ (+) (+)))
18:53clojurebot0
18:54raekright
18:54raek,(* (+ (*) (*) (*)) (+ (*) (*)) (+ (*) (*)))
18:54clojurebot12
18:54raekdon't forget to obfuscate your number constants!
18:54chipduderaek: it's at times like these I wish the mathematicians would go back to paper and leave us to our ones and zeroes
18:55augustlwhat's the % called?
18:55augustlhard to google..
18:55amalloypercent
18:55TimMchaha
18:55augustlI mean the use of % in clojure, silly
18:55augustlor in that particular situation, even
18:55skelternetoh…anon function?
18:56augustlisn't #() the anon function part?
18:56yoklovargument?
18:56TimMcaugustl: The whole thing is referred to as a "function literal". I think that's as close as you're going to get.
18:56yoklovhttp://clojure.org/reader under "anonymous function literal"
18:56TimMcaugustl: Right, and % is just captured by the macro.
18:56augustlso the % in #(build-main-menu-item % active-menu) is part of the #() syntax, which is the function literal syntax?
18:56augustlah
18:57augustlthanks, folks
18:57amalloyweird to use the word "literal" in that context
18:57TimMc(It might not be a macro technically, but it basically acts as one.)
18:57augustlso % is about macros
18:57TimMcNope.
18:57yoklovit's a reader macro, not a normal macro
18:57amalloynothing about macros except in a very uninteresting sense
18:58raek,(read-string "#(foo % bar)")
18:58clojurebot(fn* [p1__81#] (foo p1__81# bar))
18:58amalloyraek: easier to just quote it
18:59raekamalloy: true.
18:59amalloy,'#(foo % bar)
18:59clojurebot(fn* [p1__106#] (foo p1__106# bar))
18:59TimMcamalloy: Can you think of any normal macros in Clojure that capture symbols?
18:59TimMctry/catch is a special form...
18:59raekTimMc: I think 'proxy' does it with the 'this' parameter
18:59augustlhmmmmmm
18:59augustlah right of course
18:59amalloyyeah, good call raek
18:59raekI don't think it's considered good style, though
18:59augustlit just creates an anonymous function that calls the original function and passes active-menu to it
19:00TimMc&(let [% 5] 5)
19:00lazybot⇒ 5
19:00augustlso it's the same as (fn [index] (build-main-menu-item index active-menu))
19:00augustlright?
19:00TimMcbah
19:00TimMc&(let [% 5] %)
19:00lazybot⇒ 5
19:00amalloyyes
19:00yoklovaugustl: right
19:01augustland % is the way you reference args in #()
19:01TimMcaugustl: %1, %2, %3... -- yes
19:01TimMc% is %1
19:01augustlyay :)
19:01augustlthanks again folks
19:01yoklovoh huh, you can use `this' inside proxy?
19:01raekthe highest number used determines how many arguments the function takes
19:02augustlraek: that's useful, thanks
19:02TimMcAnd there's %& for rest args.
19:03TimMcA function with %1, %5, and %& in it will effectively have the formal params [p1 p2 p3 p4 p5 & pmore].
19:04augustland this is not related to the #() macro? I'm guessing you can't do (fn [] (stuff %1 %5)) though
19:04TimMcIt's only #().
19:04augustlI see
19:04TimMcaugustl: Try using syntax-quote (`) on function literals; see how they expand.
19:05augustlwill do :)
19:05TimMcThey'll be ugly because of double gensym'ing.
19:05augustlhaven't learned a new language for quite some time now. It's pretty mind blowingly awesome.
19:06augustlit being clojure probably helps too
19:08raekTimMc: augustl: ordinary quote (') works fine for this purpose as well
19:09raekas amalloy showed before
19:09TimMcraek: Ooh, right -- and only a single level of gensym.
19:10amalloy&`#(%)
19:10lazybot⇒ (fn* [p1__14849__14850__auto__] (p1__14849__14850__auto__))
19:10augustlaww, arrow keys doesn't work in the repl
19:10amalloyheh, i never realized that would have multiple gensyms. funny, TimMc
19:11TimMcaugustl: Are you using leiningen? Install rlwrap, lein will pick it up.
19:15solussdin 1.3, where do I get zip-filter? I see clojure.data.zip, but it is "the future home of zip-filter"… :/
19:20TimMcsolussd: I think it's correct.
19:21solussdTimMc, k. so I can't add it as a dependency in my leiningen project.clj?
19:22TimMcNo, I mean I think it's the new location.
19:24augustlTimMc: I'm using leiningen yes, thanks for the tip
19:25augustlTimMc: that's better :)
19:25TimMcI can't be arsed to file a ticket to get them to fix the README.
19:28technomancyquick poll: what's the path to tools.jar vs (System/getProperty "java.home") for the JDK you use?
19:29quizmehow do you write to a file from a ByteBuffer?
19:30TimMctechnomancy: Can't find it, OpenJDK Runtime Environment (IcedTea6 1.9.10) (6b20-1.9.10-0ubuntu1~10.10.2)
19:30TimMcOpenJDK Client VM (build 19.0-b09, mixed mode, sharing)
19:30technomancyTimMc: whoa; a client JVM? are you running a 64-bit OS?
19:30yoklovsomeone mentioned that #^type was deprecated in favor of ^type. is there any difference between those, or is it being deprecated because ^type looks nicer?
19:31TimMctechnomancy: Linux kibble 2.6.35-30-generic #61-Ubuntu SMP Tue Oct 11 15:29:15 UTC 2011 i686 GNU/Linux
19:31quizmeI tried this: (let [fout (-> dest java.io.FileOutputStream. .getChannel)] (do (.write fout buf) (.close fout)) but it's not writing. (actually it's a HeapByteBuffer
19:31TimMcdoesn't look like it!
19:31technomancyTimMc: bummer; I was hoping you had found a way to run a client JVM on a 64-bit system without compiling your own. =\
19:31technomancydidn't realize people still used 32-bit Oses
19:32TimMctechnomancy: That laptop is from 2005.
19:32technomancywell there ya go
19:34TimMctechnomancy: I don't like specifying the uberjit loader namespace as :main -- it confuses the reader, and more importantly, the REPL.
19:34technomancyhm; in that case you'd need a plugin
19:35TimMcAnd as for my Ubuntu Natty machine, OpenJDK 1.6.0_22 (x64, Server) does not have an obvious tools.jar either.
19:36technomancyfind /usr/lib/jvm -name tools.jar gives nada?
19:36TimMcNo, that's wrong -- it's down a level!
19:37cgraytechnomancy: /usr/lib/jvm/java-6-openjdk-i386/lib/tools.jar and "/usr/lib/jvm/java-6-openjdk-i386/jre"
19:37technomancycool; thanks
19:37technomancycgray: what OS?
19:38cgraytechnomancy: debian gnu/linux
19:38technomancycool.
19:38technomancyhow bout any macosecksists?
19:38TimMctechnomancy: ../lib/tools.jar on my Server VM, nothing in my Client VM (except /usr/lib/jvm/java-1.5.0-gcj-4.4/lib/tools.jar)
19:38technomancyyeah... I don't think gcj really counts
19:39TimMcheh
19:49technomancyswitching swank-clojure's default branch back to master; woo
20:01TimMcamalloy: Your clojopts project -- any plans to make a 1.3 release?
20:03amalloyTimMc: it's been like a year since i touched it; you're probably better off using tools.cli, though i'd love to hear why you like clojopts better
20:03TimMcamalloy: Well, it's the only thing I saw when I searched for "clojure getopt". :-P
20:04amalloywell, to be fair that's what i do that's better than cli. he rolls his own option parser which imo kinda sucks
20:04amalloyi used the java port of gnu getopt
20:06TimMcamalloy: I was looking at making clojopts 1.3 compatible. The reliance on contrib is contrib.seqs/separate (which is easy to replicate) and macro-do from your macro-utils.
20:07TimMcI can't tell what macro-do macro-does.
20:07amalloyTimMc: depend on useful instead of amalloy-utils
20:07amalloytemplating: (macro-do [name val] `(def ~name ~val) foo 1, bar 2) => (do (def foo 1) (def bar 2))
20:08amalloyTimMc: if you wind up preferring clojopts but find it's missing a feature or two then a fork would be lovely. ISTR it was hard (even for me) to figure out the syntax for using clojopts, so hopefully i documented it
20:08TimMcYou did.
20:41TimMcamalloy: Using useful would pin it to 1.3 -- what are your thoughts on maintaining backwards compat?
20:41amalloyTimMc: useful doesn't depend on anything in 1.3
20:41TimMcOK, sweet.
20:41TimMcRight, that's a soft dependency in project.clj.
21:00TimMcamalloy: Sweet, that was simple enough: https://github.com/timmc/clojopts/commit/5d243ffc03600e04765d49df46b36145aa8b2dee
21:03amalloyawesome, tests
21:08TimMcamalloy: Should I make the juxt change and do a pull request, or what?
21:09amalloyyeah, send off a pull request and i'll be happy to release to clojars
21:14TimMcamalloy: done
21:18itamarwhat do most people use for networking with clojure? aleph?
21:18amalloyTimMc: 0.3.2 on clojars
21:19TimMcyay
21:21amalloyalso, "a juxty thing because heck yes". i'm concerned you may be conning me into marrying you
21:21TimMchaha
21:35technomancyitamar: "networking" is a bit too vague to be useful
21:37rienRaynes: it's been a few weeks, no reply whatsoever (re nixeagle's live emacs buffer)
21:40devnto anyone out there reading: start a clojure meetup group in your area if one does not exist. there is a coupon for clojure meetup group organizers provided by meetup.com. I started this group roughly 1 year ago and the people I've found have been incredible
21:41skelternetI wonder if there is one in Austin. I know there was a fp group at one point
21:41devnwe have haskellites, scalaphiles, clojurians, schemers, lispers, and more -- a great group of people to meet and talk to.
21:41amalloya coupon? does meetup cost money?
21:42itamartechnomancy: custom TCP server, say
21:42devnamalloy: it does -- i dont even remember the specifics of what is and isnt included. all i remember is they offered a discount to clojure organizers. i will give them money even if that only means a free stick of gum or something
21:43devnjust for the support for the clojure community
21:43devnspeaking of which -- i keep looking at clojure open source projects. how do i pay for them? :)
21:44devn"needs moar donation buttonz"
21:45TimMcbitcoin ^_^
21:53TimMcThe tricky bit is dividing the loot.
21:53devnI'll give it to the EFF as a donation from the clojure community or something. i dont care who gets it, just want to share my appreciation with dollar bills yall.
22:38TimMcamalloy: clojopts doesn't handle --nil=foo very well. :-)
22:38amalloyinteresting
22:39amalloyi mean, it doesn't really matter of course, but i wonder why
22:40TimMcamalloy: Easy, you're using a macro to pick up symbols.
22:40TimMcJust like that conversation the other day.
22:40amalloyoh, you mean if you specify nil in the clojure spec-thingy
22:41amalloyi see
22:41TimMcyep
22:41amalloyi was trying to find where nil would upset the parsing code, not the spec code
22:42amalloyTimMc: a more interesting point that this implies is that you can't parse options like -1, the way head/tail do
22:42TimMcAh.
22:42amalloybut i don't think getopt can either; head must roll its own
22:43TimMcCan't it?
22:43TimMcI have clojopts open, I'll try modifying it.
22:43amalloyTimMc: to be clear, i'm talking about 1 as an option "name" (key), not value
22:44TimMcyep
22:44ermnikhow might one add a class to an element in hiccup? Like ckeditor to the text-area element?
22:44amalloy[:foo.editor]
22:46ermnikfrom the docs: (text-area name value)
22:46ermnikwhere would [:foo.editor] go?
22:47ermnikOr would i be using a more generic element function in hiccup?
22:47TimMcamalloy: You and your use of ` outside of macros...
22:47amalloyi think you should read the docstring, or possibly the source, for text-area
22:48amalloyTimMc: looking back over `man getopt`, i still don't see a thing like "call this function if you see an unrecognized argname"
22:48amalloyTimMc: which one are you thinking of? desugar-spec or something?
22:48TimMcyeah
22:49amalloywell, that's really in a macro anyway
22:49TimMcI mean, it reads nicely, but ` still says to me "Oh shit, here comes an s^w^w a macro!"
22:49amalloyhahaha
22:50amalloyit's just a helper function; not really the same thing as using `(~@x 0) as a shorthand for (concat x [0])
22:50TimMcOh, it's called from a macro, I see.
22:50adiabaticwhat would "an s" be? sexpr?
22:50ermnikamalloy: I took your advice... so text-area just returns a vector, second element of which is a map of attributes. should I assoc a :class in there?
22:50amalloy$google apostrophe oh shit here comes an s
22:50lazybot[Oh shit, here comes an 's'. - Reddit] http://www.reddit.com/comments/65hz7/the_apostrophe_key_does_not_mean_holy_shit_here
22:51TimMcadiabatic: http://www.reddit.com/comments/65hz7/the_apostrophe_key_does_not_mean_holy_shit_here
22:51TimMcbah, slowternets
22:51adiabaticah, thanks
22:51TimMcBing had no idea what I was talking about.
22:52amalloyi'm glad lazybot got it right
22:52TimMcI think my trial of that particular search engine is over.
22:52amalloyermnik: i would just take the very simple code text-area contains and replicate it yourself, since it doesn't seem to have a feature for adding anything but an id
22:56TimMcamalloy: -1 works fine. desugar calls str on the names, but nil goes to ""
22:56amalloyTimMc: but does getopt actually parse it?
22:56TimMcamalloy: Yeah, ["-1" "foo"] => {:1 "foo"}
22:57amalloythat's pretty amazing
22:57TimMc--1 didn't work, of course -- then I fixed my code.
22:59TimMcI think I'll bundle that in with some doc fixes.
23:09technomancydevn: what does meetup get you over a static site?
23:21alexbaranoskydevn: I'd also like to know what meetup gets you
23:27rientechnomancy: findability
23:28alexbaranoskyso I'm looking into how to add mocking of java methods to Midje -- anyone have any opinions on a good way to approach it?
23:30alexbaranoskyI envisioned it looking something like: `(fact (doubler ..x..) => "AA" (provided (.toString Object ..x..) => "A") )`
23:31alexbaranoskybut mostly I'm lost :)