2012-01-19
| 00:04 | clj_newb | The answer to this is probably "n00bs should not be doing this"; but anyways: is there a way to ahve a defrecord behave like a function? i.e. I want to be able to do something like (defrecord Foo ...) (def foo (Foo. ...)) ... (foo 1 2 3) <-- now foo is behaving as a function |
| 00:06 | bobhope | clj_newb, try (defrecord Foo [] IFn (invoke [this a b c] ...code)) |
| 00:06 | bobhope | IFn is the interface for things you can call |
| 00:06 | clj_newb | bobhope: nice; thanks |
| 00:20 | seancorfield | Raynes: what do you want to know about cat shows? |
| 00:21 | Raynes | seancorfield: Well, I didn't know of their existence. Now I'm interested in the popularity of such events and how many cats your wife has. |
| 00:24 | gf3 | is it possible to use (read-string) to read *all* expressions from a string, and not simply the first? |
| 00:24 | seancorfield | we've been breeding and showing for about 15 years - my wife's a cat show judge and gets to go all over the world |
| 00:25 | seancorfield | we're off to australia in august and then england and russia in september |
| 00:25 | seancorfield | we breed Bengal cats - hybrids with an Asian Leopard Cat |
| 00:27 | seancorfield | ,(doc read-string) |
| 00:27 | clojurebot | "([s]); Reads one object from the string s" |
| 00:27 | seancorfield | ,(apropos "read") |
| 00:27 | clojurebot | (read-line pop-thread-bindings thread-bound? read *read-eval* ...) |
| 00:27 | seancorfield | hmm, that wasn't much help |
| 00:28 | seancorfield | Raynes: as for "how many"... quite a few :) |
| 00:28 | Raynes | Huh. Well, I have one cat. |
| 00:28 | gf3 | e.g.: |
| 00:28 | gf3 | ,(read-string "(prn 9) (prn 11)") |
| 00:28 | clojurebot | (prn 9) |
| 00:28 | Raynes | No clue what breed she is. She lived under our houre. |
| 00:28 | gf3 | :( |
| 00:28 | Raynes | house* |
| 00:28 | Raynes | &(doc read) |
| 00:28 | lazybot | ⇒ "([] [stream] [stream eof-error? eof-value] [stream eof-error? eof-value recursive?]); Reads the next object from stream, which must be an instance of java.io.PushbackReader or some derivee. stream defaults to the current value of *in* ." |
| 00:28 | Raynes | gf3: ^ |
| 00:29 | Raynes | You'll want to create a pushbackreader out of your code and then read from it until it is depleted. This will involve a loop. |
| 00:29 | Raynes | Or recursion, or something. |
| 00:30 | gf3 | Raynes: thanks |
| 00:31 | JanxSpirit | the REPL doesn't do up-arrow history? |
| 00:31 | Raynes | JanxSpirit: The default Clojure repl? No. You want to rlwrap that. |
| 00:31 | Raynes | Or better yet, use Leiningen. |
| 00:31 | Raynes | Or at least reply. |
| 00:31 | Raynes | But you probably want Leiningen. |
| 00:31 | JanxSpirit | yeah I was wondering if Leiningen was the answer |
| 00:32 | JanxSpirit | it's *the way*? :) |
| 00:32 | JanxSpirit | I'll give it a go - how does it compare to SBT? |
| 00:33 | Raynes | Leiningen is our religious text. |
| 00:33 | Raynes | Not sure what 'SBT' is. |
| 00:33 | JanxSpirit | sorry it's the Scala "Simple Build Tool" |
| 00:34 | JanxSpirit | not that simple though |
| 00:34 | Raynes | Oh. Never used Scala. |
| 00:34 | Raynes | Leiningen is pretty simple. |
| 00:34 | gf3 | JanxSpirit: http://trac.macports.org/browser/trunk/dports/lang/clojure/files/clj-rlwrap.sh?format=txt |
| 00:34 | Raynes | Please don't install Clojure stuff via package managers. |
| 00:34 | Raynes | It's just going to give you a headache in the end. |
| 00:35 | JanxSpirit | package managers like RPM or APT and whatnot? |
| 00:35 | Raynes | Like anything. |
| 00:35 | JanxSpirit | I just downloaded and unzipped so far |
| 00:35 | Raynes | Installing Leiningen via a package manager is an okay way to get it as long as it has the latest version. |
| 00:36 | Raynes | And installing Leiningen is generally the equivalent of installing Clojure. |
| 00:36 | JanxSpirit | thanks gf3 |
| 00:36 | gf3 | np |
| 00:36 | JanxSpirit | OK - gonna install it |
| 00:37 | JanxSpirit | hey how do I exit the regular REPL? Feels like the first time I used vi ;) |
| 00:37 | gf3 | ⌃D |
| 00:37 | Raynes | ctrl+d should work. |
| 00:37 | JanxSpirit | cool thanks again |
| 00:39 | JanxSpirit | lein certainly seems straightforward |
| 00:39 | JanxSpirit | I think aptitude would have been slower ;) |
| 00:44 | seancorfield | with clojure you don't really need what sbt brings to the table (the watching and compiling) since clojure can be treated like a scripting language and just reloaded when it changes - and it compiles on the fly |
| 00:44 | JanxSpirit | cool - up arrow history achieved |
| 00:44 | JanxSpirit | lein does dependency management too? |
| 00:44 | seancorfield | with clojurescript it's worth having a watcher that does compilation (to javascript) |
| 00:44 | seancorfield | yes, lein handles dependencies - like maven only done right :) |
| 00:45 | seancorfield | lein can do everything - with a plugin :) |
| 00:45 | Raynes | Except it actually uses maven behind the scenes. |
| 00:45 | JanxSpirit | better than Ivy behind the scenes I think |
| 00:46 | JanxSpirit | SBT uses Ivy |
| 00:46 | seancorfield | well, it doesn't really use maven per se, but it can use maven repos |
| 00:46 | JanxSpirit | nice - yeah you need that |
| 00:46 | JanxSpirit | is there a "Clojure central" type repo? |
| 00:46 | JanxSpirit | BTW - I'm sure I can go read about this - just playing around and curious - ignore me all you want :) |
| 00:47 | seancorfield | clojars.org |
| 00:48 | seancorfield | lein checks maven central and clojars (and probably a few other places?) and you can tell it to check any other repos you want |
| 00:49 | Raynes | seancorfield: No, I'm pretty sure it uses maven. Maven is implemented as libraries on the backend, which Leiningen uses. |
| 00:49 | Raynes | Turtles all the way down. |
| 00:54 | amalloy | yes, lein bundles itself a copy of maven |
| 00:57 | seancorfield | i sit corrected Raynes amalloy - i thought it used a different library for that |
| 00:57 | JanxSpirit | maven has always worked better at dep management than Ivy in my experience |
| 00:57 | JanxSpirit | ok Clojars registered |
| 00:57 | seancorfield | still, the lein experience is way better than the maven experience |
| 00:57 | amalloy | seancorfield: he'd like it to |
| 00:57 | JanxSpirit | looks good |
| 00:57 | JanxSpirit | seancorfield: good ;) |
| 00:57 | JanxSpirit | what is lein telling me to do: |
| 00:58 | seancorfield | that's the downside of maintaining a contrib library - those use maven directly |
| 00:58 | JanxSpirit | Using JLine for console I/O; install rlwrap for optimum experience. |
| 00:58 | seancorfield | it's saying the UX is better if you have rlwrap installed and on your path |
| 00:59 | seancorfield | JLine is a fallback |
| 00:59 | JanxSpirit | dig |
| 00:59 | seancorfield | :) |
| 00:59 | Raynes | JLine is going to be removed as a fallback in 2.0, IIRC. |
| 00:59 | seancorfield | good to know |
| 00:59 | vreskcin | writing a blog post now on my re-purposing of noir-blog to build an an editable website for my dad's website on his book. |
| 01:00 | vreskcin | http://qftk.herokuapp.com |
| 01:01 | vreskcin | to get to the backend: http://qftk.herokuapp.com/admin |
| 01:02 | gf3 | JLine was really bad last I tried it |
| 01:02 | vreskcin | username guest password guest |
| 01:02 | JanxSpirit | is compojure the go-to REST framework? |
| 01:02 | vreskcin | it's not pretty, but it got the job done |
| 01:03 | vreskcin | JLine gets the job done too ;) |
| 01:04 | gf3 | JanxSpirit: Noir (based on compojure) is nice |
| 01:05 | brehaut | JanxSpirit: theres a few different REST specific libs around (not that i can remember the names off the top of my head) but i dont think any one would be described as 'go to' |
| 01:05 | mrevil | im using noir for that purpose |
| 01:05 | brehaut | compojure, moustache and noir are all entirely capable for doing REST APIs easily |
| 01:06 | vreskcin | mrevil: for restful framework, or to make a regular site, like the one I made? |
| 01:07 | gf3 | JanxSpirit: be sure to check out Hiccup and CSSGEN |
| 01:11 | seancorfield | i'm biased but i'll vote for fw/1 :) |
| 01:11 | seancorfield | i need to port the routes logic across to clojure before it's really good for REST |
| 01:12 | Raynes | seancorfield: I've been meaning to ask you, since I'm not using google in protest of SOPA, why would one use FW/1? Or anything based on something from Coldfusion, for that matter. |
| 01:13 | seancorfield | it's been around for over two years, in production, hundreds of users on the mailing list, about 10,000 downloads |
| 01:14 | seancorfield | some parts of the clojure version are cleaner / simpler than the cfml version, some not as much |
| 01:14 | JanxSpirit | http://stopsoap.com/ |
| 01:14 | seancorfield | and i prefer CFML - to include the free open source engines - rather than just ColdFusion which is Adobe's proprietary offering |
| 01:15 | seancorfield | :) |
| 01:17 | seancorfield | i'm trying to figure out how to use domina (from clojurescript:one) in another project... i thought i could just drop the lib folder into my project... and it seems to compile a :use or :require ok... but none of my cljs code works once i do that :( |
| 01:18 | seancorfield | i'm using lein-cljsbuild for compilation |
| 01:22 | vreskcin | yea, I thought that the selenium-like features in clojurescript one was pretty neat |
| 01:26 | seancorfield | vreskcin: yeah, cljs1 looks very impressive but i'd be happier if it was modular and could easily be used with other code |
| 01:28 | vreskcin | well, there was some inhibitions about letting it be a framework. Maybe they weren't completely confident it was the best workflow |
| 01:29 | vreskcin | and cljs doesn't do runtime compilation right? because then the compiler would have to be loaded in the browser... |
| 01:31 | vreskcin | I wonder how difficult it would be a worthwhile experiment to try though. |
| 01:31 | seancorfield | there's a cljs repl tho'... |
| 01:32 | vreskcin | right, I just thought it'd be need to have a repl and IDE in my browser. |
| 01:32 | seancorfield | hmm, maybe i just put the domina stuff in the wrong folder... i just moved my own dom functions to a new ns and was able to use that |
| 01:32 | seancorfield | vreskcin: have you watched the cljs1 video? |
| 01:33 | seancorfield | it's impressive - shows working with a live app in the browser, from a repl using cljs |
| 01:33 | kwertii | Are there any interesting solutions for managing the evolution over time of a relational database schema with Clojure? |
| 01:34 | clj_newb | (1) go to http://paste.lisp.org/display/127163 (2) this is a minimal test case trying to make a defrecord behave like a function. Why does it fail? |
| 01:34 | seancorfield | kwertii: lobos? |
| 01:34 | seancorfield | it does migrations |
| 01:34 | vreskcin | seancorfield: Yup. It's pretty neat. I mean an actual repl/ide and the cljs environment all in the browser. |
| 01:35 | clj_newb | Wizards of Clojure-land; I call upon thee. Slay this dragon: http://paste.lisp.org/display/127163 . |
| 01:35 | kwertii | seancorfield: looking at Lobos, not sure what it does beyond providing a thin S-expression mapping over the SQL commands |
| 01:35 | vreskcin | I suppose you could hook up a web ide/repl to talk back to the java repl, which in turn points back to the browser |
| 01:35 | brehaut | clj_newb: what dragon? |
| 01:35 | seancorfield | vreskcin: well, you need two windows regardles - one for the app, one for the repl - so why does it matter that one of them is in the browser and one in your ide? |
| 01:36 | clj_newb | brehaut: http://paste.lisp.org/display/127163 <-- why does this defrecord not behave like a function? |
| 01:36 | kwertii | seancorfield: there's also drift, and clj-liquibase |
| 01:36 | seancorfield | kwertii: hmm, then i'm not sure what you're looking for |
| 01:37 | JanxSpirit | kwertii: not clojure but in my relational days I used liquibase - uses XML to manage schema changes |
| 01:37 | brehaut | clj_newb: looks like your method signature for invoke is wrong |
| 01:37 | kwertii | seancorfield: ideally, I wouldn't have to maintain a huge chain of migrations. I'd just have a schema definition, and the lib could inspect the database state and figure out itself what needs to be done to make the DB look like the schema, warning about destructive actions.. |
| 01:38 | JanxSpirit | +1 |
| 01:38 | brehaut | clj_newb: (invoke [this args] …) |
| 01:38 | emezeske | Hmm, is there any simple way to truncate a string? All I can come up with is (take n "thestring"), but that doesn't return a string |
| 01:38 | clj_newb | brehaut: testing |
| 01:38 | clj_newb | brehaut: it worked |
| 01:38 | clj_newb | brehaut: can you explain to me: ... why can't I have the & like in normal functions? |
| 01:38 | Raynes | emezeske: ##(apply str (take 3 "abcdefg")) |
| 01:38 | clj_newb | this baffles me |
| 01:38 | lazybot | ⇒ "abc" |
| 01:39 | emezeske | Raynes: Thanks. It seems like Clojure's string manip libraries are fairly... lacking |
| 01:39 | Raynes | Protocols compile to interfaces. |
| 01:39 | kwertii | JanxSpirit: looking at clj-liquibase now. getting nightmarish flashbacks of J2EE and XML config files that are longer than the code |
| 01:39 | brehaut | clj_newb: because the interface for ifn has an object array as its argument. var args are a myth in java. clojure is able to maintain that myth, but when you step down to the interop level you have to deal with it yourself |
| 01:39 | Raynes | emezeske: That's because you can treat strings like sequences. Also, clojure.string. |
| 01:40 | Raynes | http://clojure.github.com/clojure/clojure.string-api.html |
| 01:40 | clj_newb | brehaut , Raynes : noted, thanks. |
| 01:40 | vreskcin | seancorfield: because it would be neat. Imagine being able to go to any given site and open a repl in it. have access to the running javascript through cljs |
| 01:40 | brehaut | clj_newb: actually. i think i lied about the object array. |
| 01:40 | brehaut | clj_newb: thats a related but different issue |
| 01:40 | clj_newb | brehaut: from testing; it seems like I have to specify the # of args |
| 01:40 | emezeske | Raynes: Yeah, clojure.string is really piddly |
| 01:40 | clj_newb | i.e. if my defrecord says invoke [this a]; I can't call it with 5 args |
| 01:40 | clj_newb | however; this does not bother me; I accept it |
| 01:40 | Raynes | emezeske: What isn't there that you wish were there? |
| 01:40 | brehaut | clj_newb: off course: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/IFn.java |
| 01:41 | emezeske | Raynes: Compare your truncate solution with Python, e.g. "abcdef"[:3] |
| 01:41 | Raynes | That's a syntactical trick. |
| 01:41 | emezeske | Raynes: For instance, all of the trim functions don't accept a "what to trim" arg |
| 01:41 | clj_newb | brehaut: hmm; nice ot see they can go up to 20 args |
| 01:41 | emezeske | Raynes: Most string libs accept that |
| 01:42 | Raynes | Also, I understand my solution -- the python one makes no sense to me. |
| 01:42 | emezeske | Raynes: Sure, a very very convenient trick. |
| 01:42 | emezeske | Raynes: Well, then, that's because you don't know Python :P |
| 01:42 | Raynes | Convenient and disgusting. |
| 01:42 | clj_newb | here's the notion |
| 01:42 | Raynes | I was writing Python 4 days ago. |
| 01:42 | clj_newb | if you like syntax, go perl |
| 01:42 | Raynes | I actually used that syntax, but I don't know what the colon means. |
| 01:42 | clj_newb | clojure, iirc, != perl :-) |
| 01:42 | brehaut | ,(subs "abcdef" 3) |
| 01:42 | emezeske | Regardless of using a syntactical trick, things like that come up often enough that one would think the main string manip library would help |
| 01:42 | clojurebot | "def" |
| 01:43 | Raynes | It looks to me like that syntax is overloaded to do a thousand different things. |
| 01:43 | seancorfield | ,(doc subs) |
| 01:43 | clojurebot | "([s start] [s start end]); Returns the substring of s beginning at start inclusive, and ending at end (defaults to length of string), exclusive." |
| 01:43 | emezeske | ,(subs "abcdef" 0 3) |
| 01:43 | clojurebot | "abc" |
| 01:43 | seancorfield | beat me to it :) |
| 01:43 | emezeske | There we go! thank you brehaut, seancorfield |
| 01:44 | seancorfield | ,(defn truncate [s n] (subs s 0 n)) |
| 01:44 | clojurebot | #<Exception java.lang.Exception: SANBOX DENIED> |
| 01:44 | emezeske | I'm glad there's a non-ridiculous way to do it |
| 01:44 | brehaut | (.substring "abcdef" 0 3) |
| 01:44 | seancorfield | SANBOX? |
| 01:44 | Raynes | I don't see how my example was ridiculus. |
| 01:44 | brehaut | thats pretty nonrediculous |
| 01:45 | Raynes | Strings are seqable -- using seq functions with them is perfectly acceptable. |
| 01:45 | emezeske | Acceptable != fun |
| 01:45 | seancorfield | ,(let [truncate #(subs %1 0 %2)] (truncate "some string" 4)) |
| 01:45 | clojurebot | "some" |
| 01:46 | emezeske | I've come to expect a certain set of basic string operations that are available in every language ever |
| 01:46 | emezeske | Thankfully, clojure does have "subs", which is one of them |
| 01:46 | Raynes | Actually, Java has subs. |
| 01:46 | Raynes | subs is just a wrapper. |
| 01:46 | seancorfield | and there's always the underlying Java String stuff |
| 01:46 | brehaut | and clojure.string |
| 01:46 | emezeske | Sure, sure, but (subs ...) is prettier than (.substring) |
| 01:47 | brehaut | personally im willing to loose a few 'simple' string ops if i can have nice parser combinators |
| 01:47 | emezeske | I care 0% about how it's implemented |
| 01:47 | emezeske | I just don't want to have to implement it myself if it already exists. |
| 01:47 | brehaut | s/loose/lose/ |
| 01:47 | seancorfield | java exists *zen* :) |
| 01:47 | Raynes | emezeske: Anyways, Java Strings are immutable so anything http://docs.oracle.com/javase/6/docs/api/java/lang/String.html is fine to use from Clojure. |
| 01:48 | Raynes | If you don't mind typing a dot. |
| 01:48 | Raynes | Or two. :) |
| 01:48 | brehaut | Raynes: my keyboard has a tax on dot characters |
| 01:48 | brehaut | thats why i love semicolons and lisp so much |
| 01:48 | seancorfield | semicolons? *spit* :) |
| 01:49 | brehaut | seancorfield: semicolons for english ;) |
| 01:49 | gf3 | bah, is it possible to use try/catch with loop/recur where recur is in the tail position? |
| 01:49 | gf3 | sans-finally |
| 01:50 | seancorfield | you can't recur across try/catch, eh? |
| 01:51 | gf3 | across? |
| 01:52 | seancorfield | right, you can't have recur inside try/catch in 1.3.0 |
| 01:52 | seancorfield | the ticket that changed the behavior explains why... i read it once and went "oh yeah that makes sense" but can't remember now |
| 01:53 | gf3 | you don't have a link, do you? |
| 01:53 | gf3 | (btw, thx seancorfield) |
| 01:56 | seancorfield | i'll see if i can find it |
| 01:58 | seancorfield | this is one ticket http://dev.clojure.org/jira/browse/CLJ-31 (but it's not very informative) |
| 02:00 | seancorfield | so there may have been a mailing list discussion around it too... |
| 02:01 | gf3 | seancorfield: thank you |
| 02:06 | gf3 | seancorfield: do you know if there is a idiomatic solution to this issue? I'm sure it's quite common when interfacing with Java |
| 02:19 | gf3 | or anyone? ↑ |
| 02:19 | seancorfield | the try/catch issue? i'm not even quite sure where it comes up... |
| 02:20 | amalloy | gf3: what is your broken code shaped like? |
| 02:21 | gf3 | amalloy: https://gist.github.com/c3e80e85e2072962c8d6 |
| 02:22 | gf3 | amalloy: reading a stream until the EOF exception is thrown |
| 02:23 | amalloy | gfredericks: well (a), you can't do that because recur is supposed to be a simple "jump" instruction, but here in order to recur you have to teardown the try/catch context |
| 02:23 | seancorfield | so only the (read r) can throw an exception? |
| 02:24 | amalloy | but (b) this is really better as a lazy-seq anyway |
| 02:24 | gf3 | seancorfield |
| 02:24 | gf3 | yes |
| 02:24 | amalloy | oh, and (c) you should be asking read to not throw an exception, then you don't have this issue at all |
| 02:24 | seancorfield | also your initial (read r) could throw an exception |
| 02:25 | gf3 | amalloy: ahh perhaps I have missed it, is there a way to convert a stream to a lazy seq? |
| 02:25 | gf3 | seancorfield: true enough |
| 02:25 | amalloy | well, yes, but my point is instead of loop/recur you would probably be happier using lazyseq |
| 02:26 | amalloy | &(doc read) |
| 02:26 | lazybot | ⇒ "([] [stream] [stream eof-error? eof-value] [stream eof-error? eof-value recursive?]); Reads the next object from stream, which must be an instance of java.io.PushbackReader or some derivee. stream defaults to the current value of *in* ." |
| 02:27 | amalloy | set eof-error to false, and just wait for the sentinel value |
| 02:30 | gf3 | amalloy: awesome, thank you |
| 02:30 | amalloy | that said, this has been implemented a lot of times already |
| 02:31 | gf3 | amalloy: is there something better I should be using/doing? |
| 02:31 | amalloy | well, i thought it was in clojail so i was going to point you there, but apparently not |
| 02:32 | gf3 | amalloy: I'm actually using this with clojail |
| 02:32 | amalloy | right, but you could use clojail's impl, either by depending or copy/paste |
| 02:33 | amalloy | here's one of the implementations i've written: https://gist.github.com/1638602 |
| 02:35 | gf3 | thank you |
| 02:40 | vreskcin | http://sexp.posterous.com/another-clojure-noir-site-on-heroku |
| 02:51 | tavis` | how do I get lazybot to give me a list of its available commands? |
| 02:53 | seancorfield | mostly it just evaluates clojure code... |
| 02:53 | seancorfield | tavis`: i guess you could go look at the source on github? |
| 02:54 | tavis` | ok, thanks. I'm doing that now already. |
| 02:54 | seancorfield | g'nite |
| 02:55 | amalloy | the wiki has a not-very-complete list of commands, but if you search the source for defplugin you'll at least see which ones are available (they're not all enabled on the lazybot in here) |
| 02:56 | tavis` | ah, no wonder I couldn't find the right docs - mistook it for clojurebot |
| 03:38 | Blkt | good morning everyone |
| 03:39 | gf3 | good morning |
| 03:39 | guntha | hello |
| 03:42 | gensym | moinsen |
| 03:43 | mduerksen | moin :) |
| 04:12 | tufflax | Hm, what's the reason that :test is in the metadata of a fn, but pre and postconditions are not? Aren't those the same kind of thing? |
| 04:39 | emezeske | Anyone else having issues pushing jars to clojars? |
| 04:39 | clgv | emezeske: in general or via the lein plugin? |
| 04:40 | emezeske | clgv: in general |
| 04:40 | emezeske | clgv: my scp command seems to be hanging |
| 04:41 | clgv | emezeske: you got you public ssh-key added overthere? |
| 04:41 | emezeske | clgv: yeah, I have pushed a number of jars before (including just about an hour ago) |
| 04:42 | clgv | emezeske: oh ok. maybe temporary service failure then. I got nothing to try it here. |
| 04:42 | emezeske | clgv: thanks anyway! |
| 04:42 | emezeske | clgv: yeah, I ran scp -vvv and it's authenticating, but the command it's exec'ing is hanging |
| 04:42 | emezeske | does appear to be a clojars problem |
| 04:43 | clgv | I see your clojurescript stuff was the last. |
| 04:44 | emezeske | hah, maybe I broke it ^_^ |
| 04:49 | clgv | bad boy ;) |
| 04:50 | lpetit | hi there |
| 04:52 | clgv | lpetit: hey. hows your favorite project coming along? |
| 04:53 | lpetit | hey. Quite good. I see 2012 being a veery good year for CCW develoment |
| 04:54 | lpetit | clgv: Sorry, but I don't remember who's behind clgv nickname? |
| 04:54 | clgv | thats good to hear. |
| 04:54 | clgv | lpetit: no one famous ;) |
| 04:54 | lpetit | clgv: c'mon ! |
| 04:55 | clgv | just a ccw user that took the chance to ask you how ccw is getting along |
| 04:56 | lpetit | clgv: thanks for asking, then |
| 04:57 | clgv | lpetit: the funny thing is that I checked on ccw status minutes before you showed up here. |
| 04:57 | lpetit | clgv: a 0.6.0 beta will be released today |
| 04:57 | clgv | lpetit: oh nice. |
| 04:58 | clgv | lpetit: what are the big changes? |
| 04:58 | clgv | s/big/mayor/ |
| 04:59 | lpetit | clgv: there http://code.google.com/p/counterclockwise/issues/list?q=label:next |
| 05:01 | clgv | lpetit: ah mostly bugfixes. and the one cemerick submitted for me :) |
| 05:02 | lpetit | clgv: bug fixes, use of Clojure 1.3 internally, steps towards simplification of ccw hacking/building, smart paste in string literals when in editor strict mode (paste a bunch of XML content, get the double quotes automatically escaped), automatically send repl content if cursor at the end of the repl input editor, *and* its content is well formed clojure |
| 05:04 | clgv | lpetit: I would love to be able to use the repl view standalone in my project (keyword: gui repl) some time. as far as cemerick told me thats not easily possible right now |
| 05:04 | lpetit | clgv: ? |
| 05:06 | clgv | lpetit: I mean including it for usage in my running application outside of eclipse. last time I mentioned that to cemerick I was told that could be difficult to modularity issues. is that wrong? |
| 05:06 | clgv | *due to |
| 05:08 | lpetit | clgv: for one, your app should be using the SWT graphic library. And also, the REPL view in its current form is indeed very tied to the Eclipse framework: ViewParts, etc. |
| 05:08 | lpetit | clgv: so Chas was right. |
| 05:09 | clgv | lpetit: ok. using SWT was obvious. so I would need to build an Eclipse RCP project to be able to use it? |
| 05:10 | lpetit | clgv: to say the least |
| 05:11 | clgv | lpetit: ok, so we can agree on it's still not easy? ;) |
| 05:11 | lpetit | clgv: yes, as I said ^^^, Chas was right, and it's not easy right now |
| 05:11 | lpetit | clgv: :/ |
| 05:13 | clgv | lpetit: ah one thing about the repl view history - I can step through it backwards - but is it searchable with prefix-strings like the linux bash with page-up/-down= |
| 05:13 | lpetit | clgv: not yet, nope |
| 05:14 | lpetit | clgv: what was the bug you reported to Chas, you're waiting for correction of ? |
| 05:15 | clgv | lpetit: that one "Unwanted linebreak inserted when typing ' in default editing mode" which seems included in 0.6.0 |
| 05:15 | lpetit | clgv: yeah, this was is very annoying. |
| 05:19 | clgv | lpetit: I love the syntax highlighting in repl view. I always miss that when running my jars remotely within rlwrap... |
| 05:20 | lpetit | clgv: you know you can have a repl view point to any server on any port. (and with the help of some ssh tunneling, not compromising security altogether) ? |
| 05:20 | lpetit | clgv: of course, you'll need the nrepl server started somehow in your remote jvm |
| 05:21 | clgv | lpetit: humm, is there some information on the ssh tunneling part? |
| 05:22 | lpetit | clgv: that part is really just plain old ssh tunneling, nothing specific to us. I must admit I don't have to use it so I don't know the details, but my bet is it's dead easy once you know the ssh command options |
| 05:22 | clgv | lpetit: ah ok. so gotta check the ssh docs. thanks for that hint |
| 05:23 | lpetit | clgv: basically, you use ssh on a linux/mac terminal, or the equivalent with putty on Windows, to create the tunnel, and then instead of trying to connect to the remote server, you connect to the specific port on localhost which will be bound to the remote port on the server |
| 05:25 | lpetit | clgv: plus, the beta I'll soon release (when I stop chatting ;) ) will include nrepl hyperlinks: you just put text like nrepl://127.0.0.1:9032 (or whatever) in your clojure source file, and then when hovering onto it with the Ctrl/Cmd key pressed, you're a click away from having a REPL View opening and trying to connect via this url |
| 05:26 | clgv | lpetit: cool |
| 05:26 | raek | ssh -L 1234:some.host:4568 will cause the remote side to connect to some.host:4568 whenever someone connects to localhost:1234 on the local side (and the data will be tunneled) |
| 05:26 | clgv | raek: thx. gotta paste that in my notes. |
| 05:27 | raek | sorry, "ssh -L 1234:some.host:4568 remote.host" |
| 05:27 | lpetit | raek: thanks |
| 05:36 | clj_newb | I realize this question is off topic; but I'm asking it since I respect people here's opinions: has anyone found a decent GTD style app for the ipad? I want something simple (i.e. like vim, clojure) rather than feature-full, like omnifocus/things |
| 06:11 | wiseen | is there a nicer way to write (or (instance? Foo x) (instance? Bar x) (instance? Blah x)) ? |
| 06:17 | lucian | wilfredh: i think (any (partial instance? x) [Foo Bar Blah]), but i'm not sure |
| 06:19 | wiseen | lucian, #(instance? % x) instead of (partial instance x) ? cool tnx. |
| 06:19 | lucian | or that. i'm not even sure clojure has any, really :) |
| 06:20 | lpetit | ,(let [x "yo"] (some #(instance? % x) [Integer String Long]) |
| 06:21 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading> |
| 06:21 | lpetit | ,(let [x "yo"] (some #(instance? % x) [Integer String Long])) |
| 06:21 | clojurebot | true |
| 06:21 | lpetit | ,(let [x "yo"] (some #(instance? % x) [Integer Long])) |
| 06:21 | clojurebot | nil |
| 06:21 | lucian | lpetit: ah, so it's called some |
| 06:22 | lpetit | be aware that some returns the result of the predicate, not the element for which the predicate worked |
| 06:22 | lpetit | if you want the former, you'll need (first (filter ...)) |
| 06:23 | LeNsTR | Hello guys! Can you explain me why this code does work without stack overflow? http://pastie.org/3212832 |
| 06:28 | lucian | LeNsTR: because it's lazy, pretty much |
| 06:28 | wiseen | LeNsTR, because it's not recursive or lazy-seq ? |
| 06:29 | wiseen | LeNsTR, replace line 4 with (cons a (lazy-seq (fib-seq b (+' a b)))))) |
| 06:30 | wiseen | *tail recursive |
| 06:31 | LeNsTR | I'm bit confused, because function calls yourself without 'recur' |
| 06:32 | lucian | LeNsTR: with lazy-cons, fib-seq isn't actually recursive |
| 06:32 | lucian | if you think about it, when you ask for 2, it gets called twice |
| 06:32 | lucian | it doesn't keep recurring |
| 06:33 | lucian | so there aren't any nested calls |
| 06:34 | wiseen | it uses a closure instead of the stack ? |
| 06:39 | LeNsTR | ah! lazy-seq calling internal clojure.lang.LazySeq which takes the body |
| 06:39 | LeNsTR | and working without tail calls |
| 06:41 | LeNsTR | thank you for the explanation |
| 06:44 | LeNsTR | s/tail calls/recursion |
| 07:05 | lpetit | clgv: still there ? |
| 07:15 | phao | Hey, does clojure support continuations? |
| 07:18 | lpetit | phao: no |
| 07:27 | clgv | lpetit: now again |
| 07:28 | lpetit | clgv: would you have the opportunity to beta test the future version 0.6.0 ? In that case I can send you the update site for the betas versions I've just created |
| 07:30 | clgv | lpetit: I can have a look at it in my free time: tonight or this weekend. at work it's "stable only" ;) |
| 07:31 | lpetit | clgv: okay, so no hurry, I'll make an announce on the mailing list in a few hours |
| 08:23 | lpetit | http://groups.google.com/group/clojure/browse_thread/thread/8cb9162117c62621 |
| 08:23 | lpetit | Awesome! @thinkrelevance sponsorship for #Counterclockwise development! Many thx to @muness , @redinger et al. #Clojure |
| 08:24 | clgv | lpetit: wow. great! that'll speed up development I guess =) |
| 08:24 | Licenser | lpetit :D :D :D |
| 08:24 | lpetit | Hope so, that the whole point ! :-D |
| 08:51 | chouser | lpetit: amazing! congrats! |
| 08:52 | lpetit | chouser: thanks |
| 08:59 | cemerick | lpetit: same, congratulations :-) |
| 08:59 | lpetit | cemerick: :-D |
| 09:05 | lpetit | Beta version of Counterclockwise sent in the wild: http://ccw.cgrand.net/updatesite-betas/ |
| 10:41 | Borkdude | Is there something like arrow up to get the last expression in CounterClockWise? |
| 10:45 | TimMc | Try M-p (maybe it will work) |
| 10:45 | TimMc | Borkdude: If all else fails, check the keybindings in Eclipse's preferences |
| 10:47 | cemerick | Borkdude: Ctrl- or Alt-up, usually |
| 10:47 | cemerick | *unless* you're on OS X and use spaces, in which case spaces is eating that keystroke; the workaround is to either change the keybindings for spaces, or the keybinding for previous REPL command. |
| 10:47 | Borkdude | ah Cmd-up on my Mac, tnx :) |
| 11:15 | Borkdude | What is the way to create an interactive application in Eclipse+CCW ? read / readline doesn't work, maybe create a JFrame + txtfield? |
| 11:27 | cemerick | Borkdude: what sort of inputs are you expecting? |
| 11:27 | Borkdude | cemerick: I'm just brainstorming about an exercise I can let students do, like programming tic tac toe for exaple |
| 11:27 | Borkdude | example |
| 11:28 | cemerick | JOptionPane/showInputDialog is probably as low-ceremony as you can get |
| 11:30 | Borkdude | cemerick: ah, that is usable |
| 11:30 | Borkdude | :-) |
| 11:31 | Borkdude | I can skip the entire GUI this way |
| 11:37 | Borkdude | What is the "best" way to concat two vectors? Using into or concat? |
| 11:38 | llasram | Depends on why you want to concatenate them... |
| 11:40 | TimMc | Borkdude: Do you want a lazy seq or a vector of the first type as your result? |
| 11:41 | Borkdude | TimMc: I actually didn't think about it. I am putting together some slides on clojure datastructues like lists and vectors and how to manipulate them |
| 11:44 | Null-A | Is there something I can call that will return java.lang.Integer? (class (int 3)) ? |
| 11:44 | Null-A | instead of java.lang.Long |
| 11:44 | Null-A | I tried .getClass |
| 11:44 | gfredericks | Null-A: does the symbol java.lang.Integer not work for you? |
| 11:44 | Borkdude | ,(type 1) |
| 11:44 | clojurebot | java.lang.Long |
| 11:44 | Borkdude | hmm |
| 11:44 | Null-A | ,(type (int 1)) |
| 11:44 | clojurebot | java.lang.Long |
| 11:44 | TimMc | Null-A: ##(class (Integer. 5)) |
| 11:44 | lazybot | ⇒ java.lang.Integer |
| 11:45 | Null-A | ah I see I need to box it |
| 11:45 | Borkdude | is this different in clojure 1.3? in my 1.2 repl I get an Integer |
| 11:45 | Null-A | gfredericks: it's a convenience thing, my code will be less verbose ,i'm writing a DSL |
| 11:45 | Null-A | yes Borkdude |
| 11:45 | TimMc | Borkdude: Yeah. |
| 11:45 | TimMc | It's one of the breaking changes. |
| 11:45 | Null-A | thanks TimMc |
| 11:45 | tufflax | What's the reason that :test is in the metadata of a fn, but pre and postconditions are not? Aren't those the same kind of thing? |
| 11:46 | TimMc | tufflax: :pre and :post are actually part of the function proper -- they affect how it runs |
| 11:46 | tufflax | oh |
| 11:46 | tufflax | i see |
| 11:48 | tufflax | thanks |
| 12:49 | technomancy | TimMc: that doesn't preclude using metadata though |
| 12:50 | TimMc | hrm? |
| 12:51 | technomancy | I mean the function could check its own metadata and run :pre/:post from there |
| 12:51 | gfredericks | is there some kind of guidelines/heuristics about what metadata is for? I know for data structures it's supposed to not effect the equality semantics, but that doesn't really apply to functions does it? |
| 12:53 | TimMc | technomancy: :pre and :post don't work as literals -- they need some macro assistance |
| 12:53 | TimMc | % and all |
| 12:53 | technomancy | oh yeah; that makes sense. |
| 12:54 | icey | Anyone here use elastic beanstalk as their production environment? Or evaluated it and disliked it strongly for some reason? |
| 13:19 | lpetit | technomancy: starting next thursday, I'll start work on lein support in CCW. At first, only support for automatically updating project's class path settings from project.clj. As seen with Chas, I intend to use leiningen-core to do so. |
| 13:19 | lpetit | technomancy: just to keep you informed. |
| 13:20 | technomancy | lpetit: great; I will definitely be interested in feedback on how that works out for you |
| 13:20 | lpetit | technomancy: I for sure will give you feedback as I go |
| 13:21 | technomancy | that will only give compatibility for lein 2.x though, so I guess we better press on and have a usable release soon. =) |
| 13:22 | _carlos_ | hi! |
| 13:23 | lpetit | technomancy: yeah. Anyway there's no support for lein1 in CCW, so that is not an issue. |
| 13:25 | lpetit | why do I always think about ANTLR when LeNsTR enters/quits the room ? :) |
| 13:25 | technomancy | there will be a large level of compatibility between 1.x and 2.x anyway; mostly it's :dev-dependencies getting ignored that people will notice |
| 13:27 | _carlos_ | it is beyond me why removing some parentheses from: "(import '(java.util Calendar TimeZone)) (. (. (Calendar/getInstance) (getTimeZone)) (getDisplayName))" is not possible |
| 13:28 | lpetit | technomancy: I'll use leiningen-core only for CCW's needs, independently of what leon version the user is expecting. |
| 13:28 | antares_ | technomancy: :dev-dependencies will be completely ignored? or only in some cases (like dev dependencies of dependencies) |
| 13:28 | lpetit | Must go, see you |
| 13:29 | LeNsTR | lpetit: sure, why? :D |
| 13:29 | _carlos_ | I would take parentheses from: (Calendar/getInstance), (getTimeZone), and (getDisplayName) . it seems that, if I use the form at the top level, I can remove them though |
| 13:29 | Bronsa | ,(.. (java.util.Calendar/getInstance) getTimeZone getDisplayName) |
| 13:29 | clojurebot | "Pacific Standard Time" |
| 13:30 | Bronsa | or even |
| 13:30 | Bronsa | ,(.. java.util.Calendar getInstance getTimeZone getDisplayName) |
| 13:30 | clojurebot | "Pacific Standard Time" |
| 13:31 | _carlos_ | Bronsa: ha! I was going to get to the .. part in the next page. anyways, it still doesn't anwser the question, why is it calling from inside other macros change the parentheses requirements? |
| 13:32 | TimMc | Oh man, I totally forgot about .. |
| 13:34 | Bronsa | ,(. (. (java.util.Calendar/getInstance) getTimeZone) getDisplayName) |
| 13:34 | clojurebot | "Pacific Standard Time" |
| 13:34 | Bronsa | you can avoid parenthesis here too |
| 13:34 | _carlos_ | Bronsa: please forget this issue I am still having. I think maybe I misunderstood something. I will investigate further |
| 13:35 | Bronsa | np :) |
| 13:35 | technomancy | .. is deprecated in favour of -> |
| 13:36 | technomancy | antares_: :dev-dependencies will be deprecated in favour of profiles, which are much more flexible |
| 13:36 | antares_ | technomancy: ok |
| 13:37 | technomancy | it's explained under "Profiles" but I should probably add a more concrete example involving dev-deps: https://github.com/technomancy/leiningen/blob/master/README.md |
| 13:39 | _carlos_ | technomancy: yeah! good idea -> "->" |
| 13:46 | cemerick | technomancy: Just to clarify re: lein-core, it should be v1 and v2 capable as long as we're not attempting to run any tasks right? |
| 13:46 | cemerick | I think all we need for a first cut is :deps and :repos. |
| 13:46 | technomancy | cemerick: it will read :deps and :repos from project.clj files; sure. |
| 13:46 | cemerick | (really not much more than (read-string (slurp "project.clj")) |
| 13:46 | cemerick | ok |
| 13:46 | technomancy | people just might expect it to honor :dev-deps too |
| 13:47 | cemerick | well, I (and I think lpetit as well) am happy enough to let ccw drive lein2 adoption ;-) |
| 13:47 | technomancy | works for me =) |
| 13:47 | technomancy | :plugins is backported to lein 1.7.0 anyway |
| 13:51 | _carlos_ | technomancy: wouldn't ".." be deprecated in favor of "->>" instead of "->"? I was just building the previous using that macro: http://pastebin.com/DGZ48PEQ |
| 13:52 | dnolen | _carlos_: ->> is for operating on sequences |
| 13:52 | TimMc | what |
| 13:52 | TimMc | &(doc ->>) |
| 13:52 | lazybot | ⇒ "Macro ([x form] [x form & more]); Threads the expr through the forms. Inserts x as the last item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the last item in second form, etc." |
| 13:52 | tmciver | I think either would work in this case. |
| 13:53 | TimMc | _carlos_: If you're dealing with a bunch of nllary Java methods, it doesn't matter which you use. |
| 13:53 | TimMc | *nullary |
| 13:53 | tmciver | because the second and last form are one in the same here. |
| 13:54 | llasram | _carlos_: The difference is that `->' threads the forms as the first argument to each subsequent form, while `->>' threads as the last. So interop foo usually requires `->' and sequence functions `->>' |
| 13:54 | _carlos_ | TimMc: "nullary"? what does it mean such a fashionable term? |
| 13:56 | TimMc | _carlos_: nullary = 0 args, unary = 1 arg, binary = 2 args... |
| 13:56 | _carlos_ | thanks dnolen, llasram, TimMc |
| 13:57 | TimMc | -> is specifically used in interop when you keep calling methods on the return value of the previous calls |
| 13:57 | joegallo | isn't .. better for that? |
| 13:58 | TimMc | joegallo: -> is the replacement for .., apparently |
| 13:58 | TimMc | &(doc ..) |
| 13:58 | lazybot | ⇒ "Macro ([x form] [x form & more]); form => fieldName-symbol or (instanceMethodName-symbol args*) Expands into a member access (.) of the first member on the first argument, followed by the next member on the result, etc. For instance: (.. System (getProperties) (get ... https://refheap.com/paste/356 |
| 13:58 | joegallo | huh, today-i-learned |
| 13:58 | _carlos_ | TimMc: so I guess "->" is more generic since it applies both for nullary and non-nullary methods in interop, making it therefore more idiomatic |
| 13:59 | TimMc | _carlos_: .. can be used for n-ary methods |
| 13:59 | technomancy | -> is preferred because it works for functions as well as interop |
| 13:59 | TimMc | -> applies to both methods and function... |
| 13:59 | TimMc | yeah, sniped |
| 14:01 | cemerick | .. remains handy for static method calls |
| 14:02 | TimMc | How so? |
| 14:04 | TimMc | &(-> 10 Integer. (Integer/toString 16)) |
| 14:04 | lazybot | ⇒ "a" |
| 14:04 | technomancy | http://lispcabinet.sourceforge.net/ o_O |
| 14:05 | TimMc | sweet |
| 14:05 | TimMc | Someone try it out. |
| 14:05 | technomancy | is this a reasonable thing to point windows users to? |
| 14:06 | technomancy | including a bunch of CLs and racket seems weird |
| 14:07 | lrenn | best way to remove the first, and only the first occurance of something in a sec? |
| 14:09 | technomancy | plus now we have yet another clojurescript redistributor. |
| 14:11 | llasram | lrenn: Not sure that's a super-common case. You can probably work something up using `split-with', but you're probably better off doing a recursive function with `lazy-seq' (unless `split-with' is actually what you need) |
| 14:11 | llasram | technomancy: Oh, who? |
| 14:12 | technomancy | llasram: this lisp cabinet thing appears to redistribute clojurescript |
| 14:12 | llasram | Oh, nm. Didn't noticed it was included in "Lisp Cabinet" |
| 14:12 | llasram | Context! |
| 14:12 | raek | lrenn: one way is to roll your own lazy seq: (defn without-first [item coll] (lazy-seq (when (seq coll) (if (= (first coll) item) (rest coll) (cons item (without-first item (rest coll))))) |
| 14:12 | lrenn | llasram: yeah, that's what i was doing, but seemed...wrong. Simple case really, person has a hand of cards, message comes in to play one, now i need to remove it from their hand. |
| 14:13 | technomancy | a guy on the leiningen mailing list apparently finds it very useful |
| 14:13 | technomancy | except for the fact that the bundled lein wasn't honoring his swank version |
| 14:13 | llasram | I should subscribe to that newsletter... |
| 14:13 | raek | lrenn: if there can be no duplicates, consider using a set instead |
| 14:13 | lrenn | raek: there can be duplicates :) |
| 14:14 | joegallo | ,(let [[a b] (split-with (partial not= 5) (range 0 50))] (concat a (rest b))) |
| 14:14 | clojurebot | (0 1 2 3 4 ...) |
| 14:14 | joegallo | (let [[a b] (split-with (partial not= 3) (range 0 5))] (concat a (rest b))) |
| 14:15 | joegallo | ,(let [[a b] (split-with (partial not= 3) (range 0 5))] (concat a (rest b))) |
| 14:15 | clojurebot | (0 1 2 4) |
| 14:15 | joegallo | still seems gross, though |
| 14:15 | technomancy | (let [found? (atom false)] (remove #(or @found? (and (= % thingy) (swap! found? not))) my-seq)) |
| 14:15 | technomancy | oh, that's not any shorter; boo |
| 14:15 | llasram | And walks the whole seq. And uses mutable state! Heretic! |
| 14:16 | TimMc | Eh, the atom doesn't escape. |
| 14:16 | llasram | Every time you use an atom, rhickey kills a kitten |
| 14:17 | TimMc | What's wrong with atoms? |
| 14:17 | technomancy | if a tree falls in the forest, &c |
| 14:17 | llasram | Nothing -- I'm just punchy :-) |
| 14:17 | amalloy | i prefer to think that happens when you could use an atom but use a ref instead because you're too lazy to work it all into a swap! |
| 14:18 | amalloy | &(let [[xs [y & ys]] (split-with (complement #{3}) (range 0 5))] `(~@xs ~@ys)) |
| 14:18 | lazybot | ⇒ (0 1 2 4) |
| 14:18 | joegallo | ooh, nice work with the y & ys |
| 14:18 | joegallo | clever |
| 14:19 | technomancy | amalloy has lots of practice golfing from 4clojure =) |
| 14:19 | amalloy | well, i don't think using complement made it shorter |
| 14:19 | technomancy | (comp not x) is shorter by chars but not tokens |
| 14:34 | Vinzent | Hello. I wonder why when-let can take only one binding\test pair. It cause me to write nested when-let\let |
| 14:35 | amalloy | basically: it's not obvious what additional bindings would do. test them all, or not? either is reasonable, but either could lead to some confusion if you expect the other |
| 14:36 | amalloy | and if it bothers you, it takes just two minutes to write your own when-let that behaves the way you want |
| 14:36 | llasram | Vinzent: If you want something like a flattened version of nesting multiple when-lets, check out maybe-m in algo.monads |
| 14:38 | Vinzent | hm, I thought it's natural to expect that all bindings would be tested (lazily, with and). |
| 14:38 | Vinzent | llasram, thanks, I'll check it |
| 14:39 | Vinzent | amalloy, I'm afraid my own when-let version would just make more confusion in future |
| 14:40 | amalloy | Vinzent: https://gist.github.com/1642108, for what it's worth |
| 14:42 | llasram | Oooh. I like the use of `reduce' instead of making the macro explicitly recursive |
| 14:42 | amalloy | llasram: i have to imagine the clojure.core versions would have done that, except that reduce isn't available when they're defined |
| 14:44 | llasram | Seems plausible. Def has some nice properties |
| 14:45 | Vinzent | the other way is https://gist.github.com/1642131 |
| 14:48 | Vinzent | but anyway, I don't think it's a good idea to write your own generic macros, cause it leads to many different, incompatible "helper" libs written by nearly every programmer |
| 14:49 | amalloy | Vinzent: your macro actually is wrong in a number of ways |
| 14:49 | llasram | Vinzent: 100% disagreed. As long as the language has good namespace support, what's the problem? |
| 14:50 | Vinzent | so e.g. if someone wants to contribute to your open source project, he have to learn your helper lib first (although, maybe it's not a big deal in this particular case, cause "when-lets" is pretty self-explaining) |
| 14:51 | Vinzent | amalloy, can you please explain what's exactly is wrong? |
| 14:51 | Chousuke | if you do when-lets often then it makes sense to provide one |
| 14:51 | amalloy | Vinzent: would he rather slog through a five-line macro and three one-line use-cases, or three five-line use-cases? |
| 14:51 | amalloy | eg, try (when-lets [x nil, y (.length x)] y) |
| 14:51 | amalloy | or (when-lets [[x & xs] (seq coll), y (count xs)] y) |
| 14:53 | Vinzent | amalloy, ah, right, I haven't thought about that not only body, but bindings too must not be evaluated when something is falsey (in my case inner let was just for some helper function) |
| 14:54 | magnars | Looking for idiomatic clojure: I would like to replace parts of a string, calculated from the match. Let me try to explain: (re-replace "123" #"\d" #(+ 1 %)) => "234" ... I'm rather new to clojure, and I don't want to brute force out a solution. What would be an idiomatic way of attacking this problem? |
| 14:54 | amalloy | my point, and i'm sorta tired of making it so this is the last you'll hear from me, is that if you choose not to create abstractions because other people might not write them, you're stuck writing to the lowest basic level that the language comes with. the same argument applies to functions as well as macros, but you don't hear someone saying "oh, i won't write a function for this; i'll just write its body all over the place". the whole point |
| 14:54 | Vinzent | amalloy, well, this three five-line use-cases would be clear and perfectly readable, aren't they? |
| 14:55 | hiredman | amalloy: who are you talking to? |
| 14:55 | amalloy | hiredman: Vinzent mostly |
| 14:56 | hiredman | ah |
| 14:56 | emezeske | Vinzent: so with the macro, it'd be 8 lines total, and without, 15 lines total? |
| 14:56 | emezeske | Vinzent: I believe several studies have shown that bugs are extremely well correlated with number of lines of code |
| 14:57 | emezeske | Vinzent: like, regardless of language, tools, etc, less lines of code just means less bugs in general |
| 14:58 | Vinzent | amalloy, I think that you should not create abstraction only to reduce number of lines e.g. from 5 to 3. Sometimes it's better to have a little longer code, but the one which consist of familiar, standard constructions |
| 14:58 | amalloy | right. every time you write those five lines you have to get them right. and the person reading it has to make sure all the details match up without (for example) off-by-one errors. that's one reason sequence operations are much less error-prone than the java: for (i = 0; i < foo.size(); i++) {doStuff(foo.get(i));} |
| 14:59 | Vinzent | emezeske, I think what actually matters is not number of lines, but number of concepts, complexity of the code, etc |
| 14:59 | emezeske | Vinzent: yep, but you're wrong. I know it's not intuitive. I'll try to dig up some of the papers. |
| 15:00 | emezeske | Vinzent: I think this blog post points at the paper I'm thinking of: http://blog.vivekhaldar.com/post/10669678292/size-is-the-best-predictor-of-code-quality |
| 15:00 | hiredman | it should ne intuitive to anyone with experience coding |
| 15:00 | sritchie | hey all, is it possible to proxy a protocol, not just an interface? |
| 15:00 | amalloy | sritchie: reify, not proxy |
| 15:00 | hiredman | protocols actually generate an interface of the same name |
| 15:01 | hiredman | but yes, you should prefer reify |
| 15:01 | sritchie | I've got to proxy an existing class, unfortunately |
| 15:01 | hiredman | also there is a definterface |
| 15:01 | hiredman | that looks sort of like defprotocol |
| 15:02 | sritchie | like this: https://gist.github.com/1642241 |
| 15:02 | hiredman | proxy may try and proxy the generated interface for the protocol, which will have mangled names |
| 15:03 | hiredman | so if the above doesn't work try changing the protocol to have java legal names for the methods |
| 15:03 | sritchie | ah, got it |
| 15:04 | magnars | Any pointers at all in trying to get to (re-replace "A1 B2 C3" #"\d" inc) => "A2 B3 C4" ? Any way of getting it nice? Whenever I start out with re-find or re-matcher I end up with some rather unpleasant code. :-/ |
| 15:04 | amalloy | ye cannae inc a character |
| 15:05 | hiredman | well |
| 15:05 | amalloy | (or a string. parse/cast it to an int instead) |
| 15:05 | Vinzent | emezeske, a little silly example: (fn [very-self-explanatory-name] \newline ...) is 2 times more lines than #(...), but it's better in many cases. Or very smart, short and "hacky" function might be worse than longer, but more obvious and simple one. Let me read your link... |
| 15:07 | sritchie | hiredman: this is interesting, it looks like I can't proxy an interface and a protocol together |
| 15:07 | emezeske | Vinzent: I'm not advocating playing code golf all the time. But if a simple abstraction can decrease the total lines, that's a good thing, even if it forces you to use a language feature you are not yet comfortable with. |
| 15:07 | sritchie | Implementing class |
| 15:07 | sritchie | [Thrown class java.lang.IncompatibleClassChangeError] |
| 15:07 | magnars | I'm basically looking for some way of doing (.replace "haystack" "needle" "replacement") but with a function in place of the replacement, that can decide per match what to replace with. Increasing a char is the least of my problems. :-) |
| 15:07 | sritchie | that happens if I list the protocol first; listing the class first compiles fine, but none of the protocol methods work |
| 15:07 | amalloy | magnars: clojure.string/replace does that already. increasing a char is your only problem |
| 15:08 | cemerick | sritchie: gist? |
| 15:08 | hiredman | sritchie: maybe try definterface |
| 15:08 | sritchie | cemerick: sure, one sec |
| 15:08 | magnars | amalloy: that is most excellent, thank you. Just the answer I was looking for. :-) |
| 15:08 | hiredman | or, actually, try the.ns.name.TheProtocol instead of just TheProtocol |
| 15:11 | sritchie | hiredman: that's what I was doing |
| 15:11 | sritchie | I'm definitely misunderstanding something, as I can't seem to come up with a good proxy example: |
| 15:11 | sritchie | (proxy [java.util.HashMap] [] (toString [_] "I am.")) |
| 15:12 | sritchie | is that valid? |
| 15:12 | sritchie | I'm getting Wrong number of args (1) passed to: user$eval1796$fn |
| 15:12 | cemerick | sritchie: proxy method bodies have an implicit `this` |
| 15:12 | cemerick | ,(str (proxy [java.util.HashMap] [] (toString [] "I am."))) |
| 15:12 | clojurebot | "I am." |
| 15:12 | Vinzent | emezeske, come on, I'm comfortable with macros :) I'm just afraid that such approach can lead to something we can see in Common Lisp now: many different external libs providing basic, core functionality (of course it's caused also by a number of reasons unrelated to our discussion), which is very uncomfortable for those who want to learn the language, because they have to learn this libs in addition to the language library |
| 15:13 | cemerick | sritchie: i.e. "old world" style :-) |
| 15:13 | sritchie | aha! unhygienic! |
| 15:13 | emezeske | Vinzent: c'est la lisp :) |
| 15:14 | Vinzent | emezeske, hah, yeah :) but it doesn't have to be as complex as CL is |
| 15:16 | emezeske | Vinzent: maybe text-editor support for macroexpand would help with that? if you really don't want to remember what some crazy macro does, tell your editor to just always show it expanded (maybe in a special color to indicate this) |
| 15:16 | sritchie | cemerick: https://gist.github.com/1642325 |
| 15:16 | sritchie | hiredman: here's the error, where ordering within proxy is important (on Clojure 1.3.0) |
| 15:16 | emezeske | Vinzent: but I do agree with you in the sense that macros can be arbitrarily hard to understand |
| 15:18 | hiredman | sritchie: oh, well that is the same as classes and interfaces, the class has to go before the interfaces |
| 15:18 | hiredman | (and infact user.Connected is the interface generated by your defprotocol) |
| 15:18 | sritchie | ah, okay, got it |
| 15:19 | hiredman | Connected is a var with some special stuff to make it a protocol, but user.Connected bypasses the resolution via *ns* |
| 15:19 | cemerick | sritchie: what hiredman says; class first is in the proxy doc FWIW ;-) |
| 15:20 | amalloy | neither of those is a concrete class though, right? i mean, obviously Object is, but i thought it was a special exception and "treated" like an interface by proxy/reify |
| 15:21 | Vinzent | emezeske, actually I'm talking about this stuff in general, not particulary about macros |
| 15:22 | hiredman | amalloy: for reify, sure |
| 15:22 | cemerick | I never quite grokked that; sorting the classname vector as needed is easy enough. |
| 15:22 | cemerick | ,(sort-by #(.isInterface %) [java.util.List Object]) |
| 15:22 | clojurebot | (java.lang.Object java.util.List) |
| 15:22 | cemerick | anyway |
| 15:23 | hiredman | ,(proxy [clojure.lang.AFn Object] [] (toString [] "Foo")) |
| 15:23 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: java.lang.IncompatibleClassChangeError: Implementing class> |
| 15:23 | hiredman | ,(proxy [clojure.lang.AFn] [] (toString [] "Foo")) |
| 15:23 | clojurebot | #<AFn$0 Foo> |
| 15:24 | sritchie | I can only get everything passing by using camelCase in my defprotocol |
| 15:24 | hiredman | right |
| 15:24 | sritchie | is_connected [Thrown class java.lang.UnsupportedOperationException], for example |
| 15:24 | hiredman | you are not actually using the protocol |
| 15:24 | sritchie | yeah, the interface it generates |
| 15:24 | sritchie | but shouldn't is_connected be legal? |
| 15:25 | Vinzent | emezeske, so the point is that sometimes it's better to write more lines of code and make less abstractions if it makes code more clear and improves readabilty |
| 15:25 | hiredman | hard to say |
| 15:26 | noidi | has anyone else had problems in emacs with winner-mode and slime? |
| 15:26 | Raynes | $google winner-mode emacs |
| 15:27 | lazybot | [EmacsWiki: Winner Mode] http://www.emacswiki.org/emacs/WinnerMode |
| 15:27 | emezeske | Vinzent: we may have to just disagree on that point. :) |
| 15:27 | Raynes | Huh. Never heard of that one. |
| 15:27 | noidi | for some reason winner-undo doesn't properly undo the changes that slime commands (such as slime-compile-and-load-file) make to the window configuration |
| 15:28 | sritchie | hiredman: it'd be interesting to wrap existing interfaces in corresponding protocols |
| 15:28 | noidi | I suspect the problem isn't even in winner-mode but it's a bug in slime |
| 15:28 | sritchie | then you could extend the generated protocol and be effectively extending the interface, right? |
| 15:28 | llasram | Oh, god, SLIME's window-destruction is awful |
| 15:28 | sritchie | (extend-type MyType GeneratedProtocol (mirroredMethod1 …)) |
| 15:28 | noidi | because pressing 'q' in the windows that it pops up doesn't restore the window configuration either |
| 15:28 | sritchie | and all calls to the protocol would pass directly through |
| 15:29 | noidi | llasram, have you experienced this problem as well? |
| 15:29 | Vinzent | emezeske, oh, sure. It may be just my lack of experience. |
| 15:30 | llasram | noidi: Not the particular problem, but just that the SLIME windows don't obey normal emacs temp buffer rules (or use the standard functions). I've got a bunch of advice defined to make them act more like I want |
| 15:30 | llasram | I'll put them in a paste -- might provide a starting place for you to tweak the behavior to the way you want it |
| 15:31 | noidi | llasram, appreciated! |
| 15:31 | hiredman | sritchie: I think you could write a similar macro on top of multimethods pretty easily, I don't see much benefit for it |
| 15:31 | noidi | currently every time I compile a file my window configuration is messed up, essentially forcing me to only use a single window when working on clojure code |
| 15:32 | hiredman | well, I dunno |
| 15:32 | llasram | noidi: https://refheap.com/paste/357 |
| 15:32 | sritchie | hiredman: I've got a database type that I want to be able to extend to a number of Thrift server interfaces |
| 15:32 | hiredman | sritchie: but protocols are not interfaces |
| 15:32 | noidi | llasram, thank you! |
| 15:34 | sritchie | hiredman: you'd have to generate both a wrapping protocol and a function that took an instance of the type you were extending and returned a reified instance of the interface |
| 15:34 | hiredman | sritchie: :( |
| 15:34 | hiredman | you can't reify types, only interfaces and protocols |
| 15:35 | hiredman | and proxy is much slower than reify |
| 15:35 | sritchie | (defn wrapper [some-type] (reify SomeInterface (methodOne [this x] (protocolMethodOne this x)) …)) |
| 15:36 | sritchie | so the wrapper reifies the interface, and all calls pass through to the generated protocol |
| 15:36 | sritchie | which the type has extended |
| 15:36 | hiredman | sritchie: you don't use some-type there |
| 15:36 | sritchie | whoops, sorry: (defn wrapper [some-type] (reify SomeInterface (methodOne [this x] (protocolMethodOne some-type x)) …)) |
| 15:37 | sritchie | here's where this comes into play: https://github.com/nathanmarz/elephantdb/blob/develop/src/clj/elephantdb/keyval/core.clj#L111 |
| 15:37 | hiredman | why not just extend th protocol to some-type? |
| 15:37 | sritchie | this is meant to be a trick for letting the type extend an interface |
| 15:38 | hiredman | but it doesn't |
| 15:38 | hiredman | sometype still doesn't extend the interface |
| 15:38 | hiredman | it just generates a wrapper that does |
| 15:38 | hiredman | which is meh |
| 15:38 | sritchie | sorry, from the beginning -- I'm thinking of a macro that takes an interface and generates a complementary protocol in addition to this wrapper function |
| 15:39 | sritchie | yeah, it still sucks, but check out what I have to do currently |
| 15:39 | sritchie | all the functionality at the bottom is shared: https://github.com/nathanmarz/elephantdb/blob/develop/src/clj/elephantdb/keyval/core.clj#L111 |
| 15:39 | sritchie | getStatus, update, etc |
| 15:39 | sritchie | the idea is for users to be able to extend the database type to something, and create a function like kv-service for them |
| 15:40 | sritchie | to get rid of all of this pass-through boilerplate |
| 15:40 | hiredman | database should be a type, it should be a protocol |
| 15:41 | sritchie | should or shouldn't be a type? |
| 15:41 | hiredman | shouldn't be |
| 15:41 | sritchie | here's where I define it |
| 15:41 | sritchie | https://github.com/nathanmarz/elephantdb/blob/develop/src/clj/elephantdb/common/database.clj#L96 |
| 15:41 | hiredman | :( |
| 15:42 | hiredman | if it's a tpye you control you should have the interface inline |
| 15:42 | hiredman | (deftype Foo [] ISomething (doSomething [...] ...)) etc |
| 15:43 | sritchie | this is meant to be a library others can use to write their own databases |
| 15:43 | hiredman | reifying a wrapper of an interface over a deftype is horrible |
| 15:43 | hiredman | sritchie: right, so provide protocols and interfaces they can extend with their own types |
| 15:43 | hiredman | don't provide types |
| 15:45 | hiredman | types are not an extension point, multimethods, protocols, and interfaces are |
| 15:45 | sritchie | that makes sense, |
| 15:46 | sritchie | hmm, I was using a type so I could provide implementations for most things |
| 15:46 | hiredman | you can provide default via functions |
| 15:47 | sritchie | https://github.com/nathanmarz/elephantdb/blob/develop/src/clj/elephantdb/common/domain.clj#L269 |
| 15:47 | sritchie | I see |
| 15:47 | sritchie | so for something like this type, |
| 15:47 | sritchie | well, this one actually might make sense as a type, since everything about a domain is generic |
| 15:48 | sritchie | thanks for the the advice here, btw, this is my first big dive into records & protocols |
| 15:49 | hiredman | sure |
| 15:49 | hiredman | don't provide types (as an extension point) |
| 15:50 | sritchie | hiredman: I still don't see how to avoid a whole set of repeated methods like isUpdating, isFullyLoaded, etc -- these are all part of the thrift interface, but since I can't do |
| 15:50 | sritchie | (extend MyType SomeInterface {:isUpdating (fn ….)}) |
| 15:51 | sritchie | with a map of implementations, I'm not sure how to go about supplying such a big set of defaults |
| 15:51 | sritchie | default interface implementation |
| 15:51 | sritchie | s |
| 15:54 | hiredman | sritchie: there are a few possiblities |
| 15:57 | sritchie | this one uses the lein-newnew project, it's pretty cool |
| 15:58 | hiredman | it actually would be fairly easy to (def thrift-impl '(SomeInterface (method [...] ...))) and have a macro ontop of deftype or defrecord that would be able to pull those in |
| 15:59 | sritchie | hiredman: that sounds like a good lead |
| 15:59 | sritchie | rather than building my proxy business, build a macro like "extend" that can build these thrift interfaces |
| 16:00 | sritchie | letting the user construct his own type |
| 16:00 | sritchie | that's good, I see what you mean |
| 16:01 | hiredman | it is unfortunate that macros aren't more composable |
| 16:02 | romain_p | Hi everyone, quick question (clojure, linux): why does (slurp "/proc/cpuinfo") fail on my machine ? |
| 16:02 | bhenry | hey guys. who can provide a less roundabout way of this https://gist.github.com/663d0d5cdf150b7be3d5 |
| 16:03 | bhenry | need to turn integers of seconds into date objects |
| 16:04 | hiredman | ,(java.sql.Timestamp. 10000) |
| 16:04 | hiredman | uh |
| 16:04 | clojurebot | #<Timestamp 1969-12-31 16:00:10.0> |
| 16:04 | hiredman | that is horrible, why don't you just pass them to the Date constructor? |
| 16:04 | hiredman | ,(Date. (* 100 100)) |
| 16:04 | clojurebot | #<CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: Date, compiling:(NO_SOURCE_PATH:0)> |
| 16:04 | hiredman | ,(java.util.Date. (* 100 100)) |
| 16:04 | clojurebot | #<Date Wed Dec 31 16:00:10 PST 1969> |
| 16:05 | hiredman | ,(supers java.sql.Timestamp) ;for grins |
| 16:05 | clojurebot | #{java.util.Date java.io.Serializable java.lang.Comparable java.lang.Cloneable java.lang.Object} |
| 16:05 | romain_p | ,(slurp "/proc/cpuinfo") |
| 16:05 | clojurebot | #<AccessControlException java.security.AccessControlException: access denied (java.io.FilePermission /proc/cpuinfo read)> |
| 16:06 | romain_p | On my machine, this fails with an IOException ("invalid argument") |
| 16:06 | gtrak` | &(slurp "/proc/cpuinfo") |
| 16:06 | lazybot | java.security.AccessControlException: access denied (java.io.FilePermission /proc/cpuinfo read) |
| 16:06 | hiredman | you are doing it wrong |
| 16:07 | Vinzent | Why (meta ^{:a "1"} []) works, since (meta ^{:a "1"} 'x) returns nil? |
| 16:08 | Vinzent | ah, got it |
| 16:08 | gtrak` | Vinzent: curious, what's the answer? |
| 16:08 | Vinzent | hm, no, not got it |
| 16:09 | gtrak` | i think you have to use with-meta to add metadata |
| 16:11 | amalloy | ^ is for reader metadata, which mostly is consumed by the compiler. if you want metadata on your runtime values, use with-meta |
| 16:11 | amalloy | &(meta ' ^{:a "1"} x) probably works, but is still wrong |
| 16:11 | lazybot | ⇒ {:a "1"} |
| 16:13 | gtrak` | so the reader macro is only for constants really? |
| 16:14 | amalloy | i think that's an accurate statement, but no guarantees |
| 16:14 | Vinzent | gtrak`, I use it just to have nice syntax in my macro, like (defentity foo [^:flag x y]), and wonder why such syntax not working in the repl |
| 16:14 | Vinzent | amalloy, hm, thank you |
| 16:17 | narsilou | Hi, there do you think with clojurescript and compojure someone could build a website that is either entirely server-side, or entirely client-side or anywhere in-between (meaning part of the functions are runned by the server, the rest by the client through javascript) with the samecodebase ? |
| 16:18 | brehaut | narsilou: have you looked at clojurescript one yet? |
| 16:19 | narsilou | Yes I have. |
| 16:19 | emezeske | narsilou: lein-cljsbuild has some provisions for sharing code between clj and cljs |
| 16:20 | emezeske | narsilou: You have to be careful in code that's used in both environments, though |
| 16:20 | pjstadig | ~suddenly |
| 16:20 | clojurebot | BOT FIGHT!!!!!111 |
| 16:20 | pjstadig | wut?! |
| 16:20 | pjstadig | ~suddenly |
| 16:20 | clojurebot | CLABANGO! |
| 16:21 | emezeske | narsilou: But if you keep I/O-type stuff out of the shared code, and keep it as pure as possible, I think you could have a great deal of code work either on the client or server |
| 16:23 | narsilou | Thx for lein-cljsbuild, but actually I was thinking at having only clj files, with a macro like (client `(do (cool stuff) ~(server stuff))) and it would automatically compile js (the ~stuff being ran by the server), and serve it. |
| 16:24 | narsilou | Of course this leaves out I/O which stays on the server |
| 16:24 | narsilou | And DOM manipulation should stay at the client too |
| 16:24 | emezeske | Ah, I see. If you are going down that road, you will want to aggressively memoize your cljs compilation, it is not fast. |
| 16:25 | narsilou | Yep, I actually have a test stuff (to freshen up my clojure) |
| 16:25 | narsilou | Caching the js is OK |
| 16:25 | narsilou | But I am still wondering if it could be more than a pet project |
| 16:25 | emezeske | I originally went that direction, but I'm working on a google appengine project, and the cljs compiler requires temporary files (which GAE does not allow) |
| 16:26 | emezeske | So I had to switch to doing all cljs compilation up front |
| 16:26 | hiredman | hugod: from the reflector? |
| 16:26 | narsilou | Yep I'm using tmp files too. |
| 16:26 | hugod | hiredman: yes, via core/load |
| 16:26 | hiredman | :( |
| 16:27 | narsilou | Do you actually know why cljsc requires a file ? |
| 16:27 | hiredman | hugod: there is a thread on the mailing list about it, maybe chime in (let clojure/core feel your pain) |
| 16:27 | emezeske | narsilou: I think it builds the basic JS on-disk, and then passes the JS files to the google closure optimizer as its inputs |
| 16:27 | emezeske | narsilou: But don't quote me on that |
| 16:27 | hiredman | hugod: or even look over the issue in jira |
| 16:28 | hugod | hiredman: I had been sort of following the issue, but now I have first hand experience... |
| 16:28 | cemerick | The last time I looked at it, the gclosure compiler API wasn't super-friendly |
| 16:28 | cemerick | They really want you to just use the command-line entry point. |
| 16:29 | hiredman | hugod: it is pretty lame |
| 16:29 | narsilou | Ow probably it. This sucks. |
| 16:31 | narsilou | emezeske: Anyway, do you have some code for when you tried ? It took me a lot of time to realise `(fn ~(something)) was what I wanted for client/server mixed behavior) |
| 16:32 | emezeske | narsilou: I might be able to dig it up. It was a hairy nightmare, particularly when you needed to access cljs namespaces from the code |
| 16:33 | semperos | let's say I have several `deftest` forms which I want to define in a macro, because I need to execute the same set of tests with different application contexts |
| 16:33 | narsilou | Ow, yes, namespaces might be a problem |
| 16:33 | semperos | if I just do `(deftest ~'name-of-test ...), then names collide and only one set of tests is run |
| 16:34 | hiredman | you can put (is ...) forms in regular functions and call them inside a deftest |
| 16:34 | technomancy | oh, beat me to it |
| 16:34 | hiredman | or just use doseq or something |
| 16:34 | technomancy | yeah, do what hiredman said |
| 16:34 | semperos | alrighty |
| 16:34 | narsilou | But doesn't cljsc handles namespaces ? |
| 16:34 | hiredman | (doseq [test-data some-test-data] (is (do-stuff test-data))) |
| 16:34 | hiredman | etc |
| 16:35 | emezeske | narsilou: The (ns ...) form HAS to be the first form the compiler encounters in a compilation unit |
| 16:35 | semperos | hiredman: thanks, I'll go that route |
| 16:35 | TimMc | narsilou: Not exactly. |
| 16:35 | emezeske | narsilou: So your code has to aggregate things into the (ns) form and make sure to prepend that to whatever code you're slinging at it |
| 16:36 | narsilou | Meaning cljs can't import for other cljs ? They have to be standalone ? |
| 16:37 | emezeske | narsilou: They can import. |
| 16:37 | TimMc | romain_p: Read slurp's doc -- it needs a file or stream or something, not the name of a file. |
| 16:37 | emezeske | narsilou: It's just really, really tricky to do at runtime like you're proposing |
| 16:38 | narsilou | Tricky and possible, or tricky and probably impossible ? |
| 16:38 | TimMc | romain_p: Cancel that, it should take a string... |
| 16:38 | simonadameit | hi |
| 16:38 | simonadameit | regarding build tools, is cake or leiningen the thing to use? |
| 16:38 | TimMc | simonadameit: Lein |
| 16:38 | narsilou | Lein |
| 16:39 | TimMc | Cake dev has stopped, the devs are contributing to leiningen now. |
| 16:39 | simonadameit | ah ok, thats good! |
| 16:39 | simonadameit | leiningen is so slow in startup… :( |
| 16:39 | TimMc | That's the JVM. |
| 16:39 | simonadameit | yes, but on the cake site it says they have solved that problem |
| 16:39 | TimMc | simonadameit: Are you on 64-bit Linux by any chance? |
| 16:39 | technomancy | simonadameit: two things: use a client JVM and try the interactive task. |
| 16:39 | cemerick | hopefully we can get jark to solve the startup issue permanently |
| 16:40 | technomancy | yeah I saw jark had some activity yesterday |
| 16:40 | simonadameit | TimMc: 64bit macosx |
| 16:41 | TimMc | simonadameit: Does java -version show "Server VM"? |
| 16:41 | technomancy | I have no idea how to get a client JVM on a mac =( |
| 16:41 | technomancy | if someone figures it out please document it on the wiki |
| 16:41 | cemerick | technomancy: I think they're blocking on me a bit at this point :-/ |
| 16:41 | technomancy | cemerick: blocking nrepl work? |
| 16:42 | simonadameit | i have a server jvm |
| 16:42 | TimMc | Yeah, those apparently have slow startup. |
| 16:42 | cemerick | technomancy: no, repl work is blocking jark (maybe). |
| 16:42 | cemerick | That'll not be the case in a couple of days. |
| 16:42 | technomancy | oic |
| 16:45 | romain_p | TimMc: I am told that it is because a DataInputStream cannot be created for a /proc file. Now why would slurp need a DataInputStream when it just returns a String (without any parsing AFAIK)... ? |
| 16:47 | TimMc | romain_p: I get a different error: IOException Invalid argument java.io.FileInputStream.available (FileInputStream.java:-2) |
| 16:48 | TimMc | romain_p: But this works fine: (with-open [f (java.io.FileReader. "/proc/cpuinfo")] (slurp f)) |
| 16:48 | romain_p | TimMc: ah, thanks for the tip ! |
| 16:49 | TimMc | But that does seem like a bug. |
| 16:49 | emezeske | narsilou: Tricky and possible, I think. |
| 16:49 | technomancy | simonadameit: actually try "export LEIN_JVM_OPTS=-XX:+TieredCompilation" |
| 16:49 | romain_p | TimMc: well I can always paste the code on the clojure bug tracker if I can find it |
| 16:50 | technomancy | that may get you client-jvm-level startup times without having to hunt down a new JVM |
| 16:50 | emezeske | narsilou: But I had to dip way down into the compiler code to do it; you have to largely reimplement the 'build' function yourself |
| 16:50 | technomancy | what build of hotspot do macs ship with anyway? |
| 16:51 | technomancy | I think you need at least 20 |
| 16:51 | theignorati | the 32bit version is client |
| 16:51 | brehaut | technomancy: java version "1.6.0_29" \n Java(TM) SE Runtime Environment (build 1.6.0_29-b11-402-11M3527) \n Java HotSpot(TM) 64-Bit Server VM (build 20.4-b02-402, mixed mode) |
| 16:52 | brehaut | technomancy: thats whatever lion has out of the box |
| 16:52 | technomancy | is lion the latest? |
| 16:52 | brehaut | technomancy: yes |
| 16:52 | clojurebot | Cool story bro. |
| 16:53 | brehaut | technomancy: i think you can download a non-apple openjdk that is newer? |
| 16:53 | technomancy | brehaut: can you tell if exporting that LEIN_JVM_OPTS var speeds up "time lein versin"? |
| 16:54 | brehaut | technomancy: is there an example in the readme or something? |
| 16:54 | brehaut | oh. its above |
| 16:54 | technomancy | brehaut: it's built-in to bin/lein in 1.7.0-SNAPSHOT and 2.0.0-SNAPSHOT; I just found out about it 2 days ago |
| 16:55 | brehaut | ok, i'll get myself up to date and run that for you |
| 16:55 | tavis` | you can also do export LEIN_JAVA_CMD=<path-to-32-bit-java> once you have it installed. That allows you to run lein's commands in 32 bit while still using the 64bit jvm for anything lein launches as a subproc |
| 16:55 | technomancy | brehaut: no need to update |
| 16:55 | technomancy | if you export that env var it works in older versions |
| 16:55 | brehaut | oh right |
| 16:56 | technomancy | tavis`: yeah, but from what I can tell it's hard to find 32-bit binaries |
| 16:56 | tavis` | http://stackoverflow.com/questions/6942063/how-to-run-32-bit-java-on-mac-osx-10-7-lion |
| 16:56 | technomancy | aha |
| 16:56 | tavis` | looks like -d32 does it |
| 16:57 | brehaut | technomancy: prior to export … its ~1.2 seconds total |
| 16:57 | brehaut | technomancy: after, its ~0.95 |
| 16:58 | brehaut | wait, im reading the wrong column |
| 16:58 | raek | wow. 3.8 secs before and 1.0 secs after! |
| 16:59 | brehaut | 1.6 before, 1.9 after |
| 16:59 | technomancy | o_O |
| 17:00 | raek | this one goes straight to my ~/.path_and_stuff file |
| 17:01 | semperos | technomancy: going back to putting (is) forms in functions and using (doseq) to run through them multiple times, would your robert-hooke be a good replacement for (use-fixture :each) support? |
| 17:01 | semperos | otherwise you do lose the clojure.test fixture support, if you're not running defining all test cases in individual deftest's |
| 17:01 | narsilou | emezke: Do cljs devs know about this ? |
| 17:02 | technomancy | semperos: I don't recommend using hooke to extend functions you control |
| 17:02 | semperos | that's true |
| 17:02 | technomancy | I'd just call the defn from three separate deftests if you need :each fixtures |
| 17:03 | semperos | don't think I understand what you mean |
| 17:04 | semperos | in my specific case, I have global instances of web browsers I'm controlling from Clojure |
| 17:04 | semperos | for performance reasons, I don't open/close the browser instance each time, so instead, I use an :each fixture to bring my test application back to the same URL |
| 17:04 | semperos | for the beginning of each deftest |
| 17:05 | technomancy | (defn my-check [x] (is (good? x))) (deftest check-ff (my-check :firefox)) (deftest check-chromium (my-check :chromium)) (deftest check-w3m (my-check :w3m)) |
| 17:07 | TimMc | technomancy: I don't know how to read the output of time, but "real" goes down slightly on average, and "user" goes up by 50%. |
| 17:07 | semperos | technomancy: going one step further: https://gist.github.com/1643192 |
| 17:07 | semperos | between calls to my-check and another-check within a single deftest, I need to ensure that the browser is back to the same URL |
| 17:08 | semperos | not seeing how that works without, now, adding that to the beginning of each function; not end of world, just looking to keep things DRY-ish |
| 17:09 | technomancy | TimMc: cool |
| 17:10 | technomancy | semperos: ok, maybe that won't work then |
| 17:11 | semperos | cool, just wanted to make sure I wasn't missing something obvious |
| 17:11 | tavis` | can anyone see any issues with this patch to defmethod I'd like to propose https://gist.github.com/1643214 |
| 17:12 | tavis` | it adds metadata so swank and other tools can find the source location of entry in (methods a-multifn) without resorting to hacks |
| 17:13 | hiredman | tavis`: doesn't seem very useful |
| 17:13 | hiredman | I guess it could be |
| 17:13 | tavis` | slime-who-specializes |
| 17:13 | hiredman | right |
| 17:13 | technomancy | tavis`: interesting; there's all this CL functionality just waiting to be wired up =) |
| 17:13 | hiredman | I was thinking you couldn't use it for M-. |
| 17:13 | tavis` | I implemented that in swank-clojure last night but had to resort to an ugly hack |
| 17:14 | hiredman | tavis`: how ugly? |
| 17:14 | llasram | semperos: remember that functions are data too: https://gist.github.com/1643212 |
| 17:14 | tavis` | regexes |
| 17:14 | hiredman | tavis`: you might be able to pull that info from the fn's class |
| 17:14 | semperos | llasram: there we go, that's the simple tactic I was missing |
| 17:15 | semperos | thanks |
| 17:15 | tavis` | I went fishing for it there, but couldn't see it |
| 17:16 | hiredman | hmm, yeah, too bad Class doesn't expose that info, because it is definitely there |
| 17:17 | hiredman | tavis`: if you call some method on the function badly you'll get an exception you call pull that information from |
| 17:18 | simonadameit | technomancy: again thanks, for looking into it |
| 17:18 | simonadameit | technomancy: I now found the magic option to make jvm startup super fast :) |
| 17:18 | tavis` | hiredman: not sure I understand |
| 17:18 | simonadameit | unfortunately it doesnt seem to work... |
| 17:19 | tavis` | hiredman: oh, I see what you mean |
| 17:19 | hiredman | ,(apply (fn [x y z] x) (map (fn [_] (throw (Exception.))) (range 5))) |
| 17:19 | clojurebot | #<RuntimeException java.lang.RuntimeException: java.lang.Exception> |
| 17:19 | hiredman | ,(take 3 (.getStacktrace (apply (fn [x y z] x) (map (fn [_] (throw (Exception.))) (range 5))))) |
| 17:19 | clojurebot | #<RuntimeException java.lang.RuntimeException: java.lang.Exception> |
| 17:19 | hiredman | bleh |
| 17:20 | hiredman | Oh |
| 17:20 | hiredman | AFn has a public thorwArity method |
| 17:20 | hiredman | Perfect |
| 17:20 | hiredman | ,(.throwArity (fn [] ) 1) |
| 17:20 | clojurebot | #<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: sandbox$eval87$fn> |
| 17:22 | tavis` | (.throwArity (:cdt (methods swank.core.debugger-backends/debugger-exception?)) 1) |
| 17:22 | hiredman | something like that |
| 17:22 | tavis` | the stacktrace doesn't show the source |
| 17:24 | tavis` | (.throwArity identity 1) doesn't either |
| 17:24 | simonadameit | technomancy: -d32 does improve it somewhat though... |
| 17:25 | tavis` | hiredman: anyway, I figured adding the metadata would be the most straightforward longterm |
| 17:25 | hiredman | travis`: if you are doing this at the slime repl you need to call getCause |
| 17:27 | tavis` | even then I'm just seeing some reflection and eval |
| 17:27 | hiredman | Oh, of course, it just shows you clojure.lang.AFn as the classname |
| 17:28 | hiredman | (because thats where the code that throws the exception is from) |
| 17:28 | hiredman | too bad |
| 17:28 | tavis` | right |
| 17:30 | tavis` | hiredman: the only way I could trace the method back to the source was via its name |
| 17:30 | hiredman | :/ |
| 17:31 | tavis` | hence the regex hack |
| 17:32 | chojeen | does the map function interfere with dynamic binding somehow, e.g. http://pastebin.com/iBPyiW2C |
| 17:33 | hiredman | ~map |
| 17:33 | clojurebot | map and the other sequence functions used to be lazy, but with the advent of chunked sequences, may or may not be lazy, consult your local ouija board |
| 17:33 | hiredman | ~map |
| 17:33 | clojurebot | map is laziness |
| 17:33 | hiredman | ~map |
| 17:33 | clojurebot | map is *LAZY* |
| 17:34 | chojeen | okay... |
| 17:38 | Raynes | chojeen: Laziness means that nothing is evaluated until you use it. If you use map to map over a dynamically rebound value, nothing actually happens until you try to use map's return value. However, by time you actually do that, you've left the scope of the dynamic rebinding and thus your var is set back to what it was before, resulting in boogs. |
| 17:39 | chojeen | ah, very helpful |
| 17:40 | TimMc | Some lazy-ish things copy dynamic bindings, lazy-seqs do not. |
| 17:42 | chojeen | it looks as though judicious use of doall helps, thanks |
| 17:44 | amalloy | TimMc: example? |
| 17:47 | Raynes | chojeen: Yeah, that's what doall is for. Also, doseq if you're only mapping for side effects. |
| 17:51 | TimMc | amalloy: @(binding [*print-readably* 5] (future *print-readably*)) |
| 17:51 | TimMc | I think that illustrates it... |
| 17:51 | TimMc | OK, "lazy-ish" is maybe a bad term... |
| 17:52 | amalloy | yeah, future seems unrelated to laziness |
| 17:52 | chojeen | has anybody read 'Clojure in Action'? is it worth the purchase? |
| 17:53 | TimMc | amalloy: dynamic-scope-escaping-things |
| 17:53 | tmciver | chojeen: I've been reading it. It's OK, imo. Not as good as JoC. |
| 17:53 | chojeen | I've got JoC; it's good, but it leans towards the theoretical |
| 17:54 | llasram | chojeen: I haven't read it in-depth. It's got some good walkthroughs of doing some practical Java interop stuff, but for general language knowledge and application it seems relatively weak |
| 17:54 | tmciver | I've definitely learned some things (granted I'm still a noob) so it was worth it to me. |
| 17:57 | gtrak` | future does abstract computation from synchronous execution, like laziness |
| 18:15 | TimMc | With futures and promises you *intend* to use the value. |
| 18:19 | gtrak` | i guess we have delay and force |
| 18:26 | _carlos_ | hi! |
| 18:26 | alex_baranosky | hi! |
| 18:27 | _carlos_ | why doesn't doc say ".." is somewhat deprecated in favour of "->"? |
| 18:30 | _carlos_ | by the way, is "doto" called that way because someone thought about using japanese english for "dot"? ドト〜 |
| 18:30 | amalloy | do to |
| 18:30 | _carlos_ | ha. |
| 18:35 | _carlos_ | amalloy: btw, isn't it better to just use also "->" instead of "doto"? |
| 18:59 | TimMc | _carlos_: They're different. |
| 19:01 | TimMc | _carlos_: ##(* (doto 4 (println "is the inner value.")) 3) |
| 19:01 | lazybot | ⇒ 4 is the inner value. 12 |
| 19:02 | bitops | TimMc: hey, you were helping me with my hl-line-mode problem yesterday I think it was. I found the solution. |
| 19:02 | TimMc | bitops: Probably wasn't me, but go ahead! |
| 19:03 | bitops | TimMc: to turn off hl-line-mode globally, put this in init.el: |
| 19:03 | bitops | (remove-hook 'prog-mode-hook 'esk-turn-on-hl-line-mode) |
| 19:03 | TimMc | I wonder if that was tmciver. |
| 19:03 | bitops | oh actually you're right...d'oh. it was kodein, but you *did* try to help me. |
| 19:03 | bitops | so...uh...now you know. |
| 19:03 | bitops | :) |
| 19:04 | TimMc | Glad it's fixed! |
| 19:04 | TimMc | _carlos_: doto takes the value and runs a bunch of side-effecty things on it, discarding the return value of each, then returns that initial value. |
| 19:06 | TimMc | (doto (Constructor. 5) (.setFoo 6) (.setBar 13) (.init)) => returns the object, not the result of .init |
| 19:06 | clj_newb | what does agent failed mean ? can it only be triggered if a (send _agent _fn) has _fn throw an exception, or does a watcher throwing an exception also trigger an agent failing? |
| 19:06 | clj_newb | n00bish minds want to know |
| 19:10 | TimMc | try it and see |
| 19:10 | ned | does clojure have something like macro-expand-1 |
| 19:11 | ned | and unwind-protect signaling/restart |
| 19:11 | hiredman | like macroexpand-1? |
| 19:11 | hiredman | ,(doc macroexpand-1) |
| 19:11 | clojurebot | "([form]); If form represents a macro form, returns its expansion, else returns form." |
| 19:11 | TimMc | clj_newb: Actually, the docs imply that they're treated the same way. |
| 19:11 | ned | oh, rad. |
| 19:11 | clj_newb | TimMc: which docs are you referring to? |
| 19:11 | TimMc | clj_newb: (doc agent) and (doc set-error-handler!), which the first refers you to. |
| 19:12 | hiredman | no signaling, just java style exceptions, but some people have written some libraries to try and provide things like conditions on top of exceptions |
| 19:12 | clj_newb | (sorry about these dumb questions; I feel like I'm in the area between "doing simple things that are obvious" vs "understnding details of clojure") |
| 19:12 | ned | hiredman: is there a lib that's advanced enough to be placed into something that's not-mission-critical-but-still-might-be-important |
| 19:12 | ned | or should i stick to just try/finally |
| 19:12 | hiredman | dunno, I've never used any of them |
| 19:13 | bitops | ,(doc doc) |
| 19:13 | clojurebot | "([name]); Prints documentation for a var or special form given its name" |
| 19:13 | ned | ,(doc 'doc) |
| 19:13 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.ClassCastException: clojure.lang.Cons cannot be cast to clojure.lang.Symbol> |
| 19:13 | bitops | ned: naughty |
| 19:13 | bitops | ,(.toUpperCase "very naughty") |
| 19:13 | clojurebot | "VERY NAUGHTY" |
| 19:14 | bitops | that is fantastic |
| 19:14 | TimMc | doc is a macro that reads a symbol |
| 19:14 | clj_newb | :error-mode :continue looks cool |
| 19:14 | bitops | hmm...I'm about to get in trouble here, but... |
| 19:14 | bitops | ,(source map) |
| 19:14 | clojurebot | Source not found |
| 19:14 | bitops | aw |
| 19:14 | hiredman | ~def map |
| 19:15 | bitops | ,(def foo 12) |
| 19:15 | clojurebot | #<Exception java.lang.Exception: SANBOX DENIED> |
| 19:15 | TimMc | &(source flatten) |
| 19:15 | lazybot | java.lang.RuntimeException: Unable to resolve symbol: source in this context |
| 19:15 | bitops | hahahaha |
| 19:15 | bitops | ,(str (map .toUpperCase '("that" "is" "just" "craziness"))) |
| 19:15 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: .toUpperCase in this context, compiling:(NO_SOURCE_PATH:0)> |
| 19:15 | bitops | huh. |
| 19:16 | bitops | did I mess something up? |
| 19:16 | TimMc | yep |
| 19:16 | TimMc | bitops: .foo is a method, not a function |
| 19:16 | tavis` | ,(str (map #(.toUpperCase %) '("that" "is" "just" "craziness"))) |
| 19:16 | clojurebot | "clojure.lang.LazySeq@fec989f0" |
| 19:16 | hiredman | feel to get your own repl or interact via private message |
| 19:16 | bitops | TimMc: d'oh, got it |
| 19:16 | _carlos_ | TimMc: about "doto", I understand the usage. the book I am reading, "clojure in action", uses a not so happy example because I can implement the same result with much less clutter and using "->" |
| 19:16 | tavis` | ,(apply str (map #(.toUpperCase %) '("that" "is" "just" "craziness"))) |
| 19:16 | clojurebot | "THATISJUSTCRAZINESS" |
| 19:16 | bitops | hiredman: no worries, just goofing around a bit. |
| 19:17 | TimMc | You'd want to interpose \space, but I think that's enough... |
| 19:17 | bitops | TimMc: yeah I'm already getting in trouble. :) |
| 19:17 | TimMc | _carlos_: Is the example short enough to paste? 'Cause I'm doubtful. |
| 19:18 | ned | wiat what does the % char do |
| 19:19 | TimMc | ned: It's used by the anon fn literal #() |
| 19:19 | brehaut | ned:its the first argment to an anon function defined using the #( … ) shorthand |
| 19:20 | dgrnbrg | If I have a function that is amenable to the early-return/guard-style coding, how do I write it in idiomatic clojure? |
| 19:20 | tavis` | ned: see row 2 of this http://clojure.org/other_functions table |
| 19:21 | hiredman | early returns :( |
| 19:21 | amalloy | TimMc, tavis`: every time someone uses (apply str (interpose x ys)) i cry |
| 19:21 | amalloy | (clojure.string/join x ys) |
| 19:21 | _carlos_ | TimMc: sure, http://pastebin.com/dA28QrWz |
| 19:21 | clj_newb | ,(apply str (interpose "," ["a", "b", "c"])) |
| 19:21 | clojurebot | "a,b,c" |
| 19:22 | tavis` | amalloy: hehe, just completing the code he already had |
| 19:22 | _carlos_ | TimMc: this is the import, sorry: (import '(java.util Calendar)) |
| 19:22 | clj_newb | ,(join "," ["a", "b", "c"]) |
| 19:22 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: join in this context, compiling:(NO_SOURCE_PATH:0)> |
| 19:22 | brehaut | dgrnbrg: early returns arent that common in clojure code |
| 19:23 | brehaut | dgrnbrg: but if you want something like haskells guards / case, then cond, condp and case might be appropriate |
| 19:23 | amalloy | _carlos_: http://stackoverflow.com/q/8821751/625403 is relevant here |
| 19:23 | hiredman | or the pattern matching library |
| 19:23 | amalloy | $javadoc java.util.Calendar |
| 19:23 | lazybot | http://download.oracle.com/javase/6/docs/api/java/util/Calendar.html |
| 19:23 | brehaut | clj_newb: clojure.string/join |
| 19:23 | dgrnbrg | brehaut, thanks |
| 19:24 | amalloy | and also, _carlos_, it looks from the javadocs like your assertion that -> would work as well as doto seems completely bogus |
| 19:25 | dgrnbrg | what's the difference between extends? and satisfies? |
| 19:25 | tavis` | does anyone here have experience using clj-webdriver in the way semperos was describing before? i.e. keeping one browser instance open in a repl coding/testing session rather than restarting it for each test run |
| 19:25 | brehaut | dgrnbrg: one works on types, one on instances |
| 19:25 | tavis` | (at least I think he meant that) |
| 19:26 | dgrnbrg | brehaut, thanks again! |
| 19:26 | TimMc | _carlos_: Ah, I see -- the result of the doto is discarded. |
| 19:27 | TimMc | But have you tried running your impl? I doubt it works... |
| 19:27 | _carlos_ | TimMc: yes, in the example from the book it is discarded |
| 19:27 | _carlos_ | TimMc: I don't know about the existence of impl, but I ran it on repl |
| 19:28 | _carlos_ | TimMc: ok, probably my last answers seems hilarious. did you mean "sample code" by "impl"? |
| 19:29 | TimMc | _carlos_: "implementation" :-) |
| 19:30 | clj_newb | is there a short hand for: (with-meta (agent "") {:name "foo"}) ? i.e. something involving charaters # and ^ ? |
| 19:30 | _carlos_ | amalloy: I have to read that post carefully. about "doto" "seems completely bogus", I don't understand, is it also related to that link? |
| 19:31 | TimMc | ,(import java.util.Calendar) |
| 19:31 | clojurebot | java.util.Calendar |
| 19:31 | TimMc | ,(-> (Calendar/getInstance) (.set Calendar/HOUR 0) (.set Calendar/MINUTE 0) (.getTime)) ; _carlos_ |
| 19:31 | clojurebot | #<NullPointerException java.lang.NullPointerException> |
| 19:37 | TimMc | _carlos_: Calendar's setters are pretty standard as Java goes in that they have void returns -- you can't stitch them together with ->. |
| 19:45 | _carlos_ | TimMc: I will get back to you in a second. thank you |
| 20:00 | _carlos_ | TimMc: yes, java methods would return void in many cases, which would make most implementations with "->" useless. I now understand the use case for "doto", which would be of much use for java functions. it is quite strange, though, that clojurebot returned nullpointerexception, because I ran my code without problems in the repl. did you try the entire sample on the repl? |
| 20:02 | _carlos_ | TimMc: its not relevant if it doesn't throw an exception of course. thank you for pointing the usage of doto |
| 20:04 | _carlos_ | TimMc: and clojure in action is right all along, being doto an idiomatic way of handling java methods |
| 20:05 | TimMc | _carlos_: I did not run your sample then, but I have now -- same exception. |
| 20:06 | TimMc | Their names are the same in the paste you linked, so I assume you called the wrong one while testing. :-) |
| 20:07 | _carlos_ | TimMc: weirdest thing ever. I imported the java lib. then ran the code from pastebin in repl again just now. it doesn't throw any exception o.O |
| 20:08 | _carlos_ | TimMc: did you paste the second example? |
| 20:08 | TimMc | yep |
| 20:08 | _carlos_ | TimMc: please notice this doesn't mean to prove anything. I am just curious why we are getting different results |
| 20:09 | TimMc | me too |
| 20:09 | _carlos_ | TimMc: the second example starts in line 14 |
| 20:09 | TimMc | right |
| 20:10 | TimMc | Try just pasting the *inside* of the second example: (-> ...) |
| 20:10 | TimMc | into your REPL |
| 20:11 | _carlos_ | TimMc: this is my input/ouput from repl: http://pastebin.com/jjAuPgzA |
| 20:11 | _carlos_ | TimMc: ha! inside |
| 20:11 | TimMc | _carlos_: Umm, what happens if you *run* the function? |
| 20:12 | _carlos_ | TimMc: gotcha. sorry, this was pretty lame haha |
| 20:12 | amalloy | (defn make-the-magic [] (-> Calendar/getInstance (.dosomestufftothething 10 20 30))) will compile too, but that doesn't mean it works :P |
| 20:13 | _carlos_ | can someone please remove the last logs from #clojure?? |
| 20:13 | lazybot | _carlos_: What are you, crazy? Of course not! |
| 20:14 | _carlos_ | uau.. smart |
| 20:17 | TimMc | _carlos_: You'll sometimes see "fluent" Java interfaces where the setters return the object you called them on, in which case -> could be used. |
| 20:17 | TimMc | That's what amalloy's link was about. |
| 20:17 | alex_baranosky | aka chained method calls |
| 20:19 | hiredman | ~search for sender:_carlos_ |
| 20:19 | clojurebot | <#clojure:_carlos_> uau.. smart |
| 20:19 | clojurebot | <#clojure:_carlos_> can someone please remove the last logs from #clojure?? |
| 20:19 | lazybot | clojurebot: Uh, no. Why would you even ask? |
| 20:19 | clojurebot | <#clojure:_carlos_> TimMc: gotcha. sorry, this was pretty lame haha |
| 20:19 | clojurebot | <#clojure:_carlos_> TimMc: ha! inside |
| 20:19 | clojurebot | Titim gan éirí ort. |
| 20:20 | TimMc | What was the point of that, O Unseeing One? |
| 20:21 | _carlos_ | TimMc: is the object in doto mutable? |
| 20:22 | TimMc | _carlos_: Depends on the object! |
| 20:23 | TimMc | doto is often used to initialize a mutable Java object, but you might also see it used to send off I/O actions or hammer on mutable Clojure stuff too. |
| 20:24 | TimMc | I'd say doto always means "side-effects and/or mutation" |
| 20:25 | _carlos_ | TimMc: of course! I see, what it means. it just uses the object as parameter of successive calls inside doto, instead of using the last return of expression as parameter for the next expression, regardless of what kind of object the symbol binded to at that moment |
| 20:29 | _carlos_ | TimMc: no, sorry for the rush conclusion. I am wrong. there is no way for doto to guess at some time, the method at the moment returned something useful, and rebind it to the initial symbol. so, the object may change it's state and/or produce some side effect(s) |
| 20:29 | _carlos_ | sorry for the grammar, I hope though its somehow clear |
| 20:31 | _carlos_ | TimMc: so, if so method returns a new object, and that was supposed to be the new value to bound to, one would have to use "->". if there were some methods returning a new object, and others just changing the state of the object, it would produce code with "doto" and "->" in clojure |
| 20:34 | mindbender | please how do I control which directories clojure-jack-in includes in the classpath? |
| 20:36 | technomancy | mindbender: it's just using leiningen; what do you need? |
| 20:38 | mindbender | technomancy: I'm working on the clojurescript-one project and I need the cljs and cljs-macro dir included |
| 20:38 | TimMc | _carlos_: right |
| 20:38 | _carlos_ | TimMc: I read the stackoverflow post. it quite covers our whole discussion. I am clear about this stuff. thanks |
| 20:38 | TimMc | yay! |
| 20:38 | technomancy | mindbender: maybe :extra-classpath-dirs |
| 20:38 | technomancy | mindbender: but yeah, clojurescript-one is really ridiculous in that regard |
| 20:38 | technomancy | you should probably open a bug report |
| 20:39 | mindbender | technomancy: yes it is.. I have had to make a number of such corrections.. I'll consider reporting |
| 20:41 | technomancy | mindbender: you could try this: http://p.hagelb.org/lein-cljs-swank.html |
| 20:41 | technomancy | put it in src/leiningen/cljs_swank.clj and try "lein cljs-swank" |
| 20:41 | technomancy | it should open a cljs repl on stdin and a swank server on port 4005 |
| 20:41 | technomancy | it's gross though |
| 20:42 | mindbender | technomancy: thanks.. I'll definitely try it out |
| 20:44 | mindbender | technomancy: but for clojure-jack-in it's still going to pick up the :extra-classpath-dirs, right? |
| 20:44 | technomancy | I'm starting to think lein2 is going to have to have first-class cljs support |
| 20:44 | technomancy | mindbender: right; if you jack in it will have to go in project.clj |
| 20:45 | mindbender | ok, I prefer clojure-jack-in for some reasons |
| 20:46 | technomancy | yeah, in most cases I do to, but I suspect here having two repls at once is beneficial |
| 20:46 | technomancy | and jack-in doesn't make it convenient to use stdout |
| 20:46 | technomancy | stdin/out |
| 20:48 | technomancy | but then again I've spent a total of maybe half an hour using clojurescript (minus fighting build insanity) so what do I know. |
| 20:59 | uvtc | Hi. I'm trying to modify a top-level dynamic var (or, what I *think* is a dynamic var) inside a `binding` block, but it's not working. |
| 20:59 | uvtc | http://paste.pocoo.org/show/537560/ |
| 21:00 | uvtc | I get "Warning: "*factor* not declared dynamic and thus is not dynamically |
| 21:00 | uvtc | ;; > rebindable, but its name suggests otherwise." |
| 21:00 | brehaut | uvtc: clj 1.2 or 1.3 ? |
| 21:00 | uvtc | 1.3 |
| 21:00 | brehaut | (def ^:dynamic *factor* 10) |
| 21:00 | uvtc | brehaut: Hm. I'd thought that `def` makes dynamic variables. Is that not the case? |
| 21:01 | brehaut | uvtc: it was the case up to 1.2.1 |
| 21:01 | uvtc | (by default, that is) |
| 21:01 | uvtc | Does `def` now make lexicals by default? |
| 21:01 | brehaut | 1.3 onward default to static vars |
| 21:01 | uvtc | "static" == "lexical", correct? |
| 21:01 | brehaut | err… |
| 21:02 | brehaut | you'd need to ask someone who knows the internals better |
| 21:02 | brehaut | but im sure theres subtle distinctions |
| 21:02 | uvtc | Interesting. I'd always thought they were synonyms. Thanks, brehaut. |
| 21:03 | brehaut | uvtc: well, one example is that you can ns-unmap a static var, but you cant do so with a lexically scoped var |
| 21:03 | uvtc | brehaut, btw, the code correction you gave worked. Thanks. |
| 21:04 | uvtc | My understanding of the terminology is that "static" means that scope is determined "statically" -- that is, by just looking at blocks/parens. |
| 21:05 | uvtc | Is a "global" simply a var defined at the top-level? |
| 21:05 | brehaut | uvtc: any def is global to a namespace, nomatter where it occurs |
| 21:05 | uvtc | brehaut: Thank you. |
| 21:06 | brehaut | (let [n 1] (def foo n)) foo ;=> 1 |
| 21:07 | brehaut | uvtc: clojures vars, namespaces and defs occupy a more complicated space than just their scoping rules. 'static' vs 'dynamic' here is to do with when they are resolved, rather than how the scoping works. |
| 21:08 | brehaut | uvtc: unfortunately, im right on the edge of my knowledge |
| 21:09 | uvtc | brehaut, re. `(let [n 1] (def foo n)) foo ;=> 1`, That's interesting --- at first I'd expect foo to not be visible outside the `let`, |
| 21:09 | brehaut | uvtc: if you have a scheme background its very surprising. |
| 21:10 | uvtc | brehaut: I learned a little Scheme before coming to Clojure. Everything being lexical is pretty nice and simple. |
| 21:10 | brehaut | but it illustrates the two different axis that they operate on |
| 21:10 | uvtc | yes. |
| 21:11 | uvtc | brehaut, thanks again. |
| 21:14 | TimMc | brehaut: Are you teaching nonsense again? :-P |
| 21:14 | TimMc | Everyone knows vars are just magic. |
| 21:14 | brehaut | TimMc: lol |
| 21:16 | brehaut | The secret life of vars is a blog post waiting to be written |
| 21:17 | brehaut | (by someone who understand what the hell is going on) |
| 21:17 | TimMc | I think it's fair to say that vars are globally-available bindings attached to namespaces, and that they can opt into dynamic scoping. |
| 21:17 | brehaut | TimMc: that works :) |
| 21:17 | TimMc | (not globally-*visible*, mind you) |
| 21:17 | brehaut | although i would like to understand more about them under the hood |
| 21:28 | uvtc | Not requesting this, but is there a public log of this channel anywhere? |
| 21:29 | brehaut | clojure-log.n01se.net |
| 21:29 | brehaut | (for one example) |
| 21:30 | uvtc | Thanks! |
| 21:39 | uvtc | brehaut, the docs at http://clojure.org/vars don't mention ^:dynamic. Those docs are still for Clojure 1.2? |
| 21:40 | brehaut | clojure.org needs an update :/ |
| 21:41 | uvtc | Ah. Thanks. Hate to be a hit-n-run IRC user, but family calls. :) bye again. |
| 22:11 | metajack | any idea how to fix this when trying swank.cdt? warning: unabled to add tools.jar to classpath. This may cause CDT initialization to fail. |
| 22:13 | tmciver | metajack: at least one solution is to make a symbolic link to tools.jar in your .lein directory. |
| 22:14 | clj_newb | I want to overwrite .equals for a defrecord. Here is a minimal failing example: http://paste.lisp.org/display/127181 . What am I doing wrong? |
| 22:15 | amalloy | without looking at your example, i'd say what you're doing wrong is trying to override .equals on a record |
| 22:15 | clj_newb | ah; I can only do it to a deftype |
| 22:15 | clj_newb | I'm an idiot |
| 22:16 | clj_newb | amalloy: is there anyway to make it work with defrecord; or am I forced to use deftype? |
| 22:17 | amalloy | i doubt it, and if you succeed then anyone who uses your record will want to murder you, so... |
| 22:17 | brehaut | does creating a with-db middleware for my ring (moustache) app make sense? |
| 22:17 | amalloy | brehaut: i think so |
| 22:17 | brehaut | amalloy: thanks |
| 22:18 | clj_newb | amalloy: great; given I need to release this code GPL; makeing it hard to read is all good |
| 22:18 | technomancy | metajack: that warning is not always fatal |
| 22:18 | metajack | tmciver: If I knew what tools.jar was or where I was supposed to get it, that might be helpful. Is it some standard thing? |
| 22:18 | metajack | technomancy: Indeed, CDT appears to work fine. I just figured I might as well make it happy if I can. |
| 22:18 | technomancy | metajack: it's just a bug in cdt that it emits spurious warnings |
| 22:19 | technomancy | don't waste your time on it unless you are actually interested in fixing it in cdt itself |
| 22:19 | metajack | fair enough. |
| 22:20 | technomancy | would be great if you could patch it of course =) |
| 22:21 | metajack | I may look at it later. It's on my list to dig around in a little in this stuff. |
| 22:21 | metajack | For example, I still haven't gotten the colored stacktraces working :) |
| 22:22 | technomancy | that needs tweaking on the elisp side |
| 22:22 | tavis` | metajack: are you using clojure-jack-in? |
| 22:22 | metajack | Yes |
| 22:23 | ferd | technomancy: metajack: I've seen multiple options for debuggers on Clojure. Is swank+CDT currently the best option on Emacs ? |
| 22:23 | metajack | ferd: (swank.core/break) will work without any extra setup, but CDT seems the nicest that I've seen |
| 22:23 | tavis` | ferd: I think so but you need to use swank-clojure 1.4.0-SNAPSHOT |
| 22:24 | technomancy | ferd: if you need stepping I think cdt is the best. if you just need locals and a breakpoint then yeah, it's hard to beat swank.core/break |
| 22:24 | technomancy | there is also ritz, which I haven't tried |
| 22:24 | metajack | technomancy: I've been resisting the urge so far to dive into some of the smaller issues I have. Like why the repl buffer is sometimes called *slime-repl nil* and sometimes *slime-repl clojure* etc. |
| 22:25 | tavis` | I've got a hackish patch for locals in cdt |
| 22:25 | technomancy | metajack: that's been driving me nuts for a while |
| 22:25 | metajack | oh good. it's not just me :) |
| 22:25 | technomancy | well, abstractly driving me nuts |
| 22:25 | technomancy | it doesn't bother me apart from not knowing why it happens |
| 22:25 | metajack | same here. |
| 22:26 | ferd | thanks everybody |
| 22:26 | tavis` | I've also got a patch in progress for jack-in on the el side that fixes that *slime-repl nil* issue |
| 22:26 | ferd | Are you all using Emacs 24 ? |
| 22:26 | metajack | I'm on Emacs 24. |
| 22:26 | tavis` | same |
| 22:27 | ferd | I'm still on 23 and wondering if it's worth the upgrade before it's "officially stable" |
| 22:27 | tavis` | if you change the slime-connect line in jack-in to this: |
| 22:27 | tavis` | (with-current-buffer |
| 22:27 | tavis` | (or |
| 22:27 | tavis` | (get-buffer "*slime-repl clojure*") |
| 22:27 | tavis` | (get-buffer "*slime-repl nil*") |
| 22:27 | tavis` | (current-buffer)) |
| 22:27 | tavis` | (slime-connect hostname port) |
| 22:27 | tavis` | |
| 22:27 | metajack | Do you guys use clojure-jack-in repeated to swtich between projects? Or do you run multiple repls? |
| 22:27 | technomancy | ferd: it's unofficially extremely stable |
| 22:27 | tavis` | it should prevent the nil version from being created |
| 22:27 | technomancy | more stable than 23 in my experience |
| 22:27 | technomancy | metajack: multiple emacs instances |
| 22:27 | metajack | ferd: I've had zero problems and the new theming is better too. |
| 22:28 | technomancy | tavis`: also: stick with gists for multiline pastes next time? |
| 22:28 | tavis` | sorry |
| 22:28 | tavis` | lazy |
| 22:29 | metajack | technomancy: Hadn't thought of that. I've been jacking in back and for, but I did get multiple repls going once with slime-connect and lein swank. |
| 22:29 | technomancy | metajack: I'm an oddball; not many people like multiple instances |
| 22:29 | technomancy | but it works great for me |
| 22:29 | technomancy | separate color themes keep work distinct from play, etc. |
| 22:29 | metajack | I suppose a nice patch might be to make prefixed clojure-jack-in launch a second repl :) |
| 22:29 | brandel | where did the nomenclature jack-in come from - some kind of cyberpunk homage? |
| 22:29 | technomancy | slime's support for multiple connections is kind of crappy |
| 22:30 | brandel | ah :) |
| 22:30 | technomancy | https://github.com/technomancy/slamhound <- exhibit B |
| 22:30 | brandel | I've been meaning to read some of his newer work.. I think Idoru was the last thing I read |
| 22:30 | metajack | And just to make sure, I have to re-jack-in if I want to see new deps right? |
| 22:31 | technomancy | metajack: aye, or you could try your luck with pomegranate |
| 22:31 | technomancy | brandel: it's good but not excellent. |
| 22:32 | brandel | I thought it was interesting that he no longer considers himself a sci-fi novelist in that the future he wanted to write about is mostly a reality now, or elements of it |
| 22:33 | technomancy | actually I like the third trilogy better than the second. but neither come close to the energy and pace of the sprawl trilogy |
| 22:33 | metajack | pomegranate looks nice. I'll give that a whirl. |
| 22:34 | tmciver | metajack: my apologies for being terse. I just ran find on my system to find tools.jar. On my Ubuntu system it's somewhere in /usr/lib/jvm/... |
| 22:35 | metajack | tmciver: no worries. I just had no idea what it was, and it didn't show up in ~/.m2 or ~/.lein or anywhere. |
| 22:36 | tavis` | If anyone is interested in playing with locals in CDT/swank stackframes here's a patch for it https://gist.github.com/1644817 |
| 22:37 | metajack | tavis`: does that make them show up? I seem to be able to eval them fine in each frame. |
| 22:37 | tavis` | you already can eval them |
| 22:38 | tavis` | this makes a string version of them show up in the locals part of the sldb buffer |
| 22:38 | tavis` | I can't figure out how to avoid serializing to strings though |
| 22:41 | tavis` | 1.4.0-snapshot with cdt enabled already allows you to eval locals with 'e' in sldb or by putting your cursor on a sexp in the source for the frame and hitting some magic key sequence I can't remember |
| 22:41 | metajack | C-c C-x C-p :) |
| 22:41 | tavis` | metajack: oh, sorry misread your last line though you said you couldn't eval |
| 22:42 | metajack | I'll give your patch a try a little later and let you know how it works. |
| 23:01 | PaulIIIIIIII | hi |
| 23:01 | PaulIIIIIIII | how are you |
| 23:04 | notsonerdysunny | Is there a way to see the actual sql command it is generating/using when I do a clojure.java.jdbc/insert-record ? |
| 23:04 | PaulIIIIIIII | i dont know |
| 23:05 | PaulIIIIIIII | some microproccessor command maybe |
| 23:06 | PaulIIIIIIII | if you send some stack to the lan card, and its activates from proccessor secret code, what can hack your windows |
| 23:06 | PaulIIIIIIII | but then you must been at least microproccessor archidect |
| 23:20 | tmciver | technomancy: I see that swank-clojure depends on clj-stacktrace. If I run 'lein swank' in a project that does not depend on clj-stacktrace (and therefore does not have the jar in /lib) I get a FileNotFoundException. |
| 23:20 | technomancy | it should be on the classpath regardless, either in lib/dev or as part of the plugin uberjar in ~/.lein/plugins |
| 23:24 | tmciver | technomancy: Ahh, I created a swank-clojure jar from a fresh clone of the repo. I think my problem is the swank-clojure shell script set up the class path for my old 1.3.4 swank-clojure jar. |
| 23:32 | tavis` | technomancy: I've just about got jack-in working with tramp, but I'm not sure how to handle the remote filenames for the payload .el files. Any thoughts? |