2011-09-03
| 00:00 | livingston | jblomo: that's a little wired but not that odd.. why not just switch on type or use dispatch |
| 00:00 | livingston | or just make your caller call list |
| 00:01 | jblomo | i usually like functions that are flexible and just do what i want |
| 00:01 | livingston | (it's not that odd because a recursive function might work like that) |
| 00:01 | jblomo | i'll do a sanity check to make sure i haven't written something wrong, thoguh :) |
| 00:02 | amalloy | that's a good point, livingston |
| 00:02 | amalloy | clojurebot: please cancel my previous accusations of wrong-ness |
| 00:02 | clojurebot | Titim gan éirí ort. |
| 00:02 | livingston | but then you'd have a switch right at the top is this one things or many?... |
| 00:03 | amalloy | livingston: depending on the sort of recursive function, i'd make it a protocol |
| 00:03 | livingston | why does everyone want to shove everything in an object... |
| 00:04 | amalloy | livingston: who said? see https://github.com/clojure/data.xml/blob/master/modules/xml/src/main/clojure/clojure/data/xml.clj#L196 |
| 00:05 | amalloy | it's just polymorphism based on the type of the argument, without the gross/slow `switch` at the top |
| 00:05 | livingston | that's to make existing objects seq-able, that's fine. but if you just have lists of stuff that's perfectly fine |
| 00:06 | amalloy | often you're right, which is why i said "depending on the type of recursive function" |
| 00:06 | livingston | amalloy: some kind of recursing on item/list is still going through dispatch ... you're not saving anything (there's no way the compiler knows ahead of time how many are in your list etc.) |
| 00:07 | livingston | I'm just near to much java - the kingdom of nouns and all ;) |
| 00:07 | amalloy | livingston: that's not exactly true. the jvm can dispatch on type faster than you can do an if/else and dispatch yourself |
| 00:08 | amalloy | maybe if there are only two types involved, seq/string, then that's not true |
| 00:08 | amalloy | but in general if you're dispatching on type and you care about speed, you should let the jvm get involved |
| 00:08 | livingston | I'm inclined to say that's crazy how could that be, but everytime I've done that with clojure I'm likely to be wrong, so .. ok |
| 00:09 | amalloy | most of the time at least one of those statements is false, so i don't bother with protocols |
| 00:09 | livingston | oh sure if it can turn it into a jump-table maybe |
| 00:09 | amalloy | right |
| 00:09 | amalloy | livingston: it can in fact do even better |
| 00:10 | livingston | then you pay for hashing. in some good CL implementations you could scan 30 items in a list before a hash got faster |
| 00:10 | amalloy | get the JIT involved and say "hm, this function has been called a thousand times, and EVERY TIME x was an instance of List. i'll just inline a jump to List.foo, and leave a note that if someone ever passes in a non-List i need to recompile" |
| 00:11 | amalloy | it's all magic to me, of course, but i understand it does things like that regularly |
| 00:12 | livingston | compilers are smart |
| 00:13 | amalloy | yeah, and JIT compilation can optimized based on runtime information |
| 00:33 | solussd | If I want to extend array-map and hash-map, do I extend the java.util.map interface? |
| 00:34 | amalloy | i think the first thing you do is ask yourself what you mean by "extend" |
| 00:34 | livingston | ,(doc hash-map) |
| 00:34 | clojurebot | "([] [& keyvals]); keyval => key val Returns a new hash map with supplied mappings." |
| 00:34 | solussd | amalloy: with a protocol ? |
| 00:35 | amalloy | then no, extend it to clojure.lang.IPersistentMap |
| 00:35 | solussd | excellent. thanks! |
| 00:35 | amalloy | solussd: see ##(supers (class {})) |
| 00:35 | lazybot | ⇒ #{clojure.lang.APersistentMap clojure.lang.Associative clojure.lang.IObj clojure.lang.AFn java.lang.Iterable java.io.Serializable clojure.lang.IPersistentMap clojure.lang.MapEquivalence clojure.lang.Counted clojure.lang.IMeta java.util.concurrent.Callable java.lang... https://gist.github.com/1190567 |
| 00:35 | amalloy | pick the one that most closely resembles what you want to extend, and go from there |
| 00:36 | solussd | makes sense |
| 00:36 | solussd | and wow, that's a lot of interfaces, etc |
| 00:36 | amalloy | clojure loves interfaces, yeah |
| 00:39 | gaze__ | Hey, what would be the best way to do a sort of message queue thing in clojure? |
| 00:40 | gaze__ | a la erlang message passing |
| 00:40 | livingston | could you be more specific "a sort of message queue thing" |
| 00:40 | gaze__ | yeah sorry that was pretty nonspecific, haha. |
| 00:40 | livingston | you could probably use an atom |
| 00:42 | solussd | what's the 'isa?' equivalent to check if an object implements an interface or protocol? |
| 00:43 | amalloy | solussd: turn that into two separate questions: interface, or protocol? |
| 00:44 | solussd | interface |
| 00:44 | amalloy | isa? |
| 00:44 | solussd | more generally, I want to know if something is a map or a list/vector/seq |
| 00:44 | amalloy | &(doc map?) |
| 00:44 | lazybot | ⇒ "([x]); Return true if x implements IPersistentMap" |
| 00:44 | solussd | ,(isa? [] clojure.lang.IPersistentCollection) |
| 00:44 | clojurebot | false |
| 00:45 | amalloy | &(isa? clojure.lang.IPersistentCollection []) |
| 00:45 | lazybot | ⇒ false |
| 00:45 | amalloy | oh right |
| 00:45 | amalloy | instance? |
| 00:46 | solussd | isn't that just for classes? |
| 00:46 | solussd | ,(instance? clojure.lang.IPersistentCollection []) |
| 00:46 | clojurebot | true |
| 00:46 | amalloy | interfaces are classes |
| 00:46 | solussd | ;) |
| 00:46 | amalloy | &(class clojure.lang.IPersistentCollection) |
| 00:46 | lazybot | ⇒ java.lang.Class |
| 00:51 | amalloy | livingston: btw, your remark that people want to put everything in an object reminded me of http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/aop/framework/AbstractSingletonProxyFactoryBean.html |
| 00:53 | livingston | amalloy: I don't know what that is but just reading the name of that thing makes me agitated if not angry |
| 00:53 | amalloy | i don't think anyone knows what it is, or they would never have written it |
| 00:53 | amalloy | http://www.classnamer.com/ is a less-painful, more-fun take on the same thing |
| 00:54 | livingston | I like how the doc starts with "convenient..." |
| 00:54 | livingston | ok that thing is awesome... |
| 00:59 | livingston | thanks everyone, I'm out of here. |
| 01:00 | jblomo | is there a way to stick a primitive long into a map? I keep find it converted |
| 01:00 | jblomo | boxed |
| 01:00 | amalloy | no |
| 01:18 | gaze__ | is there any way to turn a quoted sexp into a string an vis-versa? |
| 01:19 | amalloy | &(doc pr-str) |
| 01:19 | lazybot | ⇒ "([& xs]); pr to a string, returning it" |
| 01:19 | amalloy | &(doc read-string) |
| 01:19 | lazybot | ⇒ "([s]); Reads one object from the string s" |
| 01:20 | gaze__ | ahh, thanks a bunch :D |
| 01:20 | gaze__ | I'd like to try and come up with a way to have a really natural interface for storing that I want to call a function in a database, and then having it read that record out with all the arguments and actually call it |
| 01:21 | gaze__ | should be pretty simple, right? |
| 01:38 | gaze__ | actually wait... pr-str gives me some funky #<blah$something blah$blah@0xblah> which would seem to imply it cares about where that bit is loaded |
| 01:38 | gaze__ | so if I kill the vm, restart it, reload that function, that string won't actually get me back to the same function, will it? |
| 01:38 | amalloy | functions are not readably-printable |
| 01:39 | amalloy | especially not closures |
| 01:40 | gaze__ | I don't care so much that it's readable... I just want to store a blob somewhere that allows me to call that function again with say... no environment. |
| 01:40 | gaze__ | do I wanna write a macro like (defresumable name [args] contents) that defs the function as well as adds an entry to a table somewhere? |
| 01:41 | amalloy | closures already are what you want, except that they're not readable |
| 01:43 | gaze__ | readable? |
| 01:43 | amalloy | from a string |
| 01:44 | amalloy | closures are already "resumable" from within a single VM, and just writing some crap to a table somewhere isn't going to make your function "resumable" from a different VM |
| 01:45 | gaze__ | sorry, I don't mean resumable... that was a really bad choice of words. Basically this is just a mechanism to ensure that if the VM dies in the middle of a function, when I start the program back up, that function will get started from the beginning again. |
| 01:45 | gaze__ | with the same set of arguments |
| 01:46 | gaze__ | that's what I meant to set out to do from the beginning |
| 01:47 | gaze__ | say I have a system designed to transcode videos or something. If a web user comes in, uploads a file, the raw file is sitting somewhere... and then the app calls (transcode "/path/to/video.avi"), that should start and complete. If there's a power outage, I want that transcoding to still happen. |
| 01:49 | gaze__ | so if there's a table somewhere with "transcode", "/path/to/video.avi" somewhere that gets scrubbed on startup, etc. etc. |
| 01:52 | amalloy | then don't store functions. just create a simple schema for "pending tasks" |
| 01:53 | amalloy | pending.clj => {:tasks {1341 {:type :transcode :args "/path.avi"}}} |
| 01:55 | gaze__ | it'd just be nice to have an interface where I can sorta (deftask transcode [args] (do stuff)), and then (invoketask transcode "/path.avi"), and all the bookkeeping is handled for me |
| 01:56 | gaze__ | I mean, isn't the lispy way to do it to create a ton of macros and make it all nice and transparent? :D |
| 01:57 | amalloy | so do that. but you still need a storage schema, and just storing functions or code isn't going to be a good one |
| 01:58 | gaze__ | oh no no, the idea was never to store the function or code, just a way to get back to it. |
| 01:58 | gaze__ | what I wanted was to be able to do ((read-string "println") "hello") |
| 01:59 | gaze__ | only, instead of println, it'd be some stuff from that table, and instead of "hello", it'd be the stored args. |
| 02:57 | gaze__ | "java.lang.ArrayIndexOutOfBoundsException: 1 [Thrown class clojure.lang.LispReader$ReaderException]" |
| 02:57 | gaze__ | from the interpreter |
| 02:57 | gaze__ | would be a bug, yes? |
| 03:02 | hiredman | doubt it |
| 03:02 | hiredman | (well, yes a bug in your code, sure) |
| 03:14 | amalloy | &(read-string "{x}") |
| 03:14 | lazybot | java.lang.ArrayIndexOutOfBoundsException: 1 |
| 03:16 | amalloy | gaze__: ^ |
| 08:00 | nizze | Hi! |
| 08:00 | nizze | Why clojure does not have [1..100] syntax for creating vectors? |
| 08:03 | Netpilgrim | nizze: Hi. I guess (range 1 101) does what you want. Not short enough? |
| 08:03 | nizze | Netpilgrim: thanks I know about (range 1 100) |
| 08:03 | nizze | I'm just curious |
| 08:03 | Netpilgrim | nizze: And if it has to be a vector: (vec (range 1 101)) |
| 08:03 | nizze | :) |
| 08:05 | nizze | Could I write a macro to impelment [1..100]? |
| 08:05 | nizze | Or actually 1..100 |
| 08:06 | Netpilgrim | nizze: The language designers probably wanted to keep the syntactic sugar to a minimum. And in this case it wouldn't really be a big improvement. |
| 08:06 | nizze | Netpilgrim: Okay, thanks :) |
| 08:06 | nizze | What I like about clojure compared to scheme is that it has sugar |
| 08:06 | Netpilgrim | nizze: I have no experience with macros but I think they have to be of the form (macro-name …) like function calls. |
| 08:06 | nizze | Easier to read. |
| 08:07 | nizze | Okay |
| 08:07 | Netpilgrim | nizze: I'm still very new to the language, and I've just fallen in love with -> and ->>. :) |
| 08:07 | nizze | Yeah, those are cool, you should check .. as well :D |
| 08:09 | Netpilgrim | Isn't it (.. o (m1) (m2)) the same as (-> o (.m1) (.m2))? |
| 08:10 | Netpilgrim | s/it // |
| 08:13 | Netpilgrim | Apparently you can call static methods with .. but not with ->. |
| 08:21 | Netpilgrim | Is there a limit on how many function calls I can chain together with ->? I suddenly get a ClassCastException after a few almost identical calls in this code: https://gist.github.com/1191098 |
| 08:28 | raek | Netpilgrim: which function is the exception thrown from? |
| 08:29 | Netpilgrim | raek: Apparently set-edge on the marked line. |
| 08:30 | Netpilgrim | raek: It's curious because on the two lines above it I call the exact same function. |
| 08:30 | raek | but no, there shouldn't be any limit on the number of forms |
| 08:31 | raek | if you get an exception at runtime, it's not ->'s fault, since it's gone then |
| 08:31 | raek | (because it is a macro) |
| 08:32 | Netpilgrim | raek: Ah, ok. It seems the exception is thrown the third time set-edge is called, no matter what order the calls are in. |
| 08:33 | raek | I would recomment to look the stacktrace to see which line of the set-edge function it is thrown from |
| 08:34 | Netpilgrim | raek: Do you know how I can get a full stacktrace in slime-repl? |
| 08:34 | raek | you should get one |
| 08:34 | raek | maybe you need to click on the cause lines |
| 08:35 | khaliG | Netpilgrim, try (.printStackTrace *e) (i've been reading Joy :P) |
| 08:35 | raek | but the whole exception chain should be available in the buffer that pops up |
| 08:36 | Netpilgrim | raek: The compilation buffer only contains this one line I've quoted in the gist. |
| 08:37 | Netpilgrim | khaliG: (.printStackTrace *e) returns nil. |
| 08:38 | raek | Netpilgrim: do you get the exception when you compile or when you run it? |
| 08:38 | Netpilgrim | raek: When I compile it. |
| 08:39 | raek | try calling (require 'yout-ns :reload) in the repl |
| 08:42 | raek | seems like you don't get good stack traces when you don't use the repl |
| 08:42 | raek | anyway, I think this line is the problem: (conj (em from) to) |
| 08:42 | raek | and that em is a list thre |
| 08:43 | Netpilgrim | raek: "Could not locate yout_ns__init.class or yout_ns.clj on classpath" |
| 08:43 | raek | you coult also try to comment out the test-graph form from the file, copmile it, and the run that code in the repl |
| 08:44 | Netpilgrim | raek: Ah, you probably meant 'your-ns. :) |
| 08:44 | raek | or replace (def test-graph ...) with (defn test-graph [] ...) and call (test-graph) in the repl |
| 08:44 | raek | Netpilgrim: I meant whatever your namespace is called |
| 08:44 | Netpilgrim | raek: I got that now. |
| 08:45 | Netpilgrim | raek: require leads to the same ClassCastException. I'll try running the -> form in the repl. |
| 08:46 | raek | Netpilgrim: make the test thing a function. then you will have compile-time and run-time separate |
| 08:51 | Netpilgrim | raek: Wow, that's strange. I have made it a function (https://gist.github.com/1191098) and now it compiles and runs ok. |
| 08:52 | Netpilgrim | raek: It smells like a bug in the compiler. |
| 08:54 | hugod | shouldn't that be update-in rather than conj in set-edge? |
| 08:55 | raek | Netpilgrim: when I take your original code and turn test-graph into a function, I still get the exception when I run it |
| 08:56 | raek | same thing with your second gist |
| 08:57 | raek | Caused by: java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.IFn |
| 08:57 | raek | at user.DirectedGraph.set_edge(NO_SOURCE_FILE:175) |
| 08:58 | raek | if you compile it in emacs, rather than typing it in in the repl as I did now, you should get a line number too |
| 08:58 | Netpilgrim | raek: Keeps getting stranger. I can't reproduce the problem, now that it's a function. |
| 08:58 | raek | Netpilgrim: which namespace is the repl in? |
| 08:59 | raek | Netpilgrim: and you run (test-graph) in the repl? |
| 08:59 | Netpilgrim | raek: You can see the line number here: https://gist.github.com/1191098/5191de8a71d2f1c579c6171d1b553da5ccf47306 |
| 08:59 | raek | is this gist the whole file? if so, you're missing a namespace declaration |
| 09:00 | Netpilgrim | raek: Yes, I run the test-graph in the repl and it's in the same namespace as the function. |
| 09:00 | Netpilgrim | raek: I've left out the namespace declaration (and some other stuff) in the gist. |
| 09:00 | raek | what happens when you run (test-graph)? |
| 09:00 | raek | I get an sception there |
| 09:00 | raek | *exception |
| 09:01 | raek | anyway, I have to go. good luck! |
| 09:01 | Netpilgrim | raek: Damn, when I remove everything but what I've posted in the gist and call the function in the namespace "user" I get the exception again. |
| 09:02 | raek | how do you compile the file? |
| 09:04 | Netpilgrim | raek: slime-compile-and-load-file |
| 09:04 | raek | anyway, it's easier for others to debug if you post the whole file as it is |
| 09:05 | raek | but now I really have to go. |
| 09:05 | hugod | (update-in em [from] conj to) |
| 09:06 | Netpilgrim | hugod: Sorry, I wanted to get back to you on that. I'm not familiar with update-in. Is it just nicer or do you think my code is (semantically) wrong? |
| 09:07 | Netpilgrim | hugod: O, now I see the problem. Thanks for the hint. |
| 09:08 | Netpilgrim | hugod: Wow, this gets rid of the compilation problem. I just don't see how. |
| 09:09 | Netpilgrim | raek: Thanks for your help. |
| 09:11 | hugod | the original call to conj was returning a list, which was used as the value of em in the next set-edge call, giving rise to the exception you were seeing |
| 09:13 | Netpilgrim | hugod: Now there's just the mystery why compilation and run did work with one specific namespace. |
| 09:14 | Netpilgrim | hugod: But as long as something like this doesn't come up again, I can live with that. |
| 09:14 | khaliG | is scheme a better choice for making android apps than clojure? |
| 09:40 | bsteuber | khaliG: I'd stick to ClojureScript |
| 09:40 | bsteuber | but to be fair, I don't know anything about scheme android dev |
| 09:40 | zilti | Why would you compile Clojure to JavaScript if it has to run on a JVM anyway on Android? |
| 09:41 | bsteuber | why should javascript run on a jvm? |
| 09:41 | khaliG | bsteuber, I dont know anything about it either - but reading about how kawa scheme has full support for android and it runs fast without the problems clojure seems to have on the same platform |
| 09:42 | bsteuber | the thing is, if you use clojurescript, things run in any browser, so you even got iPhone in the boat |
| 09:42 | bsteuber | but of course it might depend on the type of your app |
| 11:58 | gaze__ | hey, what would be the nicest way to go about composing a list over the duration of a function... kinda like with the list monad in haskell, but without clojure's funky monad syntax |
| 11:58 | gaze__ | is there anything better than a let-bound mutable vector? |
| 12:51 | chouser | gaze__: yes, there is something better. |
| 12:51 | chouser | by definition. a let-bound mutable is to avoided if at all possible. |
| 12:52 | chouser | what about conjing onto a vector, passing it forward from one step in the function to the next. |
| 12:59 | solussd | I usually just don't, but what is the preferred way to enforce arg types to a function? |
| 12:59 | solussd | e.g. I want a function to throw an exception if not called with a keyword |
| 13:00 | solussd | pre/post conditions? |
| 13:06 | robermann | if I'd want to double a number, which whould be better / more idiomatic: using a partial as (defn pdouble [x] ((partial * 2) x)) or using a closure as (def times-two (let [x 2] (fn [y] (* y x)))) ? |
| 13:14 | gaze__ | chouser: I'm afraid I don't understand |
| 13:16 | gaze__ | what would that look like? |
| 13:19 | solussd | robermann: what's wrong with (defn [x] (* 2 x)) ? |
| 13:19 | solussd | *function-name |
| 13:23 | robermann | mmm I was tr |
| 13:23 | robermann | ying to find when to use a partial and when to use a closure |
| 13:24 | robermann | these are new concepts for me, and I'm going to study them |
| 13:25 | robermann | isn't a closure a partial function? |
| 13:25 | gaze__ | a closure is a function tied with it's environment. |
| 13:26 | solussd | a closure is a function that 'closes over' its environment |
| 13:28 | robermann | but here the partial isn't closing over the two? (def two 2) (defn pdouble [x] ((partial * two) x)) |
| 13:28 | robermann | or maybe this example is too simple to be interesting |
| 13:29 | solussd | the function partial takes a function and any number of args and returns a function that calls the original function with the args it was created with plus any args passed to it |
| 13:31 | gaze__ | I guess I don't understand how you'd write a DSL in closure... how do you go about threading state through a series of functions? |
| 13:31 | solussd | define state as the application of functions? :D |
| 13:34 | solussd | moving a data structure from one state to the next is modeled functionally as (def next-state (move-to-next-state original-state)) |
| 13:34 | gaze__ | let's put it this way... I wanna be able to do (foo [x] (add-to-list 3) (add-to-list 4) (if x > 8 (add-to-list 5))) (foo 3) => (3 4) ; (foo 9) => (3 4 5) |
| 13:35 | solussd | there be side-effects |
| 13:36 | gaze__ | sure! but haskell seems to handle this sorta thing fine |
| 13:36 | gaze__ | I mean... there's a ton of desugaring |
| 13:36 | gaze__ | I was just hoping there'd be something similar |
| 13:37 | gaze__ | basically I want to build up a transaction over the lifetime of my function, and before the function returns I'd like to commit it atomically. |
| 13:38 | michaelr525 | heyo |
| 13:38 | michaelr525 | ! |
| 13:47 | solussd | gaze__: (defn foo [x] (let [add-5? (fn [y] (if (> x 8) (conj y 5) y))] (-> [3] (conj 4) add-5?))) |
| 13:48 | solussd | use the threading macro to thread your list (in this case, a vector) through each step |
| 13:50 | solussd | more concisely, (defn foo [x] (let [add-5? #(if (> x 8) (conj % 5) %))] (-> [3] (conj 4) add-5?))) |
| 13:56 | ShereKahn | Hi, I am writing a tool to extract values from the output of commands of a system (in this case a router). The approach I have taken is to write a "parser" that is actually matching the output based on templates. |
| 13:57 | ShereKahn | but the problem I have is that I have some sub-structure in the show, so I thought that I could use some recursive function to go through the templates and the actual tokens |
| 13:58 | ShereKahn | so the issue I have is that I would need to have something that would do (while tokens (parse ...)) where the parse would send back the result and the remaining tokens if any |
| 13:58 | ShereKahn | but I am not sure how this is possible |
| 13:59 | ShereKahn | e.g. passing a ref to change the state of the remaining tokens for the while ? |
| 14:00 | ShereKahn | or is there anything more idiomatic in clojure to do that ? |
| 14:04 | ShereKahn | otherwhise put, say I have a (let [token ...] (while token (do-something (token))), is there a way for the do something to change the bindings for 'token' from inside the 'while' or the 'do-something' ? |
| 14:06 | ShereKahn | similar to what CL '(setf token new-value) ' would do ? |
| 14:07 | Netpilgrim | Can someone explain to me why the pre conditions at https://gist.github.com/1191537 are ignored? |
| 14:12 | Chousuke | ShereKahn: if you want something stateful you will need an atom or something |
| 14:13 | Chousuke | ShereKahn: however it should be entirely possible to make a stateless parser |
| 14:14 | Chousuke | actually I might have a gist somewhere that implements a simple one |
| 14:15 | ShereKahn | Chosuke : thanks I would be grateful to see it. |
| 14:23 | Chousuke | ShereKahn: https://gist.github.com/141085 I did it as a monad exercise but maybe it will give you an idea or two :) |
| 14:24 | ShereKahn | Chousuke: thanks a lot for that! I hope it'll give me enough ideas to get me unstuck |
| 14:24 | Chousuke | ShereKahn: there's also a clojure parser combinator library that you might be able to use |
| 14:25 | Chousuke | fparse or something? I don't remember exactly |
| 14:49 | rindolf | Hi all. How do I run labrepl? |
| 14:52 | rindolf | https://github.com/relevance/labrepl/wiki/Maven - I see. |
| 15:16 | scode | Would the with-private-fns macros as descibed at http://nakkaya.com/2009/11/18/unit-testing-in-clojure/ still be idiomatic for unit testing private functions in a namespace? |
| 15:21 | amalloy | Chousuke, ShereKahn: fnparse |
| 15:31 | arohner | scode: if you're not calling the fns too often , you can just ((var your-private-fn) foo) |
| 15:32 | arohner | sigh, anyone gotten a ring app to run on heroku? I'm getting Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 60 seconds of launch, and no other helpful information |
| 15:34 | scode | arohner: Interesting work-around, thanks! |
| 15:34 | michaelr525 | what work-around?! |
| 15:47 | icey | arohner: I have a ring app up there, but didn't run into any errors like that |
| 15:48 | icey | arohner: it's a tiny app, it barely does anything: https://github.com/pmn/peeranoia |
| 15:51 | arohner | icey: thanks |
| 15:52 | icey | arohner: do you have a Procfile defined? It sucks that the error message is so ambiguous. I have a noir app deployed out there that does a little more (but not much more) and it's working alright too (just checked on them to make sure they were still running) |
| 15:53 | arohner | icey: yes, I have a procfile, just 'lein run -m my-ns.server' |
| 15:53 | arohner | it's a noir app, with very few changes |
| 15:54 | arohner | I'm thinking there's an exception on startup that's not getting logged |
| 15:55 | icey | arohner: the procfile for my noir app just says "web: lein run", but having the -m <ns> shouldn't make a difference, right? |
| 15:55 | arohner | icey: yeah, I've tried it both ways |
| 15:56 | icey | hmmm. this is what my server.clj looks like: https://gist.github.com/1191690 |
| 15:56 | icey | (for the noir app) |
| 15:57 | arohner | icey: yeah, mine looks almost identical |
| 15:57 | icey | arohner: do you connect to a database or anything like that? |
| 15:57 | arohner | icey: nope |
| 15:58 | arohner | I have some static files I serve out of /resources, but that's about it |
| 15:59 | icey | have you tried deleting the heroku app and creating a new one? the only thing i can find on google about the R10 error appear to be database related - either a bad database.yaml was included, or the correct database was defined and is unreachable |
| 15:59 | arohner | sigh. Now it's working, and I don't know why |
| 15:59 | arohner | icey: thanks for your help |
| 16:00 | icey | arohner: chalk it up to random sunspot activity or something ;) |
| 18:10 | sirn | Anyone knows if Compojure still requires the (assoc-in response [:headers "Content-Type"] "whatever; charset=utf-8") middleware stuff for UTF-8 support? |
| 18:11 | jblomo | it looks like the current version adds it already |
| 18:11 | jblomo | https://github.com/weavejester/compojure/blob/master/src/compojure/response.clj |
| 18:12 | sirn | jblomo: awesome, thanks! |
| 18:23 | jblomo | what is the scope of extend-protocol? if you extend a protocol in (ns user (:require foo)) will the extension be in effect inside foo? |
| 18:28 | akhudek | is there a way to get a java iterator for a clojure seq? This is for interop purposes. |
| 18:28 | amalloy | sim: that's only setting utf-8 when you tell compojure to render a string. if you render anything else, it looks like it doesn't necessarily add utf-8 (and it shouldn't, since it doesn't know what content encoding, say, a file on the local hard disk is) |
| 18:28 | amalloy | &(doc seq-iterator) |
| 18:28 | lazybot | java.lang.Exception: Unable to resolve var: seq-iterator in this context |
| 18:28 | amalloy | &(doc iterator-seq) |
| 18:28 | lazybot | ⇒ "([iter]); Returns a seq on a java.util.Iterator. Note that most collections providing iterators implement Iterable and thus support seq directly." |
| 18:28 | akhudek | I mean the other way :) |
| 18:28 | amalloy | &(supers (class (clojure.lang.SeqIterator. (seq [1 2])))) |
| 18:28 | lazybot | ⇒ #{java.util.Iterator java.lang.Object} |
| 18:29 | akhudek | that will work? hm thanks |
| 18:29 | amalloy | akhudek: but seqs are already Iterable |
| 18:29 | amalloy | if java wants an Iterator instead of an Iterable, that's not very pleasant |
| 18:29 | akhudek | this function wants: Iterator<List<String>> |
| 18:30 | akhudek | I think the inner type can be an iterator too |
| 18:30 | amalloy | akhudek: right, my point is that's a dumb thing to want as of java 1.5, which is like a decade old. if you can get them to accept an Iterable instead... |
| 18:31 | akhudek | the code is part of mahout, I may try to submit a request, but I imagine it's unlikely to be changed any time soon |
| 18:31 | akhudek | https://builds.apache.org/job/Mahout-Quality/javadoc/org/apache/mahout/fpm/pfpgrowth/fpgrowth/FPGrowth.html |
| 18:38 | chouser | I think just (.iterator your-seq) should work |
| 18:39 | chouser | akhudek: ^^^ |
| 18:41 | akhudek | yep, that seems to work, thanks chouser |
| 18:52 | mudge | how do I make Clojure fully evaluate this map call: (map #(str project-path %) ["lib/*:" "src/:" "resources/"]) |
| 18:52 | akhudek | doseq |
| 18:52 | amalloy | uhhhh. you can stick a doall in front, but since this operation has no side effects that really won't do anything interesting |
| 18:53 | akhudek | or doall rather |
| 18:53 | mudge | I tried (doall (str (map #(str project-path %) ["lib/*:" "src/:" "resources/"]))), but it doesn't work |
| 18:53 | amalloy | clojurebot: bug report? |
| 18:53 | clojurebot | A bug report has three parts: What you did; what you expected to happen; what happened instead. If any of those three are missing, it is awfully hard to help you. |
| 18:54 | amalloy | maybe i should get him to reword that so it's clear it applies to "this doesn't work" |
| 18:57 | amalloy | but mudge, it sounds like you're trying to implement (System/getProperty "java.class.path"). aside from the fact that your implementation doesn't work, is there a reason not to use the builtin? |
| 18:57 | mudge | amalloy, i'm trying to setup a classpath for calling java |
| 18:58 | mudge | amalloy: i found a way, so I am good |
| 18:59 | amalloy | mudge: just call lein classpath |
| 18:59 | amalloy | or cake classpath |
| 18:59 | mudge | amalloy: i don't have lein on the remote server where the production server is |
| 19:01 | mudge | is there a takeall function for taking all the elements from a lazy seq? |
| 19:02 | amalloy | mudge: this is exactly as crazy as crazy as "fully evaluate this map call". a lazy seq already contains all of its elements; taking them all doesn't mean anything. you need to be more clear about what your goal is, rather than asking a solution to a sub-problem you think you need to solve |
| 19:04 | mudge | amalloy: yes, makes sense |
| 19:05 | mudge | amalloy: i am trying to append a string to each of three strings |
| 19:05 | mudge | amalloy: actually preprend a string to each of three strings |
| 19:05 | amalloy | your originally-posted code already does that |
| 19:06 | mudge | amalloy: then I want to put the three strings inside (apply str ) |
| 19:07 | amalloy | great. wrap (apply str) around your original code, and you've done it |
| 19:08 | amalloy | that said, i'd prefer to write: ##(let [path "foo"] (clojure.string/join ":" (for [suffix ["lib/*" "src" "resources"]] (str path "/" suffix)))) |
| 19:08 | lazybot | ⇒ "foo/lib/*:foo/src:foo/resources" |
| 19:10 | mudge | amalloy: so I have this: (apply str "java -cp " (map #(str "/home/nick") ["lib/*:","src/:" "resources/"])) |
| 19:10 | amalloy | &(#(str "/home/nick") "src:/") |
| 19:10 | lazybot | java.lang.IllegalArgumentException: Wrong number of args (1) passed to: sandbox17398$eval20592$fn |
| 19:11 | mudge | i mean this: (apply str "java -cp " (map #(str "/home/nick/" %) ["lib/*:","src/:" "resources/"])) |
| 19:13 | amalloy | &(apply str "java -cp " (map #(str "/home/nick/" %) ["lib/*:","src/:" "resources/"])) |
| 19:13 | lazybot | ⇒ "java -cp /home/nick/lib/*:/home/nick/src/:/home/nick/resources/" |
| 19:13 | amalloy | so what's the problem? |
| 19:14 | mudge | amalloy: yea, that works, but actually I have more strings after the map, so like this: (apply str "java -cp " (map #(str "/home/nick/" %) ["lib/*:","src/:" "resources/"]) " clojure.main") |
| 19:15 | amalloy | well that doesn't work |
| 19:15 | mudge | amalloy: yea, it doesn't |
| 19:15 | mudge | amalloy: i guess only the sequence can be at the end? |
| 19:16 | mudge | amalloy: i think this is what I was having trouble with and that I didn't understand before |
| 19:17 | amalloy | i hope you've got what you need, because tbh i'm tired of solving problems you're not actually having |
| 19:17 | mudge | amalloy: yes, i understand now, the function signature for apply is: apply f args* argseq) |
| 19:17 | mudge | amalloy: so the sequence has to be at the end and that's why i was having trouble |
| 19:19 | mudge | amalloy: so this works: (apply str "java -cp " (join "" (map #(str "/home/nick/" %) ["lib/*:","src/:" "resources/"])) " clojure.main") |
| 19:20 | mudge | amalloy: i join together the sequence into a single string so it isn't a sequence in apply |
| 19:20 | cemerick | redinger: Not wanting to clutter two lists up with it, but: consider the ongoing clojure-dev thread my input re: 1.3. "showstoppers". Especially given CLJ-736 (rightly) going into -beta3. |
| 19:21 | mudge | amalloy: i also don't need apply now, i can just use str |
| 19:48 | jblomo | is there a way in lein to run something without have test-resources in the classpath? |
| 19:49 | kof4001 | hello |
| 19:49 | kof4001 | where could I get information on how to get clojure-mode to work in emacs? |
| 19:50 | amcnamar1 | kof4001: elpa or marmelade (emacs package managers) will let you install it easily |
| 19:51 | kof4001 | I tried first with http://riddell.us method |
| 19:51 | kof4001 | and then with elpa |
| 19:51 | amcnamar1 | what problem are you seeing? |
| 19:51 | kof4001 | I might be missing something here |
| 19:52 | kof4001 | this appears in debug mode: |
| 19:52 | kof4001 | Debugger entered--Lisp error: (file-error "Cannot open load file" "clojure-mode") |
| 19:52 | kof4001 | require(clojure-mode) |
| 19:52 | amcnamara | (require 'clojure-mode) |
| 19:52 | amcnamara | emacs is a lisp |
| 19:53 | kof4001 | in my init.el I have: |
| 19:54 | amcnamara | also, usually elpa handles the loading for you behind the scenes |
| 19:54 | amcnamara | so you can drop that, restart emacs, and hit M-x clojure-mode |
| 19:54 | kof4001 | (add-to-list 'load-path "~/emacs.d/clojure-mode") |
| 19:54 | kof4001 | (require 'clojure-mode) |
| 19:55 | kof4001 | i have installed clojure mode inside .emacs.d |
| 19:55 | kof4001 | instead ~/opt |
| 19:56 | amcnamara | you may still need to load it |
| 19:56 | amcnamara | try (load "clojure-mode.el") or something equivalent off the load-path path you have above |
| 19:57 | amcnamara | (before the require call) |
| 19:57 | lobotomy_ | ugh, how do i easily print a LazySeq |
| 19:58 | lobotomy_ | (println (str "seq is " my-lazy-seq)) doesn't work so hmm |
| 19:58 | lobotomy_ | is there a way to force the lazy seq to be evaluated? or a print-for-real function? |
| 19:58 | kof4001 | that load did the trick |
| 19:58 | kof4001 | thanks |
| 19:59 | amcnamara | kof4001: np. |
| 19:59 | amcnamara | lobotomy_: try (apply str lazy-seq), that should pull all the values out |
| 19:59 | amalloy | &((juxt print-str pr-str) (range 3)) |
| 19:59 | lazybot | ⇒ ["(0 1 2)" "(0 1 2)"] |
| 20:00 | amalloy | &((juxt str pr-str) (range 3)) |
| 20:00 | lazybot | ⇒ ["clojure.lang.LazySeq@7480" "(0 1 2)"] |
| 20:00 | amalloy | there we go. that's the point i was making |
| 20:01 | amcnamara | &(apply str (range 3)) |
| 20:01 | lazybot | ⇒ "012" |
| 20:01 | lobotomy_ | (println (str "my-seq is " (apply str my-seq))) ;; still doesn't work, just prints "my-seq is clojure.lang.LazySeq@0clojure.lang.LazySeq@0" |
| 20:01 | amcnamara | everyone's a winner. |
| 20:01 | lobotomy_ | hmm, or is that a thing that contains other lazyseqs... |
| 20:01 | lobotomy_ | isn't there a force-print-dammit function? :) |
| 20:02 | lobotomy_ | maybe i'll use flatten! |
| 20:02 | amcnamara | try what amalloy posted |
| 20:02 | lobotomy_ | ooh, right |
| 20:02 | amcnamara | but yeah, looks like you've got lazies all the way down. |
| 20:03 | amalloy | &(pr-str (for [x [10]] (range x))) |
| 20:03 | lazybot | ⇒ "((0 1 2 3 4 5 6 7 8 9))" |
| 20:03 | lobotomy_ | yep, pr-str works fine |
| 20:03 | lobotomy_ | cheers |
| 20:06 | mudge | how to add to the lein classpath? |
| 20:12 | mudge | anybody ever added to the lein classpath of their project? |
| 20:12 | lobotomy_ | grr, now i just need to figure out how to view the print results in the slime repl... apparently scrolling with that is impossible |
| 20:12 | lobotomy_ | there's say 100 lines, it shows either the first 5 or the last 10 |
| 20:12 | clojurebot | Huh? |
| 20:17 | amcnamara | mudge: I've never needed to, lein is supposed to track and manage dependencies for you -- you tell it what to get instead of where to get it. |
| 20:17 | amcnamara | what are you tring to do? |
| 20:17 | kof4001 | i'm sorry to be bothering again, but the (load "clojure-mode.el") in emacs, only works if i loaded it from emacs, not from init.el |
| 20:18 | amcnamara | lobotomy_: M-x scroll-up ? |
| 20:18 | amcnamara | kof4001: probably has something to do with the order that those scripts are loaded, I dump most of those things into a .emacs file on ~ |
| 20:19 | kof4001 | i think the 23 version does not use .emacs anymore |
| 20:19 | amcnamara | I believe .emacs is run last (after elpa, which may be causing your problem) |
| 20:19 | kof4001 | i do not see a .emacs file in my home |
| 20:19 | amcnamara | you have to make it |
| 20:19 | kof4001 | i'll try |
| 20:19 | mudge | I'm using Clojure for a shell script type of command line program that starts/stops/restarts my jetty server. I have an extra directory in my project called scripts which i want to add to leiningens classpath |
| 20:20 | amcnamara | mudge: if you want them to be visable to your project but not managed by lein, dump them in myproject/lib |
| 20:21 | mudge | amcnamara: thanks |
| 20:21 | amcnamara | you may also wish to set :disable-implicit-clean to true in project.clj |
| 20:22 | amcnamara | or else whenever you run lein deps it will kill your lib |
| 20:22 | kof4001 | the .emacs did not work |
| 20:23 | kof4001 | the same problem with init.el |
| 20:23 | mudge | amcnamara: yes, thanks |
| 20:23 | amcnamara | kof4001: dump/gist the error |
| 20:24 | kof4001 | i Debugger entered--Lisp error: (file-error "Cannot open load file" "~/emacs.d/clojure-mode/clojure-mode.el") |
| 20:24 | kof4001 | load("~/emacs.d/clojure-mode/clojure-mode.el") |
| 20:24 | kof4001 | eval-buffer(#<buffer *load*> nil "/home/nonelse/.emacs" nil t) ; Reading at buffer position 64 |
| 20:24 | kof4001 | load-with-code-conversion("/home/nonelse/.emacs" "/home/nonelse/.emacs" t t) |
| 20:24 | kof4001 | load("~/.emacs" t t) |
| 20:24 | kof4001 | #[nil "\205\264 |
| 20:25 | mudge | amcnamara: I could also use the load-file function and refer to include my file that isn't in the classpath |
| 20:27 | amcnamara | kof4001: odd... |
| 20:29 | amcnamara | kof4001: lets go back to elpa, what went wrong on your install from there? |
| 20:30 | kof4001 | i installed elpa from the site http://tromey.com/elpa/install.html |
| 20:30 | kof4001 | should i do it again? |
| 20:30 | amcnamara | did you do package-install? |
| 20:31 | icey | kof4001: what OS are you using? Are you sure your idea of ~ is the same as emacs'? |
| 20:31 | kof4001 | of emacs? |
| 20:31 | kof4001 | lubuntu |
| 20:31 | amcnamara | in emacs |
| 20:31 | amcnamara | elpa is a program to fetch emacs plugins |
| 20:32 | amcnamara | M-x package-list-packages |
| 20:32 | amcnamara | will show all of the available ones |
| 20:32 | amcnamara | M-x package-install clojure-mode |
| 20:32 | amcnamara | will install clojure-mode using elpa |
| 20:32 | kof4001 | well the package install is not working |
| 20:33 | kof4001 | i guess elpa did not installed correctly |
| 20:34 | amcnamara | rerun the script from tromley, and remove the require/load clojure mode stuff you added to init.el |
| 20:36 | kof4001 | i managed to install elpa |
| 20:36 | lobotomy_ | hmm, apparently one of the sets i'm giving to clojure.set/difference isn't always a set, but sometimes a lazyseq |
| 20:36 | lobotomy_ | this looks like it might be annoying to debug |
| 20:37 | kof4001 | but clojure-mode is not detected as a package |
| 20:37 | lobotomy_ | does clojure.set/intersection or /union sometimes generate lazyseqs? |
| 20:38 | kof4001 | i had to list it first |
| 20:39 | amcnamara | kof4001: is it showing up now? |
| 20:39 | kof4001 | after i did a package-list yes |
| 20:39 | amcnamara | &(doc clojure.set/union) |
| 20:39 | lazybot | ⇒ "([] [s1] [s1 s2] [s1 s2 & sets]); Return a set that is the union of the input sets" |
| 20:39 | amcnamara | &(doc clojure.set/intersection) |
| 20:39 | lazybot | ⇒ "([s1] [s1 s2] [s1 s2 & sets]); Return a set that is the intersection of the input sets" |
| 20:40 | amcnamara | nope. |
| 20:40 | kof4001 | i guess that was it |
| 20:40 | kof4001 | i installed paredit while i was at it |
| 20:40 | kof4001 | thanks a bunch |
| 20:40 | amcnamara | paredit comes in very handy |
| 20:40 | amcnamara | np. |
| 20:41 | kof4001 | keep up |
| 20:50 | lobotomy_ | argh, i can't seem to print the stupid things before they end up in clojure.set/difference and cause that explosion |
| 20:51 | lobotomy_ | (do (println ...) (into {} (for [... :let (...)] (do (println ...) (let ... (clojure.set/difference foo bar) ;; and the println's all say everything is a hashset, and immediately after java.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to clojure.lang.IPersistentSet |
| 20:52 | lobotomy_ | wonder if debug printing stuff is actually this difficult in clojure or whether i just suck, heh |
| 20:53 | amcnamara | gist your code |
| 21:11 | amalloy | jira is such a damn pain. i can't even close issues i reported? they were informally marked as "not interested" by clojure/core, but jira still thinks they're "Unresolved, open, unassigned" |
| 21:21 | lobotomy_ | here's my code: http://pastebin.com/dMB14FKb |
| 21:22 | lobotomy_ | any ideas appreciated :) |
| 21:25 | lobotomy_ | ah damn, that seems to be incomplete. need to fix |
| 21:25 | ibdknox | unusual question: does anyone happen to know what font the Clojure logo uses? |
| 21:27 | lobotomy_ | added the pretty print stuff so it should compile: http://pastebin.com/C96NNcMu |
| 21:45 | cemerick | amalloy: Those damn fine-grained ACLs. :-P You don't have a 'close issue' button at the top of the issue? |
| 21:47 | jkkramer | lobotomy_: it looks like you're passing hash maps, not hash sets, to clojure.set/difference |
| 22:01 | mudge | what is a an ear muff? |
| 22:01 | ctran | *var*' |
| 22:02 | ctran | http://stackoverflow.com/questions/3579063/conventions-style-and-usage-for-clojure-constants |
| 22:14 | jkkramer | lobotomy_: i was mistaken. it's like 88; remove-threatening-squares ought to return a set |
| 22:15 | jkkramer | lobotomy_: it may help in the future to break your code into smaller, more testable pieces. the code flow is a bit hard to follow |
| 22:53 | amalloy | cemerick: no. or if i do it's awfully well-hidden |
| 22:53 | cemerick | amalloy: which issue? Maybe I can close it? |
| 22:54 | amalloy | 714, 707, and probably 709 also |
| 22:56 | thinker341 | hi |
| 22:57 | amalloy | cemerick: i have to step out for a while; if you need anything more from me to get those closed, just leave a message |
| 23:05 | cemerick | amalloy_: Issues closed. |
| 23:07 | ambrosebs | what do I need to do to request commit access to core.match? |
| 23:07 | cemerick | ambrosebs: find someone with admin rights in the 'clojure' github organization. |
| 23:07 | cemerick | msg to clojure-dev should do it, presumably |
| 23:08 | ambrosebs | will do, thanks chas |
| 23:10 | seancorfield | there has to be a better way... |
| 23:11 | seancorfield | so, i have a vector of maps... i want to do (map (juxt :id :name) data) which gives me ((id1 name1) (id2 name2) ...) |
| 23:11 | seancorfield | but i want that as a map {id1 name1, id2 name2, ...} |
| 23:12 | seancorfield | i can do (into {} (map vec *1)) but that seems ugly |
| 23:12 | seancorfield | is there a nicer way to turn ((a b) (c d) ...) into a map? |
| 23:18 | cemerick | seancorfield: juxt produces vectors here (-beta1) |
| 23:20 | cemerick | Otherwise, (reduce #(apply assoc % %2) {} (map (juxt :id :name) …)) ? |
| 23:20 | cemerick | Not nicer, but maybe (probably not) more efficient? |
| 23:26 | seancorfield | ,((juxt :id :name) {:id 1, :name "Sean"}) |
| 23:26 | clojurebot | [1 "Sean"] |
| 23:26 | seancorfield | how about that... *facepalm* |
| 23:27 | cemerick | It's in the docs, FWIW. I don't have 1.2.0 handy, maybe that's a change. |
| 23:27 | seancorfield | so i can lose the map vec at least... no idea why i had convinced myself i got sequences instead :( |
| 23:27 | seancorfield | thanx! |
| 23:27 | cemerick | :-) |
| 23:28 | seancorfield | now i can clean up my code quite a bit... |
| 23:30 | technomancy | jblomo: set the LEIN_NO_DEV environment variable |
| 23:38 | seancorfield | yeah, nice... much cleaner code... comp and juxt FTW :) |
| 23:38 | seancorfield | thanx cemerick !! |
| 23:39 | cemerick | seancorfield: np, glad it worked out :-) |
| 23:39 | user317 | is there a transpose function somewhere? |
| 23:42 | davekong | I tried running clojure on jnode and got this error: http://pastie.org/2478994 just wondering if anyone might have an idea how I would go about fixing this error |
| 23:46 | user317 | is there a good source on list manipulation in clojure for someone from a haskell background? like zip zipWith transpose etc... |
| 23:47 | technomancy | zip? |
| 23:47 | clojurebot | zip is not necessary in clojure, because map can walk over multiple sequences, acting as a zipWith. For example, (map list '(1 2 3) '(a b c)) yields ((1 a) (2 b) (3 c)) |
| 23:48 | user317 | ah, so thats transpose |
| 23:48 | user317 | i dont have my head wrapped around the variable arg part of clojure |
| 23:48 | user317 | makes sense |
| 23:49 | user317 | does that work over infinite lists? |
| 23:49 | technomancy | yep |
| 23:50 | user317 | cool, seems to do the right thing when they are different sizes as well |
| 23:51 | technomancy | I think it truncates to the shortest seq arg |
| 23:51 | cemerick | it does |
| 23:51 | cemerick | ,(map list [1 2 3] [1 2 3 4]) |
| 23:51 | clojurebot | ((1 1) (2 2) (3 3)) |
| 23:52 | user317 | yep |
| 23:53 | user317 | so, if i pass a record constructor as the function to map, that should apply each value from the list as arguments to the constructor, right? |
| 23:54 | cemerick | ctors are not first-class; you can't apply them to a seq of args, etc. |
| 23:54 | cemerick | However, (defrecord Foo …) creates a ->Foo factory function that will do what you want |
| 23:55 | user317 | Foo is that function, right? |
| 23:55 | cemerick | No, `->Foo` is the function's name, if your record class is named Foo. |
| 23:55 | user317 | (map ->Foo (1 2 3) (4 5 6)) |
| 23:55 | user317 | like that? |
| 23:56 | cemerick | yup |