#clojure logs

2009-05-19

02:20ccmtaylorhelp keys
02:23hiredman(doc keys)
02:23clojurebot"([map]); Returns a sequence of the map's keys."
03:07yangsx /join #ucw
06:18unlink1Is there a better way of achieving #(Math/sqrt %) ?
06:20unlink1ah. (:use [clojure.contrib.math :only (sqrt)])
07:09unlinkman, clojure really is nicer to use than scheme.
07:12unlinkThough, I suppose that is unsurprising given the two languages' design philosophies.
07:16hoeckunlink: yeah, they only have the lisp-1 in common, i guess
07:17hoeckunlink: and clojure comes with batteries included, whereas scheme wants you to build your low-level datastructures and primitives by yourself
07:19unlinkhoeck: I'm referring to simple things like (let ((x 1) (y 2)) (+ x y)), little niceties like inc/dec, loop/recur, stuff like that.
07:20unlinkbut yes, having reader-macro access to hash sets, hash maps, etc, is major win.
08:46cgrayif i make a class on the repl using proxy, what would its name be if i wanted java to call it?
08:46cgrayi have to pass the name as a string... kind of annoying
08:46Chouseryou shouldn't rely on the name of the proxy class, really.
08:46kotarakProxy doesn't make classes, it makes objects.
08:47Chouseryou can print it out with (class (proxy ...)), and pass that if you want
08:47cgrayokay, so i need to use gen-class?
08:47kotarakThe object is of an anonymous class.
08:47Chouserbut don't hard-wire that proxy class name into a .java source file.
08:47kotarakIf you need a class...
08:47cgrayok, thanks
08:48Chouserkotarak: well, proxy does create a named class if there's not an appropriate one already. But it's wisest to treat it as anonymous.
08:48Chousercgray: or gen-interface, and then proxy that. Or a write an interface in a .java and proxy that.
08:51kotarakChouser: I see proxy to generate "an object which implements the given interfaces". It's like "new Runnable() { void run() { do.somethin(); } }" in Java. If I need a class, I would use gen-*class*.
08:54unlinkWhat's the idiom for creating an object with methods? To pull an example from SICP... http://dpaste.com/45602/
08:56Chouserunlink: http://programming-puzzler.blogspot.com/
08:57Chouseroh, that's not a good way to link.
08:57Chouserhttp://programming-puzzler.blogspot.com/2009/04/adts-in-clojure.html
08:57Chouserthere. you've got some options.
08:58ChouserI have no idea who Puzzler is, but that post is very good.
08:58unlinkthanks, Chouser
09:02Chouserkotarak: what?
09:03kotarakThis whole "secure" stuff. To hide the implementation. There is an API, a contract on what's allowed and how to use the stack. Follow it and your are fine. If you do Voodoo stuff with the internals.... Well. You wanted to do Voodoo stuff. Don't complain.
09:04Chouserah, yes. I think it's almost never (maybe actually never) necessary.
09:04cgrayis gen-and-load-class broken, or is there some other reason that it is commented?
09:05ChousukeIt's broken and unnecessary
09:05ChouserThere's a reason the open stuff is simpler to do in Clojure -- it's probably what Rich thinks is right.
09:06kotarakAnd decoupling the methods from the object is also a good idea, I think. (read "multimethods")
09:11kotarakpuzzler is Mark Engelberg.
09:11Chouserah, thanks.
09:12kotarakSomehow this post doesn't fit to his recent discussion on the list.
09:13unlinkWell, there are disadvantages to the open style. It's certainly more verbose to use. (account-deposit account amount) vs. (account :deposit amount)
09:14Chouseryou can probably put it in an account namespace, and probably have no conflicts (how many libs define "deposit")
09:14Chouser...then it would be (use '(myns.account :only [deposit])) once, and later just (deposit account amount)
09:15Chouserand/or use a multimethod
09:16scottj_Is there a way to have namespace.test and use namespace without putting it on the classpath?
09:16Chouseryou can load any .clj file directly with load-file
09:17scottj_In more words, I have some small utilities, such as date-converter, and I just run them by passing date-converter.clj to java -cp clojure.jar clojure.main date-converter.clj. I'd like to put some tests in a separate file, and the namespace in that file will need to use date-converter, but I don't really want to modify the classpath.
09:18unlinkI'd like a defmethod which implicitly split the arguments into first & rest, dispatched on first, and passed rest to the method impls
09:18clojurebothttp://www.pigdog.org/auto/mr_bads_list/shortcolumn/1914.html
09:18Chousuke:P
09:19unlinkIn fact, every time I've used multimethods I've wanted that.
09:19unlinkMaybe I'm thinking of multimethods wrong.
09:19Chouserunlink: you are free to write such a thing. should be easy. Have you read the Clojure book?
09:19unlinkyes
09:20Chouseroh, I thought his multimethod examples were great. Showed some nice cases where you want multimethods dispatching on other than the first arg.
09:20unlinks/I'd like a defmethod which/I'd like the default semantics of defmethod to be to/
09:22Chouseroh.
09:23Chousukeout of curiosity, why?
09:23unlinkhmm
09:23unlinkI guess those wouldn't be ideal.
09:24unlinkI suppose what I'd rather have is a shorthand for (fn [x & _] (PRED x))
09:26unlinkok, fine, (defmacro dispatch [pred] `(fn [~'x & ~'_] (~pred ~'x)))
09:26Chouser#(do %& (PRED %)) ...it's barely shorter, but much more cryptic -- would it suffice?
09:26Chouserhar har.
09:26chessguy_work'mornin
09:26Chouserchessguy_work: hi
09:27kotarakunlink: (defmacro dispatch [pred] `(fn [x# & _#] (~pred x#)) is cleaner
09:27unlinkSome might say that O:-)
09:27chessguy_worki've been doing some thinking about how to represent chess patterns in clojure
09:28chessguy_worki have my first sample pattern written, though there's nothing behind it
09:28chessguy_workhttp://paste.lisp.org/display/80490
09:28Chousukehmmm... (defn dispatch-on-first [p] #(p (first &%))); (defmulti (dispatch-on-first class))
09:29unlinkI actually didn't know about &% until just now.
09:29chessguy_worki'm thinking that i can macro that whole thing into a function which takes a position and returns either a map of bindings for the various variables or nil
09:31Chousukechessguy_work: use a vector instead of the list, at least; ((foo) (bar)) looks like a function call.
09:32chessguy_workChousuke, you mean as the parameter to pattern?
09:32Chousukeyeah.
09:32chessguy_workgotcha
09:33Chousukealso, what exactly do the (enemy "a") etc do?
09:33chessguy_workit's sort of "declaring" those "variables"
09:33Chousukehmm
09:33chessguy_workmeaning "there exists an enemy, who we'll refer to with the string "a"
09:33chessguy_work(enemy piece)
09:34Chousukein that case, it might be better to do just [a :enemy, b :enemy] like let.
09:34Chousukeor however you represent your pieces.
09:35chessguy_workwell ultimately this is going to return a map like { "a" :f7, "b" :e2 }
09:36chessguy_worksaying, "this pattern matches the position if you take the piece on f7 to be "a",..." etc.
09:36chessguy_workso maybe i want [:a :enemy, ...] ?
09:37QuiarkHi.I have a list of items and need to update each of them, but the updating function needs to have access to the updates done so far. Something like (map fn data), but fn needs to see the most up-to-date version of the list. What would be the best way to do it?
09:38chessguy_worki want as much work as possible to be done with a macro here so that this is as close to the domain as possible
09:41ChouserQuiark: your fn needs access to the whole list?
09:41liebkeQuiark: I'm thinking you'll need to loop/recur
09:41QuiarkChouser, yep
09:41ChouserQuiark: does it need to know which element it's on (by index or something) or just the value that it's processing?
09:42QuiarkChouser, the value is enough
09:42ChouserI think reduce will probably do it for you.
09:42chessguy_workChouser, maybe something more like this: http://paste.lisp.org/display/80491
09:42jdzif i want to create my own exception classes i have to use gen-class facility, right?
09:43Chousukechessguy_work: I think for the assertions you could use functions
09:44QuiarkChouser, I have a set of objects, with x,y coords and need to move them around and to check collisions (that's why I need the up-to-date list in the updating fn)
09:44Chousukechessguy_work: that's going to be tricky to parse otherwise.
09:45chessguy_workChouser, you mean for on and if-move ?
09:46ChouserQuiark: doing this the way you suggest will probably be O(n^2) and I imagine there are ways to do it faster.
09:46ChouserQuiark: though it's a fun little Clojure puzzle, so...
09:46QuiarkChouser, yes, i know, but that's not an issue, I just want to try something out
09:46Chouserok
09:47Quiark(and try clojure along the way :)
09:47Chousuke(pattern [(declare [a :slider, b :enemy, c :enemy, line :rank-or-file]) (assert-on line #{a, b, c}) (if-move [b :off line] (attacks? a c))]
09:49chessguy_workinteresting
09:49Chousukethough declare needs to be renamed :p
09:49Chousukeas it conflicts with core
09:50Chousukeunless you just look for the symbol name. :)
09:50chessguy_workok, i'll send rich an email and make him change it
09:50Chousuke:D
09:50chessguy_workoh, you mean i need to rename mine? :)
09:51Quiarkso I guess I need to process nth item, remove nth item, insert updated one and then move on to (n+1)th item
09:51chessguy_worki guess i'm still not getting something about the difference between a and :a
09:51ChouserQuiark: I do think reduce could be made to work, but liebke's suggestion to try loop/recur is a good one.
09:51Chousukewell, in the macro context, a is a symbol, :a is a keyword
09:51chessguy_worki wouldn't have guessed i could use a, b, c, etc. like that
09:51Chousuketraditionally, symbols are names for things that the user names.
09:52Chousuke:P
09:52Chousuke(as if clojure has much tradition yet)
09:52clojurebotclojure is like life: you make trade-offs
09:52chessguy_workwell a is ultimately going to be a key in a map
09:52Chousukewell, yeah
09:52Chousukeyou can convert it from a symbol to a keyword for that purpose
09:52chessguy_workso i would have guessed it needed to be a keyword
09:53chessguy_workok
09:53Chousukekeys in maps can be anything
09:53kotarakQuiark: Chouser: Shouldn't (reduce (fn [up-to-date item] (conj up-to-date (update up-to-date item))) [] items) do the trick?
09:54chessguy_workcool. i love how little clojure syntax there is in that.
09:55chessguy_workalmost everything in there is domain-specific
09:55Chouserhm, maybe. Does update need access to the tails?
09:56Quiarkit needs all items, to check for collisions
09:57Chousukechessguy_work: the input to your macro is an unevaluated data structure. you can require it to be anything.
09:58Chousukeof course, best for you is something that's easy for you to process
09:58Chousukebut that might not be the best for the user.
09:58kotarak(defn tail-seq [s] (lazy-seq (when-let [s (seq s)] (cons s (tail-seq (rest s)))))) (reduce (fn [up-to-date [item & tail] (conj up-to-date (update up-to-date tail item))) [] (tail-seq items)), something like that?
09:59Chouser,(take-while identity (iterate next [1 2 3 4]))
09:59clojurebot([1 2 3 4] (2 3 4) (3 4) (4))
09:59ChouserQuiark: there are the not-yet-updated values...
10:01guineaHow cheap are agents? Would it be reasonable to make a spreadsheet where each cell is an agent?
10:01Chouserguinea: yes
10:01guineasweet
10:01chessguy_workChouser, in this case, i want to make these as easy as possible for the user, since there could be domain experts looking at this code
10:02ChousukeI'm already getting used to being called Chouser. I'm not even confused.
10:03ChouserChousuke: And I'm learning to ignore the yellow highlights in my window
10:03chessguy_workoy
10:03chessguy_worksorry guys
10:03Chouserno, seriously, we're used to it.
10:03chessguy_worki didn't even realize you were both talking
10:05choucrouteeveryone who's cool has a nick starting with ch*
10:05Chousukeoh no, another chou
10:05Chousersheesh
10:05gnuvinceholy crap
10:05chessguy_workhaha
10:06Chousukechessguy_work: figuring out the interface is up to you; I don't know your full requirements or even what you're up to. Just remember that clojure has more than just lists, symbols and keywords that you can use in your DSL. vectors, maps and sets (didn't forget to mention them this time!) are fine too.
10:07Chousukeyou could look at other DSLs for inspiration
10:07Chousuke:P
10:07chessguy_workChousuke, yeah, i don't even really know the full requirements either. my main goal for this part is to make the description of precise chess patterns as absolutely readable to non-programmer chess players as possible
10:07chotarakMaybe the channel should be renamed: #chojure
10:08chessguy_work(while still making it sane to parse in clojure
10:08Chouser,(reduce (fn [so-far [value & origs]] (conj so-far (* value value))) [] (take-while identity (iterate next [1 2 3 4])))
10:08clojurebot[1 4 9 16]
10:08ChouserQuiark: that's for you. only study it if you don't want to come up with your own solution. :-)
10:09kotarakChouser, like I wrote above. ;) But your take-while-iterate is more concise, than my tail-seq :)
10:09chessguy_workChousuke, got any recommendations for DSLs to look at that you like?
10:09Chouserkotarak: oh, sorry. didn't see that.
10:10QuiarkChouser, thanks, looks nice. I was thinking about a loop/recur version, because I'm not yet much used to functional style
10:10Chouserbut yes, exactly the same approach
10:13Chousukechessguy_work: hmm, not for chess stuff.
10:13Chousukechessguy_work: there are many html/xml relates DSLs around though :P
10:13chessguy_workwell, if there were a good chess DSL, i wouldn't be making my own :)
10:13Chousukeenlive and clj-html for one.
10:14chessguy_worki meant another DSL
10:14Chousukeperhaps datalog in contrib?
10:20chessguy_workChousuke, thanks, i'll take a look
10:25opqdonutis pprint broken in the current contrib?
10:25opqdonutuser=> (use 'clojure.contrib.pprint)
10:25opqdonutjava.lang.ClassNotFoundException: clojure.contrib.pprint.PrettyWriter (pprint.clj:0)
10:28rhickeywhat would it take to get a clojure-contrib.jar download that worked with clojure 1.0?
10:28kotarakopqdonut: you need to compile contrib: ant -Dclojure.jar=/path/to/clojure.jar
10:29kotarakopqdonut: pprint needs some classes generated with gen-class
10:32cgrayi'm doing (compile 'foo) and it's working, but when i do (import 'foo) it's giving me a NoClassDefFoundError: Could not initialize class foo
10:33kotarakcgray: you have to do (require 'foo) or (use 'foo)
10:33opqdonutkotarak: yeah thanks, i figured that out too
10:33kotarakcgray: import is for classes
10:33cgraybut foo is a class
10:34burkelibbeySo PragProg told me Programming Clojure would be shipping within a few weeks... out of curiosity, is there a firmer date floating around?
10:35gnuvinceJune 31st
10:36burkelibbeyHeh, that's a pretty liberal use of "few weeks". I had gotten my hopes up. Can't wait :)
10:39danlarkinrhickey: probably just a post to the ML
10:45opqdonuthmm, now it's accumulators that is complaining
10:45opqdonut [java] Compiling clojure.contrib.accumulators to /home/jkaasine/src/clojure-contrib-read-only/classes
10:45opqdonut [java] java.lang.NoSuchMethodError: clojure.lang.MultiFn.<init>(Lclojure/lang/IFn;Ljava/lang/Object;Lclojure/lang/IRef;)V (accumulators.clj:21)
10:46opqdonuti'm using clojure 1.0.0
10:47opqdonutsame error in complex-numbers if i comment out accumulators from build.xml
10:47kotarakopqdonut: try "ant clean" before building and make sure the clojure.jar is used. There is some old compiled code lingering around, which tries to use some old interface.
10:47opqdonutok
10:47kotarakopqdonut: maybe also do a rebuild for your clojure.jar
10:47kotarakwith clean and everything
10:48opqdonutyeah, it works
10:58dnolen_so has anyone messed around much with c.c.shell-out?
11:01Chousera bit. why?
11:01dnolen_Chouser: is there anyway pipe out the output from the shell immediately instead of waiting till the end?
11:02Chouserthere have been discussions...
11:03dnolen_but not much more than that?
11:03Chouserin fact I thought there was a patch. hm...
11:06Chouserhow can the google group search be so poor?
11:06dnolen_heh
11:06dnolen_I use a special gmail account to load in all my mailing lists. works well.
11:07dnolen_i found the email, Perry Trolard submitted a patch.
11:07Chouseris that the "articulated" one? that's different
11:07dnolen_oh yes, it is.
11:08Chouseroh, this was private email, not on the group.
11:08Chouserok, so the main issue is what would be returned?
11:09dnolen_system status?
11:09Chouseryou can get that now. But you want the whole stream, right?
11:10dnolen_yes, I want to be able to run commands like git, and see the output at the repl.
11:10Chouserit could return the Process, so that you can get stdout and stderr and even stdin from it, etc. But then shell-out's hardly doing anyting for you -- you might as well call .exec yourself.
11:11dnolen_i see, perhaps I was confused, what is the intended use case of shell-out over exec?
11:11Chouserit is meant to simplify common cases.
11:12Chouserand handle the opening and closing of streams, collection of the sub-process (to avoid zombies), etc.
11:13p_lkotarak: java's startup speed would work against i, I think..
11:14dnolen_so Chouser, so you think I should just use exec directly? I'm OK with that, shell-out just seemed convenient.
11:14ChouserI guess I'm not sure what you use-case is yet. One option would be something like:
11:16dnolen_I'm building a REPL-side library installer.
11:16dnolen_at the REPL:
11:16dnolen_(install 'compojure)
11:16Chouser(with-sh [[stdin stdou stderr] ("git" "status")] (read print etc stdin))
11:16dnolen_then you get feedback about git clone, downloading zip, unpacking zip, ant process.
11:18ChouserI guess I'd recommend using .exec directly for now. If you find a clean way to abstract the shelling-out part, perhaps we can use that to improve or replace shell-out
11:18Chouserit doesn't currently have any way to get data from the process until it's complete.
11:19dnolen_k, good to know. thanks!
11:26kotarakHmm.. the ants don't seem to be sooo antique....
11:29StartsWithKdnolen_: http://maven.apache.org/scm/ can help you with calling different tools (you will need them installed on your system), and ant can be used as a lib
11:34StartsWithKdnolen_: i tried to do something similar a month ago (http://code.google.com/p/truba/) using ivy and ant to build a clojure lib repository (there are like 40 libs in there) but i guess that will wait for now..
11:35StartsWithKbiggest problem was, most clojure libs don't have any build system at all, or they require that clojure.jar clojure-contrib.jar are placed in some specific directory, and some event that env variables must be used
11:36dnolen_StartsWithK: I'm only slightly familiar with Maven, until someone proves to me that it's easy to use, I'm not going to bother with it. Same with Ivy. And I agree, most clojure libraries don't have or even need a build, it's just source.
11:37StartsWithKdnolen_: maven.scm is a separate library, no need for maven build/dependancy tools.
11:37dnolen_what I'm working on simply JSON objects hosted on Google Appe Engine that resolve the library. the client side code does everything, it's intended to work with: zip files, git repo, and jars. people can add support for other things if they want, but it's really just to make my own life sane.
11:38StartsWithKit gives you something like (checkout :git {:repo bla :rev ble})
11:38kotarakI have a fairly stable setup of ant with Ivy (with the latter completely optional). Only some minor adjusts need to be done for a given library. I use it for all my projects.
11:38StartsWithKkotarak: you don't need clojure repo for ivy (just use packager resolver with zip on clojure download site)
11:39StartsWithKkotarak: something like http://github.com/ksojat/cloak/tree/master (see repo directory)
11:40kotarakStartsWithK: I also patched to contrib to provide one jar per module, so that I can say: <dependency ... conf="*->def"/> and only get clojure.contrib.def. 13k jar instead of 2.5Mb jar. :)
11:40StartsWithKif projects provided some sore of zip only downloads, repository could me made only as meta index
11:40StartsWithKkotarak: i do watch what you do with contib+ivy integration
11:41StartsWithKyou hit that problem with classes/ directory where everything is mixed
11:41kotarakHmm. cloak looks also interesting.
11:41StartsWithKi think cloak will save us :) i'm adding ant task for clojure to it, support for ssh and maven.scm for now
11:42StartsWithKwe need uniform build system that is no brainer anymore, without it, we can't even start to build repositories
11:43kotarakYeah. Cloak is interesting. I was working on something similar called rabotnik, but that is now on ice it seems. :)
11:44StartsWithKhehe, i was planing to extend truba to be full blown build system too, but, as cloak is already there, it may be the best place to place the code
11:46StartsWithKdnolen_: will your repo be then just a meta index or you will host download files too?
11:46dnolen_StartWithK: just meta index at first, and perhaps host really popular libs.
11:46dnolen_http://librynths.appspot.com/install/compojure
11:46dnolen_this is just a dummy placeholder for now.
11:46StartsWithKsomething like that i tried with truba too, like only a meta index
11:46dnolen_but it's coming along.
11:47StartsWithKbut as i said, nothing has a build that works
11:47StartsWithKso i eneded with creation of repo.zip on google code (40 clojure libs ~6mb)
11:47dnolen_StartsWithK: my thought was to have the proper build info in the meta index, that is the index shows how to correctly generate the build
11:47dnolen_perhaps we can use a cloak file here.
11:48dnolen_until the maintainer fixes their lib.
11:48StartsWithKdnolen_: truba does that too, it has a build declarations in its index, but they are ant files
11:49StartsWithKyes, thats why i would like to make cloak functional in a short time, so something can be used for building, that would solve meta index problem
11:49StartsWithKas http://code.google.com/p/ivyroundup/ is ivy based meta index for different java libs, i think i like how they did it the best, they use svn repo as 'the repo'
11:50StartsWithKthey don't even have separate download site or anything
11:50StartsWithKand that also gives someone a chance to fixate on specific repo revision
11:50dnolen_perhaps the meta index supports stable libs.
11:51dnolen_anyways you get 1gb on GAE, should enough for the popular libs.
11:51StartsWithKas there are something like 70-80 libs for clojure, they are not loarger than 10-15mb combined
11:51StartsWithKlarger*
11:52dnolen_heh yeah.
11:52AWizzArdHow do I quit a JVM? Something like (System/exit)?
11:53kotarakBingo
11:53gnuvince,(System/exit 0)
11:53clojurebotjava.security.AccessControlException: access denied (java.lang.RuntimePermission exitVM.0)
11:53kotarakAWizzArd: are stop all threads.
11:53kotarakIIRC
11:53AWizzArdthanks
11:54StartsWithKkotarak: souldn't you use configs for things like 'build', 'test' 'doc' dependancies, and modules for contrib separation?
11:56StartsWithKas i see it now, if i create contribA with my configs, and someone creates contribB, (for libs A an B) lib C can only depend on contrib-all.jar as it can't know what is in contrib A and what is in contribB
11:56kotarakStartsWithK: Not sure. I'm not an Ivy wizzard. I tried to do some kind of recursive sub-module built, but without much success. The conf stuff "Just Worked(tm)".
11:56kotarakI'm not sure it's the right way. But I also got no feedback on it, so far.
11:57StartsWithKhere is a feedback :)
11:57StartsWithKi only lurk on ml :)
11:57kotarakHave to read-up again on configurations.
11:58StartsWithKso config is used more like 'i have a lib X that i depend on when i generate docs, not when i distribute a jar'
11:58StartsWithKso conf='test' could add <dependency org='junit' ... conf='test'/>
11:58kotarakBut it seemed to me that they would be used for example for things like default, with-nifty-addition, with-another-optional-thing...
11:59StartsWithKwell, artifacts are more for that
11:59StartsWithKlike contrib.jar contrib-src.jar contrib-docs.jar contrib-bla.jar
12:00kotarakAh. I didn't know you could specify artifacts. I see, you did that in cloak.
12:00StartsWithKyou for now have one module with one artifact, and use configs to generate different profiles of contrib
12:01StartsWithKin http://bitbucket.org/ksojat/neman/ (dosn't build anymore now :( )
12:01StartsWithKi have something like neman-core -xml -web...
12:02StartsWithKthey are all separate directories, they get there own classes/ so no mixing of compiled files
12:02StartsWithKevery dir is a separate module with (for now) one artifact inside
12:03StartsWithKthey have inner dependancies declared inside there ivy.xml files and toplevel build knows how to compile them in correct order (that is provided with ivy)
12:04StartsWithKso maybe a similar split inside contrib, but maybe not on per-file basis, like map-utils seq-utils .. could go in coll-utils module
12:05StartsWithKor xml related libs in another..
12:06kotarakI grouped eg. types and generic, the whole scattered math stuff...
12:10StartsWithKkotarak: will you when finished place a contrib.zip on download page of google code?
12:11kotarakI'm not a member of contrib. But I can contact rhickey, if this is a desired goal.
12:15StartsWithKjust a plain zip with all the jars inside is all that is requiered by ivy, and maybe some sort of version
12:15kotarakWouldn't you have to download the whole zip, just to a single jar?
12:16StartsWithKyes, but ivy will cache it for you, and only that one jar is your dependency
12:26kotarakStartsWithK: I have to drop out now, but I will look into the issue and will let you know about the progress.
12:26StartsWithKkotarak: ok, thanks
12:27dfdeshomhi, how do I import a jar file from the cli?
12:28dfdeshoms/cli/REPL
12:29danlarkindfdeshom: if it's on your classpath, you do (import '(org.package name))
12:29Drakesonwalters: ping
12:29dfdeshomdanlarkin: what if it's not?
12:30danlarkindfdeshom: add it to the classpath and restart your JVM
12:32dfdeshomdanlarkin: thanks
12:38dfdeshomdanlarkin: have you used the fact library? I've added it to my classpath but (import fact) gives me an exception
12:39maaclIs it bad form to post a link to a Clojure question I have posted to stackoverflow.com?
12:39danlarkindfdeshom: Oh... for using clojure code you use a different function
12:39danlarkinsorry, I thought you meant a java jar
12:39technomancydfdeshom: from what I understand fact is deprecated
12:40stuhoodmaacl: i don't think that would be bad form
12:40technomancyits author has switched back to test-is
12:42maaclClojure / java.library.path / swank question at stackoverflow.com : http://tinyurl.com/q3257t - can anyone help?
12:42dfdeshomdanlarkin: oh, ok, i didn't know there was a difference
12:42dfdeshomtechnomancy: what would you suggest using?
12:44dfdeshomdanlarkin: how do i load a clojure jar?
12:45technomancydfdeshom: test-is is nice
12:46danlarkindfdeshom: http://clojure.org/api#require or http://clojure.org/api#use
12:46dfdeshomtechnomancy: thanks, i see it's in contrib
12:46dfdeshomdanlarkin: thanks
13:12cheddarwhat does "namespace 'foo.bar' not found after loading '/foo/bar'" mean?
13:13cheddarnever mind i think i understand...
13:19cheddarerr actually i don't :-/\
13:20technomancycheddar: do you define a namespace in foo/bar.clj?
13:22cheddartechnomancy: I have as my first line <ns foo.bar> in a file /foo/bar.clj that is on my classpath
13:23cheddaris there something i need to do?
13:24danlarkincheddar: <ns foo.bar> or (ns foo.bar)
13:25cheddar"(ns <foo.bar>)" actually
13:25cheddarah.....
13:25danlarkin"well there's your problem"
13:51technomancycan you get metadata about a namespace?
13:51technomancy~^#'clojure.core
13:51clojurebotclojure is far closer to perfection then python
13:51Raynesthan*
13:52Chouser,^(the-ns 'clojure.core)
13:52clojurebot{:doc "Fundamental library of the Clojure language"}
13:52technomancyhmm; but the metadata doesn't include the path to the file that defined it?
13:53technomancyI guess the mapping is tenuous since a namespace can be defined anywhere technically
13:53Chouserdoesn't look like it. Could be multiple files.
13:53ChouserI suppose the 'ns' macro could record something -- there's only supposed to be one of those per namespace.
13:53technomancy...in theory anyway
13:54technomancyI guess I could just assume it's in src/
13:55Chouseryou could looks for vars in the namespace and see if any of them have files
13:56Chouser,(map #(:file ^%) (vals (ns-publics 'clojure.core)))
13:56clojurebot("clojure/core.clj" "clojure/core.clj" "clojure/core.clj" "clojure/core.clj" "clojure/core.clj" nil "clojure/core.clj" "clojure/core.clj" "clojure/core.clj" "clojure/core.clj" "clojure/core.clj" "clojure/core.clj" "clojure/core.clj" "clojure/core.clj" "clojure/core.clj" "clojure/core.clj" "clojure/core.clj" "clojure/core.clj" "clojure/core.clj" "clojure/core.clj" "clojure/core.clj" "clojure/core.clj" "clojure/core.clj" "c
13:56Chouserthere seems to be a consensus
13:59technomancyChouser: very nice.
14:05Chouser,(set (map #(:file ^%) (vals (ns-publics 'clojure.core))))
14:05clojurebot#{nil "clojure/genclass.clj" "clojure/core_print.clj" "clojure/core_proxy.clj" "clojure/core.clj"}
14:09lisppaste8technomancy pasted "slime stacktrace niceties" at http://paste.lisp.org/display/80502
14:10technomancythat should allow you to jump to the line referenced by the current line in the stack trace as well as dimming stack trace lines that refer to swank or clojure core stuff
14:10technomancytry it out and let me know what you think
14:10Chousersounds nifty. I don't use slime.
14:10clojurebotslime is icky
14:11technomancyit makes a huge difference to have all those noisy lines dimmed out; makes the relevant stuff much easier to find in a trace.
14:11technomancyyou should port it to whatever you use. =)
14:20hiredmanclojurebot: botsnack
14:20clojurebotthanks; that was delicious. (nom nom nom)
14:34twismtechnomancy: i'll give it a whirl
14:47jfieldshow do I specify a java enum value?
15:12Chousukehm.
15:12Chousukeare they just classes? :/
15:13Chousuketry EnumName/ITEM
15:15ChousukeApparently they are just classes. they can even have methods and (non-enum) fields :)
15:21ChouserI guess I can't use gen-interface+proxy to make static factory methods, can I. It's gen-class or Java...
15:24Chousukehmm
15:24Chousukeenums are actually a fair bit more powerful in java than I even thought.
15:24Chousukeyou can actually have each enum value have its own implementation of some method :P
15:25Chousukeever* thought too.
15:44maaclClojure Box / java.library.path / swank question at stackoverflow.com : http://tinyurl.com/q3257t - can anyone help?
15:51sh10151I keep thinking that laziness somehow reduces a breadth-first-search's memory requirement, but that really doesn't seem right to me. Can anyone convince me that I'm right or wrong?
15:52Chouserif you've got a normal one-directional tree, something still has to keep track of parent nodes that you haven't traversed yet.
15:54sh10151But could that be a lazy sequence too
15:54sh10151?
15:54Chouseryes, but a lazy sequence over what?
15:56Chouserwhen the seq-producer has returned the last item of a level, and is asked for the next node, how does it find it?
15:57ChouserI think the answer is that it must have internally a list of the parents yet to be traversed, just like an eager breadth-first algo would.
16:03sh10151Hmm
16:04sh10151I definitely see that
16:04sh10151but I am having trouble finding it in my code
16:04sh10151assuming everything is lazy
16:05lisppaste8sh10151 pasted "where is the space consumption?" at http://paste.lisp.org/display/80508
16:05sh10151if children returns a lazy sequence
16:08sh10151hmm, I never used branch? -- just copied the tree-seq API
16:09Chouserpending accounts for the space consumption
16:09sh10151is it not a lazy sequence too?
16:10Chouserheh. um.. let's see
16:11Chouserslippery, isn't it.
16:11sh10151I think it's somehow the thunks in the lazy sequence
16:11sh10151I think
16:11sh10151but it's driving me crazy
16:11Chouserok, (children node) ... even if children is lazy, the "node" part is known and closed over and stored in the next iteration's 'pending'
16:11sh10151'cause I am almost sure you are right
16:18sh10151OK, I see it now
16:18sh10151have to think about it at the very end, when there are a bunch of nodes
16:18sh10151thanks
16:18sh10151the leaves will all have this thunk that will return an empty sequence
16:19sh10151now to write IDDFS with the same api :-P
16:19technomancyChouser: the thing about getting metadata for a var is that the :file value is still relative to the classpath; I'm curious about where it is on disk
16:20technomancyI can just search src/ in the project root, but that doesn't get me stuff that comes from dependencies.
16:20Chouserit could be in a .jar or something -- there may not be a regular disk path to it.
16:21technomancyright, but I'm working from Emacs; it can open up jars transparently.
16:22Chousukememory usage with lazy seqs is tricky :/
16:23Chousertechnomancy: seems like you'd want to get the classpath and poke through it yourself. or something.
16:24Chousuketo avoid closing over node, could you do (let [therest (children node)] before the lazy-seq?
16:24technomancyyeah, I can search myself if there's no existing function for it
16:28sh10151Chousuke: I think there's still a thunk for that, and the more nodes you take the children of, the more thunks there are
16:29sh10151at the bottom of the tree there will be a lot of empty sequences
16:30sh10151but pending contains all the thunks to get them when you reach it, thus making the max memory consumption equal to the number of leaf nodes
16:30sh10151which is BFS's memory consumption anyway
16:33sh10151it's confusing because infinite sequences *are* possible
16:33sh10151but they only have one thunk at a time
16:33sh10151bfs has as many thunks as the deepest level it's visited
16:38ChouserI thought 'compile' followed :require directives and compiled those namespaces first if needed.
16:54twismhmm..qq...
16:55twismhow would you create a function that takes an arbitray amout of arguments from a function that tkaes a fixed amount?
16:55twismabritary*
16:55Cark(reduce + args)
16:56Cark(defn [& args] (reduce binary-fn args))
16:57Chousukeif the output of your function is acceptable as its input, then reduce is what you want. :)
16:57twismsorry didn t frame the question right
16:59twismi wonat a function that would take a function with a fixed number of arguments and turn that function into the same function but can take an abritary amount of arguments
16:59twismi want*
16:59Chouserthose extra args would be ignored?
16:59twismsome of them could be
17:00Chousukethe answer depends on what you want the result function to do :p
17:00Chouserwhat would you do with the ones that aren't ignored?
17:01twismthe gist is that im trying to write a library that a user of this said library can write a function to be used (this function written by the user can take 2 or 3 arguments) but how would i tell how many arguments the function thats being passed by the user takes
17:02Chousukepass it in as a parameter? :p
17:03Chouserthis sounds familier
17:03danlarkintwism: haven't we gone over this already? or am I having deja-vu
17:03hiredmanthe answer is: pass a map
17:04twismyes
17:04twismwe did
17:04danlarkintwism: the answer hasn't changed :)
17:05twismbut the solution we came up with the last time wasnt implemented until now, and did not work out
17:05twismpass a map?
17:06twismwe came up with something like (defn fix-it [f] (do-callback <some magic happens here> new-f))
17:06twism:)
17:07Chouserwhere fix-it takes a fn of 2 args and returns a fn of 3 args, where the 3rd is ignroed, right?
17:07twismor maybe i stepped away form the computer when this discussion came up
17:07Carkwhat they mean is this : define your callback function with a single parameter, which is a map, and destructure the map in order to get the parameter values
17:07twism3rd could be ignored
17:08twismok that would work
17:09hiredmanCark: well, I would hardly put words in their mouths, but that is what I mean, for sure
17:12twismi dont like it
17:12twismbut it works
17:12Carkhiredman : you're the multiple parameter function of this chan, hence the plpural form
17:13Carkhow about defining your callback like this : (denf cb ([p1] ...) ([p1 p2] ...)) ?
17:14hiredmanmaps are awesome, what is not to like?
17:14twismCark: i prefer the maps
17:14Chouserheck, pass a vector and destructure that.
17:15twismi just wanted to provide a user the most straight forward way of defing a function
17:15twismthe user*
17:16twism(defn cb [p1 p2]... or (defn cb [p1 p2 p3]...
17:16ChouserWould could provide a replacement for defn that does what you want.
17:17twismbut (defn cb [[p1 p2 ... pn]] ... could work
17:17Carkif you can pass 2 or 3 parameter functions, that means that you need these 2 kind of functions, right ?
17:17Chouserbut some users want that 3rd arg, and others don't care, right?
17:17twismim calling this function with 3 arguments
17:18hiredmanhmmm
17:18Carkok, then i don't see why you would allow a 4 parameters function to be passed
17:18Carkit's trivial for the user to adapt the arity
17:18twismif they provide 2 then i get the WrongNumberArguments Exception
17:19hiredmanjamvm apears to run this 20x slower then the sun jvm
17:19Carkthis callback function is part of the interface of your api
17:19twismyes
17:19twismCark: yes
17:19hiredmanwell, close to 20x
17:19Chousuketwism: so you need to require your user's function to accept 3 arguments.
17:19twismjamvm.. is iphone java vm right
17:19twism?
17:19Carkwhen i call a function in any api, i'm aware of the arity of this function, the same goes for callback
17:20hiredmanjamvm is a super portable mini jvm
17:20Chousuketwism: they don't actually have to DO anything with all three arguments though.
17:20Chousukethey can just (defn mycallback [a _ _] ...)
17:20twismtrue i could force them to do that... but its rare for users to implement a function that requires the third argument
17:21twismbut specification requires i code for the case that this happens
17:21Chousukethey can just ignore it in the callback
17:21twismits not a big deal
17:22twismi can force them to provide a function that takes three arguments
17:22Chousukeyou could of course wrap the call in a try block and catch the exception, but... that's really ugly.
17:23twismit would only be icing on the cake (from where i stand) that they could provide 2 or 3
17:23twismCHouske: yeah we went thru that here
17:23Carkyou could provide two "callback registering" functions
17:24Cark(call-me-back-2 cb) and (call-me-back-3 cb)
17:24ChousukeIMO that's worse than just being forced to accept three arguments :P
17:24Carkhehe yes
17:24twismCark: i agree with Chouske
17:25twismim going to go with the (defn cb [a b _]... approach
17:25hiredmanbah
17:26hiredmanclojurebot: maps?
17:26clojurebotmaps are functions
17:26hiredmanclojurebot: maps is also <reply>maps are *AWESOME*
17:26twismi had javm running on my iphone
17:26clojurebotc'est bon!
17:26twismjamvm*
17:26twismwas doing some cool rhino iphone stuff with it
17:27twismi need to see how clojure fares on my iphone
17:28hiredmanI have three implementations of this function (searchs a byte array to see if it contains a given byte) they all run much slower on jamvm
17:29hiredmanthe fastest function on the sun jvm is thirdplace on the jamvm
17:29hiredmaner
17:29hiredmansecond place
17:29hiredmanthird place is the same
17:39Chousertwism: that's jailbroken?
17:42hiredmanSteve Jobs has been quoted as saying "Java's not worth building in. Nobody uses Java anymore. It's this big heavyweight ball and chain."
17:42hiredmanZing!
17:47dnolenhiredman: until I used Clojure, I would have agreed with him ;)
17:55cadsyou guys think anyone will ever make a bare metal clojure machine?
17:55dnolenlike a Lisp machine?
17:55cadsheh, no, a virtual machine
17:56hiredmanI have been reading through http://www.loper-os.org/
17:56cadsrather, a compiler/interpreter
17:56hiredmanthe loper-os guy seems to want to build a modern lisp machine
17:57cadsi remember reading a tweet about "when clojure's compiler is written in clojure"... and it occurred to me that at that point we could change the target language away from jvm
17:58cadshiredman: I was sad to hear that lisp machines existed and the disappeared
17:58cadsthen*
17:58hiredmanwell, I think clojure will always be strongly tired to the jvm
17:58cadsto me it doesn't lose much of its charm even separated from java interop
17:59hiredmanclojurebot: clojure?
17:59clojurebot"[Clojure ...] feels like a general-purpose language beamed back from the near future."
18:00cads:)
18:01cadsexcept for #(f %1 %2), that feels like a mix between a lambda and some shell-script
18:01dnolenOne Clojure can compile itself, I am sure people will want to port to other runtimes beyond the JVM. Clojure is an idea, and the JVM is a good place to grow it.
18:02cadsdnolen: I think so too, and that will be a very neat process to witness
18:02hiredmanclojurebot: clojure?
18:02clojurebotclojure is like life: you make trade-offs
18:03cadsclojurebot: paste?
18:03clojurebotlisppaste8, url
18:03lisppaste8To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.
18:09hiredmanclojurebot: clojure?
18:09clojurebotclojure is far closer to perfection then python
18:09technomancyhiredman: did you see this? http://twitter.com/gvanrossum/status/1838308947
18:14lisppaste8cads pasted "pseudo-module" at http://paste.lisp.org/display/80515
18:15cadshere I've tried to create a function which, given a "less-than" type comparison function, will instantiate custom versions of the rest of the comparison functions
18:16hiredmantechnomancy: yeah :P
18:17hiredmancads: it has to do with how def (which the macro defn uses) works
18:17lisppaste8cads annotated #80515 "correction" at http://paste.lisp.org/display/80515#1
18:18hiredmanthe namespace def operates in is set at compile time
18:19cadshiredman: I was thinking that a macro could not only insure that the definitions end up in the right namespace, but also let you rename the functions to reflect your customization
18:19hiredmancads: I woud use intern
18:20hiredman(doc intern)
18:20clojurebot"([ns name] [ns name val]); Finds or creates a var named by the symbol name in the namespace ns (which can be a symbol or a namespace), setting its root binding to val if supplied. The namespace must exist. The var will adopt any metadata from the name symbol. Returns the var."
18:20hiredman(intern *ns* my> (fn [x] something here))
18:22cadsthat'll work even if that line of code is in another namespace, right?
18:23hiredmanactually, I think if you use intern it doesn't even need to be a macro
18:23hiredmancads: I think so
18:23cadsi'm trying my example again
18:29mrsoloi can't do (.PI Math) can i?
18:30hiredman,(Math/PI)
18:30clojurebot3.141592653589793
18:30cadsyou can do (. Math PI)
18:30hiredman,(. Math PI)
18:30clojurebot3.141592653589793
18:30hiredmanPI is not a method
18:31mrsolothat i know i just like (.xxx yy) form better.. oh well
18:33hiredmanyou could write a macro
18:33hiredmanthat does a transform on the input, but it would be tricky, due to .xxx being valid syntax in many cases
18:33mrsoloi can eventualy :-) my clojure fu isn't there yet
18:44Chousuke,Math/PI
18:44clojurebot3.141592653589793
18:44Chousukeright, that form works too
18:45Chousukeinteresting that the function call form does as well.
18:48lisppaste8cads annotated #80515 "Revision" at http://paste.lisp.org/display/80515#2
18:48cadshiredman, check that out, that works pretty well!
18:48cadsthanks for the help :)
18:52ChousukeLooks like that should be a macro :/
18:54cadsprobably :)
18:55cadsdo you think that pattern is acceptable for use?
18:55Chousukewell, if you end up generating many global names, you should perhaps rethink your design
18:56Chousukebut it's not really wrong
18:58Chousukethough using a runtime mechanism like that looks dubious. you'd never call equalifier programmatically during runtime (it'd be really weird if you did), so it's better to just make a macro.
19:00cadswell it is a higher order function, I could see it being useful at runtime, but not really in the current side-effecting state. If equalifier returned maps storing fns it could be part of some kind of logic engine
19:00Chousukeyeah, that way it's just fine
19:00Chousukeeven good functional design
19:01Chousukebut that side-effecting thingamabob isn't a function at all; it's a procedure.
19:02cadsSince the side effect form is for humans to have it easier, I think there's nothing wrong with making it a macro like you say. Maybe a macro would let you have better control of the target namespace, or allow you to specify the modular structure in a less verbose way
19:02Chousukewell, actually making it a macro only has the difference is that a macro can be expected to make new global stuff appear, because it's generating code.
19:03Chousukeof course, you should document it if it does have global effects :)
19:05cadscan I write a map that contains fns that are defined in terms of symbols that are not yet bound?
19:05Chousukethe difference is that macro calls are always written directly in the source. you can't pass around a macro and call it at runtime to generate stuff. (disclaimer: without hideous trickery and eval)
19:05Chousukesure; declare the symbols first.
19:05cadsyeah, but the idea of passing around equalifier and calling it here and there randomly in its current form is silly :D
19:08Chousukeif you made equalifier a function that returns a map of names to (anonymous) functions, you could very well use it to generate new functions at runtime; it wouldn't even be ugly at all. The functions are just values in a map, so it's no different from any other map returning function :)
19:09cadsI want to represent a parametric module as a map of dependent functions defined in terms of the module's parameter symbols.. wait, hey, that's pretty much what you say
19:10dnolencads very interesting, this got me thinking.
19:10dnolenwhat I never like about putting fns in maps is that they can't change if you redefine them
19:10dnolenputting vars in a map works
19:10dnolenbecause vars implement IFn
19:11lisppaste8dnolen pasted "vars in maps" at http://paste.lisp.org/display/80518
19:13dnolennot sure if that's helpful to you at really, but it's something to think about...
19:14Chousukedoesn't need to be vars unless you have to redefine them later without touching the map. (which gets uglyish again)
19:14lisppaste8Chousuke annotated #80515 "untitled" at http://paste.lisp.org/display/80515#3
19:14ChousukeI make no guarantee of the parens, but you should see the general idea there :)
19:16ChousukeI also forgot to remove the docstring...
19:16cadswell, for mine I'd need something like frozen unevaluated fns (def depent-fs {fname (*fn [a b] f-depend) & }), where the fn objects would have unbound symbols, and then another function that would act like (let [f-depend my-f] dependent-fs), where the unbound symbols would be bound and the functions evaluated to create actual ifns
19:18Chousukehm
19:18cadsof course I could represent it like this: (fn [f-depend] {f-name (fn [a b] (f-depend a b))})
19:18Chousukethat seems good.
19:18cadsthen, I could compose modules using functions that works with these special lambdas
19:19Chousukelooks monadic
19:19cadsand have a final macro that interns a module with user specified dependency functions
19:19cadsgod knows everything's a monad :D
19:19Chousuke:)
19:20Chousukedo those functions always have just one function they depend on?
19:21Chousukeyou could make some macro sugar that allows you to use the f-depend name without explicitly writing the lambda
19:21cadsa vector space might need 4-6 functions
19:21cadsand your modules may always need any number of constants
19:21Chousukeokay. scratch that then.
19:22cadsbut even in the case of functions, you might want the option of defaults :P
19:22Chousukeyour "f-depend" shouldn't necessarily have to be a function.
19:22Chousukeit could just be a map of whatever the function depends on.
19:22cadsahah
19:23Chousukeand then you call ((dependent-f map-of-dependencies) args moreargs)
19:23cadsand I could merge the user provided dependencies with a corresponding defaults map
19:23Chousukeyeah.
19:24cadsthis could be very useful to me
19:24Chousukethe dependent-f will only need to document what keys it uses to look up its dependencies
19:24cadsyeah, and with a macro it could actually look very natural
19:28Chousukeyou could use a macro to bind the depends you need automatically (define-dependent-function foo [regular-arglist] [depend1 :depend-key, depend2 "another depend key"] (do-stuff-with (depend2 regular-arglist) depend1))
19:33Chousukein fact the depend list could be a clojure map destructuring form and then you could use it in let as is :P
20:01cads(defn mod-intern [prefix mod & depends] let [insta-mod (apply mod depends)] (do-seq [[name fun] insta-mod] (intern *ns* (symbol (str prefix name)) fun)))) , where a module is a function that takes values and returns a map of name/value pairs
20:04cadsthe equalifier example becomes (def equalifier (fn [<fn]
20:04cads { "<" #(<fn %1 %2) ">" #(<fn %2 %1) "=" #(not (or (<fn %1 %2) (<fn %2 %1))) "<=" #(not (<fn %2 %1)) ">=" #(not (<fn %1 %2))}))
20:07cadsand usage is like this : (mod-intern "l_0-comp" equalifier (fn [a b] (< (apply max a) (apply max b)))), (l_0-comp= [1 23 123 5232 123 9999] [1 -13 9999 100 2003]) => true
20:08cadshehe, I really need to learn how to write macros
20:16Chousukeyeah, you definitely don't want to use intern :P
20:17Chousukealso, keywords as map keys instead of strings would be more idiomatic for a map like that, I'd say.
20:19Chousukeand it still looks like generating global names at all (even with macros) is not the solution
20:20Chousukeor well, it depends :P
20:21Chousukebut your mod-intern is generating names like equalifier did too, so it's got the same problem.
20:22Chousukethough if the intent is to generate a programming API from a map of dependencies and other stuff, then it's fine I guess.
20:23ChousukeI'm just wondering where you'd use something like that.
20:24cadswell you could create a html module that takes a string module as a parameter, and then lets you parse strings of that type
20:25Chousukestrings of what type?
20:25Chousukehtml type? :/
20:28cadsno, say you have a string module that lets you define ascii strings over sequences of an arbitrary datatype, and you've defined the ascii strings over sequences of braille charachters. Well now you get all the string processing functions you can do on ascii, only the modifications work to produce the braille equivalent. And, with your spiffy html module, you can now parse html represented as braille :P
20:28cadshahaha, forgive me if the example is less than motivating, that's all pretty goofy :)
20:29Chousukeso hm, you could just map a braille->string function over your braille seq. :/
20:30hiredman~functions
20:30clojurebotfunctions are maps
20:30ChousukeI guess I get the basic gist of it.
20:31Chousukeyou want to parametrise a set of operations on some function that can have different output based on what the function is.
20:32Chousukeand then perhaps define a module that depends on such a set of operations
20:32cadsI think the concept of namespace should be doing this for us
20:33cadsbut I'm not sure
20:33Chousukewell, it could.
20:33Chousukeyou could define the set of operations differently in different namespaces
20:34Chousukeand import them with an :as directive in the "user" namespace
20:34cadsimporting could involve passing the imported namespace some parameters and it instantiating some of its features
20:34Chousukeinstantiating how?
20:35cadswell it messes up with compiled code
20:35Chousuketrue; you wouldn't be able to use multiple modules simultaneously
20:36Chousukebut that problem will remain if you generate names, too
20:36Chousukeor it'll just be transformed :P
20:36cadshm
20:37cadsI think the idea would be parametric namespaces, where different parts of the program can refer to different configurations of the same namespace
20:38cadseach different configuration relying on different values of the namespace's set of parameters
20:39Chousukeyou could do it this way: model your module as a function; then from the user namespace, pass a configuration map to the module function, and hold onto whatever it returns; the returned thing would be some data structure containing anonymous functions and data that can be accessed with some functions *operating on the data structure* (ie, not global, generated names)
20:39Chousukethen you could have as many modules and configuration combinations as you want.
20:39cadsand do all sorts of crazy stuff
20:39hiredmanChousuke: function could just return a namespace
20:40Chousukehiredman: indeed it could!
20:40cadscould a function return a namespace?
20:40Chousukethough, is that referentially transparent :P
20:40cadsor would it just define the namespace?
20:40hiredmanof course
20:40hiredmanChousuke: nope
20:40Chousuke,(create-ns 'foo)
20:40clojurebot#<Namespace foo>
20:40Chousukethere :P
20:40hiredmanactually
20:41Chousuke,(in-ns 'foo)
20:41clojurebot#<Namespace foo>
20:41hiredmanhmmm
20:41Chousukethe problem now is, that the namespace definition is global
20:41Chousukeand you want to avoid that.
20:41hiredmandoes he?
20:41cadsin part yes and in part no
20:41cadsI think modelling a module as a function is great, because that's what it is
20:41Chousukealso how do you get a value from a namespace?
20:42cadsi can compose those functions in a monad and operate on them in other ways
20:42hiredman,(find-var 'clojure.core 'map)
20:42clojurebotjava.lang.IllegalArgumentException: Wrong number of args passed to: core$find-var
20:42hiredmanbah
20:42cadsbut then I want to realize what I've created into a namespace, so that I can program with the generated module
20:42Chousukecads: the equalifier thingy returning a map of keywords to functions is a simple example of what I described.
20:43Chousukecads: equalifier is the module and the function is the parameter
20:43cadsChousuke: yup :)
20:43cadsand the realization part is a simple enough macro to write
20:43cp2,(doc find-var)
20:43clojurebot"([sym]); Returns the global var named by the namespace-qualified symbol, or nil if no var with that name."
20:44cp2,(find-var 'clojure.core/map)
20:44clojurebot#'clojure.core/map
20:44cp2e
20:44cp2r
20:45cadsChousuke: I think it would be pretty easy to create a fairly clean module system this way
20:45Chousukehmm
20:45hiredman,(find-var (ns-resolve (create-ns 'clojure.core) 'map))
20:45clojurebotjava.lang.ClassCastException: clojure.lang.Var cannot be cast to clojure.lang.Symbol
20:45hiredmanbah
20:46Chousuke,(#'eval `(~(symbol "def") ~'foo 1))
20:46clojurebotDENIED
20:46Chousukedamn!
20:46Chousukeoh, right, it gets expanded into (var eval) so it's picked up ;(
20:47Chousuke,((find-var 'clojure.core/eval) `(~(symbol "def") ~'foo 1))
20:47clojurebot#'sandbox/foo
20:47Chousuke,foo
20:47clojurebot1
20:47Chousuke\o/
20:48hiredman,(intern *ns* foo 1)
20:48clojurebotjava.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.Symbol
20:48cadsI know that I could use it in many different places, for example in my vector space library, I'd like to create vector spaces parameterized over different linear data structures, such as strings of words, or polynomial equations. The exciting thing about this approach is that I can automate not only the constructions of the secondary vector space functions like vector magnitude or projection
20:48hiredman,(intern *ns* 'foo 1)
20:48clojurebot#'sandbox/foo
20:48hiredmanbut don't spread it around
20:48Chousukeoh right, that works too...
20:49cadsI can also automatically generate test code that will test to see if the basis functions I've defined for my vector space are consistent with the definitions of a vector space
20:49Chousukeoh well, you can still only define things.
20:49Chousukethe rest of the sandbox is still functional
20:50hiredmanyou could use the exception thing to DoS
20:50Chousukeclojure is too dynamic ;(
20:51Chousukethe JVM security model is not enough for it.
20:53Chousukethough I wonder if anythign is.
21:14Drakesonhow do you (list \a \b) -> "ab" ?
21:14hiredman,(apply str '(\a \b))
21:14clojurebot"ab"
21:15Drakesonthanks.
21:15Drakesonwhy can't we do (into "" ...) ?
21:16hiredmanstrings are not Collections
21:16hiredmanthe seq function just happens to know how to turn them into sequences
21:17hiredmanand first, rest, etc call seq on their argument first
21:17DrakesonI see, thanks.
21:18hiredmanalthough, I wouldn't mind into being inhanced to do that
21:20Drakesonyeah, that would be useful
21:24mrsolowhy does this work? (:2 {:2 3})
21:24hiredmankeywords are IFns
21:24hiredmanthey look themselves up in a map
21:24hiredman(:i {:i 2})
21:24hiredman,(:i {:i 2})
21:24clojurebot2
21:25hiredman,(:i {:j 2} 3)
21:25clojurebot3
21:25Chousukea map also is a functions of its keys
21:25Chousuke-s
21:25hiredman,(ifn? {})
21:25clojurebottrue
21:25hiredman,(ifn? :foo)
21:25clojurebottrue
21:27mrsoloifns?
21:27Chousuke,(map ifn? [[], #{}, {}, 'symbol, :keyword]) ; anything else
21:27clojurebot(true true true true true)
21:27cp2think you got it all
21:27cp2er
21:27cp2struct maps
21:28Chouser ,(map ifn? [[], #{}, {}, 'symbol, :keyword, #(), (fn [])])
21:28Chousukethose are maps
21:28Chouseryou forgot functions
21:28Chouser:-)
21:28cp2yeah i figured
21:28Chousukemrsolo: IFn is hte interface that an object must implement to be usable in operator position
21:28ChousukeChouser: omitted those as obvious; guess it isn't.
21:28Chousernaw, you're probably right.
21:29mrsoloah ha.. jedi mind trick... thanks :-)
21:29mrsolohandy :-)
21:29Chousukemrsolo: the only exceptions are special forms and macros (user-defined special forms!)
21:32mrsolookay
21:32Chousuke,(ifn? ->) ; macros are a bit weird anyway
21:32clojurebotjava.lang.Exception: Can't take value of a macro: #'clojure.core/->
21:32hiredman,(ifn? #'->)
21:32clojurebottrue
21:32Chouseroh, vars.
21:33Chousukehiredman: that's a var, not a macro, though.
21:33Chouser,(ifn? #'proxy)
21:33clojurebottrue
21:34hiredman,(#'-> x foo)
21:34clojurebotjava.lang.Exception: Unable to resolve symbol: x in this context
21:34hiredman,(#'-> 'x 'foo)
21:34clojurebot(foo x)
21:34Chousukethe #'foo syntax gives you a nice way to cheat with macros like that.
21:34hiredman,(#'-> 'x 'foo 'baz 'bleep)
21:34clojurebot(clojure.core/-> (clojure.core/-> x foo) baz bleep)
21:34hiredmanhmm
21:34Chousukeit runs the macro function as usual but doesn't eval the result
21:35Chousukehm, nice sunrise
21:36Chousukeinsomnia has its benefits sometimes ;(
21:36hiredman,(binding [-> (vary-meta #'-> assoc :macro false)] (-> 'a 'b 'c 'd))
21:36clojurebotjava.lang.ClassCastException: clojure.lang.Var cannot be cast to clojure.lang.IObj
21:37Chousuke~source defmacro
21:37Chouserwouldn't work anyway, I think. The compiler would expand -> before the binding was set
21:38hiredmanI rebind doc in clojurebot somehow
21:39Chousuke,foo
21:39clojurebot1
21:40Chouser,(alter-meta! #'-> dissoc :macro)
21:40clojurebot{:ns #<Namespace clojure.core>, :name ->, :file "clojure/core.clj", :line 1017, :arglists ([x form] [x form & more]), :doc "Threads the expr through the forms. Inserts x as the\n second item in the first form, making a list of it if it is not a\n list already. If there are more forms, inserts the first form as the\n second item in second form, etc."}
21:40Chouser,(-> 'a 'b)
21:40clojurebot(b a)
21:40Chouser,(alter-meta! #'-> assoc :macro true)
21:40clojurebot{:macro true, :ns #<Namespace clojure.core>, :name ->, :file "clojure/core.clj", :line 1017, :arglists ([x form] [x form & more]), :doc "Threads the expr through the forms. Inserts x as the\n second item in the first form, making a list of it if it is not a\n list already. If there are more forms, inserts the first form as the\n second item in second form, etc."}
21:40Chouser,(-> 'a 'b)
21:40clojurebot(quote a)
21:41Chousuke,(.setMacro #'->); should work too I guess
21:41clojurebotnil
21:42Chousuke,(intern-ns 'my+ +)
21:42clojurebotjava.lang.Exception: Unable to resolve symbol: intern-ns in this context
21:42Chousukehm
21:43Chousukeoh well, time to go
21:43Chousukelater
21:43Chouser,(ns-intern 'my+ +)
21:43clojurebotjava.lang.Exception: Unable to resolve symbol: ns-intern in this context
21:45Chouser,*ns*
21:45clojurebot#<Namespace sandbox>
21:45Chouser,(intern 'sandbox 'my+ +)
21:45clojurebot#'sandbox/my+
21:45Chouser,(my+ 5 10)
21:45clojurebot15
21:50eeehi
21:50eeereduce is my hammer right now, but I'm not sure it is right
21:50eeei need to loop through a set
21:51eeeand update several data structures at the same time
21:51eeeconditionally
21:51eeethat's cake in python. totally confusing to me in clojure
21:51eeeanyone got advice?
21:51eeethanks
21:52hiredmansure, reduce is for that
21:52eeeone unsatisfying way would be with three reduce commands that each have the same logic
21:52Chouserif you're doing more than one thing per iteration, you might find loop/recure less confusing.
21:52Chouseris there any reason not to iterate multiple times?
21:52eeethe check is the same
21:53eeefor each item that p is true
21:53eeedo these three things
21:53Chouserput the check in a fn?
21:53eeewhy go through list and retest three times?
21:53Chouserhm. sure.
21:53eeeloop recur hmmm
21:53eeethat could work
21:54eeecan loop recur's be nested?
21:54hiredman,(reduce #(if (zero? (mod %2 2)) (update-in % [:evens] inc) (update-in % [:odds] inc))) {:evens 0 :odds 0} (range 20))
21:54clojurebotjava.lang.IllegalArgumentException: Wrong number of args passed to: core$reduce
21:54hiredmanbah
21:54dnolen(defn yr-fn [thing] (if (p? thing) (-> thing (step1) (step2) (step3)) thing)
21:54dnolen(map yr-fn yr-set)
21:55eeei'm trying to understand
21:56eeei've been avoiding that arrow
21:56dnolen,(-> 4 (+ 1) (* 2))
21:56clojurebot10
21:56dnolenit's not that scary ;)
21:56eeeit is
21:57eeei'm trying to figure out how to apply that to my problem
21:57eeei'll write it in pseudocode
21:57hiredman,(reduce #(update-in % [(if (zero? (mod %2 2)) :evens :odds)] inc) {:evens 0 :odds 0} (range 1 20))
21:57clojurebot{:evens 9, :odds 10}
21:57dnolenmight not apply, the other solutions might be better. just my interpretation.
21:58eeethose wierd faces make it hard to read :(
21:59eeei can cutn paste to an editor
21:59eeeahh now I can see it
21:59hiredmanyou might want to get a real irc client
22:00eeenever found a free one for mac
22:00hiredman~google free mac irc client
22:00clojurebotFirst, out of 219000 results is:
22:00clojurebotMacintosh Chat Clients
22:00clojurebothttp://www.irchelp.org/irchelp/mac/
22:01hiredmanI would just install irssi
22:01eeednolen are those step 1 step 2 step 3 things each reduces?
22:01dnolenno they are just whatever update steps you want
22:02eeei think the other solution is what i have to do
22:02eeebut maybe I don't get it
22:02eeei need to say
22:03eeeif current distance plus length less than previous length:
22:03eeechange value in heap
22:03eeeand
22:03eeeupdate "distances"
22:03eeeand
22:04eeechange path to go from current node to new node
22:04eeeand do that for each node
22:04eeein a set
22:04eeeso three data structures need to be mutated, really
22:04eeeeasiest way would be to use atoms or something
22:05hiredmannah
22:05eeebut what hiredman wrote looks possible
22:05hiredmanor you can use loop/recur
22:05eeei don't get the syntax yet
22:06eeewhy that if is in square brackets
22:06hiredmanoh
22:06hiredmanthat is just for update-in
22:06hiredman(update-in {:foo 1} [:foo] inc)
22:06hiredman,(update-in {:foo 1} [:foo] inc)
22:06clojurebot{:foo 2}
22:06hiredman,(update-in {:foo {:bar 1}} [:foo :bar] inc)
22:06clojurebot{:foo {:bar 2}}
22:07eeeok
22:09eee ,(reduce #(conj %1 %2) #{} {:evens 0 :odds 0} (range 1 20))
22:09hiredmanthat won't work
22:09hiredmanreduce takes 2 or 3 args
22:09eee,(reduce #(conj %1 %2) #{} {:evens 0 :odds 0} (range 1 20))
22:09clojurebotjava.lang.IllegalArgumentException: Wrong number of args passed to: core$reduce
22:10hiredmannot 4
22:10eeeso loop recur can be nested in loop recur?
22:10eeei may try that
22:11hiredmanyeah
22:11eeethanks
22:12eeethen when I am done with the loop recur because I am out of elements, return a list of the three structures
22:12eeethen destrcuture
22:12eeeinsane
22:15eeeoh, now I understand dnolen
22:15eeethe function does one element for each structure
22:15eeethen I map it to the "foreach"
22:16eeebut can I do it without the arrow ....
22:18dnoleneee: loop/recur sounds like a better fit for what you are trying to accomplish.
22:18dnolenthe arrow isn't magical, just a macro that converts the expression to normal form.
22:18eeethen return the three structures in a list? then destructure?
22:18eeei can't switch back to normal form while learn all these parenthesis
22:18dnolen(-> 4 (+ 1) (* 2)) becomes (* (+ 1 4) 2)
22:19dnolenoops
22:19eeeyeah, let's stick to the second
22:19dnolen(-> 4 (+ 1) (* 2)) becomes (* (+ 4 1) 2)
22:19dnoleni mean
22:19eeesecond is much clearer to me
22:20eeeanyway, so i need to return a list to get my three structures, right? ... from the loop-recure
22:20eee-e
22:21dnolenyes that's one way to do it, or return a map, whatever feel most natural.
22:21eeeoh, I see
22:22eeethis function is looking insane right now
22:22eee40 lines long
22:22eeeand probably 50 more to go
22:22eeethanks for the help
22:23eeei'll try that. it's kinda cool to feel like I'm starting over learning how to program
22:24hiredmansounds like it's time to break the function up
22:39danlarkinyeah definitely
22:41eee,(let [[a b & c] (range 3 9)])
22:41clojurebotnil
22:41eee,(let [[a b & c] (range 3 9)] a)
22:41clojurebot3
23:23danlarkinnot a big deal, but maybe this error message should be the same:
23:24danlarkin,(hash-map 1 2 3)
23:24clojurebotjava.lang.IllegalArgumentException: No value supplied for key: 3
23:24danlarkin,(array-map 1 2 3)
23:24clojurebot3
23:24danlarkinumm weird
23:26hiredmanarray-maps are fast and loose
23:26danlarkinlocally I get an error
23:27danlarkinjava.lang.ArrayIndexOutOfBoundsException
23:27hiredmanit is undefined bahaviour
23:37danlarkin,(nth {1 2 3 4} 1)
23:37clojurebotjava.lang.UnsupportedOperationException: nth not supported on this type: PersistentArrayMap
23:37danlarkin,(first {1 2 3 4})
23:37clojurebot[1 2]
23:38danlarkinwhy is this
23:39hiredmannth operates on seqs
23:39hiredmanfirst calls seq on its arg
23:39danlarkinis it because it'd be suboptimal to call seq on nth's argument in every case?
23:40danlarkinwhy doesn't nth call seq just like first calls seq
23:41hiredmanwell, maps are not ordered, so taking the 3rd thing doesn't make sensesnse
23:41hiredmanbut, yeah, first works
23:42danlarkinarray-maps are ordered
23:42danlarkinplus if taking the 3rd thing doesn't make sense then taking the first thing doesn't make sense :)
23:42danlarkinplus fnext will work, etc