2011-06-30
| 00:04 | technomancy | yeah, this looks more like a clojure 1.3 beta bug |
| 00:06 | technomancy | or... it could be that hooke was depending on a clojure 1.2 bug that was fixed |
| 00:07 | technomancy | depending on how you want to frame it |
| 00:07 | technomancy | well, I'll be sure to issue a fix before 1.3.0 lands |
| 00:07 | technomancy | *fix or workaround |
| 00:13 | amalloy | technomancy: i'm curious what the actual issue was, if you've figured it out |
| 00:13 | technomancy | amalloy: http://p.hagelb.org/fn-meta.html |
| 00:14 | technomancy | I'm leaning towards the 1.2 behaviour being suspect |
| 00:14 | technomancy | as it's my understanding with-meta should create a copy of the function |
| 00:14 | amalloy | technomancy: i'm inclined to agree |
| 00:15 | technomancy | in retrospect I'm astonished it works in 1.2 |
| 00:17 | technomancy | well, I'll hit up the mailing list tomorrow |
| 00:17 | amalloy | technomancy: https://gist.github.com/1055630 |
| 00:17 | tomoj | flipping the buffers I thought I read "wetrospect" and was relieved not to find a pun |
| 00:18 | tomoj | s/ /through/ |
| 00:18 | amalloy | tomoj: wow, what a terrible regex that was. good thing we told sexpbot to ignore you, eh? |
| 00:18 | tomoj | well.. I didn't say g |
| 00:18 | tomoj | so it's only really a bit terrible, isn't it |
| 00:19 | technomancy | amalloy: crazy town |
| 00:19 | technomancy | looks like we've got some mutability! |
| 00:19 | technomancy | clojurebot: guards |
| 00:19 | clojurebot | SEIZE HIM! |
| 00:20 | amalloy | technomancy: not necessarily? it's possible that in (fn inner [f] ... inner), the reference to inner is interpreted in some crazy way as "the current function". that would make it possible without mutating |
| 00:20 | technomancy | amalloy: maybe. doubtful considering it doesn't work that way it 1.3 though |
| 00:20 | amalloy | agreed. i think mutation is more likely. writing up a test case to determine the difference |
| 00:28 | amalloy | technomancy: a bit weird, but that does seem to be what's going on: https://gist.github.com/1055630 |
| 00:38 | technomancy | boggled |
| 00:38 | sexpbot | java.lang.Exception: EOF while reading |
| 00:42 | amalloy | i like a good hunt through the compiler as much as the next guy, but figuring out where that change happened is too hard for me:P |
| 00:43 | pcavs_ | I'm confused. It seems like the expected behavior is what's occurring? I guess I just don't have the full context for the bug you are referencing |
| 00:44 | pcavs_ | but that gist you sent made perfect sense... |
| 00:49 | amalloy | pcavs_: one behavior that might be expected is that (fn foo []) would capture the object referenced by the function, and that a version of it wrapped with (with-meta) would still refer to the same foo |
| 00:50 | pcavs_ | ,(doc with-meta) |
| 00:50 | clojurebot | "([obj m]); Returns an object of the same type and value as obj, with map m as its metadata." |
| 00:50 | pcavs_ | ,(doc identical?) |
| 00:50 | clojurebot | "([x y]); Tests if 2 arguments are the same object" |
| 00:50 | pcavs_ | So clearly (with-meta) would create a different object, although they would have the same values. |
| 00:51 | pcavs_ | Just my 2 cents. |
| 01:02 | tomoj | I only just realized you can destructure infinite seqs |
| 01:03 | tomoj | &(let [[x y z] (repeatedly rand)] [x y z]) |
| 01:03 | sexpbot | ⟹ [0.7348056642450934 0.7090822026528741 0.10813687904097102] |
| 01:15 | amalloy | tomoj: yeah, it's even handier for functions with side effects: (let [[x y z] (repeatedly read)] to read three values, or (repeatedly gensym) to create a bunch of gensyms to manage manually for a macro |
| 01:17 | amalloy | though i guess for repeatedly to be at all interesting the function has to have side effects, so i'm not really saying anything you didn't know :P |
| 01:19 | tomoj | .. or side causes? |
| 01:21 | amalloy | referential opacities? |
| 02:07 | Scriptor | did there used be be a clojure-lounge? |
| 04:02 | Cozey | is there some convenient way to remove N last characters from a string? or do i have to go subs/count way |
| 04:08 | terom | Well, that or treat string as a seq and use seq functions on it. Not sure about the performance characteristics of these approaches. If you use (.length "str") instead of (count "str"), it could be better performance-wise. |
| 04:09 | terom | ,(apply str (drop-last 3 (seq "string"))) |
| 04:09 | clojurebot | "str" |
| 04:11 | amalloy | terom: .length will be very marginally faster if type-hinted properly, and massively slower if not type-hinted |
| 04:11 | terom | amalloy: ah, good to know |
| 04:18 | terom | Also Apache Commons Lang seems to have StringUtils#substring() which accepts negative offsets. |
| 04:31 | Cozey | oh, ok |
| 05:22 | sandGorgon | hi guys - I have a hash {:a 1 :b 2) . I have a (def mystr "a") - how can I get the value from hash based on mystr -> is there any conversion from mystr to a key ? |
| 05:24 | morphling | sandGorgon: you can use strings as keys in hash maps |
| 05:24 | morphling | there is also ##(keyword "a") |
| 05:24 | sexpbot | ⟹ :a |
| 05:25 | sandGorgon | morphling, that works thanks! the hashmap was coming in from a 3'rd party lib that already used symbols |
| 05:31 | morphling | sandGorgon: just don't call keyword on user supplied strings, they get interned which allows for easy DoS attacks |
| 06:34 | ojd20 | cemerick: Thanks for Bandalore - finding it very useful. I've got a situation where we could go days without a message to receive. Could pass a really large value in to polling-receive :max-wait, or extend polling-receive to poll indefinitely for :max-wait -1. Is there a more sensible alternative, though? |
| 07:16 | cemerick | ojd20: Glad you're finding it useful :-) |
| 07:16 | cemerick | Let me refresh my memory of the impl… |
| 07:19 | cemerick | ojd20: :max-wait of Long/MAX_VALUE is equivalent to waiting indefinitely |
| 07:20 | ojd20 | cemerick: OK, great. Thanks! |
| 07:20 | cemerick | ojd20: The more sensible alternative would be for me to reimplement polling-receive to use promises |
| 07:21 | ojd20 | cemerick: I'll need to read up on those! |
| 07:22 | cemerick | Actually, you'd still need period and max-wait, or you'd end up leaking threads spawned to fulfill those promises. |
| 07:22 | cemerick | ojd20: so, yeah, Long/MAX_VALUE if you want to wait indefinitely — but make sure that that's what you really want to do :-) |
| 08:02 | clgv | $findfn {:a 1, b 2 |
| 08:02 | sexpbot | [clojure.core/cond clojure.core/dosync clojure.core/import clojure.core/prn clojure.core/refer-clojure clojure.core/print clojure.core/with-loading-context clojure.core/newline clojure.core/comment clojure.core/or clojure.core/load clojure.core/shutdown-agents cloju... http://gist.github.com/1056107 |
| 08:02 | clgv | ups |
| 08:03 | clgv | $findfn {:a 1 :b 2} {:c 3 :d 5 :a 1 :b 2} true |
| 08:03 | sexpbot | [clojure.core/not= clojure.core/distinct? clojure.core/not-any? clojure.core/not-every?] |
| 08:03 | clgv | humm not quite my intention I guess |
| 08:04 | cemerick | ~max |
| 08:04 | clojurebot | maxine is http://research.sun.com/projects/maxine/ |
| 08:04 | cemerick | ~max |
| 08:04 | clojurebot | max people is 317 |
| 08:08 | clgv | ok I got it. I want to compare whether a map has certain key value pairs. I do it by (= (select-keys m [:a :b :c]) {:a true, :b 2, :c -1}) |
| 08:08 | clgv | I guess this is the shortest way |
| 08:12 | peteriserins | I do not understand the "where-params" parameter in clojure.contrib.sql/update-values |
| 08:13 | peteriserins | what is the syntax for the selection criteria string? |
| 08:13 | peteriserins | (documentation at http://clojuredocs.org/clojure_contrib/clojure.contrib.sql/update-values) |
| 08:14 | DerGuteMoritz | peteriserins: AFAIUI it wants something like ["foo = $1" value-for-foo] |
| 08:15 | DerGuteMoritz | (assuming postgres and proper bind variables) |
| 08:16 | peteriserins | DerGuteMoritz: I am using MySql and I want to update every row |
| 08:16 | peteriserins | can I use [""]? |
| 08:16 | DerGuteMoritz | oh I see |
| 08:16 | peteriserins | or should I use ["true"]? or something? |
| 08:16 | peteriserins | peteriserins: looking at the source code, I see now that it is plunked into the UPDATE query |
| 08:17 | DerGuteMoritz | right |
| 08:17 | DerGuteMoritz | probably best to just use do-prepared directly then |
| 08:19 | peteriserins | DerGuteMoritz: OK, thanks, I'll try something |
| 08:19 | DerGuteMoritz | good luck! |
| 08:24 | peteriserins | DerGuteMoritz: oops, actually, I do want to select specific rows |
| 08:25 | DerGuteMoritz | peteriserins: heh okay then update-values it is |
| 08:26 | peteriserins | DerGuteMoritz: basically, I am running map on a select statement |
| 08:26 | peteriserins | DerGuteMoritz: doing some parsing and I want to update a column for the row I am parsing |
| 08:27 | peteriserins | DerGuteMoritz: so I should be using something like ["Id = id" id] ? |
| 08:27 | DerGuteMoritz | peteriserins: yep, seems correct, assuming "Id" is your primary key :-) |
| 08:32 | peteriserins | DerGuteMoritz: it thinks Id is a parameter, and wants two more arguments in there |
| 08:32 | DerGuteMoritz | oh sorry, you need a parameter placeholder there |
| 08:32 | DerGuteMoritz | not sure what mysql uses for those, in postgresql it's $1, $2 etc. |
| 08:33 | DerGuteMoritz | so ["Id = $1" id] |
| 08:33 | DerGuteMoritz | I'm sure you'll find it in the manual though |
| 08:36 | clgv | is there something like the following macro in clojure or contrib? (defmacro vary-when [value, predicate?, vary-body] `(if (~predicate? ~value) ~vary-body ~value)) |
| 08:37 | clgv | I needed it for the 10th time or so,thats why I have written it. but if it already exists in either clojure or contrib I would use the existing one |
| 08:39 | DerGuteMoritz | clgv: not that I'm aware of but how about changing the expansion to be `(let [v value] (if (~predicate? ~v) ~vary-body ~v)) so that if value is function call it doesn't get called twice? |
| 08:40 | clgv | hmm yes thats an option ;) |
| 08:40 | DerGuteMoritz | I guess value getting evaluated twice would surprise a user |
| 08:40 | DerGuteMoritz | oh sorry, forgot to change the ~ properly there |
| 08:41 | DerGuteMoritz | but you get the idea hehe |
| 08:41 | sandGorgon | hi guys - anybody using enlive ? I have a sequence of maps, gotten from a "with-query-results" & "doall" and I cant for the life of me figure out how to pass it on to enlive templates/snippets |
| 08:42 | clgv | correct version: `(let [v# value] (if (~predicate? v#) ~vary-body v#)) |
| 08:42 | clgv | oops not completely |
| 08:42 | DerGuteMoritz | oh right, clojure macros are explicit renaming |
| 08:42 | clgv | `(let [v# ~value] (if (~predicate? v#) ~vary-body v#)) |
| 08:42 | DerGuteMoritz | annoyingly so :-) |
| 08:47 | clgv | humm another one is 'use-default it returns a given default-value if the evaluation of the body returns nil |
| 08:48 | DerGuteMoritz | hm question regarding clojure's macro system: the vary-when macro breaks when I redefine `let' or `if' - how can I ensure that the according definition of the macro expansion environment is used? |
| 08:48 | DerGuteMoritz | or does that happen only on the REPL? cause that's where I tried it |
| 08:49 | clgv | DerGuteMoritz: no it doesnt break! syntax-quote does resolution at compile time |
| 08:49 | DerGuteMoritz | clgv: I think `use-default' is the same as `or', is it? |
| 08:49 | clgv | you would have to redefine clojure.core/let to break it |
| 08:49 | DerGuteMoritz | clgv: ok then it's a REPL thing I guess |
| 08:49 | clgv | right it is 'or |
| 08:58 | timvisher | hey all |
| 08:58 | timvisher | anyone know if compojure supports default values for unbound keys in route destructuring, and what the syntax is for it if it does? |
| 09:16 | bsod1 | is there a way to stop VimClojure REPL when it's stuck in a loop? |
| 09:19 | clgv | is there a possibility to findout if there is a certain namespace on my classpath that might not be used/required yet, without requiring it in that instant? |
| 09:21 | nizze | Hi! |
| 09:22 | nizze | I'm a clojure newbie and I have couple of questions. |
| 09:23 | nizze | I'd like to know how fast (to run) Clojure is. Is it "fast enought" i.e. I can build most of my webdev tools with it? |
| 09:24 | nizze | also, I did (source number?) |
| 09:24 | nizze | What kind of black magic is this? |
| 09:24 | nizze | And even more bizarre: (source source) |
| 09:24 | timvisher | nizze: it's almost as fast as Java in most cases, and faster than Java in some |
| 09:24 | nizze | timvisher: Thanks. |
| 09:24 | timvisher | ,(source number?) |
| 09:24 | clojurebot | java.lang.Exception: Unable to resolve symbol: source in this context |
| 09:24 | Fossi | well, as you have the source for source, have a look ;) |
| 09:25 | Fossi | basically it searches for the source file and displays the functions sourcecode |
| 09:25 | timvisher | what black magic are you observing? |
| 09:25 | nizze | Yeah :D How come other (Algol based) languages do not let me do this |
| 09:25 | timvisher | they only score a 7.5 on the awesome scale |
| 09:25 | nizze | Does the source really search the source file or does it access the AST? |
| 09:25 | timvisher | clojure get's an 8.5. so it comes with source. ;) |
| 09:26 | Fossi | java/eclipse almost do |
| 09:26 | timvisher | it searches the source file |
| 09:26 | timvisher | for instance, define a function at the repl |
| 09:26 | timvisher | and then try to source it |
| 09:26 | Fossi | but most of those don't have the sources ready |
| 09:26 | timvisher | you get nothing |
| 09:26 | nizze | Bummer. |
| 09:26 | nizze | How can I access AST? |
| 09:27 | nizze | I heard that Lisps are special cause I can access the AST at runtime. |
| 09:27 | timvisher | nizze: this might help |
| 09:27 | timvisher | http://stackoverflow.com/questions/3782970/how-can-i-display-the-definition-of-a-function-in-clojure-at-the-repl |
| 09:28 | timvisher | i never bothered getting it working |
| 09:28 | timvisher | not sure exactly what you would mean by accessing the AST at runtime |
| 09:28 | timvisher | if you mean exposing the runtime AST as a datastructure, i've never heard of such a thing |
| 09:28 | timvisher | if you mean modifying the ast at runtime by simply redefining a function, then you can in fact do that easily |
| 09:29 | clgv | in clojure you can only access the definition of a function (via defn or fn) by intercepting the defining statements (defn/fn) via macros. |
| 09:30 | nizze | Uh. I thought that AST was available for me to toy with. I have to study more. |
| 09:30 | timvisher | that's what i mean, you're not really being descriptive enough about what you mean |
| 09:30 | clgv | nizze: it can be easily implemented though. |
| 09:30 | timvisher | what does 'play with' to you mean? |
| 09:30 | timvisher | mean to you* |
| 09:30 | nizze | A sec: |
| 09:31 | timvisher | s/to you mean/mean to you |
| 09:31 | timvisher | hmm |
| 09:31 | timvisher | is that supposed to work? |
| 09:31 | nizze | Well. |
| 09:32 | clgv | nizze: easiest but not most elegant solution: (defmacro defn-ast [name & args] `(defn ~name {:definition ~args} ~@args)) |
| 09:32 | nizze | There was a ruby project which let you write things like Users.all.select{|u| u.name == 'john'}.collect{|u| u.lastname} |
| 09:32 | nizze | And turn that to SQL |
| 09:33 | nizze | I start to get the feeling that I'm asking the wrong question. |
| 09:33 | timvisher | are you saying that's an example of playing with the ast? |
| 09:34 | clgv | nizze: you probably do |
| 09:34 | nizze | Yeah. |
| 09:34 | timvisher | how is that playing with the ast? |
| 09:34 | nizze | So basically what they did there is access AST and looked what user tried to do in Ruby and turn that to SQL |
| 09:34 | Vinzent | nizze, you can do all this sorts of things (and much more) with lisp macros; see at clojureQL for example |
| 09:35 | nizze | Vinzent: thanks! |
| 09:35 | clgv | nizze: AST = Abstract Syntax Tree, right? |
| 09:35 | nizze | clgv: Yeah. |
| 09:35 | timvisher | i'm not sure you understand the ruby code above, or maybe i don't |
| 09:35 | timvisher | that looks to me like a DSL, not something that accesses the ast |
| 09:36 | timvisher | they would take that and transform it into other code at run time and dynamically generate sql based on what you've typed |
| 09:36 | nizze | timvisher: nono, That was just the regular Ruby code playing with collections. |
| 09:36 | Vinzent | nizze, about AST: I think what's you've heard was about lisp syntax. Programs are actually trees, so the code is much closer to AST than in other languages |
| 09:36 | nizze | The library did that "behind the scenes" |
| 09:36 | timvisher | yes |
| 09:36 | timvisher | but that doesn't mean they're playing with the ast |
| 09:37 | nizze | Hmm. I try to find it. |
| 09:37 | timvisher | the runtime is examining that 'string' of code and dynamically generating the real code that get's executed |
| 09:37 | timvisher | macros, as everyone else keeps mentioning, are the way you accomplish that in lisps. |
| 09:38 | nizze | Okay. |
| 09:38 | nizze | Thanks for you trouble. I go study more now :) |
| 09:38 | Vinzent | And macros transforms code in compile time, which is much faster that ruby's approach. |
| 09:39 | timvisher | nizze: if you're in the mood to part with some of what's in your wallet, i'd recommend Joy of Clojure for getting a good flavor for what Macros can accomplish. |
| 09:40 | nizze | Thanks! I've been browsing LOL. For the very first chapters it was nicely written. |
| 09:43 | nizze | You guys are really nice. I once visited the CL channel and they started to flame me as soon as I asked a question about some old Lisp related rant. |
| 09:43 | timvisher | nizze: good to hear. come back any time. :) |
| 09:48 | clgv | hmm how do I get a namespace from a symbol? namespace returns a string |
| 09:48 | clgv | and I cant use require with a string |
| 10:20 | joegallo | (require (symbol "clojure.set")) seems to work |
| 10:21 | sandGorgon | anybody know how to get the actual java command issued by leiningen when you do "lein repl" ? |
| 10:22 | pjstadig | clgv: the-ns? |
| 10:22 | pjstadig | (doc the-ns) |
| 10:22 | clojurebot | "([x]); If passed a namespace, returns it. Else, when passed a symbol, returns the namespace named by it, throwing an exception if not found." |
| 10:51 | raek | sandGorgon: you can at least get the -cp part by running lein classpath |
| 10:52 | sandGorgon | raek, thanks! |
| 11:10 | nizze | HI! |
| 11:10 | nizze | How can I find which functions (or methods) operate on a string? |
| 11:10 | nizze | In OO-language I would look String class. What do I do in Clojure? |
| 11:11 | sritchie | here are some good ones -- http://clojure.github.com/clojure/clojure.string-api.html |
| 11:13 | nizze | Thanks. |
| 11:14 | ejackson | nizze: in general you'll find similar functions, like those for strings, in a single namespace. |
| 11:14 | nizze | ejackson: and what ns is that? |
| 11:14 | ejackson | my first guess would be clojure.contrib.string |
| 11:15 | ejackson | nizze: here: http://richhickey.github.com/clojure-contrib/string-api.html |
| 11:16 | sritchie | no, it's a little different! |
| 11:16 | sritchie | that's contrib, I gave clojure.string |
| 11:16 | ejackson | aaaah |
| 11:16 | sritchie | we also have http://richhickey.github.com/clojure-contrib/str-utils2-api.html |
| 11:16 | sritchie | and http://richhickey.github.com/clojure-contrib/str-utils-api.html |
| 11:16 | ejackson | there's also this one : http://richhickey.github.com/clojure-contrib/str-utils-api.html |
| 11:16 | nizze | So what's the deal with contrib? Is it some experimental stuff? |
| 11:17 | ejackson | its kindof, but not exactly, like the standard libraries |
| 11:28 | pcavs_ | What's the best way to restart lein swank while in emacs, assuming you've updated your dependencies. |
| 11:28 | pdk | [11:10] <nizze> In OO-language I would look String class. What do I do in Clojure? |
| 11:28 | pdk | it's still a java String since it's implemented on top of java, the String methods will still work with the interop forms |
| 11:31 | wastrel | i'm going to install emacs and the whole clojure developering stack |
| 11:35 | nizze | What is the recommended editor/ide for clojure? |
| 11:36 | nizze | Can I use vi? |
| 11:39 | pcavs_ | nizze: google vimclojure I believe is the usual setup for VIM |
| 11:39 | nizze | pcavs_: Thanks! What is considered "the editor" here? I guess it's Emacs? |
| 11:40 | pcavs_ | uhh, VIM would be the editor |
| 11:40 | Chousuke | use any editor you want |
| 11:40 | pcavs_ | I think it uses something similar to swank/slime although I'm honestly not sure |
| 11:40 | Chousuke | emacs has slime and paredit so it's pretty popular among lispers |
| 11:40 | dnolen | also slimv for Vim |
| 11:41 | Chousuke | I wonder if there's a vi clone written using some lisp anywhere |
| 11:41 | dnolen | Chousuke: well you do have viper-mode |
| 11:41 | lnostdal-laptop | emacs has a vim mode i think |
| 11:41 | lnostdal-laptop | yup |
| 11:41 | nizze | viper |
| 11:41 | Chousuke | dnolen: vipermode is bad though |
| 11:42 | Chousuke | it just doesn't work with most emacs extensions. at all |
| 11:42 | kryft | Isn't vimpulse much better? |
| 11:42 | Chousuke | kind of defeats the whole point of using emacs. |
| 11:42 | Chousuke | nah |
| 11:42 | Chousuke | it's a bit better but not by much |
| 11:43 | kryft | Isn't it orthogonal to emacs modes, meaning that it should work with extensions? |
| 11:43 | nizze | Okay. I already got accustomed to vim. So using vim with some slime plugin should be ok? |
| 11:43 | tufflax | nizze: yes emacs is "the editor" :P I think pcavs_ did not interpret your question the way you meant it |
| 11:43 | dnolen | Chousuke: really? Some people seem to really like it. But perhaps vim users are used to not demanding much from their editor |
| 11:43 | dnolen | nizze: you should be fine with Vim yes. |
| 11:43 | tufflax | nizze I use vim with vimclojure and im pretty happy |
| 11:44 | nizze | Okay, thanks. |
| 11:44 | tufflax | nizze you should take a look at leiningen and lein-vimclojure too i guess |
| 11:48 | nizze | Okay. Leningen. Is that a de facto build tool for Clojure? |
| 11:48 | nizze | I loathe Maven and the like. |
| 11:48 | nizze | No xml for me pls. |
| 11:48 | coopernurse | lein avoids xml |
| 11:48 | coopernurse | but lets you rope in maven dependencies if you need them |
| 11:48 | tufflax | it's the most popular I guess, but there is also cake and maybe some others |
| 11:52 | nizze | How about testing? What is Clojure community's take on testing? |
| 11:57 | tufflax | I imagine the community likes it. lein can help you out a bit there too |
| 11:59 | wastrel | hi |
| 11:59 | wastrel | i have been using vi/vim for 20 years |
| 12:00 | Vinzent | nizze, you should definitely try Midje for testing - it's awesome! |
| 12:01 | nizze | Vinzent: thanks. |
| 12:03 | wastrel | what's midje? |
| 12:03 | tufflax | a testing framework |
| 12:04 | Vinzent | https://github.com/marick/Midje |
| 12:06 | wastrel | my favorite answer to any technology question "it's a framework" :] |
| 12:07 | Vinzent | lol :) |
| 12:20 | bsod1 | how can I see result of macroexpand or macroexpand-1? it returns something like #<user$problem_2 user$problem_2@864dfeb> |
| 12:20 | raek | bsod1: macroexpand needs the code in quoted form |
| 12:21 | raek | ,(macroexpand '(if-not a b c)) |
| 12:21 | clojurebot | (if (clojure.core/not a) b c) |
| 12:21 | bsod1 | raek: can I send it a function like in Common Lisp? |
| 12:21 | mattmitchell | I'm trying to use resolve, but the value I'm passing in is a keyword -- which doesn't work. How can I convert a keyword into something resolve wants? |
| 12:22 | raek | bsod1: what happens when you give it a function in common lisp? |
| 12:22 | bsod1 | raek: it expands the function's code and prints(at least in REPL) |
| 12:23 | technomancy | CL has interpreted mode as well as compiled, so it keeps the source around. clojure is only compiled. |
| 12:23 | technomancy | however |
| 12:23 | technomancy | clojurebot: serializable-fn |
| 12:23 | clojurebot | No entiendo |
| 12:23 | technomancy | clojurebot: get with the program |
| 12:23 | clojurebot | "There has to be something a little wrong with you for you to be a really good programmer." -- L Peter Deutsch |
| 12:23 | dnolen | mattmitchell: convert the keyword to a symbol? seems like a weird thing to do tho. |
| 12:23 | raek | mattmitchell: are you trying to use a namespace like if was a map? |
| 12:23 | technomancy | clojurebot: serializable-fn is a hack for preserving source of a compiled function: https://github.com/technomancy/serializable-fn |
| 12:23 | clojurebot | c'est bon! |
| 12:24 | mattmitchell | raek dnolen: I have a list of function names as keywords, I want to loop through those names and call corresponding functions |
| 12:25 | raek | mattmitchell: my approach would have been to make a map from keywords to functions |
| 12:26 | raek | especially if the keyword comes from a (possibly "evil") user |
| 12:27 | mattmitchell | raek: good idea, I'll try that instead |
| 12:27 | raek | mattmitchell: but you can use namespace and name to extract the parts before and after the /, and then call symbol woth those |
| 12:27 | raek | *with |
| 12:27 | mattmitchell | raek: ok cool got it, thanks |
| 12:28 | tufflax | mattmitchell i did something similar http://pastebin.com/tDs5p2KH |
| 12:29 | raek | mattmitchell: but beware of the security implications, etc etc |
| 12:29 | mattmitchell | tufflax: thanks! i'll check it out. |
| 12:29 | mattmitchell | raek: yeah you're right. thanks for pointing that out. |
| 12:32 | micahmartin | leiningen question: Custom tasks need to be in src/leiningen or else their not found. However 'lein jar' fails because custom tasks depend on leiningen but leiningen in not in the classpath. Is there a common resolution? |
| 12:33 | micahmartin | technomancy: where should custom lein tasks go if not in src/leiningen? |
| 12:34 | technomancy | micahmartin: lein jar shouldn't fail |
| 12:34 | technomancy | unless you have :aot :all |
| 12:34 | micahmartin | I do |
| 12:35 | micahmartin | kinda need it because I'm doing some dynamic loading |
| 12:35 | technomancy | I guess you need to move the tasks into a plugin if you can't stop using :aot :all |
| 12:35 | technomancy | or define them in project.clj |
| 12:36 | technomancy | (ns leninigen.foo)(defn foo [project] ) |
| 12:37 | technomancy | :aot :all is meant more as a convenience thing so you can do quick sanity checks to see if everything compiles |
| 12:37 | technomancy | you could also do :aot #"myproject" |
| 12:38 | micahmartin | oooh... does that filter by namespace? |
| 12:38 | technomancy | yup |
| 12:39 | technomancy | generally given transitive AOT you can just specify a single ns and all the ones it requires will be aot'd too though |
| 12:40 | micahmartin | Is there any way to add to lein |
| 12:41 | micahmartin | ... lein's default classpath (when it searches for tasks)? |
| 12:41 | technomancy | you can export CLASSPATH |
| 12:42 | micahmartin | :) old school! |
| 12:44 | micahmartin | If I submited a patch to make leiningen add configured :resources-path, :dev-resources-path, :source-path, etc... to the CLASSPATH, would you accept? |
| 12:44 | technomancy | unfortunately that can't be done; by the time project.clj is read it's too late |
| 12:45 | technomancy | unless you want to write a clojure parser in sh =) |
| 12:45 | micahmartin | good point... |
| 12:45 | micahmartin | what about supporting a .classpath file? |
| 12:45 | technomancy | sure; that'd be fine |
| 12:46 | micahmartin | You'd accept a patch for that? |
| 12:46 | technomancy | yeah |
| 12:46 | micahmartin | sweeet! |
| 12:46 | micahmartin | you'll have it later today |
| 12:47 | technomancy | will probably have a 1.6.1 release given the bug with hooke in 1.3 that was found last night |
| 13:04 | halfprogrammer | anybody checked out google+? |
| 13:09 | tufflax | Hm. I had a problem with nesting map calls so deep that the I got a stackoverflowerror. But not in a loop/recur or reduce, instead I was saving a map in an atom representing a player in my game, and each frame I calculated the position (a list of x and y) from the old one with a map call. And when I printed the player map, I got the error. What I find strange is that another part of the program used that position every frame. Shouldn't that |
| 13:14 | S11001001 | tufflax: might the map you're putting in the atom be a map containing the atom? |
| 13:15 | tufflax | no |
| 13:16 | tufflax | When I said map calls I meant the fn map, eg (map prn [1 2 3]) |
| 13:17 | raek | tufflax: try surrounding the map call with (doall ...) |
| 13:17 | tufflax | yes i did, but I wanna know what was going on |
| 13:18 | raek | tufflax: also, your message was clipped after "Shouldn't that" |
| 13:18 | tufflax | Shouldn't that have realized the list? And if not, shouldn't that other function have caused the stackoverflowerror? |
| 13:19 | raek | the seq is only forced when you look at the first element |
| 13:19 | S11001001 | tufflax: map doesn't do anything until you seq it, whether by first or whatever |
| 13:20 | S11001001 | ,(do (map nil 42) true) |
| 13:20 | clojurebot | true |
| 13:20 | raek | the lazy-seq represents something like (map f (map f (map f (map f ...)))) |
| 13:20 | raek | each update adds a layer of laziness |
| 13:20 | raek | when the outermost seq is forced, it must ask the seq one step inwards for it value, which must ask the next, and so on |
| 13:21 | raek | each forcing requires at least one function call stack frame |
| 13:22 | tufflax | yes i know, but every frame x and y were used to draw the player. So, ok, first: If a have an unrealized such seq (map (map (map ...))) in a data structure, and then use it, will the data structure now contain the realized list or still the same unrealized seq? |
| 13:23 | tufflax | Will the seq morph into a realized seq inside the immutable datastructure? |
| 13:23 | S11001001 | yes |
| 13:24 | tufflax | then i dont understand whats happening in my program :p |
| 13:30 | tufflax | raek S11001001 take a look: http://pastebin.com/ENJ4w8eG |
| 13:30 | pcavs_ | what do people use for sql libraries in clojure? clojureql or clojure.contrib.sql? |
| 13:32 | raek | tufflax: yes, lazy-seqs mutate internally when they are computed (they do so in a thread safe manner, of course) |
| 13:33 | S11001001 | tufflax: I imagine it's because you never forced the (rest (rest pos)) |
| 13:34 | raek | maybe the rest of the rest of the seq is never forced... :7 |
| 13:34 | S11001001 | I don't think the [x y] destructuring will force the rrest |
| 13:34 | amalloy | &(destructure '[id [x y]]) |
| 13:34 | sexpbot | ⟹ [id [x y]] |
| 13:34 | amalloy | feh |
| 13:34 | tufflax | oh, maybe... im gonna have to think about that, now i have to eat. thank you, back later |
| 13:35 | amalloy | &(macroexpand '(let [[id [x y]] fn-args]) |
| 13:35 | sexpbot | ⟹ (let* [vec__11920 fn-args id (clojure.core/nth vec__11920 0 nil) vec__11921 (clojure.core/nth vec__11920 1 nil) x (clojure.core/nth vec__11921 0 nil) y (clojure.core/nth vec__11921 1 nil)]) ; Adjusted to (macroexpand (quote (let [[id [x y]] fn-args]))) |
| 13:36 | raek | ,(letfn [(lazy-bomb [n] (lazy-seq (if (zero? n) (println "BOOM!") (cons n (lazy-bomb (dec n)))))] (let [[x y] (lazy-bomb 2)] [x y])) |
| 13:36 | clojurebot | Unmatched delimiter: ] |
| 13:37 | raek | ,(letfn [(lazy-bomb [n] (lazy-seq (if (zero? n) (println "BOOM!") (cons n (lazy-bomb (dec n))))))] (let [[x y] (lazy-bomb 2)] [x y])) |
| 13:37 | clojurebot | [2 1] |
| 13:37 | raek | ,(letfn [(lazy-bomb [n] (lazy-seq (if (zero? n) (println "BOOM!") (cons n (lazy-bomb (dec n))))))] (let [[x y] (lazy-bomb 1)] [x y])) |
| 13:37 | clojurebot | BOOM! |
| 13:37 | clojurebot | [1 nil] |
| 13:37 | raek | this explains it |
| 13:38 | wastrel | bomb! |
| 13:38 | S11001001 | sneaky cdr |
| 13:40 | amalloy | raek: and he can verify it by seeing that (println (take 2 whatever)) prints fine, while (println whatever) doesn't |
| 13:41 | S11001001 | insert debugging print, code suddenly works |
| 13:43 | amalloy | raek: or...maybe not? if he never forces the tail of the sequence, he may not run out of stack but he'll keep growing heap, won't he? all these lazy-seqs stacked on top of each other have to hang around just in case he ever wants to detonate the bomb |
| 13:44 | S11001001 | yeah, and the naming of the binding where the map result goes implies that tufflax meant to use vec there |
| 13:45 | amalloy | S11001001: vector as in mathematics, not clojure's data structure |
| 13:45 | amalloy | i doubt he ever cared what the underlying type of that intermediate sequence was |
| 14:27 | amalloy | cemerick: what's git --version say? |
| 14:27 | amalloy | i ask because your issue sounds like https://github.com/blog/809-git-dumb-http-transport-to-be-turned-off-in-90-days |
| 14:28 | cemerick | heh, probably something horribly out of date |
| 14:28 | cemerick | 1.6.2.2! :-P |
| 14:29 | cemerick | Yup, that's probably it |
| 14:29 | cemerick | amalloy: thanks, that probably saved me some wasted network diagnostic time |
| 14:42 | tufflax | amalloy raek S11001001 thank you. I tried with (take 2 pos) and that didn't blow up. But I'll use doall now that I know what is happening. :) |
| 15:06 | jcromartie | is there any mechanism within clojure.test that allows you to check simple code coverage? |
| 15:06 | jcromartie | like, what defns are covered and what aren't, etc? |
| 15:07 | technomancy | jcromartie: radagast does that. it's pretty simplistic though. |
| 15:08 | hiredman | I really wish git kept a .history |
| 15:09 | jcromartie | I guess the easiest way would be to keep tests directly in-line with what they are testing |
| 15:09 | jcromartie | in metadata |
| 15:09 | jcromartie | wait that's what deftest already does |
| 15:12 | technomancy | jcromartie: that tells you nothing about indirect coverage |
| 15:12 | jcromartie | no I read it wrong... I assumed deftest re-def'ed whatever name you passed it |
| 15:14 | amalloy | hiredman: what would it do? |
| 15:18 | hiredman | amalloy: n-last branches checked out |
| 15:18 | amalloy | hiredman: the reflog does that |
| 15:19 | hiredman | well damn |
| 15:19 | hiredman | alright then |
| 15:19 | amalloy | well. it records them. i'm still not entirely clear how you'd want to use it. but $ git reflog show HEAD will tell you all the commits HEAD has pointed at recently |
| 15:19 | jcromartie | zipmap is wonderful |
| 15:21 | hiredman | amalloy: mostly I want to be able to figure out which branch I was working before I got interrupted by something else, without having to go through the issue tracker, find which issue it was and then map from issue to branch |
| 15:21 | amalloy | ah cool. so it sounds like the reflog is the answer |
| 15:21 | matthias__ | hmm, i've been writing a game using penumbra for a while now, i tried adding a new library but then got an error... which seems to be actually penumbra related. i reverted all the changes i made about that new library and now i get an error message saying "geometry.clj:1:1: |
| 15:21 | matthias__ | error: java.lang.Exception: Unable to resolve symbol: dimension in this context (geometry.clj:35)". i've looked, there's no "dimension" in geometry.clj (that is one of penumbra's files). |
| 15:22 | hiredman | amalloy: looks like it is, thanks |
| 15:23 | wastrel | penumbra is i think the name of a game |
| 15:40 | jcromartie | yes |
| 15:41 | jcromartie | penumbra is a horror game |
| 15:41 | jcromartie | is there a way to access nested keys like the way update-in works? |
| 15:41 | jcromartie | like, to just get the value? |
| 15:41 | mattmitchell | to document a function with multi arity arg sets, do you have to add a doc string for each variant? |
| 15:42 | mattmitchell | ,(defn c []) |
| 15:42 | clojurebot | DENIED |
| 15:42 | jcromartie | get-in |
| 15:42 | jcromartie | derp |
| 15:42 | amalloy | mattmitchell: no, and you're not allowed to |
| 15:43 | amalloy | (defn c "explain all the arities here" ([]) ([x] x)) |
| 15:43 | jcromartie | I was originally annoyed by that, and by not being able to add a docstring for defmethod... but then I realized why. |
| 15:44 | matthias__ | oenumbra is a clojure library |
| 15:44 | jcromartie | If your multimethod is so complex that each dispatch value deserves its own documentation then you are Doing it Wrong™ |
| 15:44 | matthias__ | *pen |
| 15:44 | jcromartie | matthias__: yes but there is also a game |
| 15:44 | matthias__ | but i wasnt talking about that oO |
| 15:44 | mattmitchell | amalloy: oh right, thanks! |
| 15:45 | jcromartie | :) someone mentioned that they thought it might be a game |
| 15:45 | jcromartie | "wastrel: penumbra is i think the name of a game" |
| 16:17 | jcromartie | is this channel publicly logged? |
| 16:17 | jcromartie | clojurebot: logs |
| 16:17 | clojurebot | logs is http://clojure-log.n01se.net/ |
| 16:17 | jcromartie | I knew he'd have an answer. |
| 16:18 | jcromartie | (inc clojurebot) |
| 16:24 | hiredman | http://thelastcitadel.com:3000/?page=0&q=channel%3Aclojure |
| 16:30 | amalloy | jcromartie: sexpbot keeps a log too. so that's at least three logs |
| 16:32 | amalloy | http://www.raynes.me/logs/irc.freenode.net/clojure/today.txt |
| 16:33 | amalloy | dangit, today isn't symlinked right? i guess http://www.raynes.me/logs/irc.freenode.net/clojure/2011-06-30.txt works. Raynes, what's up with the today thing? |
| 16:48 | bartj | what is the best library to get tf-idf scores using Clojure ? |
| 16:54 | mikesomething | what's the clojure equivalent of "synchronized(someObject) { ... }" ? |
| 16:54 | mikesomething | dosync doesn't seem to do that |
| 16:55 | hiredman | are you sure you want a lock? |
| 16:55 | mikesomething | yes |
| 16:55 | hiredman | ,(dock locking) |
| 16:55 | clojurebot | java.lang.Exception: Unable to resolve symbol: dock in this context |
| 16:56 | hiredman | ,(doc locking) |
| 16:56 | clojurebot | "([x & body]); Executes exprs in an implicit do, while holding the monitor of x. Will release the monitor of x in all circumstances." |
| 16:56 | scgilardi | ,(doctor locking) |
| 16:56 | clojurebot | java.lang.Exception: Unable to resolve symbol: doctor in this context |
| 16:56 | mikesomething | probably doing it wrong, but i have a zillion threads working hard and the final output is a quick-write/append to a textfile i want to lock on that output operation |
| 16:58 | technomancy | mikesomething: a common idiom is to serialize through an agent |
| 16:59 | mikesomething | what are agents? |
| 16:59 | hiredman | ~agents |
| 16:59 | clojurebot | excusez-moi |
| 17:01 | technomancy | http://clojure.org/agents |
| 17:01 | amalloy | yes, agents are the usual solution to this problem |
| 17:02 | mikesomething | the lock increased my running time just on the output (i thought it was quicker) by 12% |
| 17:02 | mikesomething | can someone give me a small hand-waving about what promises are all about? |
| 17:03 | pcavs_ | Hey! I want to create a macro that takes a body, but I want a value bound to a symbol that the body could operate on. Is this possible? |
| 17:03 | pcavs_ | In this case I have an ephemeral result set that will get blown away when I step outside of the scope |
| 17:04 | chouser | mikesomething: a promise is a reference object, that is you can deref it to get what's inside. |
| 17:04 | Chousuke | something like `(let [~'a-name foo] ...) |
| 17:04 | amalloy | pcavs_: i dont' understand what you want, but it is possible |
| 17:04 | Chousuke | then a-name can be referred to from whatever ... is |
| 17:04 | chouser | mikesomething: ...unless there's nothing inside, in which case your deref will block until something is put in there. |
| 17:04 | pcavs_ | Chousuke, I saw something else like ~' what does that do? |
| 17:04 | bartj | chouser, usually associated with futures ? |
| 17:04 | mikesomething | so i can create a bunch of promises |
| 17:04 | mikesomething | and they just sit there lazily until i deref? |
| 17:04 | Chousuke | pcavs_: it puts the symbol as is in the expansion (within syntax-quote) |
| 17:05 | mikesomething | or do they execute when they can? |
| 17:05 | Chousuke | compare |
| 17:05 | chouser | bartj: not necessarily, but only useful if you've got more than one thread. |
| 17:05 | Chousuke | ,`(let [a 1] ...) |
| 17:05 | clojurebot | (clojure.core/let [sandbox/a 1] ...) |
| 17:05 | Chousuke | ,`(let [~'a 1] ...) |
| 17:05 | clojurebot | (clojure.core/let [a 1] ...) |
| 17:05 | pcavs_ | oh okay, as opposed to just ~ |
| 17:05 | pcavs_ | which does what differently? |
| 17:05 | chouser | mikesomething: a promise doesn't have anything in it when you create it. It's just an empty box until some other thread delivers to it. |
| 17:05 | Chousuke | ,`(let [~a 1] ...) ; doesn't work |
| 17:05 | clojurebot | java.lang.Exception: Unable to resolve symbol: a in this context |
| 17:05 | Chousuke | ,(let [a 'some-symbol] `(let [~a 1] ...)) ; does work |
| 17:05 | clojurebot | (clojure.core/let [some-symbol 1] ...) |
| 17:06 | mikesomething | so if i put a closure into a promise, what happens? |
| 17:06 | amalloy | mikesomething: then...you'll have a promise, with a closure in it |
| 17:06 | chouser | mikesomething: when you deref the promise, you'll be given a closure |
| 17:07 | mikesomething | maybe i'm not getting it, what's a tiny real-life example of promises |
| 17:07 | Chousuke | pcavs_: so basically ~ is a feature of syntax-quote that evaluates the following expression in the local context and uses that in the expansion. |
| 17:07 | pcavs_ | ,(defmacro [& body] (let [~'results (list 1 2 3)] ~@body)) |
| 17:07 | clojurebot | java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol |
| 17:07 | Chousuke | pcavs_: evaluating 'a results in just the symbol a which is why ~'a gets around the namespace qualifying mechanish |
| 17:08 | Chousuke | mechanism* |
| 17:08 | pcavs_ | Chousuke, ahh I see |
| 17:08 | pcavs_ | Makes sense. |
| 17:09 | Chousuke | pcavs_: you need to use syntax quote before that (let..., otherwise it's just a let, not a data structure :P |
| 17:10 | chouser | mikesomething: hm, let's see. there's a section of this book here entitled "when to use promises" |
| 17:10 | Chousuke | pcavs_: note though that pulling variables out of thin air is usually not a good idea, so be careful. |
| 17:10 | pcavs_ | yeah..what's a better idiom then? |
| 17:10 | Chousuke | pcavs_: if you must, make your macro take another argument that the results get bound to |
| 17:11 | Chousuke | so that the macro call looks something like (foo [res] bodyhere) |
| 17:11 | pcavs_ | the other variable would need to be syntax symbol quoted though right? |
| 17:11 | Chousuke | (vector is optional but most binding things use vectors so it's idiomatic) |
| 17:11 | hiredman | mikesomething: if you have thread A doing X and thread B doing Z and Z depends on some but of data from X, Z can do as much as it can in parallel to X and then block until the bit it needs is available |
| 17:12 | mikesomething | oh ok |
| 17:12 | hiredman | similar to using a transfer queue, but single shot |
| 17:12 | mikesomething | so it's for mutually inclusive threaded operations and prevents deadlock? |
| 17:12 | Chousuke | pcavs_: (defmacro foo [[arg] & body] `(let [~arg (list 1 2 3)] ~@body)) |
| 17:12 | hiredman | I dunno about prevents deadlock |
| 17:14 | hiredman | I also end up using promises to turn void java methods into fns that return something |
| 17:15 | amalloy | hiredman: how do you mean? |
| 17:16 | hiredman | like, if you have some set of visitor pattern interfaces |
| 17:17 | hiredman | so you have VisitorThing ThingYouVisit and ThingYouVisit has a .visit method that returns void and takes a VisitorThing you can reify VisitorThing and have it deliver data to a closed over promise |
| 17:17 | amalloy | i see |
| 17:18 | hiredman | https://github.com/hiredman/agilezen-jdbc/blob/master/src/agilezen_jdbc/core.clj pretty horrendous example usage with a SQL statement parsing library that uses visitors |
| 17:23 | pcavs_ | ,(defmacro foo [[arg] & body] `(let [~arg (list 1 2 3)] ~@body)) |
| 17:23 | clojurebot | DENIED |
| 17:26 | pcavs_ | Chousuke: I don't think that works. |
| 17:31 | tnbd | Hello, just wanted to ask whether anyone is creating a starter package for the next ai contest http://aichallengebeta.hypertriangle.com/ |
| 17:32 | amalloy | pcavs_: works fine |
| 17:32 | amalloy | (foo [x] x) yields (1 2 3) |
| 17:35 | dnolen | tnbd: doesn't seem like it. |
| 17:36 | ibdknox | tnbd: I might |
| 17:36 | pcavs_ | amalloy: I am stupid. Thanks. |
| 17:36 | ibdknox | I would definitely like to do it this year |
| 17:36 | ibdknox | not sure how busy I'll be though :( |
| 17:42 | ibdknox | if we wanted to take the easy way out I guess we could wrap the java one... |
| 17:42 | ibdknox | https://github.com/aichallenge/aichallenge/tree/epsilon/ants/dist/starter_bots/java |
| 17:50 | pcavs_ | Chousuke , amalloy: Why choose the have [arg] be in a vector? You metnioned it's idiomatic, but why is that the idiomatic decision. Usually there is some underlying reason, just wondering why. |
| 17:51 | Chousuke | pcavs_: often times you want more than one binding so a vector if bindings makes sense |
| 17:51 | amalloy | pcavs_: compare to common lisp: (let ((x 1) (y 2)) (+ x y)) |
| 17:51 | pcavs_ | mmhmm, makes sense |
| 17:52 | amalloy | there are a lot of parens: some are for grouping, and some are to call functions (or macros) |
| 17:52 | amalloy | clojure uses vectors for bindings so that lists usually mean "this is code" |
| 17:52 | amalloy | (and it can't use bare symbols for the reason Chousuke gives |
| 17:55 | hiredman | (let x 1 y 2 :in (+ x y)) |
| 17:55 | bsod1 | I really love vim but vimclojure REPL under vim is too slow, any advices? |
| 17:56 | amalloy | hiredman: fair enough, i suppose |
| 17:56 | dnolen | hiredman: keep that ML stuff outta here! |
| 17:57 | hiredman | or, get this, no more implicit do |
| 17:57 | hiredman | (let x 1 y 2 (+ x y)) |
| 17:57 | hiredman | more like cond |
| 18:13 | derp__ | I am trying to figure out how to use agents, and I am getting kind of confused |
| 18:13 | derp__ | this is my def for an agent: (def a (agent (fn [new-str] (println "Hello, " new-str "!")))) |
| 18:14 | derp__ | but when I run (send a "world") I get an error |
| 18:14 | amalloy | derp__: agents hold values, and are sent functions |
| 18:16 | amalloy | &(let [a (agent "test")] (send a (fn [old new] (str old new)) "more") (await a) @a) |
| 18:16 | sexpbot | Execution Timed Out! |
| 18:16 | amalloy | that's wrong. in my repl it prints "testmore" immediately |
| 18:17 | derp__ | amalloy: ah, thank you for clearing that up |
| 18:17 | amalloy | derp__: all of clojure's reference types behave that way: hold types, receive functions |
| 18:17 | amalloy | er |
| 18:17 | amalloy | hold values |
| 18:18 | hiredman | amalloy: sexpbot's threadpools are most likely shutdown |
| 18:18 | hiredman | ,(let [a (agent "test")] (send a (fn [old new] (str old new)) "more") (await a) @a) |
| 18:18 | clojurebot | "testmore" |
| 18:20 | mikesomething | with lazy-seq can i write tail-recursive functions without regarding to the recursion stack limit of 5000? |
| 18:21 | amalloy | hiredman: oh snap. did someone call shutdown-agents on him? that's mean |
| 18:21 | derp__ | amalloy: just to double check, when sending a function to an agent, the current agent value will always be the arg, correct? |
| 18:21 | derp__ | the first arg* |
| 18:21 | dnolen | mikesomething: pretty much. |
| 18:21 | amalloy | will always be the *first* arg |
| 18:21 | hiredman | amalloy: most likely it was swank-clojure |
| 18:22 | derp__ | amalloy: thanks |
| 18:22 | dnolen | mikesomething: the main thing that doesn't work with lazy-seqs from I can tell is CPS style code, that requires trampoline. |
| 18:22 | scottj | better way to write this? (cond (:completed task) :completed (:canceled task) :canceled (:started task) :started :else :new) |
| 18:23 | hiredman | scottj: I would added a field like :state to task |
| 18:25 | amalloy | (or (some #(% task) [:completed :canceled :started]) :new)? |
| 18:25 | scottj | hiredman: mostly just interested in better way to write a cond like that. |
| 18:25 | vagif | hello, i wrap an exception in my own and throw it, but when i catch it my wrapper is not there. The stack trace starts from original error |
| 18:25 | amalloy | i guess that's not right |
| 18:25 | amalloy | replace some with (comp first filter), as so often seems to happen :P |
| 18:25 | scottj | hiredman: in this case I think makes sense to track separately cause task could be started then canceled and I might want to know that |
| 18:26 | technomancy | scottj: there's always reduce |
| 18:27 | derp__ | if I have a function that's treated as data (such as '(println "Hello)) how would I turn that into a piece of callable code? |
| 18:28 | derp__ | I get (eval '(println "Hello world")) |
| 18:28 | dnolen | ,(or (some #(and (% {:completed true}) %) [:completed :canceled :started]) :new) |
| 18:28 | clojurebot | :completed |
| 18:28 | dnolen | (or (some #(and (% {:foo 'bar}) %) [:completed :canceled :started]) :new) |
| 18:28 | dnolen | ,(or (some #(and (% {:foo 'bar}) %) [:completed :canceled :started]) :new) |
| 18:28 | clojurebot | :new |
| 18:28 | derp__ | but I don't get how I can turn something like (def hello '(println "Hello world!")) can be evalled |
| 18:28 | derp__ | into something to be evaluated* |
| 18:29 | mikesomething | derp |
| 18:29 | mikesomething | wrap it in a clojure |
| 18:30 | mikesomething | (def hello #(println "Hello world!")) |
| 18:30 | mikesomething | #'user/hello |
| 18:30 | mikesomething | hello |
| 18:31 | derp__ | I thought # was a compile-time macro |
| 18:31 | amalloy | derp__: answer: stop trying to pass around code forms at runtime |
| 18:32 | amalloy | you can do it, because of eval, but you shouldn't unless you're doing some very low-level stuff like implementing an IDE |
| 18:33 | hiredman | scottj: I don't see what that has to do with it |
| 18:33 | amalloy | instead, use macros to construct the forms you want at compile time, or first-class functions to pass around "code snippets" enclosed in functions at runtime |
| 18:33 | hiredman | (defrecord task [state log]) |
| 18:33 | derp__ | I just think it would be kind of interesting, to make it so that agents are smarter than simple users of functions |
| 18:34 | ibdknox | derp__: in what way? |
| 18:34 | amalloy | huh? what feature do you envision becoming possible? |
| 18:36 | derp__ | I don't really have a plan, I just want to play around with it and see what's the easiest way of doing something |
| 18:36 | derp__ | I mean I am assuming that I'm taking the wrong/long way to accomplish this, but I just thought it would be an interesting piece of behavior to look at |
| 18:37 | derp__ | idk |
| 18:43 | scottj | hiredman: fair enough, for now I prefer being able to do (:started task) instead of defining a predicate that looks through the log and see if there was a state :started that's not followed by an undo. but I suspect there are some benefits to your model I'm missing |
| 18:44 | dnolen | derp__: (do (def x '(println "Hello world")) (eval x)), will work. But know that eval won't have access to locals (if you're used to the behavior of JS for example) |
| 18:45 | dnolen | derp__: also eval is crazy slow since it's actually compilation. |
| 18:47 | derp__ | dnolen: thanks. But what do you mean eval is slow? I thought the whole point of lisp was to play with the program<->data representations, and eval is the only convert data->program, right? |
| 18:47 | amalloy | technomancy: your tweet confuses me. didn't we prove last night that that's *not* what's happening? |
| 18:47 | amalloy | derp__: no! *macros* are the best way to convert data to a program |
| 18:48 | amalloy | eval is indeed crazy slow, just like in any other language |
| 18:49 | gfrlog` | (binding [*macros* "lots"] (eval '(println "twelve!"))) |
| 18:49 | derp__ | amalloy: but macros only run at compile time, right? so no one really plays with that stuff in running programs? |
| 18:49 | amalloy | mhm |
| 18:49 | amalloy | if you are writing your program at runtime, you're doing it wrong |
| 18:50 | technomancy | amalloy: I think your gist may have shown that it's more complicated when functions are let-bound |
| 18:50 | amalloy | technomancy: my conclusion was that it has nothing to do with metadata: the "foo" in (fn foo [x]) is bound to java's "this" |
| 18:51 | amalloy | code<=>data is appealing because it's easy to hook into the compiler: you just write a function that takes some data, returns some other data, and suddenly you've written a piece of the compiler for your program |
| 18:52 | amalloy | technomancy: so that when you attach metadata to a function f, you get out a new function, with the same class but a different this reference; then it compares whatever you call it on against *itself* instead of the original function |
| 18:52 | technomancy | amalloy: hum... I see |
| 18:53 | amalloy | i'm still not *entirely* sure that's what's going on, though. do you know a good way to test it on something other than meta? |
| 18:53 | technomancy | if that's the case then the 1.3 behaviour is quite strange |
| 18:54 | amalloy | technomancy: actually i think i am sure. https://gist.github.com/1055630 shows that a function's "name" is returning itself |
| 18:54 | amalloy | (the second part, specifically) |
| 18:56 | mikesomething | i think a program i wrote in clojure might be damaging my computer :-D too hot too the touch |
| 18:57 | technomancy | amalloy: it's [true false] in 1.3 though |
| 18:57 | technomancy | the plot thickens |
| 18:58 | dnolen | derp__: eval has it uses, but they are limited. macros let you manipulate programs as data just fine. |
| 18:58 | amalloy | yeah. both behaviors seem to make sense to me, so unless someone points out a ticket it's not clear which version has a bug |
| 18:59 | hugod | is it possible to get the type hints from the fields of a deftype? |
| 18:59 | technomancy | (identical? f (m)) ; true in 1.3 |
| 19:00 | dnolen | hugod: with reflection I would think. |
| 19:00 | amalloy | *nod* |
| 19:00 | hiredman | hugod: at runtime? |
| 19:00 | hugod | yes, at runtime |
| 19:00 | hugod | I can't see it via reflection |
| 19:01 | hiredman | well, you can get the types of the fields, I believe |
| 19:01 | hugod | which is Object |
| 19:01 | hiredman | really? |
| 19:01 | hiredman | Huh |
| 19:01 | amalloy | i know defrecord doesn't support storing anything but Object or primitives |
| 19:02 | hugod | ,(bean (first (.getFields (deftype t [^String s])))) |
| 19:02 | clojurebot | {:declaringClass sandbox.t, :class java.lang.reflect.Field, :synthetic false, :enumConstant false, :accessible false, :name "s", :declaredAnnotations #<Annotation[] [Ljava.lang.annotation.Annotation;@6788c4>, :genericType java.lang.Object, :type java.lang.Object, :modifiers 17, ...} |
| 19:02 | amalloy | i wouldn't be surprised to see deftype is the same |
| 19:02 | hiredman | amalloy: oh, good point |
| 19:03 | amalloy | ,(t "test") |
| 19:03 | clojurebot | java.lang.Exception: Expecting var, but t is mapped to class sandbox.t |
| 19:03 | amalloy | ,(t. "test") |
| 19:03 | clojurebot | #<t sandbox.t@d69cff> |
| 19:03 | technomancy | amalloy: what do you call "inner" anyway? |
| 19:03 | technomancy | an internal "anonymous" function name? |
| 19:04 | amalloy | technomancy: i usually don't call it anything, in words. i might call it a self-reference |
| 19:04 | amalloy | the compiler calls it "thisFn" |
| 19:04 | amalloy | or something similar |
| 19:05 | hiredman | it is literally the reference to the current object which happens to be a fn |
| 19:05 | amalloy | thisName |
| 19:07 | technomancy | hiredman: so now instead of copying f, with-meta just creates a new function that delegates to f? |
| 19:08 | hiredman | technomancy: huh? |
| 19:09 | technomancy | I thought you mentioned that last night |
| 19:09 | technomancy | which is why "inner" never refers to m |
| 19:11 | hiredman | why would it delegate to f? |
| 19:11 | technomancy | clojurebot: optimization is "What a tangled web we weave, when first we practice to optimize." |
| 19:11 | clojurebot | Ik begrijp |
| 19:12 | technomancy | maybe I misheard you? |
| 19:12 | hiredman | you would just call .clone or whatever |
| 19:14 | hiredman | (actually looks like the compiler just new's up another instance of the fn's class with the metadata) |
| 19:14 | amalloy | technomancy: AFunction.java looks like it does delegate, and git blame puts that commit in march |
| 19:15 | amalloy | and it *seems* like FnExpr in Compiler.java creates an AFunction, but it's hard to be sure |
| 19:16 | hiredman | amalloy: but it also generates it's own withMeta method if the Fn has metadata |
| 19:17 | amalloy | hiredman: "it" here refers to what? |
| 19:17 | hiredman | FnExpr |
| 19:18 | amalloy | oh jeez. i haven't gotten into the bytecode-generation at all yet; so far reading the parse() methods has been enough to satisfy my curiosity |
| 19:18 | hiredman | somewhere around 4096 |
| 19:18 | hiredman | ah, well, bytecode generation is disgusting |
| 19:20 | amalloy | hiredman: but i'm not sure that code is getting executed? it looks like a withMeta function is generated only if there's metadata in the original function declared; the example technomancy and i put together involves adding meta to a function that didn't start with any |
| 19:21 | hiredman | so AFn and delegation is a fallback |
| 19:22 | hiredman | AFunction |
| 20:07 | devn | hello all |
| 20:22 | pmbauer | ,(reductions * (take 20 (iterate 0 inc))) |
| 20:22 | clojurebot | java.lang.RuntimeException: java.lang.RuntimeException: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn |
| 20:23 | gfrlog` | ,(doc reductions) |
| 20:23 | clojurebot | "([f coll] [f init coll]); Returns a lazy seq of the intermediate values of the reduction (as per reduce) of coll by f, starting with init." |
| 20:24 | gfrlog` | pmbauer: ##(iterate inc 0) |
| 20:24 | sexpbot | Execution Timed Out! |
| 20:24 | gfrlog` | not sure why I wanted sexpbot to eval that |
| 20:24 | gfrlog` | but the point is you swapped the args to iterate |
| 20:25 | gfrlog` | on another note, (take 20 (iterate inc 0)) <=> (range 20) |
| 20:27 | dnolen | ,(seq (take 20 (iterate inc 0))) |
| 20:27 | clojurebot | (0 1 2 3 4 5 6 7 8 9 ...) |
| 20:28 | dnolen | ,(type (seq (take 20 (iterate inc 0)))) |
| 20:28 | clojurebot | clojure.lang.Cons |
| 20:28 | dnolen | ,(type (seq (range 20))) |
| 20:28 | clojurebot | clojure.lang.ChunkedCons |
| 20:29 | gfrlog` | dnolen: (take 20 (iterate inc 0)) <~> (range 20) ;) |
| 20:30 | gfrlog` | ,(= (range 20) (take 20 (iterate inc 0))) |
| 20:30 | clojurebot | true |
| 20:30 | gfrlog` | that much is true at least :) |
| 20:31 | pmbauer | ,*clojure-version* |
| 20:31 | clojurebot | {:major 1, :minor 2, :incremental 0, :qualifier ""} |
| 20:32 | pmbauer | @gfrlog, thanks ... trying out the clojurebot, it's kinda cute |
| 20:33 | gfrlog` | ~botsnack |
| 20:33 | clojurebot | thanks; that was delicious. (nom nom nom) |
| 20:37 | tufflax | hehe |
| 21:03 | seancorfield | is there a simple way to filter a map so it only contains a specific set of keys? a map intersection sort of function? |
| 21:04 | technomancy | ,(doc select-keys) |
| 21:04 | clojurebot | "([map keyseq]); Returns a map containing only those entries in map whose key is in keys" |
| 21:04 | hiredman | ,(doc select-keys) |
| 21:04 | clojurebot | "([map keyseq]); Returns a map containing only those entries in map whose key is in keys" |
| 21:04 | technomancy | clojurebot: double double your refreshment |
| 21:04 | clojurebot | Titim gan éirí ort. |
| 21:12 | seancorfield | technomancy: thanx!!! |
| 21:25 | seancorfield | i don't suppose there's some magic function that allows you to easily rename a single key in a map? |
| 21:26 | seancorfield | so far i have (merge (dissoc record :old-key) {:new-key (:old-key record)}) which seems ugly |
| 21:28 | seancorfield | i could also do (conj (dissoc record :old-key) [:new-key (:old-key record)]) which is probably better...? |
| 21:29 | seancorfield | ,(doc rename-keys) |
| 21:29 | clojurebot | Gabh mo leithscéal? |
| 21:30 | seancorfield | ,(doc clojure.set/rename-keys) |
| 21:30 | clojurebot | "([map kmap]); Returns the map with the keys in kmap renamed to the vals in kmap" |
| 21:36 | amalloy | seancorfield: fwiw rename-keys looks like it's rebuilding the whole map from scratch; if you have a very large map and want to just rename one key, the assoc/dissoc approach will be faster |
| 21:38 | seancorfield | ok, good to know, thanx amalloy |
| 21:38 | seancorfield | it's a very small map so i'm not worried in this case |
| 21:39 | gfrlog` | $findfn 8 -8 |
| 21:39 | sexpbot | [clojure.core/unchecked-negate clojure.core/-] |
| 21:47 | gfrlog` | ,(take 20 (iterate #(->> % - (+ (-> % int (* 2))) inc (/ 1)) 1)) |
| 21:47 | clojurebot | (1 1/2 2 1/3 3/2 2/3 3 1/4 4/3 3/5 ...) |
| 21:48 | gfrlog` | fun fact: ^ that sequence contains all the positive rational numbers with no repeats |
| 21:48 | amalloy | gfrlog`: since when are there only twenty of those? |
| 21:48 | seancorfield | :) |
| 21:48 | gfrlog` | since I didn't want to crash clojurebot :P |
| 21:49 | pdk | doesn't it have safeguards against an infinite seq anyway |
| 21:49 | gfrlog` | ,(range) |
| 21:49 | pdk | heck it already truncates the list on its own |
| 21:49 | clojurebot | Execution Timed Out |
| 21:49 | pdk | hmmmm |
| 21:49 | pdk | wonder if you could start connections from it with java connection objects |
| 22:06 | sunnibo | question: i made a WAR file with compojure, hiccup, ring, ... and deployed to my jetty server. so i can connect to http://myserver.com/mywar. everything works well. but i have a link to my website, like /dosomething. when i test this web app in my computer (with lein ring server) i made <a href="/dosomething"> link and (GET "/dosomething/" ... ) in defroutes and worked well. but when i deploys |
| 22:06 | sunnibo | my WAR to jetty, that link points to http://myserver.com/dosomething/, not http://myserver.com/mywar/dosomething/. how can i handle this problem? |
| 22:11 | Derander | pdk: clojurebot running on clojurebot |
| 22:11 | pdk | UH OH |
| 22:11 | pdk | could even make it spawn a second nick |
| 22:12 | pdk | and spam messages to activate the first one! |
| 22:12 | Derander | thereby creating a third |
| 22:12 | amalloy | sunnibo: someone said something about root wars in here the other day |
| 22:13 | amalloy | it fixed the problem you were having |
| 22:14 | sunnibo | amalloy, thanks. i'm looking for it |
| 22:30 | scottj | sunnibo: or maybe search context on compojure ml |
| 22:30 | scottj | "context" |
| 22:31 | sunnibo | i tried to make a code like <a href="dosomething">... but the generated code always has the prefix '/'. <a href="/dosomething">... i think this is a problem. my css file loaded well, actually. |
| 22:32 | sunnibo | scottj: thanks |
| 22:34 | sunnibo | a relative anchor link is prohibited? @.@ |
| 22:36 | sunnibo | or is there any way to get the current URL in my program (with compojure)? |
| 22:40 | sunnibo | oh. plz forget my question. i made a couple of stupid mistakes :( |
| 22:52 | matthias_ | i'm trying to use break, but it says "java.lang.IllegalStateException: Var swank.core.connection/*current-connection* is unbound. |
| 22:52 | matthias_ | " how does that happen? |
| 22:53 | hugod | matthias_: it only works when the break is on your repl thread |
| 22:56 | sunnibo | (link problem solved) anyway, how can i redirect my page to WAR root? i'm using ring.util.response.redirect. (redirect "/") redirects to my web site's root /. http://myserver.com/ , i want to redirect to http://myserver.com/mywar. |
| 23:04 | odie5533 | Who uses Clojure? |
| 23:06 | hiredman | http://clojure02.managed.contegix.com/display/community/Clojure+Success+Stories |
| 23:34 | devn | matthias_: gauger? |
| 23:47 | matthias_ | devn: what? |
| 23:47 | devn | matthias_: nevermind, I have a friend on IRC who is mathiasx |
| 23:47 | devn | confusing.:) |
| 23:48 | devn | matthias_: I was temporarily incredibly proud of him for discussing stacktrace intricacies in clojure |
| 23:49 | devn | I've been kicking him and everyone else I work with to get on the clojure boat for awhile so I thought I'd caught him red-handed |
| 23:49 | devn | Also, sorry to derail, but the strange loop 2011 lineup looks, in a word, incredible. |
| 23:50 | devn | Fantastic lineup. Intensely excited. |
| 23:52 | matthias_ | haven;t heard of |
| 23:52 | devn | matthias_: are you in the US? |
| 23:52 | matthias_ | germany |
| 23:53 | devn | wanna come to the states? ;) |
| 23:53 | matthias_ | i like how you described my "why wopnt iot work? :'(" as discussing the intricacies :p |