2009-01-27
| 01:31 | Cark | clojurebot: log? |
| 01:31 | clojurebot | logs is http://clojure-log.n01se.net/ |
| 03:55 | AWizzArd | Moin |
| 03:55 | AWizzArd | clojurebot: max people |
| 03:55 | clojurebot | max people is 129 |
| 04:01 | ecret | (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:02 | ecret | so my question is, how do I check and set the project folder where it looks for those classes? |
| 04:12 | ayrnieu | it'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:13 | ecret | yeah same |
| 04:13 | ecret | i need to know where to put the app/hello.clj file |
| 04:14 | ecret | or how to set the environment to the master path or at least check what it currently is |
| 04:21 | AWizzArd | And how do you try to compile? |
| 04:22 | AWizzArd | Did you set the right *compile-path*? As in: (binding [*compile-path* "/home/ecret/mystuff/"] (compile 'Hello)) |
| 04:22 | ayrnieu | the 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:23 | ecret | (compile 'app.hello) |
| 04:23 | AWizzArd | ,*compile-path* |
| 04:23 | AWizzArd | ,(print *compile-path*) |
| 04:23 | ecret | AWizzArd: i did not. Do I do this in clojure? |
| 04:23 | clojurebot | nil |
| 04:23 | ayrnieu | AWizzArd, http://clojure.org/compilation should emphasize this |
| 04:23 | AWizzArd | Yes, check what is in *compile-path* |
| 04:24 | ecret | ,(print *compile-path*) returns: classes |
| 04:24 | clojurebot | nil |
| 04:24 | AWizzArd | 1-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:25 | AWizzArd | well, the comma is not needed in Clojure, it is just for the clojurebot in this channel, to run my forms. |
| 04:26 | AWizzArd | ecret: try to set *compile-path* with (binding ..) to a path that is in your classpath. |
| 04:29 | ecret | AWizzArd: 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:30 | ecret | is that what I should of done? |
| 04:31 | ecret | java.io.FileNotFoundException: Could not locate junk/hello__init.class or junk/hello.clj on classpath: (NO_SOURCE_FILE:0) |
| 04:31 | ecret | [Thrown class clojure.lang.Compiler$CompilerException] |
| 04:31 | ayrnieu | http://paste.lisp.org/display/74340 |
| 04:31 | ayrnieu | ecret, you get that because it tries to load the class that it's just created, and *compile-path* isn't in your CLASSPATH |
| 04:37 | AWizzArd | ecret: do (System/getProperty "java.class.path") in your repl |
| 04:38 | ecret | tried that ,heres a jar file : /home/eli/clojure/classpaths/RM1_8gau_13dCep_16k_40mel_130Hz_6800Hz.jar |
| 04:38 | ecret | i copy pasted the folder into /home/eli/clojure/classpaths/csphinx/junk/hello.clj |
| 04:40 | AWizzArd | You 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:40 | AWizzArd | Then you can bind the *compile-path* to the .../classes/ dir and compile 'junk.hellp |
| 04:40 | AWizzArd | hello even |
| 04:40 | ecret | in my .emacs file, swank-clojure-extra-classpaths (directory-files (concat concourse-dir "clojure/classpaths/" |
| 04:42 | AWizzArd | Did you decide into which directory the .class files should go that result from compiling .clj files? |
| 04:42 | AWizzArd | This could be for example /home/eli/clojure/classes/ |
| 04:43 | AWizzArd | As 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:44 | AWizzArd | Now inside a possibly completely different directory create a subdir "junk". Into that put your hello.clj which begins with (ns 'junk.hello ...) |
| 04:45 | AWizzArd | And put the dir in which you created junk also into your CP. Then you can compile. |
| 04:49 | ecret | AWizzArd: 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:50 | AWizzArd | make a copy of your .emacs file to which you could go back any time |
| 04:55 | AWizzArd | ecret: here is an example of how your .emacs file could begin: http://nopaste.ch/9869fa857c1cbef.html |
| 04:58 | ecret | AWizzArd,ayrnieu thanks for the help. |
| 06:00 | Lau_of_DK | Gents, regex question |
| 06:00 | Lau_of_DK | (re-find #"\b[Author: +]\b.*" "Author: Jack Daniels <jd@drink.org>") |
| 06:00 | Lau_of_DK | I want to extract only "Jack Daniels <jd@drink.org>" How do I do ? |
| 06:04 | Lau_of_DK | (re-find #"\b[Author: ]\b+.*" "Author: Jack Daniels <jd@drink.org>") |
| 06:04 | Lau_of_DK | " Daniels <jd@drink.org>" |
| 06:04 | Lau_of_DK | This is a little closer, but it misses Jack |
| 06:17 | holly | (re-find #"(Author:\s+)(.*)" "Author: Jack Daniels <jd@drink.org>") |
| 06:17 | holly | 3rd element is the desired one... |
| 06:20 | holly | With (re-find #"(?>Author:\s+)(.*)" "Author: Jack Daniels <jd@drink.org>") it's the second... |
| 06:21 | rfgpfeiffer | (re-matches #"Author:\s+(.*)$" "Author: Jack Daniels <jd@drink.org>") |
| 06:24 | cgrand | holly: what's the difference between ?: and ?> |
| 06:37 | holly | That I have only just learned about ?> but not yet about ?: |
| 06:37 | holly | http://www.regular-expressions.info/atomic.html is what I looked at |
| 06:40 | holly | http://www.regular-expressions.info/brackets.html seems to indicate that ?: does the same as ?> |
| 06:42 | holly | Hmmm. 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:42 | holly | Compare (re-matches #"(?>Author:\s+)( .*)" "Author: Jack Daniels <jd@drink.org>") with (re-matches #"(?:Author:\s+)( .*)" "Author: Jack Daniels <jd@drink.org>") |
| 06:43 | holly | (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:44 | cgrand | holly: thanks I didn't know of ?> and the javadoc for Pattern left me nonplussed |
| 06:46 | holly | :-) There are obviously advantages to being a Java newbie and not knowing about javado |
| 06:46 | cgrand | I 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:48 | holly | You cannot backtrack *into* that group -- it can still backtrack to *before* that group |
| 06:51 | cgrand | indeed, thanks for the clarification! |
| 06:54 | Lau_of_DK | holly, I was out to lunch, thanks alot for helping out |
| 06:55 | holly | NP -- glad I can add something here instead of just lurking |
| 06:57 | Lau_of_DK | It was a big help - I fail at regex almost every time :| |
| 07:21 | rfgpfeiffer | (comp) should be identity |
| 07:21 | rfgpfeiffer | ,((comp) 3) |
| 07:21 | clojurebot | java.lang.NullPointerException |
| 07:25 | AWizzArd | no, but it could perhaps throw an exception instead |
| 07:30 | rfgpfeiffer | it would be consistent with + and * |
| 07:34 | AWizzArd | Those are defined as such |
| 07:34 | AWizzArd | empty sum and multiplication |
| 07:36 | cgrand | in the same vein (-> x) should expand to x |
| 07:41 | AWizzArd | But what should (->) do? ;-) |
| 07:44 | cgrand | thinking 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:46 | AWizzArd | I still would like to have the functional equivalent to ->, namely (defn pipe [& fs] (apply comp (reverse fs))) |
| 07:47 | AWizzArd | ,(defn pipe [& fs] (apply comp (reverse fs))) |
| 07:47 | clojurebot | DENIED |
| 07:47 | rfgpfeiffer | fixed versions: http://gist.github.com/53325 |
| 07:49 | rfgpfeiffer | cgrand: I have a composition function for n-ary fns: http://gist.github.com/51768 before-advice |
| 10:54 | scottj | What is an xrel and a rel? |
| 10:54 | Chouser | scottj: where are you seeing those? |
| 10:55 | scottj | Chouser: clojure.set/index |
| 10:56 | scottj | That only references xrel, but the function above it, rename, references both |
| 11:10 | cgrand | scottj: it seems that a rel is a set of key-values (N:N) while xrel is a map (N:1) |
| 11:11 | cgrand | cgrand: forget what I said |
| 11:12 | Chouser | suddenly |
| 12:09 | knapr | anyone with an example of a gui using JFileChooser? |
| 12:11 | jwinter | This has a JFileChooser (I just saw it today): http://github.com/ynd/mona-clojure/blob/master/mona-clojure.clj |
| 12:16 | cgrand | wow: you can try clj libs without even downloading them! |
| 12:16 | cgrand | (add-classpath "http://github.com/Lau-of-DK/clojureql/raw/master/src/") |
| 12:16 | cgrand | (require '[dk.bestinclass.clojureql :as ql]) |
| 12:16 | Chouser | ah, sweet. |
| 12:17 | rhickey | that's neat |
| 12:17 | cgrand | chouser: if there is a proper directory structure (didn't work with textjure) |
| 12:18 | cooldude127 | that's awesome! |
| 12:18 | Chouser | that also means you get the latest version each time your run. ...I hope you trust that URL. |
| 12:18 | Chouser | cgrand: yeah, textjure is just a "script", not a lib. |
| 12:18 | rhickey | Chouser: well, he'd never put add-classpath in his app, right? |
| 12:19 | danlarkin | wow that is a really really neat trick |
| 12:19 | Chouser | hm, can't use URLs on the -cp command line, I guess. |
| 12:19 | knapr | lol thats supersweet |
| 12:22 | cgrand | If you are unlucky I guess you could get an inconsistent snapshot |
| 12:48 | knapr | what is textjure? |
| 12:48 | drewr | knapr: Clojmacs. |
| 12:51 | danlarkin | shame that validator-fns are supposed to be side effect free |
| 12:51 | danlarkin | I'd feel bad giving mine side effects |
| 12:51 | knapr | sun.awt.shell.Win32ShellFolder2 cannot be cast to java.lang.String |
| 12:51 | danlarkin | so I must find a different way |
| 12:53 | knapr | clojmacs? you mean clojure-mode for emacs? |
| 13:01 | knapr | are GUIs naturally statefula nd using globals is normal? or is that just becuas eim using Swing which anturally is a OO-oriented framework? |
| 13:01 | knapr | i used Tkinter with python and before seem to force the use of globals |
| 13:06 | Chouser | knapr: GUIs are indeed stateful, but don't necessarily need globals. |
| 13:06 | cooldude127 | knapr: look at some of the haskell gui libraries to see how they are trying to unstateful guis |
| 13:06 | cooldude127 | it's hard to wrap your head around, i know i don't get it |
| 13:07 | Chouser | i 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:08 | cooldude127 | it is, but it can be represented functionally, it's just really confusing |
| 13:09 | danlarkin | it's a gui monad! *boggle* |
| 13:09 | cooldude127 | yeah maybe it would have made more sense if i could actually understand macros |
| 13:09 | cooldude127 | s/macros/monads |
| 13:11 | nymsy | hello |
| 13:11 | danlarkin | nymsy: hello! |
| 13:11 | cooldude127 | nymsy: hi |
| 13:14 | knapr | damn collision betwen paths, FileChooser uses \ and I use / , why is windows so stupid? |
| 13:17 | nymsy | so, I might loose connection... I'm in afghanistan, using a nokia phone for internet.. over a... maybe a 5 kbps link (little k) |
| 13:18 | nymsy | Thought I'd swing through irc and see how it was... webpages take forev' but this seems to work decent |
| 13:18 | Chouser | nymsy: interesting! |
| 13:19 | nymsy | Chouser: yea, makes for some interesting stress testing |
| 13:20 | noidi | a 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:20 | nymsy | So, 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:21 | Chouser | noidi: there are a couple differences. lists grow on the left, vectors grow on the right (when you conj) |
| 13:21 | hiredman | vectors are indexed (like an array) |
| 13:21 | hiredman | ,([:a :b :c] 1) |
| 13:21 | clojurebot | :b |
| 13:22 | hiredman | ,(get [:a :b :c] 1) |
| 13:22 | clojurebot | :b |
| 13:22 | Chouser | noidi: vectors provide constant-time random access to any element (by index) while lists can only be scanned in linear time |
| 13:22 | WizardofWestmarc | use vector when you want ~0(1) access time to any element in the list. |
| 13:22 | hiredman | ,((list :a :b :c) 0) |
| 13:22 | clojurebot | java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.IFn |
| 13:22 | hiredman | :( |
| 13:22 | noidi | thanks! |
| 13:23 | nymsy | So, 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:23 | Chouser | nymsy: and you have it running on your phone, right? |
| 13:27 | cooldude127 | wow lists really don't implement IFn? |
| 13:27 | cooldude127 | i guess that's to encourage you to use vectors for those situations |
| 13:27 | hiredman | yes |
| 13:30 | noidi | ,"testing" |
| 13:30 | noidi | darn :) |
| 13:30 | nymsy | Chouser: clojure or the internet? |
| 13:30 | noidi | ,([:a :b :c] 1) |
| 13:30 | clojurebot | :b |
| 13:30 | Chouser | noidi: clojurebot ignores you unless there are parens |
| 13:30 | noidi | ,(identity "testing") |
| 13:30 | clojurebot | "testing" |
| 13:30 | Chouser | nymsy: your clojure app runs on your phone, right? In fact, it's your IRC client? ;-) |
| 13:30 | noidi | cool :) |
| 13:34 | nymsy | heheh.. actually.. you could say I'm writing a simplified irc app |
| 13:34 | nymsy | but no, this runs on my computer.. I'm tethering. |
| 13:44 | nymsy | First question: what are the ways to get a value from a set? |
| 13:45 | nymsy | I saw select |
| 13:46 | Chouser | you can use 'get' or just treat the set as a fn. |
| 13:46 | Chouser | ,(#{:a :b :c} :b) |
| 13:46 | clojurebot | :b |
| 13:46 | Chouser | ,(#{:a :b :c} :d) |
| 13:46 | clojurebot | nil |
| 13:46 | nymsy | the comma.. is that clojure? |
| 13:47 | Chouser | no, that's clojurebot |
| 13:47 | durka42 | commas are whitespace |
| 13:47 | nymsy | ah |
| 13:47 | Chouser | , is whitespace in clojure |
| 13:47 | durka42 | clojurebot evalutes lines beginning with commas |
| 13:47 | nymsy | rgr |
| 13:47 | Chouser | ,#{:a,:b,:c} |
| 13:47 | Chouser | ,(prn #{:a,:b,:c}) |
| 13:47 | clojurebot | #{:a :b :c} |
| 13:48 | nymsy | yes, 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:49 | nymsy | I guess I'm wanting set to be more like a map |
| 13:49 | nymsy | Whereas, map already acts a little like a set, with unique keys |
| 13:49 | Chouser | nymsy: perhaps I misunderstood your question. A set contains only "keys" if you will, no values. Or the keys *are* the values. |
| 13:49 | danlarkin | gnuvince: s/language/state machine/ |
| 13:50 | nymsy | Chouser: right |
| 13:50 | noidi | why can't you use a map then? |
| 13:51 | nymsy | let me think of an example of what I'm trying to do |
| 13:51 | noidi | ,({:key :value} :key) |
| 13:51 | clojurebot | :value |
| 13:51 | nymsy | by the way, does clojurebot have cycle turned off? ;) |
| 13:52 | durka42 | you mean infinite loops? |
| 13:52 | Chouser | ,(take 7 (cycle [:chicken :egg])) |
| 13:52 | clojurebot | (:chicken :egg :chicken :egg :chicken :egg :chicken) |
| 13:53 | Chouser | he's got some protection against attempts at evilness. |
| 13:54 | nymsy | aye... so I've got a (def *clients* (ref #{})) |
| 13:54 | nymsy | for my irc like chat program |
| 13:55 | nymsy | (this is, by the way, based off of somebody's code from the list) |
| 13:56 | nymsy | and client is a (defstruct client-t :socket :output :reader :nick :uid :last-action-time) |
| 13:57 | Chouser | you want to be able to find the client struct from a given nick |
| 13:57 | Chouser | ? |
| 13:58 | nymsy | yes, but nicks can change, so each :nick starts as a (agent "anonymous") |
| 13:58 | nymsy | so I have to do derefing while searching the #{} |
| 13:58 | Chouser | yeah |
| 13:59 | knapr | anyone 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:59 | Chouser | it seems likely to me that the nicks should be refs instead of agents |
| 14:01 | nymsy | Chouser: this is one area I'm lost in.. knowing when to use each of the mutability tools |
| 14:01 | nymsy | I've read the differences, but I don't yet understand what exactly is being described |
| 14:02 | Chouser | I don't have an extremely firm grasp on it myself... |
| 14:02 | nymsy | I've dealt a little with locking in Java, but I'm still a noob |
| 14:03 | nymsy | what pastebin do you guys use? |
| 14:03 | Chouser | but 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:03 | durka42 | clojurebot: paste? |
| 14:03 | clojurebot | lisppaste8, url |
| 14:03 | lisppaste8 | To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste. |
| 14:03 | Chouser | "agents are for values"... |
| 14:04 | Chouser | the only coordinated reference type is the ref. |
| 14:04 | nymsy | Ok, so a collection of refs inside of a ref is normal? |
| 14:05 | Chouser | nymsy: it can be, though you could just have the top-level ref and swap out the whole collection when you update a nick |
| 14:08 | nymsy | I'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:08 | nymsy | if the server became big, how big would that operation become? |
| 14:09 | Chouser | no, it doesn't. clojure collections share as much data as they can with earlier versions of themselves |
| 14:09 | nymsy | so a ref-set is as efficient as, say, an assoc inside of a ref? |
| 14:09 | nymsy | (erm, on a ref inside the ref) |
| 14:11 | Lau_of_DK | Good evening all |
| 14:11 | nymsy | ok, watch out.. here comes some ugly code |
| 14:12 | lisppaste8 | nymsy pasted "blah.clj" at http://paste.lisp.org/display/74360 |
| 14:13 | nymsy | most of these functions are in transition, so they're ugly |
| 14:13 | nymsy | The arity in most is accommodating either access to global state, or more pure function |
| 14:14 | nymsy | One 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:15 | Chouser | I 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:16 | Chouser | that is, the collections themselves could get many times larger without either solution becoming a whole lot slower. |
| 14:17 | nymsy | ok |
| 14:17 | noidi | is anyone else here using VimClojure? |
| 14:18 | Chouser | (filter-for #(deref (:nick %)) "joe" *clients*) |
| 14:19 | nymsy | What if the value I'm looking for isnt a ref? |
| 14:20 | Chouser | then leave out the 'deref' part as you already do. |
| 14:21 | nymsy | I 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:21 | Chousuke | (doc get-in=) |
| 14:21 | clojurebot | excusez-moi |
| 14:22 | Chousuke | (doc get-in) |
| 14:22 | clojurebot | returns the value in a nested associative structure, where ks is a sequence of keys; arglists ([m ks]) |
| 14:22 | nymsy | Chousuke: works for maps inside of sets? |
| 14:22 | Chouser | oh. Well, I suppose you could add a phrase to filter-for: (if (instance? clojure.lang.IRef x) @x x) |
| 14:23 | Chousuke | nymsy: hm, I don't think so. |
| 14:23 | Chousuke | nymsy: since to get the map, you need to have the map already |
| 14:23 | Chousuke | ,(get-in {:m [:a :b {:c :d}]} [:m 2 :c]) |
| 14:23 | clojurebot | :d |
| 14:23 | Chouser | it probably does work on sets, but since you'd have to supply the whole value you're looking for, it would help much. |
| 14:25 | nymsy | if 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:25 | nymsy | so I could get-in on the for |
| 14:25 | Chousuke | maybe you should index the clients by their nickname? :/ |
| 14:25 | Chousuke | a map of nicks to the client data |
| 14:26 | Chouser | but he also sometimes looks them up by :uid, and the :nick can change. |
| 14:26 | Chousuke | hmm |
| 14:26 | nymsy | right, sometimes |
| 14:26 | Chouser | sets of maps may not be too terrible -- I can't quite decide what would do better. |
| 14:27 | nymsy | I guess get-in with for is useless, since I've already dug down |
| 14:27 | Chouser | it *might* make sense to maintain two maps -- one from uid to client-struct, the other from nick to client-struct. |
| 14:27 | Chouser | it would make lookups faster and more convenient |
| 14:27 | Chouser | presumably uids don't change, so that'd be fine. |
| 14:28 | nymsy | would each collection point to the same set of objects? |
| 14:28 | Chouser | when you update a nick, though, you've have to fix up both maps. That might still be easier than what you're doing. |
| 14:28 | Chousuke | if the client struct is wrapped in a ref, keeping them in sync would be easy too |
| 14:28 | Chouser | nymsy: either that, or the uid could be the "canonical" map, and you could have a separate map of nick to uid |
| 14:29 | Chousuke | hm, that sounds better. |
| 14:29 | Chousuke | could have multiple nicknames that way, too :P |
| 14:29 | nymsy | aye |
| 14:29 | nymsy | how would this seperate map work? |
| 14:30 | Chousuke | just (def nick-to-uid (ref {}))? :) |
| 14:30 | Chouser | I 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:30 | Chouser | right, in a ref. |
| 14:32 | nymsy | So, to send bob a message, (*nicks* "bob") > 9833498 and then (send-message-to 9833498 "msg") |
| 14:32 | nymsy | kinda deal |
| 14:33 | Chouser | right |
| 14:33 | nymsy | and maps ensure that there can only be one "bob" in *nicks* and only one uid in *uid*s |
| 14:34 | Chouser | still faster and more convenient than walking the set of all clients looking for a "bob" |
| 14:34 | nymsy | true |
| 14:36 | nymsy | I wonder if one could do a two-key-one-value map, where it was like {key-nick key-uid value, &} |
| 14:36 | durka42 | i mean, you could emulate that with two maps, or a list of triplets |
| 14:37 | Chouser | well, 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:37 | nymsy | with performance comparable by a constant factor to normal maps... |
| 14:38 | nymsy | what about {(or this that) value} |
| 14:39 | Chouser | you could put the value in there twice: {key-nick value key-uid value} |
| 14:39 | nymsy | or {#(or (= % this) (= % that)) value} |
| 14:40 | durka42 | ,(first (filter #(or (= "bob" %1) (= "bob" %2)) {["alex" 134] :alex, ["bob" 532] :bob, ["joe 1395876] :joe})) |
| 14:40 | clojurebot | Eval-in-box threw an exception:EOF while reading string |
| 14:40 | durka42 | ,(first (filter #(or (= "bob" %1) (= "bob" %2)) {["alex" 134] :alex, ["bob" 532] :bob, ["joe" 1395876] :joe})) |
| 14:40 | clojurebot | java.lang.IllegalArgumentException: Wrong number of args passed to: sandbox$eval--802$fn |
| 14:40 | durka42 | whoops |
| 14:40 | durka42 | ,(first (filter #(or (= "bob" %) (= "bob" %)) {["alex" 134] :alex, ["bob" 532] :bob, ["joe" 1395876] :joe})) |
| 14:40 | clojurebot | nil |
| 14:40 | durka42 | i should test these things |
| 14:40 | durka42 | ,(first (filter #(or (= "bob" (first %)) (= "bob" (second %))) {["alex" 134] :alex, ["bob" 532] :bob, ["joe" 1395876] :joe})) |
| 14:40 | clojurebot | nil |
| 14:40 | Chouser | yes. you should. :-) |
| 14:41 | nymsy | *as freenode crashes* |
| 14:41 | durka42 | ,(second (first (filter #(or (= "bob" (first (first %))) (= "bob" (second (first %)))) {["alex" 134] :alex, ["bob" 532] :bob, ["joe" 1395876] :joe}))) |
| 14:41 | clojurebot | :bob |
| 14:42 | durka42 | ,(second (first (filter #(or (= 134 (first (first %))) (= "bob" (second (first %)))) {["alex" 134] :alex, ["bob" 532] :bob, ["joe" 1395876] :joe}))) |
| 14:42 | clojurebot | nil |
| 14:42 | durka42 | never mind |
| 14:42 | durka42 | that got way too unwieldy |
| 14:42 | durka42 | don't do that |
| 14:44 | nymsy | ,({#(or (= % "bob") (= % 111)) "socket"} "bob") |
| 14:44 | clojurebot | nil |
| 14:44 | nymsy | hmm |
| 14:44 | Chouser | yeah, that's not going to work. |
| 14:44 | hiredman | well when data structures get unweidly, you build new functions to wield them |
| 14:45 | Chouser | ,({"bob" "socket" 111 "socket"} "bob") |
| 14:45 | clojurebot | "socket" |
| 14:45 | Chouser | just as good, and actually works. |
| 14:45 | nymsy | rgr |
| 14:45 | Chouser | :-) |
| 14:45 | nymsy | is there a way to make both "socket"s point to the same socket? |
| 14:46 | nymsy | so as to mitigate doubling the actual size in memory? |
| 14:46 | Chousuke | nymsy: just bind it to a name first and use that name as the value. |
| 14:46 | Chousuke | instead of a literal |
| 14:46 | WizardofWestmarc | actually might the JVM be smart enough to not double use literals? |
| 14:46 | Chousuke | probably, but that's not guaranteed. |
| 14:46 | WizardofWestmarc | should be possible to find out |
| 14:47 | nymsy | they won't be literals in practice |
| 14:47 | nymsy | if by literals you mean those strings |
| 14:47 | WizardofWestmarc | right |
| 14:47 | Chouser | if you do (assoc *client* "bob" socket 111 socket), they'll both point to the same socket object |
| 14:47 | Chouser | it's not going to copy it. |
| 14:47 | nymsy | they'll be complicated structs |
| 14:47 | Chousuke | nymsy: even better then: they won't be copied. |
| 14:47 | Chousuke | no assignment in java ever copies anything; except primitives. |
| 14:48 | WizardofWestmarc | Chouser: what about :a "bob" :b "bob"? |
| 14:48 | WizardofWestmarc | does bob show up twice in memory? |
| 14:48 | Chousuke | WizardofWestmarc: that's probably an implementation detail |
| 14:48 | nymsy | hmm |
| 14:48 | WizardofWestmarc | it could be specified in the jvm specification |
| 14:48 | Chouser | ,(apply identical? (map val {:a "bob" :b "bob"})) |
| 14:48 | clojurebot | true |
| 14:48 | WizardofWestmarc | so that all VMs would require it |
| 14:49 | Chouser | but I think Clojure is providing that and doesn't guarantee it. |
| 14:49 | nymsy | so where might this scheme cause a hicup? |
| 14:49 | Chouser | ,(apply identical? (map val {:a (String. "bob") :b "bob"})) |
| 14:49 | clojurebot | false |
| 14:49 | hiredman | ,(apply identical? (map val {:a (Object.) :b (Object .)}) |
| 14:49 | clojurebot | Eval-in-box threw an exception:EOF while reading |
| 14:49 | hiredman | ,(apply identical? (map val {:a (Object.) :b (Object .)})) |
| 14:49 | clojurebot | java.lang.Exception: Expecting var, but Object is mapped to class java.lang.Object |
| 14:49 | hiredman | bah |
| 14:50 | Chousuke | the answer is going to be false :p |
| 14:50 | hiredman | strings are sort of magic |
| 14:50 | hiredman | yeah |
| 14:50 | Chouser | nymsy: if you want to change something in a socket struct, you'll have to do that double-assoc again. |
| 14:50 | Chousuke | strings are guaranteed to be immutable so the JVM can optimise literals to be the same object. |
| 14:51 | Chouser | Chousuke: I think it's Clojure that's deciding to intern the strings. I don't think it's always done that. |
| 14:51 | hiredman | clojurebot: max people? |
| 14:51 | clojurebot | max people is 129 |
| 14:52 | Chouser | nymsy: while if you had *nicks* that only pointed to uids, then you'd only have to update *clients* for changes to client struct. |
| 14:52 | Chousuke | unless you use refs; like (def a (ref {:a 1})) (def b a), (dosync (commute a assoc :b 1)) @b ; -> {:a 1 :b 1} |
| 14:52 | nymsy | Ok, better than socket, lets say (assoc *clients* "bob" client-struct-1 111 client-struct-1) |
| 14:53 | Chouser | sorry, I meant "client struct" not "socket struct" |
| 14:54 | nymsy | oughtn'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:54 | Chousuke | nymsy: no. |
| 14:54 | Chouser | but 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:54 | nymsy | hmm.. associng "bob" to a new value will leave the old value attached to 111 |
| 14:55 | Chouser | ...in which case you have to put that new struct back into the map in all the appropriate places. |
| 14:55 | Chouser | nymsy: right. |
| 14:55 | Chousuke | nymsy: that's exactly how it's supposed to be. |
| 14:55 | nymsy | so (assoc *client* "bob" struct-ref 111 struct-ref) |
| 14:56 | Chousuke | nymsy: that might work. |
| 14:56 | hiredman | so you write a double-assoc fn |
| 14:56 | Chousuke | but I'd rather do two separate maps. |
| 14:56 | Chousuke | one with nicks to ids and one with id -> struct |
| 14:56 | Chousuke | then, whenever I want to "modify" a struct, I actually just do assoc-in on the id->struct map |
| 14:57 | Chousuke | yielding a new id->struct map |
| 14:57 | hiredman | is there a reason why you need both? why not have nick or uid as part of the struct? |
| 14:57 | hiredman | and the other as the key? |
| 14:57 | Chousuke | hiredman: he needs to look them up using either. |
| 14:57 | hiredman | :( |
| 14:58 | hiredman | sounds like two maps then |
| 14:58 | nymsy | I 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:59 | Chousuke | having two maps is easier IMO :/ |
| 14:59 | Chouser | do you ever need to go from uid to nick? |
| 14:59 | nymsy | When updating nick |
| 14:59 | Chouser | or only from (nick or uid) to struct |
| 14:59 | Chousuke | but having the nick and UID in the *same* map as keys pointing to a struct is wrong, IMO. |
| 15:00 | Chousuke | because then you need to update both |
| 15:00 | Chousuke | or use refs, but that's a bit ugly too |
| 15:00 | hiredman | ,(let [x (ref :somestruct)] [{111 x} {"bob" x}]) |
| 15:00 | clojurebot | [{111 #<Ref clojure.lang.Ref@8730b8>} {"bob" #<Ref clojure.lang.Ref@8730b8>}] |
| 15:01 | Chousuke | yeah, that would work, but is rather ugly. |
| 15:01 | hiredman | Chousuke: if you don't println it, it won't see it :P |
| 15:01 | nymsy | Whys it ugly? I think it's pretty |
| 15:01 | Chousuke | you'll have lots of refs though :/ |
| 15:04 | nymsy | here'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:04 | hiredman | ! |
| 15:05 | nymsy | a 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:05 | nymsy | yes! :) |
| 15:05 | nymsy | so thats another ref for *rooms* |
| 15:05 | nymsy | and another for *servers* |
| 15:07 | nymsy | so how to manage nicks and uids is important |
| 15:08 | nymsy | do I map uids to rooms and servers, or nicks? probably uids |
| 15:14 | fffej | If 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:14 | Chouser | (doc declare) |
| 15:14 | clojurebot | defs the supplied var names with no bindings, useful for making forward declarations.; arglists ([& names]) |
| 15:14 | fffej | thanks! |
| 15:14 | nymsy | hmm. 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:19 | nymsy | Or I could add a :rooms key to the client struct |
| 15:19 | hiredman | it might be easiest to have rooms as a special type of user |
| 15:20 | Chouser | so 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:20 | nymsy | and pass *clients* to broadcast-to-room [clients msg] |
| 15:20 | hiredman | so when a user sends to a :room user, it gets sent to all the other users that are talking to that room |
| 15:20 | WizardofWestmarc | that or keep an updated list of users by room |
| 15:21 | WizardofWestmarc | so when they move room remove from old room add to the new room |
| 15:22 | nymsy | WizardofWestmarc: 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:22 | WizardofWestmarc | then just write a macro to both change the structure's room # and update the room list's info |
| 15:22 | WizardofWestmarc | eh |
| 15:22 | WizardofWestmarc | if you want to send info to specific rooms from the server I would keep that info server side as well |
| 15:23 | nymsy | well, a user can be in many rooms |
| 15:23 | cooldude127 | i 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:23 | WizardofWestmarc | ah |
| 15:23 | WizardofWestmarc | still |
| 15:23 | WizardofWestmarc | then just remove the always remove constraint |
| 15:23 | WizardofWestmarc | but I'd STILL keep a hash of rooms that contain a list of users in that room |
| 15:24 | hiredman | nymsy: someone, technomancy?, is doing some kind of clojure tutorial writing a muc, which might be interesting to look at |
| 15:24 | nymsy | right, thats the other option |
| 15:24 | nymsy | hiredman: wilco |
| 15:25 | WizardofWestmarc | yeah Technomancy's doing it |
| 15:25 | WizardofWestmarc | it's in his github acct |
| 15:25 | hiredman | orly |
| 15:25 | cooldude127 | ya rly |
| 15:25 | cooldude127 | where is that guy anyway? |
| 15:26 | hiredman | ah http://github.com/technomancy/mire/tree/master |
| 15:26 | nymsy | that 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:27 | Chouser | nymsy: that strikes me as the most natural approach. |
| 15:28 | nymsy | the 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:28 | Chouser | on 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:29 | nymsy | clojure.set/index? |
| 15:29 | hiredman | ,(doc clojure.set/index) |
| 15:29 | clojurebot | "([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:29 | hiredman | mine just exploded |
| 15:29 | hiredman | my head just exploded |
| 15:29 | nymsy | me too :) |
| 15:29 | Chouser | I've not written anything in that style, and I don't know how convenient or efficient that might be. |
| 15:30 | durka42 | sounds similar to group-by |
| 15:30 | nymsy | I'd like, also, for this to be an example of doing distributed text chat in a functional way |
| 15:30 | nymsy | minimizing global state and maximizing the sharing of immutable messages |
| 15:31 | hiredman | you could do trees with zipper :P |
| 15:31 | Chouser | yikes |
| 15:31 | nymsy | Chouser: I see the doc, but I don't really see it.. can you explain how indexing helps here? |
| 15:33 | Chouser | the 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:33 | Chouser | right? |
| 15:33 | nymsy | right... |
| 15:33 | hiredman | ,(doc defonce) |
| 15:33 | clojurebot | "([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:33 | hiredman | no kidding |
| 15:34 | Chouser | like 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:34 | Chouser | that might be the most complicated one, which still isn't too terrible. |
| 15:34 | nymsy | exactly |
| 15:35 | Chouser | but 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:36 | nymsy | right.. that's what worries me about the copulating *maps* |
| 15:36 | Chouser | so 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:36 | nymsy | right |
| 15:36 | Chouser | so, for example, the layout you had at the beginning. a set of structs. |
| 15:38 | Chouser | then 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:38 | nymsy | which is how it is now? |
| 15:39 | Chouser | make-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:40 | nymsy | oh... wow |
| 15:40 | Chouser | that way all your lookups are still fast and convenient |
| 15:40 | Chouser | all the 'read' code would be quite simple, and even the 'update' code would be more simple than the alternative. |
| 15:41 | nymsy | hmm.. index attaches an index number to each item in the set? at the top level? |
| 15:41 | Chouser | the downside (or one of them, I think) would be that make-it-so would be O(n) on clients. :-/ |
| 15:41 | Chouser | nymsy: ah, on, it pulls out a key from the set of maps, and makes a map to go from ... |
| 15:42 | Chouser | hang on... |
| 15:44 | Chouser | ,(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:44 | clojurebot | Eval-in-box threw an exception:EOF while reading |
| 15:44 | cooldude127 | someone has unbalanced parens :) |
| 15:45 | cooldude127 | or just too much stuff copied |
| 15:45 | Chouser | nasty paste error. sorry |
| 15:45 | Chouser | ,(let [myset '#{{a 1 b 2} {a 3 b 4} {a 5 b 6}}, idx (set/index myset '[b])] (idx {'b 6})) |
| 15:45 | clojurebot | #{{b 6, a 5}} |
| 15:45 | Lau_of_DK | Chouser: If you chat from ERC you get Lisp highlighting in your chat :) |
| 15:45 | Chouser | ok, so there's your canonical set, "myset" |
| 15:46 | nymsy | rgr |
| 15:46 | Chouser | using set/index gives me a map from |
| 15:46 | Chouser | from {b ..whatever..} to the whole struct |
| 15:46 | knapr | http://cpp.ninjacodemonkeys.org/5080 , is that starting the player before ti starts the thread and thus the player doesnt run in the thread? |
| 15:47 | Chouser | so then it's easy to look things up based on values of b |
| 15:47 | Chouser | but I could just as easily produce as many indexes for as many different keys as I want. |
| 15:48 | hiredman | knapr: you most likely want #(.play player) |
| 15:48 | nymsy | ok.. 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:48 | hiredman | knapr: unless (.play player) returns a Runnable |
| 15:49 | Chouser | nymsy: 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:49 | hiredman | Thread. will take 0 or 1 arg, the one are being a function of no arguments |
| 15:49 | Chouser | ...until someone changes rooms or nicks, and then you have to reproduce all the maps. |
| 15:49 | hiredman | which #(.play player) will give you |
| 15:50 | knapr | hiredman: ok and then it is started when i start the thread? |
| 15:50 | hiredman | yes |
| 15:51 | nymsy | Chouser: 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:51 | knapr | hiredman: thanks! that works. |
| 15:51 | nymsy | so I deref *clients* once for each message |
| 15:52 | Chouser | nymsy: sounds reasonable. |
| 15:52 | nymsy | the rest of the pathway logic assumes that worldview.. so would it hurt to reindex on each message creation? |
| 15:53 | Chouser | might be more work than necessary, if multiple messages are sent between world state changes, which seems likely. |
| 15:54 | hiredman | you toggle a dirty bit when you dirty something |
| 15:54 | Chouser | I'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:54 | nymsy | well, theres one key that updates often |
| 15:55 | nymsy | the new one that isn't used yet, :last-action-time ... which I thought I'd use to create a connection time-out facility |
| 15:56 | BigTom | Hi |
| 15:56 | nymsy | hello |
| 15:56 | drewr | Has anyone had any problems using clojure.contrib.sql with postgres? |
| 15:56 | BigTom | I am doing something dumb |
| 15:57 | nymsy | Chouser: how bad is O(n) ? |
| 15:57 | BigTom | I think |
| 15:57 | Chouser | nymsy: double the number of users, double the processing time. |
| 15:57 | BigTom | I am getting a stack overflow on a recur but I cannot see why |
| 15:57 | Chouser | now the theorists are going to hang me, but that's the idea anyway. |
| 15:57 | nymsy | Oh.. log(n) is the better one, right? |
| 15:57 | Hun | why? it's correct. |
| 15:58 | Hun | but you should always look at the constants |
| 15:58 | Chouser | nymsy: O(1) < O(log(n)) < O(n) < O(n*log(n)) < O(n*n) ... |
| 15:58 | BigTom | are there any common mistakes that do that? |
| 15:58 | Hun | when n are only your users, and you're thinking about people, O(n) might cut it |
| 15:58 | hiredman | BigTom: lets see some code |
| 15:58 | Chouser | those are the commone ones. |
| 15:59 | Hun | as the growing of population will sooner or later stop. usually before O(n) on it becomes a problem |
| 15:59 | hiredman | Hun: and people die |
| 15:59 | Chouser | Hun: are you a theorist? Are you not hanging me!? |
| 15:59 | Hun | Chouser: computer science student, 7th semester |
| 16:00 | BigTom | hmm, hang on, I'm on two machines |
| 16:00 | Chouser | BigTom: i think we're going to have to see the code. |
| 16:00 | Chouser | oh, sorry, someone already asked. |
| 16:00 | Hun | i've seen enough theorists forget to mention that you also have to look at the order of magnitude of n |
| 16:00 | Hun | hiredman: fewer than are born |
| 16:00 | Hun | growth is still an exponential curve. that means it will sooner or later crash :) |
| 16:00 | Chouser | Well, I thought someone would complain that I said "processing time" instead of "complexity" or something. |
| 16:00 | BigTom | how much can I post on here? |
| 16:01 | Chouser | BigTom: use lisppaste for more than 1 line |
| 16:01 | hiredman | clojurebot: paste? |
| 16:01 | clojurebot | lisppaste8, url |
| 16:01 | nymsy | if you have to ask... |
| 16:01 | lisppaste8 | To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste. |
| 16:02 | hiredman | clojurebot: what is the most horrible thing? |
| 16:02 | clojurebot | the most horrible thing is http://themosthorriblething.com/index.php?h=my+algorithm+is+O%28n*n%29 |
| 16:02 | lisppaste8 | BigTom pasted "recur problem" at http://paste.lisp.org/display/74372 |
| 16:02 | nymsy | so... 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:02 | Hun | Chouser: the complexity ain't gonna change |
| 16:03 | Hun | that problem is intrinsically bound by O(n) |
| 16:03 | Hun | you sooner or later have to see every entry in the relation user <=> room for doing a dispatch |
| 16:03 | nymsy | not all the time |
| 16:04 | Hun | so you can't get lower. you can just cut it for dispatching only on the current room |
| 16:04 | Hun | and if it's just O(n) for a single room, so be it |
| 16:04 | nymsy | only users you see in rooms your in, at a constant rate.. for interactive consistency |
| 16:04 | Hun | there are a lot bigger fish to fry until profiling |
| 16:05 | AWizzArd | I 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:05 | AWizzArd | Do I remember that correctly? |
| 16:05 | nymsy | those 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:06 | Chouser | AWizzArd: a compiled fn still is a Java class, but if created via 'eval' will now be GC'd |
| 16:06 | Hun | AWizzArd: i think (not sure) that are the closure class, not the instance |
| 16:07 | Hun | so your code won't leak if you use closures in a loop, but memory consumption will be constantly sligthly higher |
| 16:07 | knapr | what 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:07 | knapr | hiredman: do you know how to pause a thread? |
| 16:07 | AWizzArd | knapr: from outside of a thread you mean? |
| 16:08 | hiredman | BigTom: I am not sure, but you may want to filter (rest ns) not ns |
| 16:09 | AWizzArd | knapr: check out http://java.sun.com/javase/6/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html |
| 16:09 | AWizzArd | "What should I use instead of Thread.stop?" is your question |
| 16:09 | hiredman | knapr: I am bet the player has some sort of pause method, I would recommend using that instead of pausing the thread |
| 16:10 | nymsy | yea, 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:10 | hiredman | AWizzArd: he is writting an mp3 player, and, having gotten it to play, he wants to get it to pause |
| 16:10 | nymsy | (I'm probably a less than average case) |
| 16:11 | AWizzArd | knapr: also think about Rich Hickeys "ants.clj" example, where he uses the variable *running* for signalling a stop. |
| 16:11 | BigTom | hiredman: Doh! Told you it was something stupid |
| 16:11 | BigTom | hiredman: thanks |
| 16:11 | hiredman | there are 647 people in #haskell |
| 16:11 | hiredman | BigTom: did that fix it? I said I wasn't sure |
| 16:11 | AWizzArd | clojurebot: max people |
| 16:11 | clojurebot | max people is 129 |
| 16:11 | nymsy | youch |
| 16:12 | AWizzArd | let's not forget this number was around 80 a few months ago |
| 16:12 | hiredman | clojurebot's max people was broken for a day or two |
| 16:12 | Hun | nymsy: about 1200, all channels i'm in combined. with about 200 collisions |
| 16:12 | hiredman | so maybe it missed everyone |
| 16:12 | BigTom | hiredman: yes, still slow as hell, it was frustrating because this is where I am starting from |
| 16:13 | nymsy | Hun.. Would you say you're average? |
| 16:13 | nymsy | (in terms of irc connectedness?) |
| 16:13 | Hun | not really. considering irc, most people are way fewer |
| 16:13 | BigTom | ah, spoke too soon, its just happening later on |
| 16:13 | Hun | bad english. most people are in fewer channels |
| 16:13 | Hun | at least those i know. i'd say about 400 might be a good average case |
| 16:14 | BigTom | hiredman: I put the whole thing up, it is breaking somewhere between 10,000 and 100,000 |
| 16:14 | Lau_of_DK | Is the code on Sourceforge still current ? |
| 16:15 | nymsy | right... 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:15 | AWizzArd | hiredman: btw, does the clojurebot automatically deny all forms in which *compile-path* is used? |
| 16:15 | AWizzArd | ,*compile-path* |
| 16:15 | AWizzArd | ,(print *compile-path*) |
| 16:15 | clojurebot | nil |
| 16:16 | nymsy | any ninjas out there able to discern the complexity of an indexing operation on 500 clients with 10 keys? |
| 16:16 | AWizzArd | hmm, funny, some hours ago it responded with ,,denied" |
| 16:16 | nymsy | for this particular situation? |
| 16:16 | Hun | nymsy: neglectable for now |
| 16:16 | nymsy | Hun: I agree |
| 16:16 | Hun | you'd have a hard time measuring it with 10000 test users |
| 16:16 | BigTom | Should you ever get StackOverflow with recur? if it is coded correctly? |
| 16:17 | Hun | should be easy with 100000 users. get to that point before optimizing :) |
| 16:17 | nymsy | heh |
| 16:18 | Chouser | BigTom: 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:18 | nymsy | anyone guestimate how long it would take to scan a set of 500 structs with 10 keys each? |
| 16:18 | Chouser | no need to guess. |
| 16:18 | Hun | nymsy: what do you mean by scan? |
| 16:18 | hiredman | nymsy: compared to the time to send/recv messages? none at all |
| 16:19 | hiredman | by that I mean network io |
| 16:19 | BigTom | Chouser: so something is hanging onto stack frames somewhere? |
| 16:20 | hiredman | clojurebot: Sieve? |
| 16:20 | clojurebot | No entiendo |
| 16:20 | hiredman | clojurebot: google Genuine Sieve of Eratosthenes |
| 16:20 | clojurebot | First, out of 850 results is: |
| 16:20 | clojurebot | The Genuine Sieve of Eratosthenes |
| 16:20 | clojurebot | http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf |
| 16:21 | BigTom | hiredman: is that for me? |
| 16:22 | hiredman | BigTom: it may help |
| 16:22 | BigTom | :-) |
| 16:22 | Chouser | ,(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:22 | clojurebot | #{{0 99, 1 0, 2 0, 3 0, 4 0, 5 0, 6 0, 7 0, 8 0, 9 0}} |
| 16:22 | clojurebot | "Elapsed time: 121.706 msecs" |
| 16:22 | hiredman | I think the code is all in haskell, so it may just kill you |
| 16:23 | BigTom | ah well |
| 16:23 | Chouser | one tenth of a second to create the set and all the maps from scratch, index them, and look up one of them. |
| 16:23 | BigTom | I knew I would have to have a proper go at it eventually |
| 16:24 | BigTom | It can go on the pile with the pythagorean triples |
| 16:25 | nymsy | wow |
| 16:25 | nymsy | thats ninja right there |
| 16:26 | Chouser | yeah, clojure is definitely too fast. Rich should sneak in a spin delay somewhere so he can "add speed" later as needed. |
| 16:27 | ecret | AWizzArd: 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:27 | ecret | Any idea what is wrong? I did what yoou suggested, i added /home/eli/clojure/classes to my classpaths |
| 16:30 | BigTom | Just to clarify something, recur is not a total substitute for Tail call is it? |
| 16:30 | Hun | it isn't |
| 16:30 | Hun | a tail call can call another function |
| 16:30 | BigTom | You cannot build results on the climb out from the recursion |
| 16:30 | knapr | hmm but isnt there jsut a simple way to kill a thread forever? |
| 16:30 | knapr | and 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:30 | BigTom | so you have to use some kind of aggregator |
| 16:30 | nymsy | so, 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:30 | Hun | that means that you can have f => g(x) and g => f(x) |
| 16:30 | Hun | and it works |
| 16:31 | Hun | BigTom: that's the trick in tail recursion |
| 16:31 | Chouser | BigTom: no, building values while returning isn't a tail call, so won't be optimized by normal TCO either. |
| 16:31 | knapr | how do i pronounce sieve? |
| 16:31 | Hun | it works well if you have an iterative algorithm. that means `doesn't need to do anything to clean stuff up' |
| 16:31 | hiredman | BigTom: as far as I am aware, in proper tail calls you also need an accumulator |
| 16:31 | Hun | hiredman: nope. |
| 16:32 | Chouser | knapr: dunno how you pronounce it, but I say "siv" |
| 16:32 | hiredman | Hun: ok, you don't need, but you would need one to do what he is talking about |
| 16:32 | Hun | the accumulator is needed to translate a recursive algorithm into a tailrecursive into an iteration |
| 16:32 | Hun | yep |
| 16:32 | BigTom | MAybe I am misremembering |
| 16:32 | nymsy | i think its seeve.. like, to _leave_ something some where |
| 16:32 | Hun | and using an accumulator is /very/ pointless |
| 16:32 | hiredman | clojurebot: whose job is to current hiredman when he says something that is not completely 100% correct? |
| 16:32 | clojurebot | that is scode's job |
| 16:33 | hiredman | Hun: see, it isn't even your job |
| 16:33 | Hun | you're exchanging the system's tested and good stack implementation for your own ad-hoc one |
| 16:33 | Hun | hiredman: so what? :) |
| 16:33 | hiredman | :P |
| 16:34 | Chouser | "sieve" rhymes with "give": http://en.wiktionary.org/wiki/sieve |
| 16:34 | Hun | i'm having an exam tomorrow and want to hang out in irc to forget it for now :) |
| 16:34 | BigTom | Hun: confused now, if I want to accumulate a value via recursion and TCO what do I do? |
| 16:34 | Hun | BigTom: you might as well just use recursion |
| 16:34 | Chouser | nymsy: I really wouldn't worry about throttling and such until you see it. |
| 16:34 | Hun | when you need an accumulator for tail recursion, you need /exactly/ as much space and time as when using recursion |
| 16:34 | hiredman | BigTom: you might as well use reduce |
| 16:35 | Hun | (in a proper working compiler at least) |
| 16:35 | Hun | BigTom: and think about it |
| 16:35 | Chouser | nymsy: regardless if you've got an O(1) or O(n) algorithm underneath. :-) |
| 16:35 | Hun | when 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:35 | hiredman | ,(reduce + 0 (range 10)) |
| 16:35 | clojurebot | 45 |
| 16:36 | nymsy | Chouser: aye |
| 16:36 | hiredman | ,(reduce conj [] (range 10)) |
| 16:36 | clojurebot | [0 1 2 3 4 5 6 7 8 9] |
| 16:36 | nymsy | Chouser: I think you hit the nail on the head with the indexing |
| 16:36 | kotarak | ,(into [] (range 10)) |
| 16:36 | clojurebot | [0 1 2 3 4 5 6 7 8 9] |
| 16:36 | nymsy | I appreciate the help |
| 16:36 | hiredman | kotarak: I was demonstrating recude |
| 16:36 | Chouser | nymsy: well, I'd be curious to know how it goes. |
| 16:36 | hiredman | reduce |
| 16:37 | BigTom | Thanks, maybe I need to rethink stuff |
| 16:37 | BigTom | My scheme days are long past |
| 16:37 | Hun | that's the proper way to think :) |
| 16:37 | Chouser | nymsy: like I said, I've not actually used that kind of pattern yet. |
| 16:37 | kotarak | hiredman: geez. Rich had to show me this twice before I remembered into. :] |
| 16:38 | BigTom | Hun: so when do you use recur? |
| 16:38 | nymsy | chouser: it seems more functional, right? I think it's the way to go.. also easier than keeping track of all those globals |
| 16:41 | nymsy | If 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:41 | Hun | BigTom: i usually don't. i try to use the normal combinators, or build a full-fetched state-machine |
| 16:41 | bakkdoor | hi. |
| 16:41 | hiredman | fetched? |
| 16:41 | BigTom | Hun: fair enough |
| 16:41 | Hun | for the state-machine, recur is good enough |
| 16:42 | BigTom | Hun: this is my first hard core foray into Functional approaches so I'll take all the advice I can |
| 16:42 | bakkdoor | is 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:42 | Hun | if you tried it once, a state machine can be expressed pretty well by recursion when you have TCO |
| 16:42 | hiredman | I think I used different seq functions more then recur for project euler stuff |
| 16:42 | BigTom | hiredman: interesting |
| 16:42 | hiredman | filter, map, for |
| 16:43 | BigTom | hun: what are the normal combinators? |
| 16:43 | hiredman | like for primes I have a lazy seq that sieves out non-primes |
| 16:43 | Hun | map, reduce, filter (and specializations of those) |
| 16:43 | hiredman | I think I may have stole that from the google group though |
| 16:43 | Hun | i'm not sure what extended versions are in clojure right now. |
| 16:43 | Hun | combinators are fun :) |
| 16:43 | hiredman | apply |
| 16:44 | BigTom | Thanks, I have another avenue to study |
| 16:44 | hiredman | hmmm |
| 16:44 | hiredman | looking at my euler.clj I did use recur for #10 |
| 16:44 | Hun | map and filter are easy. take your time with reduce. it's mighty and a bit non-intuitive |
| 16:45 | BigTom | Hun: funnily I am fairly happy with reduce, I think it is hard in most languages so I worked on it |
| 16:46 | BigTom | I think I really need to get my head around laziness |
| 16:46 | Hun | yep. i suggest reading the stream chapter in SICP |
| 16:46 | hiredman | clojurebot: sicp |
| 16:46 | clojurebot | sicp is http://www.codepoetics.com/wiki/index.php?title=Topics:SICP_in_other_languages:Clojure:Chapter_1 |
| 16:46 | Hun | eye-opening for lazy stuff |
| 16:46 | hiredman | gah |
| 16:46 | BigTom | hiredman: gah? |
| 16:46 | hiredman | clojurebot: don't you know where the pdf is? |
| 16:46 | clojurebot | Titim gan �ir� ort. |
| 16:46 | Hun | read the text and the code. reading just one doesn't really work |
| 16:47 | nymsy | hiredman: it took me months to find the pdf |
| 16:47 | hiredman | clojurebot: google sicp pdf |
| 16:47 | clojurebot | First, out of 18900 results is: |
| 16:47 | clojurebot | Structure and Interpretation of Computer Programs |
| 16:47 | clojurebot | http://deptinfo.unice.fr/~roy/sicp.pdf |
| 16:47 | nymsy | hmm |
| 16:47 | Hun | you're doing something wrong. |
| 16:47 | nymsy | heheheh |
| 16:48 | hiredman | yeah I watched the videos years before I ever found the pdf |
| 16:48 | nymsy | maybe it was the other one |
| 16:48 | nymsy | the other four letter acronym, functional programming book |
| 16:49 | nymsy | htpc |
| 16:49 | Hun | paip? |
| 16:49 | cooldude127 | i 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:49 | Hun | htwp |
| 16:49 | nymsy | how to program computers? or something? |
| 16:49 | Hun | write programs |
| 16:49 | nymsy | ah |
| 16:49 | Hun | it's nice, but doesn't have much depth |
| 16:49 | hiredman | cooldude127: be sure to throw salt over your left shoulder |
| 16:49 | nymsy | clojurebot: google htwp pdf |
| 16:49 | clojurebot | First, out of 255 results is: |
| 16:49 | cooldude127 | hiredman: ? |
| 16:49 | clojurebot | HTWP - TORQUE WRENCH PUMPS |
| 16:50 | clojurebot | http://www.hi-force.com/Pages-download/Catalogues/English%20main%20pages/Page-089.pdf |
| 16:50 | Hun | hmm |
| 16:50 | Hun | ah |
| 16:50 | hiredman | Nice |
| 16:50 | Hun | how to DESIGN programs |
| 16:50 | cooldude127 | well i need to go to class |
| 16:50 | Hun | paip is also very nice :) |
| 16:50 | BigTom | clojurebot: google how to design programs |
| 16:50 | clojurebot | First, out of 254000000 results is: |
| 16:50 | clojurebot | How to Design Programs |
| 16:50 | clojurebot | http://www.htdp.org/ |
| 16:50 | nymsy | ahah |
| 16:50 | knapr | cooldude127: can you please post the code to your avl tree and redblack tree? |
| 16:51 | knapr | cooldude127: can you please post the code to your avl tree and redblack tree? |
| 16:51 | bakkdoor | is 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:51 | nymsy | too late |
| 16:51 | hiredman | ,(map char (range 80 90)) |
| 16:51 | clojurebot | (\P \Q \R \S \T \U \V \W \X \Y) |
| 16:51 | BigTom | Thanks for all the help, hacve to go |
| 16:51 | Hun | hf |
| 16:52 | bakkdoor | ah thanks |
| 16:52 | nymsy | bakkdoor: java can do it too, i think |
| 16:52 | knapr | how do I perform some actions when the user presses close in a GUI? |
| 16:52 | hiredman | char's in java are, I think, unsigned shorts |
| 16:53 | hiredman | so int <-> char is fairly easy |
| 16:53 | nymsy | .onClose? |
| 16:53 | Hun | knapr: bind something to that event |
| 16:53 | knapr | is there something like : gui.onDestroy(doStuff); ? |
| 16:53 | nymsy | something like that |
| 16:53 | nymsy | most swing tutorials, fwir, have it in there somewhere |
| 16:53 | hiredman | by faily easy I mean a nop |
| 16:59 | nymsy | ,(({"pr" (fn [x] (pr x))} "pr") "hi") |
| 16:59 | clojurebot | "hi" |
| 16:59 | nymsy | sweet |
| 17:00 | nymsy | been thinking of setting up commands that way, in one large map |
| 17:00 | Hun | might be ok if your commands are computer generated. pretty bad for humans |
| 17:00 | nymsy | why? |
| 17:00 | Hun | ,(({"pr" (fn [x] (pr x))} "Pr") "hi") |
| 17:00 | clojurebot | java.lang.NullPointerException |
| 17:01 | Hun | any questions? |
| 17:01 | Chouser | ,(({"pr" pr} "pr") "hi") |
| 17:01 | clojurebot | "hi" |
| 17:03 | nymsy | true, true.. Hun: (def [msg "/nick nymsy"] (({"/nick" ... etc |
| 17:04 | Hun | parsing quasi-structured input is pretty hard |
| 17:05 | nymsy | aye, I made first-word and rest-words to parse the commands |
| 17:05 | nymsy | works pretty good |
| 17:06 | Hun | did 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:06 | Hun | i lost one feature (being able to have pr expand to print), but the code got a whole lot better expandable |
| 17:07 | nymsy | yea, I'm not quite there yet :) |
| 17:07 | Hun | the completion was cool. (filter #(starts-with (car x) command-string) command-table) |
| 17:07 | Hun | more or less |
| 17:08 | Chouser | Hun: Clojure? Or some other lisp? |
| 17:08 | Hun | if more than one matches (s could be save or step), the list was of length > 1 and an error was signalled |
| 17:08 | Chouser | 'car' nm. |
| 17:08 | Hun | Chouser: CL |
| 17:08 | Hun | losely translated. it's hard to lose your car, you know |
| 17:09 | Chouser | but #() is hard to ignore. :-) ...or does CL do that too? |
| 17:09 | Hun | mine did |
| 17:09 | Chouser | :-) |
| 17:09 | Hun | that macro is pretty easy to write, you know. my implementation took 20 lines |
| 17:10 | Hun | though it used _1 and _2 instead of %1 and %2 |
| 17:10 | Hun | i thought if adding key args to that would be nice (like (#(foo _bar) :bar 5) => 5 |
| 17:10 | nymsy | well, gents.. it's been swell... **Chouser: thanks again for the index tip.. I'm racking out. see yall later |
| 17:10 | Hun | but that was a bit to hard |
| 17:11 | Hun | have fun |
| 17:11 | Chouser | nymsy: good luck in the deployment |
| 17:11 | Chouser | nymsy: US? Nat'l guard? Anyway, I wish you well. |
| 17:41 | knapr | it seems to use windowlistener i have to implement a java interface, is that correct? how do I do that in Clojure? |
| 17:41 | Cark | ,(doc proxy) |
| 17:41 | clojurebot | "([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:42 | Cark | or you could use genclass |
| 17:42 | walters | one 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:42 | Cark | or make a namespsace which will become your class |
| 17:44 | hiredman | walters: I think it is a performance deal breaker |
| 17:44 | hiredman | but I forget |
| 17:44 | hiredman | someone was here and asked rhickey about it |
| 17:46 | hiredman | I imagine you could do that, but not completely transparently with a macro |
| 17:46 | hiredman | (mk-interface java.some.Interface fn) |
| 17:47 | knapr | if i want to make an executable file for my mp3, do i first use compile then i use jar on that? |
| 17:47 | walters | yeah, that's equivalent to how groovy does it, you have to say { foo, bar -> stuff(); } as java.some.Interface |
| 17:48 | hiredman | knapr: http://clojure.org/compilation under "gen-class Examples" has an example stand alone jar |
| 17:48 | hiredman | quick, name a single method java interface off the top of your head |
| 17:48 | walters | hiredman: FilenameFilter |
| 17:50 | walters | hiredman: also, two of my personal projects make extensive use of them |
| 17:50 | AWizzArd | ,(print *ns*) |
| 17:50 | hiredman | ,(:name (bean (first (.getMethods java.io.FilenameFilter)))) |
| 17:50 | clojurebot | #<Namespace sandbox> |
| 17:50 | clojurebot | "accept" |
| 17:50 | AWizzArd | ,(print (ns-publics 'sandbox)) |
| 17:50 | clojurebot | {} |
| 17:51 | hiredman | ,(symbol (:name (bean (first (.getMethods java.io.FilenameFilter))))) |
| 17:51 | clojurebot | accept |
| 17:52 | hiredman | and then you just have the macro generate the relevent proxy form around that |
| 17:52 | AWizzArd | ,(count (ns-map 'sandbox)) |
| 17:52 | clojurebot | 541 |
| 17:54 | ecret | I 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:55 | ecret | Does clojure support this mechanism? |
| 17:56 | AWizzArd | ecret: great, so you managed it to compile to .class files :-) |
| 17:57 | ecret | yes ! 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:57 | AWizzArd | ;-) |
| 17:57 | ecret | pretty sure it was just the class path + the *compile thing* though |
| 17:57 | AWizzArd | yup |
| 17:57 | knapr | man i always get suck on the damn java classpath as soon as i dont use it for a while i get confused |
| 17:57 | AWizzArd | once you found out how they play together it can be done within seconds to minutes |
| 17:58 | ecret | yep |
| 17:59 | AWizzArd | ecret: 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:00 | ecret | sort 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:02 | ecret | the caller is the transcription.clj so transcription.class |
| 18:07 | scottj | What 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:07 | knapr | if 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:20 | knapr | if 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:42 | cooldude127 | technomancy: hey did something change in clojure-mode (or at least the one in emacs-starter-kit) to make clojure-enable-paredit not work? |
| 18:43 | technomancy | cooldude127: yeah, upstream didn't like the idea of making that a flag |
| 18:43 | technomancy | check the comments in the clojure-mode header |
| 18:43 | cooldude127 | ok |
| 18:43 | technomancy | the way he switched it to work is pretty reasonable |
| 18:43 | cooldude127 | technomancy: that's the way it works for every other lisp actually |
| 18:44 | technomancy | oh cool |
| 18:45 | cooldude127 | technomancy: do you ever notice yourself doing C-c C-c on elisp expressions and expecting it to work? |
| 18:47 | technomancy | cooldude127: I actually end up using C-c C-l most of the time |
| 18:47 | technomancy | just my habit; need to spend some more quality time with the slime manual |
| 18:47 | cooldude127 | oh, i'm addicted to compiling individual top-levels |
| 18:48 | cooldude127 | but the real one to use is C-c C-k if you want to do the whole file |
| 18:48 | technomancy | what's the difference? |
| 18:48 | cooldude127 | one 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:49 | knapr | is how to deisng programs aimed at beginners? |
| 18:49 | cooldude127 | knapr: i think so |
| 18:49 | knapr | it seems bsic just skimming through it? |
| 18:49 | knapr | dude:post your avn and redblack tree please |
| 18:50 | knapr | what is a good book on how to deisgn complex programs, preferrably in a functional way |
| 18:50 | cooldude127 | knapr: k, but my RB tree doesn't do deletes yet btw |
| 18:51 | hiredman | cooldude127: you using clojure.zip for the trees? |
| 18:51 | cooldude127 | hiredman: no, but i really should look at that |
| 18:51 | cooldude127 | hiredman: they're pretty naive implementations, i'm just learning this stuff |
| 18:51 | technomancy | cooldude127: nice; one step fewer I guess |
| 18:52 | cooldude127 | knapr: here they are: http://gist.github.com/53671 |
| 18:52 | cooldude127 | technomancy: yeah, i'm all about the efficiency |
| 18:53 | cooldude127 | hiredman: holy shit, what are these zippers? |
| 18:54 | knapr | ok |
| 18:54 | cooldude127 | hiredman: 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:54 | cooldude127 | lol |
| 18:54 | hiredman | heh |
| 18:55 | hiredman | so far I have avoided actually trying to figure out the intermediate output of munging stuff with zippers |
| 18:55 | cooldude127 | hiredman: what do you mean? |
| 18:57 | hiredman | cooldude127: zippers sort of turn a data structure insideout as you move through it |
| 18:57 | hiredman | and when you are done you "zip" it back up |
| 18:58 | cooldude127 | oh jesus |
| 18:58 | cooldude127 | yeah i'm not ready for that |
| 18:58 | knapr | so |
| 18:58 | knapr | how can I run |
| 18:58 | hiredman | it is neet because you move through a ds using -> |
| 18:58 | cooldude127 | ok what do i do to make it so i can refer to clojure.zip as just zip? |
| 18:58 | hiredman | er -> |
| 18:58 | hiredman | damn it |
| 18:58 | hiredman | "->" |
| 18:58 | cooldude127 | lol |
| 18:59 | cooldude127 | i knew what you meant |
| 18:59 | hiredman | (require '[clojure.zip :as zip]) |
| 18:59 | cooldude127 | hiredman: in a ns form that would be (:require [clojure.zip :as zip]) ? |
| 19:00 | hiredman | yes |
| 19:00 | cooldude127 | k |
| 19:00 | cooldude127 | ok 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:01 | cooldude127 | can't mess with two things i don't understand at the same time |
| 19:02 | lisppaste8 | knapr pasted "compiling java is hell" at http://paste.lisp.org/display/74384 |
| 19:02 | knapr | someone can explain ^^ ? just how to run compiled clojure... |
| 19:04 | hiredman | knapr: on the compilation page where you saw that example, right under that example |
| 19:04 | hiredman | java -cp ./classes:clojure.jar clojure.examples.hello Fred |
| 19:05 | knapr | where ./classes:clojure.jar is instead C:/clojure/clojure.jar? so why doesnt that work? |
| 19:05 | hiredman | ./classes needs to be replaced with the path to your classes directory and clojure.jar with the path to your clojure |
| 19:05 | knapr | and from where shouls it be run?anywhere? |
| 19:05 | hiredman | the classpath seperator on windwos is ; |
| 19:05 | hiredman | not : |
| 19:06 | hiredman | if you have full paths then you can run it from anywhere |
| 19:12 | knapr | sigh i cant get it to work, noclassdeffounderror |
| 19:17 | knapr | about function composition |
| 19:17 | knapr | (comp map map) |
| 19:17 | knapr | def that |
| 19:17 | knapr | (mmap inc [[1,2,3,4,5]]) |
| 19:17 | knapr | java.lang.IllegalArgumentException: Wrong number of args passed to: core$map (NO_SOURCE_FILE:0) |
| 19:18 | knapr | in haskell that works |
| 19:20 | hiredman | well |
| 19:20 | hiredman | this is not haskell |
| 19:20 | hiredman | map, takes two args each time |
| 19:21 | hiredman | and outputs a single value |
| 19:21 | hiredman | so the first map outputs a single value, the second map gets a single value |
| 19:21 | hiredman | but map takes two args |
| 19:21 | hiredman | so no dice |
| 19:22 | hiredman | ,(map (patial map inc) [(range 10) (range 20 30)]) |
| 19:22 | clojurebot | java.lang.Exception: Unable to resolve symbol: patial in this context |
| 19:22 | hiredman | ,(map (partial map inc) [(range 10) (range 20 30)]) |
| 19:22 | clojurebot | ((1 2 3 4 5 6 7 8 9 10) (21 22 23 24 25 26 27 28 29 30)) |
| 19:27 | hiredman | clojurebot: for? |
| 19:27 | clojurebot | for is not a loop |
| 19:27 | hiredman | clojurebot: for is also not used often enough |
| 19:27 | clojurebot | Roger. |
| 19:33 | hiredman | my euler.clj is so embarresing |
| 19:33 | knapr | clojurebot: for? |
| 19:33 | clojurebot | for is not used often enough |
| 19:33 | knapr | clojurebot: for? |
| 19:33 | clojurebot | for is not used often enough |
| 19:33 | knapr | clojurebot: hiredmans euler.clj is so embarassing |
| 19:33 | clojurebot | 'Sea, mhuise. |
| 19:34 | knapr | clojurebot: hierdmans? |
| 19:34 | clojurebot | It's greek to me. |
| 19:34 | knapr | clojurebot: hiredmans? |
| 19:34 | clojurebot | hiredmans euler.clj is so embarassing |
| 19:34 | knapr | why? |
| 19:35 | knapr | clojurebot: meaning of life? |
| 19:35 | clojurebot | excusez-moi |
| 19:35 | knapr | clojurebot: meaning of life is to become one with Lisp |
| 19:35 | clojurebot | In Ordnung |
| 19:35 | knapr | clojurebot: meaning of life? |
| 19:35 | clojurebot | meaning of life is to become one with Lisp |
| 19:35 | hiredman | knapr: careful about over writing stuff |
| 19:37 | knapr | ok' |
| 19:38 | knapr | clojurebot: OO is to programming what astrology is to astronomy |
| 19:38 | clojurebot | Alles klar |
| 19:38 | knapr | clojurebot: OO? |
| 19:38 | clojurebot | OO is to programming what astrology is to astronomy |
| 19:40 | Cark | tss =) |
| 19:41 | gnuvince_ | hahaha |
| 19:56 | cooldude127 | hiredman: 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:01 | knapr | http://paste.lisp.org/display/74384 |
| 20:02 | cooldude127 | knapr: that hasn't gotten worked out yet? |
| 20:02 | durka42 | wouldn't you just do: java compleexample |
| 20:02 | durka42 | compileexample |
| 20:03 | cooldude127 | you need clojure on the classpath |
| 20:03 | durka42 | with clojure.jar on the $CLASSPATH |
| 20:03 | knapr | i get wrong name |
| 20:03 | cooldude127 | knapr: what do you mean? |
| 20:03 | durka42 | NoClassDefFound? |
| 20:04 | knapr | yes |
| 20:04 | durka42 | even though you have both clojure.jar and ...../prog/comex on the classpath |
| 20:04 | cooldude127 | knapr: you should be in the classes folder, and run java -cp path/to/clojure.jar progs.comex.compileexample |
| 20:04 | knapr | Caused by: java.lang.ClassNotFoundException: C:.clojure.classes.progs.comex.comp |
| 20:04 | knapr | ileexample.class |
| 20:05 | cooldude127 | java -cp .;c:\clojure\clojure.jar progs.comex.compileexample |
| 20:06 | knapr | ayay sir! |
| 20:06 | knapr | thanks |
| 20:06 | cooldude127 | no problem |
| 20:09 | knapr | and when i have abig program with reuires and imports i add :gen-class the same way? |
| 20:13 | durka42 | clojurebot: where's my list of exceptions? |
| 20:13 | clojurebot | http://paste.lisp.org/display/74305 |
| 20:14 | lisppaste8 | durka annotated #74305 with "errors" at http://paste.lisp.org/display/74305#1 |
| 20:14 | durka42 | ,(+ 840 92) |
| 20:14 | clojurebot | 932 |
| 20:19 | knapr | woot i managed to compile and run my mp3player! |
| 20:20 | durka42 | sweet |
| 20:20 | knapr | now i just need to make it executable without hocus-pocus |
| 20:20 | durka42 | hocus pocus? |
| 20:23 | knapr | java classpath |
| 20:31 | gnuvince_ | There's no literal syntax for longs, is there? |
| 20:38 | knapr | should I put my mp3player up at some wiki or something? |
| 20:39 | knapr | it 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:42 | knapr | there is a lot of things being generated and created when compiling and running |
| 20:42 | knapr | which file/files do i need in the jar? just compileexample.class? |
| 20:43 | knapr | what about compileexample_init.class? |
| 20:48 | durka42 | knapr: yeah, put it up on a wiki or github or lisppaste somewhere |
| 20:48 | durka42 | you might also need clojure.jar |
| 20:51 | durka42 | you might want to look at how gorilla does it |
| 20:51 | durka42 | it has an ant script with an option for standalone build (unzips clojure.jar into gorilla.jar) |
| 20:58 | knapr | gorilla? |
| 20:58 | knapr | you mean it has a build.xml? |
| 20:59 | durka42 | yes |
| 21:01 | durka42 | http://bitbucket.org/kotarak/gorilla/src/ |
| 21:20 | cooldude127 | is there anymore documentation clojure's zippers besides what's on the site? |
| 21:21 | hiredman | I spent alot of zip flipping back and forth with zip.clj |
| 21:21 | hiredman | hah |
| 21:21 | hiredman | a lot of time flipping |
| 21:21 | cooldude127 | lol |
| 21:27 | cooldude127 | hiredman: 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:28 | hiredman | ,(require '[clojure.zip :as zip]) |
| 21:28 | clojurebot | nil |
| 21:29 | hiredman | ,(-> '(+ 1 3 (* 2 4)) zip/seq-zip) |
| 21:29 | clojurebot | [(+ 1 3 (* 2 4)) nil] |
| 21:29 | hiredman | ,(-> '(+ 1 3 (* 2 4)) zip/seq-zip zip/down) |
| 21:29 | clojurebot | [+ {:l [], :pnodes [(+ 1 3 (* 2 4))], :ppath nil, :r (1 3 (* 2 4))}] |
| 21:29 | hiredman | ,(-> '(+ 1 3 (* 2 4)) zip/seq-zip zip/down zip/node) |
| 21:29 | clojurebot | + |
| 21:29 | hiredman | ,(-> '(+ 1 3 (* 2 4)) zip/seq-zip zip/down zip/right zip/node) |
| 21:29 | clojurebot | 1 |
| 21:31 | hiredman | ,(-> '(+ 1 3 (* 2 4)) zip/seq-zip zip/down zip/right zip/right zip/right zip/node) |
| 21:31 | clojurebot | (* 2 4) |
| 21:31 | hiredman | wheee! |
| 21:31 | cooldude127 | hiredman: 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:31 | gnuvince_ | ,(doc get) |
| 21:31 | clojurebot | "([map key] [map key not-found]); Returns the value mapped to key, not-found or nil if key not present." |
| 21:32 | hiredman | ,(-> '(+ 1 3 (* 2 4)) zip/seq-zip zip/down zip/node) |
| 21:32 | clojurebot | + |
| 21:32 | gnuvince_ | Is there a reason to use get instead of using a map as a functin? |
| 21:32 | gnuvince_ | function* |
| 21:32 | hiredman | ,(-> '(+ 1 3 (* 2 4)) zip/seq-zip zip/children) |
| 21:32 | clojurebot | (+ 1 3 (* 2 4)) |
| 21:32 | Chousuke | gnuvince_: perhaps its clearer in some cases? |
| 21:33 | hiredman | ,(-> '(+ 1 3 (* 2 4)) zip/seq-zip zip/lefts zip/node) |
| 21:33 | clojurebot | java.lang.NullPointerException |
| 21:33 | hiredman | ,(-> '(+ 1 3 (* 2 4)) zip/seq-zip zip/lefts) |
| 21:33 | clojurebot | nil |
| 21:33 | hiredman | ,(-> '(+ 1 3 (* 2 4)) zip/seq-zip zip/rights) |
| 21:33 | clojurebot | nil |
| 21:33 | hiredman | ,(-> '(+ 1 3 (* 2 4)) zip/seq-zip zip/down zip/rights) |
| 21:33 | clojurebot | (1 3 (* 2 4)) |
| 21:33 | hiredman | ,(-> '(+ 1 3 (* 2 4)) zip/seq-zip zip/down zip/lefts) |
| 21:33 | clojurebot | nil |
| 21:33 | hiredman | hmm |
| 21:34 | cooldude127 | hiredman: 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:34 | hiredman | ,(-> '((1 1) 1 3 (* 2 4)) zip/seq-zip zip/down zip/lefts) |
| 21:34 | clojurebot | nil |
| 21:35 | hiredman | you are at a leaf, and want to head left from the leaf? |
| 21:36 | bradbev | Hi guys. How much memory does an instance of a struct-map consume? |
| 21:36 | cooldude127 | hiredman: 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:36 | hiredman | dunno |
| 21:38 | bradbev | I 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:38 | hiredman | (-> [[[1] 2 [3]] 4 [[5] 6 [7]]] zip/vector-zip) |
| 21:38 | hiredman | ,(-> [[[1] 2 [3]] 4 [[5] 6 [7]]] zip/vector-zip) |
| 21:38 | clojurebot | [[[[1] 2 [3]] 4 [[5] 6 [7]]] nil] |
| 21:38 | hiredman | ,(-> [[[1] 2 [3]] 4 [[5] 6 [7]]] zip/vector-zip zip/down zip/node) |
| 21:38 | clojurebot | [[1] 2 [3]] |
| 21:38 | bradbev | The problem is that my 7 key struct injected into a map 750,000 times is about 438Mb |
| 21:39 | cooldude127 | hiredman: see that should be 4 in my ideal case |
| 21:39 | lisppaste8 | knapr pasted "making an exec jar" at http://paste.lisp.org/display/74391 |
| 21:39 | hiredman | ,(-> [[[1] 2 [3]] 4 [[5] 6 [7]]] zip/vector-zip zip/down zip/left zip/left zip/node) |
| 21:39 | clojurebot | java.lang.NullPointerException |
| 21:39 | bradbev | if I inject 750,000 ints into a vector, then it is only a handful of MB |
| 21:39 | hiredman | ,(-> [[[1] 2 [3]] 4 [[5] 6 [7]]] zip/vector-zip zip/down zip/node) |
| 21:39 | clojurebot | [[1] 2 [3]] |
| 21:39 | hiredman | ,(-> [[[1] 2 [3]] 4 [[5] 6 [7]]] zip/vector-zip zip/left zip/left zip/node) |
| 21:39 | bradbev | so, I'd guess structmaps are huge |
| 21:39 | clojurebot | java.lang.NullPointerException |
| 21:39 | bradbev | any thoughts? |
| 21:40 | hiredman | ,(-> [[[1] 2 [3]] 4 [[5] 6 [7]]] zip/vector-zip zip/down zip/right zip/node) |
| 21:40 | clojurebot | 4 |
| 21:40 | hiredman | duh |
| 21:40 | cooldude127 | hiredman: yeah i know you could do it that way, but it feels counter intuitive |
| 21:41 | hiredman | sorry I meant duh for myself |
| 21:41 | cooldude127 | i figured |
| 21:42 | cooldude127 | hiredman: i considered doing it prorder, like [data left right], but then it's still right and right -> right, instead of left and right |
| 21:43 | bradbev | Hmm, OK ref object appear to be quite large |
| 21:44 | hiredman | cooldude127: you can make your own zipper |
| 21:44 | cooldude127 | hiredman: yeah i'm looking into figuring out how to make that work correctly |
| 21:47 | knapr | http://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:49 | cooldude127 | hiredman: damnit this is confusing |
| 21:50 | hiredman | Yes |
| 21:50 | hiredman | but that does make it less cool |
| 21:51 | cooldude127 | hiredman: is there anyway to make a zipper go down, and then be able to make an immediate left? at all? |
| 21:52 | hiredman | ,(doc zip/down) |
| 21:52 | clojurebot | "([loc]); Returns the loc of the leftmost child of the node at this loc, or nil if no children" |
| 21:52 | cooldude127 | hiredman: so no? |
| 21:52 | hiredman | down should hit the left |
| 21:53 | cooldude127 | hiredman: maybe i just write my own left and right functions that do the right thing? |
| 21:54 | hiredman | you could do that |
| 21:55 | knapr | wheres does the expr hiredman come from? |
| 21:55 | knapr | i heard it in the office |
| 21:56 | hiredman | I borrowed it from a gibson book |
| 21:57 | hiredman | Count Zero, I believe |
| 22:10 | johan1 | hmm, 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:10 | durka42 | you didn't pass the object |
| 22:10 | durka42 | {what?}.setCoordinates() |
| 22:10 | johan1 | that's a typo |
| 22:10 | johan1 | it is correct in my code, but the argument is wrong |
| 22:10 | durka42 | oh ok |
| 22:11 | durka42 | in that case i'm not sure |
| 22:11 | durka42 | maybe: |
| 22:11 | durka42 | (doc make-array) |
| 22:11 | clojurebot | Creates 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:11 | cooldude127 | also: |
| 22:11 | cooldude127 | (doc into-array) |
| 22:11 | clojurebot | Returns 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:11 | durka42 | ,(into-array [1 2 3]) |
| 22:11 | clojurebot | #<Integer[] [Ljava.lang.Integer;@1f9b804> |
| 22:12 | johan1 | ok, I will give it a try |
| 22:12 | hiredman | vectors are not java arrays |
| 22:12 | cooldude127 | they are objects |
| 22:12 | cooldude127 | ,(class [1 2 3]) |
| 22:12 | clojurebot | clojure.lang.LazilyPersistentVector |
| 22:12 | hiredman | ,(class (into-array [1 2 3])) |
| 22:12 | clojurebot | [Ljava.lang.Integer; |
| 22:12 | hiredman | so are java arrays |
| 22:12 | hiredman | you most likely want ints not Intergers |
| 22:13 | hiredman | so you want |
| 22:13 | cooldude127 | hiredman: autoboxing should make that ok tho |
| 22:13 | hiredman | ,(into-array Integer/TYPE [1 2 3]) |
| 22:13 | clojurebot | #<int[] [I@92eb76> |
| 22:13 | cooldude127 | ,(into-array Integer/Type [1 2 3]) |
| 22:13 | clojurebot | java.lang.Exception: No such namespace: Integer |
| 22:13 | cooldude127 | lol |
| 22:13 | cooldude127 | hiredman: oh i messed it up |
| 22:14 | hiredman | ,(class (into-array Integer/TYPE [1 2 3])) |
| 22:14 | clojurebot | [I |
| 22:14 | hiredman | Indeed |
| 22:24 | johan1 | it works. thanks |
| 22:25 | hiredman | ,(class 1) |
| 22:25 | clojurebot | java.lang.Integer |
| 22:30 | dreish | ,(gensym) |
| 22:30 | clojurebot | G__1270 |
| 22:30 | dreish | ,(gensym) |
| 22:30 | clojurebot | G__1274 |
| 22:30 | dreish | ,(= (gensym) 'G__1278) |
| 22:30 | clojurebot | true |
| 22:31 | dreish | Is this a bug? |
| 22:31 | hiredman | ,(= (gensym) (gensym)) |
| 22:31 | clojurebot | false |
| 22:31 | durka42 | gensym creates a new symbol |
| 22:31 | durka42 | you inferred the algorithm for naming said symbol, an implementation detail |
| 22:31 | durka42 | doesn't seem like a bug |
| 22:32 | hiredman | ,(let [a (gensym)] (= a (gensym))) |
| 22:32 | clojurebot | false |
| 22:32 | dreish | Yes, and maybe the bug is in my expectations, but in Common Lisp, a gensym cannot be equal to any other existing symbol. |
| 22:32 | hiredman | ,(= nil 'a) |
| 22:32 | clojurebot | false |
| 22:32 | hiredman | ,(= (gensym) 'a) |
| 22:32 | clojurebot | false |
| 22:32 | dreish | If you begin an expression (= (gensym) ...) in CL, there is nothing you can type to make it true. |
| 22:32 | dreish | Sorry, (eq) |
| 22:33 | durka42 | hmm |
| 22:33 | hiredman | ,(str (gensym) " " (gensym)) |
| 22:33 | clojurebot | "G__1299 G__1300" |
| 22:33 | hiredman | hmmm |
| 22:33 | knapr | has anyone managed to create an executable jar of a clojure-program? could you show me? |
| 22:33 | durka42 | did you look at gorilla? |
| 22:33 | durka42 | after you do "ant -Dstandalone=true" gorilla.jar is runnable with java -jar |
| 22:33 | durka42 | i don't know how but kotarak presumably does |
| 22:34 | durka42 | dreish: i guess, the arguments to = are evaluted first, so the symbol exists before gensym creates its new one |
| 22:34 | hiredman | knapr: jars are never "executable", windows is just typically setup to, when you click on X.jar, to run java -jar X.jar |
| 22:35 | durka42 | Gorilla=> (let [a 'G__1963] (prn (gensym)) (prn a)) |
| 22:35 | durka42 | G__1963 |
| 22:35 | durka42 | G__1963 |
| 22:35 | durka42 | nil |
| 22:35 | durka42 | that does seem strange |
| 22:35 | dreish | RIght, 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:35 | dreish | Which I guess is reasonable enough. |
| 22:36 | knapr | i see |
| 22:37 | hiredman | ,(doc gensym) |
| 22:37 | clojurebot | "([] [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:37 | dreish | That 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:38 | dreish | I'm sure I must be wrong about that. |
| 22:38 | durka42 | so in CL, it looks like gensym'd symbols are a completely different type from regular symbols? |
| 22:39 | dreish | I think they're regular-enough symbols, but they print in a form that doesn't read back to the same symbol. |
| 22:40 | dreish | That might be the answer, though. Make them somehow something that can't be produced through the reader, or by calling symbol. |
| 22:41 | gnuvince_ | Could anybody lend me a hand with a macro? |
| 22:41 | gnuvince_ | I think I've almost got it, but I can't put the finishing touch. |
| 22:42 | hiredman | clojurebot: macro help? |
| 22:42 | clojurebot | macro help is http://clojure-log.n01se.net/macro.html |
| 22:42 | hiredman | :P |
| 22:42 | durka42 | isn't that captcha circumvention? |
| 22:42 | dreish | I can help you move a macro up a flight of stairs if it weighs less than about 150 lbs. |
| 22:42 | durka42 | (because that captcha is so advanced...) |
| 22:43 | durka42 | be careful, parentheses are slippery |
| 22:43 | durka42 | and quasiquotes are sharp |
| 22:45 | lisppaste8 | gnuvince pasted "parse-buffer macro" at http://paste.lisp.org/display/74394 |
| 22:47 | dreish | Why is this a macro? |
| 22:47 | gnuvince_ | Cause I don't want to manually call .get, .getShort, .getInt, etc. |
| 22:48 | gnuvince_ | I want to write a description of the buffer's structure and have all right calls made |
| 22:49 | dreish | I just don't see why this could be a function that does exactly the same thing. |
| 22:49 | dreish | couldn't |
| 22:51 | gnuvince_ | Because it looks exactly like something macros are used for. |
| 22:51 | hiredman | clojurebot: who's the man is <reply> ?(^_^)? |
| 22:51 | clojurebot | Alles klar |
| 22:51 | hiredman | clojurebot: who's the man? |
| 22:51 | clojurebot | ?(^_^)? |
| 22:51 | danlarkin | intense |
| 22:51 | durka42 | nice unicode |
| 22:52 | gnuvince_ | Anybody? |
| 22:52 | hiredman | I just stole it from someone in #haskell |
| 22:52 | gnuvince_ | I just need to figure out how to write the ~forms part in the mapcat call |
| 22:53 | hiredman | yeah, macros are for code manipulation |
| 22:53 | hiredman | which this is not |
| 22:54 | lisppaste8 | durka annotated #74394 with "expansion of the actual macro" at http://paste.lisp.org/display/74394#1 |
| 22:54 | hiredman | gnuvince_: I think you need to quote the stuff that gets put into & forms |
| 22:55 | gnuvince_ | hiredman: quote it where? in my call? |
| 22:55 | hiredman | which is a sign of not macrohood |
| 22:55 | hiredman | yeah |
| 22:55 | gnuvince_ | Fuck |
| 22:55 | dreish | It's a function trapped in a macro's body. Won't you help? |
| 22:55 | hiredman | because ~form just turns into a seq of attempted function calls |
| 22:56 | dreish | I like Stu's "rules of macro club": #1: don't write macros. |
| 22:56 | gnuvince_ | So *how* would I write this without the calling code looking like fucking Java crap? |
| 22:58 | gnuvince_ | Same definition except with defn and call with (parse-buffer buf [:field 1 :byte #(...)] ...)? |
| 22:58 | dreish | That's where I'd start. |
| 22:59 | danlarkin | ditto! |
| 23:00 | dreish | Probably use brackets for the lists instead of parens so you don't have to quote. |
| 23:00 | hiredman | sounds like a plan |
| 23:00 | danlarkin | vectors |
| 23:00 | danlarkin | not brackets |
| 23:00 | dreish | Right. When I'm especially tired I also call them square thingies. |
| 23:00 | danlarkin | important to know that vectors != lists |
| 23:01 | dreish | Little square data structures floating around in the computer. |
| 23:01 | hiredman | then once you have that, you can make a macro that turns lists into vectors and passes them to your function :P |
| 23:01 | durka42 | this macro known as [ |
| 23:02 | hiredman | actually it is a function know as vec |
| 23:02 | hiredman | ,(vec '(:a :b :c)) |
| 23:02 | clojurebot | [:a :b :c] |
| 23:03 | durka42 | (defmacro vecm [xs] `(vec '~xs)) |
| 23:05 | lisppaste8 | gnuvince pasted "Using a function" at http://paste.lisp.org/display/74395 |
| 23:06 | gnuvince_ | For the curious |
| 23:06 | dreish | Does it work? |
| 23:06 | durka42 | btw: you can annotate pastes |
| 23:07 | gnuvince_ | dreish: it does. |
| 23:07 | dreish | Woohoo! |
| 23:07 | dreish | Another problem solved by not-macros! |
| 23:07 | gnuvince_ | Gonna need to try it with my real data |
| 23:07 | gnuvince_ | But not tonight |
| 23:26 | brianh | emacs noob here |
| 23:26 | brianh | i just updated my clojure-mode & it deleted the clojure-auto file |
| 23:27 | brianh | what's the new alternative? |
| 23:29 | gnuvince_ | brianh: look in clojure-mode.el |
| 23:29 | gnuvince_ | the two lines are there |
| 23:29 | gnuvince_ | There's an autoload and an add-to-alist call |
| 23:31 | brianh | k thx |
| 23:49 | durka42 | how do you write a constructor for :gen-class? |
| 23:52 | durka42 | :int |
| 23:52 | durka42 | :init i mean |
| 23:55 | hiredman | uh, I think the init function returns a tuple (vector) |
| 23:56 | hiredman | the first element is a vector of args to pass to the superclass constructoor |
| 23:57 | hiredman | the second element is the starting state |
| 23:58 | lisppaste8 | knapr pasted "macro-problem" at http://paste.lisp.org/display/74398 |
| 23:58 | knapr | clojurebot: OO? |
| 23:58 | clojurebot | OO is to programming what astrology is to astronomy |
| 23:58 | knapr | some macro-gurus here? ^^ |