2011-11-13
| 00:00 | technomancy | I am probably not going to be measuring perf so much that I'd notice, but I appreciate having it available |
| 00:00 | dakrone | cool, well lemme know how it works regardless :) |
| 00:00 | dakrone | and lemme know how I can hely with the JAVA_OPTS lein thing |
| 00:00 | dakrone | *help |
| 00:01 | leo2007 | technomancy: do you know if fuzzy completion works in slime? |
| 00:02 | technomancy | leo2007: people have gotten it working, but I don't know the details |
| 00:04 | technomancy | dakrone: it's just the smarter quote-aware space string split in (System/getenv "JVM_OPTS") on line 94 of compile.clj |
| 00:04 | dakrone | technomancy: I'll take a look |
| 00:07 | technomancy | sweet |
| 02:26 | loz | hi |
| 02:26 | loz | it is possible to run clojure programs on android platform? |
| 02:28 | zms | loz: if clojure been ported to dalvik as well, i guess. |
| 02:30 | loz | zms: any progress in porting? |
| 02:32 | zms | loz: this is all i'm aware of http://www.deepbluelambda.org/programming/clojure/clojure-for-android-source-published |
| 02:36 | loz | zms: cool, sounds assure) |
| 03:24 | mdeboard | Weird question, but is the guy I was bickering with about the functional nature of list comprehensions in python the other day in here? |
| 04:55 | _ulises | I know this is awfully specific, but is anybody running emacs inside iTerm2/Terminal.app? |
| 04:55 | _ulises | I'm having trouble mapping C-up/down arrow for history support in slime |
| 07:39 | zms | can someone please take a look at http://pastie.org/2856453 |
| 08:13 | _ulises | zms: what's with it? |
| 08:35 | kzar | Oh I see how to do it.. just looked at how with-connection works, ovbious really! Sorry |
| 08:42 | zms | _ulises: the dorun part throws a null pointer exception and i've been unable to figure out the source |
| 08:43 | _ulises | zms: line 15, you have ((println...)) |
| 08:44 | _ulises | zms: println returns nil, if you try to eval that as a fn you're likely to get a NPE |
| 08:44 | _ulises | </wild_guess> |
| 08:44 | zms | _ulises: testing.. |
| 09:01 | zms | _ulises: you're right. the NPE goes away if i remove this statement. but the purpose of the statement was to show if it's actually doing what it should (check if files can fit into available space). that is broken too.. |
| 09:02 | _ulises | zms: you're trying to modify m with assoc. assoc returns a new map and then it gets discarded :) |
| 09:02 | _ulises | if that's what you mean by "that's broken too" |
| 09:02 | zms | _ulises: i'm not sure if the idea of updating the existing list of maps and use that in next iteration sensible at all. coming from imperative mindset i can't seem to think of a way to do it. :-( |
| 09:03 | zms | _ulises: ouch. i tried using update-in but that also didn't seem to make sense. |
| 09:03 | _ulises | zms: that's because, as you said, you're writing imperative for loops |
| 09:05 | zms | _ulises: it's been mind-bending wrapping my head around this. it's fun but frustrating as hell too. :) |
| 09:05 | _ulises | zms: let me see if I can cook up something quick that does what you want; then we can walk through it together |
| 09:06 | zms | _ulises: i'll be ever grateful. |
| 09:10 | Vinzent | anyway, why i can't write something like (def foo) (fact (inc foo) => 2 (provided foo => 1))? |
| 09:11 | Vinzent | or maybe (fact .x. => 1 (provided .x. => 1)) |
| 09:21 | _ulises | zms: nearly there |
| 09:25 | zms | _ulises: wonderful! |
| 09:31 | _ulises | zms: http://pastie.org/2856836 |
| 09:31 | _ulises | zms: there are a few nasty bits such as (comp not (some predicate...))) |
| 09:32 | _ulises | but the general flow of the algorithm is to recurse while trying to fit files into mount points; each recursion loop takes the first file and sees if it fits in any mount point, if so it adds it to the list of files that do fit somewhere, updates the mount point's free space and recurses using the updated list of mount points and files |
| 09:33 | _ulises | I'm sure the code is *not* as clear as it could be |
| 09:33 | _ulises | I also added the option of tagging each file that fits somewhere with the path where you'd have to place it |
| 09:34 | Borkdude | _ulises: did you see the thing about the encoding variable yesterday? |
| 09:35 | Borkdude | _ulises: it solved my slime error |
| 09:38 | zms | _ulises: thanks a lot! it'll take me some time to digest this and get back. |
| 09:41 | _ulises | Borkdude: I tried it today and it solved mine too :) |
| 09:41 | _ulises | zms: cool, enjoy :) |
| 10:19 | zms | _ulises: there's so many new things (for me) in what you wrote (into, partial, conj, comp, ..) and all introduced in a context/problem space that i understand. :) it'll probably be a while before i can come back to discuss the code. thanks again for your time. |
| 10:20 | _ulises | zms: no worries. Please keep in mind that that is definitely not the best code to learn from :) |
| 10:24 | zms | _ulises: hehe. still it's an order of magnitude beyond my current level so it's a gift and a lesson to me. |
| 10:24 | _ulises | zms: cool then, glad to be of assistance :) |
| 10:42 | Vinzent | here is _ulises' code with some minor modifications: http://pastie.org/2857122, wdyt? |
| 11:00 | zms | Vinzent: it does produce the same results. i see the differences are in the let bindings. i can't say which one is better or simpler yet. there's more new functions here (group by, concat, ...) and like i said above, i'm still reconfiguring my brain to think in clojure. thank you for the code. i am learning from both of them. |
| 11:21 | Vinzent | zms, i've also tried to avoid multiplie passes through the collections (when sorting and around the cons call), although it's not much perfomance boost with collections of such size :) anyway, i think it's interesting to try to find different approaches to the problem |
| 11:21 | Vinzent | so _ulises made a good exercise for both of us :) |
| 11:30 | jakeskik | hi |
| 11:31 | zms | Vinzent: indeed. :) |
| 11:32 | Vinzent | hello jakeskik |
| 11:32 | jakeskik | is there something like difference for vectors? |
| 11:33 | jakeskik | or haskell \\ operator? |
| 11:33 | jakeskik | so that (difference [1 1 1 2 3] [1 2]) would result [1 1 3] |
| 11:34 | Vinzent | you can convert one vector into the set and then (remove ...) |
| 11:35 | Vinzent | but that will return [3] for ypur example |
| 11:36 | jakeskik | yap, I need to keep the duplicates (except the one which was processed) |
| 11:38 | jakeskik | I'm finding my way around core libraries and trying to craft a decent solution for KataPotter: http://codingdojo.org/cgi-bin/wiki.pl?KataPotter |
| 11:42 | Vinzent | then it's possible either to use reduce with accumulator, or partition |
| 11:50 | jakeskik | Vinzent: thanks, i'll check patitioning. I played a bit with reduce too, but it seemed to lead quite complex solution. I'd like to do something like this: https://gist.github.com/1362307 |
| 11:52 | jakeskik | of course, the remove call on the last line doesn't do the trick and I should do the recursion with recur instead of calling the function. |
| 12:05 | Vinzent | jakeskik, sorry for the delay. here is a possible implementation: http://pastie.org/2857437 My proposal about partition was wrong, it'd help only if you want to remove the whole second-vector occurences |
| 12:05 | Vinzent | let me read your links |
| 12:10 | zeek123 | Anyone willing to look at three versions of 10 lines of code? I'm loading an file entire into a list and partitioning the list into a list of pairs. Two versions don't work and one works verrrrry slowly. Thanks. |
| 12:16 | fliebel | zeek123: You did not actually post the 10 lines. |
| 12:16 | zeek123 | Indeed. I wanted to make sure it was appropriate to do so. |
| 12:16 | zeek123 | Here they come... |
| 12:17 | TimMc | zeek123: pastebin, of course |
| 12:17 | zeek123 | that was my next q, thanks |
| 12:18 | TimMc | ~paste |
| 12:18 | clojurebot | paste is http://gist.github.com/ |
| 12:19 | zeek123 | https://gist.github.com/1362348 |
| 12:19 | fliebel | Do files and sockets actually override Object.finalize? |
| 12:21 | zeek123 | TimMc: I'm getting OutOfMemoryErrors if I remove the doalls. But with the doalls, it doesn't seem to terminate, but it might eventually. If I use my group-by-twos instead of partition, then back to OutOfMemoryErrors. I want to make sure I understand what lazy sequences do before I actually try to do something real. |
| 12:21 | TimMc | Do you really need the whole file in memory at once? |
| 12:22 | TimMc | Can you process it as a stream instead? |
| 12:22 | zeek123 | Ideally I want to do numerical processing on ~1.5GB files with Incanter, so I guess ultimately I won't be able to keep everything in mem at once. |
| 12:23 | zeek123 | My ultimate goal is an n^2 algorithm. I will need to keep scanning back to the beginning of the file... Are streams still a good fit? |
| 12:26 | TimMc | zeek123: The thing about lazy seqs is this: Although they delay computation of the seq until it is needed, they keep the results around as long as you hold onto the head of the seq. |
| 12:26 | zeek123 | I was formulating a question about that... is there a way to do this that generates what I need from a function? I know there's a classic newbie mistake in here somewhere. |
| 12:27 | TimMc | It really depends on what you want to do. |
| 12:27 | zeek123 | hmm |
| 12:28 | zeek123 | I found a bunch of blog posts about this topic, but nothing that was immediately enlightening. Any general principles or reading, or should I go back to my original problem and do some more thinking? |
| 12:28 | TimMc | seqs wrapped around file streams are great if you are doing stream processing -- as you keep calling (next) on the seq, the lines or chars that you have read into the seq (lazily) are garbage-collected. |
| 12:29 | zeek123 | TimMc: That makes sense. You keep rebinding to a new head, right? |
| 12:29 | TimMc | yeah |
| 12:29 | TimMc | In the general case, seqs are just linked lists with some potentially clever stuff in the tail. |
| 12:30 | zeek123 | Because they're lazy they're faster but they take up more mem, right? |
| 12:30 | zeek123 | Or at least they accumulate a lot of not-yet-run code. |
| 12:30 | TimMc | I don't know how much more memory they take up. Less, if you don't realize the entire tail while holding onto the head. |
| 12:31 | zeek123 | Makes sense; especially if the seq is infinite. |
| 12:31 | TimMc | right |
| 12:31 | zeek123 | So maybe I should be thinking harder about what I can throw away and when. And how to get it back on-the-fly if I need it again. |
| 12:31 | TimMc | You can keep walking (range) as long as you like as long as you don't keep a reference to the head. |
| 12:31 | duck1123 | was there a clojure library wrapping java.security.* I remember seeing something, but I can't find it again |
| 12:32 | TimMc | zeek123: Yep. What are you writing? |
| 12:32 | duck1123 | trying to avoid re-inventing the cryptographic wheel |
| 12:33 | TimMc | duck1123: java.security is just easy enough to use that I haven't bothered looking for a wrapper. |
| 12:33 | duck1123 | zeek123: as long as you make sure not to hold the head of any long lazy seqs, the JVM should be pretty good at GC-ing those discarded objects |
| 12:33 | zeek123 | TimMc: It's a compression algorithm from a 2011 paper that uses previous "contexts." You need to be able to search through everything causal to the symbol you're trying to encode. I have it mostly working in Matlab, but I'm trying to break my dependence on Matlab, etc. |
| 12:33 | TimMc | duck1123: The problem here is a quadratic algorithm that maybe requires all the data at once. |
| 12:33 | leo2007 | how to get java doc in clojure repl? |
| 12:33 | duck1123 | TimMc: not sure if that was sarcastic or not... |
| 12:33 | zeek123 | (Thanks, duck1123.) |
| 12:34 | leo2007 | duck1123: do you use ac-slime? |
| 12:35 | TimMc | duck1123: j.s.MessageDigest isn't so bad! |
| 12:35 | zeek123 | TimMc: I've never had to do this before, but maybe I should leave the file I'm encoding on disk and do random access as needed. |
| 12:35 | duck1123 | leo2007: No, I only use the default of what is loaded with the emacs starter kit |
| 12:36 | TimMc | zeek123: Is there any way you can build up a table of extracted data? |
| 12:36 | duck1123 | TimMc: I'm doing RSA encrytion and verification. (implementing the salmon protocol) and it's a bit of a pain |
| 12:37 | TimMc | hrm |
| 12:37 | TimMc | duck1123: So, not just running some bytes through MD5? |
| 12:37 | duck1123 | no, a bit more complicated than that |
| 12:39 | TimMc | zeek123: "symbols" are any byte sequence? |
| 12:39 | zeek123 | TimMc: The "contexts" heavily overlap, like a sliding window, and they can't really be boiled down into a table. I think what I'll do is have one stream of the file for encoding, and I'll have to restream the entire file for each symbol that I want to encode. |
| 12:40 | TimMc | eep |
| 12:40 | zeek123 | TimMc: Symbols are 16 bits of any arbitrary byte sequence. |
| 12:40 | zeek123 | I don't see another way to do it. :) |
| 12:41 | zeek123 | In matlab I can get the entire file into memory and then have multiple iterators off of it. |
| 12:41 | fliebel | Has anyone written something to access fields and enums nicely in Clojure? bean coms close, but that's not "it" |
| 12:41 | zeek123 | but I am still making many, many passes over the file. |
| 12:42 | TimMc | zeek123: I'm sure there's a way to load the whole file into memory in Clojure, too -- you'd just want to use something other than a lazy seq to iterate over it. |
| 12:43 | TimMc | There's probably an existing seq impl that will do what you want here/ |
| 12:43 | zeek123 | TimMc: re loading whole file into memory; yes! that would be fantastic. seq implementation: what should i be googling? |
| 12:44 | zeek123 | how can i not fill up the JVM heap? how do i know how much it's giving me? |
| 12:45 | TimMc | Well, you may need to tell the JVM to use a big heap. There are some switches like -Xmx2G you can pass it for various aspects of its memory footprint. |
| 12:46 | zeek123 | TimMc: got it |
| 12:47 | TimMc | zeek123: What sort of access do you need to the data? Aligned words? |
| 12:47 | zeek123 | TimMc: yes, the file will always be an even number of bytes |
| 12:47 | zeek123 | and my "symbols" are 16 bits |
| 12:49 | TimMc | So some kind of random-access collection of ints |
| 12:49 | TimMc | or bytes, I guess |
| 12:49 | zeek123 | TimMc: makes sense. ideas for idiomatic clojure? |
| 12:50 | TimMc | Not sure yet. |
| 12:50 | TimMc | If you read the whole thing in, the JVM might not be happy with the size of the byte[] required. |
| 12:51 | duck1123 | Okay, the good news is I can sign and verify with freshly generated keys, so this hasn't been a complete loss. Now to just figure out where the example sig I have fails. |
| 12:52 | TimMc | There are utilities around that can manage large buffers of (primitive) bytes; that's what you'd want to use. You can probably roll a quick function to slurp a file into one of these. |
| 12:53 | TimMc | duck-streams did this kind of thing, but it no longer quite exists. |
| 12:53 | duck1123 | Would a simple byte array input stream work for you? It's easy enough to get that from a file |
| 12:53 | TimMc | duck1123: For a 1+ GB file? |
| 12:53 | duck1123 | most went to c.java.io |
| 12:54 | TimMc | there are limits to the *length* of arrays in Java |
| 12:54 | TimMc | zeek123: Oh! Could you maybe memory-map a file? |
| 12:54 | zeek123 | TimMc: duck1123: It's not even so much the size of the file, it's any time i start doing interesting things with it that the memory usage explodes. |
| 12:55 | zeek123 | TimMc: that's a great idea. more transparent to me. |
| 12:55 | TimMc | java.nio I think has utils for that |
| 12:55 | duck1123 | isn't there a lazy input stream for stuff like that? I don't know as much about java io as I should |
| 12:56 | zeek123 | TimMc: I will have a look at that, and I will make sure to lose my head, as it were. That will hopefully get me a lot farther. |
| 12:56 | TimMc | duck1123: I really don't think that will work here -- this algorithm needs random access. |
| 12:57 | duck1123 | nvm then |
| 12:57 | zeek123 | TimMc: In any case, you don't think I'll be adding epicycles on top of epicycles? Clojure is a reasonable language for this? It's been a real pleasure to work with so far. I'm hoping to stick with it. |
| 12:58 | TimMc | zeek123: Nothing wrong with using Java libs. That's why Clojure targets the JVm, after all. |
| 12:59 | TimMc | I think Clojure is a fine language for this. You'll just need to be careful about which tools you use, just as in Java. |
| 12:59 | TimMc | (e.g. for this project you wouldn't use an ArrayList<Byte>.) |
| 13:00 | zeek123 | TimMc: right, thanks. i think I'm spoiled by matlab, but half the point of this is to get out of the matlab ghetto. |
| 13:00 | TimMc | haha |
| 13:00 | zeek123 | matlab is, after all, dedicated to this kind of problem |
| 13:00 | TimMc | yup |
| 13:01 | zeek123 | and i want to be working with a general language so while i'm doing this stuff i'll be building skills that i can use for my own projects. |
| 13:01 | zeek123 | anyway, thanks for much for kicking this around with me. i'll have a look at what we've chatted about. |
| 13:01 | zeek123 | thanks for the ideas duck1123. |
| 13:01 | zeek123 | afk for now |
| 13:02 | TimMc | zeek123: I'll leave you a link as soon as I can find it. |
| 13:03 | zeek123 | TimMc: i'll keep an eye on the log |
| 13:04 | TimMc | zeek123: Here is a post by dnolen with an example of high-efficiency Clojure: http://dosync.posterous.com/lispers-know-the-value-of-everything-and-the |
| 13:06 | zeek123 | TimMc: link is excellent. much food for thought. afk for real this time. |
| 13:55 | fliebel | drewr: Why is javax.activation excluded? |
| 14:05 | fliebel | Can we have clojure in clojure already? If java.lang where all protocols, life would be easy, in certain areas. |
| 14:05 | dbushenko | how to override JFrame.paint() with clojure? |
| 14:09 | TimMc | dbushenko: proxy |
| 14:09 | dbushenko | TimMc, have a look: (proxy [JFrame] [] (paint [graphics] (println "Hello, World!"))) |
| 14:10 | dbushenko | it doesn't work. could you tell my why? |
| 14:10 | fliebel | &(source into) |
| 14:10 | lazybot | java.lang.RuntimeException: Unable to resolve symbol: source in this context |
| 14:10 | TimMc | dbushenko: $source into |
| 14:10 | TimMc | ack |
| 14:10 | TimMc | $source into |
| 14:10 | lazybot | into is http://is.gd/7toqQd |
| 14:10 | TimMc | fliebel: ^ |
| 14:10 | fliebel | (use 'clojure.repl) |
| 14:11 | fliebel | &(use 'clojure.repl) |
| 14:11 | lazybot | ⇒ nil |
| 14:11 | fliebel | &(source into) |
| 14:11 | lazybot | ⇒ Source not found nil |
| 14:11 | TimMc | dbushenko: I've done it here: https://github.com/timmc/CS4300-hw6/blob/master/src/hw6/core.clj#L25 |
| 14:11 | fliebel | ok, what I wanted to say, is that it does some weird stuff for transients. |
| 14:11 | dbushenko | TimMc, thanks! |
| 14:12 | fliebel | if it is a transient, convert it to a transient, conj, and return a persustent. |
| 14:12 | TimMc | dbushenko: Mine is doing some other stuff, but the basic are there. |
| 14:13 | dbushenko | Looks like your code is similar to mine.. |
| 14:15 | TimMc | dbushenko: Does the window at least come up? |
| 14:15 | TimMc | ,(ancestors (class (transient []))) |
| 14:15 | dbushenko | yeah, but the paint function isn't called |
| 14:15 | clojurebot | #{clojure.lang.ILookup clojure.lang.ITransientCollection java.util.concurrent.Callable clojure.lang.AFn java.lang.Runnable ...} |
| 14:15 | gfredericks | ,(.run (transient [])) |
| 14:15 | clojurebot | #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: TransientVector> |
| 14:16 | TimMc | &(instance? clojure.lang.IEditableCollection (transient [])) |
| 14:16 | lazybot | ⇒ false |
| 14:16 | TimMc | &(instance? clojure.lang.IEditableCollection []) |
| 14:16 | lazybot | ⇒ true |
| 14:16 | TimMc | fliebel: That's neat. |
| 14:16 | gfredericks | O_o |
| 14:16 | gfredericks | TimMc: what does it mean? |
| 14:16 | TimMc | gfredericks: Take a look at into's source. |
| 14:17 | gfredericks | so "Editable" means "transientable"? |
| 14:17 | TimMc | Apparently. |
| 14:17 | fliebel | TimMc: wait, what... a persistent collection extends clojure.lang.IEditableCollection? |
| 14:17 | TimMc | Yeah. :-) |
| 14:17 | TimMc | It's not a great name. |
| 14:18 | fliebel | ah, I though all transients where editable, which is why I was confused. |
| 14:18 | gfredericks | ,(transient (transient [])) |
| 14:18 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentVector$TransientVector cannot be cast to clojure.lang.IEditableCollection> |
| 14:18 | TimMc | fliebel: It's more that they are Editablable :-P |
| 14:18 | TimMc | And I wonder... ##(into (transient []) [1 2 3]) |
| 14:18 | lazybot | java.lang.ClassCastException: clojure.lang.PersistentVector$TransientVector cannot be cast to clojure.lang.IPersistentCollection |
| 14:18 | TimMc | And I wonder... ##(class (into (transient []) [1 2 3])) |
| 14:18 | lazybot | java.lang.ClassCastException: clojure.lang.PersistentVector$TransientVector cannot be cast to clojure.lang.IPersistentCollection |
| 14:19 | TimMc | OK, so you can't use into with transients. Not a big surprise, you have a limited set of operators. |
| 14:20 | TimMc | Question for the channel: Is it proper to say that "seqs are collections", or is it more correct to say that "seqs happen to be implemented using a collection (list)"? |
| 14:21 | dbushenko | TimMc, I've found what was wrong. I should have invoke that with SwingUtilities/invokeLater |
| 14:21 | gfredericks | TimMc: I would question the second part, if I didn't think you knew more than me. |
| 14:21 | TimMc | dbushenko: Aha! Which should you have run with that? |
| 14:22 | TimMc | the launch of the JFrame? |
| 14:22 | dbushenko | Time: (proxy [JFrame] [] (paint [graphics] (SwingUtilities/invokeLater (proxy [Runnable] [] (run [] (draw-graph @win)))))) |
| 14:22 | dbushenko | that code works for me |
| 14:22 | TimMc | hmmm |
| 14:22 | TimMc | I don't know if that's correct. |
| 14:23 | dbushenko | why? did I have to run the JFrame with invokeLater? |
| 14:23 | TimMc | I think the Graphics object may only be safely used in the dynamic scope of paint(). |
| 14:23 | TimMc | I think so. Look at the last line of my example. |
| 14:23 | TimMc | Swing is weird about threads. |
| 14:24 | dbushenko | TimMc, hopefully I don't use it in this function. |
| 14:24 | TimMc | gfredericks: Lazy seqs use Cons cells, which is what lists are, so coll? and seq? both return true for (range). |
| 14:24 | dbushenko | draw-graph fetches the graphics object and then draws on it |
| 14:25 | TimMc | dbushenko: I believe that Swing paints on the event loop thread. |
| 14:25 | dbushenko | TimMc, how to call on the event loop? |
| 14:25 | TimMc | By the way, (proxy [Runnable] [] (run [] ...)) is just #(...) |
| 14:26 | dbushenko | really????? |
| 14:26 | dbushenko | :-D |
| 14:26 | dbushenko | great! |
| 14:26 | TimMc | Yeah, check this out: |
| 14:26 | TimMc | &(ancestors (class #(* % %))) |
| 14:26 | lazybot | ⇒ #{clojure.lang.AFunction clojure.lang.Fn clojure.lang.IMeta clojure.lang.IObj clojure.lang.IFn java.util.concurrent.Callable java.lang.Object java.lang.Runnable java.util.Comparator clojure.lang.AFn java.io.Serializable} |
| 14:26 | TimMc | See the Callable and Runnable in there? :-) |
| 14:27 | TimMc | and Comparator as well |
| 14:27 | dbushenko | super! |
| 14:27 | TimMc | So, back to Swing -- I think you want to launch the JFrame using invokeLater, and not use invokeLater in the paint method. |
| 14:27 | dbushenko | yeah, that really works |
| 14:28 | dbushenko | hmm... let me try |
| 14:28 | TimMc | I could be wrong, but that's what I seem to recall. |
| 14:28 | dbushenko | TimMc, you were right, it works |
| 14:29 | TimMc | yay! |
| 14:30 | TimMc | I recommend reading up briefly on Swing threading. I think there are some other weird things to be aware of, but I havne't used it in a bit. |
| 14:30 | fliebel | What would be the best way to convert a Clojure map to any subclass of java.util.Map? Now I just reduce the one into the other. |
| 14:30 | dbushenko | yeah, swing and threading is a weird thing |
| 14:31 | TimMc | &(java.util.HashMap. {:a 1, :b 2}) |
| 14:31 | lazybot | ⇒ #<HashMap {:b=2, :a=1}> |
| 14:31 | TimMc | &(.get (java.util.HashMap. {:a 1, :b 2}) :a) |
| 14:31 | lazybot | ⇒ 1 |
| 14:32 | TimMc | fliebel: ^ The Java Collection classes usually have a (Collection) constructor. |
| 14:32 | fliebel | TimMc: Not this one (Properties) |
| 14:32 | TimMc | Ah. |
| 14:32 | TimMc | *any* subclass? |
| 14:33 | fliebel | oh, I can call putAll |
| 14:33 | TimMc | nice! |
| 14:44 | Borkdude | Hmm, I'm puzzled by an enlive example. I get lazyseqs instead of |
| 14:44 | Borkdude | strings in my output. |
| 14:46 | fliebel | user=> (field-map javax.mail.Folder) {:holds_messages 1, :holds_folders 2, :read_only 1, :read_write 2} |
| 14:49 | raek | Borkdude: ring accepts lazy seqs of strings as response bodies |
| 14:50 | raek | using a lazy seq allows the body to be generated lazilly |
| 14:50 | TimMc | That's great! |
| 14:50 | Borkdude | raek: I got this now https://gist.github.com/1362567 |
| 14:50 | Borkdude | raek: I was trying to imitate and example from enlive on github |
| 14:51 | Borkdude | raek: I expected the tablebody to be filled by |
| 14:51 | Borkdude | *** <tr><td>names</td></tr> things |
| 14:51 | raek | is username a node tree? |
| 14:52 | Borkdude | raek: they are just strings.. not good? |
| 14:52 | raek | clojure.lang.LazySeq@... means that you gave something that expected a string something else (a seq) |
| 14:52 | brehaut | Borkdude: transformations are functions from node to node; you are returning a seq rather than a node (map with :tag :attrs :contents) |
| 14:53 | raek | sorry, my first comment does not apply in this case |
| 14:53 | raek | (thought you mean something else) |
| 14:53 | raek | "A transformation is a function that returns either a node or collection of node." |
| 14:53 | Borkdude | raek: I checked with (swank.core/break) that username in the for |
| 14:53 | Borkdude | loop is a string |
| 14:54 | Borkdude | brehaut: aha... |
| 14:54 | raek | Borkdude: also, have you considered clone-for |
| 14:54 | brehaut | Borkdude: you might want to look at clone-for in enlive |
| 14:54 | raek | ? |
| 14:54 | Borkdude | just trying to imitate this one: https://github.com/cgrand/enlive/blob/master/examples/net/cgrand/enlive_html/examples.clj |
| 14:55 | TimMc | I have found the enlive tutorials difficult to read and apply to my work. |
| 14:55 | TimMc | I just wnat to shove some data into some HTML, dammit! :-) |
| 14:55 | Borkdude | haha |
| 14:55 | Borkdude | I am touching it for the very first time now |
| 14:56 | brehaut | TimMc: my problem was that they cover all the conceptual stuff pretty quickly, and then dive into examples. i never grasped the conceptual stuff to i had bet my head against my own problems |
| 14:56 | TimMc | Borkdude: I'm working with it right now, let me show you my code so far. |
| 14:56 | Borkdude | brehaut: why clone-for if the example should work with for? |
| 14:56 | Borkdude | and why the heck is my table body disappearing |
| 14:57 | brehaut | Borkdude: im curious about that too; i wonder how old that example is; enlive changed dramatically over its life |
| 14:57 | TimMc | Borkdude: Here's where the pertinent stuff is in my case: https://github.com/timmc/seqs-and-colls/blob/master/src/seqs/core.clj#L40 |
| 14:57 | Borkdude | brehaut: I am using version 1.0.0 from clojars! |
| 14:57 | brehaut | Borkdude: but what version is that example using! ;) |
| 14:58 | raek | my guess is that something adds one extra layer of seqs |
| 14:59 | Borkdude | brehaut: good question. let me just explain what I'm trying to |
| 14:59 | Borkdude | do => insert <tr><td> ... </td></tr> 's with names filled in on the dots |
| 14:59 | raek | and maybe enlive checks whether each element of the outer seq is a map (a node), and if it isn't calls 'str' on it |
| 14:59 | Borkdude | now show me the most appropriate way in enlive ;) |
| 15:00 | raek | Borkdude: clone-for |
| 15:00 | Borkdude | raek: I guess that one is not in 1.0.0 |
| 15:00 | TimMc | Borkdude: I run clone-for over the :tr in here and then clone-for over the :td 's: https://github.com/timmc/seqs-and-colls/blob/master/src/seqs/html/table.html |
| 15:00 | brehaut | Borkdude: as raek suggests, thats the usecase for clone-for |
| 15:01 | raek | Borkdude: example: https://github.com/raek/lcug-guestbook/blob/master/src/se/raek/lcug/guestbook/view.clj |
| 15:01 | TimMc | brehaut: I often prefer to have a working example first, and then drill down into how it actually works. |
| 15:03 | brehaut | TimMc: likewise |
| 15:04 | Borkdude | ok, clone-for... what enlive version should I use from clojars then? |
| 15:04 | TimMc | I'm using 1.0.0. |
| 15:05 | TimMc | [enlive "1.0.0"] |
| 15:05 | Borkdude | hmm ok, lemme see |
| 15:05 | Borkdude | oopz, forgot to prefix it |
| 15:08 | tensorpudding | i genuinely ignored the docs for enlive, they just confused me |
| 15:08 | tensorpudding | and just looked at the code of the example in the wiki that has a form that they clone |
| 15:09 | Borkdude | hmm, I now get two tablebodies with tr/td/name in it |
| 15:09 | Borkdude | with the two names I listed though |
| 15:12 | Borkdude | ah, got it |
| 15:15 | Borkdude | works: https://gist.github.com/1362567 |
| 15:15 | Borkdude | tnx guys! |
| 15:23 | TimMc | yay |
| 15:29 | Borkdude | which transformation to use to remove smth from the html? |
| 15:29 | Borkdude | substitute? |
| 15:29 | brehaut | Borkdude: substitute with a nil result |
| 15:29 | brehaut | s/result/value/ |
| 15:30 | brehaut | or perhaps content with nil depending what your selector is |
| 15:30 | TimMc | Borkdude: (fn [nodes] (when-not (hungry?) nodes)) |
| 15:30 | TimMc | something like that |
| 15:31 | Borkdude | timmc: I have added an id to the table |
| 15:31 | Borkdude | and when the user first comes to the page, I don't want to show |
| 15:31 | Borkdude | the table |
| 15:33 | Borkdude | TimMc: so smth like this: (deftemplate welcome-page "index.html" |
| 15:33 | Borkdude | [] [:table#names] ...) |
| 15:34 | Borkdude | I'm trying to understand how it works by looking at the tests... |
| 15:34 | Borkdude | https://github.com/cgrand/enlive/blob/master/test/net/cgrand/enlive_html/test.clj |
| 15:34 | Borkdude | but that doesn't help me very much with substitute |
| 15:34 | TimMc | That [] can take a boolean called first-view? and then you can have [table#stuff] (fn [tbl] (when (not first-view?) tbl)) |
| 15:35 | tensorpudding | yes, templates are functions |
| 15:35 | tensorpudding | you can specify them with arguments that you pass |
| 15:36 | Borkdude | eh, how many lines of code can I paste without being kicked out? |
| 15:36 | Borkdude | 4 too much? |
| 15:36 | brehaut | you wont get kicked, but its not good form |
| 15:36 | tensorpudding | just use a pastebin, or gist, or ideone |
| 15:36 | gfredericks | everybody will glare at you |
| 15:36 | gfredericks | using the unicode glare character |
| 15:36 | TimMc | ಠ_ಠ |
| 15:37 | Borkdude | ok, like this? https://gist.github.com/1362634 |
| 15:37 | Borkdude | gfredericks: that is a very cool character |
| 15:37 | TimMc | It is U+0CA0 |
| 15:37 | brehaut | 💩 |
| 15:37 | TimMc | twice, with an underscore |
| 15:38 | tensorpudding | nice astral plane characters |
| 15:38 | gfredericks | ironically, it takes four lines to print it |
| 15:38 | Borkdude | tnxs a lot, these characters will come in handy |
| 15:38 | TimMc | brehaut: All I got from you was U+FFFD |
| 15:38 | brehaut | TimMc: huh. it was supposed to be the unicode pile of poo |
| 15:38 | Borkdude | btw, my example doesn't work. why not? |
| 15:38 | brehaut | i blame colloquay |
| 15:39 | TimMc | I blame my fucked-up server. |
| 15:39 | brehaut | Borkdude: you dont need to pass a fun to substitute; just pass nil |
| 15:39 | TimMc | Borkdude: Did you see my example at :29? I didn't use substitute. |
| 15:40 | brehaut | alternatively instead of subsitute you oculd use (constantly nil) |
| 15:40 | Borkdude | brehaut: ah that works |
| 15:40 | TimMc | Borkdude: Whatever expression you put in has to evaluate to a function. That function will be called with the matched list of nodes. |
| 15:41 | TimMc | The result of the function should be a string or a seq. |
| 15:46 | Borkdude | my emacs crashed... |
| 15:46 | Borkdude | TimMc: what did you say? I missed it |
| 15:47 | TimMc | Borkdude: Whatever expression you put in has to evaluate to a function. That function will be called with the matched list of nodes. / The result of the function should be a string or a seq. |
| 15:47 | Borkdude | so putting in nil... why does it work? |
| 15:48 | TimMc | Borkdude: You're not putting in nil, you're putting in a function that, when called, gives nil. |
| 15:49 | Borkdude | TimMc: I mean this: [:table#names] |
| 15:49 | Borkdude | (enlive/substitute nil) |
| 15:49 | Borkdude | like brehaut suggested, it works |
| 15:49 | brehaut | Borkdude: do you understand that all the core transformations (eg, content, substitute etc) are actually returning functions ? |
| 15:49 | TimMc | Borkdude: enlive/substitute returns a function |
| 15:49 | TimMc | brehaut: That was the key to my understanding what enlive was doing. |
| 15:50 | brehaut | Borkdude: content frinstance is approximately (fn [new-content] (fn [node] (assoc node :content new-content))) |
| 15:51 | brehaut | Borkdude: substitute is probably (fn [new-nodes] (fn [_] new-nodes)) |
| 15:51 | TimMc | it actually uses constantly :-) |
| 15:51 | Borkdude | so, substitute something returns (fn [new-content] (fn [matched-node] ...replace something in the matched-node])? |
| 15:51 | TimMc | (constantly (flatten-nodes-coll values)) |
| 15:51 | brehaut | TimMc: i figured ;) but for the purposes of simplifying whats happening |
| 15:51 | Borkdude | TimMc: I saw that, but I still don't understand it quite |
| 15:52 | TimMc | ((enlive/substitute "hello")) => '("hello") |
| 15:52 | brehaut | ,(map (constantly :foo) (range 1 10)) |
| 15:52 | clojurebot | (:foo :foo :foo :foo :foo ...) |
| 15:52 | Borkdude | ah wait, I thought substitute would substitute something inside the matched node |
| 15:52 | TimMc | Borkdude: A template is not an html tree -- it is a tree of *functions* for transforming an html tree. |
| 15:52 | brehaut | Borkdude: thats content |
| 15:53 | Borkdude | but it substitutes the entire node |
| 15:54 | TimMc | brehaut: I think they should deftemplate first, but not be released from class until they see snippets, etc. |
| 15:54 | Borkdude | ok, so substitute returns a function that always evaluates to the substitution |
| 15:54 | TimMc | yup |
| 15:54 | Borkdude | and what is that function applied to, the matched node? |
| 15:54 | TimMc | Yes, but it ignores the node. |
| 15:55 | TimMc | (nodes) |
| 15:55 | Borkdude | so each function is applied to the matched node |
| 15:55 | brehaut | Borkdude: yes exactly. |
| 15:55 | Borkdude | and that series of applications results in new html |
| 15:55 | TimMc | brehaut: This is something I am not clear on, actually -- does [:table :tr]'s matcher get all the :tr's, or just the first, or is it called once for each? |
| 15:55 | Borkdude | so why do I need snippets? |
| 15:56 | brehaut | TimMc: it should match all the :trs inside :tables inside the current context node |
| 15:56 | TimMc | So the function gets a collection. |
| 15:57 | brehaut | Borkdude: snippets are like templates that return nodes instead of a seq of strings |
| 15:57 | churib | is there an "unintern" in clojure? |
| 15:58 | brehaut | TimMc: i think it depends _where_ that selector is used; if you use it with select then i think it gets a collection; if you use it with at (which is implicit in templates and snippets) then you get single node |
| 15:58 | TimMc | OK. |
| 15:58 | raek | churib: ns-unmap? |
| 15:58 | churib | raek: sounds good - thanks! |
| 15:59 | Borkdude | brehaut: why was content a nested function? |
| 15:59 | Borkdude | brehaut: like (fn [new-content] (fn [node] ...)) |
| 15:59 | Borkdude | what is new-content? |
| 15:59 | brehaut | Borkdude: all the standard transforms are nested function |
| 16:00 | brehaut | Borkdude: the transformations are only ever passed a node (or node set for a selection range) |
| 16:00 | churib | raek: how do i get the current namespace? |
| 16:01 | brehaut | Borkdude: but you probably want additional data in that transformation (such as the new content to insert); the inner function closes over outer functions locals. new-content is whatever the new content of the node is (ie, it replaces :content in the node map) |
| 16:01 | TimMc | ,*ns* |
| 16:01 | clojurebot | #<Namespace sandbox> |
| 16:01 | churib | TimMc: thanks :) |
| 16:02 | TimMc | churib: There might be a better way... |
| 16:02 | brehaut | Borkdude: constantly returns a function too - a function that ignores its arguments and returns the same thing constantly |
| 16:02 | Borkdude | brehaut: er, the outer function gets "usernames" in my example then? |
| 16:02 | sritchie | hey all -- is the clojure 1.4 snapshot available on maven? |
| 16:03 | sritchie | for dev |
| 16:03 | Borkdude | brehaut: I know that, but constantly doesn't return a nested function |
| 16:03 | churib | TimMc: I used it only in the repl to get rid of an typo |
| 16:03 | churib | (symbol) |
| 16:03 | brehaut | (source constantly) |
| 16:03 | TimMc | Ah, OK. |
| 16:03 | brehaut | Borkdude: i need a link to the code you are talking about |
| 16:03 | Borkdude | brehaut: ok, wait |
| 16:04 | Borkdude | brehaut: https://gist.github.com/1362567 |
| 16:04 | Borkdude | brehaut: if clone-for returns a nested function |
| 16:04 | brehaut | Borkdude: so are you refering to the argument to content ? |
| 16:05 | Borkdude | brehaut: then what would an application to it look like? |
| 16:05 | brehaut | Borkdude: https://github.com/cgrand/enlive/blob/master/src/net/cgrand/enlive_html.clj#L658-661 |
| 16:06 | brehaut | Borkdude: clone-for is a special case here; it uses a macro to generate the function rather than creating it through closuring |
| 16:06 | brehaut | Borkdude: but it still creates a function from node -> nodes |
| 16:06 | Borkdude | brehaut: ah, that's why I was confused |
| 16:07 | Borkdude | brehaut: but also constantly isn't nested right? I get node -> nodes, but not new-content -> node -> nodes like you suggested (I think) |
| 16:07 | Borkdude | new-content -> (node -> nodes) I mean |
| 16:08 | Borkdude | brb |
| 16:09 | brehaut | Borkdude: i dont understand what you mean about constantly not being nested |
| 16:10 | brehaut | constantly is defined as (defn constantly [x] (fn [& args] x)) |
| 16:21 | Borkdude | brehaut: yes, so constantly doesn't return a nested function, but just a function that returns x |
| 16:22 | brehaut | Borkdude: i think we may have different notions of what a 'nested function' is |
| 16:22 | Borkdude | brehaut: my notion is: a function that returns a function |
| 16:23 | brehaut | Borkdude: thats _exactly_ what constantly is |
| 16:23 | Borkdude | brehaut: yes, but it doesn't _return_ a nested function |
| 16:23 | TimMc | uh... |
| 16:24 | TimMc | ,(let [return-value (constantly 17)] (fn? return-value)) |
| 16:24 | clojurebot | true |
| 16:24 | brehaut | Borkdude: lets use more precise terminology then. constantly returns an anonymous function that is within the lexical scope of the invocation constantly that returned, closing over constantly's argument |
| 16:24 | brehaut | Borkdude: thats the same as enlive's content and substitute |
| 16:25 | brehaut | also i fail at english |
| 16:25 | Borkdude | TimMc: you are just checking if the return-value is a function, not if it is a function that will return a function |
| 16:25 | Borkdude | brehaut: I'm just trying to understand |
| 16:26 | TimMc | Oh, it most certainly isn't. That's true. |
| 16:26 | brehaut | Borkdude: lets start with the basics. do you know what lexical scope is? |
| 16:26 | Borkdude | brehaut: yes |
| 16:26 | brehaut | Borkdude: and you understand that the inner function is closing over the containing functions lexical variables ? |
| 16:27 | Borkdude | brehaut: (constantly 3) returns a function of varargs that closes over the value 3 |
| 16:27 | Borkdude | brehaut: right? |
| 16:27 | brehaut | right |
| 16:28 | brehaut | now; can you tell me why you think thathttps://github.com/cgrand/enlive/blob/master/src/net/cgrand/enlive_html.clj#L598-601 is a different construction to constantly? |
| 16:30 | Borkdude | brehaut: I think we can agree on "a transformation _is_ a function of --args-- that _returns_ a function of a node that closes over the --args--", right? |
| 16:30 | brehaut | yes |
| 16:30 | Borkdude | brehaut: ok |
| 16:31 | Borkdude | brehaut: then I think I'm starting to understand it ;-) |
| 16:31 | brehaut | Borkdude: phew :) |
| 16:37 | Borkdude | brehaut: some Haskell-ish notation would be helpful here maybe |
| 16:37 | Borkdude | brehaut: in the code itself |
| 16:37 | brehaut | Borkdude: it wouldnt hurt. |
| 16:39 | brehaut | data HTMLNode = Nil | HTMLText String | HTMLNode String (Map String String) [HTMLNode] |
| 16:39 | brehaut | content :: HTMLNode -> HTMLNode -> HTMLNode |
| 16:39 | brehaut | ;) |
| 16:40 | brehaut | substitute :: HTMLNode -> HTMLNode -> HTMLNode |
| 16:40 | brehaut | not really all that clarifying is it ;P |
| 16:41 | churib | is there a way to get all symbols of an namespace? |
| 16:43 | brehaut | &(keys (ns-map 'clojure.core)) ;; churib |
| 16:43 | lazybot | java.lang.SecurityException: You tripped the alarm! ns-map is bad! |
| 16:43 | brehaut | hah. well, try that in your own repl churib |
| 16:43 | Borkdude | brehaut: hmm... that brings us to, what would it look like for clone-for? ;) |
| 16:43 | brehaut | Borkdude: my template haskell is weak ;) |
| 16:44 | churib | brehaut: thanks! |
| 16:45 | djanatyn | how feasible would it be to write a game in 48 hours, and then distribute it publically with clojure? |
| 16:46 | djanatyn | I'm thinking of entering a 48 hour game-making competition - I did it last time with python and pygame |
| 16:46 | brehaut | djanatyn: distribution would be trivial; lein uberjar would create a self contained jar file that you could run |
| 16:46 | djanatyn | the competition is in 33 days - would it be possible? |
| 16:46 | djanatyn | yeah, I saw lein had some really cool distribution things when I was playing with it. |
| 16:46 | djanatyn | but how is the library situation for making games? |
| 16:47 | djanatyn | I'm not really interested in learning clojure to make games, but I think this might be a cool opportunity to force myself to write some real clojure code |
| 16:47 | brehaut | djanatyn: i dont know if there is anything that is analogous to pygame |
| 16:47 | brehaut | partly because pygame is all over the place wrt what it provides |
| 16:47 | djanatyn | my friend tomoj linked me this: https://github.com/jvillste/clojure-lwjgl |
| 16:48 | djanatyn | i've never used lwjgl before, not really sure what it is |
| 16:48 | djanatyn | I've used SDL with perl and python with pygame |
| 16:48 | tomoj | https://github.com/ztellman/penumbra |
| 16:48 | tomoj | then wrap whatever else from lwjgl you want |
| 16:50 | tomoj | maybe that clojure-lwjgl library is good, no docs it seems. at least inspiration |
| 16:53 | tomoj | https://github.com/ztellman/penumbra/blob/master/test/example/game/asteroids.clj |
| 16:59 | Borkdude | brehaut: how would you go about removing all things from the html that have class="welcome" |
| 16:59 | Borkdude | brehaut: I have [:.welcome] (enlive/substitute nil) |
| 16:59 | Borkdude | brehaut: but it only removes one |
| 17:00 | brehaut | Borkdude: (enlive/transform doc [:.welcome] (enlive/subsitute nil)) |
| 17:01 | brehaut | Borkdude: i probably wouldnt use an at form to do it (or a snippet or template which have implicit ats) |
| 17:05 | Borkdude | brehaut: how would I use this inside a deftemplate? |
| 17:06 | brehaut | Borkdude: i dont think you would |
| 17:06 | Borkdude | brehaut: so deftemplate kind of presumes that every selector,transform pair is only applied once? |
| 17:07 | brehaut | i think so? |
| 17:07 | brehaut | ive never tried to do anything super fancy with deftemplates |
| 17:08 | Borkdude | brehaut: maybe I should just make a second html file... but I'm too lazy ;-) |
| 17:08 | brehaut | lol |
| 17:08 | brehaut | how about you just use a html-resource, an at, a transform and an emit* |
| 17:08 | brehaut | rather than the special case that template wraps up for you |
| 17:10 | Borkdude | brehaut: ok, let me check that out, tnx |
| 17:10 | brehaut | (deftemplate name "my.html" [args] atstuff…) is roughly (defn name [args] (at (html-resource "my.html") atstuff…)) |
| 17:10 | Borkdude | Perfect! |
| 17:10 | brehaut | Borkdude: although it caches the html-resource |
| 17:19 | daaku | what's the right way to deal with destructuring in macros defining functions? let should do the trick, but i'm wondering if that's the idiomatic way. this gist should explain better: https://gist.github.com/f2e1c00a93826b40dd34 |
| 17:19 | Borkdude | brehaut: ah wait, deftemplate worked ok, but I just made a mistake in the html |
| 17:19 | Borkdude | brehaut: two class attributes... oopz |
| 17:20 | brehaut | ah lol :) |
| 17:32 | ohpauleez | finally home after the conj- I can feel my brain coming back together |
| 17:32 | Borkdude | I guess this is working then finally with some Enlive templates :) http://whosnotfollowingme.herokuapp.com/ |
| 17:34 | dnolen | ohpauleez: was lots of fun. |
| 17:34 | Borkdude | brehaut, TimMc : tnx for helping, learned a lot today |
| 17:34 | brehaut | Borkdude: no problem |
| 17:36 | jimduey | ohpauleez: me too. It was a blast. |
| 17:37 | ohpauleez | dnolen: jimduey: Totally. One of the most fun, educational, and inspiring trips I've had in awhile. I'm reading through a new stack of papers as we speak |
| 17:48 | djanatyn | penumbra is pretty great |
| 17:54 | ohpauleez | djanatyn: What are you using it for? Or just playing around with it |
| 17:54 | djanatyn | ohpauleez: Well, I haven't used it yet at all. I cloned the git repo, not really sure how to work with it. |
| 17:55 | djanatyn | I've been learning common lisp, and I really like lisp and want to start using it. There's a 48 hour game-making competition coming up in a little bit over a month, and I figured that maybe the library situation would be better with clojure. |
| 17:55 | djanatyn | I'm not really sure how to do distribution with common lisp, either. |
| 17:56 | djanatyn | It seems like most people advocate bundling a common lisp interpreter *with* your program, but I'm not sure how to do that either |
| 17:56 | djanatyn | a quicklisp is a little intimidating for me, at least. |
| 17:56 | djanatyn | s/a/and |
| 17:58 | ohpauleez | ahh, gotcha - well, welcome to Clojure! There's been some great success making games in Clojure |
| 17:58 | djanatyn | awesome :) |
| 17:59 | djanatyn | i'm really interesting in functional programming, too |
| 17:59 | djanatyn | however, the only thing i've ever written in a vaguely functional style was a little haskell script |
| 18:00 | djanatyn | I can grok lisp a lot easier than haskell, and it looks like clojure's distribution is super easy with lein (I've had distribution issues in the past), so I'm excited |
| 18:05 | zerokarmaleft | when using cljs-watch, is bootstrap.js the only thing that needs to be pulled in? |
| 18:06 | dnolen | zerokarmaleft: what do you mean? |
| 18:07 | zerokarmaleft | dnolen: from within an html file |
| 18:08 | djanatyn | does clojure sepreate pure and non-pure functions in the same way as haskell? |
| 18:08 | brehaut | djanatyn: no |
| 18:08 | brehaut | djanatyn: if by 'the same way' you mean via the type system |
| 18:08 | dnolen | zerokarmaleft: you don't need to include bootstrap.js, just whatever output file you specified. |
| 18:10 | bhenry | i want the overtone presentation video asap! (i never use "asap," but this time it's deserving) |
| 18:11 | djanatyn | hmm, weird. |
| 18:11 | djanatyn | so clojure doesn't have, like, an IO type? |
| 18:11 | dnolen | djanatyn: no, it has reference types. we have statement management, we just don't rely a type system for such things. |
| 18:11 | dnolen | er state management |
| 18:14 | zerokarmaleft | dnolen: i'm just running cljs-watch with no args, so the default output is bootstrap.js |
| 18:15 | TimMc | djanatyn: This is a good read: http://www.clojure.org/state |
| 18:15 | dnolen | zerokarmaleft: ok, then yes that should work. |
| 18:15 | zerokarmaleft | i'm able to get an inferior-lisp repl connected to the browser fine that way, i just seem to be missing dom functions |
| 18:15 | dnolen | zerokarmaleft: did you switch into your namespace? you need to eval your ns form to do that. |
| 18:15 | zerokarmaleft | yes |
| 18:16 | dnolen | zerokarmaleft: so dom/getElement is not working? |
| 18:16 | zerokarmaleft | for instance, append and get-element work, but not much else |
| 18:16 | dnolen | zerokarmaleft: oh are you trying to use cljs dom namespace? not the google one? |
| 18:17 | dnolen | I wouldn't do that. I think cljs dom is half-baked at this point. |
| 18:19 | zerokarmaleft | dnolen: ah ok, that's it then! |
| 19:30 | gfredericks | I just used the {:strs ...} destructuring form for the first time. |
| 19:30 | gfredericks | in case any of you were wondering. |
| 19:33 | klauern | gfredericks: I'm new to clojure, what is that? |
| 19:33 | klauern | I know sort of what destructuring is, but only on a var-args defn kind of way |
| 19:33 | Raynes | gfredericks: Not sure I'm familiar with that there non-existent form. |
| 19:34 | gfredericks | ,(let [{:strs [foo bar]} {"foo" 734, "bar" [1 2 3]}] [foo bar]) |
| 19:34 | clojurebot | [734 [1 2 3]] |
| 19:34 | gfredericks | Raynes: did I misdescribe something? |
| 19:34 | Raynes | Oh, cool! |
| 19:35 | gfredericks | Raynes: also :syms |
| 19:35 | Raynes | You have to write blog posts about this. |
| 19:35 | gfredericks | one for :strs and one for :syms? |
| 19:35 | klauern | these kinds of things seem kind of magical to me |
| 19:36 | klauern | Where do you pull up the docs for that kind of thing? |
| 19:36 | gfredericks | klauern: :keys is the one most people are familiar with, and it seems a bit cryptic until you've written (let [{foo :foo, bar :bar} m] ...) a million times |
| 19:37 | klauern | Yeah, part of it is that is seems fairly non-obvious that you'll get some sort of modified result because of a :symbol being there |
| 19:37 | gfredericks | klauern: http://clojure.org/special_forms#Special Forms--(let [bindings* ] exprs*) |
| 19:38 | klauern | ah, got it |
| 19:38 | klauern | well, I'm off to read something for a bit ;) |
| 19:38 | gfredericks | klauern: have fun |
| 19:39 | gfredericks | klauern: I was trying to link to the section on let, in case the whitespace in that link mucked things up |
| 19:39 | klauern | ah, yeah, %20 would work to hack around those spaces |
| 19:39 | gfredericks | should be easy enough to find it manually |
| 19:40 | klauern | http://clojure.org/special_forms#Special Forms--(let%20[bindings*%20]%20exprs*) |
| 19:40 | klauern | http://clojure.org/special_forms#Special%20Forms--(let%20[bindings*%20]%20exprs*) |
| 19:40 | klauern | whoops |
| 19:42 | klauern | Something that I was confused for a while in Clojure was that the terminology used seemed academic. For instance, alot of the time I was thinking "why aren't they just calling that a method", but then I realized that Clojure (and I suppose Lisps in general) have alot of nuance in behavior, so method wouldn't work in some cases, etc. |
| 19:42 | klauern | Now I'm starting to get a handle on the language a bit better, but it's tricky trying to learn something that has such depth to it compared to OO/Imperative languages |
| 19:44 | gfredericks | klauern: my impression is that "method" is an OO word referring specifically to a "function on an object" |
| 19:44 | gfredericks | probably it's used more loosely than that most of the time though :/ |
| 19:45 | klauern | Well, in general I see things like 'lexical binding' and then get confused for a second since it's not easily transferrable to other languages I work with. |
| 19:45 | klauern | binding in particular |
| 19:45 | klauern | destructuring is neat and something that opens up a nice world of flexibility |
| 19:45 | klauern | I'm not even up to learning protocols and multimethods, so it's still a fun ride ahead for me |
| 19:46 | pnicholson | Hey, I'm trying to play with overtone and am getting "CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: File" |
| 19:46 | gfredericks | do you need to import it? |
| 19:47 | gfredericks | klauern: it is fun stuff. |
| 19:47 | pnicholson | I don't think so… https://github.com/overtone/overtone/blob/master/src/overtone/helpers/file.clj#L151 is the line is failing on |
| 19:48 | klauern | I like the organic nature to it. "Growing a language" and all that |
| 19:49 | gfredericks | pnicholson: I don't see File imported at the top, so I'm not sure why that would be expected to work. Does the library have tests you can run? |
| 19:49 | gfredericks | klauern: have you seen rich's Simple Made Easy talk? |
| 19:50 | pnicholson | gfredericks: file is part of the io package right? |
| 19:50 | gfredericks | pnicholson: java.io.File is a java class, and those have to be imported separately from clojure namespaces |
| 19:51 | gfredericks | I would expect adding an (:import java.io.File) to the ns declaration at the top of that file would make the error go away |
| 19:51 | klauern | gfredericks: That is a good video. He mentions that one slide should be used as a reference for something, but that slide is full of concepts that I'm not even familiar with to know what they are, so I'm trudging along with a book or two and some minor pet projects to get a feel for the language |
| 19:52 | pnicholson | gfredericks: hmm….this stuff was demoed at the conj yesterday |
| 19:52 | zerokarmaleft | dnolen: have you posted your slides anywhere yet? |
| 19:52 | gfredericks | pnicholson: yeah, it sounds like a popular lib, so I'm weirded out a bit |
| 19:52 | dnolen | zerokarmaleft: not yet, I'll try to get them added to the conj slide repo soon. |
| 19:53 | zerokarmaleft | cool |
| 21:01 | alexbaranosky | I'm far enough into installing emacs to realize I suck at it |
| 21:01 | alexbaranosky | I've clone Sam Aaron's emacs files |
| 21:02 | alexbaranosky | I stuck them in the .emacs.d folder |
| 21:03 | alexbaranosky | I couldn't tell for sure if I had done it right so I tried to do something simple (to my mind) which was install a color theme |
| 21:04 | alexbaranosky | I put the color theme .el file into .emacs.d/config/ and tried to do M-x color-theme-tango, to which Emacs replied [No match]... What does no match mean exactly, and have I done something utterly wrong? |
| 21:05 | alexbaranosky | is Emacs somehow not finding the file? |
| 21:08 | brehaut | alexbaranosky: im not an expert or anything, but have you done a (require …) for the theme.el? |
| 21:21 | alexbaranosky | brehaut: in the color-theme-tango.el file? |
| 21:22 | brehaut | in your init.el ? |
| 21:22 | alexbaranosky | I'm still learning the whole Emacs ecosystems, so I'm probably missing something obvious |
| 21:22 | alexbaranosky | let me check |
| 21:31 | alexbaranosky | brehaut: seems to be working if I add: (require 'color-theme) |
| 21:31 | alexbaranosky | (color-theme-initialize) |
| 21:31 | alexbaranosky | (color-theme-robin-hood) to the .emacs file |
| 21:31 | alexbaranosky | however, the theme doesn't look like I thought it was supposed to |
| 21:31 | alexbaranosky | I think I hear themes work differently between GUI emacs and terminal Emacs |
| 21:35 | duck1123 | alexbaranosky: they do look a little different depending on the settings of your terminal |
| 21:36 | duck1123 | usually you just have to try them all till you find one that works for you |
| 21:37 | alexbaranosky | do most folks use the GUI Emacs or the terminal version? |
| 21:37 | amalloy | or modify one you almost-like |
| 21:37 | alexbaranosky | I'm fond of that ;) |
| 21:38 | duck1123 | I'd say that most use the gui if they have it available |
| 21:38 | alexbaranosky | amalloy: I used 'macro-do` yesterday |
| 21:38 | alexbaranosky | amalloy: and `juxt`. Thought you'd be proud |
| 21:39 | amalloy | *chuckle* |
| 21:40 | amalloy | macro-do is one i try to avoid using - it's tempting to use macros when in fact functions are sufficient |
| 21:41 | alexbaranosky | I almost never write macros |
| 21:43 | amalloy | alexbaranosky: out of curiosity do you have a link handy for your use of macro-do? |
| 21:45 | alexbaranosky | yes. I was cleaning up some Midje code, replacing a few (map (fn []...)) spots with (for [] and ran into a spot where we're generating 10 checkers, let me show you the link |
| 21:46 | alexbaranosky | Last lines of: https://github.com/marick/Midje/blob/master/src/midje/checkers/collection.clj |
| 21:49 | amalloy | i see. yes, it's hard to avoid when the underlying form you want to generate is a macro |
| 21:49 | amalloy | btw, you can link to a specific line on github by clicking the line number in the left margin |
| 21:50 | alexbaranosky | thx |
| 21:51 | alexbaranosky | hmmm, my dark background theme (tango) comes out with a white background... weird |
| 21:52 | amalloy | alexbaranosky: i use tty-dark, if you want to give that a try |
| 21:55 | alexbaranosky | let me show you my `juxt`spot: https://github.com/marick/Midje/blob/master/src/midje/ideas/metaconstants.clj#L23 |
| 21:58 | alexbaranosky | amalloy: (I'm clearly failing badly at the color theme setup... I have to go back to square one. Don't think it was really working when I thought it was) |
| 22:26 | daaku | any vim users know if there's a way do something along the lines of set lispwords+=def* (which doesnt work) to make anything starting with def a lispword? |
| 23:15 | daaku | i remember running into some debugging macro that logged a form and returned it, anyone know what its called? |
| 23:16 | daaku | found it: spy |
| 23:57 | klauern | When documenting a (defn), is there a preferred format, much like Ruby's RDoc, or Java's Javadoc format? |