#clojure logs

2008-11-04

00:00sohailmy java knowledge is showing... under what situations does -Djava.library.path=/foo not work but export LD_LIBRARY_PATH=/foo work?
00:03sohailhm, being banned from ##java doesn't help me solve this problem either
00:23albinoheh
00:24sohailso if I have a.b.c(foo,bar) in Java, what is the cleanest way to write it in Clojure?
00:25albinoIs c an instance of a class?
00:31sohailalbino, no a function
03:34lashhow do i join together a sequence of strings? like php's implode(), python's string.join, etc
03:38hoecklash: (apply str '("foo" "bar" "baz"))
03:40lashcool. how would i add a space between each one?
03:44hoecklash: then i would simply use print-str instead of str
03:44hoecklike (apply print-str '("foo" "bar" "baz"))
03:46lashyes, that's a nice way
03:49tWipor you could (apply str (interleave ["foo" "bar" "baz"]) (repeat " ")))
03:49tWipminus one )
03:49hoecktWip: (butlast (interleave ...
03:50hoeckhad the same idea :)
03:50tWipyeah, that to remove the unnecessary last space
03:52tWip (reduce #(str %1 " " %2) ["foo" "bar" "baz"])
03:52tWipwill work also
04:10lashhttp://pastebin.com/d1a0d4590 is this a good use for macros? is it correct? seems to work at least :p
04:13jdzlash: that macro is wrong
04:13jdzlash: and yes, that's a case when a macro should be used\
04:15jdzlash: if you used 'when' instead of 'if' then you'd be ok.
04:21hoeckjdz: are you shure? (if condition expr) works in clojure
04:21jdzhoeck: but there can be more than one expr, right?
04:22hoeckah, i see, sorry
04:23hoecki first thought you that macro is wrong because of the if only having a "then" clause
04:23hoeckbut its the missing do around body (which the "when" implies)
04:24hoeckr/you/you mean
04:24lashjdz: well, then you'd use "do", right?
04:24lashthat's how i figured
04:25lashand with this i get something like unless with an else ;)
04:26jdzlash: building on existing code has many benefits: your code is smaller, you remove code duplication, somebody else smarter than you might have got it right, and you have less ways to get it wrong.
04:27lashyes
04:27jdzlash: writing more code just because you can is a wrong attitude, imo.
04:29lashis it really wrong that my if has the same behaviour as an inverse if?
04:29lashs/my if/my unless/
04:30jdzlash: if has two branches, so it already is an inverse of itself depending on the ordering of then/else expressions.
04:30lashyep
04:31jdzand there are 'when' and 'unless' in common lisp already, which have defined semantics...
04:31lashdid not know :)
04:31lashthat's the best argument i suppose
04:31jdzfirst rule of good software design: somebody somewhere has already writted what you have in mind :)
04:32lashyeah, that's why i was suprised to not find unless in clojure already
04:32lashi haven't used common lisp before
04:32jdzi avoid using it because i always have to pause for a minute or so to figure out what exactly is happening. especially if the condition contains an 'and' or 'or'
04:33hoecklash: its called when-not
04:33lashi mainly wrote it because i wanted to try to write a macro
04:34hoeckjdz: yeah, i have the same problems with unless, i prefer the verbosity of (if (not )) in this case
04:34jdzhoeck: and i just switch the then/else expressions :)
04:35jdzor sometimes just make it so that the shorter expression comes in the then spot
04:35jdzif the other is relatively long
04:36jdzlash: i hope you learned the lesson that getting macros right is a bit harder than just ordinary functions because you must foresee all the uses of it.
04:40lashjdz: yes
08:29jkantzin common lisp I would do (find-if 'evenp '(1 2 3 4)) ... what's the idiomatic thing to do in clojure?
08:29Chouserthat returns true as soon as it finds one?
08:30duck1123jkantz: I believe filter is what you're looking for
08:30AWizzArdChouser: yes
08:30AWizzArd==> 2
08:30AWizzArdfilter is in Common Lisp remove-if
08:30Chouserhm. (first (filter even? [1 2 3 4]))
08:31jkantzok that works for me
08:31jkantzb/c filter returns a lazy sequence
08:33Chouserjkantz: right
08:34Chouserfewer built in functions is a goodthing
08:37AWizzArdthe (first (filter ..)) approach is a bit more "chatty" vs (find-if even? [1 2 3 4]), but also more flexible.
08:42duck1123you could always write find-if to wrap that up if you find yourself doing it a lot.
08:43duck1123you could even do a (first-even [1 2 3 4])
08:45gnuvincewhat does FIND-IF do?
08:45gnuvinceReturns true or false if an element is even?
08:46Chousergnuvince: apparently it returns the first element for which the pred is true.
08:46gnuvinceah
08:46gnuvinceIf it had only returned true or false, `some� would've been appropriate.
08:47Chouseryep
08:52jdzthere are some, every, notevery and notany in common lisp, too
08:56Carkhey there ... i come with a question
08:56Carkusing slime (widows) i can't seem to make the gui examples work
08:56Carkit just hangs
08:56Carkwhile it works from the *inferior-lisp*
08:57Carkany idea on how to fix this ?
09:01hoeckCark: have you any examples?, just opening swing frames (using cgrands wonderful javadoc) works here (slime + w2k)
09:03Carki just copy pasted the temperatur converter example at in a file http://en.wikibooks.org/wiki/Clojure_Programming
09:03Carkthen (require 'my-file)
09:05Carki also tried doing this manually ... you know : import the java classes, then create and setVisible a frame from the repl
09:07hoecksometimes java windows just don't appear for the first time, or they are hidden behind all other windows
09:08Carkit's not behind a window ... i checked that =)
09:09Carkbut yes, once i do it from the *inferior-lisp* it works under slime-repl
09:09Carkjust can't do it from slime first or it will lock it
09:09hoeckwell, maybe its hidden in other obscure ways
09:09Carkbtw i tried the cgrand javadoc and same thing
09:14Carkthat wouldn't prevent slime's next prompt to show up
09:14hoeckright
09:23SnowBuddyis it not possible to run a .clj file without pasting into the REPL, or am I just incompetent? ;)
09:24gnuvinceSnowBuddy: it is possible
09:24gnuvinceSnowBuddy: java -cp clojure.jar clojure.lang.Script foo.clj
09:25Carkor (load-file "my-file.clj") from the repl
09:33SnowBuddyhmm, ClassNotFoundException when I try running it through clojure.lang.script. i think i just don't understand how this stuff is supposed to work
09:33Carkuppercase S in clojure.lang.Script ?
09:34hoeckCark: i just tried to open a swing frame on windows vista with slime+xemacs+jdk6_10 without any problems except the window doesn't appear on top the first time its opened
09:34SnowBuddywith or without uppercase S, same result
09:34Carkhoeck : there must be some problem with my slime installation ... i'll just open it first from the inferior-lisp
09:34Carkthanks anyways
09:42abrooksclojure-spec looks like a nice example+test mechanism: http://www.bitbucket.org/BestFriendChris/clojure-spec/wiki/Home
09:42ChouserSnowBuddy: you can get a repl, though?
09:43SnowBuddyChouser: yep, everything works fine interactively
09:43ChouserSnowBuddy: what if you just add a filename at the end of the command-line you use to start the repl?
09:44SnowBuddysame thing, class not found exception on clojure.lang.Repl instead of clojure.lang.Script
09:45Chouserbut it must be finding the class when you don't provide a .clj
09:45Chousercan you paste your whole command-line and the whole stack trace?
09:46Chouserat http://paste.lisp.org/new/clojure
09:47lisppaste8SnowBuddy pasted "Error running script" at http://paste.lisp.org/display/69696
09:48lisppaste8Chouser annotated #69696 with "try this instead" at http://paste.lisp.org/display/69696#1
09:51SnowBuddyChouser: no errors now, but nothing seems to happen. it pauses for a moment and then goes back to the command prompt
10:12ChouserSnowBuddy: well, what does scratch.txt do? is it supposed to print anything?
10:19SnowBuddythat's it. i wasn't doing anything that would show an effect ^_^
10:21Chouseri had exactly the same "problem" when I started.
11:03kib2hi, did someone here played with the Processing backend ?
11:04Lau_of_DKHi guys
11:05Chouserhi
11:05duck1123hey Lau_of_DK
11:40sohailany of you guys ever see 2 prints with the same output when you only expected one?
11:41tomppawith SLIME?
11:41sohailtomppa, yes
11:42jdzsohail: are you sure they are both prints? one of them might be the return value of the expression you evaluated.
11:42sohailjdz, pretty sure because this isn't the last statement in the function
11:43tomppaat least some older versions of clojure-slime evaled expressions twice
11:43sohailtomppa, ok I don't think that is my problem
11:43tomppabut I think it has been fixed in the latest versions
11:43sohailwell might as well do an update anyway
12:21fyuryukib2: I played with it
13:05tomppawhat is the right way to build paths and filenames in Java? I'd need to have a list of paths and
13:06tomppathen go through them and find if a specific file exists in one of them
13:06tomppaI guess the paths would be URLs
13:06Carkthere is the File class i think for that
13:07leafwChouser: I can't get your pasted jambi example to work
13:07leafwChouser: http://paste.lisp.org/display/69450
13:07tomppaCark, I found it, thanks
13:08leafwChouser: two errors: first, the *command-line-args* may be null (easy to solve)
13:08Chouserah, sorry.
13:08Carktomppa : all-files (. (new File base-path) (listFiles))
13:08leafwChouser: second, the .ui file: I made a simple .ui file in the qt designer, but I get this error on the clojure side: com.trolltech.qt.designer.QUiLoaderException: Unsupported language: '', expected 'jambi'
13:08leafwChouser: should one specify somewhere this "language" option?
13:09leafwChouser: in the designer, I mean.
13:09Chouserleafw: yeah, I don't know what that's about, but that's why I have the comment in there about editing the .ui file manually
13:09leafwChouser: oops, should read better myself, thanks.
13:10Chousersomeone who knows jambi better should find the "right" way to set the language.
13:10leafwChouser: ok, that's a small problem, there must be an option among the gazilions somewhere in the designer app.
13:12leafwalso fails for silly things like unsupported properties such as Qt::LeftToRight enum for a QMenu widget ... weird
13:12leafwbecause that's the default
13:14leafwalso, I had to explicitly add the LD_LIBRARY_PATH to /usr/lib/jni ... or jambi .so files could not be found.
13:15leafwChouser: (doc into-array) claims to accept only one argument
13:15leafwChouser: but your example used (into-array String *command-line-args*), which fails.
13:20Chouserleafw: maybe I have a newerversion of clojure?
13:21Chousersorry,my space key is failing today.
13:21leafwnp
13:42lau_Has anybody here got the JLine functionality working in Emacs ?
13:44leafwChouser: also, strangely enough, I can't run the example from the interpreter (gets an exception). But when pasted line by line, it works.
13:44Chouserweird. let me try it again
13:44leafwI mean, from a file as in (load-file "/path/to/file.clj")
13:46Chouseroh! ok.
13:47Chouserworks fine for me, with main.clj on the command line or with load-file
13:48leafwweird
13:48ChouserI'm using latest svn clojure -- doesn't seem to have a problem with an empty *command-line-args* either.
13:48leafwalso, from the interpreter, if I quit the application and then just run it again with (QApplication/exec), then the UI doesn't show ... and the interpreter is locked. Lots of gotchas.
13:49Chouserproper use of Qt will, I think, require some special thread and/or repl setup.
13:50Chouserthe Qt gui functions must be run in the main thread, QApplication should only be exec'ed once, etc.
13:50Chouserthese are all well documented in Qt, but not quite as natural as swing.
13:51Chouser...although apparently swing stuff is supposed to be runin it's own thread as well, it's just not as enforcedas Qt's restriction.
13:51leafwI did Qt in c++ years ago, most faded ... but the native look in ubuntu of the gui is very appealing.
13:52leafwSwing does not enforce anything: one must run it all via SwingUtilities.invokeLater(new Runnable() { ...} )
13:52leafwwhich is a pain -- just so it gets executed in the queue of the EventDispatchThread.
13:52ChouserI'm a bit of a Qt fanboy for C++, but very much less so in Java, andeven less than that for Clojure.
13:53leafwSwing is a pain to build guis with --I've done many. Mostly manually, in the end.
13:53Lau_of_DKI think Qt can be used in a very limted scope in Clojure, but it definately has its purposes
13:55leafwunless jdk7 solves the non-native look of java apps, Qt-jambi-java has plenty of future with clojure, Lau_of_DK .
13:55ChouserFor me the upsides of Qt in Clojure would include very fast native libraries with good support forhardware accel., integrated opengl with accel, featureful gui designer, well-designed and beautiful-looking multi-language text support.
13:57Chouserdownsides: 3rd party lib, including platform-specific downloads, awkward thread requirements, some use of global state (QApplication, for example), and requirement to do have some direct clojure support to handle signals and slots fully and easily.
13:59leafwis there any clojure function to empty the current namespace?
13:59leafwi.e. forget all vars
14:00AWizzArdyes
14:00Lau_of_DKleafw, depends a little on how you look at it. The threading in QtJambi is not very intelligently designed. For instance when you start using slots and signals you'll find out that any fail will drop silently and QApplication will ignore it. That means that if all goes well, no problem, but if/when somethings breaks, you'll never know about it. I expect that for larger apps we'll see concurrency issues and the likes. This might all be fixed, but so far Q
14:00Lau_of_DKt is useful for good looking simple GUIs and such
14:01AWizzArdleafw: (ns-interns 'user) ==> map of all your bindings
14:01leafwwoah and now qt java segfaulted the VM ... when trying to re-run a QApplication.
14:01Chouserleafw: you could try: (doseq [n v] (ns-interns *ns*) (ns-unmap *ns* n))
14:01leafwthanks AWizzArd
14:01Chouserleafw: yeah, you can't do that.
14:01AWizzArd(ns-unmap 'namespace 'yourvar) ==> removes the var
14:02leafwthanks
14:02Chouserleafw: the "right way" to do qt would be to start a new repl prompt in another thread, allowing Qt to "own" the main thread so you don't need to re-run QApplication
14:02ChouserI think.
14:03leafwI see what you mean about requiring some clojure support from within
14:07leafwChouser: latest svn is what I have, from 6 days ago, and the (into-array String *command-line-args*) fails
14:07AWizzArdTo release all your vars you could do something like:
14:07AWizzArd(map #(ns-unmap 'user %) (keys (ns-interns 'user))) where 'user is your namespace
14:08leafwthanks AWizzArd, I figured that one out :)
14:08ChouserAWizzArd: you missed my post? :-) you'd have to watch out that "map" is lazy.
14:08AWizzArdChouser: I just saw it when scrolling back *sigh*
14:08AWizzArdmaybe I need more sleep
14:09ChouserAWizzArd: thanks for ns-interns, though. I only knew of ns-publics which would have been insufficient.
14:09AWizzArdChouser: btw, good explanation in the GG about Stuarts code with his (map identity map) thing
14:10ChouserAWizzArd: thanks!
14:10Chouserthat was a tricky one
14:30AWizzArdabout what "Clojure actors" is Rich talking in posting 4 here? http://groups.google.com/group/clojure/browse_frm/thread/2a2b24ffef5d1631/f4c4cdf44d00f70c?tvc=1
14:31Chouserthat's old!
14:31AWizzArdyes
14:31Chouserthey're called "agents" now
14:32AWizzArdso with idle actors he means: threads in a threadpool, yes? (not running)
14:33Chouserno, an agent that is not running doesn't have a thread
14:35Chouserwhen you send an action to an agent (using"send"), the agent either gets a thread from the pool or gets queued up for when a thread is available.
14:44AWizzArdSo what does he mean with having millions of agents ideling around?
14:45Chouseran agent is an object. It holds onto a state value. You can have millions of those idle
14:45AWizzArdoh okay, sure
14:46Chouserif you want to change an agent's state value, you send it an action, at which point the action executes on a thread or gets queued up to do so in the future.
14:47AWizzArdYes, this I fully understand. I was just mislead to think about Erlang having tens of thousands of processes running at the same time, and so came to the idea of threads.
14:48AWizzArdSo conceptually Rich just had a collection of some million objects in memory. In this case it were agents, but it could have been numbers as well
14:48Chouserright. I think partof why Clojure uses the word agent is to remind us they're not quite like erlang actors.
14:48AWizzArdyes
14:49ChouserAWizzArd: sure, but agents are not just numbersof course, they have their own semantics. Specifically they manage mutability.
14:49AWizzArdyes, I just wanted to express that it is IMO nothing spectecular of them in a col
14:50AWizzArdIt would be nice if they were actually running on a 10mio-Core cpu ;-)
14:50Chouserwell, if you had that many cores and that much work to do,they would.
14:51AWizzArdIn fact, I could probably easily get billions of those systems to 100% load for my problems
14:51Chouserit's not in itself "impressive" that he's got amillion of them, but when you're designing a solution in some frameworks you'd use athread instead of an agent.
14:52AWizzArdbtw, to have millions of them one has to start java with a respective heap size I guess
14:52Chouserhaving a million threads may not work well, even if they're idle. so by providing agents, clojure lets you deal with a useful abstraction that allows millions.
14:54Lau_of_DKkotarak, good evening
14:54AWizzArdDoes java offer some constructs that allow me to fine tune the priority of threads? Maybe I want that some agents get very much cpu time, while others are really not important at all
14:54kotarakhi Lau_of_DK
14:54AWizzArdMoin kota :-)
14:54ChouserAWizzArd: I've no idea. I don't really know Java well.
15:10rapidoquestion: immutable data OK. But is it possible to have immutable functions/code? (or immutable curried functions)
15:11rapidoif code is data and data is immutable - why not?
15:11wwmorganrapido: functions are immutable
15:13wwmorganeg. (partial + 2) returns a new function and doesn't change +
15:13rapidowwmorgan: good example
15:14rapidowwmorgan: but the top level environment is mutable
15:14rapidothe definition of + is mutable
15:14AWizzArdit would be even better if we had currying, so we could say $(+ 2) instead
15:15wwmorganrapido: not quite. The name + can be changed to refer to a different function (or any value), but if you did (def plus +) and then (def + -) then (plus 2 2) would still be 4
15:16rapidowhat does (+ 2 2) mean without an definition of +?
15:16rapidothe environment is implicit
15:17rapidoto get absolute immutability, the environment should be made explicit in the context of every expression.
15:18AWizzArdrapido: what do you mean by that?
15:18wwmorgansince the underlying functions aren't changing, functions are immutable. I think you're suggesting that it shouldn't be possible to change the value of vars
15:19Chouserclojure isn't tryingto get absolute immutability.
15:20ChouserI think clojure's aiming for minimal and well-managed mutability.
15:21gnuvinceQuick announcement: because of my incapability at composing a decent blog post in French, I'll be writing my draft in English and I'll translate to French afterwards. Again, if some people are interested in proof-reading, I'll be posting the link to a draft in the coming days.
15:21rapidoChouser: yes, i know - i'm just theorizing about immutable environments, together with immutable expressions and immutable data :)
15:23AWizzArdrapido: Clojure is a dynamic system. We *want* it to be changable. Only during programming in the repl, or later for administration you would overwrite existing bindings with a (def ...)
15:24rapidonaively, immutable code can be achieved with namespaces + version numbers
15:24Chouserrapido: sounds like a poor man's monad.
15:24rapidoi want to refer to a specific piece of code that is immutable
15:24AWizzArdAnd only there those cases it should happen that you overwrite something. You *could* do it anytime, but you *should* not.
15:25AWizzArdrapido: just store that piece of code in a collection
15:25AWizzArdand collect code pieces there
15:26rapidoAWizzArd: when i 'overwrite' code i want a new immutable version (just like clojure data)
15:27rapidothat maximally shares code 'structure' with the 'overwritten' version
15:28wwmorganrapido: clojure is a compiled language. Once that code is read in, the S-expressions are no longer retained
15:28rapidoit's just an idea
15:29rapidowwmorgan: i know s-expressions
15:29danlarkinclojure code _is_ immutable
15:29kib2gnuvince : I can help in French if you want to
15:29danlarkinremember code is data
15:29AWizzArdrapido: put the function into a hashmap on which you have a ref and do not use defn instead
15:30AWizzArdor write a macro that puts the functions into a defn for nice usability, but also adds it to a copy of the collection
15:30gnuvincekib2: the words just don't come as easily in French as in English when I write about programming. I'll just get something down in English and do the translation afterward.
15:30kib2gnuvince : as you want, I suppose it's better for all that you write in English.
15:31Chouserfunctions are just another data object. In fact, some data objects are also functions. Thus they can be stored in any of the ways other clojure data is stored: immutably in locals, or in the mutable objects var, ref, or agent
15:31rapidodanlarkin: what about redefinitions in the top level environment?
15:32gnuvincekib2: I still intend to post the final draft in French: I have not seen any mention of Clojure on any French web site or blog or forum. I would like to stir the interest of the French programmers just a little bit.
15:32danlarkinrapido: that isn't changing code, it's just changing where the variable points to. The old function still exists unchanged (until it gets GCed of course)
15:33kib2gnuvince : good idea indeed. I saw you were in 'Developpez!' forum, that may be a good idea to start from there.
15:33gnuvincekib2: that's where I want to start.
15:33gnuvincekib2: post something in the Java and Functional Programming sections and see if anyone seems interested.
15:33rapidodanlarkin: true - but doesn't that change the definition of all the 'immutable' code that refers to that variable?
15:34gnuvince(I'm guessing I'll have more success in the Lisp forum)
15:34AWizzArdrapido: you can look at some example code here: http://paste.lisp.org/display/69638
15:35AWizzArdthere you will have a basic macro that you could use for making your own, to define functions but keeping their sources
15:35wwmorganlisppaste8: url
15:35lisppaste8To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.
15:35danlarkinrapido: clojure is dynamic, so if I get passed a variable called foo, I'm not getting passed a pointer to a memory location, I'm basically getting passed a name that resolves at runtime
15:35kib2gnuvince : yes, I think there will be some interest from the FP forum, I don't know about the Java one (and in fact I don't know anything about Java yet) .
15:36Chouserdanlarkin: umm... I'm not sure that's quite right.
15:36rapidodanlarkin: ok, so it's essentially about variables, not about immutable code/data whatever
15:36danlarkinChouser: isn't it?
15:36rapidovariables that are resolved at runtime defy immutability
15:37Chouser(let [foo (Object.)] (my-fn foo)) ; in this case my-fn is passed essentially a pointer to the Object I created.
15:37wwmorganrapido: the canonical example is "today". "today" is a name that refers to the current date. The date that it refers to changes
15:37Chousermy-fn doesn't have any way of know it was in any way related to something called "foo"
15:38rapidowould it be feasible to make clojure's environment immutable?
15:38AWizzArdrapido: just offer your own version of def
15:38AWizzArdwrite a macro for that.. it won't allow redefinition
15:39AWizzArdthen you would say (defconstant ...) instead of (def ...)
15:39AWizzArdThe thing is: you *should* treat (def ..) as if it were a constant
15:39Chouserrapido: if A calls B and I create a new version of B, you want A to continue to behave the old way?
15:39AWizzArdIn principle you can use def as you use = in Java
15:40rapidocouldn't redefinition copy the old environment to a new environment with the redefinition?
15:40AWizzArdthis was explicitly not wanted
15:40AWizzArdin static systems like Haskell or ML it works like that
15:41AWizzArdin their repl you can define a function foo, then bar which calls foo and then redifne foo. Bar will still call the first foo.
15:41AWizzArdClojure explicitly does not want this. It is a dynamic system.
15:41AWizzArdFor administrative tasks you want to be able to override code.
15:42rapidoChouser: yes, i want A to explicitly bind to the new B instead of impliticly
15:42AWizzArdThis will allow you to fix bugs in a running computer program without restarting it.
15:42AWizzArdIt is regarded as bad style to overwrite functions outside of the repl and you should never do this in principle.
15:43AWizzArdBut in Lisp you log in to the computer of your customer and while his program is running you integrate a compiled version of the function that is now patched.
15:43rapidoAWizzArd: I understand the practicality of implicit redefinitions - but i work for a bank :)
15:43AWizzArdWhile you have your customer on the telephone and talk with him you will fix his bug.
15:44Chouserrapido: how would you accomplish explicitly re-binding A? Provide the code for it again, so the reference to B could be resolved to thelatest version?
15:44AWizzArdrapido: then simply store your functions inside a ref.
15:44AWizzArdIn a ref on a vector or map I mean
15:44rapidoChouser: A shouldn't be bound to B in the first place
15:44AWizzArdwhenever you first touch (get-the-right-one-out-of @your-functions) it will continue to support that version.
15:45lisppaste8danlarkin pasted "immutable code/data" at http://paste.lisp.org/display/69712
15:45AWizzArdthis is MCC, Clojures Multiversion Concurrency Control system
15:45rapidoif A refers to B this should be resolved against a specific version of the environment
15:46rapidoi mean: A shouldn't be bound to a specific version of B
15:46lisppaste8wwmorgan pasted "IOW, rapdio: this is NOT what you want" at http://paste.lisp.org/display/69713
15:46Chouserrapido: I'm not following you -- that sounds like the opposite of what you were asking for before.
15:48rapidoenv1 -> (A -> B B) (B -> 1)
15:48rapidoooops
15:48rapidoenv1 -> (A=B B) (B=1)
15:49rapidodamn it: smileys get in the way
15:49AWizzArdI see no smileys
15:50Chouserme neither
15:50rapidoenv1 = (A=B B, B=1)
15:50rapidoenv2 = (A=B B, B=2)
15:50rapidoenv1 and env2 share the defintion of A
15:50rapidoenv1 and env2 differ in the definition of B
15:50AWizzArdyes, you want the same thing that ML or OCaml are doing
15:51rapidobut ML nor OCaml shares (immutable) structure between env1 and env2
15:52AWizzArdWell, you got some suggestions how to solve this in Clojure. It's now your choise what you will do
15:53AWizzArdchoice even
15:55rapidoAWizzArd: thanks - i'm going to try your suggestion: the redefinition of def
15:56wwmorganrapido: you actually can't redefine def, because it's a special form
15:56Chouserrapido: note that clojure hash-maps have specifically the sharing of common entries that you seem to desire for the "environment"
15:56AWizzArdbut in your own namespace you can offer a new version of def
15:56AWizzArdor call it defconstant
15:58rapidoAWizzArd: let me try to hack it - and see if i can achieve it in plain clojure (no java source hacking)
15:59duck1123is it possible to set up some sort of security policy where re-definition would not be allowed?
15:59AWizzArdsure, this is possible
15:59duck1123you would ruin the power of the repl, but that's what you get
16:00AWizzArdIt's against the Clojure way to solve thins and more MLs way of doing it. But with some macros you can integrate that behaviour into Clojure as well and let it seem more natural.
16:01rapidogot to run, later...
16:02duck1123truthfully, if you lock it down properly, someone who has access to the repl, probably has access to do other nasty things to the system anyway.
16:04AWizzArdyes
16:04AWizzArdseems there is no 100% safety
16:04Chouserclojure doesn't have features to protect against malicious code
16:04Chouseryou can switch to the clojure namespace and wreak havok
16:05AWizzArdin the real world you are not supposed to drive into trees with your car, but in principle you *could* do it
16:05AWizzArd(probably not very often though, if you are not really slow)
16:05Chouserbut it's pretty good about helping you avoid doing bad things.
16:09AWizzArdWhy does (take 8 fac) result in a stackoverflow for (def fac (lazy-cat [1 2 6 24 120] [(* (last fac) (inc (count fac)))])) ?
16:09AWizzArdat the same time I can (def fac [1 2 6 24 120]) and in the repl repeat (def fac (assoc fac (count fac) (* (last fac) (inc (count fac))))) a few times without problems
16:12gnuvinceWouldn't it be easier to do: (def fact [x] (reduce * (range 1 (+ 1 x)))) (def facts (map fact (iterate inc 0))) ?
16:13wwmorganAWizzard: for the same reason that (def foo (lazy-cat [4] [(last foo)])) generates a stack overflow
16:13Hunthat's a pretty stupid algorithm. it throws away the precomputed factorials
16:16AWizzArdgnuvince: I was thinking about (def fibs (lazy-cat [0 1] (map + fibs (drop 1 fibs)))), so, doing it without defn
16:16wwmorganI think what you're looking for is (def facts (lazy-cat [1] (map * facts (iterate inc 1))))
16:17gnuvinceAWizzArd: ok.
16:18AWizzArdwwmorgan: why can fibs continue appending numbers to the vector although it does not produce an infinite sequence?
16:19wwmorganAWizzArd: because lazy-cat, map, and drop are lazy
16:19AWizzArdoh okay, drop is lazy too
16:20AWizzArddidn't look into its doc, sorry
16:38AWizzArdgnuvince: using a lazy sequence has the advantage of automatic memoization. So if (time (nth lazy-seq 10000)) takes 10 seconds, then (time (nth lazy-seq 10001)) will only take one msec. And every access between 0 and 10k will return immediate results
16:40AWizzArdBut you could also write a macro for memoization... (memoize my-function)... and from then on a call to my-function will return its result immediately when called with the same arguments as before.
16:40AWizzArdPeter Norvig showed this in 1990 in his book, which is btw one of the very best about programming in general
16:41Lau_of_DKTheres a memoize in Clojure.contrib
16:41AWizzArdgreat
16:41Lau_of_DKBut Wizkid, are you sure that lazy is auto memoized ?
16:41AWizzArdI wanted to suggest anyway to have that
16:42AWizzArdyes Lau, see: (def sum (lazy-cat [0] (map + sum (iterate inc 1)))) and then: (time (nth sum 80000)) needs 522 msecs for me. But (time (nth sum 81000)) is done within 24 msecs
16:42Lau_of_DKok cool
16:42Lau_of_DKI just noticed a tremendous slowdown as you parse further and further down the lazy seq
16:42Lau_of_DKSo much that I had to abandon that approach entirely for certain calculations
16:43AWizzArdand it comes with the disadvantage of eating up your ram
16:48AWizzArdLau_of_DK: do you have an example for the tremendous slowdown at hand?
16:48Lau_of_DKNo sorry Im on my Work PC atm
17:45AWizzArdis there something like (Math/pow ..) that returns BigDecimals?
17:46Lau_of_DK(.pow (Bigint %) %)
17:46Lau_of_DK(bigint, not Bigint)
17:48AWizzArdhmm, (Math/pow (bigint 3) (bigint (Math/pow 3 3))) ==> 7.625597484987E12 and not 7625597484987
17:48Lau_of_DK.pow
17:48Lau_of_DKuser=> (.pow (bigint 3) (.pow (bigint 3) 3))
17:48Lau_of_DK7625597484987
17:54Lau_of_DKAWizzArd, you got it?
17:58lisppaste8AWizzArd pasted "how to convert to bigints?" at http://paste.lisp.org/display/69721
17:59AWizzArdno Lau, I can't use .pow but only Math/pow instead
17:59AWizzArd.pow is unknown
18:00Lau_of_DKGet the latest version then
18:00AWizzArdI have the one from Oct. 29
18:01Lau_of_DKYou must have done something with the namespace
18:01Lau_of_DKIts standard
18:01Lau_of_DKAnyway, gotta hit the sack, as you saw, it worked on mine, which is the latest :)
18:01wwmorganmy guess, AWizzArd, is that you're not passing an int to pow
18:02AWizzArd(.pow 2 4) ==> java.lang.IllegalArgumentException: No matching method found: pow for class java.lang.Integer
18:03wwmorgan(.pow (bigint 2) 4)
18:06AWizzArdI see
18:06lisppaste8wwmorgan annotated #69721 with "another way to do it" at http://paste.lisp.org/display/69721#1
18:07wwmorganalthough I'm not quite sure what graham's number is so the math might be wrong
18:07wwmorganit sure grows fast, though
18:08AWizzArdwwmorgan: yes.. but this is even not grahams number
18:08AWizzArdfor x=4 it explodes already
18:08wwmorganis that right?
18:08AWizzArdyes
18:09AWizzArdAckermanns function is a bad joke in comparison ;-)
18:09wwmorganwell. That's not a very useful function then
18:09AWizzArdit is very useful
18:09AWizzArdit's used for a mathematical proof
18:10AWizzArdand it (Grahams Number) holds the record of being the biggest number ever used in a meaningful proof
18:10wwmorganI mean compared to (def grahams-number-test [3 27 7625597484987])
18:10AWizzArdah okay ;-)
18:27AWizzArdOT but funny: http://andrewsullivan.theatlantic.com/the_daily_dish/2008/11/a-different-rac.html
18:32AWizzArdAgain OT, but even funnier: a voting machine elected itself to be next president: http://www.theonion.com/content/node/89550 ;-)
18:32AWizzArdThere is definitly some AI around in these voting machines. Probably programmed in Clojure
20:01kwatfordBeta is out for Programming Clojure: http://www.pragprog.com/titles/shcloj/programming-clojure
20:03duck1123sweet
20:05gnuvince_yay!
20:06duck1123I wish I wasn't so broke right now, or I'd buy it now
20:08kwatfordIt does still have a bunch of empty chapters, so probably no need to rush
20:09Chouserkwatford: you bought it already, eh? pretty cool.
20:10kwatfordYeah, I've been itching to use my praprog coupon.
20:12Chousernice
20:13duck1123kwatford: how did you get a coupon?
20:15kwatfordPeople who have purchased books from them recently got coupons for their anniversary celebration.
20:42AWizzArdn8
20:58Drakesonhow do you serialize/pickle? python has cPickle.dump(...,fd). Is there an easy way to serialize into an XML or S-expr file, and also do the reverse?
21:02Chouserprn and read
21:03Drakesonis there a with-open-file?
21:04Chouserthere's a with-open
21:05Chouserbut it doesn't open a file, it just closes it at the end of the block
21:06DrakesonIs it what we should use when we open and close files (in addition to something that actually opens the file)?
21:07Chouseryep
21:08Drakesongood. thanks :)
21:08Chouserfiles, urls, sockets, anything with a .close method.
21:09kwatfordI believe it closes the object almost always, yes?
21:10Chouserit calls the .close method of whatever you've got.
21:11Drakesonis it possible to compile .clj's into bytecode?
21:11Chouserit's the only way it works. there is no interpreter
21:13kwatfordRight, but does it *guarantee* that it calls .close (in all reasonable situations)? The API page mentions a finally block, so I'm assuming it does.
21:13DrakesonI mean, can I get a compiled file/directory as a way to deployment on an inferior platform?
21:13Chouserkwatford: ah, yes.
21:13ChouserDrakeson: ah, to a .class file. Around here we call that AOT compilation, and it as of today: no
21:14Chouserbut it's in the works, should be available before too long.
21:14kwatfordDrakeson: You can produce a jar file with clojure and your cljs in it. Haven't tried it though.
21:16Drakesonkwatford: but the cljs need to be compiled on the inferior machine as well
21:17DrakesonWhat are the important options for a web application server? Are there many good ones?
21:17kwatfordDrakeson: That's ok, since you can put clojure in with them, and it is small. A stub main class can launch the script.
21:18ChouserDrakeson: yes. as of today, you can bundle up a .jar with everything you need, as long as the target has a "regular" JVM.
21:18Chouserbut if you need .class files to convert them to something else, for example to run on an Android phone, you can't do that without AOT
21:19sohailare there any android phones?
21:19kwatfordyes, the G1 from T-mobile
21:21sohailis it out?
21:21sohailcan I buy it?
21:21sohailcan I hack it?
21:21sohailseriously? I hate iPhone
21:21DrakesonI have to build the target myself. Is Jetty a good option?
21:22Drakeson(I have no idea what are popular/good java based web servers)
21:22kwatfordsohail: http://www.t-mobile.com/shop/phones/Cell-Phone-Detail.aspx?cell-phone=T-Mobile-G1-with-Google-Black
21:27RadioApeShotAnyone else using compojure?
21:27RadioApeShotOr have experience with jetty?
21:27albinoDrakeson: I have a friend who like Jetty and Tomcat both a lot
21:28duck1123RadioApeShot: I am using compojure
21:28RadioApeShotSo where should I put my stylesheets?
21:29RadioApeShotI can't seem to make my pages see them.
21:29duck1123do you read the mailing list
21:29RadioApeShotNot actively
21:29duck1123there was just recently a thread about this
21:29RadioApeShotI have searched (via google) for compojure and stylesheets
21:29RadioApeShotBut had no luck
21:30RadioApeShotCan you give me a link?
21:30duck1123http://groups.google.com/group/compojure/browse_thread/thread/c2dae4830ac04008
21:30RadioApeShotduck1123: Thanks.
21:30duck1123the method should be the same for stylesheets
21:33RadioApeShotExcellent
21:33RadioApeShotI will see if I can make it work
21:34duck1123np
21:36duck1123RadioApeShot: I don't know how much you've done, but have you been finding you need the request object in many of your page view fns?
21:36duck1123I'm trying to get support for making request/response thread-local, but my experience may be atypical
21:37RadioApeShotI haven't implemented very much yet
21:37RadioApeShotJust a very basic skeleton
21:37RadioApeShotI am not that experienced with the web.
21:37RadioApeShotI put together a rails app while back
21:37RadioApeShotBut that is about it
21:38RadioApeShotI am more of a scientist by trade.
21:38duck1123so far the only things I've really gotten done is basic CRUD operations, and OpenID authentication
21:39duck1123I only work on it when I have free time
21:39RadioApeShotI am not even sure what CRUD stands for
21:39RadioApeShotI have this super simple project I am doing more for fun than anything
21:39RadioApeShotI am really glad to have found Clojure
21:39duck1123Create Read Update Delete
21:40RadioApeShotI am pretty sure Clojure is a Lisp I will basically stick with from here out.
21:40RadioApeShotCommon Lisp is too old and crusty
21:43arohnerdo clojure maps implement java maps yet?
21:45Chouserarohner: yes
21:46Chousersince Oct 6
21:49arohnercool, thanks
21:49arohneris there any easy way to figure that out? I remember reading the discussion on the mailing list, but didn't remember if it ever made it in
21:50Chouserthe way I just did it was using git log and searching for "java.*map"
21:51duck1123isn't there a implements? type call in java?
21:51Chouserbut that was to get the date
21:52Chouser(supers (class {}))
21:52Chouseror for your specific question: ((supers (class {})) java.util.Map)
21:53Chouseror yes, (instance? java.util.Map {})
21:54arohnervery cool, thanks
22:25arohneris there a way to cast a java.util.Map that is a generic?
22:25arohneri.e. java.util.Map <String,Object>
22:25Chouserjust ignore the generic part. It'll work.
22:26arohnersorry, is there a way to pass a clojure map to a function that expects a Generic map?
22:26duck1123coerce ?
22:26Chouseryou shouldn't have to do anything special.
22:27Chouserjust make sure the actual keys in your clojure map are Strings, and you should be able to pass it right in.
22:28arohnerhrm. ok. maybe I'm doing something else wrong
22:28kwatfordAre you passing it in from the Clojure side or the Java side?
22:29arohneryeah, looks like I was doing something else stupid. misreading the javadocs of the API I was calling
22:29arohnerkwatford: I was creating a clojure map and trying to pass it to a java function
22:30kwatfordRight, but that doesn't tell me what language you're doing it from
22:33arohneroh, I was creating a clojure map literal in clojure
22:35kwatfordI assumed so, but having to juggle generics made me wonder
22:48wwmorga1is metadata attached to the Symbol or the Var?
22:49kwatfordto the object
22:53wwmorga1what about when you do (defn #^{:a :b} foo [] 1)
22:56kwatfordBoth the function and the symbol foo are objects, but it doesn't look like either of those have the metadata you're trying to put on.
22:57wwmorga1you have to do ^#'foo to get at it. Alternatively (meta (var foo))
22:57kwatfordah, right
22:58kwatfordin that case, it's on the function, not the var or the symbol
22:58wwmorga1So it looks like the metadata is attached to the Var, but the documentation says metadata is associated with symbols & collections only
22:58kwatfordI think
22:58kwatfordhmm, maybe not.
22:59wwmorga1it isn't attached to the function, else ^foo would work
22:59kwatfordyeah, gotta be the var then
22:59Chouserwhen you def a var and attach metadata, yes, it goes on the var
23:00wwmorga1that's what I thought, but this recent post on the google group has thrown me for a loop
23:00Chouser(def foo #^{:a :b} [])
23:00Chouserthat attaches to the val: ^foo
23:03sohailChouser, what is making you sad
23:03kwatfordhmm, should (def foo #^{:a :b} (fn [] 1)) put the metadata on the function?
23:04wwmorga1kwatford: functions can't have metadata. Only collections, and symbols and/or vars can
23:05wwmorga1I think I'm just going to have to wait for someone smarter than me to answer the question
23:05kwatfordAh. That explains why it didn't work the last time I wanted to do that, but why?
23:07wwmorga1that's a language design choice that I don't quite understand. I'm sure rhickey has explained it before
23:08kwatfordI wonder how non-helpful a search for "metadata on functions" on the list would be...
23:13Chousersohail: non-clojure, and therefore off topic. :-)
23:14sohailChouser, nonsense, if clojure can't save the world, there is no hope
23:14Chouser:-)
23:22arohnerone thing I find amusing and slightly annoying about working in clojure:
23:22arohnerI've found that using clojure to call the java API of some libraries is *less* verbose than their usual XML configuration
23:23arohnerexcept that the java guys all expect that you want to use the XML interface, so the programmatic way is usually poorer documented than the XML way