2011-12-10
| 00:15 | lnostdal_ | there's something i don't understand .. why does lein deps "sometimes" seem to just go on even though project.clj refers to something it can't find? i mean, it can't find a clojure 1.4 snapshot here now, so instead it seems to add clojure 1.2.0 to lib/ here then just silently continues |
| 00:43 | lnostdal_ | seems the problem is something in enlive .. [org.clojure/clojure "[1.2.0,)"] looks weird |
| 01:01 | ambrosebs | where can I find the definitions of clojure.core/gen-interface and clojure.core/gen-class? |
| 01:09 | jodaro | Source clojure/genclass.clj:492 |
| 01:10 | jodaro | according to clojuredocs.org |
| 01:10 | jodaro | http://clojuredocs.org/clojure_core/clojure.core/gen-class |
| 01:10 | jodaro | Source clojure/genclass.clj:669 for gen-interface |
| 01:22 | ambrosebs | jodaro: cheers :) |
| 01:23 | amalloy | lnostdal_: "[1.2.0,)" is: "any version at least as high as 1.2.0" |
| 01:24 | amalloy | which is effectively promising it will work with clojure 5.7 - a dubious claim, but one i made myself back before i knew better |
| 01:28 | lnostdal_ | amalloy, hm, ok .. perhaps it doesn't "understand" 1.4.0-master-SNAPSHOT or something |
| 01:28 | amalloy | i don't really know the rules of maven dependency version selection |
| 01:29 | lnostdal_ | if i change enlive to depend on "1.2.0" .. my project gets the right clojure jar in its lib/ folder |
| 01:29 | lnostdal_ | me neither |
| 01:30 | lnostdal_ | sometimes there's too much java |
| 01:30 | lnostdal_ | ..involved |
| 01:40 | skeeterbug | can someone help me out with clojureql? |
| 01:40 | skeeterbug | i am a bit of a clojure noobie |
| 01:41 | Raynes | amalloy, lnostdal: The thing about it is, version ranges are kind of useless. It doesn't matter what you specify, whatever version of Clojure the project depending on you depends on wins. |
| 01:42 | Raynes | Closed version ranges can be useful to document the specific versions that you're capable of working with, but open ended version ranges are just silly. |
| 01:53 | notostraca | &(print (apply str (flatten (repeatedly 1 (fn [] (conj (shuffle (concat (repeat 40 "/") (repeat 40 "\\"))) "\n")))))) |
| 01:53 | lazybot | ⇒ ////\\//\\//\\\//\\///\\\\\\//\\\\///\//\/\\\\///////\///\//\/\\\/\\\\///\\\\/\/ nil |
| 01:53 | notostraca | god I love clojure |
| 02:58 | amalloy | notostraca: btw, since you seem to be shuffling stuff: would a lazy shuffle be of any utility to you? |
| 02:59 | notostraca | amalloy, I don't know what I would use it for yet, but maybe someday :-) |
| 03:00 | notostraca | mostly I am trying to figure out how to "rotate" a 2D array of slashes and backslashes to become horizontal and vertical lines |
| 03:03 | amalloy | you probably want to (a) figure out what that actually means, and (b) come up with an algorithm, before you write any clojure |
| 04:11 | notostraca | hmm |
| 04:11 | notostraca | ,doc take |
| 04:11 | clojurebot | #<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.repl/doc, compiling:(NO_SOURCE_PATH:0)> |
| 04:12 | notostraca | ,(doc take) |
| 04:12 | clojurebot | "([n coll]); Returns a lazy sequence of the first n items in coll, or all items if there are fewer than n." |
| 04:12 | notostraca | so how do I evaluate the lazy sequence? I just don't seem to understand how laziness works in clojure |
| 04:12 | notostraca | ,(doc do) |
| 04:12 | clojurebot | No entiendo |
| 04:18 | notostraca | amalloy, still around? |
| 04:18 | amalloy | indeed |
| 04:18 | amalloy | the point is mostly you shouldn't need to worry about when they get evaluated, of course |
| 04:19 | amalloy | if you care about that, it implies side effects in your code |
| 04:28 | notostraca | amalloy, actually I do have side effects, I want to generate some strings randomly, and printing the sequences just gives me LazySeq@abcd78 or some other ID |
| 04:29 | notostraca | I want to only use the first 10 or so strings I generate in the sequence |
| 04:29 | amalloy | do you want to generate some strings, or print them? i suspect you don't have any need to print the actual sequence of strings to the console at once |
| 04:30 | notostraca | well it is kinda complicated, but I am generating the strings so I can copy them into a text editor and regex them into java code |
| 04:31 | notostraca | anyway, i solved it by only printing at the very end |
| 04:31 | notostraca | and not str'ing a lazy sequence, just conj'ing what I need onto the end of it |
| 04:32 | amalloy | notostraca: a good rule of thumb is not to give lazy sequences to side-effecty things. instead, use some side-effect-oriented operation, like doseq, to extract non-lazy values out of the sequence |
| 04:32 | notostraca | ah ok |
| 04:32 | amalloy | eg, print is side-effecty, and it doesn't like lazy sequences very much. but (doseq [s strings] (print s)) would work |
| 04:33 | amalloy | or, you could use (pr strings) |
| 04:50 | notostraca | ok, now I have a list of 2d vectors, each 2d vector a 3x3 box of tile names. I need to concatenate the rows of all the boxes into 3 long rows instead of 10 boxes with 3 rows each |
| 05:37 | lnostdal | Raynes, yes, that what i've generally seen; the "end project" gets the vote for what clojure version stuff will actually run under .. but in this particular case, that doesn't happen |
| 06:33 | Borkdude | &findfn |
| 06:33 | lazybot | java.lang.RuntimeException: Unable to resolve symbol: findfn in this context |
| 06:33 | Borkdude | what is the syntax again? |
| 06:33 | Borkdude | lazybot: findfn |
| 06:34 | lazybot | [clojure.core/cond clojure.core/dosync clojure.core/import clojure.core/prn clojure.core/refer-clojure clojure.core/print clojure.core/with-loading-context clojure.core/newline clojure.core/comment clojure.core/or clojure.core/load clojure.core/shutdown-agents cloj... https://gist.github.com/1454963 |
| 06:34 | raek | $findfn |
| 06:34 | lazybot | [clojure.core/cond clojure.core/dosync clojure.core/import clojure.core/prn clojure.core/refer-clojure clojure.core/print clojure.core/with-loading-context clojure.core/newline clojure.core/comment clojure.core/or clojure.core/load clojure.core/shutdown-agents cloj... https://gist.github.com/1454964 |
| 06:34 | Borkdude | $findfn 'a 'b 'b |
| 06:34 | lazybot | [clojure.core/max-key clojure.core/char-escape-string clojure.core/*clojure-version* clojure.core/min-key clojure.core/char-name-string clojure.core/primitives-classnames clojure.core/merge-with] |
| 06:34 | Borkdude | Is there a function in clojure that does this: (fn [a b] b) ? |
| 06:35 | Borkdude | I want to use it to swap an atom value to a new value regardless of the old one |
| 06:35 | Borkdude | maybe there is an easier way (probably) |
| 06:35 | raek | Borkdude: yes: 'reset!' |
| 06:36 | cemerick | reset! |
| 06:36 | Borkdude | ah |
| 06:37 | raek | there's also constantly: (def constantly [x] (fn [& args] x)) |
| 06:37 | raek | which is kinda like a two-step version of your fn |
| 06:37 | raek | *defn |
| 06:38 | Borkdude | hmhm, ok |
| 06:39 | Borkdude | why do I get a nullpointerexception: (def cmp-prev (let [prv (atom nil)] (fn [nxt] (let [retval (< @prv nxt)] (reset! prv nxt) retval)))) |
| 06:39 | Borkdude | if I call it like (cmp-prev 1) |
| 06:41 | Borkdude | I guess < can't handle nil? |
| 06:48 | cemerick | what would it possibly return for (< 6 nil)? |
| 06:48 | raek | Borkdude: you should only use reset! when you don't care about the previous value of the atom |
| 06:49 | Borkdude | raek: yes, ok |
| 06:49 | raek | otherwise you will have a race condition due to the different point of read and write |
| 06:49 | Borkdude | cemerick: right |
| 06:49 | raek | Borkdude: just make a fn that you pass to swap! |
| 06:49 | Borkdude | raek: I don't care about the previous value |
| 06:50 | lnostdal_ | lein stuck doing apparently nothing again .. gah .. and no output; nothing |
| 06:50 | raek | Borkdude: but you use it to compute the return value of the fn |
| 06:50 | Borkdude | raek: I can't be sure that this will happen before the reset? |
| 06:51 | raek | Borkdude: but what if another thread runs the same code? |
| 06:52 | raek | then you can get an interleaving where this happens: thread 1 derefs, thread 2 derefs, thread 1 reset!s, thread 2 reset!s |
| 06:53 | raek | and if you want to maintain state within *one* thread you shouldn't use a (global) atom at all |
| 06:53 | raek | you can use loop variables in loop/recur |
| 06:53 | Borkdude | raek: I just want to build a function with some memory |
| 06:53 | raek | (computational state, that is) |
| 06:53 | Borkdude | so I can use partition-by over a sequence with this function |
| 06:54 | raek | Borkdude: you could also use a thread local var in this case |
| 06:54 | Borkdude | can I do a closure over a var? |
| 06:55 | raek | well, in that case you would just use binding to get your own var, and then set! and deref to access it |
| 06:55 | raek | Borkdude: there is probably a purely functional way of solving the problem |
| 06:56 | Borkdude | raek: I am realizing this |
| 06:56 | Borkdude | raek: Just experimenting, I don't use atoms often |
| 06:57 | raek | if the standard library fuctions don't allow you to "get the right values to the right places", you should probably fall back to a simple loop/recur |
| 06:58 | raek | atoms are made for dealing with concurrency and not really for maintaining values in stateless computations |
| 06:59 | Borkdude | raek: so this is actually not a good solution: http://stackoverflow.com/questions/8442524/writing-an-accumulator-function-in-clojure |
| 06:59 | Borkdude | ? |
| 07:09 | Borkdude | not a thread-safe solution anyway then |
| 07:23 | Borkdude | is there a function that does this? (select max count [[1 1] [1 1 1] [1]]) => [1 1 1]) ? |
| 07:25 | Borkdude | like this: (reduce (fn [a b] (if (> (count a) (count b)) a b)) [[1 1] [1 1 1] [1]]) |
| 07:28 | cemerick | ,(max-key count [1 1] [1 1 1] [1]) |
| 07:28 | clojurebot | [1 1 1] |
| 07:28 | Borkdude | great |
| 07:28 | Borkdude | ,(doc max-key) |
| 07:28 | clojurebot | "([k x] [k x y] [k x y & more]); Returns the x for which (k x), a number, is greatest." |
| 07:29 | Borkdude | why is this called max-"key"? |
| 07:30 | cemerick | can't say |
| 07:49 | raek | Borkdude: yes. that was not intended as an example of how you should do it. |
| 07:50 | raek | hrm. I misread the example. it is not intended as an example of how to have an accumulator in a computation |
| 07:50 | _ulises | ahoy! |
| 07:51 | raek | but it is how you would make a function that modifies a globally accessible atom |
| 07:52 | raek | which you don't need when you just want to remember a previous value |
| 07:52 | raek | (in a computation) |
| 07:53 | Borkdude | finally solved this 4clojure problem 53, fully functional ;) |
| 08:24 | _ulises | anybody here interested in advising me on literate programming? |
| 08:38 | Somelauw | ,(apply max-key count [(([1 0]) ([0 1] [1 2] [2 3]) ([3 0]) ([0 4] [4 5] [5 6]))) |
| 08:39 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: Unmatched delimiter: )> |
| 08:39 | Somelauw | ,(apply max-key count [(([1 0]) ([0 1] [1 2] [2 3]) ([3 0]) ([0 4] [4 5] [5 6]))]) |
| 08:39 | clojurebot | #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: PersistentVector> |
| 08:42 | Somelauw | ,(apply max-key count ['(([1 0]) ([0 1] [1 2] [2 3]) ([3 0]) ([0 4] [4 5] [5 6]))]) |
| 08:42 | clojurebot | (([1 0]) ([0 1] [1 2] [2 3]) ([3 0]) ([0 4] [4 5] [5 6])) |
| 08:44 | Somelauw | Sorry, I wanted to paste a problem that I have, but that appears harder than I thought. I will post the problem later. |
| 08:44 | Somelauw | Okay I figured it out. Here is the problem: |
| 08:47 | Somelauw | Okay, I think I figured it out myself. Nested lists can be tricky sometimes. |
| 09:20 | Wild_Cat | hmm. webnoir.org is down. |
| 09:56 | Borkdude | Is it possible to just run one test you defined with deftest? |
| 09:59 | Somelauw | I know how to find the longest increasing subseq in a list. |
| 09:59 | Borkdude | Somelauw: I solved that one as well |
| 10:06 | Borkdude | How do you do this with paredit: (| (expr1) (expr2)) => (expr1) (expr2) |
| 10:06 | Borkdude | I keep running into this one |
| 10:07 | _ulises | Borkdude: I do it with M-up arrow |
| 10:08 | _ulises | but the cursor must be exactly where you put it, otherwise hilarity ensues |
| 10:08 | Borkdude | _ulises: tnx |
| 10:08 | _ulises | np |
| 10:36 | Borkdude | Is there also a transpose like ("a"| "b") => ("b" a")? |
| 11:29 | ambrosebs | which Java classes are implicitly imported in a Clojure namespace? |
| 11:30 | jodaro | i think it might be just java.lang |
| 11:30 | jodaro | but i have no proff |
| 11:30 | jodaro | or proo |
| 11:30 | jodaro | f |
| 11:30 | jodaro | crap |
| 11:30 | jodaro | more coffee needed, apparently |
| 11:30 | ambrosebs | ,Character |
| 11:30 | clojurebot | java.lang.Character |
| 11:30 | gtrak` | i think for java it's just java.lang |
| 11:31 | ambrosebs | any idea where this happens? |
| 11:31 | ambrosebs | the imports? |
| 11:31 | gtrak` | well, for java source it's a compiler thing |
| 11:32 | gtrak` | if you got the clojure source, do a grep java.lang :-) |
| 11:32 | ambrosebs | sure |
| 11:34 | jodaro | there are a bunch in clojure/lang/LispReader.java |
| 11:34 | jodaro | but i'm not sure if thats what makes them available directly in clojure |
| 11:34 | gtrak` | yea, those are imports fot the actual java |
| 11:35 | gtrak` | how about the asm commons Method.java? |
| 11:35 | ambrosebs | right, that makes sense |
| 11:36 | gtrak` | ah, no, that's not it |
| 11:37 | gtrak` | ah yea, check it out, sb.append("java/lang"), I'm guessing that's related |
| 11:37 | jodaro | could it be that they don't have to be explicitly imported by clojure? |
| 11:38 | gtrak` | take a look at Method.java https://github.com/clojure/clojure/blob/master/src/jvm/clojure/asm/commons/Method.java specifically the 'map' function |
| 11:40 | gtrak` | I'm guessing that both the reflection api and the ASM lib use that as a default, it doesn't look like clojure's doing anything special itself |
| 11:40 | ambrosebs | excellent :) now I just need a seq with all java.lang.* class names ... |
| 11:47 | jodaro | http://snippets.dzone.com/posts/show/4831 |
| 11:47 | jodaro | not sure if thats what you want |
| 11:47 | ambrosebs | jodaro: :) will try |
| 11:47 | jodaro | you want to find it dynamically? |
| 11:48 | jodaro | or just have a static sequence of them |
| 11:48 | ambrosebs | the latter will do fine.. how volatile is java.lang? |
| 11:48 | ambrosebs | I'm guessing not very |
| 11:48 | jodaro | heh probably not |
| 11:49 | ambrosebs | I'll just do it statically, seems less error prone |
| 12:01 | TimMc | WTF, is enlive removing my doctype? |
| 12:02 | gtrak` | ambrosebs, even if it changes, they'll only add stuff |
| 12:06 | ambrosebs | grak`: yea, it's part of the language now |
| 12:06 | duck1123 | yeah, java seems to keep depreciated methods around for quite a while |
| 12:06 | gtrak` | duck1123, it'll never go away |
| 12:07 | gtrak` | nothing can get removed or even changed, maybe code relies on the broken semantics |
| 12:08 | gtrak` | but it seems with clojure we have a way out :-) |
| 12:09 | duck1123 | that's really a shame though. You would think that after a few years and several versions of having things deprecated, it would be safe to remove them. That's one of Microsoft's biggest problems |
| 12:10 | gtrak` | it helps the platform at the expense of the language |
| 12:11 | gtrak` | I think it's the right thing to do |
| 12:11 | gtrak` | java was started as a high-level lang, but now it's relatively low-level compared to the other stuff |
| 12:16 | TimMc | duck1123: Having the @Deprecated annotation helps. |
| 12:16 | TimMc | You don't get that in C++, I think. |
| 12:17 | TimMc | Deprecating *language* features, on the other hand -- that's tricky. |
| 12:18 | gtrak` | C++ is really really weird :-) |
| 12:25 | ambrosebs | is there a version of resolve that doesn't throw an exception if a class cannot be found? |
| 12:30 | ssideris | hello |
| 12:30 | ssideris | does anyone use lein-multi? |
| 12:31 | ssideris | I'm running "lein multi test" and apart from the dependency sets that I have defined, it does run the tests against the "base" set of dependencies |
| 12:32 | ssideris | is that because I have a dev-dependencies as well? |
| 12:45 | ambrosebs | dnolen: https://gist.github.com/1455735 :) |
| 13:32 | seertaak | hi everyone. really stupid question: how can I make functions defined in a file (with a (ns ...) clause at the top) available to a REPL which loads the package? |
| 13:32 | seertaak | Loads the package via (import my-package) , by the way |
| 13:38 | chewbran` | sweet |
| 13:39 | seertaak | Please ignore my question, I've worked it out myself. |
| 14:19 | alexbaranosky | amalloy_, you there? I'm curious about possibile the midje git repo trimming |
| 14:32 | daniel__ | im trying to use korma but is there not a way of defining a database schema? should i look to the jdbc driver docs for doing this? i need some way of defining the tables, otherwise ill forget what i need |
| 14:40 | alexbaranosky | daniel__, there's a library whose name escapes me that is good for setting up the schema |
| 14:40 | alexbaranosky | don't think you need to use jdbc driver |
| 14:43 | daniel__ | alexbaranosky: ok, let me know if you remember |
| 14:43 | daniel__ | i'll have a search |
| 14:46 | daniel__ | alexbaranosky: lobos? https://github.com/technomancy/lobos |
| 14:47 | alexbaranosky | daniel__, lobos sounds like it |
| 14:47 | daniel__ | ok :) |
| 14:48 | alexbaranosky | good luck |
| 14:48 | gtrak` | ambrosebs, is that what I think it is? |
| 14:49 | TimMc | alexbaranosky: What I meant about licensing was, can I get your OK on using the EPL for the seqs repo? |
| 14:51 | TimMc | You're a slippery one to pin down! |
| 14:51 | alexbaranosky | TimMc: sounds good to me |
| 14:52 | alexbaranosky | is there something I need to do? |
| 14:52 | alexbaranosky | TimMc: I'm using emacs over here... it is truly painful |
| 14:53 | TimMc | haha, OK |
| 14:53 | gtrak` | TimMc, consider printing out the cheat sheets |
| 14:53 | gtrak` | i mean alexbaranosky |
| 14:53 | TimMc | alexbaranosky: Nah, just wanted your permission. |
| 14:54 | alexbaranosky | gtrak`, I've got them up in my browser, but printing is a good idea |
| 14:54 | gtrak` | alexbaranosky, circling the ones I look for often helped me a lot |
| 14:54 | devn | hello all |
| 14:54 | alexbaranosky | hi devn |
| 14:54 | devn | how goes the clojuring? |
| 14:55 | gtrak` | alexbaranosky, though I had to do some image processing on the paredit cheat sheet to get it to look good |
| 14:55 | alexbaranosky | I recently made it so that Midje tabular doesn't require ?'s which I think is pretty sweet |
| 14:56 | daniel__ | does anyone know if i can use the connection that korma makes instead of also connecting via lobos? |
| 14:57 | Raynes | alexbaranosky: https://skitch.com/discipleraynes/gxj72/clojure don't diss the Emacsen. |
| 14:58 | gtrak` | Raynes, is that ubuntu mono? <3 |
| 14:59 | Raynes | gtrak`: Certainly not |
| 14:59 | gtrak` | ah, what font is it then? |
| 14:59 | Raynes | DejaVu. |
| 14:59 | gtrak` | ah |
| 15:00 | alexbaranosky | Raynes, no dissing here, just painful switching from Intellij where I'm really comfortable. -- I want to see what Emacs can do that isn't possible in Intellij, but so far the paradigm shift is heavy duty |
| 15:00 | Raynes | alexbaranosky: I understand. |
| 15:00 | alexbaranosky | do any of you all use stuff like ECB for Emacs? |
| 15:01 | Raynes | Emacs is an acquired taste. If you give up before you acquire it, you may never understand why it is so amazing. |
| 15:01 | clojurebot | 'Sea, mhuise. |
| 15:01 | alexbaranosky | one major thing I miss when in Emacs or Vim is the ability to have a bird's eye view of all the files in a project |
| 15:02 | kumarshantanu | daniel__: it seems both of them use the same map structure |
| 15:02 | kumarshantanu | probably they get passed to clojure.java.jdbc |
| 15:02 | Tharem | Hi there. I'm trying to require a namespace in the slime REPL, but it's giving me an error: nth not supported on this type: Class. When invoking the program using lein run, it doesn't give a problem. What could be wrong? |
| 15:03 | gtrak` | alexbaranosky, you can just use M-x grep to look for stuff or C-x C-f to navigate, it gives you lists |
| 15:03 | gtrak` | it might be rgrep |
| 15:04 | Raynes | alexbaranosky: Chances are, there is elisp to do what you want. |
| 15:04 | Tharem | There is also a package that shows the possible completions in the minibuffer (I pulled it in via emacs starter kit). That's quite usefull when switching between buffers |
| 15:04 | alexbaranosky | Tharem, the completions thing is nice, I have it too |
| 15:04 | dnolen | Tharem: how are you trying to require it? |
| 15:04 | alexbaranosky | but so far.... none of this is better than Intellij |
| 15:05 | Raynes | alexbaranosky: Does it give a tree view of the entire project? |
| 15:05 | alexbaranosky | I want to know the stuff that is actually an improvement over it, not just a different approach to mostly the same thing |
| 15:06 | Raynes | Well, the defining feature of Emacs is really how extensible it is. If it doesn't do exactly what you want, you can write Elisp code to make it do exactly what you want. Doesn't matter if what you want is genius or insane, you can do it with a little elispfu. |
| 15:06 | Tharem | Alexbaranosky, I use (require RogueLike.core). RogueLike.core is also the namespace defined at the top of my file |
| 15:06 | alexbaranosky | Raynes, Intellij? yeah. 'project view', just like a little tree-style file browser on the side of the screen... Emacs can have it too, but most don't use it |
| 15:07 | Raynes | As such, people have written insane things in Elisp that run in Emacs. ERC is an example. A full-on IRC client in Emacs that is a joy to use and navigate even with several networks and over a dozen channels. |
| 15:07 | Raynes | None of it slows Emacs down either. |
| 15:07 | devn | could someone please use my nick in here? |
| 15:07 | Raynes | I've got a twitter client in a buffer two clicks left of here. |
| 15:07 | alexbaranosky | Raynes, speed is nice, IDEs can bog down sometimes |
| 15:07 | Raynes | devn: Hi. |
| 15:07 | Tharem | devn: sure, but why? |
| 15:07 | devn | perfect. thanks. |
| 15:07 | TimMc | Tharem: Sounds like there's a compile error in whatever you're require'ing. |
| 15:07 | devn | i lost my hilight window and needed to create a new one and wanted to make sure i had set it up correctly |
| 15:08 | Tharem | Then why does it run through leiningen? |
| 15:08 | Raynes | alexbaranosky: Now, none of the last two things I've mentioned have anything at all to do with editing, but my point is to demonstrate the power and flexibility of having an editor configured in a Lisp. |
| 15:08 | Tharem | Any errors that don't show up when running through leiningen? |
| 15:08 | TimMc | hmm |
| 15:08 | alexbaranosky | Tharem, what were you talking about regarding RogueLink? I didn't understand that. |
| 15:08 | Raynes | A great thing, for example, is that if I didn't have ERC loaded when I started Emacs up, I could always load/reload it later. Emacs is a big Lisp box. A giant sophisticated repl. |
| 15:09 | Tharem | Nothing special, that's just the name of the namespace |
| 15:09 | Tharem | I've defined it using (ns RogueLike.core (:import [imports ommitted])) |
| 15:10 | alexbaranosky | Tharem, so its a macro for that for you? |
| 15:11 | TimMc | Tharem: quote the namespace: (require 'RogueLike.core) |
| 15:11 | TimMc | and don't do :require, use require |
| 15:12 | Tharem | XD Yeah now it returns nil. I'm assuming that's ok? |
| 15:12 | TimMc | yep! |
| 15:12 | Tharem | Also, why shouldn't I be sing :require in the ns macro? |
| 15:12 | alexbaranosky | Raynes, thanks for your thoughts on Emacs |
| 15:12 | TimMc | (:require foo) in ns, (require 'foo) from REPL. :-/ |
| 15:12 | Tharem | using* |
| 15:13 | Tharem | Oh ok. Thanks a lot guys |
| 15:13 | TimMc | It's inconsistent, but there it is. |
| 15:14 | Tharem | I don't think it's inconsistent. (require foo) is a function call, :require is an argument to the ns macro |
| 15:14 | TimMc | Yeah, but it trips a *lot* of people up. |
| 15:14 | TimMc | Anyone who has written a Lein plugin: How hard do you suppose it would be to create a "n00b" plugin for Leiningen that catches common errors? |
| 15:15 | Raynes | Tharem: The fact that you're not screaming "What? That's bullshit!!!" right now means you have an excellent future with Clojure. Welcome to the team. |
| 15:15 | alexbaranosky | TimMc, such as? |
| 15:15 | Raynes | TimMc: You're looking for a lint. |
| 15:15 | TimMc | alexbaranosky: Like `(:require SomeSymbol) => nth not supported by Class |
| 15:15 | Raynes | http://community.haskell.org/~ndm/hlint/ |
| 15:16 | alexbaranosky | yeah, sounds like there are two pieces: a Clojure lint, and a lein plugin that just runs the lint on the project |
| 15:16 | Tharem | Raynes: Thanks. I actually have some experience with common lisp (in b4 HERETIC :P ). I'm still smacking my forehead for not thinking of using a few quotes XD |
| 15:17 | TimMc | alexbaranosky: A REPL-oriented lint, specifically. |
| 15:18 | Tharem | TimMc, what you're actually suggesting is to improve the error handling. I seem to recall that Java puts some limits on how error handling goes |
| 15:19 | TimMc | Tharem: Better error handling would be nice (although calling (pst) after an error on the REPL is not so bad), but this would specifically look for common mistakes and suggest tips to the user. |
| 15:19 | TimMc | A REPL Clippy, if you will. |
| 15:22 | Tharem | One way would be to have function and macro calls routed through a function that checks for common mistakes and tosses a readable error message if it detects a common mistake |
| 15:22 | Tharem | That wouldn't immediately dump you into the Java debugger |
| 15:23 | TimMc | Well, I wouldn't want to prevent normal execution. |
| 15:23 | TimMc | For one thing, this would *not* be a conservative checker, so it might get some stuff wrong. |
| 15:24 | Tharem | You don't need to prevent normal execution. What you could do is check the input to detect a possible error, run it, then catch any errors and give hints |
| 15:24 | TimMc | (:require foo) is a valid statement if (def foo {:require true}) |
| 15:24 | TimMc | I think after execution is the time to do it, since then you can see whether it produced an exception. |
| 15:26 | Tharem | Yes but after execution the input is gone, so you have to cache the input to detect possible errors. You can't tell the difference between "nth not supported by class" caused by a wrong load or by calling nth on something that isn't a sequence |
| 15:26 | alexbaranosky | hey Raynes, what is the one thing you wish Midje had when you use it? |
| 15:26 | duck1123 | focus |
| 15:26 | Raynes | alexbaranosky: Less, so that I wouldn't feel bad when I inevitably end up using only a subset of what I actually should be using because I'm too lazy to learn the whole API. |
| 15:27 | alexbaranosky | duck1123, was that directed at me? Could you elaborate? |
| 15:27 | Raynes | duck1123: Did we just say the same thing? |
| 15:27 | alexbaranosky | I think so! |
| 15:27 | TimMc | Tharem: I guess it depends on how the REPL works. |
| 15:27 | alexbaranosky | interesting. I wonder how we could make less? |
| 15:28 | Raynes | I was actually just kidding. |
| 15:28 | Raynes | I don't have anything in particular that I'd like right now. |
| 15:28 | alexbaranosky | are there features that could be collapsed into one? |
| 15:28 | duck1123 | alexbaranosky: I know the question wasn't directed at me, but I wish there was an easy way to restrict down to only some test. Like RSpec's focus |
| 15:28 | Raynes | Right, I was wondering about ways to run only specific tests myself. |
| 15:28 | alexbaranosky | so you want a way to run just on etest? |
| 15:28 | TimMc | OK, I have come to a conclusion about seqs and colls: They are abstractions, and it is not possible to determine which abstraction a particular value "belongs" to. |
| 15:29 | alexbaranosky | is that what you meant by focus? |
| 15:29 | duck1123 | alexbaranosky: yes |
| 15:29 | TimMc | You can only coerce a value into the abstraction you want, you can't inspect it to see what it already is. |
| 15:29 | alexbaranosky | duck1123, yeah, I want that too :) |
| 15:29 | Raynes | Since tests aren't named, we don't have a way to refer to them. |
| 15:29 | alexbaranosky | do you know you can run just a single ns? |
| 15:30 | alexbaranosky | Raynes, we could conceivably do something with metadata... there's an idea floating around around the idea of tagging groups of facts, then being able to run that tagged group |
| 15:30 | alexbaranosky | lein midje org.alexbaranosky.justthisonens |
| 15:31 | Raynes | alexbaranosky: Can you give me input on how I did these tests here: https://github.com/Raynes/tentacles/blob/master/test/tentacles/users_test.clj |
| 15:32 | alexbaranosky | Raynes, sure thing |
| 15:32 | Raynes | alexbaranosky: In particular, I'm not sure if my grouping of assertions is nice or not. |
| 15:32 | duck1123 | the namespace reduction helps, but sometimes you want to just focus on a specific test, and don't feel like autotesting or testing in a repl |
| 15:32 | Raynes | alexbaranosky: I grouped assertions about certain 'types' of API calls. Felt good, but I'm not sure if I've done something terrible. |
| 15:33 | alexbaranosky | funny enough, I've never seen `has` :D |
| 15:34 | alexbaranosky | Raynes, I don't think anything there is terrible. I have a different style when I test, but I think it is mainly a stylistic thing, where I would be more explanation of what each fact is confirmig in the doc strings... let me show you a project of mine with a lot of midje facts ......... |
| 15:35 | Raynes | The users and keys facts there are what I was unsure about. I primary started grouping these things because I needed to wrap several assertions in the same let so that I could let an API call and then test that result and use it in the other assertions as well. I wasn't sure what would happen if I, for example, wrapped several facts in a let and an exception occurred outside of the let itself. |
| 15:35 | duck1123 | so are you guys using lein-midje to run your tests, or lein test? I had some issues with lein midje and am still wrapping all of my facts in deftests |
| 15:35 | Raynes | Er, outside of a fact itself. |
| 15:36 | alexbaranosky | Raynes, example of more my style https://github.com/AlexBaranosky/EmailClojMatic/blob/master/src/ecm/fact/reminder_parsing_facts.clj |
| 15:36 | Raynes | duck1123: I'm using lein test. No particular reason. I'll probably use lein midje later. |
| 15:36 | alexbaranosky | Raynes, grouping facts is good |
| 15:37 | alexbaranosky | duck1123, I use lein midje -- what were your issues? |
| 15:38 | duck1123 | alexbaranosky: IIRC, it was mostly because I was using 1.3 before it supported 1.3, and had to patch my own version of midje |
| 15:39 | duck1123 | Here's an example of how I structure some of my tests: https://github.com/duck1123/jiksnu/blob/master/test/jiksnu/actions/activity_actions_test.clj (not as much 'provided' as there should be yet) |
| 15:39 | daniel__ | does anyone use lobos? i cant understand why i need to define a schema and migrations... cant i just use migrations? is there an alternative to lobos that people use? |
| 15:40 | alexbaranosky | duck1123, is `testing` a clojure.test thing? |
| 15:41 | duck1123 | yes. I'm using it as a poor man's "context" in the BDD sense |
| 15:42 | Raynes | alexbaranosky: For example, in my keys fact, I wrap my assertions in a let that binds 'ks' to an API call that returns the ssh keys a user has, and then that data is used in the following assertions. If I made each of those assertions (which are assertions about entirely different API calls) individual facts, I'd have to wrap them in a let like so: (let [l (Integer. "a")] (fact l => 3)). Now, the previous code will fail, but not in a |
| 15:42 | Raynes | pretty way. The error happens outside of a fact so I just get an ugly exception slathered on my terminal. And that is the extremely long explanation about why I grounded those assertions under one fact. |
| 15:42 | alexbaranosky | duck1123, gotcha... you can just use raw strings and Midje will ignore them |
| 15:42 | gtrak` | daniel__, you could probably do it yourself, I've written one in java in a couple hours. all you need is a db table to keep track of changes, and a migrate-up sql runner thingy |
| 15:42 | Raynes | s/grounded/grouped/ |
| 15:43 | duck1123 | I've been thinking I want to write an actual "context" macro for midje that will define the grouping like that but also allow me to attach backgrounds to that block in a nice way. Just haven't done it yet |
| 15:43 | alexbaranosky | Raynes, let me think about that |
| 15:44 | daniel__ | gtrak`: i could probably do it myself but im sure someone's already done it |
| 15:45 | gtrak` | yea |
| 15:45 | duck1123 | Raynes: what if you puth that let in a around background? |
| 15:45 | gtrak` | lots of wheels reinvented all the time :-) |
| 15:46 | duck1123 | Raynes: ie. https://github.com/duck1123/jiksnu/blob/master/test/jiksnu/model/webfinger_test.clj#L16 |
| 15:47 | alexbaranosky | Raynes, I've thought about it and I think what you're doing is fine. If I think of a cleaner way, I'll let you know |
| 15:47 | mindbender | (fact (let [l (Integer. "a"] l) => 3) |
| 15:48 | gtrak` | daniel__, http://budu.github.com/lobos/doc/uberdoc.migration.html |
| 15:49 | alexbaranosky | duck1123, Raynes yeah there might be something there with background or around... I'd dig in the docs in the wiki |
| 15:49 | Raynes | Digging. |
| 15:51 | alexbaranosky | Raynes, looks like `around` is what you want: https://github.com/marick/Midje/wiki/Setup%2C-Teardown%2C-and-State |
| 15:51 | Raynes | alexbaranosky: Yeah! |
| 15:51 | Raynes | duck1123: Thanks! :) |
| 15:51 | Raynes | Now I can FACTor this stuff out. ;) |
| 15:54 | duck1123 | One gotcha, multiple (background (arounds)) will overwrite each other. I have a global around that I keep in a test helper macro, that means that if I then want a per-namespace around, I need to use against-background, which indents all my tests |
| 15:55 | daniel__ | thanks gtrak` |
| 16:05 | Raynes | duck1123: This is working brilliantly. Thanks for pointing that out. |
| 16:06 | kumarshantanu | daniel__: https://bitbucket.org/kumarshantanu/lein-lb/overview |
| 16:06 | duck1123 | Raynes: no problem |
| 16:06 | Raynes | kumarshantanu: Do you use bitbucket to prove you're a rebel? |
| 16:07 | kumarshantanu | Raynes: I used to maintain my own mercurial repo once upon a while, then bitbucket was my consequential refuge |
| 16:17 | duck1123 | I have to say, I'm enjoying the little bit of color in my midje test results now. |
| 16:17 | alexbaranosky | duck1123, awesome :) |
| 16:19 | alexbaranosky | is there a way to set the REPL to pretty-print all output? |
| 16:38 | TimMc | alexbaranosky: Maybe a set! on one of those print vars? |
| 16:40 | TimMc | Hmm, I'm thinking of clojure.pprint |
| 16:40 | Raynes | alexbaranosky, duck1123: https://github.com/Raynes/tentacles/blob/master/test/tentacles/users_test.clj |
| 16:42 | daniel__ | thanks kumarshantanu |
| 16:45 | TimMc | alexbaranosky: You could have your REPL always pull in clojure.pprint/pp. Then you can write (pp) any time you want to pretty-print the last result. |
| 16:46 | Magnars | I just watched Rich doing his Simple made Easy talk. It was amazing. Anyone link to more videos/posts in that vein? |
| 16:48 | TimMc | Magnars: "Are We There Yet?" is a pretty good one. |
| 16:49 | Magnars | TimMc: Excellent, thanks. Loading it up right now. :-) |
| 16:50 | TimMc | Magnars: It is more foundational -- pre-Clojure stuff. |
| 16:51 | Magnars | TimMc: Sounds good. I'm very intrigued by his thoughts on state, time and complexity. |
| 16:53 | djhworld | does the clojure standard library function for flipping the arguments to a function? (like 'flip' in haskell) |
| 16:53 | djhworld | I've only managed to come up with this |
| 16:53 | djhworld | (defn flip [f & args] |
| 16:53 | djhworld | (apply f (reverse args))) |
| 16:54 | djhworld | but I was just wondering if there's one already out there |
| 16:55 | alexbaranosky | djanatyn, not in the standard library |
| 17:03 | duck1123 | I use a macro that log the pprinted result of the wrapped code. That handles all my desires to see stuff pprinted |
| 17:09 | Tharem | I've got a question about building trees in clojure. I've got a record that keeps some data around and can either point to nothing, one element or two other nodes. Now I want to code a function to add nodes to the tree, but of course assoc returns a new node instead of altering an existing one. Does that mean I have to use assoc to rebuild the entire tree or am I missing a shortcut? |
| 17:15 | duck1123 | Tharem: you would either want to return a new tree, or update an external ref. (prefer the first) |
| 17:15 | duck1123 | Clojure's data structures to make it way more efficient to return a whole new value than in other languages |
| 17:15 | Tharem | Yeah I get that. What I'm wondering about is building the new tree. Do I to use assoc on every element of the tree or is there a shortcut. |
| 17:16 | wiseen | Tharem, update-in ? |
| 17:16 | duck1123 | check out assoc-in and update-in |
| 17:17 | Tharem | Thanks. Looks like those where the functions I was looking for. Will they return a new tree? |
| 17:17 | duck1123 | yes |
| 17:17 | Tharem | OK nice |
| 17:18 | duck1123 | by "tree" are you talking maps of maps, or is this some other data structure |
| 17:18 | TimMc | &(update-in {:a [0 1 2] :b 6} [:a 1] * 30) |
| 17:18 | lazybot | ⇒ {:a [0 30 2], :b 6} |
| 17:19 | Tharem | It's essentially a map of maps. I've got a record that can point to two other records of the same type |
| 17:19 | TimMc | Any `associative?` data structure will do. |
| 17:19 | accel | Clojure likes immutable data right. Suppose I am writing a WYSIWYG editor; with nested components. How do I do updates to the document without recreating the entire document? |
| 17:19 | Tharem | The exact definition is (defrecord node [x-min y-min x-max y-max content split]). Content can either contain an element or a set of two nodes |
| 17:20 | TimMc | Tharem: You can access record fields using keywords. |
| 17:21 | TimMc | accel: It's a tree of maps and records and other associative data structures. Refer to the conversation Tharem is in right now. :-) |
| 17:21 | accel | so when I update a piece |
| 17:22 | wiseen | accel, you use one of "update" functions on the object and clojure returns a "new" object that *shares* all unmodified data with previous object |
| 17:22 | accel | is it O(n) time, or O(log n) time? |
| 17:23 | accel | wiseen: ah, so clojure does all this under the scene for me |
| 17:23 | TimMc | accel: Bonus: The old versions can be safely stored in an undo buffer. |
| 17:23 | TimMc | and they'll share structure, to keep memory down. |
| 17:23 | accel | x.update(k, y) = "create new x', with x'[k] = y" ? |
| 17:24 | TimMc | something like that |
| 17:26 | alexbaranosky | 32-bit vector trie rings a bell |
| 17:26 | wiseen | accel, http://www.innoq.com/blog/st/2010/04/clojure_performance_guarantees.html |
| 17:27 | TimMc | accel: This app I wrote <https://github.com/timmc/CS4300-HW3/> stores the entire program state as an associative data structure (maps, vectors, and records) and keeps undo and redo buffers of those values. |
| 17:27 | TimMc | I could also have stored the GUI state in there, which would have an interesting (probably unwanted) effect. |
| 17:28 | tmciver | TimMc: using slime/swank yet? |
| 17:28 | TimMc | haha, nope |
| 17:28 | accel | wiseen: are the columns off by 1 (i.e. should e shifted to the right by 1) |
| 17:28 | tmciver | TimMc: I just discovered that the slime-interrupt we talked about is bound to C-c C-c. Awesome. |
| 17:28 | TimMc | Haven't been doing algorithmic stuff, though. |
| 17:28 | TimMc | nice |
| 17:28 | wiseen | accel, yeah :) |
| 17:29 | tmciver | TimMc: Do you ever take a break from irc? Jeesh! |
| 17:29 | wiseen | it's not my site I just found that recently - I think it answers your questions |
| 17:30 | tmciver | TimMc: how am I supposed to keep up when you're here all the time? |
| 17:30 | Tharem | Hmm, so if I want to use update-in or assoc-in, I need to know the keys needed to get to the right node beforehand right? Or can I use a function that traverses the tree in some way, for example via a lazy sequence? |
| 17:31 | TimMc | tmciver: I keep my IRC window on all workspaces, so I chime in when there's something interesting. |
| 17:31 | TimMc | Tharem: That's right, you need to know the nature of the data structure. |
| 17:31 | alexbaranosky | TimMc, and there's almost always something interesting |
| 17:31 | TimMc | yup |
| 17:31 | tmciver | TimMc: I got my recursive hex-printing function working but I'm having a lot of trouble doing it non-recursively. |
| 17:32 | alexbaranosky | tmciver, use a loop |
| 17:32 | TimMc | Tharem: Wouldn't be hard to write something that recurses in a more complicated way. |
| 17:32 | Tharem | Yeah, I'm thinking of that too |
| 17:32 | tmciver | TimMc: the non-recursive way seems like it should have an elegant functional solution but I can't get my head around it yet. |
| 17:33 | TimMc | tmciver: What's wrong with loops? :-) |
| 17:33 | alexbaranosky | is it online where I could see it? |
| 17:33 | tmciver | alexbaranosky: hold on |
| 17:33 | TimMc | gist that sucker |
| 17:34 | accel | wiseen: it's very helpful; thanks! |
| 17:34 | accel | I have a structure that is equivalent to a HTML DOM tree. It's being constantly updated. What is the right clojure way to store it? |
| 17:35 | alexbaranosky | accel, a map most likely |
| 17:35 | Tharem | how is it being updated? |
| 17:35 | TimMc | accel: Store the top-level value in a ref. |
| 17:35 | accel | dom elements change |
| 17:35 | wiseen | accel, can you be a little more vague please, I can still get a hint of your problem :) |
| 17:36 | tmciver | TimMc: alexbaranosky: https://gist.github.com/1456800 |
| 17:36 | alexbaranosky | wiseen, good one, you made me laugh there |
| 17:36 | Tharem | No, I mean are you calling an update function every time, does it watch some value, is a thread sending it updates? |
| 17:36 | kumarshantanu | accel: perhaps either a transient vector or atom/ref of a vector, depending on where you want to use |
| 17:36 | tmciver | I started a looping version but it's a mess. |
| 17:37 | alexbaranosky | tmciver, I thought you said it was recursive? |
| 17:37 | alexbaranosky | that version is looping |
| 17:37 | tmciver | alexbaranosky: isn't it? It uses loop/recur |
| 17:37 | alexbaranosky | <<<loop>>> :) |
| 17:38 | alexbaranosky | loop/recur is the only way to loop in clojure |
| 17:38 | Tharem | You could use trampoline |
| 17:38 | Tharem | That can also be used for loops |
| 17:38 | alexbaranosky | well I guess maybe like doall or something |
| 17:38 | tmciver | alexbaranosky: I wanted to come up with an equivalent version that uses some combination of map/apply or some sort. |
| 17:38 | TimMc | tmciver: You want to print ab cd ef gh\nij kl mn... |
| 17:39 | tmciver | Yes. 16 bytes per line, with a space between pairs of bytes. |
| 17:40 | Tharem | hmm, doesn't clojure have a return keyword? I'm writing a function that's basically a long cond and it first needs to check a condition and return nil if the condition fails. Do I need to wrap the whole cond in an if-clause? |
| 17:40 | accel | wiseen: I have this idea in mind; I think it's turing complete, and thus can be written up in Clojure. However, I'm not sure where to start. |
| 17:40 | tmciver | TimMc: (with 2 spaces after 4 byte pairs. |
| 17:40 | tmciver | TimMc: that's what that version does. |
| 17:40 | accel | Let me rephrase my question. Suppose you're trying to write something like MS Word in Clojure, i.e. a WYSIWYG editor; what would be the right way to store the state of the documnet (i.e. the text, the nested structure of the text, etc ...) |
| 17:40 | accel | wiseen: ^is that better? |
| 17:43 | TimMc | accel: I also recommend using a data structure called a "rope" for any long strings of text. |
| 17:43 | Tharem | I'm not exactly sure of what you'd have to store but I'd go with nested maps. You can use watches to keep the GUI up-to-date and use normal map operations to update the maps. |
| 17:43 | TimMc | tmciver: Yeah, it can probably be done as a one-liner. |
| 17:43 | TimMc | accel: There's a Java library for it. Ropes are persistent data structures, by the way. |
| 17:44 | kumarshantanu | map entries are not ordered I think(?) |
| 17:44 | Tharem | They are if you use an ordered map ;) |
| 17:44 | TimMc | vectors are ordered, and can contain maps |
| 17:45 | Tharem | But if you need your stuff ordered and have no need to access them via keywords, vectors or lists would also work |
| 17:57 | kumarshantanu | tmciver: are you still looking for a non-loop solution for the snippet you gist'ed? |
| 17:57 | TimMc | Tharem: Regarding `return`, no, I don't know of a bail-out mechanism. |
| 17:58 | Tharem | Oh, I've found a way around it already, but thanks anyway. |
| 17:58 | TimMc | I've seen one written in Scheme with call/cc. :-P |
| 17:58 | TimMc | tmciver: Can you provide an example output? |
| 18:00 | tmciver | kumarshantanu: yeah, I'm working on it but if you want to take a crack feel free. |
| 18:00 | tmciver | TimMc: yep, hold on. |
| 18:02 | TimMc | tmciver: Data generator: (byte-array (take 20 (repeatedly #(byte (- (rand-int 256) 128))))) |
| 18:03 | tmciver | TimMc: updated gist: https://gist.github.com/1456800 |
| 18:03 | TimMc | Yeah, that's going to require 3 partition or partition-all calls. |
| 18:04 | tmciver | TimMc: for generating random binary data? Nice. |
| 18:06 | tmciver | Gotta go for a few minutes. Be back soon. |
| 18:08 | kumarshantanu | tmciver: I posted a comment with a snippet |
| 18:09 | TimMc | nice |
| 18:11 | TimMc | It does use flatten though, which is slightly squicky. |
| 18:12 | TimMc | I also prefer \space -- it is less visually magical. |
| 18:13 | kumarshantanu | TimMc: +1 @ \space |
| 18:13 | TimMc | I guess there's no harm in flatten when you *know* your data. |
| 18:13 | Tharem | Anyone got a good resource to learn about macros in clojure? I'm only familiar with Common Lisp macros and I have a hard time finding out how and where they differ |
| 18:14 | TimMc | Tharem: Some of that knowledge lives in http://clojure.org/reader |
| 18:17 | TimMc | Tharem: If you find a good post on the read vs. compile vs. eval stages of Clojure, I'd love to see it. |
| 18:17 | kumarshantanu | Tharem: TimMc: `The Joy of Clojure` describe macros and quoting quite nicely |
| 18:17 | TimMc | and of course http://clojure.org/lisps is good to review periodically. |
| 18:18 | kumarshantanu | I guess some other books do a good job too, but I don't remember |
| 18:18 | TimMc | kumarshantanu: Ah, I think I bought that. I should read it. >_< |
| 18:18 | Tharem | That's probably a bit deeper than I'm looking for right now, all I'm trying to do is write a let-variant of cond XD |
| 18:19 | TimMc | Tharem: ` is syntax-quote, ~ is unquote, ~@ is splicing-unquote, foo# is a gensym. :-) |
| 18:19 | kumarshantanu | Tharem: This might help -- http://java.ociweb.com/mark/clojure/article.html#Macros |
| 18:19 | Tharem | Kurman, yeah I'm looking at that right now |
| 18:19 | Tharem | Also screw me, there's a clojure "port" of practical common lisp. If there's one book that's a good introduction it's that |
| 18:20 | TimMc | kumarshantanu: After trying to write something without flatten, I think you were right to use it. |
| 18:20 | TimMc | too many (map (partial apply str) ...) |
| 18:22 | kumarshantanu | TimMc: A clever way to avoid flatten is to convert to string at every step, so as to give up laziness |
| 18:22 | TimMc | I tried that, it was ugly. Maybe I need to try harder. |
| 18:23 | Tharem | Oh joy, looks like I'm going to have to write a recursive macro :) |
| 18:26 | TimMc | Tharem: Want to gist the surface and expanded forms? |
| 18:34 | tmciver | kumarshantanu: Very good. Thanks! |
| 18:35 | tmciver | kumarshantanu: interpose, I forgot about that one. Makes things much easier, I think. |
| 18:36 | TimMc | tmciver: A close cousin of interleave. |
| 18:37 | devn | anyone here use clojurecheck? |
| 18:38 | devn | http://kotka.de/blog/2010/06/ClojureCheck_is_back.html |
| 18:38 | tmciver | TimMc: yes, another good one. This is why I come here, to be reminded of gems like those. |
| 18:38 | Tharem | Hmm, what's wrong with the following macro? http://pastebin.com/GJNvdash. It's giving me the following error: if-let requires a vector for its binding |
| 18:38 | TimMc | tmciver: Look at the source on http://clojuredocs.org/clojure_core/clojure.core/interpose |
| 18:39 | TimMc | Tharem: Have you tried macroexpanding it? |
| 18:39 | kumarshantanu | Tharem: the form is not quoted! |
| 18:39 | alexbaranosky | I'd love it if GitHub allowed people to upvote issues |
| 18:39 | Tharem | It won't even accept the definition. And before you ask, I see I forgot to add a # to the first rest. That doesn't affect the result |
| 18:40 | Tharem | Hmm, the form isn't quoted? which one? |
| 18:40 | alexbaranosky | I never know which feature to work on next... Sometimes it is hard to tell which features people care most about |
| 18:40 | TimMc | Tharem: gensyms are only valid inside syntax-quote |
| 18:40 | Tharem | oh... Good point |
| 18:40 | Tharem | Let me test it without that |
| 18:40 | TimMc | I think they are, at least! |
| 18:40 | Tharem | Hmm, removing the #'s doesn't change a thing |
| 18:41 | tmciver | TimMc: I didn't get the (drop 1 . . . part but it's to get rid of the first separator. |
| 18:41 | TimMc | tmciver: Correct. I tried making my own interpose, but I couldn't figure out how to get rid of the last separator -- the answer was to start with the separator! |
| 18:42 | tmciver | TimMc: couldn't you use drop-last? |
| 18:42 | TimMc | tmciver: Not as fun. |
| 18:43 | TimMc | (Probably less efficient.) |
| 18:43 | TimMc | Tharem: You are unquoting before getting to the gensym. Can you give an example of the desired input/output? |
| 18:44 | Tharem | Sure, here it is: http://pastebin.com/ydc1YLuZ. It also contains the newest macro definition with the gensyms stripped |
| 18:46 | alexbaranosky | Tharem, my version: (defmacro cond-let [cond fun & more] |
| 18:46 | alexbaranosky | `(if-let ~cond ~fun (cond-let ~more))) |
| 18:48 | TimMc | Racket's cond already has this, I think. |
| 18:50 | georgek | does anyone know of another location for the Noir docs, webnoir.org seems to be down |
| 18:50 | Tharem | Alexbaranosky: Almost works. First I had to splice the more. Now it's giving me errors because I'm calling cond-let with 0 input args, which can be fixed by adding a 0-element clause to cond-let |
| 18:50 | Tharem | Thanks |
| 18:50 | TimMc | alexbaranosky, Tharem: http://clojuredocs.org/clojure_contrib/clojure.contrib.cond/cond-let |
| 18:51 | Tharem | Ok I'm getting too tired for this XD |
| 18:52 | Tharem | Anyway, the macro is running now and it was good practice |
| 18:54 | TimMc | Tharem: Did you see macroexpand-1? It's a great debugging tool. |
| 18:54 | TimMc | You can also put printlns in your macro. :-P |
| 18:54 | Tharem | Yeah I know it. It doesn't help if the macro itself isn't a valid expression :P |
| 18:54 | georgek | nm, looking at the repository on github |
| 18:57 | TimMc | OK, time to switch my brain to Python for a bit. |
| 19:04 | jodaro | bleh. trying to get from a shitty java while loop with a bunch of "breaks" to a reasonably idiomatic clojure version |
| 19:05 | jodaro | if anyone has any general advice, i'd appreciate it |
| 19:05 | amalloy | TimMc: you can use foo# symbols outside of syntax-quote (since they're valid symbols, you can let them, etc), but it will just confuse people (usually the author) |
| 19:05 | jodaro | loop/recur gets me a lot of the way there i think |
| 19:05 | kumarshantanu | jodaro: can you gist it? |
| 19:06 | jodaro | https://github.com/imatix/zguide/blob/master/examples/Java/mdcliapi.java |
| 19:06 | jodaro | its the send method of that |
| 19:07 | jodaro | right now i'm loop/recurring on retries |
| 19:08 | jodaro | and the first thing i do is if-not interrrupted and retries |
| 19:08 | kumarshantanu | jodaro: consider this -- https://bitbucket.org/kumarshantanu/clj-miscutil/src/acfb97c662d9/src/main/clj/org/bituf/clj_miscutil.clj#cl-502 |
| 19:08 | jodaro | that actually gets me a decent amount of the way but i'm trying to figure out what to do on like line 106 |
| 19:09 | jodaro | looking |
| 19:10 | jodaro | ok yeah |
| 19:10 | jodaro | wow lots of great stuff here |
| 19:11 | jodaro | thanks |
| 19:22 | TimMc | amalloy: Ah, you're right -- I made a mistake when testing if it was allowed! |
| 19:23 | jcrossley3 | anyone know of a simple webdav library for clojure? |
| 19:24 | TimMc | You'll probably want to broaden your search to include Java libs. |
| 19:25 | jcrossley3 | yeah, figured, but wondered if anyone here might've used one they liked. |
| 20:16 | duck1123 | How do you point to a pom as a dependency in leiningen? ie. I want the transitive dependencies to be included |
| 20:20 | travisjeffery | Is there an easy way to get the value of a hash map for a key that may be either a string or keyword, e.g. if given {:my-keyword "my value"}, I could access "my value" with "my-keyword" hopefully without having to result to using a control structure. |
| 20:22 | cemerick | duck1123: lein does not support parent poms |
| 20:28 | TimMc | &(map keyword ["foo" 'foo :foo]) ; travisjeffery |
| 20:28 | lazybot | ⇒ (:foo :foo :foo) |
| 20:29 | tomoj | aren't parent poms a separate issue? |
| 20:31 | tomoj | you can point to a pom with :type "pom", but you just get the pom, not its deps.. due to the way the maven ant task works? |
| 20:33 | TimMc | &(symbol :foo) :-( |
| 20:33 | lazybot | java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.lang.String |
| 20:34 | mrb_bk | does anyone have much experience with clojure.java.io ? |
| 20:34 | mrb_bk | I'm trying to read in a byte stream and I'm wondering what the idiomatic clojure way of handling this is |
| 20:36 | cemerick | tomoj: poms don't have dependencies, they declare dependencies. Poms can have parents, but leiningen's model doesn't opt into that inheritance mechanism. It could, but there are actually far more powerful dependency/project composition options that have yet to be explored. |
| 20:37 | cemerick | This is part of what I'm driving at w/ my point #2 here. http://groups.google.com/group/leiningen/msg/cef32b294960b678 |
| 20:38 | cemerick | Lein v2 will make a lot of that sort of stuff feasible. |
| 20:40 | TimMc | mrb_bk: Depends on what you want to do with it, I think. |
| 20:41 | TimMc | A generic approach would use FileInputStream's .read into a byte-array. |
| 20:41 | mrb_bk | TimMc: actually that's what I'm tryign to do! |
| 20:41 | TimMc | I'm sure someone has created a lazy byte-seq thingy. |
| 20:42 | mrb_bk | I'm a total noob and am figuring out how to call the read(byte[] b, int off, int len) form of .read |
| 20:43 | weavejester | mrb_bk: What do you want to do with the ByteStream? |
| 20:43 | mrb_bk | weavejester: read it in x bytes at a time, compare it to some tokens, etc. |
| 20:44 | mrb_bk | so regular (.read (input-stream file)) works for me but I don't know the right way to call the above form |
| 20:45 | weavejester | Why not just read it into a byte array? |
| 20:45 | TimMc | mrb_bk: What specifically are you having trouble with? Creating a byte array? |
| 20:45 | weavejester | (let [b (byte-array 10)] (.read stream b) b) |
| 20:46 | weavejester | Although you probably want to reuse the array |
| 20:46 | mrb_bk | ah |
| 20:46 | mrb_bk | yes |
| 20:47 | mrb_bk | TimMc: yeah that's what was tripping me up |
| 20:48 | TimMc | mrb_bk: Example: (with-open [r (java.io.FileInputStream. "project.clj")] (let [bs (byte-array 20)] (.read r bs) (seq bs))) |
| 20:48 | TimMc | The (seq bs) is just to get you something printable. |
| 20:50 | mrb_bk | TimMc: beautiful |
| 20:50 | mrb_bk | thank you |
| 20:50 | mrb_bk | weavejester: thanks! |
| 20:51 | weavejester | np |
| 20:51 | mrb_bk | how about using a function like the above to scan through the file |
| 20:51 | mrb_bk | i have to take 5 bytes, and then 2 bytes, and then 6 bytes, and then 8 bytes, etc. |
| 20:52 | weavejester | I almost wonder whether chunked arrays might be a good choice to do that... |
| 20:52 | weavejester | Or chunked seqs, I mean |
| 20:53 | mrb_bk | this is close to clicking with me but i get confused about the correct way to hold on to the "index" of the stream being seq'd |
| 20:53 | mrb_bk | like for the above i want to .read 5, and then another number after |
| 20:53 | mrb_bk | not read the first 5 and then the first 2 again, etc. |
| 20:54 | weavejester | Well, I'm not sure how efficient it would be, but you could turn the whole stream into a lazy seq of bytes |
| 20:54 | weavejester | Well... maybe that would be inefficient... |
| 20:54 | TimMc | weavejester: tmciver has been playing with byte stuff too. Can you think of an efficient way to make aand use a byte-seq? |
| 20:55 | TimMc | perhaps a hinted seq class |
| 20:55 | weavejester | TimMc: Hmm... I haven't really given it much thought... |
| 20:56 | weavejester | I doubt a standard lazy seq of bytes would be hugely memory-efficient :) |
| 20:56 | weavejester | But maybe something that implements the ISeq interface? |
| 21:00 | weavejester | mrb_bk: What are you going to do with the bytes when they have been read? |
| 21:00 | weavejester | It kinda sounds like you're implementing some sort of binary protocol? |
| 21:07 | TimMc | weavejester: Shouldn't be too hard to write one. How can I tell if it is employing boxing, by the way? |
| 21:08 | weavejester | TimMc: You mean boxing a byte into a Byte? |
| 21:08 | TimMc | right |
| 21:09 | TimMc | I can throw hints at it all I like, but how can I tell if they are working? :-P |
| 21:09 | weavejester | Not sure why it would be, but maybe I'm thinking of a different sort of implementation. |
| 21:09 | mrb_bk | weavejester: yep, binary protocol |
| 21:09 | mrb_bk | so it has a small "magic number" header, a version number, and then data |
| 21:10 | amalloy | binary protocol: probably worth learning gloss |
| 21:10 | mrb_bk | a lazy seq of bytes is what i was hoping i could get |
| 21:10 | weavejester | You could probably make a function like: |
| 21:10 | mrb_bk | amalloy: oh cool, gloss looks like it could help |
| 21:11 | weavejester | (defn read-bytes [s n] (let [bs (byte-array n)] (.read s bs) (seq bs))) |
| 21:12 | mrb_bk | weavejester: it should return the "rest" of the file, right? |
| 21:12 | weavejester | mrb_bk: What returns the rest of the file? |
| 21:14 | mrb_bk | weavejester: sorry, i just mean the function should read n bytes from the stream, do some evaluation of the bytes which have been put into a byte array, and then should either have the opportunity to exit or read the next n bytes |
| 21:17 | weavejester | mrb_bk: Yeah, so .read is a side-effectful operation, right? |
| 21:18 | weavejester | mrb_bk: So you can just do something like (read-bytes stream 4) to read the next 4 bytes |
| 21:20 | TimMc | It would be better to have the mutation contained. |
| 21:21 | weavejester | Yeah... Gloss sounds nice in that regard. |
| 21:22 | TimMc | Does Gloss expose some of the lower-level aspects, and not just a fancy DSL? |
| 21:22 | weavejester | But I'm not sure how tricky the protocol is... |
| 21:22 | weavejester | No idea, honestly. I haven't looked into Gloss. |
| 21:25 | TimMc | Oh, it looks pretty nice, actually. |
| 21:26 | TimMc | mrb_bk: Yeah, just use Gloss, it looks fantastic. |
| 21:26 | weavejester | ztellman usually does good work. |
| 21:26 | weavejester | All of his libraries tend to be well-thought-out |
| 21:31 | TimMc | Huh, has a pretty good blog too. |
| 21:32 | tomoj | I haven't been able to figure out how to do magic numbers in gloss |
| 21:33 | tomoj | I mean, if you know the length of the thing it's easy to parse successfully, but it seems ideally it'd be a constant in the frame definition and would be left out of the result |
| 21:35 | tomoj | I guess your decoder function can just throw it out? |
| 21:47 | TimMc | tomoj: Call it _, I guess. :-) |
| 21:47 | TimMc | I think you can say to expect a literal. |
| 21:48 | amalloy | tomoj: it looks like you can use a header |
| 21:50 | amalloy | (header :int32 {0xDEADBEEF body-codec} (constantly 0xDEADBEEF)) |
| 21:51 | amalloy | and use an error-detecting-function instead of just a plain map if you want something nicer than NPE when the magic number is wrong |
| 22:14 | tomoj | yeah, that looks good, thanks |
| 22:35 | ambrosebs | gtrak`: my gist before was the ClojureScript analyzer being used on clojure code |
| 22:40 | misfo | Did the anonymous function literal work differently in clojure 1.2? |
| 22:41 | TimMc | misfo: Not that I know of, why? |
| 22:42 | misfo | I'm using compojure for a web app (which uses Clojure 1.2) and for some reason I can't get map to work with an anonymous function literal |
| 22:42 | misfo | It works just fine with (fn [thing] ...) |
| 22:59 | TimMc | misfo: Here's a debugging tip: Enter the literal in a REPL, preceded by ` |
| 23:00 | TimMc | &`#(+ % 4) ; for example |
| 23:00 | lazybot | ⇒ (fn* [p1__25495__25496__auto__] (clojure.core/+ p1__25495__25496__auto__ 4)) |
| 23:02 | TimMc | then compare that to your explicit version |
| 23:02 | misfo | Tim: that's a good tip |
| 23:02 | TimMc | amalloy taught me that one |
| 23:03 | misfo | I figured out that I my code was trying to execute a map |
| 23:03 | misfo | woops |
| 23:03 | misfo | (map #({:a (:b %)}) other-map) |
| 23:04 | TimMc | Well, that *can* work... if you pass it an argument. :-) |
| 23:04 | misfo | works fine as (map (fn [m] {:a (:b m)}) other-map) |
| 23:05 | TimMc | Probably best to use the fn version. |
| 23:05 | misfo | which leads me to another question: is there a better way to "rename" a key in every map in a collection? |
| 23:06 | misfo | sorry, "other-map" in my example is actually a sequence of maps |
| 23:06 | cgray | misfo: you could use (map #(hash-map :a (:b %)) other-map) if you wanted |
| 23:06 | TimMc | Well, that reduces to how to rename a key in a single map. |
| 23:07 | misfo | cgray: thanks, that's what i was *trying* to do with the function literal |
| 23:09 | misfo | TimMc: makes sense. so is there a better way to do that than the fn i was passing to map? |
| 23:09 | TimMc | misfo: It's probably time for a helper function. I don't know of a core fn. |
| 23:09 | TimMc | I know there's a fn to map over the keys of a fn, but that's not what you want. |
| 23:10 | cgray | misfo: store the value of :b somewhere, then dissoc :b and assoc :a |
| 23:10 | tomoj | wouldn't the (:b %) always return nil? |
| 23:10 | tomoj | oh |
| 23:11 | tomoj | missed that bit :) |
| 23:11 | TimMc | There's probably some nasty trick with replace. |
| 23:12 | misfo | cgray: that would work, but wouldn't be any shorter. i was just wondering if there was a function for doing that in core |
| 23:12 | misfo | (map %(rename-key :old :new) maps) |
| 23:12 | misfo | something like that |
| 23:12 | misfo | no big deal if there isn't |
| 23:13 | TimMc | I don't think it's really common. |
| 23:13 | misfo | errr.... (map #(rename-key % :old :new) maps) |
| 23:13 | cgray | misfo: well just write rename-key yourself :) |
| 23:13 | tomoj | there is clojure.set/rename-keys |
| 23:13 | tomoj | but that doesn't do what you wrote |
| 23:14 | TimMc | that renames all of them, right? |
| 23:14 | misfo | cgray: point taken |
| 23:14 | tomoj | it renames whichever you want, but it keeps the rest of the kvs too |
| 23:14 | tomoj | instead of just returning a map with one pair |
| 23:14 | TimMc | that's fine, right? |
| 23:15 | TimMc | Oh hey, that's perfect. |
| 23:15 | TimMc | ,(require 'clojure.set) |
| 23:15 | clojurebot | nil |
| 23:16 | TimMc | ,(clojure.set/rename-keys {:a 1, :b 2} {:a :c}) |
| 23:16 | clojurebot | {:c 1, :b 2} |
| 23:16 | TimMc | welp |
| 23:16 | tomoj | I am slightly curious why it's in clojure.set.. |
| 23:16 | TimMc | misfo: ^ |
| 23:17 | misfo | yeah, that's exactly what i need |
| 23:17 | misfo | thanks |
| 23:17 | misfo | ! |
| 23:17 | misfo | yeah, why is that in clojure.set? |
| 23:17 | TimMc | &(inc tomoj) |
| 23:17 | lazybot | java.lang.RuntimeException: Unable to resolve symbol: tomoj in this context |
| 23:17 | TimMc | haha |
| 23:17 | tomoj | wtf is a rel anyway? |
| 23:17 | TimMc | &inc tomoj |
| 23:17 | lazybot | ⇒ #<core$inc clojure.core$inc@d47af3> |
| 23:17 | TimMc | -.- |
| 23:18 | cgray | tomoj: see line 1 of the example in map-invert on clojuredocs |
| 23:20 | tomoj | hmm.. is a rel a seq of associatives? |
| 23:21 | tomoj | as in.. _rel_ational maybe? |
| 23:21 | TimMc | where do you see "rel"? |
| 23:22 | tomoj | docs for many functions in clojure.set |
| 23:22 | tomoj | looks like it is canonically a set of associatives, though any seqs work too, at least in some places? |
| 23:23 | TimMc | Oh, makes sense, I think. |
| 23:23 | TimMc | It's a set of named tuples. |
| 23:24 | TimMc | clojure.set seems to be centered around relational algebra. |
| 23:26 | tomoj | and a rel is a set, so clojure.set makes perfect sense for a name. </sarcasm> |
| 23:26 | TimMc | Probably named that way for hysterical raisins. |
| 23:28 | TimMc | Like, someone was doing some database stuff, and created that lib for sets, then expanded it sideways. :-) |
| 23:29 | tomoj | index: "Returns a map of the distinct values of ks in the xrel mapped to a set of the maps in xrel with the corresponding values of ks." |
| 23:30 | tomoj | jeebus |
| 23:30 | tomoj | clojuredocs to the rescue :D |
| 23:38 | TimMc | I want the author of ClojureDocs to send a pull request to the Clojure/Core team. -.- |
| 23:55 | apetrescu | I think Marginalia might be the prettiest documentation generator I've ever seen |
| 23:55 | apetrescu | I would start using Clojure just for that |