2012-01-02
| 00:00 | technomancy | it 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:01 | bitops | technomancy: I may be misremembering, but I thought I had read that contrib was bundled with the clojure jar? |
| 00:01 | technomancy | no, contrib has been split up into a bunch of separate jars now |
| 00:01 | bitops | right, I saw that from the link(s) above |
| 00:02 | bitops | it'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:03 | graphbum | since 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:03 | bitops | ah okay |
| 00:03 | graphbum | you can do that a number of ways.... |
| 00:04 | bitops | I'll go out on a limb and assume leiningen is the easiest way? |
| 00:04 | graphbum | that's what technomancy was saying |
| 00:04 | amalloy | clojurebot: leiningen is always the easiest way |
| 00:04 | clojurebot | Ack. Ack. |
| 00:04 | bitops | if the right thing to do is having a "playground" project I'm all for that |
| 00:04 | amalloy | bitops: yes, sounds good |
| 00:05 | bitops | that'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:05 | graphbum | so you'd like.... "lein new playground" somewhere |
| 00:05 | bitops | graphbum: what if I have some existing files I want to leiningenify? |
| 00:06 | graphbum | lein will make the structure for you and populate it with some stuff, namely a project.clj I believe |
| 00:06 | graphbum | you can dump whatever you want in there |
| 00:06 | graphbum | in the directory |
| 00:06 | bitops | ah, just tried it. pretty painless |
| 00:07 | graphbum | you set dependencies inside project.clj |
| 00:07 | technomancy | it's not really the standard library |
| 00:07 | bitops | well geez, when's the pain going to start?! I was expecting a yak to show up any old time now. |
| 00:07 | bitops | :P |
| 00:07 | technomancy | the standard library is just clojure.set/xml/zip/test/etc that comes with the jar |
| 00:07 | amalloy | right. the standard library is the stuff that *does* come with clojure. functions like map, filter, reduce |
| 00:09 | graphbum | there's some really useful shit in contrib though... |
| 00:09 | graphbum | useful for me at least |
| 00:10 | amalloy | there's some really useful stuff in ring too, but that doesn't make it part of the clojure stdlib |
| 00:13 | graphbum | right....except some of that really useful shit from contrib did become part of the standard lib....because it was useful |
| 00:14 | bitops | technomancy: 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:14 | technomancy | bitops: I usually try http://search.maven.org |
| 00:16 | bitops | technomancy: 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:16 | technomancy | if you do "lein help tutorial" it should have you covered |
| 00:16 | technomancy | you can skim to the part about adding deps, but at some point you should read the whole thing |
| 00:17 | bitops | technomancy: ah okay, thank you, I'll do that |
| 00:17 | bitops | thanks for all the help! much appreciated :) |
| 00:17 | technomancy | sure |
| 00:50 | graphbum | did the old repl-utils from clojure.contrib make it into the new modular stuff under 1.3? |
| 00:50 | graphbum | trying to grab what used to be clojure.contrib.repl-utils/show |
| 00:52 | amalloy | clojure.reflect/reflect |
| 00:52 | graphbum | nice, thanks. |
| 01:26 | graphbum | wow...i did not realize how disruptive 1.3 would be against 1.2 projects I had |
| 02:14 | replaca | technomancy: still around? |
| 04:14 | tomoj | is there a better way than @(promise) to cause a thread to just do nothing |
| 04:20 | amalloy | (.wait (Object.))? |
| 04:31 | tomoj | I just get an IllegalMonitorStateException |
| 04:38 | woodz | You 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:40 | tomoj | so (let [o (Object.)] (locking o (.wait o))) ? |
| 04:41 | amalloy | well @(promise) has got to be better than that |
| 04:41 | Fossi | :D |
| 04:41 | woodz | Yes, 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:41 | amalloy | woodz: that was the point |
| 04:41 | tomoj | that's the goal |
| 04:42 | woodz | I joined the conversation a bit late, so missed that bit :-) |
| 04:42 | tomoj | if the thread dies, it will be reborn elsewhere automatically |
| 04:42 | woodz | ok |
| 04:42 | amalloy | fwiw, @(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:44 | amalloy | &(doc monitor-enter) |
| 04:44 | lazybot | ⇒ "Special: monitor-enter; Synchronization primitive that should be avoided\n in user code. Use the 'locking' macro." |
| 04:44 | amalloy | super-efficient! you can refuse to include the monitor-exit that (locking) would introduce :) |
| 04:45 | amalloy | saving 100% (and also 0%) of the cpu cycles that would be spent on that |
| 04:48 | wiseen | https://github.com/wiseen/core.observable - I wrote a .NET RX event handling library for clojure/clojurescript |
| 07:31 | rangen | why 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:32 | rangen | full 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:35 | holo | hello |
| 07:35 | holo | can someone tell me a very simple case of use (actually useful) for "let" form? |
| 07:41 | Chousuke | uhh... any time you want a local variable? |
| 07:41 | Chousuke | which is not that uncommon |
| 07:42 | Chousuke | or do you use only global variables and literals in your programs? :P |
| 07:46 | Chousuke | holo: 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:47 | Chousuke | though 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:47 | Chousuke | I mean closures are common, not counters. :P |
| 07:57 | holo | chousuke, 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:00 | Chousuke | I'm sure you'll find lots of uses for let once you start writing code, then |
| 08:02 | Fossi | for me the most common occurrence is: (let [foo (some-"expensive"-calculation bar baz)] (dothis foo) (dothat foo)) |
| 08:03 | Fossi | and expensive can also be hard/annoying to write twice ;) |
| 08:05 | Fossi | hmm i guess: (let [foo (some-"expensive"-calculation bar baz) quux (some-transformation)] (dothis quux) (dothat foo)) is even used more often :) |
| 08:05 | Fossi | as in saving something for later |
| 08:09 | holo | Fossi, at the second example there is no reutilization of results |
| 08:11 | holo | OK, I guess its cleaner and there is an implicit "do" by using let |
| 08:13 | Fossi | ups |
| 08:14 | Fossi | i meant to write (some-transformation foo) |
| 08:18 | holo | I see, but for a language which returns an expression by being functional looks to have a strong imperative flavour |
| 08:19 | Fossi | well, let isnt needed if your code is purely functional |
| 08:19 | Fossi | other than saving you lots of typing |
| 08:20 | Fossi | oh, and save computation |
| 08:20 | Fossi | but not strictly needed, no |
| 08:20 | raek | if the value of one expression is needed in multiple expressions, you still need let in purely functional code |
| 08:21 | Fossi | you can recompute it then |
| 08:22 | raek | holo: why does Clojure look to have a strong imperative flavour? |
| 08:23 | Fossi | i think "let" does |
| 08:24 | holo | raek, 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:25 | antares_ | 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:27 | holo | in caml, let in the toplevel would create global variables. if used inside something like those examples from Rossi, it would create local variables |
| 08:29 | raek | I 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:33 | Fossi | raek: well, you could disallow that |
| 09:29 | nickik | I want to reset up my emacs. Witch is the best current tutorial to get emacs/Starter Kid/Clojre Mode/slime/swank working? |
| 09:45 | CrazyWoods | how to use clojure to start a GUI project? |
| 09:46 | vimja | nickik: i used http://data-sorcery.org/2009/12/20/getting-started/ to get started |
| 09:46 | benoyst | nickik: I've also found this one interesting: http://postposttechnical.com/2011/11/first-steps-with-clojure/ |
| 09:51 | benoyst | CrazyWoods: I've read a very exciting article a few days ago: http://blog.darevay.com/2011/12/a-seesaw-tutorial/ |
| 09:51 | benoyst | Hope this helps. |
| 09:53 | CrazyWoods | benoyst, thank you |
| 09:53 | Fossi | that looks almost nice :) |
| 09:54 | benoyst | indeed |
| 10:01 | Fossi | does anyone know a tutorial on debugging java via emacs/swank? does that even work? |
| 10:14 | zilti | Does someone here use SQLKorma? What type does exec return for a select query? |
| 10:35 | bhenry | is there a way to use binding on something qualified as alias/var where alias is the last part of (require '[namespace :as alias]) |
| 10:38 | Raynes | bhenry: If I understand your question right, then there is nothing stopping you. |
| 10:47 | lypanov | if i use someones library that has a line saying (def *vm-session-type* "gui") |
| 10:47 | lypanov | how can i change the value for my usage of the library? |
| 10:47 | lypanov | i assume thats what its for.. |
| 10:49 | bhenry | lypanov: &&(doc binding) |
| 10:57 | zilti | Now 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:58 | skelternet | is it accessing it for write? |
| 10:59 | skelternet | oh…Reflector |
| 10:59 | zilti | I'm playing around in the repl and did a (def digest (Whirlpool/DIGESTBYTES)) |
| 11:01 | zilti | Any 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:02 | raek | zilti: what is DIGESTBYTES? a method or a field? |
| 11:02 | zilti | A static field |
| 11:02 | raek | then you should do this: (def digest Whirlpool/DIGESTBYTES) |
| 11:03 | raek | the extra parens means method call |
| 11:03 | zilti | Hmm 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:08 | lynaghk | Has anyone defined multimethods in ClojureScript before? I'm having some namespace troubles excluding clojure.core/+ |
| 11:08 | lynaghk | https://gist.github.com/1551222 |
| 11:13 | zilti | Pro-tip: Declare a class as "public" if you want to access it from another namespace... |
| 11:16 | yoklov | is there any slowdown associated with metadata |
| 11:17 | yoklov | actually no nevermind it'll still be way faster than the numerical calculations I'm doing. |
| 11:21 | zilti | I 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:32 | chouser | pods, if only they existed. |
| 11:42 | TimMc | chouser: pods? A web search didn't reveal anything. |
| 11:43 | chouser | yeah, they don't exist |
| 11:43 | lynaghk | It's a planned construct that Rich talked about at the Conj |
| 11:43 | chouser | http://kotka.de/blog/2010/12/What_are_Pods.html |
| 11:43 | TimMc | Ah, got it. I took it to be something that existed in some other language. |
| 11:48 | zilti | That's a pity... But how should I do it? I'm quite new to concurrency, especially in Clojure |
| 11:51 | TimMc | zilti: It's a single instance that you need to coordinate access to from multiple Clojure threads? |
| 11:51 | TimMc | Maybe you could send thunks to an agent that controls the instance. |
| 11:52 | cemerick | That, or there's always `locking`. :-P |
| 11:52 | TimMc | Point. |
| 11:53 | raek | (def foo-lock (Object.)) (defn foo [...] (locking foo-lock ...)) |
| 11:53 | zilti | But 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:54 | zilti | So I had something like a "queue" in mind that just puts the other threads trying to access in a "sleep" state |
| 11:54 | TimMc | zilti: locking pauses the thread |
| 11:55 | zilti | Ok, then I'll do locking |
| 11:55 | raek | zilti: have you checked you java.util.concurrent.BlockingQueue? |
| 11:55 | raek | http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/BlockingQueue.html |
| 11:55 | raek | *checked out |
| 11:55 | TimMc | If 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:56 | zilti | Yes, 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:57 | jodaro` | so i'm messing around with aleph/lamina/gloss stuff |
| 11:57 | jodaro` | using tcp-client to interact with a server that uses a binary protocol |
| 11:57 | jodaro` | i've specified a frame to handle the request |
| 11:57 | cemerick | zilti: `locking` uses a Java monitor, just like `synchronized`. |
| 11:58 | jodaro` | enqueue it on the connection |
| 11:58 | jodaro` | and receive-all the response |
| 11:58 | jodaro` | everything appears to work correctly but i'm noticing that my respone is also being decoded using said frame |
| 11:58 | jodaro` | which happens to work, but what if i wanted to use a different codec for the response |
| 12:00 | jodaro | oh |
| 12:00 | jodaro | looks like i can specify an encoder and decoder |
| 12:04 | dbushenko | hi all! |
| 12:04 | dbushenko | what's the ultimate mongodb clojar? |
| 12:08 | solussd | when 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:11 | cemerick | solussd: XML is textual; there's no reason to expect it to natively round-trip other data types. |
| 12:12 | cemerick | You could speculatively parse attributes using clojure.walk |
| 12:14 | solussd | cemerick: hm. too bad clojure.xml/parse can't be fed a schema |
| 12:16 | cemerick | solussd: schemas aren't supported in the JDK IIRC. |
| 12:17 | cemerick | OK, so that's wrong. |
| 12:17 | cemerick | I should say, I think schemas can only be used to validate. |
| 12:40 | solussd | how do you list all of the interfsaces/protocols a type implements? |
| 12:47 | Scorchin | I 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:49 | yoklov | Scorchin: if it's in a let or a function you could use destructuring |
| 12:50 | Scorchin | yoklov: thanks, I'll check that out |
| 12:56 | yoklov | Scorchin: something like this ##(let [[[fst snd trd]] (list (vector "h1. " "h1" ""))] snd) |
| 12:56 | lazybot | ⇒ "h1" |
| 12:57 | yoklov | though, thats still somewhat awkward. |
| 13:02 | flashingpumpkin | hey 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:05 | Chousuke | flashingpumpkin: that sort of stuff usually happens when there are multiple similar constructors |
| 13:06 | Chousuke | flashingpumpkin: try typehinting the vertex argument, or force the integer literals to be ints with (int 3) |
| 13:06 | flashingpumpkin | Chousuke, there are indeed multiple constructors. But, I'm just rewriting the Java example (that works) into Clojure. |
| 13:06 | flashingpumpkin | Chousuke, ok, trying :) |
| 13:08 | yoklov | that ctor has varargs in java, does that mean anything for the clojure interop/ |
| 13:09 | flashingpumpkin | Chousuke, nope. Both does not work. Here's maybe more context for the Mesh constructors: https://gist.github.com/153d4bc319da0b0f9efd |
| 13:09 | yoklov | try putting the vertex in an array |
| 13:10 | yoklov | (to-array [vertex]) maybe? |
| 13:11 | flashingpumpkin | yoklov, nope |
| 13:11 | Chousuke | looks like it should work if you typehint the vertex |
| 13:11 | Chousuke | did you try typehinting it and forcing the 3s to ints at the same time? |
| 13:12 | flashingpumpkin | Chousuke, yes |
| 13:12 | flashingpumpkin | (to-array [^VertexAttribute vertex]) |
| 13:14 | flashingpumpkin | I had no idea there is such a thing as varargs in java. |
| 13:14 | yoklov | Err, 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:15 | jodaro | ok, another gloss question |
| 13:16 | jodaro | if i have something like |
| 13:16 | jodaro | foo\0bar\0baz |
| 13:17 | jodaro | is (repeated (string :utf-8 :delimiters ["\0 |
| 13:17 | jodaro | "])) |
| 13:17 | jodaro | the right way? |
| 13:20 | TimMc | I guess try it out? |
| 13:20 | jodaro | yeah |
| 13:20 | jodaro | its the 4 part of the protocol |
| 13:20 | TimMc | My only question would be whether there is a final delimiter. I guess there has to be. |
| 13:20 | jodaro | fourth part of a response, actually |
| 13:21 | yoklov | What's the difference between typehinting with #^type and ^type? |
| 13:22 | amro | is there a way to get more information out of "No value supplied for key: true"? |
| 13:22 | TimMc | yoklov: The latter is deprecated. |
| 13:22 | yoklov | otherwise they're the same? |
| 13:22 | clojurebot | I don't understand. |
| 13:23 | TimMc | amro: Are you trying to build a map? |
| 13:23 | TimMc | I mean, what is the context? |
| 13:23 | mattmitchell | jodaro: in your example, what is "string" ? |
| 13:24 | clj_newb | this 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:24 | TimMc | yoklov: Wait, maybe it's the other way around... |
| 13:24 | clj_newb | (I was under the impression taht LLVM = the uber JIT, using the latest + best in research tech) |
| 13:25 | amro | TimMc: 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:25 | TimMc | yoklov: Right, ^ is the correct form. |
| 13:25 | amro | I fixed it since, but I'd still like to know for future reference |
| 13:28 | TimMc | &{:a 1 :b} |
| 13:28 | lazybot | java.lang.RuntimeException: Map literal must contain an even number of forms |
| 13:28 | jodaro | mattmitchell: its part of gloss |
| 13:28 | TimMc | So, not that error... |
| 13:28 | jodaro | https://github.com/ztellman/gloss/wiki/Introduction |
| 13:28 | TimMc | &(hahs-map :a 1 :b) |
| 13:28 | lazybot | java.lang.RuntimeException: Unable to resolve symbol: hahs-map in this context |
| 13:28 | TimMc | &(hash-map :a 1 :b) |
| 13:28 | lazybot | java.lang.IllegalArgumentException: No value supplied for key: :b |
| 13:28 | TimMc | amro: ^ that's what was happening in the lib. |
| 13:28 | lypanov | clj_newb: many people don't have much of a clue about it :) |
| 13:29 | lypanov | clj_newb: but using llvm would be a huge amount of work. it'd require custom optimization passes |
| 13:29 | lypanov | the JVM does a crazy amount of stuff. |
| 13:29 | sritchie | hey guys, I'm running into what might be a bug with inlined functions |
| 13:29 | sritchie | https://gist.github.com/1551640 |
| 13:30 | TimMc | &((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:30 | lazybot | java.lang.IllegalArgumentException: No value supplied for key: :b |
| 13:30 | sritchie | the environment seems to be interpreting ^bytes as a var, not a type hint |
| 13:30 | jodaro | hrm |
| 13:30 | sritchie | but only the second time I evaluate that form |
| 13:31 | jodaro | that "works", but the resulting byte buffers seem to be longer than i expect |
| 13:31 | jodaro | if i encode ["foo" "bar"] |
| 13:31 | yoklov | clj_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:31 | jodaro | i guess i'd expect 8 bytes |
| 13:33 | TimMc | sritchie: "Can't type hint a local with a primitive initializer" |
| 13:34 | clj_newb | lypanov , yoklov: so the core is: "JIT in Java is automatic. JIT in LLVM requires manual work." ? |
| 13:34 | sritchie | TimMc: yeah, hinting the original x and y doesn't pass through to the inline definition, unfortunately |
| 13:34 | sritchie | TimMc: can you think of any way to hint those arguments? |
| 13:35 | TimMc | sritchie: Never mind, that was my bad -- I was passing in junk. |
| 13:35 | TimMc | and I get the exception you see on the first call. |
| 13:36 | TimMc | sritchie: (java.util.Arrays/equals ^bytes ~x ^bytes ~y) |
| 13:37 | TimMc | sritchie: Also, you might use reduce. |
| 13:38 | amro | TimMc: thanks |
| 13:38 | TimMc | sritchie: The reduce idea might need work... |
| 13:38 | amro | but it said true, not :true, so it was building a map with true as a key I guess? |
| 13:38 | TimMc | amro: That's my guess. |
| 13:39 | TimMc | &(hash-map true) |
| 13:39 | lazybot | java.lang.IllegalArgumentException: No value supplied for key: true |
| 13:39 | TimMc | &(hash-map :true) |
| 13:39 | lazybot | java.lang.IllegalArgumentException: No value supplied for key: :true |
| 13:39 | amro | yep, I just tried that |
| 13:39 | amro | well, in any case I was misusing the API |
| 13:41 | yoklov | clj_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:42 | sritchie | TimMc: that doesn't seem to pick up the type hint, unfortunately |
| 13:44 | lypanov | llvm has a irc channel on oftc |
| 13:45 | lypanov | clj_newb: pretty much, though i'd rather say JIT in JVM has 30 years worth of experience fixing crap code. |
| 13:45 | lypanov | clj_newb: llvm OTOH has very different goals. it is just an insanely great machine code generator. |
| 13:46 | lypanov | clj_newb: you might also want to try #rubinius some of the guys there have actual experience, i just have 2nd hand guesses ;) |
| 13:51 | mattmitchell | if 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:54 | jodaro | i think it depends on why you need to do it that way |
| 13:54 | TimMc | sritchie: Hmm, how can inlining be debugged? |
| 13:54 | sritchie | I'm not sure, I don't really know the expansion rules |
| 13:56 | clj_newb | this is starting to make sense now |
| 13:56 | clj_newb | I always wondered why such a brilliant langauge like clojure picked java |
| 13:56 | clj_newb | now I get it: it makes impelmenting clojure much much easier |
| 13:56 | yoklov | versus llvm? |
| 13:56 | clj_newb | no need to implement a VM, a FFI, or a JIT |
| 13:56 | clj_newb | it's all provided by java |
| 13:57 | yoklov | Or the hundreds of libraries that come with java. |
| 13:57 | TimMc | ":inline-arities >1?" <- wtf |
| 13:57 | clj_newb | Thus, 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:57 | mattmitchell | jodaro: 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:57 | TimMc | Oh, it's a private fn. |
| 14:03 | lypanov | clj_newb: there is a project called vmkit that if it were to be improved could offer all the advantages of JVM and llvm |
| 14:03 | lypanov | but it'd be years of work |
| 14:03 | lypanov | and openjdk is okay ish now |
| 14:03 | clj_newb | Currently asking in llvm on irc.oftc.net |
| 14:04 | clj_newb | I 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:06 | mattmitchell | is 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:08 | TimMc | mattmitchell: Ill-defined, what happens with key collisions? |
| 14:08 | TimMc | Or can you assume there are none? |
| 14:08 | mattmitchell | TimMc: it can blow up in that case |
| 14:08 | mattmitchell | yeah, there shouldn't be any |
| 14:08 | mattmitchell | I'm using reduce right now, but it seems too complex |
| 14:08 | TimMc | for might be better |
| 14:09 | lypanov | clj_newb: you could, use clojurescript + v8 and implement it all on top of js "threading" concepts ;) |
| 14:09 | TimMc | mattmitchell: And maps are fine, no need to specify hash-maps. |
| 14:09 | mattmitchell | TimMc: ahh right |
| 14:09 | mattmitchell | TimMc: could you give me a hint on the "for" approach? :) |
| 14:11 | jodaro | hrm, well, treating it as a single string and then splitting it on \x00 works for now |
| 14:11 | TimMc | &((fn [fk & ms] (into {} (for [m ms] [(m fk) m]))) :id {:id 1 :a 2} {:id 5 :b 4}) ;; mattmitchell |
| 14:11 | lazybot | ⇒ {1 {:a 2, :id 1}, 5 {:b 4, :id 5}} |
| 14:12 | mattmitchell | TimMc: awesome thanks |
| 14:12 | TimMc | mattmitchell: I think you could sneak a juxt in there, actually. |
| 14:13 | mattmitchell | oh maybe juxt and zipmap? |
| 14:13 | TimMc | &((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:13 | lazybot | ⇒ {1 {:a 2, :id 1}, 5 {:b 4, :id 5}} |
| 14:13 | mattmitchell | ahh i see |
| 14:20 | clj_newb | based 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:25 | TimMc | clj_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:26 | clj_newb | TimMc: how does macros related to JITTing? |
| 14:26 | lypanov | that can be done without JIT if the system applies system wide opts. |
| 14:26 | clj_newb | oh, macros can be done at _runtime_ ? |
| 14:26 | clj_newb | rather than multiple compilation passes? |
| 14:27 | TimMc | clj_newb: Yeah, JIT means you are distributing source, unexpanded. |
| 14:27 | amalloy | i think you two are confusing each other |
| 14:27 | clj_newb | amalloy: enlighten us |
| 14:27 | TimMc | oh no, an expert! |
| 14:27 | amalloy | TimMc is just saying that the compilation happens in the same environment where code is going to execute |
| 14:27 | amalloy | so you know what will be available |
| 14:28 | clj_newb | How does this related to JITTing? |
| 14:28 | raek | The oracle implementation of the JVM (Hotspot) uses JIT compilation to speed up the virtual machine. |
| 14:28 | amalloy | it's not related to java's JITing, but it is basically clojure's JIT: compile it Just In Time, before they run it |
| 14:28 | amalloy | clojure doesn't care at all about java's JIT; it just runs on the jvm and gets a performance boost for free |
| 14:29 | TimMc | Yeah, I guess there's a jargon mismatch here. |
| 14:29 | AeroNotix | What's a good method for type checking in clojure? |
| 14:29 | TimMc | Clj -> .class -> native machine code -- *both* of those steps are compilations. |
| 14:30 | clj_newb | amalloy: ah, the point you're getting at is (1) Just in Time macro expansion vs (2) Just in Time compilation + code execution ? |
| 14:30 | amalloy | no |
| 14:30 | TimMc | &(instance? String "AeroNotix") |
| 14:30 | lazybot | ⇒ true |
| 14:30 | AeroNotix | Thank you |
| 14:30 | amalloy | that's the point that is dividing you and TimMc |
| 14:30 | AeroNotix | @TimMC thank you |
| 14:30 | TimMc | AeroNotix: isa? can do some fancier stuff |
| 14:30 | AeroNotix | thanks, I'll get to google |
| 14:30 | amalloy | i guess maybe that's the point i was getting at also |
| 14:31 | amalloy | but 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:34 | lypanov | JIT implies continuous. clojure isn't continuous. |
| 14:34 | lypanov | there is no "hotspot" detection in clojure's compiler. its just a compiler. |
| 14:39 | clj_newb | the more I learn about clojure; the more brilliant I think it is |
| 14:40 | clj_newb | I 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:40 | AeroNotix | clj_newb: It does? |
| 14:41 | lypanov | clj_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:44 | clj_newb | lypanov: what did you like about scala / how did it burn you? |
| 14:44 | lypanov | clj_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:44 | lypanov | clj_newb: i was burnt my its complexity. |
| 14:44 | lypanov | by* |
| 14:45 | lypanov | i also simply couldn't deal with the compile times. |
| 14:45 | lypanov | its 2012! |
| 14:45 | lypanov | ;) |
| 14:55 | lypanov | anyone else read lwn.net & have a kindle? |
| 14:56 | lynaghk | lypanov; have you seen the Send-to-Kindle google chrome extension? It's pretty decent at extracting article text and formatting for Kindle |
| 14:57 | lypanov | lynaghk: i'd really like to have a .mobi with nice headers and a ToC etc |
| 14:57 | lypanov | i want to dissect whatever magic instapaper is performing is thats the format i'd like |
| 14:59 | lynaghk | Ah, 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:59 | lynaghk | Good luck |
| 15:01 | lypanov | yeah probably going to use kindlegen for it if i can get it to produce the right file |
| 15:01 | lypanov | thank you :) |
| 15:03 | AWizzArd | When I eval *out*, a ^:dynamic var under Clojure 1.3, is that then equivalent to @#'*out*, from an efficiency point of view? |
| 15:04 | AWizzArd | I 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:07 | holo | hello |
| 15:09 | AWizzArd | My 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:10 | amalloy | AWizzArd: 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:11 | AWizzArd | amalloy: 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:12 | AWizzArd | So 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:13 | amalloy | huh? why of course? i don't think i understand you |
| 15:13 | AWizzArd | (def out-logger (make-logger *out*)) <-- out-logger always .writes to the same Writer. |
| 15:13 | amalloy | (make-logger #'*out*) |
| 15:13 | AWizzArd | Exactly. |
| 15:13 | AWizzArd | This would work. |
| 15:14 | AWizzArd | But then: (.write #'*out* ...) doesn’t. Of course, because it expects a Writer, not a Var. |
| 15:14 | AWizzArd | So I would have to deref the arg to make-logger. |
| 15:14 | amalloy | right |
| 15:14 | AWizzArd | And when I realized this I thought: will this be less efficient than writing explicitly (.write *out* ...)? |
| 15:15 | AWizzArd | The dotimes micro benchmark from above indicates that it makes no difference at all. |
| 15:15 | AWizzArd | But looking at the bytecode seems like a reasonable idea. |
| 15:16 | amalloy | AWizzArd: i'm doing that already, i'll let you know |
| 15:16 | AWizzArd | Oh good, thx. |
| 15:17 | simonadameit | Hi, can I add functions (maybe even private ones) to a deftype without implementing an interface? |
| 15:18 | AWizzArd | simonadameit: but you still want polymorphism? |
| 15:18 | AWizzArd | Because otherwise you could just write an ordinary defn or defn- for the private version, which expects one or more instances of a deftype. |
| 15:18 | raek | simonadameit: if they do not participate in the protocol, you can just have them outside the defrecord form |
| 15:18 | amalloy | AWizzArd: @#'*out* has more obvious work in it: https://gist.github.com/1551956 |
| 15:18 | raek | as ordinary functions |
| 15:19 | simonadameit | raek: you mean without specifying them inside the deftype form? |
| 15:19 | raek | yes |
| 15:19 | AWizzArd | amalloy: hmm I see |
| 15:20 | raek | (defn- foo [...] ...) (defrecord Bar [...] SomeProto (some-method [...] ... (foo ...) ...)) |
| 15:20 | amalloy | mainly because you have to actually call clojure.core/deref, i think |
| 15:20 | amalloy | as compared to just calling .get on the var |
| 15:21 | AWizzArd | amalloy: 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:22 | simonadameit | raek but they wont be implemented as methods directly defined in the class backing the deftype? |
| 15:22 | raek | simonadameit: yes. |
| 15:23 | raek | they will be implemented as a method in a function class instead |
| 15:24 | raek | the reason you want to have protocol methods implemented as java methods is fast polymorphism |
| 15:24 | simonadameit | ah, ok.. I dont need polymorphism for these functions |
| 15:24 | raek | but for a private helper function that is only used in one implementation of the protocol you don't use any polymorphism |
| 15:25 | raek | exactly |
| 15:28 | simonadameit | thanks raek, .. I guess I will have to get used to this separation of function and data :) |
| 15:29 | AWizzArd | amalloy: interesting, it seems there is then no other way to parameterize on dynamic vars. |
| 15:30 | amalloy | hm? you could do .get on the Var with interop instead of using the more generic deref, since you don't need genericity |
| 15:32 | AWizzArd | amalloy: calling .get will probably also result in more code than what you got for (defn foo [] (println *out*)). |
| 15:33 | amalloy | not really. it should just add a single checkcast to that version |
| 15:34 | amalloy | and 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:36 | simonadameit | what is the name of the protocol that conj is part of? |
| 15:37 | amalloy | it's an interface |
| 15:37 | amalloy | clojure.lang.IPersistentCollection/cons, i think |
| 15:39 | raek | simonadameit: this can be useful: https://github.com/Chouser/clojure-classes/blob/master/graph-w-legend.png |
| 15:40 | augustl | is there a way to disable all of the built-in pages of noir? Such as the default 404 page for example. |
| 15:41 | simonadameit | raek thanks, thats great |
| 15:43 | simonadameit | is there a performance difference between using extend-type or defining the methods directly in a deftype` |
| 15:43 | simonadameit | ? |
| 15:44 | amalloy | yes, but not one that's likely to matter if you're implementing something slower than hello world |
| 15:49 | bweaver | Hello, 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:53 | amalloy | those are reader macros, so the objects should be embedded in the code |
| 15:53 | amalloy | ie, no memoization is necessary |
| 15:54 | raek | bweaver: if you're wondering whether #"..." will only instantiate a Pattern once, then yes (IIRC) |
| 15:54 | bweaver | Ok, thanks. |
| 15:59 | Xenocorp_ | in emacs repl. If I shadow a built-in, how do I reset the repl? |
| 16:03 | bweaver | Xenocorp_: You can `(use 'clojure.core)` to re-import all of the core bindings into your namespace. Does that help? |
| 16:04 | Xenocorp_ | bweaver: That'll do :) |
| 16:04 | Xenocorp_ | Thanks |
| 16:15 | augustl | is there a reference to all the syntax in clojure? Currently trying to find out what the ampersand in (defn foo [& something] ....) means |
| 16:16 | bweaver | augustl: I find that the cheatsheet is helpful `http://clojure.org/cheatsheet`, most other reader stuff is documented in `http://clojure.org/reader`. |
| 16:17 | bweaver | augustl: 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:17 | augustl | ah that cheat sheet is useful |
| 16:17 | bweaver | augustl: So, for example, calling `(foo 1 2 3)` will bind `something` to `(list 1 2 3)`. |
| 16:17 | bweaver | augustl: Or maybe it's a vector. |
| 16:17 | augustl | I see, thanks |
| 16:18 | amalloy | neither, actually. but you get a sequential view of it, which is all that matters |
| 16:19 | bweaver | Thanks amalloy :) |
| 16:19 | amalloy | &((fn [& args] (class args)) 1 2 3) |
| 16:19 | lazybot | ⇒ clojure.lang.ArraySeq |
| 16:19 | augustl | found the docs in http://clojure.org/special_forms |
| 16:19 | augustl | for the record |
| 16:19 | Scorchin | If I'm using clojure 1.3, how do I add clojure-contrib to my project? |
| 16:22 | augustl | Scorchin: I'm using leiningen, I added [org.clojure/clojure-contrib "1.2.0"] to dependencies in project.clj |
| 16:22 | Scorchin | augustl: is 1.2.0 the latest stable version? The website wasn't very clear on that |
| 16:22 | technomancy | clojurebot: what happened to clojure contrib? |
| 16:22 | clojurebot | It's greek to me. |
| 16:22 | technomancy | clojurebot: what happened to contrib? |
| 16:22 | clojurebot | Well... it's a long story: http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go |
| 16:22 | amalloy | if you want old-contrib in a 1.3 project, step one is ritual suicide |
| 16:23 | Scorchin | technomancy: <3 |
| 16:23 | augustl | Scorchin: don't remember how I found that version number, I remember struggling with that as well |
| 16:30 | augustl | given (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:30 | amro | in what case would (print (str (type x))) output nothing? |
| 16:30 | Scorchin | interesting, 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:30 | Scorchin | Anyone what's going on there? |
| 16:31 | technomancy | Scorchin: you haven't loaded the clojure.string namespace |
| 16:32 | bweaver | augustl: `(vec (flatten bar))`? |
| 16:32 | Scorchin | technomancy: thank you |
| 16:33 | augustl | bweaver: cool, thanks |
| 16:33 | nick_s | Is let free? |
| 16:34 | bweaver | augustl: You could also use `concat` depending on whether you needed the intermediate nested vector for anything. |
| 16:34 | nick_s | After it's compiled that is. Does a let binding have a performance cost associated with it? |
| 16:34 | amalloy | if 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:36 | mcrittenden-afk | noir's built in server isn't meant to be used in production, right? and if not, then what are people using? |
| 16:37 | mcrittenden-afk | oh just realized it uses jetty which I assume would be fine in production. never mind. |
| 16:37 | Xenocorp_ | apparently at my work we're using two toasters strapped together with an ethernet cord |
| 16:40 | augustl | pastie can't highlight lisps it seems, any suggestions? :) |
| 16:40 | amalloy | ~paste |
| 16:40 | clojurebot | paste is gist |
| 16:40 | amalloy | ugh, really? |
| 16:40 | amalloy | clojurebot: forget paste |is| gist |
| 16:40 | clojurebot | I forgot that paste is gist |
| 16:40 | amalloy | clojurebot: paste is https://gist.github.com |
| 16:40 | clojurebot | c'est bon! |
| 16:41 | technomancy | paste is delicious |
| 16:41 | augustl | thanks |
| 16:41 | zilti | amalloy: pastie.org can highlight Clojure: http://pastie.org/l |
| 16:41 | augustl | since I don't know much about clojure, it seems to me that these calls would be identical https://gist.github.com/1552241 |
| 16:41 | augustl | is there an easy explanation for a noob? :) |
| 16:42 | augustl | just seems to me that (vec (flatten head-extra)) evaulates to a vector, i.e. exactly the same as head-extra |
| 16:42 | amalloy | zilti: i have no opinion about pastie, but he asked for a good pastebin, and that's gist |
| 16:42 | technomancy | flatten? |
| 16:42 | clojurebot | flatten 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:42 | amalloy | ~botsnack |
| 16:42 | clojurebot | Thanks! Can I have chocolate next time |
| 16:42 | bweaver | augustl: You might want to try appending head-extra instead of inserting it into the vector literal. |
| 16:42 | zilti | amalloy: I prefer gist, too |
| 16:43 | amalloy | bweaver: nah, that shouldn't matter |
| 16:43 | augustl | bweaver: it's nice to keep the literal structure when doing HTML.. |
| 16:44 | augustl | anyhow, is "flatten" a special form of some sorts that makes stuff happen under the hood? |
| 16:44 | amalloy | no, flatten is a great evil sent by the devil |
| 16:44 | bweaver | augustl: no, it's just a function |
| 16:44 | amalloy | included only to confuse people into using it when they shouldn't |
| 16:44 | augustl | still don't quite grok the difference between the two calls, since vec evaulates to a vector (I guess) |
| 16:45 | amalloy | augustl: the difference is, what if head-extra is [:foo [:bar [:baz]]] |
| 16:45 | amalloy | flatten turns it into [:foo :bar :baz] |
| 16:45 | augustl | the only thing I can think of is that "flatten" sets some state under the hood that causes clojure to evaulate the vector differently |
| 16:45 | augustl | ah we wouldn't want that.. |
| 16:46 | bweaver | augustl: for what it's worth, you might try using quasiquoted lists instead of vectors for representing markup |
| 16:46 | bweaver | augustl: `(:head (:title "...") ~@head-extra) |
| 16:46 | amalloy | bweaver: i have to wonder what position you're giving advice from. hiccup uses vectors |
| 16:46 | augustl | wonder if hiccup supports that |
| 16:46 | augustl | ah, right |
| 16:46 | bweaver | amalloy: oh, didn't know that |
| 16:47 | bweaver | amalloy: I'm new to Clojure too and just find quasiquotes convenient. If there's a framework already, then that's definitely more convenient :)( |
| 16:47 | bweaver | amalloy: This is what I was thinking of: http://okmij.org/ftp/Scheme/SXML.html |
| 16:47 | augustl | the value of head-extra in my case is ["Test test"], so I still don't understand how flatten helps me in this case :) |
| 16:47 | augustl | I do understand it will turn nested lists into flat lists |
| 16:47 | bweaver | augustl: Sorry augustl, ignore me :) |
| 16:47 | augustl | not how it "concatinates" vectors into other vectors, inline, sort of |
| 16:47 | bweaver | augustl: I was assuming something different than what you're trying to do. |
| 16:48 | amalloy | it doesn't help you, flatten never helps, i wish i could remove it from clojure.core |
| 16:48 | augustl | it does actually help me in this situation, though |
| 16:48 | augustl | perhaps my head-extra vector doesn't have the value I think it does.. |
| 16:48 | amalloy | no, it obviously doesn't, because (vec (flatten ["foo"])) ie still ["foo"] |
| 16:49 | amalloy | if your goal is to end up with the contents of head-extra dumped into the head, you want ##(doc into) |
| 16:49 | lazybot | ⇒ "([to from]); Returns a new coll consisting of to-coll with all of the items of from-coll conjoined." |
| 16:49 | amalloy | (into [:head [:title ...] ...] head-extra) |
| 16:49 | amalloy | or if you prefer, `[:head [:title ...] ... ~@head-extra] |
| 16:50 | augustl | updated https://gist.github.com/1552241, build-head-3 works and I understand it, so yay :) |
| 16:50 | augustl | amalloy: hmm that's interesting, I wonder why build-head and build-head-2 behaves differently then |
| 16:50 | augustl | that's good to hear, at least, that means I did actually understand what flatten did ;) |
| 16:50 | skelternet | I've been building tables with hiccup. |
| 16:51 | augustl | amalloy: ah I'll look up the ~@foo syntax |
| 16:51 | skelternet | I noticed some of the tags seem to only respect one parameter the way I had been using them. |
| 16:52 | technomancy | warms my heart seeing all these folks learning Clojure for 2012 =) |
| 16:52 | cgray | is 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:53 | skelternet | for instance, I had a [:tr (for … (println something) [:td column] … and the td's weren't getting returned |
| 16:53 | augustl | odd, "Attempting to call unbound fn: #'clojure.core/unquote-splicing ", guess I need to import something |
| 16:53 | skelternet | Don't know if that helps, agustl, |
| 16:53 | skelternet | I'm still trying to wrap my head around it. |
| 16:53 | augustl | skelternet: hmm, you probably need to map instead of for looping? |
| 16:53 | amalloy | augustl: you didn't include ` |
| 16:53 | augustl | not sure what a for loop that prints is doing inside a vector that's supposed to represent HTML :) |
| 16:54 | skelternet | was just there while debugging…but it seemed to make things worse while it was there :| |
| 16:54 | skelternet | when I removed it, life was better |
| 16:54 | augustl | amalloy: include what? :) |
| 16:55 | cgray | augustl: the backtick symbol |
| 16:55 | augustl | oh |
| 16:55 | amalloy | &(let [x 1] `(:foo ~x)) |
| 16:55 | lazybot | ⇒ (:foo 1) |
| 17:04 | clj_newb | I need to gain 6000 experience points to advance from clj_newb to clj_novice. What are good clojure codebases to read? |
| 17:04 | cgray | clj_newb: core.clj is a pretty good place to do some learning |
| 17:05 | cgray | clj_newb: sorry, I mean clojure.core |
| 17:05 | amalloy | downvote. core is interesting once you already know a lot |
| 17:05 | amalloy | but it contains a ton of stuff that is a Bad Idea in other code because it's bootstrapping |
| 17:05 | cgray | good point |
| 17:05 | cgray | maybe the second half of core or so |
| 17:05 | pandeiro | amalloy: anything you'd recommend? |
| 17:06 | clj_newb | "bootstrapping" <-- as in the code is not idiomatic, because clojure idioms requires things in clojure.core ? |
| 17:06 | amalloy | right |
| 17:06 | clj_newb | actually, that sounds awesome; I love understanding how things work |
| 17:07 | amalloy | *shrug* what you should read depends on what you want to learn |
| 17:07 | clj_newb | the great thing about software, as opposed to hardware is that I don't have to put it back together |
| 17:08 | clj_newb | amalloy: 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:09 | amalloy | haha no, it's because i spend a lot of time in here. i have more fun helping out than writing a magnum opus |
| 17:09 | amalloy | but a lot of www.4clojure.com is mine, if you're looking for an excuse to idolize me |
| 17:10 | clj_newb | I merely found it interesting how that whenever you disagree with someone, they just assume you're right. :-) |
| 17:10 | clj_newb | what does 4clojure have to do with cheap realestate? |
| 17:10 | amalloy | foreclosure |
| 17:10 | amalloy | it's a pun, you see. not my pun, thank god |
| 17:11 | cgray | clj_newb: the damn thing is, he is right so much of the time... plus it's just a pretty respectful community in general |
| 17:13 | augustl | clj_newb: currently making a simple web page with Noir. Learning a lot from that. |
| 17:13 | augustl | I got about 200 experience points after a couple of hours! |
| 17:14 | clj_newb | augustl: lol |
| 17:15 | clj_newb | amalloy: 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:15 | amalloy | i don't know what 3SAT is. but solve 50 4clojure problems, then you can submit that as a problem yourself |
| 17:18 | amalloy | haha, were you trolling me? you: "output in polynomial time..." wikipedia: "3-SAT is NP-complete..." |
| 17:22 | clj_newb | amalloy: look up millenium prize -- a solution is worth 1 million dollars. Additionally, it's probably also worth a turing award. :-) |
| 17:22 | amalloy | sure, i know. as a kid i figured i would win that prize by solving minesweeper |
| 17:23 | clj_newb | damn, it is NP complete |
| 17:23 | clj_newb | amalloy: how old are you? the Clay prize isn't that old, and you mention "as a child ..." |
| 17:24 | amalloy | yeah, "kid" |
| 17:24 | amalloy | i must have been like 17 at the time. 26 now |
| 17:46 | solussd | is there something clojure more generic than (Long/parseLong "1367") ? |
| 17:47 | solussd | i.e. something that'll work on any number |
| 17:47 | amalloy | &(doc read-string) |
| 17:47 | lazybot | ⇒ "([s]); Reads one object from the string s" |
| 17:47 | solussd | ,(read-string "387429837492387492734923794729347923749") |
| 17:47 | clojurebot | 387429837492387492734923794729347923749N |
| 17:49 | wingie | is clojure fine to script with? |
| 17:49 | AWizzArd | solussd: 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:49 | wingie | compared to groovy |
| 17:50 | solussd | ,(.parse "23984294832.23423") |
| 17:50 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: No matching field found: parse for class java.lang.String> |
| 17:51 | solussd | oh, duh. |
| 17:51 | AWizzArd | Yes, I think the String class doesn't provide such a .parse method. |
| 17:53 | AWizzArd | This DecimalFormat class also provides parsing for some more exotic formats. Though as long read-string works fine I would surely prefer that one. |
| 17:55 | AWizzArd | http://docs.oracle.com/javase/tutorial/i18n/format/decimalFormat.html |
| 17:56 | TimMc | solussd: Just be sure to (binding [*read-eval* false] ...) around that for security. |
| 17:56 | TimMc | wingie: If you don't mind the several-second startup time of the JVM, sure, it's fine to script with. |
| 17:56 | solussd | yeah, I think that's overkill for me. :) |
| 17:57 | TimMc | solussd: Well, as long as you aren't reading user-generated strings, OK. |
| 17:57 | solussd | oh, you're referring to 'read-string' |
| 17:57 | TimMc | Yeah, sorry. |
| 17:58 | TimMc | wingie: Compared to any other JVM language I know of, yes, Clojure is the best for scripting -- LISPs are great for extracting patterns. |
| 17:59 | solussd | TimMc, what could be fed to read-string that would result in evaluation? |
| 17:59 | TimMc | &(read-string "#=(+ 1 2)") ; solussd |
| 17:59 | lazybot | java.lang.RuntimeException: EvalReader not allowed when *read-eval* is false. |
| 17:59 | TimMc | Semi-undocumented syntax. |
| 18:00 | solussd | yikes |
| 18:00 | TimMc | I'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:00 | solussd | what does #= mean exactly? |
| 18:01 | TimMc | solussd: It means to use the results of evaluating the next form. |
| 18:02 | TimMc | solussd: Put (read-string "[(+ 1 2) #=(+ 1 2)]") into a REPL. |
| 18:03 | TimMc | clojurebot is stupid, I can demonstrate here: |
| 18:04 | TimMc | ,(binding [*read-eval* true] (read-string "[1 2 #=(- 7 4) 4]")) |
| 18:04 | clojurebot | [1 2 3 4] |
| 18:04 | TimMc | The main use is serializing data structures that don't have literal support. |
| 18:05 | solussd | TimMc: whoa. So I could force evaluation of macro arguments when I pass them |
| 18:05 | TimMc | Not following that. |
| 18:06 | TimMc | Seriously, don't use #= in your code -- it's probably going away. |
| 18:06 | chipdude | so #=() is a lift macro |
| 18:07 | solussd | (defmacro printform [form] `'~form) |
| 18:07 | TimMc | It's reader syntax. |
| 18:07 | wingie | TimMc: is there any way to eliminate the startup time for java? (im new to java) |
| 18:07 | chipdude | [1 #=(prn 2) (x)] |
| 18:07 | chipdude | 2 |
| 18:07 | chipdude | java.lang.Exception: Unable to resolve symbol: x in this context (NO_SOURCE_FILE:2) |
| 18:08 | solussd | then I could (printform #=(+ 2 1)) to force it to pass 3 |
| 18:09 | chipdude | TimMc: what will replace it |
| 18:14 | TimMc | chipdude: Nothing official, I'm just guessing. |
| 18:15 | TimMc | I *think* it was mainly used for records, which now have their own (also undocumented!) literal syntax. |
| 18:18 | TimMc | technomancy: Did you take a look at the no-AOT uberjar example I wrote? |
| 18:24 | amalloy | TimMc: i don't think #= is actually going away anytime soon, but it's definitely something to avoid anyway |
| 18:24 | TimMc | amalloy: Do you know what else it is used for? |
| 18:24 | amalloy | &(print-dup (sorted-set)) |
| 18:24 | lazybot | clojure.lang.ArityException: Wrong number of args (1) passed to: core$fn--4023$fn |
| 18:25 | amalloy | &(binding [*print-dup* true] (pr-str (sorted-set))) |
| 18:25 | lazybot | java.lang.SecurityException: You tripped the alarm! pop-thread-bindings is bad! |
| 18:25 | TimMc | Ah, right. |
| 18:25 | TimMc | clojurebot won't mind |
| 18:25 | amalloy | damn it Raynes, can you just let the thread-binding stuff back into the list? he is crippled without binding |
| 18:25 | amalloy | ,(binding [*print-dup* true] (pr-str (sorted-set))) |
| 18:26 | clojurebot | "#=(clojure.lang.PersistentTreeSet/create [])" |
| 18:27 | TimMc | amalloy: pop-thread-bindings is only found in the macro expansion -- does clojail really need to inspect the expansion results? |
| 18:27 | TimMc | (Or rather, why.) |
| 18:28 | amalloy | &(macroexpand '(clojure.lang.Compiler/eval foo)) |
| 18:28 | lazybot | java.lang.SecurityException: You tripped the alarm! class clojure.lang.Compiler is bad! |
| 18:29 | augustl | someone told me earlier what I had to do to enable ~@ (unquote-splicing), but I didn't grok what it was.. Anyone knows? |
| 18:29 | augustl | getting "Attempting to call unbound fn: #'clojure.core/unquote-splicing" |
| 18:29 | amalloy | ugh, whatever. the point is there are a lot of "special cases" where stuff doesn't look like a problem until it's expanded |
| 18:29 | skelternet | I might have it in a buffer, do you need it or need to grok it? |
| 18:30 | TimMc | amalloy: I see, lots of sugary stuff. |
| 18:31 | TimMc | doto, etc. |
| 18:31 | amalloy | right. but you make an interesting point, i think |
| 18:31 | augustl | skelternet: need to grok it :) |
| 18:31 | amalloy | i (or Raynes?) just macroexpanded because it seemed like you could hide dangerous things inside a macro |
| 18:32 | augustl | need to import `, not sure how to do that |
| 18:32 | chipdude | TimMc: the record syntax is as found here? http://dev.clojure.org/display/design/defrecord+improvements |
| 18:32 | amalloy | there's nothing to import |
| 18:33 | augustl | oh, I'm probably using it wrong then |
| 18:33 | amalloy | TimMc: actually i think memfn was the macro that makes it necessary to expand |
| 18:33 | TimMc | Ah, right. |
| 18:34 | TimMc | So you'd have to look at all the things that mess with names and calling. Ugh. |
| 18:34 | TimMc | &`[1 2 3 ~@(list 4 5 6) 7 8] ; augustl |
| 18:34 | lazybot | ⇒ [1 2 3 4 5 6 7 8] |
| 18:35 | technomancy | TimMc: yeah, makes it sense |
| 18:36 | technomancy | maybe package it up as a plugin? |
| 18:36 | TimMc | I'm trying to think how exactly. |
| 18:37 | TimMc | There's also the question of how to indicate that this is the desired behavior. |
| 18:37 | technomancy | if you had it read the main ns out of jar metadata, you could probably just make it a plain old dependency |
| 18:37 | technomancy | wouldn't need to be a plugin |
| 18:38 | TimMc | I was thinking a resource like uberjit.properties |
| 18:39 | TimMc | But no, that's silly -- there might be multiple. |
| 18:40 | jmdev | Hi guys |
| 18:40 | technomancy | jar metadata lives in project.clj right next to :main; it makes sense to keep them together |
| 18:41 | augustl | I |
| 18:41 | augustl | err |
| 18:41 | augustl | I'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:42 | amalloy | (defn ... (def)) is evil |
| 18:42 | augustl | I should inline it? |
| 18:42 | raek | augustl: def is only for global constants |
| 18:42 | amalloy | no, you should never use def inside a defn |
| 18:42 | amalloy | you want let |
| 18:43 | augustl | ah |
| 18:43 | augustl | a "minor" oversight.. |
| 18:43 | skelternet | would the inner def survive outside of the scope? |
| 18:43 | skelternet | tag-attrs in this case? |
| 18:43 | raek | skelternet: it will mutate a global variable |
| 18:43 | augustl | I'm curious if my use of concat of vectors makes sense. Not used to functional programming and static collections |
| 18:44 | augustl | and if having a build-main-menu-iter makes sense. Inspired by SICP which I just started reading ;) |
| 18:44 | yoklov | haha i thought your code looked like scheme code |
| 18:44 | yoklov | but wasn't going to say anything because mine does too lol |
| 18:44 | augustl | recur is the only "trick" I learned so far ;) |
| 18:45 | TimMc | skelternet: The inner def would not become defined until that function had been called. |
| 18:46 | amalloy | the manual recursion looks a lot like a map or a mapcat or something |
| 18:46 | skelternet | I thought mutations to it were stacked and thread-specific. I must be thinking of bind |
| 18:46 | amalloy | but it's hard to tell because you wrote it as manual recursion and now it takes all this effort to read :P |
| 18:46 | augustl | guess I could use conj instead of concat-ing vectors |
| 18:46 | augustl | amalloy: hehe, the idea is that I need to pass active-menu to the calls to build-main-menu-item |
| 18:46 | augustl | seems that map only passes the item in the collection and doesn't support arbitrary params |
| 18:47 | raek | skelternet: yes, when using 'binding' and 'set!' |
| 18:47 | arohner | using 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:47 | augustl | hmm seems conj isn't what I need |
| 18:48 | skelternet | def will just mutate it…whenever def gets eval'd? that would be much more difficult to reason about |
| 18:48 | raek | but 'def' is for those cases when you unconditionally want to change a global in all threads (unthreadsafely) -- nameley when fixing existing code |
| 18:48 | amalloy | (defn build-main-menu [active-menu] (mapcat #(build-main-menu-item % active-menu) main-menu-links))? |
| 18:48 | raek | skelternet: yes |
| 18:48 | raek | it should normally only be used on the top level |
| 18:48 | skelternet | same for defn? |
| 18:48 | raek | yes |
| 18:48 | augustl | amalloy: ah, mapcat looks nice |
| 18:49 | raek | think of 'def' as define global / repair broken global |
| 18:49 | augustl | and #() is shorthand for a lambda/anon function right? |
| 18:49 | yoklov | yes |
| 18:50 | raek | skelternet: (defn foo ...) is just a shorthand for (def foo (fn ...)) |
| 18:50 | yoklov | you can also use fn which is the same as lambda. |
| 18:50 | raek | it's a macro |
| 18:50 | augustl | hah, awesome |
| 18:51 | skelternet | (dreaming of swapping out implementations of a protocol mid-execution) |
| 18:51 | augustl | now it's just https://gist.github.com/1552654 |
| 18:51 | augustl | time to open The Joy of Clojure and grok what the % does :) |
| 18:51 | yoklov | it's the parameter for the #() function shorthand. |
| 18:52 | TimMc | %`#(+ %1 %3) |
| 18:52 | TimMc | &`#(+ %1 %3) |
| 18:52 | lazybot | ⇒ (fn* [p1__14814__14817__auto__ p2__14816__14818__auto__ p3__14815__14819__auto__] (clojure.core/+ p1__14814__14817__auto__ p3__14815__14819__auto__)) |
| 18:52 | augustl | updated it to use just map (still https://gist.github.com/1552654) |
| 18:52 | skelternet | it's almost built-in obfuscation |
| 18:53 | amalloy | yeah, the mapcat was (i think) replicating what you were doing but didn't make sense to me |
| 18:53 | raek | ,(* (+ (+) (+) (+)) (+ (+) (+)) (+ (+) (+))) |
| 18:53 | clojurebot | 0 |
| 18:54 | raek | right |
| 18:54 | raek | ,(* (+ (*) (*) (*)) (+ (*) (*)) (+ (*) (*))) |
| 18:54 | clojurebot | 12 |
| 18:54 | raek | don't forget to obfuscate your number constants! |
| 18:54 | chipdude | raek: it's at times like these I wish the mathematicians would go back to paper and leave us to our ones and zeroes |
| 18:55 | augustl | what's the % called? |
| 18:55 | augustl | hard to google.. |
| 18:55 | amalloy | percent |
| 18:55 | TimMc | haha |
| 18:55 | augustl | I mean the use of % in clojure, silly |
| 18:55 | augustl | or in that particular situation, even |
| 18:55 | skelternet | oh…anon function? |
| 18:56 | augustl | isn't #() the anon function part? |
| 18:56 | yoklov | argument? |
| 18:56 | TimMc | augustl: The whole thing is referred to as a "function literal". I think that's as close as you're going to get. |
| 18:56 | yoklov | http://clojure.org/reader under "anonymous function literal" |
| 18:56 | TimMc | augustl: Right, and % is just captured by the macro. |
| 18:56 | augustl | so the % in #(build-main-menu-item % active-menu) is part of the #() syntax, which is the function literal syntax? |
| 18:56 | augustl | ah |
| 18:57 | augustl | thanks, folks |
| 18:57 | amalloy | weird to use the word "literal" in that context |
| 18:57 | TimMc | (It might not be a macro technically, but it basically acts as one.) |
| 18:57 | augustl | so % is about macros |
| 18:57 | TimMc | Nope. |
| 18:57 | yoklov | it's a reader macro, not a normal macro |
| 18:57 | amalloy | nothing about macros except in a very uninteresting sense |
| 18:58 | raek | ,(read-string "#(foo % bar)") |
| 18:58 | clojurebot | (fn* [p1__81#] (foo p1__81# bar)) |
| 18:58 | amalloy | raek: easier to just quote it |
| 18:59 | raek | amalloy: true. |
| 18:59 | amalloy | ,'#(foo % bar) |
| 18:59 | clojurebot | (fn* [p1__106#] (foo p1__106# bar)) |
| 18:59 | TimMc | amalloy: Can you think of any normal macros in Clojure that capture symbols? |
| 18:59 | TimMc | try/catch is a special form... |
| 18:59 | raek | TimMc: I think 'proxy' does it with the 'this' parameter |
| 18:59 | augustl | hmmmmmm |
| 18:59 | augustl | ah right of course |
| 18:59 | amalloy | yeah, good call raek |
| 18:59 | raek | I don't think it's considered good style, though |
| 18:59 | augustl | it just creates an anonymous function that calls the original function and passes active-menu to it |
| 19:00 | TimMc | &(let [% 5] 5) |
| 19:00 | lazybot | ⇒ 5 |
| 19:00 | augustl | so it's the same as (fn [index] (build-main-menu-item index active-menu)) |
| 19:00 | augustl | right? |
| 19:00 | TimMc | bah |
| 19:00 | TimMc | &(let [% 5] %) |
| 19:00 | lazybot | ⇒ 5 |
| 19:00 | amalloy | yes |
| 19:00 | yoklov | augustl: right |
| 19:01 | augustl | and % is the way you reference args in #() |
| 19:01 | TimMc | augustl: %1, %2, %3... -- yes |
| 19:01 | TimMc | % is %1 |
| 19:01 | augustl | yay :) |
| 19:01 | augustl | thanks again folks |
| 19:01 | yoklov | oh huh, you can use `this' inside proxy? |
| 19:01 | raek | the highest number used determines how many arguments the function takes |
| 19:02 | augustl | raek: that's useful, thanks |
| 19:02 | TimMc | And there's %& for rest args. |
| 19:03 | TimMc | A function with %1, %5, and %& in it will effectively have the formal params [p1 p2 p3 p4 p5 & pmore]. |
| 19:04 | augustl | and this is not related to the #() macro? I'm guessing you can't do (fn [] (stuff %1 %5)) though |
| 19:04 | TimMc | It's only #(). |
| 19:04 | augustl | I see |
| 19:04 | TimMc | augustl: Try using syntax-quote (`) on function literals; see how they expand. |
| 19:05 | augustl | will do :) |
| 19:05 | TimMc | They'll be ugly because of double gensym'ing. |
| 19:05 | augustl | haven't learned a new language for quite some time now. It's pretty mind blowingly awesome. |
| 19:06 | augustl | it being clojure probably helps too |
| 19:08 | raek | TimMc: augustl: ordinary quote (') works fine for this purpose as well |
| 19:09 | raek | as amalloy showed before |
| 19:09 | TimMc | raek: Ooh, right -- and only a single level of gensym. |
| 19:10 | amalloy | &`#(%) |
| 19:10 | lazybot | ⇒ (fn* [p1__14849__14850__auto__] (p1__14849__14850__auto__)) |
| 19:10 | augustl | aww, arrow keys doesn't work in the repl |
| 19:10 | amalloy | heh, i never realized that would have multiple gensyms. funny, TimMc |
| 19:11 | TimMc | augustl: Are you using leiningen? Install rlwrap, lein will pick it up. |
| 19:15 | solussd | in 1.3, where do I get zip-filter? I see clojure.data.zip, but it is "the future home of zip-filter"… :/ |
| 19:20 | TimMc | solussd: I think it's correct. |
| 19:21 | solussd | TimMc, k. so I can't add it as a dependency in my leiningen project.clj? |
| 19:22 | TimMc | No, I mean I think it's the new location. |
| 19:24 | augustl | TimMc: I'm using leiningen yes, thanks for the tip |
| 19:25 | augustl | TimMc: that's better :) |
| 19:25 | TimMc | I can't be arsed to file a ticket to get them to fix the README. |
| 19:28 | technomancy | quick poll: what's the path to tools.jar vs (System/getProperty "java.home") for the JDK you use? |
| 19:29 | quizme | how do you write to a file from a ByteBuffer? |
| 19:30 | TimMc | technomancy: Can't find it, OpenJDK Runtime Environment (IcedTea6 1.9.10) (6b20-1.9.10-0ubuntu1~10.10.2) |
| 19:30 | TimMc | OpenJDK Client VM (build 19.0-b09, mixed mode, sharing) |
| 19:30 | technomancy | TimMc: whoa; a client JVM? are you running a 64-bit OS? |
| 19:30 | yoklov | someone 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:31 | TimMc | technomancy: Linux kibble 2.6.35-30-generic #61-Ubuntu SMP Tue Oct 11 15:29:15 UTC 2011 i686 GNU/Linux |
| 19:31 | quizme | I 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:31 | TimMc | doesn't look like it! |
| 19:31 | technomancy | TimMc: bummer; I was hoping you had found a way to run a client JVM on a 64-bit system without compiling your own. =\ |
| 19:31 | technomancy | didn't realize people still used 32-bit Oses |
| 19:32 | TimMc | technomancy: That laptop is from 2005. |
| 19:32 | technomancy | well there ya go |
| 19:34 | TimMc | technomancy: I don't like specifying the uberjit loader namespace as :main -- it confuses the reader, and more importantly, the REPL. |
| 19:34 | technomancy | hm; in that case you'd need a plugin |
| 19:35 | TimMc | And as for my Ubuntu Natty machine, OpenJDK 1.6.0_22 (x64, Server) does not have an obvious tools.jar either. |
| 19:36 | technomancy | find /usr/lib/jvm -name tools.jar gives nada? |
| 19:36 | TimMc | No, that's wrong -- it's down a level! |
| 19:37 | cgray | technomancy: /usr/lib/jvm/java-6-openjdk-i386/lib/tools.jar and "/usr/lib/jvm/java-6-openjdk-i386/jre" |
| 19:37 | technomancy | cool; thanks |
| 19:37 | technomancy | cgray: what OS? |
| 19:38 | cgray | technomancy: debian gnu/linux |
| 19:38 | technomancy | cool. |
| 19:38 | technomancy | how bout any macosecksists? |
| 19:38 | TimMc | technomancy: ../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:38 | technomancy | yeah... I don't think gcj really counts |
| 19:39 | TimMc | heh |
| 19:49 | technomancy | switching swank-clojure's default branch back to master; woo |
| 20:01 | TimMc | amalloy: Your clojopts project -- any plans to make a 1.3 release? |
| 20:03 | amalloy | TimMc: 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:03 | TimMc | amalloy: Well, it's the only thing I saw when I searched for "clojure getopt". :-P |
| 20:04 | amalloy | well, to be fair that's what i do that's better than cli. he rolls his own option parser which imo kinda sucks |
| 20:04 | amalloy | i used the java port of gnu getopt |
| 20:06 | TimMc | amalloy: 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:07 | TimMc | I can't tell what macro-do macro-does. |
| 20:07 | amalloy | TimMc: depend on useful instead of amalloy-utils |
| 20:07 | amalloy | templating: (macro-do [name val] `(def ~name ~val) foo 1, bar 2) => (do (def foo 1) (def bar 2)) |
| 20:08 | amalloy | TimMc: 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:08 | TimMc | You did. |
| 20:41 | TimMc | amalloy: Using useful would pin it to 1.3 -- what are your thoughts on maintaining backwards compat? |
| 20:41 | amalloy | TimMc: useful doesn't depend on anything in 1.3 |
| 20:41 | TimMc | OK, sweet. |
| 20:41 | TimMc | Right, that's a soft dependency in project.clj. |
| 21:00 | TimMc | amalloy: Sweet, that was simple enough: https://github.com/timmc/clojopts/commit/5d243ffc03600e04765d49df46b36145aa8b2dee |
| 21:03 | amalloy | awesome, tests |
| 21:08 | TimMc | amalloy: Should I make the juxt change and do a pull request, or what? |
| 21:09 | amalloy | yeah, send off a pull request and i'll be happy to release to clojars |
| 21:14 | TimMc | amalloy: done |
| 21:18 | itamar | what do most people use for networking with clojure? aleph? |
| 21:18 | amalloy | TimMc: 0.3.2 on clojars |
| 21:19 | TimMc | yay |
| 21:21 | amalloy | also, "a juxty thing because heck yes". i'm concerned you may be conning me into marrying you |
| 21:21 | TimMc | haha |
| 21:35 | technomancy | itamar: "networking" is a bit too vague to be useful |
| 21:37 | rien | Raynes: it's been a few weeks, no reply whatsoever (re nixeagle's live emacs buffer) |
| 21:40 | devn | to 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:41 | skelternet | I wonder if there is one in Austin. I know there was a fp group at one point |
| 21:41 | devn | we have haskellites, scalaphiles, clojurians, schemers, lispers, and more -- a great group of people to meet and talk to. |
| 21:41 | amalloy | a coupon? does meetup cost money? |
| 21:42 | itamar | technomancy: custom TCP server, say |
| 21:42 | devn | amalloy: 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:43 | devn | just for the support for the clojure community |
| 21:43 | devn | speaking of which -- i keep looking at clojure open source projects. how do i pay for them? :) |
| 21:44 | devn | "needs moar donation buttonz" |
| 21:45 | TimMc | bitcoin ^_^ |
| 21:53 | TimMc | The tricky bit is dividing the loot. |
| 21:53 | devn | I'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:38 | TimMc | amalloy: clojopts doesn't handle --nil=foo very well. :-) |
| 22:38 | amalloy | interesting |
| 22:39 | amalloy | i mean, it doesn't really matter of course, but i wonder why |
| 22:40 | TimMc | amalloy: Easy, you're using a macro to pick up symbols. |
| 22:40 | TimMc | Just like that conversation the other day. |
| 22:40 | amalloy | oh, you mean if you specify nil in the clojure spec-thingy |
| 22:41 | amalloy | i see |
| 22:41 | TimMc | yep |
| 22:41 | amalloy | i was trying to find where nil would upset the parsing code, not the spec code |
| 22:42 | amalloy | TimMc: a more interesting point that this implies is that you can't parse options like -1, the way head/tail do |
| 22:42 | TimMc | Ah. |
| 22:42 | amalloy | but i don't think getopt can either; head must roll its own |
| 22:43 | TimMc | Can't it? |
| 22:43 | TimMc | I have clojopts open, I'll try modifying it. |
| 22:43 | amalloy | TimMc: to be clear, i'm talking about 1 as an option "name" (key), not value |
| 22:44 | TimMc | yep |
| 22:44 | ermnik | how might one add a class to an element in hiccup? Like ckeditor to the text-area element? |
| 22:44 | amalloy | [:foo.editor] |
| 22:46 | ermnik | from the docs: (text-area name value) |
| 22:46 | ermnik | where would [:foo.editor] go? |
| 22:47 | ermnik | Or would i be using a more generic element function in hiccup? |
| 22:47 | TimMc | amalloy: You and your use of ` outside of macros... |
| 22:47 | amalloy | i think you should read the docstring, or possibly the source, for text-area |
| 22:48 | amalloy | TimMc: looking back over `man getopt`, i still don't see a thing like "call this function if you see an unrecognized argname" |
| 22:48 | amalloy | TimMc: which one are you thinking of? desugar-spec or something? |
| 22:48 | TimMc | yeah |
| 22:49 | amalloy | well, that's really in a macro anyway |
| 22:49 | TimMc | I mean, it reads nicely, but ` still says to me "Oh shit, here comes an s^w^w a macro!" |
| 22:49 | amalloy | hahaha |
| 22:50 | amalloy | it's just a helper function; not really the same thing as using `(~@x 0) as a shorthand for (concat x [0]) |
| 22:50 | TimMc | Oh, it's called from a macro, I see. |
| 22:50 | adiabatic | what would "an s" be? sexpr? |
| 22:50 | ermnik | amalloy: 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:50 | amalloy | $google apostrophe oh shit here comes an s |
| 22:50 | lazybot | [Oh shit, here comes an 's'. - Reddit] http://www.reddit.com/comments/65hz7/the_apostrophe_key_does_not_mean_holy_shit_here |
| 22:51 | TimMc | adiabatic: http://www.reddit.com/comments/65hz7/the_apostrophe_key_does_not_mean_holy_shit_here |
| 22:51 | TimMc | bah, slowternets |
| 22:51 | adiabatic | ah, thanks |
| 22:51 | TimMc | Bing had no idea what I was talking about. |
| 22:52 | amalloy | i'm glad lazybot got it right |
| 22:52 | TimMc | I think my trial of that particular search engine is over. |
| 22:52 | amalloy | ermnik: 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:56 | TimMc | amalloy: -1 works fine. desugar calls str on the names, but nil goes to "" |
| 22:56 | amalloy | TimMc: but does getopt actually parse it? |
| 22:56 | TimMc | amalloy: Yeah, ["-1" "foo"] => {:1 "foo"} |
| 22:57 | amalloy | that's pretty amazing |
| 22:57 | TimMc | --1 didn't work, of course -- then I fixed my code. |
| 22:59 | TimMc | I think I'll bundle that in with some doc fixes. |
| 23:09 | technomancy | devn: what does meetup get you over a static site? |
| 23:21 | alexbaranosky | devn: I'd also like to know what meetup gets you |
| 23:27 | rien | technomancy: findability |
| 23:28 | alexbaranosky | so 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:30 | alexbaranosky | I envisioned it looking something like: `(fact (doubler ..x..) => "AA" (provided (.toString Object ..x..) => "A") )` |
| 23:31 | alexbaranosky | but mostly I'm lost :) |