2009-03-14
| 00:38 | Mec | is there a not equal? |
| 00:40 | Raynes | Mec: not= |
| 00:41 | Mec | lol how did i miss that, thanks |
| 00:43 | danlarkin | or (not (= |
| 00:43 | danlarkin | or (compliment = |
| 00:43 | cp2 | just use not= |
| 00:43 | cp2 | :) |
| 00:43 | danlarkin | agreed :) |
| 00:44 | Mec | its so obvious i never considered it, im used to != or <> or ~= or ^= |
| 00:45 | cp2 | yeah Mec |
| 00:45 | cp2 | i didnt notice it at first etiehr |
| 00:45 | cp2 | infact i think i did a few (not (= |
| 00:45 | cp2 | not that thats wrong, just looks...idunno |
| 00:47 | Mec | not= is like one logical idea and there's a parenthesis cutting our idea in half in (not (= .. it hurts the mind |
| 00:53 | slashcom | Anyone use JNA with clojure at all? I'm having trouble with it |
| 00:55 | cp2 | well, i havent used it |
| 00:55 | cp2 | but maybe i can help |
| 00:55 | slashcom | okay well I started with this mailing list posting: http://groups.google.com/group/clojure/browse_thread/thread/77e626c5440bf1a0 |
| 00:55 | slashcom | but gen-and-load-interface isn't around anymore, as far as I can tell |
| 00:56 | cp2 | iirc it was removed |
| 00:56 | slashcom | http://gist.github.com/78949 so I have this test file |
| 00:57 | cp2 | ok |
| 00:58 | slashcom | http://gist.github.com/78950 and here's my repl |
| 01:00 | slashcom | I ran my compiled JnaTest through jad too: http://gist.github.com/78951 |
| 01:00 | slashcom | but using _28_quote_20_getpid_29_ as my method doesn't help either |
| 01:01 | cp2 | hm |
| 01:02 | slashcom | i haven't tried doing it in java yet. maybe i should do that |
| 01:02 | cp2 | to be honest i dont really know much about proxies in clojure, you might want to see if someone more experienced is around |
| 01:02 | cp2 | like Chouser, or hiredman |
| 01:02 | cp2 | :) |
| 01:02 | cp2 | danlarkin was just here too |
| 01:02 | danlarkin | pong |
| 01:02 | slashcom | hi dan :) |
| 01:02 | slashcom | mind looking at the problem above? |
| 01:03 | danlarkin | depends on where on your body it is |
| 01:03 | danlarkin | I'm above the waist only |
| 01:03 | danlarkin | oh jeez |
| 01:03 | danlarkin | it's late |
| 01:03 | danlarkin | that doesn't even make sense does it |
| 01:03 | slashcom | :) |
| 01:04 | danlarkin | I'm sorry... it's been a long day |
| 01:04 | slashcom | yeah, well, it's pi day now, right? |
| 01:04 | danlarkin | hey! true |
| 01:05 | danlarkin | Hm, I haven't don any JNA |
| 01:06 | slashcom | is there a way to ask clojure what methods an object has? |
| 01:06 | slashcom | kind of like python's dir()? |
| 01:06 | danlarkin | there's a nice function called show in clojure-contrib |
| 01:07 | slashcom | [ 9] (quote getpid) : Integer () |
| 01:07 | slashcom | [10] (quote getppid) : Integer () |
| 01:07 | slashcom | [11] (quote sleep) : Void (Integer) |
| 01:07 | danlarkin | oh |
| 01:07 | danlarkin | well there ya go |
| 01:07 | danlarkin | remove the quotes from your interface definition |
| 01:08 | Mec | is there a way to keep track of only the last 10 digits of a number while performing calculations on it? greater than 10 is fine but not less |
| 01:09 | slashcom | cp2: danlarkin: yay it worked! thanks guys |
| 01:09 | cp2 | i didnt help much, but ok :) |
| 01:11 | slashcom | my goal is to use OSX's fsevents or linux's inotify to notice when .clj files change and automagically reload them |
| 01:14 | danlarkin | slashcom: I have code doing that, but not as nicely as you plan |
| 01:14 | danlarkin | mine has a thread that loops with a 1 second sleep checking mtimes |
| 01:16 | slashcom | yeah, I saw a lot of that on the interwebz. Unfortunately I've never done anything with fsevents or jna |
| 02:10 | cads | hey, has anyone here heard of this clojure meeting in atlanta? : http://leafhopper.github.com/clojure.html |
| 02:12 | Puzzler | Hi. Anyone here using the IntelliJ plugin? |
| 02:24 | Lau_of_DK | Good morning gents |
| 02:25 | durka42 | good night Lau |
| 02:26 | Lau_of_DK | Night night |
| 02:26 | durka42 | ~ Lau wandered into #clojure, and suddenly saw a release to play with |
| 02:26 | clojurebot | clojure is cheating |
| 02:26 | durka42 | ~ Lau was wandering around, and suddenly saw a release to play with |
| 02:26 | clojurebot | CLABANGO! |
| 02:27 | Lau_of_DK | :) |
| 02:27 | durka42 | it's on github somewhere |
| 04:59 | javuchi | hello |
| 04:59 | javuchi | i need some support with swan-clojure |
| 04:59 | javuchi | anyone here? |
| 05:18 | maacl | javuchi: yeah |
| 05:20 | maacl | javuchi: what's the prob |
| 05:41 | javuchi | anyone can help with this: |
| 05:41 | javuchi | http://groups.google.com/group/clojure/browse_thread/thread/34a93067a525e176# |
| 05:43 | maacl | javuchi: looks like a swank / clojure mismatch - you could use clojure-modes clojure-install |
| 05:44 | javuchi | maacl: i don't understand what you say |
| 05:44 | maacl | javuchi: download clojure-mode from git |
| 05:45 | maacl | github |
| 05:45 | maacl | javuchi: are you familiar with git ? |
| 05:46 | javuchi | maacl: i followed the guide |
| 06:20 | AWizzArd | clojurebot: max people |
| 06:20 | clojurebot | max people is 162 |
| 09:36 | leafw | is there any built-in way to export a map as xml ? |
| 09:37 | leafw | i.e. outputting <map> <entry key="%" value="%" /> </map> or similar |
| 09:37 | leafw | it's trivial to write a fn to do it, but I wonder if it's there already |
| 09:47 | Lau_of_DK | leafw, I think zip-filter can get you there quite quickly |
| 09:47 | mecolin | hi |
| 09:47 | Lau_of_DK | hi :) |
| 09:48 | Lau_of_DK | leafw, I remember using emit to do something like that a while ago |
| 09:52 | mecolin | I can't figure out how to alter a root binding of var: (def x 1) (def y) (alter-root-var (var y) (constantly x)) gives "var user/y is unbound. |
| 09:56 | cgrand | mecolin: alter-root-var works only on vars that are already, you can symply do (def y x) to set/overwrite the current root binding |
| 09:56 | leafw | thanks Lau_of_DK , will check |
| 09:57 | Lau_of_DK | Hey cgrand |
| 09:57 | cgrand | Hey Lau_of_DK! |
| 10:00 | mecolin | cgrand: what if y is in different namespace ? |
| 10:01 | cgrand | mecolin: java interop (.setRoot or something like that) |
| 10:02 | cgrand | (.bindRoot #'my/var new-value) |
| 10:02 | cgrand | Lau_of_DK: did you look at Madison? |
| 10:03 | Lau_of_DK | Yea, Im helping dan a little, getting it ready for Github/alpha |
| 10:03 | cgrand | hmmm... then what is already up is pre alpha? |
| 10:04 | cgrand | I was looking for cookie and session mngment. Is there such a thing? |
| 10:04 | Lau_of_DK | He uped it last night? |
| 10:04 | Lau_of_DK | upped |
| 10:04 | cgrand | http://github.com/danlarkin/madison/tree/master |
| 10:04 | Lau_of_DK | Oh so it is |
| 10:05 | Lau_of_DK | I havent come across session/cookie handling. So far Ive gone through the tests, basic setup, and the automated project creation tool |
| 10:06 | cgrand | ok, in my ring's fork there's some cookie handling stuff |
| 10:06 | Lau_of_DK | Which all works great |
| 10:06 | Lau_of_DK | Cool |
| 10:07 | cgrand | and I'd like to provide HttpCore as another backen to ring (not servlet-based and smaller than Jetty) |
| 10:09 | eevar | cgrand, what's wrong with servlets? |
| 10:12 | cgrand | eevar: they do too much |
| 10:16 | Lau_of_DK | Like what? |
| 10:16 | Lau_of_DK | And cgrand, how does your HttpCore work ? |
| 10:17 | eevar | the ruby world has spent ages coming up with a unified request+response interface (rack), Java already has that, and I doubt fragmentation would help anyone |
| 10:18 | Lau_of_DK | eevar, you'll have to learn sooner or later: If cgrand says its a good idea, it is a good idea |
| 10:20 | cgrand | Lau_of_DK: it's not mine it's Apache's http://hc.apache.org/httpcomponents-core/ |
| 10:20 | Lau_of_DK | ah ok |
| 10:20 | Lau_of_DK | But whats gained specifically from switching away from servlets? cgrand |
| 10:21 | leafw | what is the proper way to add documentation to a defmulti? |
| 10:21 | Chouser | (alter-var-root #'clojure.core/*print-length* (constantly 99)) |
| 10:22 | kotarak | leafw: (defmulti foo "docstring" ....) |
| 10:22 | leafw | thanks kotarak |
| 10:23 | leafw | by the way, kotarak: you've got mail |
| 10:23 | kotarak | I've got mail? Just a sec. |
| 10:23 | leafw | (IIRC you wrote vimclojure) |
| 10:24 | mattrepl | just came across this statement on (ab)use of overloaded keywords in Java: "You can tell a language is mature when each keyword has multiple uses." |
| 10:30 | kotarak | leafw: you are albert? |
| 10:30 | leafw | kotarak: yes |
| 10:30 | kotarak | leafw: yes. I'm Meikel. |
| 10:31 | leafw | your nick matches one of the class namespace levels. Could guess that much :) |
| 10:31 | kotarak | leafw: kotarak means tomcat in bulgarian, kotka is cat. :) |
| 10:32 | leafw | I gabariu pa ruski nemnoga, pa ne pa bulgarski :( |
| 10:33 | AWizzArd | Ja nje ponamaju po russki |
| 10:34 | leafw | AWizzArd: said in perfect russian, ole |
| 10:34 | AWizzArd | na logen ;) |
| 10:35 | AWizzArd | ,(for [a (range 5) :let [x (* a a)]] x) |
| 10:35 | clojurebot | (0 1 4 9 16) |
| 10:35 | AWizzArd | Does this work for you in svn r1327? |
| 10:36 | Lau_of_DK | ,(for [a (range (Math/pow 2 12))] (map println (range 0 a))) |
| 10:36 | clojurebot | Execution Timed Out |
| 10:36 | Lau_of_DK | :( |
| 10:37 | Lau_of_DK | ,(doseq [spam (range 100)] (Thread/sleep 50) (println spam)) |
| 10:37 | clojurebot | 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
| 10:39 | kotarak | leafw: jena mi e belgarka. kak e kotka na ruski? Come si dice "cat" in russo? |
| 10:40 | cgrand | Lau_of_DK: ring is an abstraction (similar to Rack) of the http protocol as is HttpCore, everything that Servlets provide can be modularly added |
| 10:40 | leafw | kotarak: katioshka |
| 10:40 | Lau_of_DK | I get that - I was just poking at which particular features of servlets you're looking to remove |
| 10:42 | cgrand | Lau_of_DK: auth + some encoding issues + web.xml hell |
| 10:44 | kotarak | leafw: to answer the easy question: The repl checks for the Clojure=> prompt. When you delete it by accident (as you described in the email) the repl can get confused. This is only text.... the limits of Vim. |
| 10:45 | kotarak | leafw: There needs to be more error checking. At the moment I'm actually happy, that it works at all. |
| 10:47 | kotarak | leafw: The Heisenbugs you describe are a bit puzzling. Can you try to get hold of them and find a way to repreduce them? |
| 10:47 | leafw | kotarak: yeah, I am happy too. I wish I knew more vim internals (I'm just a power user) to be able to help there |
| 10:47 | leafw | kotarak: I have been trying to reproduce them. I need to test smaller sets of files -- I'm editing a large project right now |
| 10:48 | leafw | will do today. |
| 10:50 | kotarak | leafw: haha. Lucky you! The vim internals are a horror cabinet of inconsistencies and hacks. ;) |
| 10:51 | mattrepl | cgrand: what's the plan for handling multipart/form-data in ring? there's the FileUpload lib from Apache to decode it, but it needs the servlet request object |
| 10:51 | mattrepl | s/handling/exposing |
| 10:53 | cgrand | mattrepl: haven't thought about this yet |
| 10:54 | mattrepl | it may be ugly, but adding the original servlet req object to ring's req map might be the pragmatic choice to leverage existing libs that expect the servlet interface |
| 10:54 | mattrepl | that way multipart/form-data support becomes middleware |
| 10:55 | kotarak | leafw: May I ask a stupid question? How do you switch between buffers? Simply switching shouldn't cause VimClojure to do anything. |
| 10:56 | leafw | control+w j to go to the buffer below-- split windows |
| 10:57 | kotarak | leafw: you may also check the bleeding-edge branch in the repo. There I added a better error reporting. (Not in a buffer, yet, but with more information what went wrong). Maybe it can help you to track down the problem. http://bitbucket.org/kotarak/vimclojure |
| 10:57 | leafw | thanks! |
| 10:58 | cgrand | mattrepl: I think that FileUpload provides some classes (eg MultipartStream) that will help without requesting the Servlet interface |
| 10:58 | cgrand | bbl |
| 10:59 | leafw | kotarak: another error: when pushing return after (defn [] ..), the cursor doesn't return all the way to under the ( of (defn, but rather two spaces to its right. |
| 10:59 | kotarak | leafw: works for me |
| 11:01 | leafw | kotarak: would be nice if you could deliver a minimal .vimrc that does all. I have lots of vars and functions defined in there that may interfere. |
| 11:04 | kotarak | leafw: you mean as a complete example of all settings necessary? |
| 11:05 | leafw | that would be a minimal one -- but I am sure you have other settings enabled, which do not interfere. Like incremental search and what not. |
| 11:05 | kotarak | sure |
| 11:05 | leafw | I'd like to see what do I have to trim down, or at least, from where should I start. |
| 11:06 | kotarak | Ok. I can send you my .vimrc, if you want. |
| 11:07 | leafw | that' be nice :) |
| 11:12 | kotarak | leafw: email is away :) |
| 11:12 | leafw | thanks :) |
| 11:16 | lisppaste8 | leafw pasted "untitled" at http://paste.lisp.org/display/77018 |
| 11:17 | leafw | do the (.width r) and (.height r) get multiplied as Number or as primitive int? |
| 11:19 | Lau_of_DK | I would be surprised if it wasnt primitive |
| 11:19 | leafw | Lau_of_DK: point is, don't know how to check |
| 11:19 | leafw | because * is a fn, so it takes Object args |
| 11:20 | leafw | I don't know what magic has been added there to circumvent that. |
| 11:20 | Lau_of_DK | But if you (class x) , both number and primitive would return Integer wouldnt they ? |
| 11:20 | leafw | I think so |
| 11:20 | leafw | ,(class (int 0)) |
| 11:20 | clojurebot | java.lang.Integer |
| 11:21 | kotarak | (doc unchecked-mult) |
| 11:21 | clojurebot | I don't understand. |
| 11:21 | kotarak | Hmm... |
| 11:21 | kotarak | I think there were this unchecked math things. |
| 11:21 | leafw | (doc unchecked-*) |
| 11:21 | clojurebot | Titim gan �ir� ort. |
| 11:21 | Lau_of_DK | (defn * |
| 11:21 | Lau_of_DK | "Returns the product of nums. (*) returns 1." |
| 11:21 | Lau_of_DK | {:inline (fn [x y] `(. clojure.lang.Numbers (multiply ~x ~y))) |
| 11:21 | Lau_of_DK | :inline-arities #{2}} |
| 11:21 | Lau_of_DK | ([] 1) |
| 11:21 | Lau_of_DK | ([x] (cast Number x)) |
| 11:21 | Lau_of_DK | ([x y] (. clojure.lang.Numbers (multiply x y))) |
| 11:21 | Lau_of_DK | ([x y & more] |
| 11:21 | Lau_of_DK | (reduce * (* x y) more))) |
| 11:22 | leafw | ,(doc unchecked-multiply) |
| 11:22 | clojurebot | "([x y]); Returns the product of x and y, both int or long. Note - uses a primitive operator subject to overflow." |
| 11:23 | leafw | but I recall rhickey saying that math operators do boundary checks with primitives unless they overflow, in which occasion they'd use BigInteger and such |
| 11:24 | kotarak | leafw: I think this :inline magic above makes primitives possible when (.width) etc. return such. |
| 11:32 | leafw | how can one define a function that takes a named argument, i.e. like :else in cond, or does it have to be a macro? |
| 11:32 | leafw | I think it has to be a macro ... but I may be wrong |
| 11:32 | leafw | and can one define a macro with different arities? |
| 11:34 | kotarak | leafw: sure. (defmacro foo ([x] ...) ([x y] ...)) Macros are in the end only functions. |
| 11:35 | leafw | ok |
| 11:35 | kotarak | leafw: for the named parameter: (defn foo [x y & named-args] (let [{keys [name1 name2] :or {name1 :abc name2 :fgh}} (apply hash-map named-args)] ....)) |
| 11:36 | kotarak | leafw: then (foo some-x some-y :name2 :xyz) |
| 11:37 | leafw | aha you deconstruct the named-args |
| 11:37 | kotarak | leafw: yes, inclusive default values, of course only if you want those. |
| 11:37 | leafw | I noticed the default values, that :or |
| 11:38 | leafw | very nice |
| 11:38 | Chouser | :else is just a keyword, so there's no problem passing that to a function. |
| 11:39 | leafw | its just so simple I thought it had to be more complicated. |
| 11:40 | kotarak | leafw: this is Rich's version http://paste.lisp.org/display/69347 (haven't tried it myself, though) |
| 11:44 | leafw | I can barely read it. Half the functions I've never used them yet. |
| 11:44 | leafw | mapcat, complement, array-map, split-with. |
| 11:46 | kotarak | I think you use it like this: (defnk foo [x y :name1 abc :name2 fgh] ...) and don't need the boilerplate I showed above. |
| 11:47 | leafw | nice |
| 11:48 | kotarak | maybe this should go to clojure.contrib.def *hints at Chouser* :) |
| 11:50 | leafw | \me seconds that |
| 12:15 | tashafa | ,(doc dup) |
| 12:15 | clojurebot | java.lang.Exception: Unable to resolve var: dup in this context |
| 12:15 | tashafa | ,(doc duplicate) |
| 12:15 | clojurebot | java.lang.Exception: Unable to resolve var: duplicate in this context |
| 12:16 | tashafa | ,(repeat 2 "r") |
| 12:16 | clojurebot | ("r" "r") |
| 12:16 | tashafa | ha |
| 12:17 | tashafa | ,(repeat "r") |
| 12:17 | clojurebot | Execution Timed Out |
| 12:17 | tashafa | ,(repeat "r") |
| 12:17 | tashafa | hmm |
| 12:17 | clojurebot | Execution Timed Out |
| 12:18 | tashafa | is that the epected behaviour? |
| 12:18 | tashafa | expected* |
| 12:18 | eevar | you asked for an infite sequence of 'r's |
| 12:19 | eevar | ,(doc repeat) |
| 12:19 | clojurebot | "([x] [n x]); Returns a lazy (infinite!, or length n if supplied) sequence of xs." |
| 12:30 | Hun | seems clojurebot is eager |
| 12:31 | tashafa | ah |
| 12:31 | tashafa | thanks |
| 12:34 | eevar | ,(set! *print-length* 10) |
| 12:34 | clojurebot | java.lang.IllegalStateException: Can't change/establish root binding of: *print-length* with set |
| 12:49 | Chouser | ,(,(alter-var-root #'clojure.core/*print-length* (constantly 20)) |
| 12:49 | clojurebot | EOF while reading |
| 12:49 | Chouser | ,(alter-var-root #'clojure.core/*print-length* (constantly 20)) |
| 12:49 | clojurebot | 20 |
| 12:49 | Chouser | ,(repeat "r") |
| 12:49 | clojurebot | Execution Timed Out |
| 12:50 | Chouser | hmph |
| 12:50 | Chouser | ,(do (alter-var-root #'clojure.core/*print-length* (constantly 20)) (repeat "r")) |
| 12:50 | clojurebot | Execution Timed Out |
| 13:04 | slashus2 | ,(binding [*print-length* 5] (repeat 6 "r")) |
| 13:04 | clojurebot | ("r" "r" "r" "r" "r" "r") |
| 13:06 | slashus2 | ,(binding [*print-length* 5] (println (repeat 6 "r"))) |
| 13:06 | clojurebot | (r r r r r ...) |
| 13:06 | Chouser | I was hoping to find a way to make it stick. |
| 13:06 | Chouser | but I guess clojurebot runs each expression in a new thread, so fresh thread-local bindings. |
| 13:07 | slashus2 | ,(alter-var-root #'clojure.core/*print-length* 5) |
| 13:07 | clojurebot | java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn |
| 13:11 | slashus2 | ,(alter-var-root *print-length* constantly 20) |
| 13:11 | clojurebot | java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.Var |
| 13:28 | leafw | kotarak: when the compiler throws an exception, *e in the Repl doesn |
| 13:28 | leafw | 't print it |
| 13:28 | leafw | where is that exception? Can one see a bit more into it? |
| 13:28 | leafw | it tells me the right clojure line, but makes no sense |
| 13:28 | leafw | oh nm |
| 13:28 | leafw | xD |
| 13:29 | leafw | user problem as usual |
| 13:30 | leafw | also: can macros be :use 'd in a ns declaration? i.e. (ns this.that (:use (t2.util some-macro-name))) |
| 13:30 | leafw | for some reason, that fails. |
| 13:33 | leafw | (doc ns) says that's the right way to use :use in a ns declaration. |
| 13:33 | clojurebot | Huh? |
| 13:33 | leafw | no for you, clojurebot |
| 13:33 | leafw | xD |
| 13:37 | durka42 | leafw: i think you use :only to get specific fns/macros by name |
| 13:37 | leafw | clojure-contrib contains half a dozen ways to use :use |
| 13:38 | leafw | hum |
| 13:38 | leafw | like this: (:use [clojure.contrib.test-is :only (deftest- is)])) |
| 13:38 | leafw | which is not documented in (doc ns) |
| 13:39 | durka42 | well, yes but i think in (doc ns) my.lib.this and my.lib.that are namespaces |
| 13:40 | durka42 | it is kind of documented in (doc use) |
| 13:41 | leafw | thanks, even a bit better in (doc refer) |
| 13:42 | kotarak | yeah, namespace docs are bit difficult (was away till now) |
| 13:42 | Puzzler | It's also confusing how sometimes you need to quote the name of the library, and sometimes you don't. |
| 13:43 | Puzzler | (e.g., (use 'permutations) but (in-ns permutations) |
| 13:43 | kotarak | Puzzler: (ns ....) no quote, (use ..), (require ...) quotes |
| 13:43 | kotarak | in-ns should also need a quote, no? |
| 13:43 | Puzzler | I don't think so, but then again, I'm the one who keeps getting confused :) ... |
| 13:43 | durka42 | in-ns does but ns doesn't |
| 13:44 | Puzzler | Maybe I'm thinking of the :use inside of an in-ns? |
| 13:44 | Puzzler | I'm pretty sure that doesn't need a quote. |
| 13:44 | durka42 | you're thinking of ns when you say in-ns |
| 13:45 | Puzzler | Yeah, you're right. |
| 13:45 | Puzzler | So why all the differences? |
| 13:46 | durka42 | hmm |
| 13:46 | durka42 | seems like everything is quoted except inside ns, because it's a macro |
| 13:47 | leafw | namespaces need a cleanup--it's overly confusing. |
| 13:48 | Puzzler | Speaking of cleanup, is there any difference between the find function and the get function (except that get takes an extra optional argument)? |
| 13:48 | Puzzler | Couldn't we ditch find? |
| 13:48 | leafw | on a different topic: would be nice if if-let would allow multiple bindings, and 'and' all of them as for the test. |
| 13:48 | Puzzler | I think the contrib library has a cond-let which is a similar idea. |
| 13:49 | Puzzler | But yes, I like that idea. I frequently end up with a bunch of nested if-lets, and it gets ugly fast. |
| 13:50 | leafw | Puzzler: yes. |
| 13:50 | Puzzler | Yesterday, I wrote my longest bit of Clojure code so far. |
| 13:51 | Puzzler | Opinion: It's easy to write, a bit tricky to debug with the crazy error messages, and somewhat hard to read when you're done with the whole thing. |
| 13:51 | leafw | I find it easy to read |
| 13:51 | leafw | but I create very short functions that call other named functions. |
| 13:52 | leafw | i.e. reads like prose, or I'd like to. |
| 13:52 | leafw | debugging is tricky, but environments like vimclojure make it easier |
| 13:53 | kotarak | Puzzler: that will change after wrote more clojure. Especially the readability thing. |
| 13:53 | Puzzler | I create relatively short functions also; it's more a function of how much you can fit on one line. When writing, it's natural to use long chains of map/filter/whatever, but when reading back, it's totally unclear what it does. |
| 13:53 | Chousuke | don't put so much on one line then :) |
| 13:53 | Puzzler | Yes, but once you wrap around more than one line, it's even less clear. |
| 13:53 | Puzzler | :) |
| 13:54 | Puzzler | Also, I have similar problems with drilling down into maps via keys and such. |
| 13:54 | Puzzler | Easy to write (because maps work like functions), but hard to read back, because it looks just like everything else. |
| 13:54 | Puzzler | There's something to be said for good old dot syntax to deal with deeply nested structures. |
| 13:55 | Chousuke | then perhaps your map is misnamed :/ |
| 13:55 | Chousuke | you might also want to take a look at the -> macro |
| 13:55 | kotarak | together with update-in, get-in, assoc-in... |
| 13:57 | leafw | so -> looks for a key in a map and into any submaps nested in there, recursively? |
| 13:57 | Chousuke | no |
| 13:57 | Chousuke | its more generic. |
| 13:57 | Puzzler | By the way, I've probably written as much Scheme code as C/C++/Java/Python code in my life, and I've always felt this way. My feeling about Clojure being easier to write than read is no different than my feeling about Scheme, which I've used for many years. |
| 13:57 | kotarak | It uses that keywords are functions of maps. |
| 13:58 | leafw | the (doc ->) is a piece of art, and would benefit from an example. |
| 13:58 | Puzzler | Python is my favorite language *to read*. But for much of my work, I can really get much more done with immutable data structures. |
| 13:58 | Chousuke | (-> foo (bar barend) zonk) expands into (-> (bar foo barend) zonk) and that becomes (zonk (bar foo barend)) |
| 13:58 | Puzzler | So I use Scheme/Clojure/etc. |
| 13:59 | kotarak | (-> thing a b (c d) (e)) <=> (e (c (b (a thing)) d)) |
| 13:59 | Chousuke | so (-> map :key :key2) eventually becomes (:key2 (:key map)) |
| 14:00 | kotarak | ,(-> {:a {:b {: c 5}}} :a :b :c) |
| 14:00 | clojurebot | Invalid token: : |
| 14:00 | kotarak | ,(-> {:a {:b {:c 5}}} :a :b :c) |
| 14:00 | clojurebot | 5 |
| 14:02 | durka42 | maybe i'll write one |
| 14:02 | Chousuke | heh |
| 14:02 | kotarak | durka42: I think konrad hinsen did that, you should check the list archive |
| 14:03 | Lau_of_DK | durka durka |
| 14:04 | Lau_of_DK | kotarak, RE your commercial Im like "whoa!" - Vim can actually calculate line numbers now? Man thats progress :) |
| 14:05 | kotarak | Lau_of_DK: SLIME obviously is not able to do it. :P |
| 14:05 | p_l | kotarak: cause Lisp doesn't have lines... |
| 14:05 | kotarak | p_l: so then why do people complain? ;) |
| 14:06 | p_l | kotarak: I guess they don't grasp there's no lines... |
| 14:06 | durka42 | what's the difference between coll? and seq?? |
| 14:06 | durka42 | http://groups.google.com/group/clojure/msg/28837d55525306d8 |
| 14:06 | kotarak | coll? tests for collections (IPersistentCollection), seq? for seqs (ISeq), I guess. |
| 14:07 | kotarak | Ok. So it was not Konrad, then... |
| 14:08 | durka42 | Clojure=> (macroexpand-r '(-> thing a b (c d) (e))) |
| 14:08 | durka42 | (e (c (b (a thing)) d)) |
| 14:14 | Drakeson | do you know of any `shell' ns written for clojure? |
| 14:15 | leafw | Drakeson: what do you mean? |
| 14:15 | kotarak | Drakeson: there is clojure.contrib.shell-out or something like that |
| 14:15 | Drakeson | in the spirit of eshell in emacs |
| 14:16 | Drakeson | or even more lispy |
| 14:16 | kotarak | I don't know eshell, maybe something like scsh? |
| 14:19 | leafw | kotarak: does vimclojure have a binding for \rf all .clj buffers? |
| 14:20 | kotarak | leafw: yes. The bindings are set for all buffers. For buffers w/o a ns or in-ns at the top it doesn't make much sense, though. |
| 14:20 | leafw | would be also nice if \rf of a file also \rf any .clj cited on the :use of its namespace. |
| 14:20 | Drakeson | kotarak: shell-out is also interesting, for slightly different purposes. eshell provides a bash-like shell with a many commands written in elisp. you can also define eshell/foo-command in lisp, and run foo-command in the shell. |
| 14:20 | leafw | kotarak: I mean load all buffers, in one shot. |
| 14:21 | kotarak | leafw: ah, no. That's not implemented, yet. |
| 14:22 | leafw | kotarak: I wouldn't mind bufdo \rf if it could be done in the right order of dependencies. |
| 14:22 | p_l | just make a clojure machine.... |
| 14:22 | kotarak | Drakeson: sounds like scsh for scheme. Although that is not intended for interactive use. I don't think, that something like that is available for Clojure, yet. |
| 14:23 | kotarak | leafw: well, \rf figures this out itself. I can change the :reload to :reload-all. |
| 14:23 | Drakeson | I am still thinking of doing scripting in clojure. Instead of #!/path/to/clj-wrapper, I want to experiment with a clojure.lang.Repl, or something like clojure.contrib.shell-repl (to be created) as the main shell. |
| 14:23 | leafw | kotarak: or just one more binding for reload-all. |
| 14:23 | kotarak | leafw: currently \rf means: (require :reload :verbose '<contents of b:vimclojure_namespace>) |
| 14:23 | kotarak | leafw: or that. \rF |
| 14:24 | leafw | the problem with reload all is: does order matter? |
| 14:24 | kotarak | leafw: no. That's what require is for. But some things might be reloaded several times. |
| 14:24 | kotarak | when you do bufdo .... |
| 14:25 | leafw | kotarak: that's ok, would be great. So \rF is not yet there, is it |
| 14:25 | kotarak | hahahahahrahrarhaharhar }:-) |
| 14:25 | kotarak | leafw: not, but is to add. Will be up on the repo this evening. |
| 14:26 | leafw | thanks ! |
| 14:26 | kotarak | is easy to add |
| 14:26 | leafw | :) |
| 14:26 | leafw | finally, proper incremental programming .. for java! MWAHAHA |
| 14:26 | kotarak | \o/ |
| 14:27 | kotarak | leafw: wait till you get the snippet completion I'm working on. ;) Who needs IDEs? |
| 14:27 | leafw | I hate eclipse and netbeans, if that's what you meant. |
| 14:27 | leafw | I considered eclim for a while, but one needs to know eclipse too well. |
| 14:27 | kotarak | I'm also not a particular fan of them. |
| 14:28 | leafw | they lack an editor ;) |
| 14:28 | kotarak | And it was kind of unstable for me.... |
| 14:28 | kotarak | eclim I mean |
| 14:28 | Drakeson | can you do debugging in vimclojure or slime+clojure, yet? |
| 14:28 | leafw | although there is a jvi plugin for them. |
| 14:28 | leafw | Drakeson: vimclojure gives you back the line number with the error |
| 14:28 | kotarak | Drakeson: not in vimclojure and probably not any time soon |
| 14:28 | leafw | it's something :) |
| 14:29 | kotarak | Yes, such basic things. :) But no integrated debugger. |
| 14:29 | Drakeson | not just the location of the error. I want to step over a function and see what happens ... |
| 14:29 | leafw | and is always right, so far. |
| 14:29 | kotarak | Even when re-evaling code VC tries hard to get the line numbers right. Also they might diverge slowly for code below the change. |
| 14:30 | kotarak | And it seems that it does a better job than SLIME in that respect. :) |
| 14:38 | Drakeson | how can I see a list of public symbols of a namespace? |
| 14:38 | kotarak | (keys (ns-interns (the-ns 'some.ns))) |
| 14:39 | hiredman | Drakeson: clojure.org/namespaces has a list of useful namespace related functions |
| 14:39 | kotarak | ,(keys (ns-interns (the-ns 'clojure.set))) |
| 14:39 | clojurebot | (rename-keys union select project join intersection bubble-max-key map-invert difference rename index) |
| 14:40 | Drakeson | great, thanks |
| 14:42 | leafw | good night everybody |
| 14:44 | kotarak | leafw: still here? |
| 14:44 | kotarak | leafw: \rf is actually \rF :) |
| 14:45 | kotarak | But will change it now. |
| 14:47 | dnolen | anyone tried connecting to a remote Clojure REPL with SLIME using clojure.contrib.server-socket? |
| 14:58 | Drakeson | dnolen: I am run swank on the remote machine, make an ssh tunnel (ssh -L ...) to it, and use slime-connect to connect. not so perfect but works. |
| 14:58 | Drakeson | s/am// |
| 15:00 | Jedi_Stannis | kotarak: C-up and C-down are not working for me in the vimclojure repl |
| 15:05 | dnolen | Drakeson: cool! so how does the swank bit the remote machine work? and what's lacking? |
| 15:06 | dnolen | the swank bit _on_ the remote machine work i mean. |
| 15:07 | dnolen | Drakeson: do you just load up swank.clj? |
| 15:11 | mecolin | is there any way to call a private function from a different namespace (for debug purposes) ? |
| 15:12 | Chouser | as cgrand says, yell at it until it obeys |
| 15:12 | Chouser | (@#'other.namespace/foo 1 2 3) |
| 15:14 | mecolin | Chouser: thanks |
| 15:15 | Lau_of_DK | @#' ? |
| 15:15 | Lau_of_DK | You guys are getting worse and worse at these secret Rich Hickey disciple black belts tricks |
| 15:16 | Lau_of_DK | "Gen-class doesnt work" "oh, you just have to (gen-class #@$$.---!!your.class.foo (:use (@foobiedoopie_@))) where foobiedoopie is hardcoded into core" |
| 15:18 | Drakeson | dnolen: swank.clj is a bunch of defn's. I put (:require [swank.swank]) in the remote ns, and do (swank.swank/start-server ".slime-socket" :port 4005 :encoding "utf-8") in the remote code. |
| 15:18 | danlarkin | Lau did you see, madison has been published! |
| 15:18 | Lau_of_DK | I saw my friend - Good work :) |
| 15:19 | danlarkin | now the real work begins |
| 15:19 | Lau_of_DK | up until now its been fake work ? |
| 15:21 | danlarkin | haha |
| 15:21 | danlarkin | well now people can see it |
| 15:24 | Lau_of_DK | Everybody got that? danlarkin is making a full port of Django to Clojure - Its on Github named 'Madison' - Please have a look and submit quality code snippits asap plz |
| 15:25 | danlarkin | :-o |
| 15:27 | dnolen | Drakeson: hmm, I'm getting a "error in process filter: No inferior lisp process" when testing out connecting to the remote repl on the server itself. |
| 15:27 | dnolen | Drakeson: that's the error from slime-connect 127.0.0.1 port 9998 in my case. |
| 15:28 | Drakeson | dnolen: did you do ssh -L 9988:localhost:9988 user@remotehost ? |
| 15:32 | dnolen | Drakeson: just trying test from the server itself, do I need to setup a tunnel? I'm starting up a REPL on the server, starting up swank, then I launch emacs and trying to connect with slime-connect. Is there something wrong with that setup. Thanks much for the help on this. |
| 15:32 | dnolen | launch emacs from the server (not my local machine) |
| 15:32 | Drakeson | dnolen: no, you don't need the tunnel |
| 15:33 | dnolen | any thoughts about the No inferior lisp process error then? |
| 15:33 | Drakeson | did you put that line in the code on the server? |
| 15:33 | dnolen | slime-connect? yes |
| 15:34 | Drakeson | I mean: (swank.swank/start-server ".slime-socket" :port 4005 :encoding "utf-8") |
| 15:34 | dnolen | yes I did that on the server when I launched the REPL from the command line |
| 15:37 | Drakeson | I just did a vanilla test: on the command line: clj RET, (require 'swank.swank)(swank.swank/start-server "/dev/null" :port 4006 :encoding "utf-8") RET. Now I can M-x slime-connect to this port. |
| 15:38 | Drakeson | (in other words, works for me) |
| 15:38 | Drakeson | do you have recent versions of slime and swank-clojure? |
| 15:38 | dnolen | thanks for verifying checking. |
| 15:39 | Lau_of_DK | clojurebot, seen technomancy? |
| 15:39 | Drakeson | (for instance, I had a fairly old slime (about 1-2 months old, I guess), and I was getting a similar error as what you got) |
| 15:41 | dnolen | are you using the slime mirror from github or somewhere else? |
| 15:45 | Drakeson | slime: git://git.boinkor.net/slime.git, swank-clojure: git://github.com/jochu/swank-clojure.git |
| 15:48 | Lau_of_DK | hiredman, didnt you implement that 'seen' functionality ? |
| 15:48 | Lau_of_DK | ~seen technomancy? |
| 15:48 | clojurebot | no, I have not seen technomancy |
| 15:48 | Lau_of_DK | ~why not? |
| 15:48 | clojurebot | why not? |
| 15:49 | Lau_of_DK | ~yes, why havent you seen him? He's been here quite a few times... when suddenly... |
| 15:49 | clojurebot | no, I have not seen him? He's been here quite a few times... when suddenly... |
| 15:49 | cmvkk_ | heh |
| 15:51 | Drakeson | can you make clojurebot say something that then he himself says CLABANGO? :D |
| 15:51 | hiredman | clojurebot doesn't persist its seen information |
| 15:52 | Drakeson | ~yes ~ ... when suddenly ... |
| 15:52 | clojurebot | CLABANGO! |
| 16:00 | Raynes | ~yes, the sky turned dark. The ground opened up and the demons came... When suddenly... |
| 16:00 | clojurebot | CLABANGO! |
| 16:06 | Drakeson | (println "~ ...when suddenly ...") |
| 16:06 | Drakeson | ,(println "~ ...when suddenly ...") |
| 16:06 | clojurebot | ~ ...when suddenly ... |
| 16:06 | Drakeson | ,(println "~ ... when suddenly ...") |
| 16:07 | clojurebot | ~ ... when suddenly ... |
| 16:07 | Drakeson | ,(println "~ I was bot abusing... when suddenly ...") |
| 16:07 | clojurebot | ~ I was bot abusing... when suddenly ... |
| 16:07 | Drakeson | ~ I was bot abusing... when suddenly ... |
| 16:07 | clojurebot | CLABANGO! |
| 16:07 | Drakeson | d'oh! |
| 16:09 | Chouser | lisppaste8: url |
| 16:09 | lisppaste8 | To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste. |
| 16:09 | Chouser | ah, that's not addressed to clojurebot, so no looping ability there. |
| 16:10 | Chouser | ~paste |
| 16:10 | clojurebot | lisppaste8, url |
| 16:10 | lisppaste8 | To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste. |
| 16:11 | Drakeson | how can I remove a namespace from the repl? |
| 16:12 | arohner | Drakeson: the whole namespace, or an individual var? |
| 16:12 | Chouser | namespace functions are at: http://clojure.org/namespaces |
| 16:12 | hiredman | ^- |
| 16:12 | Chouser | there's a section named "Removing things" |
| 16:13 | Drakeson | silly me |
| 16:13 | Drakeson | thanks |
| 16:13 | arohner | ,(doc remove-ns) |
| 16:13 | clojurebot | "([sym]); Removes the namespace named by the symbol. Use with caution. Cannot be used to remove the clojure namespace." |
| 16:13 | Chouser | skillsmatter must have a different definition of "soon" than I do. |
| 16:14 | hiredman | still not up? |
| 16:14 | Chouser | nope |
| 16:26 | arohner | can I do a ref-set followed by an alter in the same transaction? |
| 16:26 | arohner | on the same ref |
| 16:28 | arohner | it appears that after the ref-set, @my-obj is nil |
| 16:34 | Lau_of_DK | Can somebody explain this fnparse for me? What is it? |
| 16:40 | kotarak | Lau_of_DK: is a parser library. I understand (roughly) like this: (fnparse EBNF) => parser-for-the-grammar) |
| 16:42 | arohner | isn't there a var that limits how much of a struct a repl will print? |
| 16:43 | arohner | I accidentally printed a big struct, and it's been going for a few minutes now... |
| 16:43 | kotarak | *print-length*, IIRC |
| 16:44 | arohner | thanks. is that doc'd anywhere? I couldn't find it |
| 16:46 | hiredman | ,(doc *print-length*) |
| 16:46 | clojurebot | "; *print-length* controls how many items of each collection the printer will print. If it is bound to logical false, there is no limit. Otherwise, it must be bound to an integer indicating the maximum number of items of each collection to print. If a collection contains more items, the printer will print items up to the limit followed by '...' to represent the remaining items. The root binding is nil indicating no limit. |
| 16:47 | gnuvince_ | I downloaded jsr166y.jar and started my REPL with -cp /path/to/jsr166y.jar, but I still can't require clojure.parallel |
| 16:47 | gnuvince_ | Any ideas? |
| 16:47 | durka42 | i think the classes have been moved into the jsr166-extra.jar or something like that |
| 16:48 | gnuvince_ | ok |
| 16:48 | lisppaste8 | durka42 pasted "clojure.parallel" at http://paste.lisp.org/display/77047 |
| 16:48 | durka42 | when i was playing with clojure.parallel i had to do that in parallel.clj |
| 16:48 | durka42 | i don't know if that is still relevant |
| 16:50 | arohner | hiredman: when asking if that was doc'd, I meant on clojure.org. I expected to find it in "main and repl" |
| 16:51 | Lau_of_DK | kotarak, its greek to me |
| 16:54 | kotarak | Lau_of_DK: EBNF => Enhanced(?) Backus-Naur-Form, I didn't look into fnparse, though. So don't ask me about its details. |
| 16:55 | Lau_of_DK | Ok I wont :) |
| 16:56 | hiredman | I started playing with fnparse and tried to translate a wiki-markup ebnf |
| 16:56 | hiredman | but I think I lacked a grasp on some of the key concepts |
| 16:58 | hiredman | so I eagerly wait someone writing a fnparse for dummies blog post |
| 16:58 | Lau_of_DK | k - I should look up a pdf on google-tech-docs on functional parsing |
| 16:58 | hiredman | last I tried the pdf it 404'ed |
| 17:02 | danlarkin | Lau_of_DK: fnparse is really cool :-o |
| 17:03 | dnolen | Drakeson: thx for the help earlier, turns out it was working the whole time, but I need to call slime-repl directly from emacs. |
| 17:07 | danlarkin | the idea behind a functional parser (aka parser combinator) is that you get a lexer and a parser in one step |
| 17:07 | hiredman | all well and good |
| 17:07 | hiredman | but how do you use it? |
| 17:08 | danlarkin | http://github.com/danlarkin/madison/blob/59dd04cd3723e9fbcb83ca40724e18312106bc9d/src/madison/template/parser.clj |
| 17:08 | hiredman | not helping |
| 17:09 | danlarkin | it's bottom up style |
| 17:10 | hiredman | still not helping |
| 17:10 | danlarkin | so you write a little function that matches "<" for instance |
| 17:10 | danlarkin | and then one that matches ">" |
| 17:10 | danlarkin | and then one that matches stuff that's valid to have inside a < and > |
| 17:10 | danlarkin | and then you're on your way to an xml parser |
| 17:10 | hiredman | then combine them |
| 17:10 | danlarkin | ..kinda |
| 17:10 | hiredman | hmmm |
| 17:15 | danlarkin | and the nice thing about the parser combinator is that it combines the lexing and parsing, so you can have semantics assigned to "<element>" and in one pass turn it into whatever, instead of first tokenizing it and then parsing the tokens |
| 17:16 | hiredman | mmm |
| 17:17 | kotarak | and you can make parser on the fly. you parse a <element> and then create on the fly a parser for </element>. Matching the exact element. |
| 17:19 | hiredman | I guess I'll just have to get back on the horse and try again |
| 17:20 | leafw | kotarak: the problem I was seeing earlier on, related to the heisenbug, is gone once all namespace declarations of all involved files are properly set. |
| 17:20 | leafw | kotarak: looks like vimclojure is very sensitive to proper ns declaration (which as we said earlier lacks documented examples of all its possibilities) |
| 17:20 | kotarak | leafw: :) good to hear. |
| 17:21 | kotarak | leafw: yeah the namespace are difficult to grasp in the beginning.. |
| 17:22 | hiredman | ~namespace |
| 17:22 | clojurebot | namespaces are (more or less, Chouser) java packages. they look like foo.bar; and corresponde to a directory foo/ containg a file bar.clj in your classpath. the namespace declaration in bar.clj would like like (ns foo.bar). Do not try to use single segment namespaces. a single segment namespace is a namespace without a period in it |
| 17:22 | kotarak | Well. I have to rely on correct code. The mind_reader.vim plugin doesn't work in my MacVim, yet. ;) |
| 17:22 | leafw | xD |
| 17:23 | leafw | hiredman: (doc ns) leads to (doc use) which leads to (doc refer). The whole thing could take a nice dedicated page with its variety of possibilities. |
| 17:23 | hiredman | I supose clojure.org/namespace might be the place too put it |
| 17:24 | leafw | like combining several (:use [this.that :only (one two)] [other.there :only (three)]), combined with full :use of libs, and :import ... |
| 17:25 | kotarak | (:use (common.prefix [this :only (that)] [an :exclude (other)])) |
| 17:26 | leafw | woah |
| 17:26 | leafw | didn't know that one. |
| 17:26 | kotarak | That's basically all features in one form |
| 17:26 | kotarak | require has :as but the syntax is the same |
| 18:58 | Lau_of_DK | Hail Sohail |
| 19:01 | sohail | yes, hail me |
| 19:15 | arohner | I'm really starting to get addicted to using if statements as expressions |
| 20:20 | Guest66367 | there are no "statements" |
| 20:23 | danlei | ,(find-doc |
| 20:23 | clojurebot | EOF while reading |
| 20:23 | danlei | ,(find-doc #"[Ss]tatement") |
| 20:24 | clojurebot | ------------------------- clojure.core/ns ([name & references]) Macro Sets *ns* to the namespace named by name (unevaluated), creating it if needed. references can be zero or more of: (:refer-clojure ...) (:require ...) (:use ...) (:import ...) (:load ...) (:gen-class) with the syntax of refer-clojure/require/use/import/load/gen-class respectively, except the arguments are unevaluated and need not be quoted. |
| 20:39 | hiredman | danlei: (?i) turns the regex into a case insensitive regex |
| 20:40 | hiredman | clojubreot may need its own version of find-doc |
| 21:49 | keithb | If I have a long Clojure file, is it a good or bad idea to create a main() function and then call it, a la http://is.gd/ndTV (see bottom)? |
| 22:08 | Chouser | keithb: I don't think it matters much yet. |
| 22:08 | Chouser | having a main function would help if you plan to compile to a stand-alone .jar |
| 22:10 | Chouser | But I'm sure you'll get more complete answers from your posting to the group. :-) |
| 22:57 | AWizzArd | Is there something like (join ..) instead of the common pattern (apply str ..)? |
| 23:11 | Chouser | in contrib.str-utils |
| 23:15 | AWizzArd | already found it, thanks :) |
| 23:15 | hiredman | I think having a main function is a good idea |
| 23:16 | hiredman | you don't even have to call it at the end of the file, jsut clojure.main -i somefile.clj -e "(main)" |
| 23:29 | replaca_ | hiredman: what does the -i do there? |
| 23:33 | hiredman | replaca_: it evals that file |
| 23:33 | hiredman | includes it |
| 23:33 | hiredman | I think it is -i |
| 23:33 | replaca_ | hiredman: ahh, ok, thx |
| 23:59 | hiredman | hah! |