#clojure logs

2009-01-27

01:31Carkclojurebot: log?
01:31clojurebotlogs is http://clojure-log.n01se.net/
03:55AWizzArdMoin
03:55AWizzArdclojurebot: max people
03:55clojurebotmax people is 129
04:01ecret(ns app.hello (:gen-class)) (defn -main [& args] (println "application works")) I am trying to make a class in clojure. The file is hello and its in the app folder but I am unsure of how to tell clojure to start in the folder before the app folder. When I try to compile it gives me an error.
04:02ecretso my question is, how do I check and set the project folder where it looks for those classes?
04:12ayrnieuit's behaving oddly for me. I can (require 'app.hello) successfully, but (compile 'app.hello) yields java.io.IOException: No such file or directory (hello.clj:1) , which is not the "java.io.FileNotFoundException: Could not locate app/hello__init.class or app/hello.clj on classpath: (NO_SOURCE_FILE:0)" that you get when the file is legitimately not there.
04:13ecretyeah same
04:13ecreti need to know where to put the app/hello.clj file
04:14ecretor how to set the environment to the master path or at least check what it currently is
04:21AWizzArdAnd how do you try to compile?
04:22AWizzArdDid you set the right *compile-path*? As in: (binding [*compile-path* "/home/ecret/mystuff/"] (compile 'Hello))
04:22ayrnieuthe exception is thrown by clojure.lang.Compiler.writeClassFile , calling java.io.File.createNewFile ; probably it's trying to create the class files in a directory that you're expected to have set up
04:23ecret(compile 'app.hello)
04:23AWizzArd,*compile-path*
04:23AWizzArd,(print *compile-path*)
04:23ecretAWizzArd: i did not. Do I do this in clojure?
04:23clojurebotnil
04:23ayrnieuAWizzArd, http://clojure.org/compilation should emphasize this
04:23AWizzArdYes, check what is in *compile-path*
04:24ecret,(print *compile-path*) returns: classes
04:24clojurebotnil
04:24AWizzArd1-2 days after compilation was introduced to Clojure I also had the problem that I couldn't compile my .clj files, because I did not point to the directory into which the corresponding .class files should go to.
04:25AWizzArdwell, the comma is not needed in Clojure, it is just for the clojurebot in this channel, to run my forms.
04:26AWizzArdecret: try to set *compile-path* with (binding ..) to a path that is in your classpath.
04:29ecretAWizzArd: I did (binding [*compile-path* "/home/eli/nlp/csphinx/"] (compile 'junk.hello)) my path to the file is /home/eli/nlp/csphinx/junk/hello.clj, still doesnt work
04:30ecretis that what I should of done?
04:31ecretjava.io.FileNotFoundException: Could not locate junk/hello__init.class or junk/hello.clj on classpath: (NO_SOURCE_FILE:0)
04:31ecret [Thrown class clojure.lang.Compiler$CompilerException]
04:31ayrnieuhttp://paste.lisp.org/display/74340
04:31ayrnieuecret, you get that because it tries to load the class that it's just created, and *compile-path* isn't in your CLASSPATH
04:37AWizzArdecret: do (System/getProperty "java.class.path") in your repl
04:38ecrettried that ,heres a jar file : /home/eli/clojure/classpaths/RM1_8gau_13dCep_16k_40mel_130Hz_6800Hz.jar
04:38ecreti copy pasted the folder into /home/eli/clojure/classpaths/csphinx/junk/hello.clj
04:40AWizzArdYou should have /home/eli/clojure/classes/ in your CP (create that dir if it does not exist yet), and /home/eli/nlp/csphinx/ as well in CP.
04:40AWizzArdThen you can bind the *compile-path* to the .../classes/ dir and compile 'junk.hellp
04:40AWizzArdhello even
04:40ecretin my .emacs file, swank-clojure-extra-classpaths (directory-files (concat concourse-dir "clojure/classpaths/"
04:42AWizzArdDid you decide into which directory the .class files should go that result from compiling .clj files?
04:42AWizzArdThis could be for example /home/eli/clojure/classes/
04:43AWizzArdAs soon you decided which dir will be the target, put that into your classpath (for example by adding it to your swank-clojure-extra-classpaths).
04:44AWizzArdNow inside a possibly completely different directory create a subdir "junk". Into that put your hello.clj which begins with (ns 'junk.hello ...)
04:45AWizzArdAnd put the dir in which you created junk also into your CP. Then you can compile.
04:49ecretAWizzArd: i am hesitant to change my .emacs file since I had a rough time getting it to work in the first place with the jar classpaths. How would I change swank-clojure-extra-classpaths (directory-files (concat concourse-dir "clojure/classpaths/") t ".jar$") to have the classes folder?
04:50AWizzArdmake a copy of your .emacs file to which you could go back any time
04:55AWizzArdecret: here is an example of how your .emacs file could begin: http://nopaste.ch/9869fa857c1cbef.html
04:58ecretAWizzArd,ayrnieu thanks for the help.
06:00Lau_of_DKGents, regex question
06:00Lau_of_DK(re-find #"\b[Author: +]\b.*" "Author: Jack Daniels <jd@drink.org>")
06:00Lau_of_DKI want to extract only "Jack Daniels <jd@drink.org>" How do I do ?
06:04Lau_of_DK(re-find #"\b[Author: ]\b+.*" "Author: Jack Daniels <jd@drink.org>")
06:04Lau_of_DK" Daniels <jd@drink.org>"
06:04Lau_of_DKThis is a little closer, but it misses Jack
06:17holly(re-find #"(Author:\s+)(.*)" "Author: Jack Daniels <jd@drink.org>")
06:17holly3rd element is the desired one...
06:20hollyWith (re-find #"(?>Author:\s+)(.*)" "Author: Jack Daniels <jd@drink.org>") it's the second...
06:21rfgpfeiffer(re-matches #"Author:\s+(.*)$" "Author: Jack Daniels <jd@drink.org>")
06:24cgrandholly: what's the difference between ?: and ?>
06:37hollyThat I have only just learned about ?> but not yet about ?:
06:37hollyhttp://www.regular-expressions.info/atomic.html is what I looked at
06:40hollyhttp://www.regular-expressions.info/brackets.html seems to indicate that ?: does the same as ?>
06:42hollyHmmm. Not quite maybe -- ?> seems to be like the cut from Prolog -- throws away all backtracking info from withing that group. For this regecp that shouldn't make a difference -- we want the greedy behaviour.
06:42hollyCompare (re-matches #"(?>Author:\s+)( .*)" "Author: Jack Daniels <jd@drink.org>") with (re-matches #"(?:Author:\s+)( .*)" "Author: Jack Daniels <jd@drink.org>")
06:43holly(note that now we want to match one space in front of "Jack" -- with ?> we don't find this as it first greedily matched all spaces and then couldn't backtrack
06:44cgrandholly: thanks I didn't know of ?> and the javadoc for Pattern left me nonplussed
06:46holly:-) There are obviously advantages to being a Java newbie and not knowing about javado
06:46cgrandI understand now ?> is as greedy as possible even if it causes the rest of the regex to fail: you can't backtrack -- that's what they meant by "independent"
06:48hollyYou cannot backtrack *into* that group -- it can still backtrack to *before* that group
06:51cgrandindeed, thanks for the clarification!
06:54Lau_of_DKholly, I was out to lunch, thanks alot for helping out
06:55hollyNP -- glad I can add something here instead of just lurking
06:57Lau_of_DKIt was a big help - I fail at regex almost every time :|
07:21rfgpfeiffer(comp) should be identity
07:21rfgpfeiffer,((comp) 3)
07:21clojurebotjava.lang.NullPointerException
07:25AWizzArdno, but it could perhaps throw an exception instead
07:30rfgpfeifferit would be consistent with + and *
07:34AWizzArdThose are defined as such
07:34AWizzArdempty sum and multiplication
07:36cgrandin the same vein (-> x) should expand to x
07:41AWizzArdBut what should (->) do? ;-)
07:44cgrandthinking more about it: identity is only the neutral element for unary functions not for all function -- comp is indeed irregular: its rightmost arg can be any function but other args have to be unary functions
07:46AWizzArdI still would like to have the functional equivalent to ->, namely (defn pipe [& fs] (apply comp (reverse fs)))
07:47AWizzArd,(defn pipe [& fs] (apply comp (reverse fs)))
07:47clojurebotDENIED
07:47rfgpfeifferfixed versions: http://gist.github.com/53325
07:49rfgpfeiffercgrand: I have a composition function for n-ary fns: http://gist.github.com/51768 before-advice
10:54scottjWhat is an xrel and a rel?
10:54Chouserscottj: where are you seeing those?
10:55scottjChouser: clojure.set/index
10:56scottjThat only references xrel, but the function above it, rename, references both
11:10cgrandscottj: it seems that a rel is a set of key-values (N:N) while xrel is a map (N:1)
11:11cgrandcgrand: forget what I said
11:12Chousersuddenly
12:09knapranyone with an example of a gui using JFileChooser?
12:11jwinterThis has a JFileChooser (I just saw it today): http://github.com/ynd/mona-clojure/blob/master/mona-clojure.clj
12:16cgrandwow: you can try clj libs without even downloading them!
12:16cgrand(add-classpath "http://github.com/Lau-of-DK/clojureql/raw/master/src/&quot;)
12:16cgrand(require '[dk.bestinclass.clojureql :as ql])
12:16Chouserah, sweet.
12:17rhickeythat's neat
12:17cgrandchouser: if there is a proper directory structure (didn't work with textjure)
12:18cooldude127that's awesome!
12:18Chouserthat also means you get the latest version each time your run. ...I hope you trust that URL.
12:18Chousercgrand: yeah, textjure is just a "script", not a lib.
12:18rhickeyChouser: well, he'd never put add-classpath in his app, right?
12:19danlarkinwow that is a really really neat trick
12:19Chouserhm, can't use URLs on the -cp command line, I guess.
12:19knaprlol thats supersweet
12:22cgrandIf you are unlucky I guess you could get an inconsistent snapshot
12:48knaprwhat is textjure?
12:48drewrknapr: Clojmacs.
12:51danlarkinshame that validator-fns are supposed to be side effect free
12:51danlarkinI'd feel bad giving mine side effects
12:51knaprsun.awt.shell.Win32ShellFolder2 cannot be cast to java.lang.String
12:51danlarkinso I must find a different way
12:53knaprclojmacs? you mean clojure-mode for emacs?
13:01knaprare GUIs naturally statefula nd using globals is normal? or is that just becuas eim using Swing which anturally is a OO-oriented framework?
13:01knapri used Tkinter with python and before seem to force the use of globals
13:06Chouserknapr: GUIs are indeed stateful, but don't necessarily need globals.
13:06cooldude127knapr: look at some of the haskell gui libraries to see how they are trying to unstateful guis
13:06cooldude127it's hard to wrap your head around, i know i don't get it
13:07Chouseri guess you can try to pretend it's not stateful, but the thing you're looking at on the screen sure seems like it's a "state"
13:08cooldude127it is, but it can be represented functionally, it's just really confusing
13:09danlarkinit's a gui monad! *boggle*
13:09cooldude127yeah maybe it would have made more sense if i could actually understand macros
13:09cooldude127s/macros/monads
13:11nymsyhello
13:11danlarkinnymsy: hello!
13:11cooldude127nymsy: hi
13:14knaprdamn collision betwen paths, FileChooser uses \ and I use / , why is windows so stupid?
13:17nymsyso, I might loose connection... I'm in afghanistan, using a nokia phone for internet.. over a... maybe a 5 kbps link (little k)
13:18nymsyThought I'd swing through irc and see how it was... webpages take forev' but this seems to work decent
13:18Chousernymsy: interesting!
13:19nymsyChouser: yea, makes for some interesting stress testing
13:20noidia newbie question: what's the difference between a list and a vector? after some googling I gather that the former's a linked list while the latter is an array of references...
13:20nymsySo, I've been in transit for about 2 weeks, on my way out for a deployment in A-stan, and I've been working on a clojure app, to kill time while I wait
13:21Chousernoidi: there are a couple differences. lists grow on the left, vectors grow on the right (when you conj)
13:21hiredmanvectors are indexed (like an array)
13:21hiredman,([:a :b :c] 1)
13:21clojurebot:b
13:22hiredman,(get [:a :b :c] 1)
13:22clojurebot:b
13:22Chousernoidi: vectors provide constant-time random access to any element (by index) while lists can only be scanned in linear time
13:22WizardofWestmarcuse vector when you want ~0(1) access time to any element in the list.
13:22hiredman,((list :a :b :c) 0)
13:22clojurebotjava.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.IFn
13:22hiredman:(
13:22noidithanks!
13:23nymsySo, I'm going to go off and open up my code and get back here and ask some of the questions I've been burning to ask for 2 weeks... :)
13:23Chousernymsy: and you have it running on your phone, right?
13:27cooldude127wow lists really don't implement IFn?
13:27cooldude127i guess that's to encourage you to use vectors for those situations
13:27hiredmanyes
13:30noidi,"testing"
13:30noididarn :)
13:30nymsyChouser: clojure or the internet?
13:30noidi,([:a :b :c] 1)
13:30clojurebot:b
13:30Chousernoidi: clojurebot ignores you unless there are parens
13:30noidi,(identity "testing")
13:30clojurebot"testing"
13:30Chousernymsy: your clojure app runs on your phone, right? In fact, it's your IRC client? ;-)
13:30noidicool :)
13:34nymsyheheh.. actually.. you could say I'm writing a simplified irc app
13:34nymsybut no, this runs on my computer.. I'm tethering.
13:44nymsyFirst question: what are the ways to get a value from a set?
13:45nymsyI saw select
13:46Chouseryou can use 'get' or just treat the set as a fn.
13:46Chouser,(#{:a :b :c} :b)
13:46clojurebot:b
13:46Chouser,(#{:a :b :c} :d)
13:46clojurebotnil
13:46nymsythe comma.. is that clojure?
13:47Chouserno, that's clojurebot
13:47durka42commas are whitespace
13:47nymsyah
13:47Chouser, is whitespace in clojure
13:47durka42clojurebot evalutes lines beginning with commas
13:47nymsyrgr
13:47Chouser,#{:a,:b,:c}
13:47Chouser,(prn #{:a,:b,:c})
13:47clojurebot#{:a :b :c}
13:48nymsyyes, but why would I want to return :b from #{:a :b :c} if I already have :b? It's nice to know that it's there and all...
13:49nymsyI guess I'm wanting set to be more like a map
13:49nymsyWhereas, map already acts a little like a set, with unique keys
13:49Chousernymsy: perhaps I misunderstood your question. A set contains only "keys" if you will, no values. Or the keys *are* the values.
13:49danlarkingnuvince: s/language/state machine/
13:50nymsyChouser: right
13:50noidiwhy can't you use a map then?
13:51nymsylet me think of an example of what I'm trying to do
13:51noidi,({:key :value} :key)
13:51clojurebot:value
13:51nymsyby the way, does clojurebot have cycle turned off? ;)
13:52durka42you mean infinite loops?
13:52Chouser,(take 7 (cycle [:chicken :egg]))
13:52clojurebot(:chicken :egg :chicken :egg :chicken :egg :chicken)
13:53Chouserhe's got some protection against attempts at evilness.
13:54nymsyaye... so I've got a (def *clients* (ref #{}))
13:54nymsyfor my irc like chat program
13:55nymsy(this is, by the way, based off of somebody's code from the list)
13:56nymsyand client is a (defstruct client-t :socket :output :reader :nick :uid :last-action-time)
13:57Chouseryou want to be able to find the client struct from a given nick
13:57Chouser?
13:58nymsyyes, but nicks can change, so each :nick starts as a (agent "anonymous")
13:58nymsyso I have to do derefing while searching the #{}
13:58Chouseryeah
13:59knapranyone good with Java, swing and threads? When I play an mp3 it eats up all the "authority" of the app. apparently im messing with main event dispatch threa dor something
13:59Chouserit seems likely to me that the nicks should be refs instead of agents
14:01nymsyChouser: this is one area I'm lost in.. knowing when to use each of the mutability tools
14:01nymsyI've read the differences, but I don't yet understand what exactly is being described
14:02ChouserI don't have an extremely firm grasp on it myself...
14:02nymsyI've dealt a little with locking in Java, but I'm still a noob
14:03nymsywhat pastebin do you guys use?
14:03Chouserbut agents for for values that are independant of each other. The fact that the nicks are in a collection that is itself in a ref suggests to me that the *clients* collection and the nick values themselves need to be coordinated with each other.
14:03durka42clojurebot: paste?
14:03clojurebotlisppaste8, url
14:03lisppaste8To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.
14:03Chouser"agents are for values"...
14:04Chouserthe only coordinated reference type is the ref.
14:04nymsyOk, so a collection of refs inside of a ref is normal?
14:05Chousernymsy: it can be, though you could just have the top-level ref and swap out the whole collection when you update a nick
14:08nymsyI'm afraid that solution might get heavy, but I'm not sure if clojure optimizes for that... doesn't that copy all the clients and their sockets, readers, writers, etc?
14:08nymsyif the server became big, how big would that operation become?
14:09Chouserno, it doesn't. clojure collections share as much data as they can with earlier versions of themselves
14:09nymsyso a ref-set is as efficient as, say, an assoc inside of a ref?
14:09nymsy(erm, on a ref inside the ref)
14:11Lau_of_DKGood evening all
14:11nymsyok, watch out.. here comes some ugly code
14:12lisppaste8nymsy pasted "blah.clj" at http://paste.lisp.org/display/74360
14:13nymsymost of these functions are in transition, so they're ugly
14:13nymsyThe arity in most is accommodating either access to global state, or more pure function
14:14nymsyOne of my problems is the the filter-for and its sister function filt-for-deref.. cause I couldn't figure out how to get filter-for to do both
14:15ChouserI think that changing a item in a collection inside another collection inside a ref would be slower than if you had another ref at the lowest level, but only by a constant factor of the depth.
14:16Chouserthat is, the collections themselves could get many times larger without either solution becoming a whole lot slower.
14:17nymsyok
14:17noidiis anyone else here using VimClojure?
14:18Chouser(filter-for #(deref (:nick %)) "joe" *clients*)
14:19nymsyWhat if the value I'm looking for isnt a ref?
14:20Chouserthen leave out the 'deref' part as you already do.
14:21nymsyI want a general function to dip down into the nested collection I've created and sometimes grab the value of a normal value and sometimes grab the derefed value of a ref value
14:21Chousuke(doc get-in=)
14:21clojurebotexcusez-moi
14:22Chousuke(doc get-in)
14:22clojurebotreturns the value in a nested associative structure, where ks is a sequence of keys; arglists ([m ks])
14:22nymsyChousuke: works for maps inside of sets?
14:22Chouseroh. Well, I suppose you could add a phrase to filter-for: (if (instance? clojure.lang.IRef x) @x x)
14:23Chousukenymsy: hm, I don't think so.
14:23Chousukenymsy: since to get the map, you need to have the map already
14:23Chousuke,(get-in {:m [:a :b {:c :d}]} [:m 2 :c])
14:23clojurebot:d
14:23Chouserit probably does work on sets, but since you'd have to supply the whole value you're looking for, it would help much.
14:25nymsyif i'm looking for one nick in all the clients in a ref, I've been using for to go through every item in the set
14:25nymsyso I could get-in on the for
14:25Chousukemaybe you should index the clients by their nickname? :/
14:25Chousukea map of nicks to the client data
14:26Chouserbut he also sometimes looks them up by :uid, and the :nick can change.
14:26Chousukehmm
14:26nymsyright, sometimes
14:26Chousersets of maps may not be too terrible -- I can't quite decide what would do better.
14:27nymsyI guess get-in with for is useless, since I've already dug down
14:27Chouserit *might* make sense to maintain two maps -- one from uid to client-struct, the other from nick to client-struct.
14:27Chouserit would make lookups faster and more convenient
14:27Chouserpresumably uids don't change, so that'd be fine.
14:28nymsywould each collection point to the same set of objects?
14:28Chouserwhen you update a nick, though, you've have to fix up both maps. That might still be easier than what you're doing.
14:28Chousukeif the client struct is wrapped in a ref, keeping them in sync would be easy too
14:28Chousernymsy: either that, or the uid could be the "canonical" map, and you could have a separate map of nick to uid
14:29Chousukehm, that sounds better.
14:29Chousukecould have multiple nicknames that way, too :P
14:29nymsyaye
14:29nymsyhow would this seperate map work?
14:30Chousukejust (def nick-to-uid (ref {}))? :)
14:30ChouserI guess it'd be another global. *clients* would now be a map instead of a set, and you'd also have *nicks* which would look like {"joe" 123, "bob" 456}
14:30Chouserright, in a ref.
14:32nymsySo, to send bob a message, (*nicks* "bob") > 9833498 and then (send-message-to 9833498 "msg")
14:32nymsykinda deal
14:33Chouserright
14:33nymsyand maps ensure that there can only be one "bob" in *nicks* and only one uid in *uid*s
14:34Chouserstill faster and more convenient than walking the set of all clients looking for a "bob"
14:34nymsytrue
14:36nymsyI wonder if one could do a two-key-one-value map, where it was like {key-nick key-uid value, &}
14:36durka42i mean, you could emulate that with two maps, or a list of triplets
14:37Chouserwell, you can put the nick and uid in a vector, and use the vector as the key. ...but then you'd have to know both to look up anything.
14:37nymsywith performance comparable by a constant factor to normal maps...
14:38nymsywhat about {(or this that) value}
14:39Chouseryou could put the value in there twice: {key-nick value key-uid value}
14:39nymsyor {#(or (= % this) (= % that)) value}
14:40durka42,(first (filter #(or (= "bob" %1) (= "bob" %2)) {["alex" 134] :alex, ["bob" 532] :bob, ["joe 1395876] :joe}))
14:40clojurebotEval-in-box threw an exception:EOF while reading string
14:40durka42,(first (filter #(or (= "bob" %1) (= "bob" %2)) {["alex" 134] :alex, ["bob" 532] :bob, ["joe" 1395876] :joe}))
14:40clojurebotjava.lang.IllegalArgumentException: Wrong number of args passed to: sandbox$eval--802$fn
14:40durka42whoops
14:40durka42,(first (filter #(or (= "bob" %) (= "bob" %)) {["alex" 134] :alex, ["bob" 532] :bob, ["joe" 1395876] :joe}))
14:40clojurebotnil
14:40durka42i should test these things
14:40durka42,(first (filter #(or (= "bob" (first %)) (= "bob" (second %))) {["alex" 134] :alex, ["bob" 532] :bob, ["joe" 1395876] :joe}))
14:40clojurebotnil
14:40Chouseryes. you should. :-)
14:41nymsy*as freenode crashes*
14:41durka42,(second (first (filter #(or (= "bob" (first (first %))) (= "bob" (second (first %)))) {["alex" 134] :alex, ["bob" 532] :bob, ["joe" 1395876] :joe})))
14:41clojurebot:bob
14:42durka42,(second (first (filter #(or (= 134 (first (first %))) (= "bob" (second (first %)))) {["alex" 134] :alex, ["bob" 532] :bob, ["joe" 1395876] :joe})))
14:42clojurebotnil
14:42durka42never mind
14:42durka42that got way too unwieldy
14:42durka42don't do that
14:44nymsy,({#(or (= % "bob") (= % 111)) "socket"} "bob")
14:44clojurebotnil
14:44nymsyhmm
14:44Chouseryeah, that's not going to work.
14:44hiredmanwell when data structures get unweidly, you build new functions to wield them
14:45Chouser,({"bob" "socket" 111 "socket"} "bob")
14:45clojurebot"socket"
14:45Chouserjust as good, and actually works.
14:45nymsyrgr
14:45Chouser:-)
14:45nymsyis there a way to make both "socket"s point to the same socket?
14:46nymsyso as to mitigate doubling the actual size in memory?
14:46Chousukenymsy: just bind it to a name first and use that name as the value.
14:46Chousukeinstead of a literal
14:46WizardofWestmarcactually might the JVM be smart enough to not double use literals?
14:46Chousukeprobably, but that's not guaranteed.
14:46WizardofWestmarcshould be possible to find out
14:47nymsythey won't be literals in practice
14:47nymsyif by literals you mean those strings
14:47WizardofWestmarcright
14:47Chouserif you do (assoc *client* "bob" socket 111 socket), they'll both point to the same socket object
14:47Chouserit's not going to copy it.
14:47nymsythey'll be complicated structs
14:47Chousukenymsy: even better then: they won't be copied.
14:47Chousukeno assignment in java ever copies anything; except primitives.
14:48WizardofWestmarcChouser: what about :a "bob" :b "bob"?
14:48WizardofWestmarcdoes bob show up twice in memory?
14:48ChousukeWizardofWestmarc: that's probably an implementation detail
14:48nymsyhmm
14:48WizardofWestmarcit could be specified in the jvm specification
14:48Chouser,(apply identical? (map val {:a "bob" :b "bob"}))
14:48clojurebottrue
14:48WizardofWestmarcso that all VMs would require it
14:49Chouserbut I think Clojure is providing that and doesn't guarantee it.
14:49nymsyso where might this scheme cause a hicup?
14:49Chouser,(apply identical? (map val {:a (String. "bob") :b "bob"}))
14:49clojurebotfalse
14:49hiredman,(apply identical? (map val {:a (Object.) :b (Object .)})
14:49clojurebotEval-in-box threw an exception:EOF while reading
14:49hiredman,(apply identical? (map val {:a (Object.) :b (Object .)}))
14:49clojurebotjava.lang.Exception: Expecting var, but Object is mapped to class java.lang.Object
14:49hiredmanbah
14:50Chousukethe answer is going to be false :p
14:50hiredmanstrings are sort of magic
14:50hiredmanyeah
14:50Chousernymsy: if you want to change something in a socket struct, you'll have to do that double-assoc again.
14:50Chousukestrings are guaranteed to be immutable so the JVM can optimise literals to be the same object.
14:51ChouserChousuke: I think it's Clojure that's deciding to intern the strings. I don't think it's always done that.
14:51hiredmanclojurebot: max people?
14:51clojurebotmax people is 129
14:52Chousernymsy: while if you had *nicks* that only pointed to uids, then you'd only have to update *clients* for changes to client struct.
14:52Chousukeunless you use refs; like (def a (ref {:a 1})) (def b a), (dosync (commute a assoc :b 1)) @b ; -> {:a 1 :b 1}
14:52nymsyOk, better than socket, lets say (assoc *clients* "bob" client-struct-1 111 client-struct-1)
14:53Chousersorry, I meant "client struct" not "socket struct"
14:54nymsyoughtn't, if I make changes to client-struct-1, elsewhere, "bob" and 111 both point to the new client-struct-1 that reflects those changes?
14:54Chousukenymsy: no.
14:54Chouserbut if client-struct-1 is just a struct (and not a ref as Chousuke is suggesting) you can't actually change it. you can only make a new one based on the old one
14:54nymsyhmm.. associng "bob" to a new value will leave the old value attached to 111
14:55Chouser...in which case you have to put that new struct back into the map in all the appropriate places.
14:55Chousernymsy: right.
14:55Chousukenymsy: that's exactly how it's supposed to be.
14:55nymsyso (assoc *client* "bob" struct-ref 111 struct-ref)
14:56Chousukenymsy: that might work.
14:56hiredmanso you write a double-assoc fn
14:56Chousukebut I'd rather do two separate maps.
14:56Chousukeone with nicks to ids and one with id -> struct
14:56Chousukethen, whenever I want to "modify" a struct, I actually just do assoc-in on the id->struct map
14:57Chousukeyielding a new id->struct map
14:57hiredmanis there a reason why you need both? why not have nick or uid as part of the struct?
14:57hiredmanand the other as the key?
14:57Chousukehiredman: he needs to look them up using either.
14:57hiredman:(
14:58hiredmansounds like two maps then
14:58nymsyI could look them up as uids most of the time, and then scan the whole think when nicks are needed, or vice versa, which is what I'm doing now
14:59Chousukehaving two maps is easier IMO :/
14:59Chouserdo you ever need to go from uid to nick?
14:59nymsyWhen updating nick
14:59Chouseror only from (nick or uid) to struct
14:59Chousukebut having the nick and UID in the *same* map as keys pointing to a struct is wrong, IMO.
15:00Chousukebecause then you need to update both
15:00Chousukeor use refs, but that's a bit ugly too
15:00hiredman,(let [x (ref :somestruct)] [{111 x} {"bob" x}])
15:00clojurebot[{111 #<Ref clojure.lang.Ref@8730b8>} {"bob" #<Ref clojure.lang.Ref@8730b8>}]
15:01Chousukeyeah, that would work, but is rather ugly.
15:01hiredmanChousuke: if you don't println it, it won't see it :P
15:01nymsyWhys it ugly? I think it's pretty
15:01Chousukeyou'll have lots of refs though :/
15:04nymsyhere's another aspect of the program that needs consideration... a) it's going to be p2p.. each user will have server code, which synchronizes with all other user's servers, and distributes messages.. b) I still have to implement rooms
15:04hiredman!
15:05nymsya server can have more than one client hanging off of it, but the normal use case will be one gui client connected to the server code locally
15:05nymsyyes! :)
15:05nymsyso thats another ref for *rooms*
15:05nymsyand another for *servers*
15:07nymsyso how to manage nicks and uids is important
15:08nymsydo I map uids to rooms and servers, or nicks? probably uids
15:14fffejIf I have two functions A and B that both call each other, how should I declare them in a CLJ file such that I don't get a "unable to resolve symbol" error when I compile them?
15:14Chouser(doc declare)
15:14clojurebotdefs the supplied var names with no bindings, useful for making forward declarations.; arglists ([& names])
15:14fffejthanks!
15:14nymsyhmm. typo in the message struct. :dest and :room are the same. anyway, if a client sends text into a room, the client code puts the room name in :dest/:room. Then the server does a doseq on the room collection with .println to the :output of each
15:19nymsyOr I could add a :rooms key to the client struct
15:19hiredmanit might be easiest to have rooms as a special type of user
15:20Chouserso then a msg to a room would require walking the list of all clients, checking each to see if their in the target room?
15:20nymsyand pass *clients* to broadcast-to-room [clients msg]
15:20hiredmanso when a user sends to a :room user, it gets sent to all the other users that are talking to that room
15:20WizardofWestmarcthat or keep an updated list of users by room
15:21WizardofWestmarcso when they move room remove from old room add to the new room
15:22nymsyWizardofWestmarc: I'm thinking the server won't deal with context switching between rooms, only the client rendering code will, if you know what I mean
15:22WizardofWestmarcthen just write a macro to both change the structure's room # and update the room list's info
15:22WizardofWestmarceh
15:22WizardofWestmarcif you want to send info to specific rooms from the server I would keep that info server side as well
15:23nymsywell, a user can be in many rooms
15:23cooldude127i thought clojure-mode was fixed to work for imenu stuff, but i only get one symbol, a defstruct (because it's also used in CL)
15:23WizardofWestmarcah
15:23WizardofWestmarcstill
15:23WizardofWestmarcthen just remove the always remove constraint
15:23WizardofWestmarcbut I'd STILL keep a hash of rooms that contain a list of users in that room
15:24hiredmannymsy: someone, technomancy?, is doing some kind of clojure tutorial writing a muc, which might be interesting to look at
15:24nymsyright, thats the other option
15:24nymsyhiredman: wilco
15:25WizardofWestmarcyeah Technomancy's doing it
15:25WizardofWestmarcit's in his github acct
15:25hiredmanorly
15:25cooldude127ya rly
15:25cooldude127where is that guy anyway?
15:26hiredmanah http://github.com/technomancy/mire/tree/master
15:26nymsythat other option: a map of rooms to lists of users.. a map of servers to lists of users.. a map of nicks, to uids, and a map of uids to clients
15:27Chousernymsy: that strikes me as the most natural approach.
15:28nymsythe other option is to use a #{} with a client struct that has all of those specific key values, and just scan the set for those desired keys each time, passing the whole *clients* in to each function.. (which seems more functional, than maintaining all these globals.. though it seems less efficient)
15:28Chouseron the other hand, I'm curious about the possibility of having a set of maps (like you did originally) as the "canonical form" of everything. Then when something changes use clojure.set/index to recreate the various maps.
15:29nymsyclojure.set/index?
15:29hiredman,(doc clojure.set/index)
15:29clojurebot"([xrel ks]); Returns a map of the distinct values of ks in the xrel mapped to a set of the maps in xrel with the corresponding values of ks."
15:29hiredmanmine just exploded
15:29hiredmanmy head just exploded
15:29nymsyme too :)
15:29ChouserI've not written anything in that style, and I don't know how convenient or efficient that might be.
15:30durka42sounds similar to group-by
15:30nymsyI'd like, also, for this to be an example of doing distributed text chat in a functional way
15:30nymsyminimizing global state and maximizing the sharing of immutable messages
15:31hiredmanyou could do trees with zipper :P
15:31Chouseryikes
15:31nymsyChouser: I see the doc, but I don't really see it.. can you explain how indexing helps here?
15:33Chouserthe way we've desribed all these global maps suggests that any code that makes changes to them would have all the logic built in to go update each of the things that must be kept in sync.
15:33Chouserright?
15:33nymsyright...
15:33hiredman,(doc defonce)
15:33clojurebot"([name expr]); defs name to have the root value of the expr iff the named var has no root value, else expr is unevaluated"
15:33hiredmanno kidding
15:34Chouserlike an update-nick function would have to know to fix *nicks* and also go find the right client struct in *clients* and update the :nick value there.
15:34Chouserthat might be the most complicated one, which still isn't too terrible.
15:34nymsyexactly
15:35Chouserbut if there are more interconnected changes that have to be made, and more functions to make these changes, the possibility of a bug in one of them that gets things into a "wrong state" becomes more likely
15:36nymsyright.. that's what worries me about the copulating *maps*
15:36Chouserso one way to reduce that likelihood would be to store a canoncial state of things with no duplicate information, so that there can be no "bad" state.
15:36nymsyright
15:36Chouserso, for example, the layout you had at the beginning. a set of structs.
15:38Chouserthen anywhere that wants to make any change at all to the state of the world would start with that set, muck around with it until it reflects the new state of the world, and pass it to a single make-it-so fn
15:38nymsywhich is how it is now?
15:39Chousermake-it-so could then use clojure.set/index to compute new nick-to-client, uid-to-client, room-to-client, etc. maps, and in a dosync swap refs to point to this new state.
15:40nymsyoh... wow
15:40Chouserthat way all your lookups are still fast and convenient
15:40Chouserall the 'read' code would be quite simple, and even the 'update' code would be more simple than the alternative.
15:41nymsyhmm.. index attaches an index number to each item in the set? at the top level?
15:41Chouserthe downside (or one of them, I think) would be that make-it-so would be O(n) on clients. :-/
15:41Chousernymsy: ah, on, it pulls out a key from the set of maps, and makes a map to go from ...
15:42Chouserhang on...
15:44Chouser,(let [myset '#{{a 1 b 2} {a 3 b 4} {a 5 b 6}}, idx (set/index myset '[b])user=> (let [myset '#{{a 1 b 2} {a 3 b 4} {a 5 b 6}}, idx (set/index myset '[b])] (idx {'b 6}))
15:44clojurebotEval-in-box threw an exception:EOF while reading
15:44cooldude127someone has unbalanced parens :)
15:45cooldude127or just too much stuff copied
15:45Chousernasty paste error. sorry
15:45Chouser,(let [myset '#{{a 1 b 2} {a 3 b 4} {a 5 b 6}}, idx (set/index myset '[b])] (idx {'b 6}))
15:45clojurebot#{{b 6, a 5}}
15:45Lau_of_DKChouser: If you chat from ERC you get Lisp highlighting in your chat :)
15:45Chouserok, so there's your canonical set, "myset"
15:46nymsyrgr
15:46Chouserusing set/index gives me a map from
15:46Chouserfrom {b ..whatever..} to the whole struct
15:46knaprhttp://cpp.ninjacodemonkeys.org/5080 , is that starting the player before ti starts the thread and thus the player doesnt run in the thread?
15:47Chouserso then it's easy to look things up based on values of b
15:47Chouserbut I could just as easily produce as many indexes for as many different keys as I want.
15:48hiredmanknapr: you most likely want #(.play player)
15:48nymsyok.. so it kinda does better what my for-filter did.. return the map in which the given has a given key with a given value
15:48hiredmanknapr: unless (.play player) returns a Runnable
15:49Chousernymsy: right, very similar, but instead of doing a linear lookup each time you need something, this takes that linear hit once and returns a map that you can use for any number of lookups
15:49hiredmanThread. will take 0 or 1 arg, the one are being a function of no arguments
15:49Chouser...until someone changes rooms or nicks, and then you have to reproduce all the maps.
15:49hiredmanwhich #(.play player) will give you
15:50knaprhiredman: ok and then it is started when i start the thread?
15:50hiredmanyes
15:51nymsyChouser: here's my idea on world-view consistency... once someone hits the enter key on the keyboard, *clients* and msg become frozen for that msg
15:51knaprhiredman: thanks! that works.
15:51nymsyso I deref *clients* once for each message
15:52Chousernymsy: sounds reasonable.
15:52nymsythe rest of the pathway logic assumes that worldview.. so would it hurt to reindex on each message creation?
15:53Chousermight be more work than necessary, if multiple messages are sent between world state changes, which seems likely.
15:54hiredmanyou toggle a dirty bit when you dirty something
15:54ChouserI'm mostly uncomfortable with the O(n)'ness of the whole thing. Everything's going to slow down the more users you've got, even if they're only one person is talking to one other person.
15:54nymsywell, theres one key that updates often
15:55nymsythe new one that isn't used yet, :last-action-time ... which I thought I'd use to create a connection time-out facility
15:56BigTomHi
15:56nymsyhello
15:56drewrHas anyone had any problems using clojure.contrib.sql with postgres?
15:56BigTomI am doing something dumb
15:57nymsyChouser: how bad is O(n) ?
15:57BigTomI think
15:57Chousernymsy: double the number of users, double the processing time.
15:57BigTomI am getting a stack overflow on a recur but I cannot see why
15:57Chousernow the theorists are going to hang me, but that's the idea anyway.
15:57nymsyOh.. log(n) is the better one, right?
15:57Hunwhy? it's correct.
15:58Hunbut you should always look at the constants
15:58Chousernymsy: O(1) < O(log(n)) < O(n) < O(n*log(n)) < O(n*n) ...
15:58BigTomare there any common mistakes that do that?
15:58Hunwhen n are only your users, and you're thinking about people, O(n) might cut it
15:58hiredmanBigTom: lets see some code
15:58Chouserthose are the commone ones.
15:59Hunas the growing of population will sooner or later stop. usually before O(n) on it becomes a problem
15:59hiredmanHun: and people die
15:59ChouserHun: are you a theorist? Are you not hanging me!?
15:59HunChouser: computer science student, 7th semester
16:00BigTomhmm, hang on, I'm on two machines
16:00ChouserBigTom: i think we're going to have to see the code.
16:00Chouseroh, sorry, someone already asked.
16:00Huni've seen enough theorists forget to mention that you also have to look at the order of magnitude of n
16:00Hunhiredman: fewer than are born
16:00Hungrowth is still an exponential curve. that means it will sooner or later crash :)
16:00ChouserWell, I thought someone would complain that I said "processing time" instead of "complexity" or something.
16:00BigTomhow much can I post on here?
16:01ChouserBigTom: use lisppaste for more than 1 line
16:01hiredmanclojurebot: paste?
16:01clojurebotlisppaste8, url
16:01nymsyif you have to ask...
16:01lisppaste8To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.
16:02hiredmanclojurebot: what is the most horrible thing?
16:02clojurebotthe most horrible thing is http://themosthorriblething.com/index.php?h=my+algorithm+is+O%28n*n%29
16:02lisppaste8BigTom pasted "recur problem" at http://paste.lisp.org/display/74372
16:02nymsyso... since this is a "distributed" p2p chat room.. the mesh couldem have hundreds of rooms... but the user will only be in 1 to maybe 10 or th
16:02HunChouser: the complexity ain't gonna change
16:03Hunthat problem is intrinsically bound by O(n)
16:03Hunyou sooner or later have to see every entry in the relation user <=> room for doing a dispatch
16:03nymsynot all the time
16:04Hunso you can't get lower. you can just cut it for dispatching only on the current room
16:04Hunand if it's just O(n) for a single room, so be it
16:04nymsyonly users you see in rooms your in, at a constant rate.. for interactive consistency
16:04Hunthere are a lot bigger fish to fry until profiling
16:05AWizzArdI think it was on reddit where I read that until recently Clojure represented closures internally as anon Java classes. And those can't be garbage collected.
16:05AWizzArdDo I remember that correctly?
16:05nymsythose people you don't see, you don't need to interact with immediately.. so I could use other logic for trying to find a user, by nick, that is not in my main *clients* list, for example, right?
16:06ChouserAWizzArd: a compiled fn still is a Java class, but if created via 'eval' will now be GC'd
16:06HunAWizzArd: i think (not sure) that are the closure class, not the instance
16:07Hunso your code won't leak if you use closures in a loop, but memory consumption will be constantly sligthly higher
16:07knaprwhat I dont understnad is how to stop or pause the thread from executing. stop is deprecated. I tried interrupt but it doesnt do anything.
16:07knaprhiredman: do you know how to pause a thread?
16:07AWizzArdknapr: from outside of a thread you mean?
16:08hiredmanBigTom: I am not sure, but you may want to filter (rest ns) not ns
16:09AWizzArdknapr: check out http://java.sun.com/javase/6/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html
16:09AWizzArd"What should I use instead of Thread.stop?" is your question
16:09hiredmanknapr: I am bet the player has some sort of pause method, I would recommend using that instead of pausing the thread
16:10nymsyyea, I'm not overly worried about the O(n) of it. As long as *clients* doesn't list all clients in the web, just those in the rooms your connected to. I mean, on average, how many people do you see, if you add up all the people in all the rooms you're in on irc, on average?
16:10hiredmanAWizzArd: he is writting an mp3 player, and, having gotten it to play, he wants to get it to pause
16:10nymsy(I'm probably a less than average case)
16:11AWizzArdknapr: also think about Rich Hickeys "ants.clj" example, where he uses the variable *running* for signalling a stop.
16:11BigTomhiredman: Doh! Told you it was something stupid
16:11BigTomhiredman: thanks
16:11hiredmanthere are 647 people in #haskell
16:11hiredmanBigTom: did that fix it? I said I wasn't sure
16:11AWizzArdclojurebot: max people
16:11clojurebotmax people is 129
16:11nymsyyouch
16:12AWizzArdlet's not forget this number was around 80 a few months ago
16:12hiredmanclojurebot's max people was broken for a day or two
16:12Hunnymsy: about 1200, all channels i'm in combined. with about 200 collisions
16:12hiredmanso maybe it missed everyone
16:12BigTomhiredman: yes, still slow as hell, it was frustrating because this is where I am starting from
16:13nymsyHun.. Would you say you're average?
16:13nymsy(in terms of irc connectedness?)
16:13Hunnot really. considering irc, most people are way fewer
16:13BigTomah, spoke too soon, its just happening later on
16:13Hunbad english. most people are in fewer channels
16:13Hunat least those i know. i'd say about 400 might be a good average case
16:14BigTomhiredman: I put the whole thing up, it is breaking somewhere between 10,000 and 100,000
16:14Lau_of_DKIs the code on Sourceforge still current ?
16:15nymsyright... then people have their instant messaging going on.. so we'll say a liberal average is 500?.. so 500 clients.. say, 10 keys per client struct...
16:15AWizzArdhiredman: btw, does the clojurebot automatically deny all forms in which *compile-path* is used?
16:15AWizzArd,*compile-path*
16:15AWizzArd,(print *compile-path*)
16:15clojurebotnil
16:16nymsyany ninjas out there able to discern the complexity of an indexing operation on 500 clients with 10 keys?
16:16AWizzArdhmm, funny, some hours ago it responded with ,,denied"
16:16nymsyfor this particular situation?
16:16Hunnymsy: neglectable for now
16:16nymsyHun: I agree
16:16Hunyou'd have a hard time measuring it with 10000 test users
16:16BigTomShould you ever get StackOverflow with recur? if it is coded correctly?
16:17Hunshould be easy with 100000 users. get to that point before optimizing :)
16:17nymsyheh
16:18ChouserBigTom: the 'recur' itself can't be consuming any stack, but that something being done within each pass of the loop could indeed consume stack.
16:18nymsyanyone guestimate how long it would take to scan a set of 500 structs with 10 keys each?
16:18Chouserno need to guess.
16:18Hunnymsy: what do you mean by scan?
16:18hiredmannymsy: compared to the time to send/recv messages? none at all
16:19hiredmanby that I mean network io
16:19BigTomChouser: so something is hanging onto stack frames somewhere?
16:20hiredmanclojurebot: Sieve?
16:20clojurebotNo entiendo
16:20hiredmanclojurebot: google Genuine Sieve of Eratosthenes
16:20clojurebotFirst, out of 850 results is:
16:20clojurebotThe Genuine Sieve of Eratosthenes
16:20clojurebothttp://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf
16:21BigTomhiredman: is that for me?
16:22hiredmanBigTom: it may help
16:22BigTom:-)
16:22Chouser,(time (let [myset (reduce #(conj % {0 %2 1 0 2 0 3 0 4 0 5 0 6 0 7 0 8 0 9 0}) #{} (range 500)), idx (set/index myset [0])] (idx {0 99})))
16:22clojurebot#{{0 99, 1 0, 2 0, 3 0, 4 0, 5 0, 6 0, 7 0, 8 0, 9 0}}
16:22clojurebot"Elapsed time: 121.706 msecs"
16:22hiredmanI think the code is all in haskell, so it may just kill you
16:23BigTomah well
16:23Chouserone tenth of a second to create the set and all the maps from scratch, index them, and look up one of them.
16:23BigTomI knew I would have to have a proper go at it eventually
16:24BigTomIt can go on the pile with the pythagorean triples
16:25nymsywow
16:25nymsythats ninja right there
16:26Chouseryeah, clojure is definitely too fast. Rich should sneak in a spin delay somewhere so he can "add speed" later as needed.
16:27ecretAWizzArd: I am trying to compile hello.clj to try to get classes working in clojure. I have the file in /home/eli/clojure/classes/junk/hello.clj to compile it I go (binding [*compile-path* "/home/eli/clojure/classes/"] (compile 'junk.hello)) but this does not work. I get java.lang.Exception: namespace 'junk.hello' not found after loading '/junk/hello' (NO_SOURCE_FILE:0)
16:27ecret Any idea what is wrong? I did what yoou suggested, i added /home/eli/clojure/classes to my classpaths
16:30BigTomJust to clarify something, recur is not a total substitute for Tail call is it?
16:30Hunit isn't
16:30Huna tail call can call another function
16:30BigTomYou cannot build results on the climb out from the recursion
16:30knaprhmm but isnt there jsut a simple way to kill a thread forever?
16:30knaprand the damn player only has stop the player nad play it so not a very complete library. and doing stop on the player doesnt work
16:30BigTomso you have to use some kind of aggregator
16:30nymsyso, out of 500 users, where events are nick changes and room enter/leave ... how many events happen per second? probably less that ten... but I could put all change events in a queue and, if there's traffic, the cpus running hot, theres lots to do, i could throttle events at 5 a second.
16:30Hunthat means that you can have f => g(x) and g => f(x)
16:30Hunand it works
16:31HunBigTom: that's the trick in tail recursion
16:31ChouserBigTom: no, building values while returning isn't a tail call, so won't be optimized by normal TCO either.
16:31knaprhow do i pronounce sieve?
16:31Hunit works well if you have an iterative algorithm. that means `doesn't need to do anything to clean stuff up'
16:31hiredmanBigTom: as far as I am aware, in proper tail calls you also need an accumulator
16:31Hunhiredman: nope.
16:32Chouserknapr: dunno how you pronounce it, but I say "siv"
16:32hiredmanHun: ok, you don't need, but you would need one to do what he is talking about
16:32Hunthe accumulator is needed to translate a recursive algorithm into a tailrecursive into an iteration
16:32Hunyep
16:32BigTomMAybe I am misremembering
16:32nymsyi think its seeve.. like, to _leave_ something some where
16:32Hunand using an accumulator is /very/ pointless
16:32hiredmanclojurebot: whose job is to current hiredman when he says something that is not completely 100% correct?
16:32clojurebotthat is scode's job
16:33hiredmanHun: see, it isn't even your job
16:33Hunyou're exchanging the system's tested and good stack implementation for your own ad-hoc one
16:33Hunhiredman: so what? :)
16:33hiredman:P
16:34Chouser"sieve" rhymes with "give": http://en.wiktionary.org/wiki/sieve
16:34Huni'm having an exam tomorrow and want to hang out in irc to forget it for now :)
16:34BigTomHun: confused now, if I want to accumulate a value via recursion and TCO what do I do?
16:34HunBigTom: you might as well just use recursion
16:34Chousernymsy: I really wouldn't worry about throttling and such until you see it.
16:34Hunwhen you need an accumulator for tail recursion, you need /exactly/ as much space and time as when using recursion
16:34hiredmanBigTom: you might as well use reduce
16:35Hun(in a proper working compiler at least)
16:35HunBigTom: and think about it
16:35Chousernymsy: regardless if you've got an O(1) or O(n) algorithm underneath. :-)
16:35Hunwhen your problem is so hard that you can't use one of the usual combinators, it's usually to hard to be expressed in a simple recursion either :)
16:35hiredman,(reduce + 0 (range 10))
16:35clojurebot45
16:36nymsyChouser: aye
16:36hiredman,(reduce conj [] (range 10))
16:36clojurebot[0 1 2 3 4 5 6 7 8 9]
16:36nymsyChouser: I think you hit the nail on the head with the indexing
16:36kotarak,(into [] (range 10))
16:36clojurebot[0 1 2 3 4 5 6 7 8 9]
16:36nymsyI appreciate the help
16:36hiredmankotarak: I was demonstrating recude
16:36Chousernymsy: well, I'd be curious to know how it goes.
16:36hiredmanreduce
16:37BigTomThanks, maybe I need to rethink stuff
16:37BigTomMy scheme days are long past
16:37Hunthat's the proper way to think :)
16:37Chousernymsy: like I said, I've not actually used that kind of pattern yet.
16:37kotarakhiredman: geez. Rich had to show me this twice before I remembered into. :]
16:38BigTomHun: so when do you use recur?
16:38nymsychouser: it seems more functional, right? I think it's the way to go.. also easier than keeping track of all those globals
16:41nymsyIf there were a way to update the indexes automatically, without having to rebuild the whole thing, it'd make for a good pattern in general
16:41HunBigTom: i usually don't. i try to use the normal combinators, or build a full-fetched state-machine
16:41bakkdoorhi.
16:41hiredmanfetched?
16:41BigTomHun: fair enough
16:41Hunfor the state-machine, recur is good enough
16:42BigTomHun: this is my first hard core foray into Functional approaches so I'll take all the advice I can
16:42bakkdooris there an easy way to cast numbers to chars? for example, i have a sequence of hexadecimal numbers and want to convert it into its corresponding character string
16:42Hunif you tried it once, a state machine can be expressed pretty well by recursion when you have TCO
16:42hiredmanI think I used different seq functions more then recur for project euler stuff
16:42BigTomhiredman: interesting
16:42hiredmanfilter, map, for
16:43BigTomhun: what are the normal combinators?
16:43hiredmanlike for primes I have a lazy seq that sieves out non-primes
16:43Hunmap, reduce, filter (and specializations of those)
16:43hiredmanI think I may have stole that from the google group though
16:43Huni'm not sure what extended versions are in clojure right now.
16:43Huncombinators are fun :)
16:43hiredmanapply
16:44BigTomThanks, I have another avenue to study
16:44hiredmanhmmm
16:44hiredmanlooking at my euler.clj I did use recur for #10
16:44Hunmap and filter are easy. take your time with reduce. it's mighty and a bit non-intuitive
16:45BigTomHun: funnily I am fairly happy with reduce, I think it is hard in most languages so I worked on it
16:46BigTomI think I really need to get my head around laziness
16:46Hunyep. i suggest reading the stream chapter in SICP
16:46hiredmanclojurebot: sicp
16:46clojurebotsicp is http://www.codepoetics.com/wiki/index.php?title=Topics:SICP_in_other_languages:Clojure:Chapter_1
16:46Huneye-opening for lazy stuff
16:46hiredmangah
16:46BigTomhiredman: gah?
16:46hiredmanclojurebot: don't you know where the pdf is?
16:46clojurebotTitim gan �ir� ort.
16:46Hunread the text and the code. reading just one doesn't really work
16:47nymsyhiredman: it took me months to find the pdf
16:47hiredmanclojurebot: google sicp pdf
16:47clojurebotFirst, out of 18900 results is:
16:47clojurebotStructure and Interpretation of Computer Programs
16:47clojurebothttp://deptinfo.unice.fr/~roy/sicp.pdf
16:47nymsyhmm
16:47Hunyou're doing something wrong.
16:47nymsyheheheh
16:48hiredmanyeah I watched the videos years before I ever found the pdf
16:48nymsymaybe it was the other one
16:48nymsythe other four letter acronym, functional programming book
16:49nymsyhtpc
16:49Hunpaip?
16:49cooldude127i wrote an AVL tree in clojure yesterday. today i wrote a red-black tree in clojure as well. the two files have the exact same number of lines. WEIRD
16:49Hunhtwp
16:49nymsyhow to program computers? or something?
16:49Hunwrite programs
16:49nymsyah
16:49Hunit's nice, but doesn't have much depth
16:49hiredmancooldude127: be sure to throw salt over your left shoulder
16:49nymsyclojurebot: google htwp pdf
16:49clojurebotFirst, out of 255 results is:
16:49cooldude127hiredman: ?
16:49clojurebotHTWP - TORQUE WRENCH PUMPS
16:50clojurebothttp://www.hi-force.com/Pages-download/Catalogues/English%20main%20pages/Page-089.pdf
16:50Hunhmm
16:50Hunah
16:50hiredmanNice
16:50Hunhow to DESIGN programs
16:50cooldude127well i need to go to class
16:50Hunpaip is also very nice :)
16:50BigTomclojurebot: google how to design programs
16:50clojurebotFirst, out of 254000000 results is:
16:50clojurebotHow to Design Programs
16:50clojurebothttp://www.htdp.org/
16:50nymsyahah
16:50knaprcooldude127: can you please post the code to your avl tree and redblack tree?
16:51knaprcooldude127: can you please post the code to your avl tree and redblack tree?
16:51bakkdooris there an easy way to cast numbers to chars? for example, i have a sequence of hexadecimal numbers and want to convert it into its corresponding character string
16:51nymsytoo late
16:51hiredman,(map char (range 80 90))
16:51clojurebot(\P \Q \R \S \T \U \V \W \X \Y)
16:51BigTomThanks for all the help, hacve to go
16:51Hunhf
16:52bakkdoorah thanks
16:52nymsybakkdoor: java can do it too, i think
16:52knaprhow do I perform some actions when the user presses close in a GUI?
16:52hiredmanchar's in java are, I think, unsigned shorts
16:53hiredmanso int <-> char is fairly easy
16:53nymsy.onClose?
16:53Hunknapr: bind something to that event
16:53knapris there something like : gui.onDestroy(doStuff); ?
16:53nymsysomething like that
16:53nymsymost swing tutorials, fwir, have it in there somewhere
16:53hiredmanby faily easy I mean a nop
16:59nymsy,(({"pr" (fn [x] (pr x))} "pr") "hi")
16:59clojurebot"hi"
16:59nymsysweet
17:00nymsybeen thinking of setting up commands that way, in one large map
17:00Hunmight be ok if your commands are computer generated. pretty bad for humans
17:00nymsywhy?
17:00Hun,(({"pr" (fn [x] (pr x))} "Pr") "hi")
17:00clojurebotjava.lang.NullPointerException
17:01Hunany questions?
17:01Chouser,(({"pr" pr} "pr") "hi")
17:01clojurebot"hi"
17:03nymsytrue, true.. Hun: (def [msg "/nick nymsy"] (({"/nick" ... etc
17:04Hunparsing quasi-structured input is pretty hard
17:05nymsyaye, I made first-word and rest-words to parse the commands
17:05nymsyworks pretty good
17:06Hundid 2 parsers for a debugger. the first one was an ad-hoc one (homegrewn regexes with HUGE casetables), the second one uses a proper grammar
17:06Huni lost one feature (being able to have pr expand to print), but the code got a whole lot better expandable
17:07nymsyyea, I'm not quite there yet :)
17:07Hunthe completion was cool. (filter #(starts-with (car x) command-string) command-table)
17:07Hunmore or less
17:08ChouserHun: Clojure? Or some other lisp?
17:08Hunif more than one matches (s could be save or step), the list was of length > 1 and an error was signalled
17:08Chouser'car' nm.
17:08HunChouser: CL
17:08Hunlosely translated. it's hard to lose your car, you know
17:09Chouserbut #() is hard to ignore. :-) ...or does CL do that too?
17:09Hunmine did
17:09Chouser:-)
17:09Hunthat macro is pretty easy to write, you know. my implementation took 20 lines
17:10Hunthough it used _1 and _2 instead of %1 and %2
17:10Huni thought if adding key args to that would be nice (like (#(foo _bar) :bar 5) => 5
17:10nymsywell, gents.. it's been swell... **Chouser: thanks again for the index tip.. I'm racking out. see yall later
17:10Hunbut that was a bit to hard
17:11Hunhave fun
17:11Chousernymsy: good luck in the deployment
17:11Chousernymsy: US? Nat'l guard? Anyway, I wish you well.
17:41knaprit seems to use windowlistener i have to implement a java interface, is that correct? how do I do that in Clojure?
17:41Cark,(doc proxy)
17:41clojurebot"([class-and-interfaces args & fs]); class-and-interfaces - a vector of class names args - a (possibly empty) vector of arguments to the superclass constructor. f => (name [params*] body) or (name ([params*] body) ([params+] body) ...) Expands to code which creates a instance of a proxy class that implements the named class/interface(s) by calling the supplied fns. A single class, if provided, must be first. If not
17:42Carkor you could use genclass
17:42waltersone trick that rhino does that *really* helps in java integration is for functions to transparently implement single-method interfaces, i don't see why clojure fns couldn't do that
17:42Carkor make a namespsace which will become your class
17:44hiredmanwalters: I think it is a performance deal breaker
17:44hiredmanbut I forget
17:44hiredmansomeone was here and asked rhickey about it
17:46hiredmanI imagine you could do that, but not completely transparently with a macro
17:46hiredman(mk-interface java.some.Interface fn)
17:47knaprif i want to make an executable file for my mp3, do i first use compile then i use jar on that?
17:47waltersyeah, that's equivalent to how groovy does it, you have to say { foo, bar -> stuff(); } as java.some.Interface
17:48hiredmanknapr: http://clojure.org/compilation under "gen-class Examples" has an example stand alone jar
17:48hiredmanquick, name a single method java interface off the top of your head
17:48waltershiredman: FilenameFilter
17:50waltershiredman: also, two of my personal projects make extensive use of them
17:50AWizzArd,(print *ns*)
17:50hiredman,(:name (bean (first (.getMethods java.io.FilenameFilter))))
17:50clojurebot#<Namespace sandbox>
17:50clojurebot"accept"
17:50AWizzArd,(print (ns-publics 'sandbox))
17:50clojurebot{}
17:51hiredman,(symbol (:name (bean (first (.getMethods java.io.FilenameFilter)))))
17:51clojurebotaccept
17:52hiredmanand then you just have the macro generate the relevent proxy form around that
17:52AWizzArd,(count (ns-map 'sandbox))
17:52clojurebot541
17:54ecretI am able to compile clojure classes but the whole reason I wanted to do that was so that java.lang.Class.forName("clojureclassname") would work in the java jar file that I called. But I am unable to (Class/forName "clojureclassname") as a test. I get java.lang.ClassNotFoundException: transcriber The brief code is at http://paste.lisp.org/display/74380
17:55ecretDoes clojure support this mechanism?
17:56AWizzArdecret: great, so you managed it to compile to .class files :-)
17:57ecretyes ! took 5 hours but it worked. I am not totally 100% sure which of the things I did fixed it but I am not going to meddle :>
17:57AWizzArd;-)
17:57ecretpretty sure it was just the class path + the *compile thing* though
17:57AWizzArdyup
17:57knaprman i always get suck on the damn java classpath as soon as i dont use it for a while i get confused
17:57AWizzArdonce you found out how they play together it can be done within seconds to minutes
17:58ecretyep
17:59AWizzArdecret: so why do you want to do Class/forName? Is your goal to use code that you have written in Clojure inside of Java?
18:00ecretsort of. A Jar file I am accessing has this line : Class cls = Class.forName(className); where className is specified in a config.xml file that needs to belong to the caller of the jar file
18:02ecretthe caller is the transcription.clj so transcription.class
18:07scottjWhat software could one use to make it easy to define a macro that takes an equation and outputs a function for each variable that solves for that variable?
18:07knaprif i have: C:/clojure/classes/progs/comex/ and in comex i have compileexample.class et al. then i ahve C:/clojure/progs/ and i ave progs.comex.compileexample.clj, how do i run that?
18:20knaprif i have: C:/clojure/classes/progs/comex/ and in comex i have compileexample.class et al. then i ahve C:/clojure/progs/ and i ave progs.comex.compileexample.clj, how do i run that?
18:42cooldude127technomancy: hey did something change in clojure-mode (or at least the one in emacs-starter-kit) to make clojure-enable-paredit not work?
18:43technomancycooldude127: yeah, upstream didn't like the idea of making that a flag
18:43technomancycheck the comments in the clojure-mode header
18:43cooldude127ok
18:43technomancythe way he switched it to work is pretty reasonable
18:43cooldude127technomancy: that's the way it works for every other lisp actually
18:44technomancyoh cool
18:45cooldude127technomancy: do you ever notice yourself doing C-c C-c on elisp expressions and expecting it to work?
18:47technomancycooldude127: I actually end up using C-c C-l most of the time
18:47technomancyjust my habit; need to spend some more quality time with the slime manual
18:47cooldude127oh, i'm addicted to compiling individual top-levels
18:48cooldude127but the real one to use is C-c C-k if you want to do the whole file
18:48technomancywhat's the difference?
18:48cooldude127one prompts you for the file, and is evaling it i think (not sure about that), but C-c C-k just compiles it like you did C-c C-c on everything in the file
18:49knapris how to deisng programs aimed at beginners?
18:49cooldude127knapr: i think so
18:49knaprit seems bsic just skimming through it?
18:49knaprdude:post your avn and redblack tree please
18:50knaprwhat is a good book on how to deisgn complex programs, preferrably in a functional way
18:50cooldude127knapr: k, but my RB tree doesn't do deletes yet btw
18:51hiredmancooldude127: you using clojure.zip for the trees?
18:51cooldude127hiredman: no, but i really should look at that
18:51cooldude127hiredman: they're pretty naive implementations, i'm just learning this stuff
18:51technomancycooldude127: nice; one step fewer I guess
18:52cooldude127knapr: here they are: http://gist.github.com/53671
18:52cooldude127technomancy: yeah, i'm all about the efficiency
18:53cooldude127hiredman: holy shit, what are these zippers?
18:54knaprok
18:54cooldude127hiredman: it's a good thing i didn't know about these before i wrote the avls, i had to translate that back to java, and zippers would not have made that easy
18:54cooldude127lol
18:54hiredmanheh
18:55hiredmanso far I have avoided actually trying to figure out the intermediate output of munging stuff with zippers
18:55cooldude127hiredman: what do you mean?
18:57hiredmancooldude127: zippers sort of turn a data structure insideout as you move through it
18:57hiredmanand when you are done you "zip" it back up
18:58cooldude127oh jesus
18:58cooldude127yeah i'm not ready for that
18:58knaprso
18:58knaprhow can I run
18:58hiredmanit is neet because you move through a ds using ->
18:58cooldude127ok what do i do to make it so i can refer to clojure.zip as just zip?
18:58hiredmaner ->
18:58hiredmandamn it
18:58hiredman"->"
18:58cooldude127lol
18:59cooldude127i knew what you meant
18:59hiredman(require '[clojure.zip :as zip])
18:59cooldude127hiredman: in a ns form that would be (:require [clojure.zip :as zip]) ?
19:00hiredmanyes
19:00cooldude127k
19:00cooldude127ok back to my avl tree, cuz no way am i mucking around with the RB tree when i barely understand both RB trees and zippers
19:01cooldude127can't mess with two things i don't understand at the same time
19:02lisppaste8knapr pasted "compiling java is hell" at http://paste.lisp.org/display/74384
19:02knaprsomeone can explain ^^ ? just how to run compiled clojure...
19:04hiredmanknapr: on the compilation page where you saw that example, right under that example
19:04hiredmanjava -cp ./classes:clojure.jar clojure.examples.hello Fred
19:05knaprwhere ./classes:clojure.jar is instead C:/clojure/clojure.jar? so why doesnt that work?
19:05hiredman./classes needs to be replaced with the path to your classes directory and clojure.jar with the path to your clojure
19:05knaprand from where shouls it be run?anywhere?
19:05hiredmanthe classpath seperator on windwos is ;
19:05hiredmannot :
19:06hiredmanif you have full paths then you can run it from anywhere
19:12knaprsigh i cant get it to work, noclassdeffounderror
19:17knaprabout function composition
19:17knapr(comp map map)
19:17knaprdef that
19:17knapr(mmap inc [[1,2,3,4,5]])
19:17knaprjava.lang.IllegalArgumentException: Wrong number of args passed to: core$map (NO_SOURCE_FILE:0)
19:18knaprin haskell that works
19:20hiredmanwell
19:20hiredmanthis is not haskell
19:20hiredmanmap, takes two args each time
19:21hiredmanand outputs a single value
19:21hiredmanso the first map outputs a single value, the second map gets a single value
19:21hiredmanbut map takes two args
19:21hiredmanso no dice
19:22hiredman,(map (patial map inc) [(range 10) (range 20 30)])
19:22clojurebotjava.lang.Exception: Unable to resolve symbol: patial in this context
19:22hiredman,(map (partial map inc) [(range 10) (range 20 30)])
19:22clojurebot((1 2 3 4 5 6 7 8 9 10) (21 22 23 24 25 26 27 28 29 30))
19:27hiredmanclojurebot: for?
19:27clojurebotfor is not a loop
19:27hiredmanclojurebot: for is also not used often enough
19:27clojurebotRoger.
19:33hiredmanmy euler.clj is so embarresing
19:33knaprclojurebot: for?
19:33clojurebotfor is not used often enough
19:33knaprclojurebot: for?
19:33clojurebotfor is not used often enough
19:33knaprclojurebot: hiredmans euler.clj is so embarassing
19:33clojurebot'Sea, mhuise.
19:34knaprclojurebot: hierdmans?
19:34clojurebotIt's greek to me.
19:34knaprclojurebot: hiredmans?
19:34clojurebothiredmans euler.clj is so embarassing
19:34knaprwhy?
19:35knaprclojurebot: meaning of life?
19:35clojurebotexcusez-moi
19:35knaprclojurebot: meaning of life is to become one with Lisp
19:35clojurebotIn Ordnung
19:35knaprclojurebot: meaning of life?
19:35clojurebotmeaning of life is to become one with Lisp
19:35hiredmanknapr: careful about over writing stuff
19:37knaprok'
19:38knaprclojurebot: OO is to programming what astrology is to astronomy
19:38clojurebotAlles klar
19:38knaprclojurebot: OO?
19:38clojurebotOO is to programming what astrology is to astronomy
19:40Carktss =)
19:41gnuvince_hahaha
19:56cooldude127hiredman: when using zippers, what's the best way to represent a binary tree? i was imagining vectors kinda like the example, but then i wondered what order to put elements in
20:01knaprhttp://paste.lisp.org/display/74384
20:02cooldude127knapr: that hasn't gotten worked out yet?
20:02durka42wouldn't you just do: java compleexample
20:02durka42compileexample
20:03cooldude127you need clojure on the classpath
20:03durka42with clojure.jar on the $CLASSPATH
20:03knapri get wrong name
20:03cooldude127knapr: what do you mean?
20:03durka42NoClassDefFound?
20:04knapryes
20:04durka42even though you have both clojure.jar and ...../prog/comex on the classpath
20:04cooldude127knapr: you should be in the classes folder, and run java -cp path/to/clojure.jar progs.comex.compileexample
20:04knaprCaused by: java.lang.ClassNotFoundException: C:.clojure.classes.progs.comex.comp
20:04knaprileexample.class
20:05cooldude127java -cp .;c:\clojure\clojure.jar progs.comex.compileexample
20:06knaprayay sir!
20:06knaprthanks
20:06cooldude127no problem
20:09knaprand when i have abig program with reuires and imports i add :gen-class the same way?
20:13durka42clojurebot: where's my list of exceptions?
20:13clojurebothttp://paste.lisp.org/display/74305
20:14lisppaste8durka annotated #74305 with "errors" at http://paste.lisp.org/display/74305#1
20:14durka42,(+ 840 92)
20:14clojurebot932
20:19knaprwoot i managed to compile and run my mp3player!
20:20durka42sweet
20:20knaprnow i just need to make it executable without hocus-pocus
20:20durka42hocus pocus?
20:23knaprjava classpath
20:31gnuvince_There's no literal syntax for longs, is there?
20:38knaprshould I put my mp3player up at some wiki or something?
20:39knaprit contains quite a lot of interest for the CLojure-curious. GUI(swing+miglayuout+using clojure-contrib). basic threading. playing sound. a lot of interopearting with Java etc.
20:42knaprthere is a lot of things being generated and created when compiling and running
20:42knaprwhich file/files do i need in the jar? just compileexample.class?
20:43knaprwhat about compileexample_init.class?
20:48durka42knapr: yeah, put it up on a wiki or github or lisppaste somewhere
20:48durka42you might also need clojure.jar
20:51durka42you might want to look at how gorilla does it
20:51durka42it has an ant script with an option for standalone build (unzips clojure.jar into gorilla.jar)
20:58knaprgorilla?
20:58knapryou mean it has a build.xml?
20:59durka42yes
21:01durka42http://bitbucket.org/kotarak/gorilla/src/
21:20cooldude127is there anymore documentation clojure's zippers besides what's on the site?
21:21hiredmanI spent alot of zip flipping back and forth with zip.clj
21:21hiredmanhah
21:21hiredmana lot of time flipping
21:21cooldude127lol
21:27cooldude127hiredman: i'm trying to figure out how to write a zipper that will let me get at the data in the tree and still get at the left and right nodes using zip/left and zip/right, idk what i'm doing tho
21:28hiredman,(require '[clojure.zip :as zip])
21:28clojurebotnil
21:29hiredman,(-> '(+ 1 3 (* 2 4)) zip/seq-zip)
21:29clojurebot[(+ 1 3 (* 2 4)) nil]
21:29hiredman,(-> '(+ 1 3 (* 2 4)) zip/seq-zip zip/down)
21:29clojurebot[+ {:l [], :pnodes [(+ 1 3 (* 2 4))], :ppath nil, :r (1 3 (* 2 4))}]
21:29hiredman,(-> '(+ 1 3 (* 2 4)) zip/seq-zip zip/down zip/node)
21:29clojurebot+
21:29hiredman,(-> '(+ 1 3 (* 2 4)) zip/seq-zip zip/down zip/right zip/node)
21:29clojurebot1
21:31hiredman,(-> '(+ 1 3 (* 2 4)) zip/seq-zip zip/down zip/right zip/right zip/right zip/node)
21:31clojurebot(* 2 4)
21:31hiredmanwheee!
21:31cooldude127hiredman: that's not what i want tho, i want to be able to go down, then go left or right to the the left or right subtree
21:31gnuvince_,(doc get)
21:31clojurebot"([map key] [map key not-found]); Returns the value mapped to key, not-found or nil if key not present."
21:32hiredman,(-> '(+ 1 3 (* 2 4)) zip/seq-zip zip/down zip/node)
21:32clojurebot+
21:32gnuvince_Is there a reason to use get instead of using a map as a functin?
21:32gnuvince_function*
21:32hiredman,(-> '(+ 1 3 (* 2 4)) zip/seq-zip zip/children)
21:32clojurebot(+ 1 3 (* 2 4))
21:32Chousukegnuvince_: perhaps its clearer in some cases?
21:33hiredman,(-> '(+ 1 3 (* 2 4)) zip/seq-zip zip/lefts zip/node)
21:33clojurebotjava.lang.NullPointerException
21:33hiredman,(-> '(+ 1 3 (* 2 4)) zip/seq-zip zip/lefts)
21:33clojurebotnil
21:33hiredman,(-> '(+ 1 3 (* 2 4)) zip/seq-zip zip/rights)
21:33clojurebotnil
21:33hiredman,(-> '(+ 1 3 (* 2 4)) zip/seq-zip zip/down zip/rights)
21:33clojurebot(1 3 (* 2 4))
21:33hiredman,(-> '(+ 1 3 (* 2 4)) zip/seq-zip zip/down zip/lefts)
21:33clojurebotnil
21:33hiredmanhmm
21:34cooldude127hiredman: i guess what i want is for it to start at the data, then be able to go left or right from there, instead of always starting at the beginning
21:34hiredman,(-> '((1 1) 1 3 (* 2 4)) zip/seq-zip zip/down zip/lefts)
21:34clojurebotnil
21:35hiredmanyou are at a leaf, and want to head left from the leaf?
21:36bradbevHi guys. How much memory does an instance of a struct-map consume?
21:36cooldude127hiredman: i want something like this: [[[1] 2 [3]] 4 [[5] 6 [7]]] for a binary tree, and for it to start in the middle
21:36hiredmandunno
21:38bradbevI want to write a memory logging application, each alloc should be represented by a struct-map, with about 7 keys, so I'd guess 7*4 = about 28 bytes. I want to put every alloc into a map keyed on its address, and keep a list of all maps through time. That should be ok due to structure sharing.
21:38hiredman(-> [[[1] 2 [3]] 4 [[5] 6 [7]]] zip/vector-zip)
21:38hiredman,(-> [[[1] 2 [3]] 4 [[5] 6 [7]]] zip/vector-zip)
21:38clojurebot[[[[1] 2 [3]] 4 [[5] 6 [7]]] nil]
21:38hiredman,(-> [[[1] 2 [3]] 4 [[5] 6 [7]]] zip/vector-zip zip/down zip/node)
21:38clojurebot[[1] 2 [3]]
21:38bradbevThe problem is that my 7 key struct injected into a map 750,000 times is about 438Mb
21:39cooldude127hiredman: see that should be 4 in my ideal case
21:39lisppaste8knapr pasted "making an exec jar" at http://paste.lisp.org/display/74391
21:39hiredman,(-> [[[1] 2 [3]] 4 [[5] 6 [7]]] zip/vector-zip zip/down zip/left zip/left zip/node)
21:39clojurebotjava.lang.NullPointerException
21:39bradbevif I inject 750,000 ints into a vector, then it is only a handful of MB
21:39hiredman,(-> [[[1] 2 [3]] 4 [[5] 6 [7]]] zip/vector-zip zip/down zip/node)
21:39clojurebot[[1] 2 [3]]
21:39hiredman,(-> [[[1] 2 [3]] 4 [[5] 6 [7]]] zip/vector-zip zip/left zip/left zip/node)
21:39bradbevso, I'd guess structmaps are huge
21:39clojurebotjava.lang.NullPointerException
21:39bradbevany thoughts?
21:40hiredman,(-> [[[1] 2 [3]] 4 [[5] 6 [7]]] zip/vector-zip zip/down zip/right zip/node)
21:40clojurebot4
21:40hiredmanduh
21:40cooldude127hiredman: yeah i know you could do it that way, but it feels counter intuitive
21:41hiredmansorry I meant duh for myself
21:41cooldude127i figured
21:42cooldude127hiredman: i considered doing it prorder, like [data left right], but then it's still right and right -> right, instead of left and right
21:43bradbevHmm, OK ref object appear to be quite large
21:44hiredmancooldude127: you can make your own zipper
21:44cooldude127hiredman: yeah i'm looking into figuring out how to make that work correctly
21:47knaprhttp://paste.lisp.org/display/74391 , <- i cant get it to work(making an exec jar). i looked at gorilla but it was to complicated
21:49cooldude127hiredman: damnit this is confusing
21:50hiredmanYes
21:50hiredmanbut that does make it less cool
21:51cooldude127hiredman: is there anyway to make a zipper go down, and then be able to make an immediate left? at all?
21:52hiredman,(doc zip/down)
21:52clojurebot"([loc]); Returns the loc of the leftmost child of the node at this loc, or nil if no children"
21:52cooldude127hiredman: so no?
21:52hiredmandown should hit the left
21:53cooldude127hiredman: maybe i just write my own left and right functions that do the right thing?
21:54hiredmanyou could do that
21:55knaprwheres does the expr hiredman come from?
21:55knapri heard it in the office
21:56hiredmanI borrowed it from a gibson book
21:57hiredmanCount Zero, I believe
22:10johan1hmm, I still don't get Java interop. I'm trying to call a method setCoordinates(arg), where arg is int[]. In Clojure I try (.setCoordinates [1 2 3]) which doesn't work. Any idea on how to create a int[] argument from clojure?
22:10durka42you didn't pass the object
22:10durka42{what?}.setCoordinates()
22:10johan1that's a typo
22:10johan1it is correct in my code, but the argument is wrong
22:10durka42oh ok
22:11durka42in that case i'm not sure
22:11durka42maybe:
22:11durka42(doc make-array)
22:11clojurebotCreates and returns an array of instances of the specified class of the specified dimension(s). Note that a class object is required. Class objects can be obtained by using their imported or fully-qualified name. Class objects for the primitive types can be obtained using, e.g., Integer/TYPE.; arglists ([type len] [type dim & more-dims])
22:11cooldude127also:
22:11cooldude127(doc into-array)
22:11clojurebotReturns an array with components set to the values in aseq. The array's component type is type if provided, or the type of the first value in aseq if present, or Object. All values in aseq must be compatible with the component type. Class objects for the primitive types can be obtained using, e.g., Integer/TYPE.; arglists ([aseq] [type aseq])
22:11durka42,(into-array [1 2 3])
22:11clojurebot#<Integer[] [Ljava.lang.Integer;@1f9b804>
22:12johan1ok, I will give it a try
22:12hiredmanvectors are not java arrays
22:12cooldude127they are objects
22:12cooldude127,(class [1 2 3])
22:12clojurebotclojure.lang.LazilyPersistentVector
22:12hiredman,(class (into-array [1 2 3]))
22:12clojurebot[Ljava.lang.Integer;
22:12hiredmanso are java arrays
22:12hiredmanyou most likely want ints not Intergers
22:13hiredmanso you want
22:13cooldude127hiredman: autoboxing should make that ok tho
22:13hiredman,(into-array Integer/TYPE [1 2 3])
22:13clojurebot#<int[] [I@92eb76>
22:13cooldude127,(into-array Integer/Type [1 2 3])
22:13clojurebotjava.lang.Exception: No such namespace: Integer
22:13cooldude127lol
22:13cooldude127hiredman: oh i messed it up
22:14hiredman,(class (into-array Integer/TYPE [1 2 3]))
22:14clojurebot[I
22:14hiredmanIndeed
22:24johan1it works. thanks
22:25hiredman,(class 1)
22:25clojurebotjava.lang.Integer
22:30dreish,(gensym)
22:30clojurebotG__1270
22:30dreish,(gensym)
22:30clojurebotG__1274
22:30dreish,(= (gensym) 'G__1278)
22:30clojurebottrue
22:31dreishIs this a bug?
22:31hiredman,(= (gensym) (gensym))
22:31clojurebotfalse
22:31durka42gensym creates a new symbol
22:31durka42you inferred the algorithm for naming said symbol, an implementation detail
22:31durka42doesn't seem like a bug
22:32hiredman,(let [a (gensym)] (= a (gensym)))
22:32clojurebotfalse
22:32dreishYes, and maybe the bug is in my expectations, but in Common Lisp, a gensym cannot be equal to any other existing symbol.
22:32hiredman,(= nil 'a)
22:32clojurebotfalse
22:32hiredman,(= (gensym) 'a)
22:32clojurebotfalse
22:32dreishIf you begin an expression (= (gensym) ...) in CL, there is nothing you can type to make it true.
22:32dreishSorry, (eq)
22:33durka42hmm
22:33hiredman,(str (gensym) " " (gensym))
22:33clojurebot"G__1299 G__1300"
22:33hiredmanhmmm
22:33knaprhas anyone managed to create an executable jar of a clojure-program? could you show me?
22:33durka42did you look at gorilla?
22:33durka42after you do "ant -Dstandalone=true" gorilla.jar is runnable with java -jar
22:33durka42i don't know how but kotarak presumably does
22:34durka42dreish: i guess, the arguments to = are evaluted first, so the symbol exists before gensym creates its new one
22:34hiredmanknapr: jars are never "executable", windows is just typically setup to, when you click on X.jar, to run java -jar X.jar
22:35durka42Gorilla=> (let [a 'G__1963] (prn (gensym)) (prn a))
22:35durka42G__1963
22:35durka42G__1963
22:35durka42nil
22:35durka42that does seem strange
22:35dreishRIght, so it ought to be no problem to create a different one. But I think I remember seeing that the reader is side-effect-free, and that symbols aren't interned (but keywords are). So I guess it would be impossible for gensym to be as clean as it is in Common Lisp, and it would presumably just be the responsibility of the programmer to avoid creating symbols beginning G__.
22:35dreishWhich I guess is reasonable enough.
22:36knapri see
22:37hiredman,(doc gensym)
22:37clojurebot"([] [prefix-string]); Returns a new symbol with a unique name. If a prefix string is supplied, the name is prefix# where # is some unique number. If prefix is not supplied, the prefix is 'G__'."
22:37dreishThat actually seems a little more troubling, now that I think about it, because it means any symbol with a number at the end could potentially collide with a gensym.
22:38dreishI'm sure I must be wrong about that.
22:38durka42so in CL, it looks like gensym'd symbols are a completely different type from regular symbols?
22:39dreishI think they're regular-enough symbols, but they print in a form that doesn't read back to the same symbol.
22:40dreishThat might be the answer, though. Make them somehow something that can't be produced through the reader, or by calling symbol.
22:41gnuvince_Could anybody lend me a hand with a macro?
22:41gnuvince_I think I've almost got it, but I can't put the finishing touch.
22:42hiredmanclojurebot: macro help?
22:42clojurebotmacro help is http://clojure-log.n01se.net/macro.html
22:42hiredman:P
22:42durka42isn't that captcha circumvention?
22:42dreishI can help you move a macro up a flight of stairs if it weighs less than about 150 lbs.
22:42durka42(because that captcha is so advanced...)
22:43durka42be careful, parentheses are slippery
22:43durka42and quasiquotes are sharp
22:45lisppaste8gnuvince pasted "parse-buffer macro" at http://paste.lisp.org/display/74394
22:47dreishWhy is this a macro?
22:47gnuvince_Cause I don't want to manually call .get, .getShort, .getInt, etc.
22:48gnuvince_I want to write a description of the buffer's structure and have all right calls made
22:49dreishI just don't see why this could be a function that does exactly the same thing.
22:49dreishcouldn't
22:51gnuvince_Because it looks exactly like something macros are used for.
22:51hiredmanclojurebot: who's the man is <reply> ?(^_^)?
22:51clojurebotAlles klar
22:51hiredmanclojurebot: who's the man?
22:51clojurebot?(^_^)?
22:51danlarkinintense
22:51durka42nice unicode
22:52gnuvince_Anybody?
22:52hiredmanI just stole it from someone in #haskell
22:52gnuvince_I just need to figure out how to write the ~forms part in the mapcat call
22:53hiredmanyeah, macros are for code manipulation
22:53hiredmanwhich this is not
22:54lisppaste8durka annotated #74394 with "expansion of the actual macro" at http://paste.lisp.org/display/74394#1
22:54hiredmangnuvince_: I think you need to quote the stuff that gets put into & forms
22:55gnuvince_hiredman: quote it where? in my call?
22:55hiredmanwhich is a sign of not macrohood
22:55hiredmanyeah
22:55gnuvince_Fuck
22:55dreishIt's a function trapped in a macro's body. Won't you help?
22:55hiredmanbecause ~form just turns into a seq of attempted function calls
22:56dreishI like Stu's "rules of macro club": #1: don't write macros.
22:56gnuvince_So *how* would I write this without the calling code looking like fucking Java crap?
22:58gnuvince_Same definition except with defn and call with (parse-buffer buf [:field 1 :byte #(...)] ...)?
22:58dreishThat's where I'd start.
22:59danlarkinditto!
23:00dreishProbably use brackets for the lists instead of parens so you don't have to quote.
23:00hiredmansounds like a plan
23:00danlarkinvectors
23:00danlarkinnot brackets
23:00dreishRight. When I'm especially tired I also call them square thingies.
23:00danlarkinimportant to know that vectors != lists
23:01dreishLittle square data structures floating around in the computer.
23:01hiredmanthen once you have that, you can make a macro that turns lists into vectors and passes them to your function :P
23:01durka42this macro known as [
23:02hiredmanactually it is a function know as vec
23:02hiredman,(vec '(:a :b :c))
23:02clojurebot[:a :b :c]
23:03durka42(defmacro vecm [xs] `(vec '~xs))
23:05lisppaste8gnuvince pasted "Using a function" at http://paste.lisp.org/display/74395
23:06gnuvince_For the curious
23:06dreishDoes it work?
23:06durka42btw: you can annotate pastes
23:07gnuvince_dreish: it does.
23:07dreishWoohoo!
23:07dreishAnother problem solved by not-macros!
23:07gnuvince_Gonna need to try it with my real data
23:07gnuvince_But not tonight
23:26brianhemacs noob here
23:26brianhi just updated my clojure-mode & it deleted the clojure-auto file
23:27brianhwhat's the new alternative?
23:29gnuvince_brianh: look in clojure-mode.el
23:29gnuvince_the two lines are there
23:29gnuvince_There's an autoload and an add-to-alist call
23:31brianhk thx
23:49durka42how do you write a constructor for :gen-class?
23:52durka42:int
23:52durka42:init i mean
23:55hiredmanuh, I think the init function returns a tuple (vector)
23:56hiredmanthe first element is a vector of args to pass to the superclass constructoor
23:57hiredmanthe second element is the starting state
23:58lisppaste8knapr pasted "macro-problem" at http://paste.lisp.org/display/74398
23:58knaprclojurebot: OO?
23:58clojurebotOO is to programming what astrology is to astronomy
23:58knaprsome macro-gurus here? ^^