2012-08-27
| 00:58 | Sgeo | So, is my unamb too dangerous to use due to possible uncollectable garbage creation? |
| 00:58 | Sgeo | (The creation of unstoppable infinite looping threads) |
| 01:06 | wmealing_ | Sgeo: when you say it like that.. it sounds like an evil creation.. just saying |
| 01:07 | wmealing_ | all that is missing is maniacal laughter |
| 01:18 | gzmask | Hey folks, I got a question about overtone: why the saw function in the tutorial has three parameters? I checked odoc and it only requires one. Code: https://github.com/overtone/overtone/blob/master/src/overtone/examples/getting_started/basic.clj#L9 |
| 01:53 | emezeske | gzmask: That's one one parameter -- it's a vector of length three |
| 01:53 | emezeske | gzmask: From looking at that code, I'd guess that each entry in the vector will produce an additional saw wave |
| 01:53 | emezeske | gzmask: It's pretty common to stack multiple detuned saws to get a "fat" sound |
| 02:09 | Sgeo | ClojureScript doesn't have promises? |
| 02:10 | wmealing_ | empty, empty promises |
| 02:13 | emezeske | Sgeo: Javascript is single threaded, so a lot of Clojure's concurrency primitives don't make much sense. Although I guess they could be implemented in some kind of async way. |
| 02:14 | Sgeo | Promises strictly speaking don't need threading, although they might be not as useful without it |
| 02:14 | Sgeo | Although, doesn't a lot of Javascript library stuff do things that take callbacks? |
| 02:18 | Sgeo | Hmm, might not be useful without threading even there |
| 02:18 | emezeske | Tons of callbacks, everywhere. |
| 02:19 | emezeske | But I don't know how you'd implement a promise in Javascript -- you can't really do coroutines like that, AFAIK |
| 02:19 | emezeske | Maybe if there was a Thread/yield function or something that let the event loop run |
| 02:21 | emezeske | But, JS doesn't have a yield function. If it did, there could be a lot less callback soup |
| 02:21 | Sgeo | It's not a question of implemeting them, it's a question of using them usefully. |
| 02:21 | Sgeo | A promise could be as simple as a mutable container that contains either no value or a value. |
| 02:22 | Sgeo | deliver sets the value if there is no value |
| 02:22 | emezeske | I'm pretty sure that's not what a promise is in clojure. |
| 02:23 | Sgeo | Although then what would deref do if there is no value... "blocking" would not be ... helpful |
| 02:23 | emezeske | It's totally pointless, you can't do that in JS |
| 02:23 | Sgeo | emezeske, hmm? |
| 02:23 | Sgeo | (The "hmm" as to "not what a promise is") |
| 02:24 | emezeske | I was saying that a promise as just a "mutable container that contains eithe rno value or a value" is not what a promise is in Clojure |
| 02:24 | emezeske | The key feature of a promise in Clojure is that it "Calls to deref/@ prior to delivery will |
| 02:24 | emezeske | block" |
| 02:24 | emezeske | Which you can't do in JS, so it's pointless. |
| 02:25 | Sgeo | Hmm... I'm sure someone has written continuation stuff for Clojure, that should be portable to ClojureScript right? |
| 02:27 | emezeske | The closest thing I know of to continuation passing in Clojure is trampoline |
| 02:28 | emezeske | Which should work fine in ClojureScript |
| 02:28 | amalloy | $google clojure delimc |
| 02:28 | lazybot | [swannodette/delimc · GitHub] https://github.com/swannodette/delimc |
| 02:30 | emezeske | Neato! |
| 02:30 | amalloy | do cljs atoms support watchers? if so you can build promise on top of that |
| 02:30 | ibdknox | amalloy: yes |
| 02:30 | emezeske | amalloy: How would that work? |
| 02:31 | amalloy | emezeske: actually, i think the thing i was thinking of uses promises to get blocking, so not really a viable implementation strategy for getting promises |
| 02:31 | ibdknox | you can't do it without code-rewriting |
| 02:32 | emezeske | amalloy: Yeah, the blocking-until-available part is what kills promises for the JS target |
| 02:32 | emezeske | amalloy: Even if you made deref just poll, you'd be tying up the only thread |
| 02:32 | ibdknox | you need a CPS transformer :) |
| 02:32 | emezeske | ibdknox: Yeah, it would have to turn your code into continuations behind the scenes |
| 02:32 | ibdknox | that's how the C# async stuff was done |
| 02:32 | amalloy | emezeske: presumably we've made an ajax call that's set to call something when it's completed? i don't do a lot of js, but i thought that's what people did? |
| 02:33 | emezeske | amalloy: Yeah, but if you made that async ajax call and then, e.g. went into an infinite loop, you'd never get the result |
| 02:33 | emezeske | amalloy: There's no preempting, nor yield |
| 02:33 | amalloy | for what it's worth, i was thinking of https://github.com/flatland/useful/blob/develop/src/useful/state.clj#L53, which lets you block until a reference's value satisfies some condition: (wait-until evel? my-atom) |
| 02:34 | amalloy | even? |
| 02:35 | emezeske | So desu |
| 02:36 | emezeske | Hey, it's meta-circular. Just use promises to implement themselves, QED. |
| 02:37 | emezeske | If only clojure was a native browser language... |
| 02:37 | emezeske | Or really anything less stupid than JavaScript |
| 02:38 | Sgeo | Dart? |
| 02:38 | tomoj | I think it shouldn't be too hard to port lamina's async macro to cljs |
| 02:39 | tomoj | but I feel like future seqs (better channels) are more important anyway |
| 02:39 | emezeske | Sgeo: Heh, NaCl running a java vm running clojure? Hell yeah. |
| 02:39 | emezeske | Yo dawg... |
| 02:41 | Sgeo | "Why is it so bad with many threads you might wonder. Well, first of all they are expensive, both in the JVM and on .NET." |
| 02:41 | Sgeo | :/ |
| 02:41 | Sgeo | Haskell has rather lightweight threading |
| 02:42 | emezeske | Java threading may not be the lightest weight thing ever, but I think quite a few shops get by with ridiculous numbers of threads |
| 02:43 | emezeske | Anyway, pooling often makes more sense anyway. Even greenlets have some overhead. |
| 02:49 | nkkarthik | In lein2 project.clj, how can I include some jars in the lib folder? |
| 02:51 | amalloy | ~repeataibility |
| 02:51 | wmealing_ | i used lein-localrepo |
| 02:51 | clojurebot | Titim gan ?ir? ort. |
| 02:51 | amalloy | ~repeatability |
| 02:51 | clojurebot | repeatability is crucial for builds, see https://github.com/technomancy/leiningen/wiki/Repeatability |
| 02:51 | wmealing_ | but i a agree with amalloy |
| 02:51 | wmealing_ | you'll get less suck if you make it work.. ie publish your jars |
| 02:52 | amalloy | don't agree with me, that's technomancy's article. i mean, i basically agree with it, but even if you disagree you should read: iirc it includes workarounds, as well as an explanation of why you shouldn't use them |
| 02:55 | Sgeo | Workarounds? |
| 02:55 | nkkarthik | wmealing_, amalloy... thank you... so there is only the holy approach |
| 02:56 | Sgeo | I take it things like Smalltalk and certain Common Lisp implementations are poisonous? |
| 02:56 | wmealing_ | Sgeo: localrepo, |
| 02:57 | Sgeo | iirc SBCL was forked from CMU CL in order to have a cleaner build process |
| 02:57 | wmealing_ | is it easy to run your own .. clojars ? |
| 02:57 | nkkarthik | what's the harm in quickly testing out a jar? |
| 02:58 | nkkarthik | why have a repl then... repl is neither used in build or production |
| 03:00 | nkkarthik | I think, tool should allow good practices not mandate them with one holy approach |
| 03:00 | nkkarthik | but I might be wrong |
| 03:00 | nkkarthik | anyways thank you guys... and sorry if I have said something wrong out of ignorance |
| 03:01 | nkkarthik | I will look at the localrepo |
| 03:09 | emezeske | nkkarthik: I gather that :extra-classpath-dirs was something of a pain from a support perspective /speculation |
| 03:11 | nkkarthik | emezeske: oh... you mean for lein developers or extra-classpath-dirs users? |
| 03:12 | devn | ,(require '[clojure.pprint :as pp]) |
| 03:12 | clojurebot | nil |
| 03:12 | emezeske | nkkarthik: For developers. |
| 03:12 | emezeske | Pure speculation on my part, though. |
| 03:13 | nkkarthik | emezeske: oh ok |
| 03:13 | devn | (with-out-str (pp/with-pprint-dispatch pp/code-dispatch (pp/pprint (read-string "(let [f (^:once fn* [x] x)] [(f 1) (f 2)])"))) |
| 03:14 | devn | ,(with-out-str (pp/with-pprint-dispatch pp/code-dispatch (pp/pprint (read-string "(let [f (^:once fn* [x] x)] [(f 1) (f 2)])"))) |
| 03:14 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading> |
| 03:14 | devn | ,(with-out-str (pp/with-pprint-dispatch pp/code-dispatch (pp/pprint (read-string "(let [f (^:once fn* [x] x)] [(f 1) (f 2)])")))) |
| 03:14 | Sgeo | Why are macros not allowed in the sandbox? |
| 03:14 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol> |
| 03:14 | nkkarthik | emezeske: thank you... I will try out something else then |
| 03:14 | hyPiRion | Sgeo: Macros are allowed, but defs aren't |
| 03:14 | Sgeo | &(defmacr sg-macro []) |
| 03:14 | lazybot | java.lang.RuntimeException: Unable to resolve symbol: defmacr in this context |
| 03:14 | Sgeo | &(defmacro sg-macro []) |
| 03:14 | lazybot | java.lang.SecurityException: You tripped the alarm! def is bad! |
| 03:14 | hyPiRion | afaik |
| 03:14 | Sgeo | Oh |
| 03:15 | devn | can anyone help me figure out the above mystery |
| 03:15 | devn | Is it complaining about the (^:once...) |
| 03:15 | hyPiRion | ,(with-out-str (pp/with-pprint-dispatch pp/code-dispatch (pp/pprint (read-string "(let [f (fn* [x] x)] [(f 1) (f 2)])")))) |
| 03:15 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol> |
| 03:15 | Sgeo | |
| 03:15 | hyPiRion | doesn't look like it. |
| 03:16 | devn | the use of fn* is weird |
| 03:16 | hyPiRion | devn: oh, blimey |
| 03:17 | devn | ,(fn* [x] (+ x 1)) |
| 03:17 | clojurebot | #<sandbox$eval135$fn__136 sandbox$eval135$fn__136@695d9f0> |
| 03:17 | devn | ,((fn* [x] (+ x 1)) 100) |
| 03:17 | clojurebot | 101 |
| 03:17 | hyPiRion | ,(with-out-str (pp/with-pprint-dispatch pp/code-dispatch (pp/pprint (read-string "(let [f (^:once fn* ([x] x))] [(f 1) (f 2)])")))) |
| 03:17 | clojurebot | "(let [f (fn* ([x] x))] [(f 1) (f 2)])\n" |
| 03:17 | Sgeo | What's fn*? |
| 03:17 | devn | hyPiRion: except! |
| 03:17 | devn | the former is valid clojure |
| 03:18 | hyPiRion | yeah, I noticed. |
| 03:18 | devn | ,(let [f (^:once fn* [x] x)] [(f 1) (f 2)]) |
| 03:18 | clojurebot | [1 2] |
| 03:18 | hyPiRion | ,(let [f (^:once fn* [x] x)] (mapv f [1 2])) |
| 03:18 | clojurebot | [1 2] |
| 03:18 | devn | :( |
| 03:18 | noidi | ,(doc fn*) |
| 03:18 | clojurebot | Excuse me? |
| 03:19 | devn | ,(use 'clojure.repl) |
| 03:19 | clojurebot | nil |
| 03:19 | devn | ,(doc fn*) |
| 03:19 | clojurebot | No entiendo |
| 03:19 | hyPiRion | $source fn* |
| 03:19 | lazybot | Source not found. |
| 03:19 | devn | fn* is internal |
| 03:19 | devn | but obviously not that internal |
| 03:20 | hyPiRion | It's in the clojure/java transition area, isn't it? |
| 03:20 | devn | transition area? |
| 03:20 | devn | (yes if you mean what i think you mean) |
| 03:21 | hyPiRion | the area where clojure fns are written in java |
| 03:21 | hyPiRion | or converted/parsed |
| 03:21 | amalloy | &(macroexpand-1 '(fn [x] x)) |
| 03:21 | lazybot | ⇒ (fn* ([x] x)) |
| 03:21 | amalloy | fn* forms are always generated with the wrapped parens, so pprint probably relies on that. if you're creating fn* forms yourself, you probably shouldn't be |
| 03:22 | amalloy | oh, except that the lazy-seq macro generates the thing you pasted? |
| 03:22 | devn | amalloy: *nod* I think so |
| 03:22 | amalloy | it does. i don't really use pprint much, so i'm not bothered or surprised that it's broken |
| 03:23 | devn | amalloy: im not bothered or surprised either, but i figure it was worth asking |
| 03:23 | devn | well, let me elaborate |
| 03:23 | devn | i was surprised, but after talking it out I'm not bother, nor do I think it is generally surprising |
| 03:24 | devn | bothered* |
| 03:27 | devn | amalloy: thanks for the help |
| 03:27 | devn | amalloy: clojure/conj this year? |
| 03:28 | amalloy | not planning on it |
| 03:28 | devn | :( |
| 03:30 | magopian | man kodowa is recruiting |
| 03:30 | magopian | that is just so awesome |
| 04:00 | Sgeo | How careful do I have to be to avoid accidentally rebinding functions? |
| 04:00 | Sgeo | I know Lisp-2 proponents say things like they like not having to name variables lst, but what if you do in Clojure name a variable list? |
| 04:00 | Sgeo | In a local binding, I mean? |
| 04:01 | hyPiRion | Sgeo: it's not a problem |
| 04:01 | hyPiRion | ,(let [list '[a-list of elements]] (println list)) |
| 04:01 | clojurebot | [a-list of elements] |
| 04:02 | hyPiRion | ,(let [f (fn [a] (let [list [1 2 3]] (a list)))] (f list)) |
| 04:02 | clojurebot | ([1 2 3]) |
| 04:02 | Sgeo | Hmm. Suppose a macro expands into some code that uses list, and you've rebound list like that? |
| 04:02 | Sgeo | And use the macro from within there? |
| 04:03 | hyPiRion | Use gensyms if that's a problem |
| 04:03 | amalloy | Sgeo: then the macro is badly written |
| 04:03 | Sgeo | ...for using the list function? |
| 04:03 | amalloy | &`(list 1 2 3) |
| 04:03 | lazybot | ⇒ (clojure.core/list 1 2 3) |
| 04:03 | hyPiRion | Oh, right |
| 04:03 | hyPiRion | they are namespaced, so it shouldn't be a problem |
| 04:03 | hyPiRion | unless you go full retard with ##`(,'list 1 2 3) it should be okay |
| 04:03 | lazybot | ⇒ ((quote clojure.core/list) 1 2 3) |
| 04:04 | hyPiRion | ,`(~'list 1 2 3) |
| 04:04 | clojurebot | (list 1 2 3) |
| 04:04 | hyPiRion | i mean. |
| 04:05 | Chousuke | usually hygiene isn't a problem with clojure macros |
| 04:05 | Sgeo | &(let [list '(1 2 3)] (namespace 'list)) |
| 04:05 | lazybot | ⇒ nil |
| 04:05 | Sgeo | (namespace 'list) |
| 04:05 | Sgeo | &(namespace 'list) |
| 04:05 | lazybot | ⇒ nil |
| 04:07 | Chousuke | it's difficult to screw things up so that you get hidden misbehaviour |
| 04:08 | hyPiRion | Chousuke: Well, yeah, as long as you know about gensyms, you should be fine |
| 04:08 | Chousuke | you don't even need gensyms, though they make things easier. |
| 04:08 | hyPiRion | Oh, you do. |
| 04:08 | Sgeo | Uh. I think writing macros without knowing gensyms is probably a recipe for failure. |
| 04:08 | Chousuke | oh, wait, yeah. I was thinking of autogensyms |
| 04:09 | hyPiRion | Well, autogensyms are just syntactic sugar. But it's very clean though. |
| 04:10 | Chousuke | it's a good feature. no point in leaving it out :) |
| 04:11 | hyPiRion | Clojure itself seems like the royal bathroom if you compare it to common lisp. |
| 04:12 | Sgeo | There are some things in Common Lisp I like. The ability to rename namespaces, the condition system |
| 04:12 | Chousuke | The best feature Clojure has is all the features together. :P |
| 04:12 | Chousuke | none of them alone is anything earth-shattering but the way Clojure combines everything just works nicely. |
| 04:13 | Sgeo | And then protocols get thrown in the mix in a non-interchangeable way with multimethods |
| 04:14 | Chousuke | how could they be interchangeable? |
| 04:14 | Chousuke | besides both creating functions as the interface. |
| 04:14 | Sgeo | Well, protocols could be built on top of multimethods in a clear way. |
| 04:15 | Chousuke | no they couldn't. |
| 04:15 | Chousuke | they wouldn't perform well enough |
| 04:15 | tomoj | :D |
| 04:15 | Chousuke | the whole point of having protocols in addition to multimethods is performance :P |
| 05:40 | nz- | what is the home row? |
| 05:42 | hughfdjackson | asdfjkl; |
| 05:42 | hughfdjackson | nz-: isn't it those keys on your keyboard? ^ |
| 05:43 | hughfdjackson | asdf on your left hand, jkl; on your right; where your fingers should (in theory) rest |
| 05:43 | hughfdjackson | :3 or am i wildly off the mark here? |
| 05:43 | magopian | hughfdjackson: i would have answered nearly the exact same |
| 05:43 | magopian | nz-: the "home row" is the middle row, the one which has two keys with "bumps" on them |
| 05:44 | magopian | those keys are where the index of both your hands should 'rest' |
| 05:44 | nz- | goofed with irc history, somebody answered already |
| 06:00 | Sgeo | Is Clojure arithmatic really supposed to take 1/10th of a second? |
| 06:00 | Sgeo | Clojure> (time (* 1 1)) |
| 06:00 | Sgeo | "Elapsed time: 103.083431 msecs" |
| 06:01 | Sgeo | (On tryclj.com ) |
| 06:01 | magopian | $(time - |
| 06:01 | magopian | $(time (* 1 1)) |
| 06:02 | magopian | a(time (* 1 1)) |
| 06:02 | magopian | &(time (* 1 1)) |
| 06:02 | lazybot | ⇒ "Elapsed time: 221.855607 msecs" 1 |
| 06:02 | magopian | &(time (* 1 1)) |
| 06:02 | lazybot | ⇒ "Elapsed time: 225.222137 msecs" 1 |
| 06:02 | magopian | mmmm |
| 06:02 | magopian | that looks long indeed |
| 06:02 | magopian | maybe the repl is fired up each time? |
| 06:07 | algernon | probably some sandbox. |
| 06:08 | algernon | it's 0.025 locally (clojure 1.3) |
| 06:22 | Raynes | Sgeo: tryclojure and lazybot are completely worthless for benchmarking. The sandbox adds code and such. |
| 06:22 | Raynes | magopian: ^ |
| 06:49 | magopian | Raynes: thanks a lot for the information ;) |
| 07:28 | Sgeo | Is it possible for the same jar to have two different versions of a library? |
| 07:28 | Sgeo | Say, if my code uses library A which relies on X version 1 and library B which relies on X version 2 |
| 07:32 | Scorchin | I'm trying to write a crawler that will check that all links on pages for a given domain (e.g. mysite.com) are valid (return status 200 OK). I have an idea of what I'd like to achieve, but I'm not sure how to make it concurrent. Currently I'm starting with a set of URLs that I call, check their status, and then get a list of URLs for the same domain on the page which I add to the set to be checke |
| 07:32 | Scorchin | d. What are the best ways to tackle this in a Clojure-like way? |
| 07:33 | Scorchin | I was originally thinking about using futures, but that could bloat the number of threads |
| 07:36 | jml | I'm feeling a bit dense. How do I specify jenkins (org.jenkins-ci.jenkins) as a dependency in leiningen? |
| 07:36 | jml | I've got :repositories [["jenkins" "http://repo.jenkins-ci.org/public/"]] in my project.clj |
| 07:37 | jml | and [org.jenkins-ci/jenkins "1.26"] in the :dependencies vector |
| 07:37 | jml | and http://repo.jenkins-ci.org/public/org/jenkins-ci/jenkins/ seems to be there, merrily existing away |
| 07:38 | jml | but I get 'Could not find artifact org.jenkins-ci:jenkins:jar:1.26 in jenkins (http://repo.jenkins-ci.org/public/)' during 'lein run' |
| 07:51 | xeqi | jml: http://repo.jenkins-ci.org/public/org/jenkins-ci/jenkins/1.26/ only has a pom, so you might try :extension "pom" |
| 07:52 | Sgeo | I'm going to have to learn what a pom is, aren't I? |
| 07:52 | Sgeo | :/ |
| 07:52 | xeqi | Sgeo: not usually. The jvm loads the first instance of the class it finds on the classpath, so having v1 and v2 leads to bad interaction |
| 07:53 | Sgeo | xeqi, :/ |
| 07:53 | xeqi | not usually |
| 07:53 | Sgeo | I think the last time I actually liked/wanted/anything'd the JVM or the JDK was as a kid |
| 07:53 | Sgeo | I was excited by a book about Java that I bought, since I didn't see any other ways to start programming for free. |
| 07:54 | Sgeo | I eventually found Python, which was the first time I actually started writing code outside of Visual Basic and VBA |
| 07:54 | xeqi | how does python handle having two of the same library? |
| 07:55 | jml | xeqi: it takes the first thing it finds on sys.path |
| 07:55 | xeqi | sounds like the same thing to me |
| 07:55 | Sgeo | My Python mention was a tangent |
| 07:58 | magopian | poor lad, vb and vba |
| 07:58 | magopian | :) |
| 08:06 | clgv | Scorchin: you can use java's ExecutorSevices |
| 08:09 | Sgeo | I feel like I'm going to end up learning way more than I ever wanted to know about Java. |
| 08:12 | clgv | Sgeo: do not complain to soon about vague feelings ;) |
| 08:34 | llasram | Sgeo: I felt the same way at first, and everyone knows about the amazingly bad parts of the Java standard library and Java frameworks, but there's some amazingly high-quality parts too |
| 08:35 | Sgeo | Clojure wouldn't happent to have built-in not-blatent-Java-FFI file access, would it? |
| 08:35 | Sgeo | *happen |
| 08:35 | llasram | If you look at Clojure's concurrency support, it's pretty interesting how much of it is just bolting the STM to a thin veneer over the Java standard library concurrency libraries |
| 08:35 | antares_ | Sgeo: clojure.java.io |
| 09:02 | jsabeaudry | Is there anything besides lein-deps-tree that will print a dependency tree for my project? (lein-deps-tree crashes on a could not locate leiningen/core/classpath__init....) |
| 09:02 | llasram | jsabeaudry: lein2, `lein deps :tree` ? Or is that what you're talking about? |
| 09:02 | clgv | jsabeaudry: lein2 deps :tree - but only for leiningen2 |
| 09:03 | jsabeaudry | Oh yes, for lein 1.7.1, I'm still waiting for the official release before I move to lein2 |
| 09:04 | Raynes | There isn't a real reason to do that. |
| 09:04 | llasram | I'd suggest going ahead and switching. My understanding is that the only reason technomancy hasn't done an official 2.0 release is because he's waiting on new clojars infrastructure. It's not because the lein2 codebase isn't ready |
| 09:05 | Raynes | Pretty much everyone has moved already and lein 2 is generally complete. |
| 09:06 | Raynes | But if you insist on using old lein, mvn dependency:tree should work with your lein-generated pom.xml file. |
| 09:07 | pyykkis | has anyone installed lein2 with homebrew? I wonder if there's an updated recipe somewhere or should I make pull req |
| 09:10 | clgv | pyykkis: what was different from normal lein installation with homebrew? |
| 09:10 | Raynes | The commands used. *shrug* |
| 09:11 | Raynes | Oh, never mind. Misunderstood the question. |
| 09:12 | pyykkis | oh, and one can actually install 2.x with 'brew install leiningen --HEAD' |
| 09:15 | pyykkis | clgv: it's pretty much the same under the hood, just easier with homebrew one-liner |
| 09:15 | pyykkis | https://github.com/mxcl/homebrew/blob/master/Library/Formula/leiningen.rb |
| 09:16 | pyykkis | I wasn't awere of --HEAD flag, though. Maybe it's time to actually read homebrew docs.. |
| 09:18 | clgv | pyykkis: well, that seems to get you 1.7.1 |
| 09:24 | Sgeo | Don't have time to fix my copy of labrepl now, but when I get it working, does it provide a REPL in the browser, or will it expect me to do it in the REPL I launch labrepl from? |
| 09:28 | pyykkis | clgv: hm...works on my laptop? |
| 09:28 | pyykkis | $ lein version |
| 09:28 | pyykkis | Leiningen 2.0.0-SNAPSHOT on Java 1.7.0_05 Java HotSpot(TM) 64-Bit Server VM |
| 09:29 | clgv | pyykkis: I just read the link where 1.7.1 was explictely named. maybe there is some magic besides that. |
| 09:29 | clgv | I have not the slightest idea of how homebrew works ;) |
| 09:31 | pyykkis | clgv: there's also 'head' defined in the homebrew recipe, which points to master branch |
| 09:32 | pyykkis | ..which is used with 'brew install leiningen --HEAD' |
| 09:32 | clgv | ah ok. |
| 09:37 | Sgeo | If I'm on JRE 7 why does (javadoc System) bring me to the thing for 6? |
| 09:38 | hyPiRion | $source javadoc |
| 09:38 | lazybot | Source not found. |
| 09:38 | xeqi | pyykkis: that is a weird lein version number |
| 09:41 | robermann | Sgeo: http://clojuredocs.org/clojure_core/clojure.java.javadoc/javadoc |
| 09:42 | xeqi | pyykkis: I have a suspicion that your getting the 4month old -SNAPHSHT on https://github.com/technomancy/leiningen/downloads |
| 09:42 | pyykkis | xeqi: well..yeah, it isn't any of the previews, it's the HEAD from master branch https://github.com/technomancy/leiningen/blob/master/project.clj#L4 |
| 09:43 | xeqi | right, but I don't see the homebrew script bootstrapping lein |
| 09:43 | xeqi | just calling self-install, which pulls from the github download page |
| 09:44 | naeg | how often do you actually use -> and ->> in real code? like (f (g v)) instead of (-> v g f) |
| 09:44 | pyykkis | xeqi: ah..thanks, I haven't even looked so far. Maybe I'll do manual install then, afterall. |
| 09:45 | xeqi | -> is not uncommon, ->> is rarer |
| 09:46 | pyykkis | naeg: more often than not. I'd be close to say "always" |
| 09:46 | naeg | is it rarer because people just don't need ->> that often or because peopl like to write it out instead of using ->>? |
| 09:47 | xeqi | I usually start using -> when I get to a chain of 3 |
| 09:47 | naeg | do other lisp's have this too? I can't remember such a macro from CL |
| 09:47 | antares_ | naeg: -> is pretty commonly used. In the example you've demonstrated I just do (f (g v)), though |
| 09:47 | xeqi | ->> is rarer cause things like assoc are designed for -> |
| 09:47 | robermann | Sgeo: maybe you should check/set the *remote-javadocs* var |
| 09:49 | jweiss | would it be frowned upon to use the extensible reader to create a group of common imports (eg, require's, use's)? like (ns blah #=(my-common-stuff-a) #=(my-common-stuff-b)) |
| 09:50 | jsabeaudry | ,(str (doall (map int [1 2 3 4]))) |
| 09:50 | clojurebot | "clojure.lang.LazySeq@e93c3" |
| 09:51 | S11001001 | ,(str (proxy [Object] [] (toString [] nil))) ; my favorite, jsabeaudry |
| 09:51 | clojurebot | nil |
| 09:52 | jsabeaudry | S11001001, Looks good, unfortunately I cannot really appreciate it as I am not familiar with proxy :( |
| 09:53 | jsabeaudry | Ah, I think I get it, str call tostring and you deined an bject that returns nil when you call tostring on it? |
| 09:53 | hyPiRion | ,(= (proxy [Object] [] (equals [x] 'foobar)) nil) |
| 09:53 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.UnsupportedOperationException: nth not supported on this type: Symbol> |
| 09:54 | S11001001 | hyPiRion: sorry, there's only one trick :) |
| 09:54 | hyPiRion | S11001001: Apparently. |
| 09:54 | chouser | jweiss: that's an interesting idea. Certainly not one I've seen. |
| 09:54 | S11001001 | ,(let [snil (proxy [Object] [] (toString [] nil))] (str snil snil)) |
| 09:54 | clojurebot | #<NullPointerException java.lang.NullPointerException> |
| 09:54 | chouser | jweiss: where would my-common-stuff-a be defined? |
| 09:54 | S11001001 | neat |
| 09:55 | S11001001 | ,(let [snil (proxy [Object] [] (toString [] nil))] (-> snil str str)) |
| 09:55 | clojurebot | "" |
| 09:56 | S11001001 | the point of this being that ∃v. (str v) ≠ (str (str v)) |
| 09:57 | jweiss | chouser, it'd be a function in some other namespace. i suppose i'd have to refer to it by its fully qualified name and ensure that it's already loaded. |
| 10:04 | augustl | anyone know how to get the raw Set-Cookie headers from clj-http? It seems to remove them from :headers and add the parsed result to :cookies |
| 10:04 | chouser | jweiss: yeah, interesting. The 'ns' block was supposed to be declarative so as to support tooling in general, and such use of #=() might break that. ...but I'm not aware of any tools that read the ns block anyway, so *shrug* |
| 10:06 | jweiss | chouser, declarative meaning a literal list and no calculated values? |
| 10:07 | chouser | well, yeah -- that's why you're having to use #=(), because the bodies are essentially quoted for you |
| 10:08 | augustl | can't find any reference to :cookies anywhere in the code of clj-http, weird |
| 10:08 | chouser | and also declarative in that ns uses :require instead of the symbol require |
| 10:08 | jeremyheiler | augustl: if you don't need the wrap-cookies middleware, you can remove it. |
| 10:08 | jeremyheiler | it's in src/clj_http/cookies.clj |
| 10:08 | augustl | ugh, was looking at someones fork on github |
| 10:08 | augustl | or something like that |
| 10:08 | jeremyheiler | ah lol |
| 10:09 | augustl | do I need to build my own set of middlewares from scratch? |
| 10:12 | augustl | by reading https://github.com/dakrone/clj-http/blob/0.5.3/src/clj_http/cookies.clj#L129 you'd think setting :cookie-store to false in the request would do the trick, but that doesn't seem to help |
| 10:13 | jeremyheiler | yeah, the wrap-cookies function is the culprit. |
| 10:13 | jeremyheiler | more specifcally, decode-cookie-header |
| 10:13 | augustl | ugh, when :cookie-store is falsy, it wil use its own internal one |
| 10:16 | jeremyheiler | would it be possible just to encode the cookie again? |
| 10:19 | augustl | probably yeah |
| 10:20 | jeremyheiler | that's probably the less painful solution |
| 10:21 | robermann | in emacs, is there a way to do a "in-ns" to the namespace in the currently open .clj file? |
| 10:23 | robermann | never mind, found it: C-c M-p |
| 10:23 | robermann | (I was wrongly remembering C-c C-z) |
| 11:12 | estebann | is there any easy way to prevent c3p0 from spewing stuff into the repl? it makes useful output hard to find... |
| 11:16 | ohpauleez | lynaghk: ping |
| 11:20 | nz- | I think that c3p0 prints stuff via log4j so add log4j.xml under test. configure that log4j.xml so that nothing is printed to STDOUT |
| 11:21 | estebann | nz-: cool, thanks |
| 11:23 | nz- | estebann: example of suitable log4j.xml is here |
| 11:23 | nz- | https://github.com/korma/Korma |
| 11:23 | estebann | nz-: nice, thanks again |
| 11:24 | naeg | is someone aware of a bigger game written in a functional language? preferably clojure, but doesn't have to be |
| 11:25 | ejackson | dammit - laziness kicks my arse *again* ! |
| 11:25 | psii | naeg: what do you mean by "bigger"? |
| 11:27 | jml | what do I need to add to my projects.clj to be able to depend on Jenkins (in order to be able to make a jenkins plugin)? (a pom.xml here: http://paste.ubuntu.com/1170038/; generated by following instructions at https://wiki.jenkins-ci.org/display/JENKINS/Plugin+tutorial#Plugintutorial-SettingUpEnvironmen) |
| 11:29 | naeg | psii: just more than a few hundred lines |
| 11:29 | psii | naeg: http://joyridelabs.de -- although in haskell |
| 11:29 | naeg | psii: the actual question is whether the functional style could extend to larger (2d) games |
| 11:29 | psii | well then, this link is for you :) |
| 11:30 | naeg | thanks psii |
| 11:31 | jml | I think I'm just a vanilla fool |
| 11:39 | xeqi | jml: you might be able to figure it out by reading https://github.com/pyr/jenkins-leiningen 's pom |
| 11:40 | xeqi | though I'm not sure there is an equivalent for plugin-repositories ... |
| 11:41 | jml | xeqi: thanks. I'm looking for an equivalent projects.clj, but I think I've got something that's working well enough for me to move on to the next problem :) |
| 11:41 | xeqi | I think you could use :pom-additions for that, but its prolly not well documented |
| 11:41 | jml | is there a syntax for importing inner classes? |
| 11:41 | xeqi | OuterClass$InnerClass |
| 11:42 | jml | thanks |
| 11:44 | TimMc | jml: Inner classes are a Java lie. :-) |
| 11:45 | TimMc | s/lie/concept/ |
| 11:46 | unlink | `lein ring server` takes a shocking long time to start (~15 seconds), and code reloading is anything but infallible. How do people work around this? |
| 11:47 | weavejester | unlink: There's something wrong with the code reloading I need to look into. I suspect the namespace dependencies aren't being calculated correctly. |
| 11:48 | unlink | Oh, OK. |
| 11:48 | weavejester | unlink: In the meantime, you could always start a server in a REPL and reload manually |
| 11:49 | unlink | How would I do that? |
| 11:49 | weavejester | unlink: (run-jetty your-handler {:join? false :port 3000}) |
| 11:49 | weavejester | unlink: And then (require 'your.namespace :reload-all) |
| 11:50 | unlink | oh, great. I'll try that. |
| 11:50 | brainproxy | I like to do it the other way around; I use `lein ring server ...` to fire up the dev server, and inside whatev.core I fire up a repl server which I can connect to from emacs |
| 11:50 | augustl | unlink: I've had problems with code reloading as well, for what it's worth :) |
| 11:50 | augustl | so you're not alone |
| 11:51 | weavejester | It probably won't be too long until I fix the namespace reloading, as I'm getting bored of it myself. |
| 11:51 | augustl | some times I get a 500 error in the form of a blank page, and then on the next request everything works, as it was before I changed the code and introduced the error. I very rarely get the stack trace etc. |
| 11:51 | weavejester | I suspect the problem is in the ns-tracker library |
| 11:51 | weavejester | augustl: That indicates a compile error. e.g. the require itself is failing |
| 11:52 | augustl | ah, I see |
| 11:52 | weavejester | augustl: And because the require throws an exception, it's not loading the new code. |
| 11:52 | thorbjornDX | Is there a well-defined C interface for clojure/java? |
| 11:52 | augustl | in this case I'm one of those "I don't care I just want it to work" peeps :) |
| 11:52 | weavejester | augustl: Hm, but… I guess I could say that if there's an exception, it keeps trying to reload so you get the same error and it's not lost when you refresh. |
| 11:53 | augustl | that would rock :D |
| 11:53 | augustl | would ofc also be nice if some kind of error could be displayed on the page |
| 11:53 | weavejester | augustl: Don't you get a stacktrace? |
| 11:53 | augustl | quite often it's just a blank page |
| 11:54 | augustl | and then the "previous version" on subsequent requests, until restart |
| 11:54 | weavejester | Maybe the stacktrace middleware is below the reload middleware. So if there's an error requiring the file, the stacktrace middleware won't catch it. |
| 11:55 | weavejester | Yeah, it is. |
| 11:55 | augustl | ah |
| 11:55 | weavejester | That's an easy fix at least. |
| 11:55 | augustl | so apparently code reloading is not black magic, it's just code like everything else? |
| 11:55 | weavejester | augustl: Yes :) |
| 11:57 | weavejester | In a nutshell it looks for modified files when a new request comes in, then uses ns-tracker to calculate any dependencies. For instance, if namespace A is changed, but namespace B requires A, then both A and B need to be reloaded. |
| 11:57 | weavejester | Then it reloads the namespaces with (require namespace :reload) |
| 11:58 | weavejester | The stacktrace middleware is designed to catch exceptions and display a nice stacktrace, but the stacktrace middleware is currently placed below the reload middleware |
| 11:58 | weavejester | So if a require fails because there's a syntax error (for example), then there won't be a stacktrace. |
| 11:59 | weavejester | I suspect there's also a problem with the namespace tracking in ns-tracker. I'm finding that dependent namespaces aren't being reloaded all the time. |
| 12:00 | weavejester | BTW, if anyone has problems with Lein-Ring or whatever, raise an issue on Github. |
| 12:05 | llasram | weavejester: Oh, BTW, lein2 now has support for explicit framework-provided dependencies via a :provided profile. I contributed it for Hadoop job JAR building, but my hope is that it'll simplify things like WAR construction |
| 12:10 | weavejester | llasram: Thanks for the info |
| 12:29 | hughfdjackson | other than the ability to define records that can have protocols defined for them, doesn't defrecord seem a slightly second-rate way to define datastructures? |
| 12:29 | hughfdjackson | as far as I can tell, it doesn't seem to support named fields on construction |
| 12:30 | hughfdjackson | which ends up with ordered params instead |
| 12:30 | hughfdjackson | :D i'm thinking that i probably misunderstood this |
| 12:31 | technomancy | yeah, don't use records if you can get away with multimethods |
| 12:31 | technomancy | multimethods and maps, rather |
| 12:31 | llasram | And if you do need them, the work-around is that you have a Clojure factor function rather than directly use the JVM class constructor |
| 12:31 | llasram | s,factor,factory, |
| 12:31 | hughfdjackson | hrm, drat |
| 12:32 | augustl | I'm mostly using records when I need "private" data structures |
| 12:32 | augustl | i.e. where initialization only happens one or two places, in the same namespace |
| 12:32 | hughfdjackson | is it the 'named type rather than duck type' side of it that irks, or is it the problem with instantiating them without key:val pairs that i mentioned? |
| 12:32 | llasram | Yeah. I really really wish deftype let you specify custom constructors. I'd let me ditch most of the remaining cases where I need to squiggle some Java into the codebase |
| 12:33 | Sgeo | I'm having problems with Eclipse |
| 12:33 | weavejester | I hate SQL so much |
| 12:34 | Sgeo | Surely there are things for Clojure that let you avoid using SQL directly? |
| 12:35 | weavejester | Sgeo: Yes, for querying and such, but less for generating schema. There's lobos, but it can't do everything. |
| 12:36 | llasram | SQL truly is the worst query language, except for all the others |
| 12:36 | technomancy | schema generation isn't even really standardized |
| 12:36 | weavejester | The main problem is that SQL syntax is such a horrific ball of mud that even the simplest things are difficult or impossible |
| 12:36 | nz- | what is missing from lobos? |
| 12:36 | weavejester | llasram: Actually… I can't think of a worse query language than SQL... |
| 12:37 | weavejester | nz-: It might be that lobos can actually do everything I want |
| 12:37 | weavejester | But "to keep it simple" I've gone with files of SQL for migrations |
| 12:37 | technomancy | nz-: I get the feeling it's just got too much |
| 12:38 | weavejester | The problem is that I forgot you can't execute multiple SQL statements of certain types in the same command |
| 12:38 | weavejester | And there doesn't appear to be any library to split them up in Java |
| 12:38 | weavejester | Or any language. |
| 12:38 | llasram | weavejester: Yeah, fair enough. Really the only contrast I'm familiar with is SQL over full relational data model vs. limited data-access API for much more constrained data model, which doesn't really cover the case of e.g. Datalog |
| 12:39 | weavejester | llasram: Admittedly most of the better query languages I can think of don't have as much functionality as SQL. |
| 12:39 | tvladeck1 | quick question; is there any way to use the "map" function in the new reducers library, if you don't actually need to reduce the result? |
| 12:40 | Bronsa | (into [] (r/map ..)) |
| 12:41 | tvladeck1 | cool; and does that achieve the same sort of fork/join goodness that exists in the "par" branch? |
| 12:41 | hughfdjackson | isn't the point of the reducers that all common forms of operations over sets can be 'reduced' (gettit) to a reduce with an appropriate fn? |
| 12:41 | Bronsa | into calls reduce |
| 12:41 | hughfdjackson | (:p this Q is more for me than for you) |
| 12:41 | weavejester | technomancy: I'm using the code you wrote for Ragtime ages ago. Did you happen to give any thought to putting more than one SQL statement in a migration file? |
| 12:42 | dnolen | hughfdjackson: not sure what you mean. |
| 12:42 | hughfdjackson | dnolen: i watched the rich hickey talk while i was kinda nodding off i'm afraid :# |
| 12:42 | technomancy | weavejester: not really; best I came up with was splitting on ;; and a big old "don't use ;; inside actual SQL" comment at the top |
| 12:42 | tvladeck1 | Bronsa: so into calls "reduce", but isn't it necessary to call "par/reduce" to get the advantage? |
| 12:42 | augustl | hughfdjackson: that's my impression as well. The actual units of work only describe what needs to be done with one item. Then there's a generic tool to parallelize the actual operation. |
| 12:43 | weavejester | technomancy: I was afraid of that :) |
| 12:43 | hughfdjackson | but i thought the point of it was that reduce an abstract operation that you can define reduce/map/each in terms of |
| 12:43 | technomancy | weavejester: but I also have experimented with doing it from Clojure itself: https://github.com/heroku/buildkits/blob/master/src/buildkits/db/migrate.clj |
| 12:43 | technomancy | the main downside there is you don't get syntax highlighting, which is awful and terrible |
| 12:43 | Bronsa | tvladeck1: they both call coll-reduce |
| 12:43 | tvladeck1 | ok got it |
| 12:43 | technomancy | but on the other hand data manipulation is a lot nicer |
| 12:44 | technomancy | and ordering too |
| 12:44 | weavejester | technomancy: True... |
| 12:44 | weavejester | technomancy: I'm currently turning Ragtime into a Lein plugin |
| 12:44 | technomancy | maybe a helper defn to load a single SQL statement from a file, but it lacks immediacy |
| 12:44 | technomancy | really? why's that? |
| 12:44 | technomancy | I don't see the point of running anything inside leiningen's process |
| 12:45 | weavejester | technomancy: Well, ragtime core wouldn't be changed |
| 12:45 | weavejester | But I was adding an extra ragtime.lein so you could run "lein migrate" |
| 12:45 | technomancy | you can do that easily already |
| 12:45 | technomancy | :aliases {"migrate" ["run" "-m" "ragtime.core"]} |
| 12:45 | weavejester | Hm. How? |
| 12:46 | weavejester | Hm… problem with that is that you have to write your own migrate code |
| 12:47 | technomancy | that doesn't mean that you have to run code inside leiningen's process though |
| 12:47 | technomancy | it's all still project-isolated |
| 12:47 | weavejester | Oh, I'm using eval-in-project |
| 12:47 | weavejester | So it's a very thin wrapper |
| 12:47 | technomancy | sure; but you should use eval-in-project via the run task rather than calling it directly |
| 12:48 | jweiss | does the extensible reader support spliciing? (eg, #foo/bar 1 -> 1 2 3 ) ? |
| 12:48 | weavejester | technomancy: Hm... |
| 12:48 | Bronsa | jweiss: dont think so |
| 12:49 | weavejester | So if one was making a plugin for Leiningen that primarily execute code in project |
| 12:49 | Sgeo | ECLIPSE PLEASE STOP BEING STUPID |
| 12:49 | weavejester | Perhaps instead of using eval-in-project, it would inject alieases instead into the project map |
| 12:49 | Sgeo | I'm trying to import labrepl |
| 12:49 | weavejester | Oh wait, that wouldn't work... |
| 12:49 | Sgeo | It complains that it overlaps another project: labrepl |
| 12:49 | Sgeo | I think it's downloading the files then noticing that there are files there |
| 12:50 | technomancy | weavejester: if you're going to have to add one line to project.clj for a :plugins entry why not add a line for :aliases instead? |
| 12:50 | weavejester | technomancy: Because you'd need lines for rollback as well, and some configuration too. |
| 12:50 | weavejester | Currently I have two config vars |
| 12:51 | Sgeo | Any help? |
| 12:51 | technomancy | weavejester: suggest loading config from resources |
| 12:51 | weavejester | :ragtime {:migrations ns.for.func.that/generates-migrations, :database "jdbc:h2:mem:test_db"} |
| 12:51 | technomancy | also: a single -main function can support migration and rollback |
| 12:52 | technomancy | lein run -m ragtime.main [REVISION] |
| 12:52 | weavejester | technomancy: That's an idea. lein run -m ragtime.main migrate |
| 12:52 | weavejester | technomancy: But I don't like the idea of scattering configs around. |
| 12:53 | technomancy | Leiningen has never encouraged using project.clj for runtime config |
| 12:53 | weavejester | I know |
| 12:53 | weavejester | But... |
| 12:54 | technomancy | I suspect any app nontrivial enough to need migrations is already going to have to be reading config from somewhere already |
| 12:54 | weavejester | There isn't a better alternative IMO. |
| 12:54 | bhenry | looks like someone needs to rewrite ants.clj http://news.stanford.edu/news/2012/august/ants-mimic-internet-082312.html |
| 12:54 | weavejester | technomancy: In production, that would be the environment, according to 12factor.net :) |
| 12:55 | weavejester | But in development... |
| 12:55 | weavejester | Adding configs to Lein profiles is very nice. |
| 12:56 | weavejester | So we either need to build a separate profile/config system |
| 12:56 | weavejester | Or we could tie into Leiningen's |
| 12:56 | weavejester | Although Lein isn't designed to be used in this fashion, I don't see why it couldn't be. |
| 12:57 | Frozenlock | `find' is to be used with a map, but is there an equivalent function for a collection? I want to check if I have a given item in a vector. |
| 12:58 | nDuff | Frozenlock: some? |
| 12:58 | xeqi | (some #{1} [2 3 4 1]) |
| 12:58 | weavejester | Frozenlock: some? |
| 12:58 | weavejester | technomancy: I like the idea of a ragtime.main though |
| 12:58 | Frozenlock | Yes! Thanks! |
| 12:59 | thorbjornDX | ,(some #{1} [2 3 4 1]) |
| 12:59 | clojurebot | 1 |
| 13:01 | thorbjornDX | ,(some #{:a :b} {:a 1 :b 2}) |
| 13:01 | clojurebot | nil |
| 13:01 | thorbjornDX | I guess that's where find is used? |
| 13:02 | Frozenlock | I guess I must be too used to elisp's find function. |
| 13:02 | thorbjornDX | Frozenlock: I'm used to python's 'in' |
| 13:02 | nDuff | ...the thing about 'in' is that it can behave in ways with wildly different performance characteristics |
| 13:03 | nDuff | whereas Clojure tends to have functions in its standard library with well-defined performance characteristics |
| 13:03 | Frozenlock | Eh python.... one day, one day :) |
| 13:03 | thorbjornDX | nDuff: yeah, it's hard to know what it's doing behind the scenes |
| 13:03 | nDuff | ...if you're using some, you _know_ that it's an O(n) operation. |
| 13:04 | technomancy | weavejester: yeah, some people are using project.clj for runtime config |
| 13:04 | thorbjornDX | 1 in [1, 2, 3, 4] is O(n), 1 in {1: 1, 2: 2, 3: 3, 4: 4} is O(1), yea? |
| 13:05 | nDuff | thorbjornDX: Exactly. |
| 13:05 | technomancy | it's this weird thing where I can't point to any specific reasons it's a bad idea; it's just that I haven't thought it all the way through yet. there are a lot of design decisions that were made without factoring it in at all |
| 13:05 | weavejester | technomancy: If it makes you feel better, I'm only using it in development :) |
| 13:06 | technomancy | I'm just wary because as soon as I start encouraging it I may push myself into a corner where there'd be some great feature I'd like to implement but can't because it doesn't jive with runtime-level config |
| 13:06 | weavejester | technomancy: I tend to use environ and profiles to configure dev stuff, and then in production environment vars or system properties. |
| 13:06 | weavejester | technomancy: Noted. |
| 13:07 | technomancy | so I guess I should encourage people to experiment with it unofficially for a while and have them report any issues =) |
| 13:07 | weavejester | technomancy: But in that case, we'd likely need something to replace Lein. Like… a runtime config/profiles thing. |
| 13:07 | technomancy | weavejester: have you seen configleaf? |
| 13:07 | weavejester | technomancy: No... |
| 13:07 | technomancy | I think it does some of the stuff you're describing |
| 13:08 | weavejester | technomancy: Hm, that goes a little further than I was thinking... |
| 13:09 | weavejester | technomancy: In my case I'm just using it as a way to populate env vars during development. |
| 13:10 | weavejester | And I guess to specify how to run the application. |
| 13:10 | weavejester | But Lein does that already with :main, so that seems to be in line with how it works already |
| 13:11 | weavejester | Specifying :main or specifying a :handler seem similar. |
| 13:20 | technomancy | yeah, in fact IMO lein run with the right aliases covers most of the use cases of lein ring |
| 13:20 | technomancy | lein ring server, I mean |
| 13:20 | technomancy | if you're using embedded jetty |
| 13:21 | weavejester | technomancy: Yes, apart from the configuration |
| 13:21 | weavejester | technomancy: lein run + aliases + some kind of config with profiles would cover my use cases at the moment |
| 13:21 | technomancy | weavejester: lein-ring says it does stack traces in development; does it just check LEIN_NO_DEV, or what? |
| 13:22 | weavejester | technomancy: Yes, by default, but you can be more exact with profiles |
| 13:22 | weavejester | technomancy: It seemed like a reasonable default to have. |
| 13:22 | technomancy | yeah, unfortunately LEIN_NO_DEV is specific to 1.x |
| 13:23 | weavejester | technomancy: You can still set it for 2.0 - it just wouldn't do anything to Lein itself. |
| 13:23 | weavejester | technomancy: That said, for Lein 2 you'd probably want to use profiles. |
| 13:23 | technomancy | sure, it's just no longer a documented convention |
| 13:23 | Sgeo | ,(some #{:a :b} (keys {:a 1 :b 2}) |
| 13:23 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading> |
| 13:23 | technomancy | might help to be clearer about that in the lein-ring readme |
| 13:23 | Sgeo | ,(some #{:a :b} (keys {:a 1 :b 2})) |
| 13:23 | clojurebot | :a |
| 13:23 | Sgeo | Oh, I was scrolled up |
| 13:23 | weavejester | technomancy: True |
| 13:24 | jbarrios | ,graph |
| 13:24 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: graph in this context, compiling:(NO_SOURCE_PATH:0)> |
| 13:25 | jbarrios | where's the old clojure.contrib.graph package now? |
| 13:27 | raek | jbarrios: nowhere. it is unmaintained. |
| 13:27 | raek | http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go |
| 13:27 | jbarrios | so I guess dgraph is the best choice atm? |
| 13:28 | jbarrios | https://github.com/gcv/dgraph |
| 13:31 | jml | is there a recommended pastebin for this channel? |
| 13:31 | llasram | jml: https://www.refheap.com/paste |
| 13:31 | jml | llasram: thanks. |
| 13:32 | jml | pretty. |
| 13:32 | hyPiRion | gists are also nice if you wonder whether the code is idiomatic or not |
| 13:32 | hyPiRion | 'cause of forking possibilities |
| 13:32 | sh10151 | quick leiningen/clojure-jack-in question for emacs people: |
| 13:33 | sh10151 | things in my resources/ directory don't appear to be on the classpath in a repl started in clojure-jack-in ... does that sound right? if so, any way to change that? |
| 13:34 | jsabeaudry | what kind of "things" ? |
| 13:34 | sh10151 | xslt file |
| 13:34 | sh10151 | null pointer returned by clojure.java.io/resource on its name |
| 13:35 | technomancy | sh10151: did you create the resources/ dir after starting the JVM? |
| 13:35 | sh10151 | hmm good question. does clojure-jack-in tear down the whole JVM or not? |
| 13:35 | sh10151 | i think i have just been repeatedly calling that |
| 13:35 | sh10151 | saying to get rid of the exsting process |
| 13:36 | technomancy | it does restart the JVM, yeah |
| 13:36 | sh10151 | ok, so no |
| 13:36 | sh10151 | it's been there |
| 13:36 | sh10151 | if it's supposed to work, I can look for typos or something |
| 13:36 | sh10151 | just wanted to make sure it's supposed to work |
| 13:36 | sh10151 | after not seeing any typos |
| 13:36 | raek | yeah, it is supposed to work |
| 13:37 | technomancy | it definitely should work |
| 13:37 | sh10151 | ok, I see making the uberjar puts the file in there |
| 13:37 | jsabeaudry | it does work here, just tested it |
| 13:37 | jsabeaudry | what path did you give to (resource ) ? |
| 13:37 | raek | sh10151: so if you have a file in resources/foo/bar.txt you use (io/resource "foo/bar.txt") to get it? |
| 13:37 | sh10151 | "/filename.xsl" |
| 13:37 | sh10151 | it's at top level of resources dir |
| 13:38 | sh10151 | maybe no leading "/" ? |
| 13:38 | jsabeaudry | try without the leading slash? |
| 13:38 | raek | I can't remember what happens if you have a leading slash |
| 13:38 | jsabeaudry | returns nil if i had a leading slash here |
| 13:38 | sh10151 | relative to package of the classloader loading the resource I think |
| 13:38 | jsabeaudry | add* |
| 13:39 | sh10151 | I mean, that's what Java does, not sure about java.io.resource |
| 13:39 | raek | it uses the java stuff under the hood |
| 13:40 | sh10151 | that did it, thanks for the help. I should have tried that |
| 13:40 | deeplloyd | I have been trying to pick up clojure over the past couple of weekends. i find a decent amout of people's learning experiences w/ clojure plus the normal documentation. What I feel I have not found is a non lisp, non clojure, python/c ish dev's account of coming blind from said technologies to writing a web app in clojure. webnoir is about the best. I have a decent background in programming, and know that it will take time to get |
| 13:40 | sh10151 | just porting some clojure 1.0.x era code with maven-clojure-plugin to current stuff |
| 13:40 | sh10151 | and I know it used to work back in the day :) |
| 13:41 | dnolen | deeplloyd: have you checked out the O'Reilly book? |
| 13:41 | Frozenlock | Perhaps I was doing it the wrong way, but in clojure I could get the value of a symbole simply by doing (eval my-symbol). How can I do it in cljs? |
| 13:41 | deeplloyd | dnolen: clojure programming? |
| 13:42 | synfinatic | yep that one |
| 13:42 | dnolen | deeplloyd: yes |
| 13:42 | xeqi | ,(resolve '+) |
| 13:42 | clojurebot | #'clojure.core/+ |
| 13:42 | sh10151 | deeplloyd: In my experience the Java/JVM adds quite a bit of complexity too, if you're not already familiar with it. my last question is an example of such complexity. :-/ |
| 13:43 | Sgeo | Hmm |
| 13:43 | cemerick | deeplloyd: http://clojurebook.com if you'd like a precis (or, the closest you'll get to one for a technical book I guess) |
| 13:43 | Sgeo | &(resolve '+) |
| 13:43 | lazybot | java.lang.SecurityException: You tripped the alarm! resolve is bad! |
| 13:43 | Sgeo | So, there's a difference between clojurebot's sandbox and lazybot's sandbox |
| 13:43 | deeplloyd | synfinatic: dnolen not past the free samples. i dont pirate and would prefer to hold out on spending the bucks until finances are a bette |
| 13:43 | technomancy | you'd run into the problem of complexity around the ability to load files transparently either off disk or from a compressed archive no matter the runtime |
| 13:43 | deeplloyd | cemerick: precis? |
| 13:43 | Sgeo | ,(future (+ 1 1)) |
| 13:43 | clojurebot | #<SecurityException java.lang.SecurityException: no threads please> |
| 13:44 | cemerick | $google define:precis |
| 13:44 | lazybot | [Précis - Wikipedia, the free encyclopedia] http://en.wikipedia.org/wiki/Pr%C3%A9cis |
| 13:44 | cemerick | oh well |
| 13:44 | deeplloyd | ah |
| 13:44 | xeqi | Sgeo: quite abit, clojurebot resets the sandbox every ~15m or so and uses classloaders to prevent some bad stuff; lazybot uses clojail to achieve the same thing |
| 13:44 | Sgeo | classloaders? |
| 13:44 | sh10151 | technomancy: sure, but in other runtimes that's not really something that's valued enough to bake into the system |
| 13:45 | Sgeo | I've heard the term before but don't know much about it |
| 13:45 | cemerick | A brief abstract of some material (paper, book, etc), usually written by a student to verify comprehension, etc. |
| 13:45 | deeplloyd | okay. well then that is the way I suppose. hopefully il be able to make what im looking for in the process |
| 13:45 | sh10151 | technomancy: here I'm thinking of Python/C per deeplloyd's question :) |
| 13:45 | xeqi | Sgeo: think path to search for libraries |
| 13:45 | Sgeo | I thought that's classpath |
| 13:45 | technomancy | sh10151: so if you don't want the ability to read contents transparently from either an archive or disk why are you using resources? |
| 13:46 | xeqi | they both have to load other libs to run, but want to present a repl w/ a limited subset |
| 13:46 | xeqi | classloaders are the objects that load classes from the classpath |
| 13:46 | deeplloyd | btw cemerick i enjoyed the state survey |
| 13:46 | Sgeo | Ah |
| 13:46 | technomancy | you can always fall back to loading a file from a specific path on disk |
| 13:46 | Sgeo | I'm pretty sure that I won't be mentally designing ClojureNomic |
| 13:46 | sh10151 | technomancy: oh, I am interested in doing it either way, but only because these things are often deployed as a jar but developed running from files |
| 13:46 | cemerick | deeplloyd: Glad for that :-) |
| 13:47 | Sgeo | I think newLisp is good for a nomic because of save |
| 13:47 | deeplloyd | cemerick: what did you write your blog in? |
| 13:47 | cemerick | cemerick.com is on wordpress.com |
| 13:48 | cemerick | So is mostlylazy.com |
| 13:48 | deeplloyd | do you have a clojure site i can scour? |
| 13:49 | sh10151 | technomancy: which is something that a person who's primarily billing themselves as Python/C might not know off the bat. |
| 13:49 | cemerick | deeplloyd: What, of strictly clojure-related content? http://cemerick.com/category/clojure/ I suppose. :-P |
| 13:50 | technomancy | sh10151: sure, so you're trading a bit of up-front complexity for an easier single-file deployment |
| 13:50 | weavejester | technomancy: I think I'm going to have a ragtime.main with two arguments. The first to specify a function that returns a list of migrations. The second to specify a database URL. |
| 13:50 | weavejester | technomancy: Then I'll add a Lein plugin that will thinly wrap ragtime.main and take the arguments from the project map. |
| 13:50 | technomancy | weavejester: yeah, since aliases support partial application you can put the function in project.clj |
| 13:51 | weavejester | technomancy: Yes, though I'll also add a plugin to do the same thing, but in a nicer way |
| 13:51 | sh10151 | technomancy: yep, and that complexity's the kind of thing that can trip people up if they're not prepared. just pointing out to deeplloyd that understanding Java is at least as important to production Clojure as is understanding Lisp. |
| 13:51 | weavejester | technomancy: I want to see which I like best. |
| 13:52 | technomancy | weavejester: I guess the other thing you get with a plugin is a docstring |
| 13:52 | technomancy | I dunno. I don't think it's worth it, but try it and see for yourself =) |
| 13:52 | weavejester | technomancy: Yeah. And if we decide to move away from plugins, it's only going to be a thin wrapper. |
| 13:53 | deeplloyd | cemerick: IE9 > FF ?!? |
| 14:02 | Sgeo | http://www.reddit.com/r/netsec/comments/ywbhq/new_java_0day_exploited_in_the_wild/ |
| 14:17 | cemerick | deeplloyd: ?? |
| 14:17 | lazybot | cemerick: Uh, no. Why would you even ask? |
| 14:20 | Sgeo | I feel like I'm about to give up on labrepl |
| 14:20 | Sgeo | Or maybe just Eclipse |
| 14:20 | cemerick | Sgeo: What's tripping you up? I can help with Eclipse/ccw, but I know nothing of labrepl. |
| 14:21 | Sgeo | cemerick, when I try to import the thing via git, at the end of the wizard it says there's already a project there |
| 14:22 | Sgeo | (Following the instructions at http://dev.clojure.org/display/doc/Getting+Started+with+Eclipse+and+Counterclockwise ) |
| 14:24 | Sgeo | (Specifically, after "Import as general project", it says "C:\Users\Sgeo\DEV\Eclipse\labrepl15 overlaps the location of another project: ;labrepl15' |
| 14:24 | cemerick | Sgeo: Worked for me; perhaps you've done this a couple of times, and so the project is already cloned with an eclipse project set up therein? |
| 14:24 | Sgeo | Erm, 'laprepl15' |
| 14:25 | Sgeo | cemerick, would that effect it even if I keep using different numbers for the directory? |
| 14:25 | cemerick | Sgeo: Wouldn't think so, but apparently… |
| 14:25 | darklajid | Hi. Probably I'm missing something obvious. I'm just getting started, playing with some simple http tools. I'm using ring, and a request seems to be just a map, right? Where would I find the structure/keys of this beast? I'm looking for the remote ip/port of the underlying socket, specifically |
| 14:26 | cemerick | Sgeo: Try: Import > General > Existing projects, and see if there's one already in place ready to go |
| 14:26 | cemerick | Is labrepl even maintained anymore? Last change was 10 months ago. |
| 14:26 | technomancy | darklajid: just print the request |
| 14:27 | Sgeo | No projects are found to import |
| 14:27 | technomancy | or return it in the response: (defn app [req] {:headers {"Content-Type" "text/plain"} :status 200 :body (prn req)}) |
| 14:27 | ohpauleez | cemerick: I'm not sure, but it is a good learning tool |
| 14:27 | cemerick | Sgeo: it looks like labrepl is just another leiningen project, so you can just use a clone of it as such |
| 14:28 | Sgeo | ? |
| 14:28 | xeqi | darklajid: https://github.com/ring-clojure/ring/blob/master/SPEC for the structure |
| 14:28 | cemerick | ohpauleez: dunno, it's starting people off with clojure 1.3.0, and old compojure, ring, etc. |
| 14:28 | darklajid | technomancy: Gives me two problems. a) I don't see the required data there (I get a :remote-addr, but that seems to be a string/ip address. No port) and b) Is that the normal way? I did that already, but I was kind of hoping for a missing link to some docs.. :) |
| 14:29 | cemerick | Sgeo: Are you specifically looking to use labrepl for something, or are you just wanting to get started with programming in Clojure in general? |
| 14:29 | ohpauleez | cemerick: Ah wow, I wasn't aware it was that out of date |
| 14:29 | ohpauleez | 4clojure would definitely be better |
| 14:29 | technomancy | darklajid: you could read the SPEC file for ring, but you should also get comfortable with exploring the API interactively |
| 14:29 | Sgeo | cemerick, getting started with Clojure in general, although I have learned a bit already I think |
| 14:29 | technomancy | that's the whole request object though |
| 14:30 | darklajid | xeqi: technomancy: Cool, the spec looks neat. But .. no port. So ring is not for me, I guess? Back to sockets? |
| 14:30 | cemerick | Sgeo: As long as you can get a Clojure+Leiningen project going in ccw with a REPL, you're on your way. :-) |
| 14:30 | Sgeo | I seem to have gotten independent leiningen installed finally |
| 14:32 | Sgeo | labrepl working now |
| 14:35 | xeqi | darklajid: yeah, you'll prolly need something else.. why are you interested in the client's port out of curiousity? |
| 14:37 | darklajid | *cough* Quite frankly I suck at Clojure, but have cemerick's book on my kindle for ages. There's a current ctf from stripe and I'm trying to solve the last level -> The only one that needs code -> "Maybe I can learn some clojure with this particular goal" |
| 14:37 | xeqi | ah, I solved that one in python |
| 14:37 | darklajid | Problem: I need the addr/port to get even started. So the whole 'explore all these web stuff I've read about in clojure land' dies before I even begin :) |
| 14:37 | xeqi | since it was already on l2 |
| 14:37 | darklajid | xeqi: ;-) |
| 14:38 | darklajid | xeqi: Yeah, but .. I'm worse at python than at clojure, even. :) But I don't care about learning python very much, so.. Hmpf. |
| 14:39 | xeqi | heh, I didn't want to deal with installing a jdk |
| 14:39 | xeqi | *jre |
| 14:40 | lucian | xeqi: i didn't even bother getting twisted there |
| 14:40 | lucian | even that is too much trouble |
| 14:40 | xeqi | yeah, I went singlethreaded python w/ sockets and httplib |
| 14:57 | Sgeo | "Starting in 1.3.0, Clojure no longer auto-boxes this type of operation for you." |
| 14:57 | Sgeo | Hmm, why? |
| 14:58 | S11001001 | Sgeo: what? |
| 14:58 | Sgeo | S11001001, arithmatic that might overflow |
| 14:58 | nDuff | Sgeo: Performance. |
| 14:58 | S11001001 | MORE SPEED |
| 14:58 | ohpauleez | Sgeo: Most developers are aware of the numeric scope they're operating in, so the performance trade-off of auto-boxing and converting up the numeric tower wasn't worth it |
| 14:58 | clojurebot | stuartsierra has come to the conclusion that dynamic scope is a bug. |
| 14:59 | ohpauleez | Sgeo: you can still get that behavior if you want it |
| 15:08 | Frozenlock | If any of you have 1 or 2 min to spare, could you look at this code https://www.refheap.com/paste/4660 (view the result here http://173.246.15.182:8888, try to click Bar Foo and Zon) and tell me if I'm doing crazy things? |
| 15:19 | acheng | clojure style question: to take a map and return a new one where any nil values have been replaced with empty strings, i wrote an fn that maps an if-statement, flattens, then apply's assoc on {} and the result. is there a better clojure way to do it? |
| 15:19 | amalloy | ~flatten |
| 15:19 | clojurebot | flatten is rarely the right answer. Suppose you need to use a list as your "base type", for example. Usually you only want to flatten a single level, and in that case you're better off with concat. Or, better still, use mapcat to produce a sequence that's shaped right to begin with. |
| 15:20 | amalloy | i wonder how rude it would be to have lazybot notice any message with "flatten" in it and respond like that |
| 15:21 | acheng | i wouldn't mind if it provided an example as well :-P |
| 15:21 | technomancy | acheng: sounds like a classic reduce |
| 15:23 | Sgeo | amalloy, I wonder if its uselessness can be noticed by how in Haskell such a function can't be given a type |
| 15:23 | xeqi | ,(into {} (map (fn [k v] (vector k (if (nil? v) "" v))) {:a nil :b "b" :c "c"})) |
| 15:23 | clojurebot | #<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: sandbox$eval27$fn> |
| 15:23 | Sgeo | Well, in Haskell, you can't even have lists that have different nesting levels |
| 15:24 | Sgeo | But flattenOneLevel :: [[a]] -> [a] |
| 15:24 | xeqi | ,(into {} (map (fn [[k v]] (vector k (if (nil? v) "" v))) {:a nil :b "b" :c "c"})) |
| 15:24 | clojurebot | {:a "", :c "c", :b "b"} |
| 15:24 | Sgeo | Pretty sure there's a real Haskell function |
| 15:24 | amalloy | Sgeo: it's concat |
| 15:24 | Sgeo | amalloy, indeed. I hoogled it >.> |
| 15:24 | amalloy | xeqi: (map (fn ...)) makes me so sad; just use (for ...) |
| 15:24 | xeqi | haha, habits |
| 15:26 | xeqi | ,(into {} (for [[k v] {:a nil :b "b" :c "c"}] (vector k (if (nil? v) "" v)))) |
| 15:26 | clojurebot | {:a "", :c "c", :b "b"} |
| 15:26 | acheng | thanks folks! |
| 15:26 | xeqi | will remember for next time |
| 15:27 | jkkramer | ,(= (vector :a 1) [:a 1]) |
| 15:27 | clojurebot | true |
| 15:27 | xeqi | I've stopped using data literal syntax with variables, even though I know its safe here |
| 15:27 | acheng | oh. so in this case, which is preferable.. reduce or into ... or are these approaches basically equally good? |
| 15:28 | Chousuke | into is usually better if you're building a data structure. |
| 15:29 | jkkramer | into is shorter here. vs e.g. (reduce-kv (fn [m k v] (assoc m k (if (nil? v) "" v))) {} m). but either approach is fine |
| 15:29 | Sgeo | I really want to be able to browse the source of an item on clojars |
| 15:30 | llasram | IMHO `into` more directly expresses intent (vs just being shorter), and has the side effect of being more efficient due to internally using transients |
| 15:31 | alcy | cemerick: ping |
| 15:31 | cemerick | alcy: pong |
| 15:31 | mk | acheng: https://github.com/flatland/useful/blob/develop/src/useful/map.clj#L46 ? |
| 15:31 | alcy | cemerick: hi, had a question about the book you authored, is this one of the right mediums to ask ? :) |
| 15:31 | cemerick | sure, fire away |
| 15:32 | acheng | mk: ooh |
| 15:33 | alcy | cemerick: thanks, so i've made till destructuring, which started to pose some semantic confusion (coming from perl), but I have _just_ been able to understand the point minus the technical terms ... is this expected and things gonna get better ? |
| 15:33 | alcy | cemerick: for eg., the book doesnt tell me about seqs/vectors etc. formally, but I can kinda make out |
| 15:33 | alcy | cemerick: well by book, right now, I mean the first initial few topics |
| 15:34 | mk | acheng: I ended up asking the same question on the 14th, I think that was the best answer (provided by gtrak). You can look at what was said at http://clojure-log.n01se.net/date/2012-08-14.html , by ctrl-f "of map entries" |
| 15:34 | cemerick | alcy: seqs and vectors and all the rest are covered in depth later on; if you're still in chapter 1, the (significant) differences between seqs and vectors can be glossed over. |
| 15:35 | mk | acheng: I think I was worried about efficiency |
| 15:36 | alcy | cemerick: ah thanks, I suppose it will be two passes of the book & terminology when I start making real programs ;) |
| 15:36 | amalloy | Sgeo: petition library authors to include a :url entry in their project.clj |
| 15:36 | cemerick | alcy: Make sure you've got a working REPL going so you can experiment along the way. As for whether it's going to "get better"…well, part I of the book is purposefully intensive. Of course, feel free to jump around in order to get a better feel for details (e.g. certainly read about data structures straight off if that interests you). |
| 15:36 | alcy | cemerick: ah yes, definitely, I have been doing that |
| 15:36 | Sgeo | Why can't clojars just open the jar itself? |
| 15:37 | cemerick | alcy: tryclj.com is a good default, if you don't want to mess around with setting up tools, etc. |
| 15:37 | alcy | cemerick: oh trust me I have done that tutorial twice, in fact, I have been waiting for someone to complete it ;) |
| 15:37 | amalloy | why can't you? it's a lot easier to do on a local filesystem than it is for clojars to reinvent githubj |
| 15:37 | alcy | cemerick: unless you just meant to get the repl |
| 15:37 | alcy | :) |
| 15:37 | xeqi | and not every jar includes source |
| 15:37 | cemerick | alcy: well, I meant that it's a reasonable REPL in general. |
| 15:38 | alcy | cemerick: yep |
| 15:38 | Sgeo | Unless you want to mess with futures or agents |
| 15:38 | alcy | cemerick: do you think, a preliminary knowledge of some particular concepts help ? prerequisites of sort ? |
| 15:38 | cemerick | alcy: Well, carry on, and feel free to ask questions here; lots of people that know their stuff. :-) |
| 15:39 | alcy | cemerick: cool, thanks |
| 15:39 | cemerick | alcy: We refer to various resources along the way in the text, but I'd hope that nothing would be a prerequisite. |
| 15:39 | mk | if I have a map that's a few million entries long, and I want to do map-vals, which I expect to only change 3 values, how might I implement that in a way that doesn't create a brand new and huge map? |
| 15:40 | alcy | cemerick: hmm, alright. wonder if its just me who finds the info to be a little dense |
| 15:43 | SegFaultAX|work2 | mk: If your only changing 3 values, then it's possible that most of the rest of the data structure will be shared. |
| 15:43 | SegFaultAX|work2 | mk: Clojure uses persistent data structures to help ameliorate problems like the one you just outlined. |
| 15:43 | wkelly | alcy: coming from a similar background, I think there's a pretty steep initial learning curve for clojure no matter which book you choose, but there really aren't too many fundamental concepts, so it does not stay too steep for too long |
| 15:44 | ordnungswidrig | is there a path for midje-mode to support nrepl? |
| 15:44 | ordnungswidrig | s/path/patch/ |
| 15:44 | alcy | wkelly: ah, thanks for the validation :) |
| 15:44 | mk | SegFaultAX|work2: the map-vals implementation I posted above doesn't seem to share that much structure |
| 15:45 | alcy | cemerick: thanks for your help too ! kinda like zen & the art of motorcycle maintenance where Pirsig leaves the difficult/dense part for a later chapter ;) |
| 15:45 | SegFaultAX|work2 | wkelly: Unless you're new to functional and declarative programming entirely. That might increase the learning complexity. |
| 15:45 | SegFaultAX|work2 | mk: Oh? Is it possible you're using the wrong data structure or the wrong algorithm? |
| 15:45 | SegFaultAX|work2 | mk: For example. would a zipper be more suitable to your needs? |
| 15:47 | scriptor | mk: it doesn't share any structure because theoretically every element could be different |
| 15:47 | scriptor | mk: so if you have a a map of entirely different values then of course you won't share any structure, but there's nothing to share |
| 15:47 | SegFaultAX|work2 | I see. I don't really know of a good way to side-step that. |
| 15:48 | SegFaultAX|work2 | mk: How big is the map in question? |
| 15:50 | naeg | I /quit |
| 15:51 | mk | SegFaultAX: I'm imagining a very large map, for example a map of word pair frequencies, or something |
| 15:52 | amalloy | mk: map-vals isn't doing any structural sharing, because each key has a new value that it can't predict |
| 15:52 | scriptor | mk: you don't really need map-vals if you need to update frequencies or anything like that |
| 15:52 | amalloy | personally i don't advocate the use of any of the map-* or filter-* functions in useful.map |
| 15:53 | mk | scriptor: what do you suggest? |
| 15:53 | scriptor | mk: nothing wrong with assoc |
| 15:54 | SegFaultAX|work2 | mk: Why would you only need to update 3 keys in a frequency map? |
| 15:54 | mk | my general idea is that I might have a large map where I only need to update a few keys. Assoc would do that? |
| 15:54 | amalloy | it's exactly what assoc is for |
| 15:55 | dnolen | what is decaf? https://gist.github.com/3491702 |
| 15:55 | TimMc | SegFaultAX|work2: Perhaps when new data comes in? |
| 15:55 | ninjudd | dnolen: https://github.com/flatland/decaf |
| 15:56 | mk | SegFaultAX|work2: might be adding a 4-word sentence to a large frequency list |
| 15:56 | SegFaultAX|work2 | Why does that require map-vals? |
| 15:56 | mk | amalloy: great - is there an impl of map-vals that's better suited for that? |
| 15:57 | amalloy | no, because map-vals is not a tool for doing what you said you need to do |
| 15:57 | amalloy | map-vals iterates the whole map; you have a small number of known keys |
| 15:57 | dnolen | ninjudd: ah interesting approach - so it just always a keeps a second JVM ready to go. |
| 15:58 | tomoj | ninjudd: sounds like a great idea. but how to cleanup the reserve jvms? manually kill? |
| 15:58 | mk | SegFaultAX|work2: not sure, it might not. I don't really remember what case I had in mind earlier. I guess the idea was that you would map-vals over the map, and there's a good chance that only a few would be updated. Like map-vals-when? |
| 15:59 | tos9 | a/11 |
| 16:01 | amalloy | tomoj: i think he already has code to kill them after an hour or whatever length of time if they just sit idle. if he doesn't yet, he will soon |
| 16:02 | ninjudd | tomoj amalloy: haven't written that code yet but i did make an issue https://github.com/flatland/decaf/issues/2 |
| 16:02 | tomoj | oh, cool |
| 16:11 | pbostrom_ | does anyone know of a good "intro to Clojure" slide deck? I found a couple that look pretty good: http://stuartsierra.com/download/2011-09-18-strangeloop-clojure-intro.pdf and http://www.slideshare.net/theceo/introduction-to-clojure-9639369 |
| 16:20 | alcy | pbostrom_: don't know about slide decks, probably just search on speakerdeck but http://blip.tv/clojure is also full of resources |
| 16:20 | alcy | pbostrom_: and infoq as well |
| 16:24 | Frozenlock | If any of you have 1 or 2 min to spare, could you look at this code https://www.refheap.com/paste/4660 (view the result here http://173.246.15.182:8888, try to click Bar Foo and Zon) and tell me if I'm doing crazy things? I wouldn't want to start my cljs adventure on a bad foot :-) |
| 16:26 | naeg | Frozenlock: did you ask on stack overflow for code review already? |
| 16:27 | nDuff | Isn't there a separate StackExchange site for review? |
| 16:27 | nDuff | StackOverflow is more for specific questions |
| 16:27 | naeg | nDuff: dunno, but there is: http://stackoverflow.com/questions/tagged/code-review |
| 16:27 | nDuff | ..."please review this code" questions tend to get closed quickly |
| 16:27 | Frozenlock | No, I've never used it and it didn't think it was a question worth of it... |
| 16:27 | amalloy | http://codereview.stackexchange.com |
| 16:27 | nDuff | ^^ that. |
| 16:28 | naeg | oh, but still in beta. You either use that or stack overflow's code-review tag |
| 16:28 | naeg | why not try it Frozenlock? can't hurt I guess |
| 16:29 | naeg | (sry, new to Clojure too, can't help that much) |
| 16:30 | Frozenlock | naeg: Sure I'll give it a try |
| 16:30 | naeg | Frozenlock: but use that codereview stackexchange |
| 16:31 | naeg | this questions suggest so: http://stackoverflow.com/questions/12098078/how-readable-is-this-line-of-code |
| 16:33 | Frozenlock | Oh wow... "To create code blocks or other preformatted text, indent by four spaces:" I wasn't on Emacs, I would cry. |
| 16:34 | Raynes | Frozenlock: copy them all and then ctrl+k |
| 16:34 | nDuff | Frozenlock: There's a javascript button to do that for you. |
| 16:34 | nDuff | Frozenlock: ...so you can select your code in the browser's editor, click the {} symbol, and it does the indent. |
| 16:36 | Frozenlock | Raynes: That's for inline, no? |
| 16:36 | Raynes | I don't think so, no. |
| 16:36 | Frozenlock | nDuff: Indeed... I don't know why I stopped looking once I found the `code' button. |
| 16:36 | Raynes | There is a command that does it regardless, but what nDuff just said would work too. |
| 16:37 | emezeske | Frozenlock: I am not sure about this, but I kind of seem to think that things like (js/jQuery.plot) only work by accident, and that you should use (.plot js/jQuery) instead |
| 16:37 | emezeske | Frozenlock: I could be wrong though. |
| 16:37 | amalloy | hah, i never even noticed SO had wysiwyg-style editor buttons. i just have a keybinding in emacs for "copy all this, and indent it by four spaces" |
| 16:39 | Frozenlock | emezeske: I have found js/jQuery to be working sporadically. I still don't know why :( |
| 16:39 | casion | technomancy: rectangle commands are out there for cokeror |
| 16:39 | emezeske | Frozenlock: What do you mean by sporadic? |
| 16:39 | casion | there was someone on the IRC channel who implemented them |
| 16:39 | casion | conkeror* |
| 16:40 | technomancy | casion: as a third-party lib? |
| 16:40 | casion | technomancy: yes |
| 16:41 | technomancy | huh; cool |
| 16:41 | Frozenlock | emezeske: Sometimes it works, other it doesn't. |
| 16:41 | technomancy | I wonder if it'd be good enough to merge into mainline |
| 16:42 | emezeske | Frozenlock: Can you be more specific? Like, what happens when it doesn't work? An exception? A compile warning? Does it ever fail without recompiling, and just refreshing the browser? |
| 16:45 | bosie | technomancy: are you responsible for clojure at heroku? |
| 16:46 | technomancy | bosie: yeah, what's up? |
| 16:46 | bosie | technomancy: no, nothing. was just wondering if you do ruby or clojure there |
| 16:46 | technomancy | I do a bit of ruby here and there |
| 16:47 | bosie | why the heck are you fluent in indonesian/malaysian? |
| 16:48 | technomancy | I grew up in Indonesia |
| 16:48 | technomancy | also, it's literally the easiest non-artificial language in the world |
| 16:48 | bosie | cool |
| 16:48 | Frozenlock | emezeske: Sure, sorry about that. So if it works for a function, it will always work, but not all function are ok with this. For example, If I want to use the .datepicker from jQuery, I need to call it directly: (.datepicker ($ :#datepicker)). Calling it as I did with the .plot, (js/jQuery.datepicker ($ :#datepicker)) will result in this: #<TypeError: Property 'datepicker' of object function (a,b){return new p.fn.init(a,b,c)} is |
| 16:48 | Frozenlock | function> |
| 16:48 | bosie | easy to say if you grew up there ;) |
| 16:49 | emezeske | Frozenlock: I think sporadic is not the right word for that. Inconsistent, maybe? |
| 16:49 | emezeske | Frozenlock: Anyway, I'm pretty sure js/Something.anything is wrong |
| 16:49 | emezeske | Frozenlock: If you want to call something on the jQuery object iself, (.member js/jQuery) |
| 16:49 | emezeske | Frozenlock: If you want to call something on a jquery container: (.member ($ thing)) |
| 16:50 | Sgeo | http://nathanaeljones.com/45/clojure-cross-platform-fast-concurrent-concise/ |
| 16:50 | Frozenlock | Definition of SPORADIC |
| 16:50 | Frozenlock | : occurring occasionally, singly, or in irregular or random instances (from merriam-webster) |
| 16:50 | Sgeo | What's this about edit-and-continue? |
| 16:50 | Frozenlock | I like my words :) |
| 16:50 | emezeske | Frozenlock: "irregular" |
| 16:50 | emezeske | Frozenlock: I promise that it works regularly, just not how you expect |
| 16:50 | emezeske | Frozenlock: Sporadic would be if js/jQuery worked when you ran the code once, but not the next time you ran the same code |
| 16:52 | emezeske | Frozenlock: Anyway, you want to avoid js/Stuff as much as possible. Wrap js/jQuery in a function, and use that, and never use js/Whatever anywhere else in your code, and you'll be fine |
| 16:53 | Frozenlock | Ok, for a particular instance, it's consistent (js/jQuery.plot), but for the usage of js/jQuery it's irregular. |
| 16:53 | Frozenlock | But what's wrong with it? |
| 16:54 | Frozenlock | Shouldn't js/jQuery be able to call ev-e-ry thing? |
| 16:55 | emezeske | Well, the fact that it does unexpected things seems like a great reason not to use it |
| 16:55 | emezeske | And again, I really don't think js/Thing.member is supposed to work, I think that's an accident |
| 16:55 | emezeske | Anyway, feel free to not listen to me, I'm just throwing out some suggestions |
| 16:56 | SegFaultAX|work2 | emezeske: Why should you wrap js/* in a function? |
| 16:56 | SegFaultAX|work2 | emezeske: (I have never used cljs) |
| 16:57 | Frozenlock | Hey, I really appreciate, I just didn't want to rely on rule of thumbs. |
| 16:57 | Frozenlock | Please, feel free to suggest anytime :) |
| 16:58 | emezeske | SegFaultAX|work2: I just suggest it to keep the code as clojure-y as possible |
| 16:58 | emezeske | SegFaultAX|work2: js/ is a bit of an escape hatch to JS, and you can do silly things with it -- it's nice to just hide it away and do everything clojure-y |
| 17:00 | Sgeo | ,(.toUpper "hm") |
| 17:00 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: No matching field found: toUpper for class java.lang.String> |
| 17:00 | hyPiRion | ,(.toUpperCase "hm") |
| 17:00 | clojurebot | "HM" |
| 17:00 | Sgeo | ,(map .toUpperCase '("hm" "argh")) |
| 17:00 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: .toUpperCase in this context, compiling:(NO_SOURCE_PATH:0)> |
| 17:00 | Sgeo | ,(map #(.toUpperCase %) '("hm" "argh")) |
| 17:00 | clojurebot | ("HM" "ARGH") |
| 17:01 | hyPiRion | ,(map (memfn toUpperCase) ["hm" "argh"]) |
| 17:01 | clojurebot | ("HM" "ARGH") |
| 17:01 | hyPiRion | ,(doc memfn) |
| 17:01 | clojurebot | "([name & args]); Expands into code that creates a fn that expects to be passed an object and any args and calls the named instance method on the object passing the args. Use when you want to treat a Java method as a first-class fn." |
| 17:01 | brehaut | ,(map (memfn toUpperCase) ["hm" "argh"]) |
| 17:01 | clojurebot | ("HM" "ARGH") |
| 17:02 | Sgeo | is there an equivalent for static methods? |
| 17:16 | tanzoniteblack | Sgeo: generally I just use the #() for statics |
| 17:16 | tanzoniteblack | ,(map #(String/valueOf %) [2 3]) |
| 17:16 | clojurebot | ("2" "3") |
| 17:17 | Sgeo | I'm going to end up learning the Java standard library, aren't I? :/ |
| 17:17 | tanzoniteblack | what static method do you need? |
| 17:17 | SegFaultAX|work2 | Is there a function to get every nth element of a seq given some step. Like the first, third, fifth, seventh, etc. |
| 17:18 | SegFaultAX|work2 | Ah, take nth. |
| 17:18 | magopian | guys, i'm pondering at problem 113 on 4clojure at the moment (http://www.4clojure.com/problem/113), but can't find how to tackle it |
| 17:19 | Sgeo | tanzoniteblack, I mean, just in general for using Clojure |
| 17:19 | magopian | may i have a hint on what to use? I'm just a noob in clojure, so i'm believing i'm missing some kind of language construct/feature that would allow some data to be represented differently if it's "str" or "seq" |
| 17:20 | magopian | for example, using python, i would play with __str__ and __iter__ |
| 17:20 | brehaut | magnars: i havent solved that one, but it looks like reify might be a good play to start |
| 17:20 | tanzoniteblack | ,(let [my-list '("one" "two" "three" "four")] |
| 17:20 | tanzoniteblack | (map #(nth my-list %) (range 0 4 2))) |
| 17:20 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading> |
| 17:20 | tanzoniteblack | whoops, messed that up |
| 17:20 | tanzoniteblack | but nth will get the nth item from a set |
| 17:20 | tanzoniteblack | and you can use that as a function |
| 17:20 | SegFaultAX|work2 | tanzoniteblack: If that's for me, take-nth is a thing. |
| 17:20 | magopian | brehaut: i think that was for me and not magnars ;) thanks for the tip, i'm going to find some documentation on reify |
| 17:21 | brehaut | magopian: yes. sorry |
| 17:21 | magopian | brehaut: no problem, thanks for the tip ;) |
| 17:21 | tanzoniteblack | Sgeo: the nth thing was for you |
| 17:21 | tanzoniteblack | ,(let [my-list '("one" "two" "three" "four")] (map #(nth my-list %) (range 0 4 2))) |
| 17:21 | clojurebot | ("one" "three") |
| 17:21 | Sgeo | tanzoniteblack, wait, what? why am I being told about nth? |
| 17:21 | brehaut | magopian: you now about the doc command? |
| 17:22 | brehaut | s/command/function/ |
| 17:22 | tanzoniteblack | no wait...I'm confusing myself now, that was for SegFaultAX|work2 |
| 17:22 | SegFaultAX|work2 | tanzoniteblack: And see my reply. |
| 17:22 | magopian | brehaut: i think so (doc reify) |
| 17:22 | magopian | however, it doesn't seem to work in the LightTable playground ;) |
| 17:23 | magopian | &(doc reify) |
| 17:23 | lazybot | ⇒ "Macro ([& opts+specs]); reify is a macro with the following structure: (reify options* specs*) Currently there are no options. Each spec consists of the protocol or interface name followed by zero or more method bodies: protocol-or-interface-or-Object (methodNa... https://www.refheap.com/paste/4663 |
| 17:23 | tanzoniteblack | SegFaultAX|work2: cools, I hadn't seen take-nth before, thanks |
| 17:24 | mpenet | Sgeo: not necessarly, there are lua, c, js, gambit scheme, clr, python and probalbly more implementations out there |
| 17:27 | mpenet | At this point it depends on what you intend to do. Playing with the language, or getting things done, if that is the later the JVM or clojurescript is your best bet for now. |
| 17:27 | magopian | brehaut: wow, the doc of reify speaks chinese to me ;) |
| 17:27 | brehaut | haha |
| 17:27 | brehaut | sorry |
| 17:28 | ordnungswidrig | you'll understand the doc when you understand reify |
| 17:28 | magopian | brehaut: however, the doc seems to more or less answer the exact problem stated in 4clojure ;) |
| 17:29 | magopian | (with str and seq ;) |
| 17:29 | magopian | i should be able to work something out |
| 17:29 | magopian | ordnungswidrig: that's scary :) |
| 17:29 | magopian | ordnungswidrig: and will i understand reify when i understand the doc? ^^ |
| 17:29 | hyPiRion | Wow, the reify-doc is horrible. |
| 17:30 | magopian | hyPiRion: dunno, i can hardly understand half of it |
| 17:30 | magopian | but i keep re-reading it, i'll make some sense out of it ;) |
| 17:30 | hyPiRion | magopian: Look at examples, they give you a better understanding. |
| 17:31 | ordnungswidrig | the best part: (reify options* specs*) … Currently there are no options. |
| 17:31 | magopian | hyPiRion: yup, thanks for the tip |
| 17:31 | ordnungswidrig | this is what I call a real optional parameter |
| 17:31 | ordnungswidrig | Sgeo: no |
| 17:36 | magopian | mmm i'm going to get some sleep now, i'm sure it'll make more sense tomorrow ;) |
| 17:36 | SegFaultAX|work2 | For http://www.4clojure.com/problem/50, is this cheating? (comp vals (partial group-by type)) |
| 17:36 | magopian | SegFaultAX|work2: why would it be cheating? |
| 17:36 | amalloy | any solution that works isn't cheating. you heard it here first, folks |
| 17:37 | magopian | amalloy: thanks for 4clojure ;) |
| 17:37 | magopian | it's what drives me to learn more clojure, day after day ;) |
| 17:37 | magopian | (and keeps my brain awake) |
| 17:37 | SegFaultAX|work2 | amalloy: It just seems slightly abusive. :) |
| 17:37 | magopian | well, it's going to sleep now, but you get my point ;) |
| 17:37 | magopian | good night folkds |
| 17:38 | Raynes | amalloy: I saw something implement the nth problem with '.get' |
| 17:38 | Raynes | I lol'd |
| 17:38 | amalloy | nice |
| 17:49 | hiredman | ob |
| 17:58 | SegFaultAX|work2 | To do #53 on 4clojure, I've written the following: https://www.refheap.com/paste/4665 Does this seem generally useful? Is there a better way? |
| 18:00 | Frozenlock | Am I a bad person for never using defn- ? |
| 18:01 | dnolen | Frozenlock: no |
| 18:01 | ordnungswidrig | Frozenlock: No, unless you're using (defn ^:private) :-) |
| 18:01 | Raynes | Implying that (defn ^:private ..) is bad? |
| 18:02 | SegFaultAX|work2 | Is it functionally different from (defn- ...)? |
| 18:02 | Raynes | No. |
| 18:02 | xeqi | I don't like to make functions private, but when I do I use (defn ^:private ..) |
| 18:02 | Raynes | And it is much more consistent with the rest of Clojure. |
| 18:02 | SegFaultAX|work2 | Ah. |
| 18:02 | Raynes | defn- is more of an artifact of the past than anything. |
| 18:02 | hyPiRion | SegFaultAX|work2: If you generalize it, it would proably be a bit more... general |
| 18:02 | Raynes | Which is why there isn't any def-, for example. |
| 18:03 | ordnungswidrig | dnolen: is core.logic capable of generating solutions that are lists in a "minimal" way? it's finite domain. |
| 18:03 | SegFaultAX|work2 | Is there something wrong with private functions? It seems like keeping your namespace API uncluttered with internal functions is a good thing. |
| 18:03 | dnolen | ordnungswidrig: what do you mean? |
| 18:03 | ordnungswidrig | dnolen: so, give a list of chess queen positions such that every field on the board is attacked. |
| 18:04 | ordnungswidrig | dnolen: there are a lot of solutions, some are smaller than others |
| 18:04 | nDuff | SegFaultAX: The place where they annoy me are cases where I want to replace some parts of functionality in 3rd-party code while retaining those which overlap, but where the overlap is all in functions marked private. |
| 18:05 | ordnungswidrig | dnolen: i'm not interested in the theoretical minimum, though. building the constrainst, such that the "first" solution is a small one would do. |
| 18:05 | nDuff | SegFaultAX: ...and with respect to namespace cleanliness, there's an argument to be made that global refers are Doing It Wrong anyhow. |
| 18:05 | SegFaultAX|work2 | nDuff: Well if it's private that probably means "internal implementation detail," right? Do wouldn't monkey patching that be pretty bad anyway? |
| 18:05 | SegFaultAX|work2 | So wouldn't* |
| 18:06 | dnolen | ordnungswidrig: are you specifically interested in an nqueens solution? Martin Trojer did one. |
| 18:07 | Frozenlock | Thanks guys, I wasn't expecting so much details :) |
| 18:07 | SegFaultAX|work2 | dnolen: That's a pretty compact solution, too. |
| 18:08 | dnolen | ordnungswidrig: but perhaps I understand what you are asking ... and I believe the answer is yes. the new core.logic alphas support constraint logic programming over finite domains. |
| 18:08 | ordnungswidrig | dnolen: no, it was only an example. I have a list of devices which have each some properties which values are in a finite domain. I want to generate a set of devices such that 1) every possible value of a single property is covered. 2) every pairwise combination of two properties values are coverred. |
| 18:09 | ordnungswidrig | dnolen: like device1: big, yellow, expensive device2: big, green, cheap, device3: big, yellow, cheep. |
| 18:09 | ordnungswidrig | dnolen: (d1,d2) would cover every property value. |
| 18:10 | ordnungswidrig | dnolen: but for pairwise it would miss a device that is "yellow+cheap" |
| 18:14 | hyPiRion | ordnungswidrig: So put differently, given a set of vectors on the form [x_1 x_2 ... x_n], find the minimal solution where every pair [x_a x_b], 1 <= a, b <= n, is contained within the solution. |
| 18:15 | dnolen | ordnungswidrig: you could encode those values as integers - I've been thinking about some sugar to make it less tedious. |
| 18:15 | ordnungswidrig | hyPiRion: yes, I think this is the formalized variant |
| 18:15 | ordnungswidrig | dnolen: integers would be ok |
| 18:15 | ordnungswidrig | I can map them back later |
| 18:15 | dnolen | ordnungswidrig: will have to wait for some refactoring of the constraint solver. |
| 18:15 | dnolen | ordnungswidrig: then yes that works just fine. |
| 18:16 | dnolen | ordnungswidrig: that's precisely what I did here, http://github.com/clojure/core.logic/blob/master/src/main/clojure/clojure/core/logic/bench.clj#L398 |
| 18:17 | ordnungswidrig | dnolen: how would I ensure that a "minimal" solution will be found? |
| 18:19 | dnolen | ordnungswidrig: hmm ... I believe there are some ad-hoc tricks for that in CLP(FD) literature. More explicit support may be possible a la Mozart/OZ, but I've got nothing planned in the near future. |
| 18:19 | ordnungswidrig | ok |
| 18:19 | ordnungswidrig | I'll dig the literature then |
| 18:20 | hyPiRion | ordnungswidrig: It's an interesting problem though, thanks for sharing. |
| 18:20 | dnolen | ordnungswidrig: google for "Finite Domain Constraint Programming in Oz. A Tutorial.". Most of my understanding of CLP(FD) and far beyond is from their. Haven't time to dig into - there are some things that need fixing first to tackle even the simplest CLP(FD) problems they talk about. |
| 18:21 | ordnungswidrig | dnolen: ok, thanks! |
| 18:21 | ordnungswidrig | I'll go to bed now. Hammock time, or like that. |
| 18:22 | dnolen | ordnungswidrig: I would like a lot of that text to applicable to Clojure. Though the search strategy may be challenging since that's not really covered in the original cKanren design. |
| 18:22 | ordnungswidrig | dnolen: I'd love it! |
| 18:22 | ordnungswidrig | bye! |
| 18:23 | XPherior | with-redefs.. It redefines something within the scope of it's calling that macro. But it doesn't seem to redefine it in other namespaces? |
| 18:24 | XPherior | IE, I redefine the function b to be something else. Within the with-redefs, function a calls b. b appears to be the original b, not the one I substituted in. |
| 18:27 | XPherior | I guess what I'm asking for is a "global function redefinition" |
| 18:30 | technomancy | XPherior: with-redefs works in terms of vars. if someone has a copy of the original version in a local or some such, there's no way to change it. |
| 18:31 | technomancy | other than to pass around vars instead |
| 18:31 | XPherior | technomancy: It's merely calling the other function via namespace. No functions with side effects. |
| 18:31 | SegFaultAX|work2 | hyPiRion: Was that about my code post? |
| 18:31 | XPherior | How would one "hold onto" a function in Clojure? |
| 18:31 | XPherior | Well, I guess with def. But I don't see a case where I used that. |
| 18:38 | technomancy | the classic example is with (run-jetty app {:port 8080}) |
| 18:38 | Sgeo | It occurs to me that if I keep getting bothered when I see individuals who are crucial to an ecosystem in an IRC channel, I will always be bothered |
| 18:39 | technomancy | with-redefs and recompilation won't be visible to jetty since you're passing the value of app; you have to pass in #'app |
| 18:39 | XPherior | technomancy: Go on |
| 18:39 | hyPiRion | SegFaultAX|work2: oh, second. |
| 18:39 | XPherior | Hm.. |
| 18:39 | SegFaultAX|work2 | hyPiRion: I'm interested in your thoughts on how I could make it better. |
| 18:39 | XPherior | Okay, I think that puts me on the right track, technomancy |
| 18:40 | XPherior | I'll be back. Gonna switch out to Linux so I can hack on the problem more. |
| 18:40 | XPherior | Thanks again! |
| 18:40 | hyPiRion | SegFaultAX|work2: So instead of taking 2 elements, namely prev and current, you could take more than 2 |
| 18:41 | hyPiRion | Like n-2 n-1 and n. |
| 18:41 | SegFaultAX|work2 | hyPiRion: I don't know how to make that very general. The usage I was looking at was something like (take-seq #(= (inc %1) %2) [1 2 3 4]) |
| 18:42 | SegFaultAX|work2 | hyPiRion: It would return [1 2 3 4]. But if that seq was, say, [1 2 3 5 6 7] it would only return [1 2 3] |
| 18:42 | hyPiRion | SegFaultAX|work2: What would that one return? |
| 18:42 | hyPiRion | oh, okay. |
| 18:43 | hyPiRion | hmm, second |
| 18:43 | SegFaultAX|work2 | hyPiRion: So where take-while returns values as long as the predicate is true, take-seq does the same thing but it allows you to work with the current and last value to recognize a sequence. |
| 18:55 | hyPiRion | SegFaultAX|work2: https://www.refheap.com/paste/4667 |
| 19:01 | SegFaultAX|work2 | hyPiRion: Awesome! |
| 19:03 | hyPiRion | SegFaultAX|work2: It's not perfect though - it cannot take in an infinite seq and return a new infinite seq |
| 19:04 | hyPiRion | Though if it helps you in any way, then I'm glad to be of help :) |
| 19:04 | SegFaultAX|work2 | hyPiRion: I wanted mine to work on infinite seqs which is why it's so verbose. But your solution is a lot cleaner and more general than mine. |
| 19:05 | SegFaultAX|work2 | partition* are awesome. |
| 19:06 | wmealing_1 | SegFaultAX|work2: did you find an built-in function to split a list on a condition (dichotomize-by ? |
| 19:06 | hyPiRion | yeah, partition and partition-all are more powerful than I thought they would be |
| 19:06 | SegFaultAX|work2 | wmealing_1: Not a built-in, no. |
| 19:07 | SegFaultAX|work2 | wmealing_1: (juxt remove filter) was good enough for my purposes. |
| 19:07 | hyPiRion | split-with? |
| 19:07 | SegFaultAX|work2 | hyPiRion: Nope. |
| 19:08 | wmealing_1 | had me scratching my head for a bit. |
| 19:08 | hyPiRion | Hum, okay |
| 19:08 | hyPiRion | Oh, yeah, I see. |
| 19:08 | wmealing_1 | i ended up writing my own, but i wasn't happy. |
| 19:08 | SegFaultAX|work2 | wmealing_1: The only downside is running through the list twice instead of separating it in one pass. |
| 19:09 | hyPiRion | ,(vals (group-by odd? (range 10))) |
| 19:09 | clojurebot | ([0 2 4 6 8] [1 3 5 7 9]) |
| 19:09 | hyPiRion | The order is scary though |
| 19:09 | hyPiRion | ,(vals (group-by even? (range 10))) |
| 19:09 | clojurebot | ([0 2 4 6 8] [1 3 5 7 9]) |
| 19:09 | hyPiRion | So scratch that. |
| 19:10 | SegFaultAX|work2 | hyPiRion: Yea. This was for a quicksort so I wanted to have all the numbers >= pivot separated from the rest. |
| 19:11 | SegFaultAX|work2 | hyPiRion: My initial solution started with a group-by. The juxt one was better, minus the aforementioned speed penalty. |
| 19:11 | SegFaultAX|work2 | (Better in terms of code size.) |
| 19:12 | amalloy | SegFaultAX|work2: shouldn't take-seq just use partition? |
| 19:13 | hyPiRion | ,(separate odd? (range 10)) |
| 19:13 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: separate in this context, compiling:(NO_SOURCE_PATH:0)> |
| 19:13 | SegFaultAX|work2 | amalloy: How do you mean? I wanted it to be able to recognize arbitrary sequences, not just increasing or decreasing. |
| 19:13 | XPherior | Hey technomancy. The function I'm trying to redefine in used by a route in Compojure's defroutes macro. It must be hanging onto the value of the function that I told it to call when it hits the respective route, huh? |
| 19:14 | amalloy | &((fn take-seq [pred coll] (map second (filter (partial apply pred) (partition 2 1 coll)))) #(= %2 (inc %1)) [1 2 3 5 6 9]) |
| 19:14 | lazybot | ⇒ (2 3 6) |
| 19:15 | SegFaultAX|work2 | amalloy: That's not correct. |
| 19:15 | technomancy | XPherior: yeah, just using a var instead should do the trick |
| 19:15 | amalloy | it matches your docstring |
| 19:15 | XPherior | technomancy: Hm? Instead what? |
| 19:16 | technomancy | instead of the value of the var |
| 19:16 | amalloy | if you want to include the 1 at the front, then you can do the three-arg vs two-arg thing, but i was just demonstrating using partition instead of lazy-seq |
| 19:16 | SegFaultAX|work2 | amalloy: Then my docstring sucks. For context I was working on 4clojure #53 |
| 19:16 | SegFaultAX|work2 | amalloy: Longest subseq of increasing integers. |
| 19:16 | SegFaultAX|work2 | amalloy: Yours does not return the correct answer. |
| 19:17 | XPherior | technomancy: Yeah, that seeems correct. I don't see how to be able to override it for testing though. Is it just not possible? Sorry, my understanding is a little fuzzy here. |
| 19:18 | SegFaultAX|work2 | amalloy: Did you catch hyPiRion's solution? https://www.refheap.com/paste/4667 |
| 19:18 | SegFaultAX|work2 | amalloy: I'm still looking for a good way to implement the general take-seq/take-while-partition "take the longest contiguous sequence given some predicate" function. |
| 19:19 | XPherior | Oh technomancy, sorry I read that wrong. Makes more sense now. |
| 19:26 | amalloy | SegFaultAX|work2: useful.seq/glue has a pretty thorough implementation of that sort of "split a sequence up into N chunks" idea, although it's so flexible it's a bit unwieldy to use in most real-life cases. https://gist.github.com/3493313 has an example usage, and docstring is at https://github.com/flatland/useful/blob/develop/src/useful/seq.clj#L193 |
| 19:33 | hyPiRion | Ah, SegFaultAX|work2, https://www.refheap.com/paste/4669 works on infinite lists too. |
| 19:35 | XPherior | Why would something like with-redefs [#'ns/func substitute-fun] throw lojure.lang.PersistentList cannot be cast to clojure.lang.Symbol |
| 19:35 | XPherior | Werd |
| 19:36 | amalloy | &(doc with-redefs) |
| 19:36 | lazybot | java.lang.SecurityException: You tripped the alarm! with-redefs is bad! |
| 19:36 | amalloy | ,(doc with-redefs) |
| 19:36 | hyPiRion | haha |
| 19:36 | clojurebot | "([bindings & body]); binding => var-symbol temp-value-expr Temporarily redefines Vars while executing the body. The temp-value-exprs will be evaluated and each resulting value will replace in parallel the root value of its Var. After the body is executed, the root values of all the Vars will be set back to their old values. These temporary changes will be visible in all threads. Useful for mockin... |
| 19:36 | amalloy | XPherior: read the docstring |
| 19:37 | XPherior | amalloy: I have many times. =/ |
| 19:37 | XPherior | #' returns a var, as far as I understand. Passing that in as the first element in the vector should be fine |
| 19:37 | amalloy | what do you suppose var-symbol means? i would bet money that it means "this should be a symbol" |
| 19:38 | XPherior | I suppose that makes a bit more sense. But, when I do that, I just get that 'cons cannot be cast to symbol' |
| 19:38 | XPherior | I mean, when it says it rebinds vars, it seems like it wants a var to target. |
| 19:39 | Apage43 | it does (var) aka #' internally. |
| 19:40 | Apage43 | https://github.com/clojure/clojure/blob/d0c380d9809fd242bec688c7134e900f0bbedcac/src/clj/clojure/core.clj#L6589 |
| 19:40 | XPherior | I can't just pass in the function value, because as technomancy were talking about earlier.. Another function already has the value of that function. I'd need to redefine the function at the var level |
| 19:41 | Apage43 | with-redefs is a macro, so you're passing it symbols, not values |
| 19:46 | Frozenlock | I've stumbled uppon this nice little function in a C2 demo code: (defn evt->key [e] (get {13 :enter} (.-keyCode e))) Is it the idiomatic way to get a keypress? |
| 19:47 | Frozenlock | |
| 19:47 | dnolen | Frozenlock: yes |
| 19:48 | Frozenlock | dnolen: thank you |
| 20:01 | SegFaultAX|work2 | amalloy: Awesome, thanks for the tip. I hadn't heard of useful until now. |
| 21:18 | cjfrisz | Everybody must be hard at work here |
| 21:20 | stankley | cjfrisz: Very much so... |
| 21:22 | cjfrisz | Seeing as though I broke my parser last night and it's still mad at me, I should probably be harder at work |
| 21:27 | Frozenlock | Ah crap, I think I opened a can of worms. |
| 21:28 | Frozenlock | -=keyCodes=- |
| 21:28 | uvtc | Hey, where did all these worms come from? ... Frozenlock! |
| 21:31 | cjfrisz | Man...sometimes I think Clojure has too few parentheses |
| 21:31 | shaungilchrist | ahaha |
| 21:32 | cjfrisz | Take "cond" for instance |
| 21:32 | Frozenlock | cjfrisz: Yeah, I don't feel the rush of adrenaline caused by closing 20 parentheses! ))))))))))))))))0 |
| 21:33 | cjfrisz | Scheme has an extra set of brackets around each clause |
| 21:33 | cjfrisz | This makes indent functions in text editors much happier if you need to make a line break after the test |
| 21:33 | shaungilchrist | I like to accelerate as I type them so it's literally a rush |
| 21:49 | Frozenlock | Before I waste a night trying to make some hotkeys functions for cljs, does anybody know if there's already a library for this? (in cljs) |
| 21:59 | Raynes | Frozenlock: Why does it have to be in cljs? |
| 22:03 | Frozenlock | It could also be in google closure (I haven't found one). If I understand correctly, google closure or cljs are what is required to be able to use the compiler efficiently. |
| 22:31 | Spaceghostc2c | Please sir, may I have some clojure? |
| 22:34 | cjfrisz | Spaceghostc2c: ...yes? |
| 22:34 | Spaceghostc2c | cjfrisz: I think my british accent was off. |
| 22:34 | cjfrisz | Oh! |
| 22:34 | cjfrisz | Spaceghostc2c: More? |
| 22:34 | cjfrisz | Spaceghostc2c: You want *MORE*?? |
| 22:34 | lazybot | cjfrisz: What are you, crazy? Of course not! |
| 22:36 | Spaceghostc2c | Well done gents! We'll be here all week. |
| 23:06 | emezeske | Frozenlock: You can use any javascript library you want from cljs, as long as you provide an :externs file |
| 23:07 | emezeske | Frozenlock: (The :exterms file lets you compile with :advanced optimizations) |
| 23:10 | Frozenlock | emezeske: But the extern files won't be included in the generated js? |
| 23:10 | Frozenlock | (that might not be a big deal) |
| 23:11 | emezeske | Frozenlock: This probably will answer your question: http://lukevanderhart.com/2011/09/30/using-javascript-and-clojurescript.html |
| 23:11 | Frozenlock | Thanks! |
| 23:45 | TimMc | Frozenlock: Man, who even types closing parens? |
| 23:45 | TimMc | That's so... without paredit. :-P |
| 23:46 | cjfrisz | So...I used to use paredit |
| 23:46 | tomoj | that's surprising |
| 23:46 | cjfrisz | And I had a couple of very prolific Schemers convince me that it can be detrimental to hacking out scraps of code |
| 23:47 | cjfrisz | There are things I miss about it, but I think I am overall happier |
| 23:47 | cjfrisz | You inherently get corralled into writing your code in a particular way when you use tools like paredit that force structure on your coding while you're in the process of writing it |
| 23:48 | uvtc | TimMc: I have not yet drank of the paredit coolaid. I kinda' like watching those matching parens light up when I type the closing ones. :) |
| 23:48 | cjfrisz | There's nothing necessarily wrong with it, but it is something I hadn't thought about when I started using it |
| 23:48 | cjfrisz | uvtc: I totally drank the paredit coolaid at first ;-) |
| 23:48 | arohner_ | cjfrisz: it convinces you to *type* your code in a different way, but I'm reasonably sure I'm net productive on it |
| 23:48 | Frozenlock | TimMc: Yeah, paredit is among the numerous tools I've yet to try. |
| 23:49 | arohner_ | never having misbalanced parens has definitely improved my flow |
| 23:49 | cjfrisz | arohner_: Mileage may vary |
| 23:49 | cjfrisz | arohner_: I don't doubt that you are very productive, and you may even be moreso than me |
| 23:49 | tomoj | you get corralled into writing your code in valid forms |
| 23:49 | tomoj | how could that be a bad thing? |
| 23:49 | eggsby | did anyone itc finish stripes CTF and mind lending a hint ? |
| 23:49 | emezeske | cjfrisz: You get corralled into writing code that has balanced and structurally correct paranthesis, but that's about it |
| 23:50 | emezeske | Every time you balance parens manually, God kills a kitten and replaces it with a slightly less productive kitten |
| 23:52 | Frozenlock | Eh, the time I waste writing parens in clojure is negligible. |
| 23:52 | Frozenlock | I waste way more time by being stupid. |
| 23:52 | Frozenlock | \o/ |
| 23:52 | tomoj | it's not just auto-balancing |
| 23:53 | uvtc | Might save my right pinky some fatigue though ... not having to reach for that closing paren. :) |
| 23:53 | tomoj | (and you must also count the time spent dealing with balance errors) |
| 23:53 | emezeske | Tell me this: do you literally count the number of parens at the end of a function sometimes? And that doesn't drive you bats? |
| 23:53 | Frozenlock | (show-paren-mode) |
| 23:54 | emezeske | Still, you're basically counting. Keep moving the cursor until the paren you want is highlighted, right? |
| 23:54 | uvtc | I never count ... just let Emacs show me the matching one. It smartly highlights it when the cursor is just after the closing one. |
| 23:55 | Frozenlock | Yes. |
| 23:55 | Frozenlock | I can has bad methodz? |
| 23:55 | emezeske | To each his own. |
| 23:55 | TimMc | You don't have to use it, but you do have to try it. |
| 23:56 | cjfrisz | emezeske: That's really the crux of it |
| 23:56 | cjfrisz | I used to have a workflow that jived with paredit |
| 23:56 | Frozenlock | Yes it's on my todo list. This and elnode are on the top. |
| 23:56 | uvtc | Will try it, at some point ... just need to get this program working ... |
| 23:56 | cjfrisz | And then I worked with some people who showed me a workflow where paredit kinda got in the way |
| 23:56 | emezeske | cjfrisz: Like what? |
| 23:56 | cjfrisz | And for now I use the latter |
| 23:56 | TimMc | It's more than paren balancing -- it is structural editing. Kill a whole form at a time, or transpose it with another, or convolute them... |
| 23:56 | emezeske | I cannot possibly see how it could get in the way. |
| 23:57 | tomoj | cjfrisz: any possibility you can give an example? |
| 23:57 | Frozenlock | TimMc: To select forms I like expand-region.el |
| 23:57 | TimMc | It's hard to give examples, since code evolves in weird ways. |
| 23:57 | emezeske | You can always shut paredit off temporarily while you do some crazy pasting, and then turn it back on |
| 23:58 | Frozenlock | http://emacsrocks.com/e09.html |
| 23:58 | cjfrisz | Maybe it's less that it gets in the way and more that it's just not helpful |
| 23:58 | cjfrisz | I've started writing more of an unfinished scrap here, moving on, and then coming back to the unfinished bits |
| 23:59 | emezeske | I refuse to believe that it's more productive to write in units of not-even-structurally-correct code. |
| 23:59 | cjfrisz | I found it more helpful when there were no scraps; only plunking out complete thoughts at a time |
| 23:59 | cjfrisz | emezeske: That's fine; you don't have to |