#clojure logs

2011-04-28

00:18mecI used a macro within a deftype and now (use :reload 'ns-with-deftype) is throwing Linkage Error: attempted duplicate class definition
00:25mecah, apparently you cant use types before they're defined ;p
00:26tomojlinkage error? never seen that before
00:27mecI was referring to a type in a macro before i defined it, I guess it created it for some reason
01:21technomancyslamhound just got smarter; works on 92% of our work project's namespaces.
01:22chrissbxHow do I create a recursive local definition? Like letrec in Scheme.
01:23amalloychrissbx: letfn is letrec
01:24chrissbxthanks
01:24amalloyif you don't need mutual recursion, just name your anonymous function: ##((fn ! [n] (if (zero? n) 1 (* n (! (dec n))))) 5)
01:24sexpbot⟹ 120
01:26chrissbxaha
01:32Vinzentwhy enlive is moving into clojure? it's great lib, but I can't see any reason to include it in clojure itself
01:33amalloycitation needed?
01:33amalloyi mean, if you say it it's probably true, but i don't know how i could judge why it's the case without even a link to the evidence that it's happening
01:34Vinzenthttps://github.com/clojure/data.enlive
01:35Vinzentit's even have its own name! (why not data.templating then)
01:35amalloyi think that indicates that it's moving into the new version of contrib
01:36amalloyeg, https://github.com/clojure/tools.logging is the new version of clojure.contrib.logging
01:36clojurebotYou don't have to tell me twice.
01:36Vinzentyeah, that's what i mean
01:36amalloycontrib is *not* synonymous with clojure. to move into core is very different from moving into contrib
01:37amalloyespecially now that it's being split up
01:38Vinzentbut contrib (as i see it, maybe i'm wring) is the place for general things, like logging, data structures, etc, and enlive is specialized lib
01:39Vinzenti mean, why not include hiccup, ring and compojure then?
01:40amalloy*shrug* that's pretty subjective. contrib has some kind of server-socket library
01:41dnolenVinzent: enlive is useful for many kinds of data transformation, also hiccup, ring, compojure, issues of who submitted patches to those projects.
01:43seancorfield__http://dev.clojure.org/display/design/Contrib+Library+Names
01:44seancorfield__i am a bit surprised that the enlive name was carried over
01:45markomanwhat is the difference between hiccup and enlive?
01:45dnolenseancorfield: ah nice, ring *is* getting folded in.
01:45amalloyi'm glad to hear ring is getting in. it's very nice
01:45seancorfield__the current list of active repos can be seen here https://github.com/clojure
01:45chrissbxIs there a "println" that doesn't add a space between each argument?
01:45markomanim using hiccup on my project, would it be easy to change it to enlive?
01:46amalloy&(prn 1 2)
01:46sexpbot⟹ 1 2 nil
01:46amalloy&(print 1 2)
01:46sexpbot⟹ 1 2nil
01:46seancorfield__,(println (str "list" "of" "strings"))
01:46amalloyhrm
01:46clojurebotlistofstrings
01:46chrissbxyeah, str.
01:46amalloyi mean, for sure you can use str
01:46Vinzentdnolen, ok, i've just been interested in selection criteria for contrib
01:47chrissbxyep, true; thanks for ppointing it out
01:47seancorfield__i haven't used ring... probably will get to it at some point... especially now it'll be org.clojure/net.ring :)
01:48seancorfield__Vinzent: a lot of it depends on having someone willing to actively maintain the "new contrib" library - someone with a signed CA on record
01:48ambrosebshi
01:48seancorfield__i pushed for c.c.sql to be promoted because i rely heavily on it at work
01:50ambrosebsI'm trying to bind dynamic variables with deftest
01:50ambrosebs(def a 2)
01:50ambrosebs(binding [a 1]
01:50ambrosebs (deftest we
01:50ambrosebs (println a)))
01:50ambrosebsthis prints 2
01:50ambrosebshow do i print 1?
01:50amalloythey're called dynamic because they're not lexical
01:51amalloyif you wanted lexical bindings, you could just use (let...)
01:54Vinzentmarkoman, enlive follows different (from hiccup and similar templating engines) philosophy, so i think it can require some effort to move from hiccup
01:56ambrosebsthe context: I have a macro `with-stevedore-impl` that sets up some bindings, and I want to place deftests inside it
01:57markomanwell need to see library itself
01:57ambrosebsit doesn't look like it's possible.. but i don't quite understand why
01:58chrissbxIs there a way to trace all function calls (print function name and arguments, and maybe return value) in some scope?
01:58Vinzentambrosebs, i think this binds a only at def time, but you need bindings when fn will be called, so place it inside deftest
01:58Vinzentambrosebs, or around the call of the test
01:59ambrosebsVinzent: looks like that's the way to go, thanks!
01:59markomanthen i have a question. if I store string to datastore and I'd like to evaluate it on clojure, how it is done and what security issues I should handle?
01:59markomanfor example: (:k (eval "{:k 1}"))
02:00markomanwhere "{:k 1}" i stored as a string to data store
02:04Vinzentchrissbx, there are clojure.contrib.trace, that might help
02:05Vinzentmarkoman, you can use read, but i believe there should be the other way to store collections in your db
02:06markomanthe problem is, that "collection" can be things like: "1", "1,2", "{:k 1}", "[1,2,3]", "any string",...
02:07markoman"1,2" not good example
02:08Vinzent&(read-string "1")
02:08sexpbot⟹ 1
02:08Vinzent&(read-string "{:a 1}")
02:08sexpbot⟹ {:a 1}
02:09markomani may a problem with types then...
02:09markoman&(= (type 1) (read-string "1"))
02:09sexpbot⟹ false
02:09markoman&(= (type 1) (type (read-string "1")))
02:09sexpbot⟹ true
02:09markomanwell, maybe not
02:12markomanbut this isnt working: (read-string "(println 2)") ?
02:12hiredmanmarkoman: are you kidding?
02:13markomanevaluating any string as a clojure code?
02:13Vinzentmarkoman, it's only reads a string and returns clojure datastructure, so you are getting plain list; you can eval it then, if you want
02:14markomanok, that can help with security issues. if they are only datastructures, then there are less possible problems
02:20Vinzentbtw, is there a form strongly associated with clojure? like, schemers have call-cc and common lispers have defmacro or (loop (print (eval (read)))). What's about clojure?
02:21VinzentWhat a cool name can i pick for my blog? What must be written on my new t-shirt?
02:22ambrosebsxD
02:22ambrosebssounds like an awesome idea
02:23amalloy(-> (read) (eval) (print) (loop)) is less inside out but not actually legal clojure
02:23ambrosebswas just thinking that
02:23ambrosebsdarn
02:27Vinzentamalloy, well, repl is an all-lisp thing (so primarily associated with CL), there should be something more clojurish... something about functions, concurrency, what else?
02:27thorwilVinzent: lazy blog name must be forced
02:27markomanmy eye catches defn, :clojure-keyword and ns clojure.name.space from my codes, but they are not that unique
02:28ambrosebswhat about dosync?
02:28Vinzentthorwil, yes, and laziness :)
02:31markoman"Don't know how to create ISeq" is strongly associated with my coding too ;)
02:32amalloyhaha
03:18thorwilEnlive has no function that will simply return the content of a file, no selection, no wrapping!?
03:22thorwilquestion then is how to read files from the resources dir myself
03:23ambrosebssomething like slurp?
03:23ambrosebs,(doc slurp)
03:24clojurebot"([f & opts]); Reads the file named by f using the encoding enc into a string and returns it."
03:25thorwilambrosebs: yeah, problem is slurp doesn't handle the relative path
03:25ambrosebsah
03:26ambrosebsseems to work for me
03:27thorwilactually, i'm wrong by one level. the enlive forms will happily work with a "templates/foo.html", but with slurp it must be "resources/templates/foo.html"
03:27ambrosebsah
03:27ambrosebs,(. System getProperty "user.dir")
03:27clojurebotjava.security.AccessControlException: access denied (java.util.PropertyPermission user.dir read)
03:27ambrosebsthat should give pwd
03:30ataggartif you're not doing anything with the file contents, why are you slurping it into a string?
03:30ataggartyou might find stuff in clojure.java.io more useful
03:32thorwilataggart: i need the content as argument for an enlive snippet. initially i thought html-resource would be for that case, but it wraps <html> and <body> around the content
03:33ataggartI only went though dnolen's enlive tutorial, but I thought the point of the defsnippet stuff was to have enlive pull the content out of files
03:33thorwili can't find any mention of "resources" as part of the path, or any use of System in the Enlive source, so i still wonder how it knows to just look inside resources
03:34ataggartclojure.java.io/resource ?
03:35ataggarthave you looked at the tutorial? I think the some of the helper files in there had custom paths for the file locations
03:35ataggarthttps://github.com/swannodette/enlive-tutorial
03:47raekthorwil: it's on the classpath (lein puts it there)
03:49thorwil(-> "resources/templates/404.html" slurp en/html-snippet) does what i want. or it has to be ((en/snippet "templates/404.html" [:p] []))
03:50thorwilwhere :p makes it unnecessarily specific, but if i use :*, the content will appear thrice
03:54raekthorwil: I would suggest (-> "templates/404.html" io/resource slurp en/html-snippet)
03:55raekthis uses the classpath instead of the current working directory
03:55raekwhich will also work when if you make an uberjar of your project
03:57thorwilah, thanks
04:12thorwili use a single base.html as skeleton for all pages. it references a main.css. it works everywhere, except on /admin/*. here firefox complains about a bad selector and a missing closing } on a line number that doesn't exist in the css file
04:16Kerrisit's you
04:16Kerrisyou are the gremlin
04:23thorwilawesome, for /admin mains.css is served like it should, but for /admin/test one of my handlers is triggered instead.
04:26thorwiland i thought static files served from the war dir had priority over any route i write
04:28maacl_LauJensen: Are you around?
04:36thorwilall the trouble because i didn't have a / in front of main.css
04:38clgvthorwil: hopefully you learnt that now for next time ;)
04:47fortxun$seen rhickey
04:47sexpbotrhickey was last seen quitting 1 week and 1 day ago.
05:50fliebelWhat kind of data do you use seque for? I'd think infinite lazy computationally intensive stuff, but I'd love to hear more cases.
05:51ilyakWhere do I find help on clojure.lang.Compile command line arguments?
05:55fliebelilyak: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compile.java#L33
05:56fliebelSp basically, it just takes a bunch of files. I don't see any code for handling other stuff.
06:47fliebelI'd rather have something with a FSM and function composition. Or maybe not. I wonder how this is done: https://github.com/cgrand/regex
06:49ilyakant is pain
06:49clgvfliebel: the last one seems nice.
06:49ilyakstill pain after all years
06:50fliebelYea, as I see it, patter matching is just regex for sequences.
06:52clgvcgrande's regex seems to be a different way to create standard regular expressions which could be useful if you have to build these expresion dynamically since you dont need to build a regex string
06:54fliebelright
06:56sid3kguys, I've decided to give a try to clojure after several months of break but I'm getting the same exact error again
06:56sid3kafter I create a new project using lein
06:57sid3kI can't run lein deps without any error. ant produces a long error output
06:58sid3keven though I've recent version of clojure and lein, still it tries to get clojure and install again as I see
06:58sid3kany ideas?
06:59sid3khere is the output: https://gist.github.com/946164
07:00fliebelsid3k: 1.2 has been released, so these snapshot builds are out of date.
07:00fliebelI'm not sure if they are even around anymore.
07:00fliebelSo just using 1.2.0 should be fine.
07:00sid3kyeah, it works that way
07:03no_mindI declared a transient map but when I use assoc! to add key it, the key is not added
07:08clgvno_mind: you have to use the return value of assoc! to see the changes in general - though in some special cases it might work
07:09no_mindk
07:10fliebelhow does a transient decide the cost of mutating vs copying?
07:14clgvfliebel: that's a source code lookup question, I guess ;)
07:17fliebelclgv: Okay, there we go… dusting of java knowledge.
07:18clgv*g*
07:18clgv$source transient
07:18sexpbottransient is http://is.gd/WJdgXr
07:18clgv$source TransientVector
07:18sexpbotSource not found.
07:18fliebelclgv: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/ATransientMap.java
07:19clgv$source assoc!
07:19sexpbotassoc! is http://is.gd/UU78OT
07:19clgvthx
07:20fliebelstill deeper...
07:20clgvhmm no "upper" in fact. doAssoc is abstract ;)
07:21fliebelhttps://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/PersistentVector.java#L385
07:22clgvmap example: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/PersistentHashMap.java#L198
07:23clgvah it has to do with the tree structure
07:23fliebelI see some stuff with the root node, but I don't really understand it.
07:24clgvafair most structures are tree-ish
07:26clgvhumm it's strange: TransientHashMap.doAssoc always returns this
07:26fliebelclgv: yes, but this.root is changed or not.
07:27fliebelSo I think that if the root of the tree is changed, it behaves like an immutable one, otherwise just a few childs are changed.
07:27clgvthat doesnt amtter since you should get the identic jvm object back
07:28fliebelclgv: But if the .get methods use the root attribute, it'd just work, right?
07:28clgvyeah, I think so
07:28clgvassoc! only calls assoc on each key-val-pair. so no magic happening overthere
07:29fliebelI think one needs to understand the tree structure to know what is going on.
07:29clgvno, you dont need to. you do get exactly the same TransientHashMap jvam object back.
07:30fliebelyes, but *maybe* with a different root node.
07:30clgvthat doesnt matter since you have to see the change then as well!
07:30fliebelhuh, yea… true
07:31clgvwould be interesting now, why it behaves differently
07:31fliebelthen I don't see how it can return a different map.
07:31clgvI don't either
07:32fliebelMaybe I'll ask again when the side of the globe with clojure/core on it awakes.
07:32clgvyeah. let me know what they answered in case I am not around to read it ;)
07:33fliebelsure :)
07:33clgvatm it looks like black magic ;)
07:52mecwhat does it mean to have a final variable that is a subclass with non final variables
08:14fliebelWhat is the syntax for these pre and post conditions?
08:16mec(fn [x y] {:pre [(pos? x) (neg? y)] :post [(= % 10)]} (+ x y))
08:30mecIs it possible to update from a jdk7 snapshot to a newer one without downloading the whole thing?
08:34fliebelmec: Thanks.
08:37jfieldsis there a better way to (filter #(= contract-name (:contract-name %)) list-of-maps)
08:38jfieldsI do that often enough that it feels like there is an idiom I'm missing.
08:40Chousukewell you could make the function point-free but that's not really better. :/
08:41mec(filter #{contract-name} (map :contract-name list-of-maps)) ; is better for varying degrees of better
08:42Chousukehmm
08:42jfieldswhat does "make the function point-free" mean? sorry I'm not familiar with that phrase.
08:42Chousuke(filter (comp #{contract-name} :contract-name) list-of-maps)
08:43Chousukejfields: it means that instead of creating a lambda explicitly, you use function composition and partial application or currying
08:43jfieldsChousuke, gotcha, thanks.
08:46Chousukeunfortunately comp and partial are a bit too clumsy in clojure so point-free style is not as idiomatic as in Haskell for example.
08:46mecI gave up on partial, its easier to use #(f a %) than (partial f a)
08:46Chousukein haskell you can do stuff like map (-) . (+1) [1, 2, 3], but in clojure you'd have to do (map (comp - (partial + 1)) [1 2 3])
08:47mecChousuke: . is infix comp?
08:47ChousukeIIRC yes
08:47ChousukeI haven't actually done any haskell beyond some tutorials :/
08:51zdennisIs there a easy way to convert a clojure file to yaml?
08:51zdennisI see the https://github.com/lancepantz/clj-yaml project
08:52zdennisand was curious if there was another way or if that was recommended
08:56fliebel&(destructure ['a 1 'b 2 ['c 'd] [1 2]])
08:56sexpbot⟹ [a 1 b 2 vec__36718 [1 2] c (clojure.core/nth vec__36718 0 nil) d (clojure.core/nth vec__36718 1 nil)]
08:57fliebelzdennis: Why not json?
09:04fliebelHow can I tell in a macro if a form was quoted or not? (= (first s) 'quote) maybe?
09:04fliebelfeels weird...
09:06chouser_fliebel: that should be about right, though I would be suspicious of the desire to do it.
09:08fliebelchouser: Well, yes. I am too. I'm considering ways to do destructuring properly.
09:10fliebelI want to do it with functions rather than a huge macro pile, which works mostly. Now I'm trying to add some icing.
09:11chouserto replace the current implementation in clojure.core?
09:11fliebelchouser: Huh? whre?
09:11mecwhat are you trying to destructure
09:12chouserfliebel: Clojure already does destructuring, so I'm not quite sure what you're trying to do.
09:12fliebelchouser: Oh, no, I mean pattern matching actually.
09:13fliebelI found this one, which uses a lot of weird tricks, with the question marks and quoting. https://github.com/dcolthorp/matchure
09:13chouser,(destructure '[[a b c] [4 5 6]])
09:13clojurebot[vec__1177 [4 5 6] a (clojure.core/nth vec__1177 0 nil) b (clojure.core/nth vec__1177 1 nil) c (clojure.core/nth vec__1177 2 nil)]
09:13chouserfliebel: ah, pattern matching. I see.
09:18fliebelchouser: Well, destructure is nice, but does not what I want really. I don't want to bind stuff, just expand it.
09:18fliebelor maybe I do, but.. let me see
09:20zdennisI'd like to play around with a clojure library, I've downloaded it, built it with lein, installed it, but trying to require it in the interactive-clj prompt can't find it.
09:20zdennisThis is my first attempt to play with clojure, so I'm sure I'm doing something stupid
09:20zdennisor not doing something
09:20zdennisany pointers?
09:21raekfliebel: fyi, another pattern matching lib: http://www.brool.com/index.php/pattern-matching-in-clojure
09:21Chousukezdennis: you most likely forgot to include it in the classpath when you started the repl
09:21Chousukezdennis: you should just be able to run "lein repl" from the library's top level directory
09:21raekI like it's syntax better than matchure's
09:22zdennisChousuke: thank you, that worked
09:24raekzdennis: "lein install" puts the lib in your local maven repo, but that doesn't automatically make it available whenever you launch clojure somewhere
09:24zdennisraek: is there a way when using the repl to make maven repository available if you want to play around with different libraries?
09:24fliebelraek: This too has a lot of werid stuff going on. It looks a lot more sane though.
09:24raekzdennis: if you are a beginner, then you probably want to create a new lein project, add the lib you are interested in as a dependency and then do lein deps and lein repl
09:25chouserfliebel: I'm not sure that clojure.core/destructure is of any use to a pattern matching lib.
09:25raekclojure does not use the "system wide install" approach which many other languages use
09:26raekwhich libraries to use, and what versions of them, is handled in a per-project basis
09:26fliebelchouser: Me neither, but it does handle the & stuff.
09:27raekzdennis: you might want to check out cake. it has a "global project", which lets you try a library without creating a project for the "play seesion"
09:28zdennisthat sounds like what I need ,thx raek
09:31dnolenfliebel: pattern matching is a special case of predicate dispatch, always looking for help on my pred match work :)
09:34fliebeldnolen: Uhm, okay. Could you explain that?
09:36dnolenfliebel: predicate dispatch is a more generalized form of pattern matching - pattern matching w/ guards is not that dissimilar from predicate dispatch, except that predicate dispatch is open - anybody can add another case later.
09:37dnolenin fact the only novelty I'm introducing is that guards can be predicates that are stored in a logic db, the logic db can use that info to reorder clauses to prevent the kinds of problems you run into w/ pattern matching.
09:39fliebeldnolen: predicate dispatch is the same thing that cond is doing, tight? only faster and more flexible.
09:40dnolenfliebel: if by faster and more flexible you mean - doesn't try clauses in the order you wrote them, and it can be extended :)
09:43fliebeldnolen: tbh, I don't see how that helps much with my problem. If I can help with the dispatch without reading a ton of papers, that'd be fun though.
09:46dnolenfliebel: you could probably use one of those previously mentioned libs and be just fine. But if you're interested, only two papers - Efficient Predicate Dispatch, Compiling Pattern Matching to Good Decision Trees. Both are short and approachable, I think.
10:10cemerickdnolen: congrats on the contrib include :-)
10:27fliebelokay, dnolen, where are those papers of yours?
10:39dnolencemerick: thx!
10:40dnolenfliebel: http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.47.4553, http://moscova.inria.fr/~maranget/papers/ml05e-maranget.pdf
10:40fliebeldnolen: Yea, great to see logos in contrib :) found the papers btw, although your notion of short and understandable seems to be different from mine :)
10:40dnolenfliebel: heh ;)
10:41fliebelI had some trouble find out where the names started and stopped, and then I got the dylan one and all.
10:41dnolenfliebel: the predicate dispatch one is I think pretty easy to understand, it's not important to understand their algorithm tho, just the general idea.
10:41clgvfliebel: lol 31 papers is indeed not short for a paper ;)
10:41clgvs/papers/pages/
10:41sexpbot<clgv> fliebel: lol 31 pages is indeed not short for a paper ;)
10:41dnolenfliebel: the Maranget paper seems mathematical, it's not really, it's just notation so they don't have to write OCaml
10:42fliebelanyway, I'll see if I can read some of it later. I'm going to play with CPS first :)
10:43dnolenfliebel: nice
10:53no_mindI have a nested map and a sequence which contains the path (hierarchy) of the key for value to fetch. Is there a function which will let me fetch the key from nested map ? Or do I need to iterate over the map ?
10:54mec(get-in map [key1 key2])
10:54mecalso assoc-in, and update-in
10:54mecerr is that what you're asking
10:57no_mindmec: lets say I have a map {"user" {"admin" {"status "1"}}} and a sequence ("user" "admin" "status") . I want to find the value of "status". What is the easiest way to do this ?
10:58clgvit's like mec suggested: ##(get-in {"user" {"admin" {"status "1"}}} ["user" "admin" "status"])
10:59clgv&(get-in {"user" {"admin" {"status" 1}}} ["user" "admin" "status"])
10:59sexpbot⟹ 1
11:01clgvand ##(assoc-in {"user" {"admin" {"status" 1}}} ["user" "admin" "status"] 2)
11:01sexpbot⟹ {"user" {"admin" {"status" 2}}}
11:08dakronewhen you have something like http://pastebin.com/DwCrYqNw how can I get it to resolve correctly and not give me "More than one matching method found: writeNumber"?
11:09clgvdakrone: type hints. I guess you need them for "jg" as well
11:09mecI believe the args are being passed to instance? backwards
11:10mectry #(instance? %2 %1)
11:10clgvmec: ah yes. that as well ;)
11:11mecerr nope, im wrong
11:12clgv&(instance? java.lang.Integer (int 0))
11:12sexpbot⟹ true
11:12dakronethe condp is correct, this worked on 1.2, on 1.3 it trows, even if I type hint both the obj and jg
11:12dakrone*throws
11:12clgvwhat does it throw?
11:13dakronejava.lang.IllegalArgumentException: More than one matching method found: writeNumber
11:13mecwhat arities does writeNumber have?
11:14dakronethey're all 1 arity, just different classtypes
11:15mecdo you have a generic Object one?
11:16dakroneno, only ones for Integer, Long, Float, BigDecimal, etc number types
11:17scottjcake channel name?
11:20raekscottj: #cake.clj
11:21clgvthats weird: java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Class
11:22clgvok it's not lol
11:22fliebelclgv: Reversed the arguments?
11:22clgvexamples for condp should use asymmetric predicates ;)
11:23mecclgv: what do you mean
11:23clgvmec: I also did think that the argument order should be reversed ^^
11:24mec,(condp instance? 5 Integer 'Integer Long 'Long Float 'Float Double 'Double BigInteger 'BigInteger)
11:24clojurebotInteger
11:25raek,(instance? Integer 5)
11:25clojurebottrue
11:25raekthe order condp applies the function always surprises me
11:25raekbut it does fit isa?...
11:26mec,(isa? 5 Integer)
11:26clojurebotfalse
11:28raek,(isa? (class 5) Integer)
11:28clojurebottrue
11:43clgvI tried to provide one of my deftypes with meta-data like: clojure.lang.IObj (withMeta [this, new-meta-data] ...)
11:43clgvbut I get: java.lang.AbstractMethodError with no description
11:44mecdid you define (meta [this]) also?
11:45fliebelclgv: Typehints maybe?
11:45clgvmec: humm no. lol. which interface is it?
11:45fliebelclgv: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/IObj.java
11:45mecIObj
11:46clgvah it's in IMeta. thats why I forgot it
11:48clgvjava.lang.ClassCastException: "MyDeftype cannot be cast to clojure.lang.IPersistentMap" :(
11:49clgvah found it
12:13fliebel((match (literal 1) (coll (literal 3) (other #(every? even? %))) _ (literal 3)) [1 [3 4 2] 2 3]) ; true
12:27clgvcan incanter handle a list of maps as dataset or do I have to build seq for every row?
12:52clgvok I converted the data.
12:53Ramblurrcan anyone please explain why the nullpointerexception is thrown in this example: http://www.ideone.com/COjaV ?
12:54joegalloextra parens
12:54joegallo(defn foo [n] (<--- this one right here, delete it
12:55fliebelnice one :)
12:55Ramblurrjoegallo: Ahh! thanks
12:55joegallonp
12:56Ramblurrjoegallo: why did that almost work, but fail at the end? how did the interpreter interpret (hehe) that ?
12:56joegallo1. do the work of printing the numbers, 2. execute the function returned by 1.
12:56joegallobut 1 (doseq ...) returns nil
12:57joegalloso you are (nil)
12:57joegalloinvoking nil as a function, hence npe.
12:57Ramblurrjoegallo: gotcha, thanks again
12:58joegallonp, again :)
13:05fliebelHow does a transient decide whether to mutate or copy? I looked at the source with clgv, be we couldn't figure it out.
13:12amalloyfliebel: fwiw, i test for quoting with (= (first s) 'quote)
13:13amalloyneeded it for sexpbot so he can macro-expand your form for sneakiness, but still leave quoted sections alone so that code you provide doesn't get mangled
13:13amalloyeg ##(macroexpand '(.getName x))
13:13sexpbot⟹ (. x getName)
13:13mecfliebel: what do you mean? doesn't a transient always mutate?
13:14amalloymec: no
13:14amalloywhereas if you asked him to eval (.getName x) he expands that into pages and pages of code to verify that it's an allowed operation
13:16amalloy&(let [x (transient [])] (dotimes [n 100] (conj! x n)) (persistent! x))
13:16sexpbot⟹ [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99]
13:16amalloyhm
13:16mecwould you know an example of where a transient copies instead of mutating?
13:16amalloywell, i expected that example to be one
13:17amalloythe point is that conj! returns to you a new list. that list may be a pointer to the same one you gave it, if it chose to mutate that; or it may give you a new one back if that was more efficient
13:17amalloyif you throw away the result of conj! you're doing it wrong
13:19fliebel&*clojure-version*
13:19sexpbot⟹ {:major 1, :minor 2, :incremental 0, :qualifier ""}
13:20fliebel&(let [x (transient {})] (dotimes [n 100] (assoc! x n n)) (persistent! x))
13:20sexpbot⟹ {0 0, 1 1, 2 2, 3 3, 4 4, 5 5, 6 6, 7 7}
13:21mecah i forgot maps swap to more efficient implementations
13:21fliebelWould that be it? Just the move from array-map to hash-map?
13:22fliebel&(let [x (transient (hash-map)] (dotimes [n 100] (assoc! x n n)) (persistent! x))
13:22sexpbotjava.lang.Exception: Unsupported binding form: (dotimes [n 100] (assoc! x n n))
13:22fliebel&(let [x (transient (hash-map))] (dotimes [n 100] (assoc! x n n)) (persistent! x))
13:22sexpbot⟹ {0 0, 1 1, 2 2, 3 3, 4 4, 5 5, 6 6, 7 7}
13:24fliebel&(let [x (transient (apply hash-map (range 20)))] (dotimes [n 100] (assoc! x n n)) (sort (persistent! x)))
13:24sexpbot⟹ ([0 0] [1 1] [2 2] [3 3] [4 4] [5 5] [6 6] [7 7] [8 8] [9 9] [10 10] [11 11] [12 12] [13 13] [14 14] [15 15] [16 16] [17 17] [18 18] [19 19] [20 20] [21 21] [22 22] [23 23] [24 24] [25 25] [26 26] [27 27] [28 28] [29 29] [30 30] [31 31] [32 32] [33 33] [34 34] [35 35... http://gist.github.com/946808
13:27fliebelThere you have it, that seems to work, only the second example is weird.
13:27fliebelIf it changed back to an array map it would contain nothing, if it did not, it would contain everything.
13:29fliebelno_mind had some code this morning that did this. I wonder what he had.
13:29amalloyfliebel: you have mismatched parens in your second example
13:29fliebelamalloy: Third one then...
13:29amalloysexpbot tried to fix them but guessed wrong
13:30fliebelI count like a repl.
13:30no_mindfliebel: well my code was creating an acyclic directed graph
13:30amalloyfliebel: i feel sure there are other situations in which it might give you a different pointer
13:32fliebelamalloy: clgv and I traced the code down to the transient, and it looked like it modifies the root attribute, but always returns the same object.
13:48apgwozhas anyone heard from Raynes?
13:49amalloyapgwoz: his power is out, and cell service is spotty
13:49apgwoz(or anyone else from the affected tornado states for that matter?)
13:49apgwozamalloy: cool.
13:49apgwoz(well, uncool about power, but cool that he's ok)
13:49amalloyyeah
13:50astoddardA question with an apparently erroneous answer on stackoverflow piqued my interest. http://stackoverflow.com/questions/5821585/clojure-proxy-and-override
13:51astoddardIt appears a call to proxy can attempt to implement an non-existing base method: (proxy [Object] [] (nonExistingBaseMethod [] "Foo"))
13:51astoddardIs that nonExistingBaseMethod actually callable in any way?
13:51fliebelI'd say so.
13:52amalloy&(.getName (proxy [Object] [] (getName[] "test")))
13:52sexpbotjava.lang.IllegalStateException: Var null/null is unbound.
13:52amalloyhm
13:52amalloythat looks like a clojail bug, but it doesn't work in the repl either
13:54amalloyastoddard, fliebel: clojure.contrib.repl-utils/show indicates that a proxy created in that way does not have a method with that name
13:54fliebelamalloy: So do you have to define an interface first?
13:55amalloyprobably
13:55amalloythough in that case you may just want to reify?
13:55amalloyi guess not
13:56astoddardamalloy: agreed, no method in the proxy. Interestingly an entry is in the IPersistentMap available from __getClojureFnMappings.
13:59RamblurrI'm using a for to put strings inside a list basically (for [...] (fun-that-returns-a-str)), these strings contain spaces
13:59Ramblurrand when I call count on the result of the for loop, its interpreting each word as a separate element
14:00Ramblurrwhat's the proper way to put a string into a list so the spaces between words are preserved?
14:01amalloyhuh? you are wrong; ##(count ["this has spaces"])
14:01sexpbot⟹ 1
14:02Ramblurrherm
14:03fliebelTeh codez for my micro matcher. Comments? https://gist.github.com/946857
14:04amalloy&(count (for [x (range 10)] (clojure.string/join " " (repeat x "word"))))
14:04sexpbot⟹ 10
14:39thorwilgiven that (ds/defentity Quark [^:key milch sahne yoghurt]) expands to (clojure.core/defrecord Quark [milch sahne yoghurt] appengine-magic.services.datastore/EntityProtocol ...
14:40thorwilhow could i access the vector [milch sahne yoghurt] afterwards?
14:41mec(nth (macroexpand-1 '(ds/defentity Quark [^:key milch sahne yoghurt]) 3)
14:43dnolenfliebel: nice.
14:43thorwilheh
14:44thorwilmec: but without repeating the macro call. i mean, this information has to be accessible from Quark afterwards, somehow
14:45dnolenthorwil: reflection is one way.
14:45fliebeldnolen: Thanks. What amount of dead tree would you think I can consume during 4 hours of train?
14:46dnolenfliebel: probably both papers, I read papers on the way to work, my commute is only 30 min on train, so it usually takes 2 rides to finish one.
14:47mecthorwil: you could probably use symbol capture but it really depends what you're doing
14:47dnolenof course, I usually have to read a paper 2 or 3 times before I understand it...
14:47fliebeldnolen: Okay, good :) I wonder if the empty cartridge will make it to the end of the 31 pages one :P
14:56sritchie,((fn [f a b] (f a b)) (read-string "+") 2 3)
14:56clojurebot3
14:56sritchiedoes anyone know why that doesn't eval to 5?
14:57justinlilly,(= (read-string "+") '+)
14:57clojurebottrue
14:57justinlilly,((fn [f a b] (f a b)) '+ 2 3)
14:57clojurebot3
14:58justinlillydo you have to unquote the + somehow?
14:58justinlilly,('+ 2 3)
14:58clojurebot3
14:58justinlillythat's effectively what's happening.
14:59technomancyjustinlilly: needs resolve or eval
14:59technomancy,('+ {'+ :plus} :not-found)
14:59clojurebot:plus
14:59sritchie,((fn [f a b c] (f a b c)) (read-string "+") 1 5 5)
14:59clojurebotjava.lang.IllegalArgumentException: Wrong number of args (3) passed to: Symbol
14:59sritchieyeah, interesting
15:00hiredmanjustinlilly: I'd suggest learning about lisp readers
15:00justinlilly,((fn [f a b] ((eval f) a b)) (read-string "+") 2 3)
15:00clojurebotDENIED
15:00justinlillytsk.
15:00mecyou're calling a symbol, which take 1 or 2 args
15:00hiredmanand following that up by learning about evaluators
15:00hiredmanfollowed up by writing a lisp
15:00justinlillyhiredman: direct comments to sritchie :)
15:00manutter,((fn [f a b] ((resolve f) a b)) (read-string "+") 2 3)
15:00mecthe first arg is the environment to look themselves up, and the 2nd is not-found
15:00clojurebot5
15:00sritchieah, that's really interesting
15:00hiredmanmec: map
15:01hiredmannot environment
15:01sritchie,('+ {'+ 4} 2)
15:01clojurebot4
15:02mec,(('+ {'+ +}) 2 3)
15:02clojurebot5
15:02mec,(('+ {} -) 2 3)
15:02clojurebot-1
15:17TimMcWait, what does invoke on a Symbol do?
15:17fliebelTimMc: Lookup in a map
15:17TimMcah, like keywords
15:17fliebeloh, maybe not, that was my python mind confusing me
15:17TimMc,('foo {'foo :sym, :foo :key})
15:17clojurebot:sym
15:18TimMc,('bar {'foo :sym, :foo :key} :qux)
15:18clojurebot:qux
15:18TimMcwith optional default
15:18fliebeloh, okay
15:19TimMcmec: And by "environment" you mean an associative data structure?
15:21mecTimMc: indeed
15:22mecon invoke symbol calls RT.get(arg1, this, not-found)
16:09ordnungswidrighi all
16:42ordnungswidrigCan protocols extend protocols?
16:50mecordnungswidrig: I dont think so
16:54edwDo the modular contrib projects work in 1.2.1?
17:02ohpauleezedw: I don't think so. I think they're only for 1.3
17:02ohpauleezBut I haven't personally tried
17:02ohpauleezsome (most?) will probably work
17:02ohpauleezsince most of the code of contrib isn't 1.3 specific
17:03edwOK. "Should I be using a 1.3 prerelease?" is a question I'm thinking of asking.
17:05ohpauleezIf you're just playing around, I'd say go for it!
17:05ohpauleezif you're doing production work, I think you should stick to 1.2.1
17:07edwI'm doing active development, so dealing with occasional changes isn't a biggie. I'd rather do that than deal with migrating to the new libs later.
17:07ohpauleezYeah, sure. I've been working on 1.3 stuff. There's a lein plugin for working with multiple clojure version, I believe it's called lein-multi
17:08edwDoesn't it just come down to futzing with your project.clj?
17:10technomancylein-multi is designed for testing libraries for cross-compatibility, though nothing prevents you from using it to test applications as well.
17:11technomancyedw: https://github.com/technomancy/swank-clojure/blob/master/project.clj#L7
17:12edwAh. I'm writing apps. (A Scheme -> JS translation web service right now.)
17:13ohpauleezedw: You're quite the polyglot programmer, huh? :)
17:14ordnungswidrigI try to solve the expression problem on event handling: events (data) and handlers (behaviour)
17:15ordnungswidrigI made the handlers protocol (with a single method) and deftyped the events that extend protocols
17:15ordnungswidrighttps://gist.github.com/947353
17:15ordnungswidrigany idea on this? I don't like the runtime registration of the handler protocols
17:16edwohpauleez: I just hate writing CPS-style programs in JS (too much syntax) so I figured I'd write something that would compile Scheme to JS a la CoffeeScript so I can get on with my life.
17:17ohpauleezedw: For sure, I definitely understand. I think it's a cool project.
17:19edwActually, I'm writing it because I'm sort of depressed, and I need something fun to do. I think I'm having a Bipolar Lisp Programmer kind of day.
17:19apgwozedw: have you looked at cpscm? or did you just want to write it yourself?
17:19edwapgwoz: See above. ;)
17:19apgwozyeah. we wrote at the same time :)
17:20edwBut I'll check that out. Maybe it's a pile of mud I can help make a little bigger.
17:20apgwoznever as fun as writing it yourself though...
17:20apgwozi'd vote for that
17:20apgwoz:)
17:21dnolenedw: have you seen scheme2js ?
17:22edwdnolen: No. What's it written in?
17:22dnolenedw: it's insane actively worked on, http://www-sop.inria.fr/indes/scheme2js/
17:22dnolensupports call/cc
17:23dnolenpretty much all of r5rs is there.
17:23dnolenthe main issue is that documentation is sparse.
17:24edwinria.fr... Is that home to OCaml?
17:24dnolenedw: yup.
17:25edwAh.
17:25dnolencompiler does trampolining transformation, so tail recursive code is guaranteed to not stack overflow.
17:25dnolenwas considering playing around with it and Node.js
17:26edwMaybe I should just cut out and go to Oscar's (local dive). Reintroducing myself to primitive java character i/o is causing my body to sigh.
17:26ohpauleezI think fogus has a functional JS/Node.js project going on. I don't know how far he's gotten with it though
17:26technomancythat seems a bit backwards; why put yourself on an untested runtime with no libraries when there are lots of really solid scheme compilers already?
17:26ohpauleezbut it'd be worth looking at
17:29edwtechnomancy: Because I'm done hosting my own projects. I ran my consulting firm's web site on a framework I wrote in Scheme (Magic) and I sometimes had to connect to SLIME at 3am to re-start the mofo. The Joyent Node Service is nice. But I hear you. I miss Scheme48.
17:32dnolenedw: have you used Geiser?
17:32edwNo.
17:32dnolenedw: works beautifully with Racket
17:33edwAnd by Racket, do you mean what MzScheme's become?
17:34dnolenedw: yes
17:34edwI just read the front page slash manifesto. Sounds like one of my people. I was bitching about having to bounce the JVM just to update a project's dependencies.
17:34edw...just the other day.
17:35edwOh noes, he supports Guile...
17:37hiredmanyou can add classes and what not, it just can run into odd scoping issues and can be tricky to deal with
17:37edwdnolen: Downloading Racket...
17:37hiredmanso there is nothing preventing people from rolling their own runtime classloading whatever, clojure just doesn't provide something out of the box
17:38ordnungswidrigHow can I extract all functions out of a protocol?
17:38edwhiredman: Right good point. [As edw sticks head in oven.]
17:41no_mindIn a nested map how do I insert a new key at a any given level. Foreg. I have {"user" {"admin" {"status" "1"}}} and I want {"user" {"admin" {"status" "1", "roles" "2"}}}
17:41hiredmanhttps://github.com/hiredman/clojurebot/blob/master/src/clojurebot/plugin.clj
17:42ordnungswidrigno_mind: ,(update-in {"user" {"admin" {"status" "1"}}} ["user" "admin"] assoc "roles" 2)
17:42ordnungswidrig(update-in {"user" {"admin" {"status" "1"}}} ["user" "admin"] assoc "roles" 2)
17:42ordnungswidrig,(update-in {"user" {"admin" {"status" "1"}}} ["user" "admin"] assoc "roles" 2)
17:42clojurebotjava.lang.Exception: Unable to resolve symbol:   in this context
17:42ordnungswidrig*grr*
17:42no_mindalternatively, which data structure is most suitable for presenting hierarchical data
17:44dnolen,(assoc-in {} [:foo :bar :baz] 1)
17:44clojurebot{:foo {:bar {:baz 1}}}
17:44ordnungswidrigno_mind: thats ok, however I'd user keywords: {:users {:admin {:status 1 :roles 2}}}
17:44dnolenno_mind: ^
17:44no_mindassoc-in wont add a key but will replace
17:45dnolenno_mind: update-in
17:47lancepantzedw/hiredman: that's what classlojure is for
17:47lancepantzwe use it in cake to update dependencies without bouncing the jvm
17:47hiredman~cake
17:47clojurebotcake is http://wondermark.com/030/
17:47lancepantzit has multiple application classloaders, you can use it to run multiple versions of clojure in the same jvm too
17:53ordnungswidrigcan one determine if a value is a protocol? The type of a protocol seems to be PersistentArrayMap
17:53ordnungswidrigI'm on 1.2
17:53dnolensick, http://www.artisancoder.com/2011/04/cps-and-beta-reduction/
17:58ordnungswidrigdnolen: nice
17:59ataggartprotocols are not types, but you can check if an object satisfies a protocol with (satisfies? P obj)
18:02ordnungswidrigataggart: I know. But I have (defprotocol Foo) (defprotocol Bar) and I wan't to register a protocol (-type) at runtime, say (defn add-handler [p] (alter handlers conj p)) But I want to make sure that p in the latter function is a protocol
18:02ordnungswidrignot something else
18:03ataggartprotocols are not types
18:03ohpauleezordnungswidrig: I'd look at the supers of the a protocol, and see what interface you can check for
18:03ordnungswidrigataggart: I know.
18:04ordnungswidrigohpauleez: the runtime representation of a protocol is a map, not a java type
18:04ohpauleezah right
18:05ohpauleezbut does it include any extra interfaces, outside of a standard map?
18:05ataggartthe question is tantamount to asking if an argument is a multimethod.
18:07ohpauleezordnungswidrig: There are a keys you can check for
18:07ordnungswidrigother question: is using protocols for dispatch faster than using multimethods?
18:07Ramblurris there a function like (do ..) that evalutes all the exprs *and returns* all the results?
18:07ordnungswidrigohpauleez: the keys, yes
18:07ohpauleezordnungswidrig: yes
18:08technomancyRamblurr: pvalues
18:08amalloyvector
18:08amalloy&(vector 1 2 3)
18:08sexpbot⟹ [1 2 3]
18:08technomancyoh yeah, that's better
18:08technomancyor list
18:08Ramblurryea i thought of that, but I don't want a list, because the returned values are already going into a list :\
18:09amalloyRamblurr: clojure does not have multiple-value return
18:09amalloylook at mapcat
18:09ordnungswidrigRamblurr: what about with-meta
18:09Ramblurrinside a (for..) i want to evalute several exprs and have for return all the results
18:09amalloy&(mapcat #(if (even? %) [:even %] %) (range 10))
18:09sexpbotjava.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Integer
18:10amalloy&(mapcat #(if (even? %) [:even %] [%]) (range 10))
18:10sexpbot⟹ (:even 0 1 :even 2 3 :even 4 5 :even 6 7 :even 8 9)
18:10Ramblurrah interesting
18:14hiredman,(for [x (range 10) :when (even? x) y [:even x]] y)
18:14clojurebot(:even 0 :even 2 :even 4 :even 6 :even 8)
18:15hiredmanit's a shame that for doesn't have an explicit concat option
18:17amalloyi agree
18:17amalloyi feel dirty having to use mapcat
18:18amalloyhiredman: that's a pretty neat trick
18:19Ramblurramalloy: i'm not sure how to apply mapcat to this example: http://www.ideone.com/Y4Sn9
18:19Ramblurryou can see the (do.. ) where I'd like it to return both
18:20Ramblurrdont pay attention to the redundancy of (foo.. ) ;)
18:21amalloyRamblurr: like hiredman says, you can't do it with for
18:22amalloythis is...almost exactly identical to the mapcat example i gave
18:22Ramblurramalloy: yup, but where would you add the call to (foo ..) in the mapcat example
18:22amalloy(mapcat #(if (even? %) [(foo %) "even"] ["odd"]) (range 50))
18:22Ramblurroh :\
18:29mecthis sounds like a job for (fort [a (range 5) b (range 5) :transform (partial apply concat)] [a b])
18:33ataggartxy?
18:33clojurebotxy is http://mywiki.wooledge.org/XyProblem
18:34amalloyspeaking of xy, Ramblurr, did you figure out what was going on with your "strings with spaces" issue?
18:35amalloymec: that's just silly. you can (apply concat) the result of the for; but that doesn't resolve the "issue" of wanting to return two things sometimes and one thing other times: you still have to wrap everything in a vector
18:36mecif none of those are collections themselves you could always flatten
18:37mecits too bad concat doesnt work as flatten-1
18:38amalloyugh. flatten is good, but the language would be better without putting it in core so that people stop trying to abuse it for one-level flattening
18:39nickikhttp://stackoverflow.com/questions/5232350/clojure-semi-flattening-a-nested-sequence/5232787#5232787
19:46devnhow can I passing something like a namespace as an arg without 'quoting it?
19:46devns/passing/pass
19:46sexpbot<devn> how can I pass something like a namespace as an arg without 'quoting it?
19:46devn(myfn foo.core) => (myfn 'foo.core)
19:49scgilardithe arguments to a function are evaluated before the function is invoked. if you need exactly what you're saying, myfn needs to be a macro.
19:50devnscgilardi: *nod*
19:50devni figured as much, no big deal
19:50devnthanks though
19:57hiredmanfoo.core is a symbol, 'fore.core is a quoted symbol, there is no literal syntax for namespaces
20:08choffsteinanyone here use clj-cont?
20:22dnolenchoffstein: clj-cont is now delimc
20:23choffsteinah, thanks.
20:23choffsteinnot available on clojars yet?
20:23choffsteinAh ... for 1.3.0
20:24dnolenchoffstein: lemme double check fi that's necessary
20:27dnolenchoffstein: done, 0.1.0 pushed to Clojars, compat with 1.2.0
20:27choffsteinYou're a lovely, beautiful person
20:27choffsteinAnd I kiss you
20:27dnolenchoffstein: not much documentation, but it basically works like shift/reset in Scheme.
20:27dnolenchoffstein: relatively easy to sort out what's going no by looking at the test.
20:29choffsteinI'll take a peek. Thanks.
20:30choffsteinI'm trying to build a very simple component based web framework just to learn clojure
20:30choffsteinand it seems like I can do it by passing around function objects and using refs and transactions ... but continuations seem sexier if I can figure em out
20:31dnolenchoffstein: cool, that's why I originally developed delimc 2 1/2 years ago, to port weblocks. delimc is too slow for general use, but definitely more than fast enough for I/O bound things.
20:31choffsteini'm 99% sure i'm too stupid to get it working, but what doesn't kill me only makes me ... smarter?
20:33carllercheI'm trying to write a connection pool, would it be better to represent it as an atom -> { "hostname" PersistentQueue } or maybe ref -> { "hostname" ref -> PersistentQueue } and then use dosync?
20:33dnolenchoffstein: yeah it was never completely clear to me how to implement it properly, but I never looked at weblocks or Seaside deeply enough. arc would be good to look at as well.
20:33carllercheor maybe a ref -> { "hostname PersistentQueue } directly and still use dosync?
20:34choffsteindnolen: yeah, I was playing around with seaside and was wondering if I could implement something really simple in clojure that captured the essence of the idea
20:35dnolenchoffstein: it's definitely possible. just have to map unique keys to a frozen computation. and garbage collect those frozen computations somehow.
20:37choffsteindnolen: the reset/shift system is new to me, so I'm still trying to figure out how the freeze the computation. I come from a ruby background, so trying to understand the parallel is rocking the boat for me
20:38dnolenreset, mean start recording everything here and allow me to jump back at any time - shift.
20:38dnolens/mean/means
20:38sexpbot<dnolen> reset, means start recording everything here and allow me to jump back at any time - shift.
20:40choffsteinhmmm, interesting
20:40choffsteinand reset won't actually execute the code?
20:41dnolencontinuations are the new hotness at ICFP 2011, they're doing a whole workshop on them.
20:41choffsteinI'm just really trying to figure out how to implement call-backs via continuations.
20:41choffsteinI don't think I understand them well enough at the moment.
20:41hiredman"new"
20:42choffsteinhiredman: isn't that how the world works?
20:42dnolenwell the academics are excited about them - a lot of type theory to sort out.
20:46choffsteini'm not gonna lie, dnolen, the test cases don't help me at all :D
20:52dnolenchoffstein: I would do something simple like try to solve the arc challenge.
20:52choffsteinokay
20:54carllercheIs there a functional difference between ref-set and alter besides just convenience?
20:54dnolenchoffstein: use ring for the server, handlers are just fns, so you can just use reset around the body of the fn. that would be pretty awesome to see actually.
20:56dnolencarllerche: you'd have to read the ref to change it with ref-set, I believe. (ref-set ref (inc @myref)) vs. (alter ref inc)
20:57carllerchednolen: yeah... i'm just wondering if there are any functional differences under the hood
20:57carllercheor if one could implement ref-set in terms of alter (or vice versa)
20:57TimMccarllerche: Doesn't look like it. https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Ref.java#L172
20:58carllerchehmm... indeed, thanks :)
20:58hiredman~alter
20:58clojurebotalter is always correct
20:58TimMccarllerche: Also, there doesn't appear to be any difference in the stated semantics, so that *probably* won't change out from under you.
20:59TimMchiredman: Because it is easier to reason about?
20:59dnolenTimMc: if you look at the code ref-set and alter are quite different. alter is more "atomic"
20:59hiredmanTimMc: that is an out of context quote of rich talking about alter vs. commute
21:00carllerchebut, the transaction would restart if ref-set isn't atomic
21:01hiredmanunless you really need the stm I would use an LBQ or similar instead of refs or atoms
21:02dnolenTimMc: but maybe not, my understanding of concurrency issues is still noob-level.
21:09choffsteindnolen: Hmm, don't think I really understand what you mean there by just wrapping the fns with reset. Where does that get me?
21:10choffsteinI'm trying to basically implement a component system where call-backs are implemented using continuations
21:10dnolenchoffstein: you create holes that you can callback into at any point.
21:11dnolenchoffstein: on the delimc landing page you can see I'm saving points I can return while allow the function to run to completion as well.
21:13choffsteindnolen: Right. I think what I am trying to do is do that will the components. I am basically having each component be a set of state and procedures that renders itself with call-backs that affect the state. My thought was to use continuations to implement those call-backs for when a link is pressed or a form is submitted.
21:14dnolenchoffstein: you can render a page, see that something is missing, store the continuation, call another function, produce a page with an input field, when the user submits that you can then call the stored continuation to finish the *original* page.
21:14choffsteinah, interesting
21:15brehautdnolen: whats the link for this lib?
21:16dnolenbrehaut: https://github.com/swannodette/delimc
21:16brehautthanks!
21:16dnolenchoffstein: that's the essence of the arc challenge which is why I recommended doing that.
21:17dnolenchoffstein: http://www.paulgraham.com/arcchallenge.html
21:17choffsteini'll take a read
21:18choffsteinhmm, interesting challenge. i'll give it a try :)
21:19dnolenchoffstein: if you do it you should definitely do a blog post about, I've been hoping somebody would give it a shot with delimc.
21:19choffsteinyeah, well, I just started using clojure a month ago and it is my first lisp, so don't hold your breath ;)
21:19dnolenchoffstein: the cool thing is very complex form flows become trivial.
21:20brehautdnolen, choffstein: it also seems useful for irc bots
21:20dnolenbrehaut: true, never considered that.
21:22choffsteinokay, I think I am getting this reset / shift stuff...
21:23choffsteinThough, only in its simplest form...
21:33choffsteindnolen: how would funcall-3 and funcall-4 change if it had been (+ 2 (shift ...)) instead of (+ (shift ...) 2)? Does it matter?
21:34choffsteinfrom reading up on scheme's reset / shift, it seems like anything between reset / shift is put into a lambda and applied where 'k' is in the shift statement
21:38dnolenchoffstein: in that case it wouldn't matter no.
21:43choffsteinokay, didn't think so.
21:54Ramblurramalloy: regarding the strings as spaces, that was just me being confused by the toString version of the sequence
21:54Ramblurramalloy: I had miscounted, the (count) result was correct
21:55Ramblurrits weird seeing a list printed like (This is a sentence broken into chunks, but you would never know it)
21:56Ramblurrwhen I had expected something like ("This is a sentence" "broken into chunks" ", but you would never know it")
21:56amalloyRamblurr: instead of str, you can use pr-str, which prints in a way that preserves type information
21:57amalloy&((juxt str pr-str) '("string" "more"))
21:57sexpbot⟹ ["(\"string\" \"more\")" "(\"string\" \"more\")"]
21:58amalloy&((juxt str pr-str identity) '("string" "more"))
21:58sexpbot⟹ ["(\"string\" \"more\")" "(\"string\" \"more\")" ("string" "more")]
21:58amalloyokay whatever
21:58amalloyi'm not sure what you did to get that confusing output
21:59choffsteindnolen: I'm feeling like the examples of reset/shift I am seeing are just unnecessarily complex versions of let / fn... obviously, I must be missing something here.
22:01dnolenchoffstein: let / fn doesn't let you continue from any point.
22:01amalloychoffstein: the chapter on continuations in On Lisp blew my mind. have you read it?
22:01choffsteinamalloy: not yet. i'll try to read it
22:02amalloyi didn't really internalize it all
22:04dnolenchoffstein: bascially shift let's you create a hole, this hole is a function. You can call this function to reinsert a new value and continue where that hole was made.
22:04Ramblurramalloy: im having trouble applying the mapcat idiom to my actual function http://pastebin.com/dVQGJ7XG
22:04Ramblurrall of a sudden i'm getting the "wrong number of args" exception :\
22:04dnolenchoffstein: this is achievable if you write all your code in CPS style by hand - but delimc does that for you, it walks you code and applies that transformation automatically.
22:05choffsteindnolen: Ah, I see. I think I am just confusing myself with how I thought I would use callbacks with the code I was playing around with and how continuations really work.
22:07dnolenchoffstein: it's pretty heady stuff, I still don't really understand it thoroughly myself.
22:08choffsteinyeah. trying to figure out new concepts is like going around a drain. You just keep circling and circling until finally it clicks
22:14amalloyRamblurr: the i in your original version has disappeared in the mapcat version
22:14amalloyclojure is complaining that you created an #(anonymous function) that takes 0 args (it has no % in it), and you're calling it with one arg
22:15Ramblurroh! so that error is referring to the anonymous function, not the call to parsen
22:16amalloyyes. user$parsen$fn means "an anonymous function, nested inside of parsen, which is in the namespace user"
22:17amalloysince you're not *using* i at all, i'd rewrite this as something like (apply concat (repeatedly n #(do whatever, return a vector)))
22:17amalloyno point getting map(cat) involved if you don't use the input sequence for anything
22:17amalloy&(repeatedly 10 (rand-int 5))
22:17sexpbotjava.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn
22:17amalloy&(repeatedly 10 #(rand-int 5))
22:18sexpbot⟹ (2 3 0 2 4 0 2 0 3 0)
22:19dnolenchoffstein: https://github.com/swannodette/delimc, perhaps example that don't involve arithmetic make it clearer
22:20choffsteindnolen: yeah, i'm trying to work through them now in my head. thanks.
22:20dnolenchoffstein: I added an example w/ strings
22:25daakui'm running into an issue where macro expansion is happening before the associated use statement runs, making the symbol references inside the macro be invalid (i think). code/output here: https://gist.github.com/754b1f7e4c5a65e1e58e ("app" is a macro).. anyone know how to get around this?
22:25Ramblurramalloy: so i can put multiple function calls inside a [] and they'll all be evaluated for the return?
22:26tomojis that moustache's app or is it under your control?
22:26daakutomoj: moustache's app
22:27tomoj(appengine-environment-type) won't change, will it?
22:27tomojI mean, in one jvm
22:27daakutomoj: nope, it wont
22:27tomojthen decide at compile time which to do
22:28tomojone solution, I think, would be (if (= :interactive (appengine-environment-type)) (defn wrap-dev [handler] ..) (def wrap-dev identity))
22:28daakui see, switch to def and let the if run
22:28tomojbut a bit ugly
22:28tomojright, or that
22:28tomojprobably less ugly
22:28daakulets try
22:32tomojprobably better to have the use call outside the handler
22:33daakutomoj: not sure i follow (very much a n00b)
22:33daakui tried this: https://gist.github.com/754b1f7e4c5a65e1e58e -- but still fails. seems like i'm misunderstanding how macro expansions work
22:35tomojhmm.. right
22:36tomojwhy not just always add those uses to the namespace?
22:36tomojmaybe a tiny bit of startup overhead, but that's it, right?
22:37daakui guess to keep ring-devel and it's deps in :dev-dependencies i guess :).. but not terribly important i guess
22:37tomojah
22:37daakubut i want to understand why it still won't work anyways ;)
22:37amalloydaaku: (do a b c) compiles a b and c at the same time, so wrap-reload won't be linked in yet while you're compiling
22:38daakuamalloy: ah! that explains it
22:38amalloythere's a special exception if (do) is a form at the very top level, in which case it compiles/runs, compiles/runs, etc
22:38tomojwhoa
22:39tomojso eval could save you, but, :'(
22:39amalloytomoj: or a macro
22:39tomojhow?
22:39clojurebotwith style and grace
22:39amalloybut really you probably shouldn't be making changes to the compilation environment at runtime
22:40tomojthe problem seems the opposite to me
22:40choffsteindnolen: can you have a continuation you don't pass anything to?
22:40tomojwe want to check at compile-time whether to make runtime changes, no?
22:40tomojoh, I see
22:40tomoj"compilation environment" including which namespaces are used
22:41amalloyindeed
22:41tomojyou take the use call in the latest gist to be at runtime?
22:41dnolenchoffstein: that seems reasonable/possible to me.
22:42daakuwhat is the best way to solve the problem of optional dependencies then?
22:42amalloytomoj: (appengine-environment-type) is a runtime function
22:42amalloymaybe. i dunno
22:42amalloydaaku: depend on things anyway
22:42amalloyit costs so little
22:42tomojdepends..
22:43tomojring-devel is probably small
22:43tomojseems java deps can get quite costly in e.g. uberjar time
22:43tomoj..and uberjar result size
22:44amalloyif you're actually shipping two (or N) different versions of the jar, then fine
22:44tomojdaaku: btw, I think #(identity) can never be called without error
22:44amalloytomoj: wrong
22:45amalloy&((#(identity)) 10)
22:45sexpbotjava.lang.IllegalArgumentException: Wrong number of args (0) passed to: core$identity
22:45amalloyoh
22:45amalloyokay right
22:45amalloyhaha
22:45daakuhaha
22:45tomojI had to try it out a few different ways before realizing..
22:45amalloyi was thinking of (constantly identity), sorry
22:45daakunice
22:45tomojyeah, that's what I expected when I tried it I think
22:46tomojdaaku: to be clear #(identity) is (fn [] (identity))
22:47daakutomoj: yep, i didn't realize arity was enforced :)
22:48daakuwhich makes sense since defn seems to support arity based dispatch
22:52tomojbut only to the defined arities
23:05choffstein...is there a reason why calling count on a dered reference to a list would return a list?!
23:07choffsteinwhoops, stupid mistake
23:07choffsteinmiiigghhhtt be time to stop coding
23:46choffsteindnolen: you still here?
23:47dnolenchoffstein: what's up?
23:47choffsteindnolen: I'm pulling my hair out trying to create a continuation using shift / reset that doesn't take any args. any ideas?
23:49choffsteini'm looking at the rules for reset and shift at racket-lang.org, which I assume are similar to scheme's and therefore what you implemented. it's not looking very possible by design...
23:49choffsteinsee: http://docs.racket-lang.org/reference/cont.html#(form._((lib._racket/control..rkt)._reset))
23:49dnolenchoffstein: perhaps you can jump back to let expression and return a value you don't use?
23:50dnolenchoffstein: but yes, it's not exactly goto.
23:50choffsteindnolen: hmm, maybe.
23:50dnolenchoffstein: but I would argue, do you really need to do that?
23:51choffsteindnolen: well, for what I am trying to do, I do...
23:51choffsteindnolen: Which probably means I am going about doing this wrong :D
23:51dnolenchoffstein: why would you want to return to a place without inserting the missing value?
23:52choffsteindnolen: hold on, i'll show you on github in 10 seconds
23:54choffsteinokay, didn't quite get what I was looking for :( but here is the code anyway... https://github.com/newfoundresearch/surf
23:55choffsteinthe code is horrible, but I am just trying to use the continuations in the construct-callback function to delay potentially expensive callback calls. This way, I can put up 20 callbacks, and only actually execute the one that needs to be executed.
23:56choffsteinThe relevant lines are ~67. The program works as expected, but it doesn't seem to be delaying the callback calls ... just the redirect...
23:57choffsteinOh, shit, I got it
23:57choffsteinJust had to move some lines around :D
23:57dnolenchoffstein: cool.
23:58choffsteinThis is one of those times where I look at my code and say, "okay, it's working ... but there is no way it should be"
23:58dnolenchoffstein: heh, yeah I would take a moment to sort that out :) Not sure why you need dosync in this code.
23:59choffsteinbecause existing-callbacks is a ref that I am altering...
23:59dnolenchoffstein: why does it need to be a ref?
23:59choffsteinbecause if you go down to the 'render' implementation in the counter-component, using a ref prevents me from having to pass around new pages every time a add a call-back