2012-11-16
| 00:34 | Sgeo | Is it safe to say that a + b - b might not = a when using floats? |
| 00:52 | pyrtsa | Sgeo: Yes. |
| 00:57 | amalloy | Sgeo: a = 1e-20, b=1e20 is an easy case |
| 00:58 | Sgeo | I wonder if there cases that might come up in a 3d world that uses floats for locations |
| 00:59 | Sgeo | Beyond the fun shakiness further out in the world |
| 00:59 | amalloy | or b∈{NaN, ∞, -∞} |
| 01:00 | Sgeo | Can I have two namespaces each of which uses a var defined in the other? |
| 01:00 | ivan | probably with resolve |
| 01:00 | Sgeo | Without resolve, I mean |
| 01:01 | cshell | circular deps? |
| 01:01 | amalloy | well, yes and no. you can't use the vars directly, but they can be passed in from some third namespace that depends on both of those |
| 01:01 | Sgeo | :/ |
| 01:02 | Sgeo | Eh, my usecase is literally just one def that I could easily rewrite |
| 01:02 | Sgeo | in the other namespace |
| 01:10 | rattboi | bbloom: I'm having issues w/ the code you posted. The inner let defines grid, but then it is attempted to be used outside the let. |
| 01:16 | mindbender1 | ,(set? {1 1}) |
| 01:18 | ivan | &(set? {1 1}) |
| 01:18 | lazybot | ⇒ false |
| 01:18 | ivan | &(set? #{1 1}) |
| 01:18 | lazybot | java.lang.IllegalArgumentException: Duplicate key: 1 |
| 01:19 | mindbender1 | (set {1 2}) |
| 01:19 | mindbender1 | &(set {1 2}) |
| 01:19 | lazybot | ⇒ #{[1 2]} |
| 01:19 | mindbender1 | i think this is inconsistent |
| 01:20 | ivan | you're passing a map to set |
| 01:20 | mindbender1 | yes |
| 01:20 | ivan | &(set {1 2 3 4}) |
| 01:20 | lazybot | ⇒ #{[3 4] [1 2]} |
| 01:20 | metellus | &(vec {1 2 3 4}) |
| 01:20 | lazybot | ⇒ [[1 2] [3 4]] |
| 01:22 | mindbender1 | #{{1 2}} => #{{1 2}} but (set {1 2}) => #{[1 2]} |
| 01:23 | mindbender1 | &(type (first (set {1 2}))) |
| 01:23 | lazybot | ⇒ clojure.lang.MapEntry |
| 01:23 | mindbender1 | ok |
| 01:23 | bbloom | rattboi: d'oh sorry |
| 01:25 | bbloom | rattboi: but it's an easy fix, move the vector into the comprehension https://www.refheap.com/paste/6767 |
| 01:25 | amalloy | mindbender1: you're making it unnecessarily complicated. (set x) doesn't create a new set containing the element x, it creates a set containing each element of x |
| 01:25 | mindbender1 | amalloy: example? |
| 01:25 | amalloy | &(set 1) |
| 01:25 | lazybot | java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long |
| 01:26 | amalloy | &(set [1]) |
| 01:26 | lazybot | ⇒ #{1} |
| 01:26 | mindbender1 | I passed a map |
| 01:26 | mindbender1 | not a list |
| 01:26 | metellus | maps are key,val pairs |
| 01:26 | mindbender1 | ok, a list of pair |
| 01:27 | mindbender1 | thanks |
| 01:28 | Sgeo | ,`foobar/baz |
| 01:28 | rattboi | bbloom: awesome. I'm finally getting somewhere :) |
| 01:28 | Sgeo | &`foobar |
| 01:28 | lazybot | ⇒ clojure.core/foobar |
| 01:28 | Sgeo | &`foobar/baz |
| 01:28 | lazybot | ⇒ foobar/baz |
| 02:13 | amalloy | does anyone know what IRC channels ztellman hangs out in? i thought he had #lamina or something, but that's empty |
| 02:52 | alex_baranosky | are sorted-maps quicker to do lookups in? |
| 02:53 | amalloy | slower, usually |
| 02:58 | bbloom | alex_baranosky: the advantage of sorted-maps is the ability to use subseq on them and walk a key range -- it's an index |
| 02:58 | bbloom | alex_baranosky: similarly for sorted sets |
| 02:59 | bbloom | amalloy: also, aren't tree maps generally more space efficient? |
| 02:59 | alex_baranosky | generally indexed things are quicker to do lookups from, is that also true of sorted-map? |
| 03:00 | amalloy | they might be smaller, i suppose. i doubt it's a noticeable fraction of the total size |
| 03:00 | bbloom | alex_baranosky: hash-maps have unsorted keys and O(1) complexity lookups. tree-maps have sorted keys and logarithmic complexity |
| 03:00 | alex_baranosky | bbloom: thanks for the info |
| 03:01 | bbloom | although i may be wrong about O(1) for the immutable hash maps in clojure |
| 03:01 | bbloom | my data structures are a little rusty :-) |
| 03:01 | bbloom | alex_baranosky: but yeah, if you need to do a prefix match or something, you can use a sorted map |
| 03:02 | bbloom | alex_baranosky: or if you want to walk the keys started from a particular entry |
| 03:02 | bbloom | &(doc subseq) |
| 03:02 | lazybot | ⇒ ------------------------- clojure.core/subseq ([sc test key] [sc start-test start-key end-test end-key]) sc must be a sorted collection, test(s) one of <, <=, > or >=. Returns a seq of those entries with keys ek for which (test (.. sc comparator (compare ek key)) 0) is true nil |
| 03:03 | alex_baranosky | bbloom: I plan to create a lookup table where the key is [start-timestamp end-timestamp] and the value is the result of a calculation. |
| 03:03 | amalloy | bbloom: clojure's hash maps are O(log32(n)), which for any value of n that can fit in a computer is a small integer |
| 03:04 | bbloom | amalloy: i figured: i knew they were red black trees, which means logs of course |
| 03:04 | bbloom | tree screams log :-) |
| 03:04 | bbloom | alex_baranosky: do you plan to look up by an exact key match? |
| 03:05 | amalloy | huh? you asked about hash maps, and i answered hash maps, which are not red/black |
| 03:05 | bbloom | amalloy: gah, sorry |
| 03:05 | alex_baranosky | bbloom: yeah, exact match, so sounds like hash-maps will be good for me here, right? |
| 03:05 | bbloom | right, that's the default type of map |
| 03:06 | bbloom | amalloy: the hash maps are trie's right? |
| 03:07 | amalloy | yes, although the difference between a trie and a tree has never made sense to me |
| 03:07 | alex_baranosky | bbloom: yep, I'm not that noon :) |
| 03:08 | bbloom | heh, trie just means a prefix tree |
| 03:08 | bbloom | afaict |
| 03:08 | amalloy | oh, does it? that's simple enough then |
| 03:08 | bbloom | amalloy: http://en.wikipedia.org/wiki/Trie |
| 03:08 | alex_baranosky | are you two at the COnj this yeaR? |
| 03:08 | bbloom | i won't be |
| 03:09 | alex_baranosky | I almost decided to come, but chickened out of paying for it :) |
| 03:09 | amalloy | no |
| 03:10 | alex_baranosky | I should plan harder for next year |
| 03:10 | amalloy | if i were at the conj i definitely would not be on irc at this hour |
| 03:10 | alex_baranosky | amalloy: good point |
| 03:11 | bbloom | since we're talking data structures, i'm gonna out the results of my wikipedia-ing for the sake of my own memory |
| 03:11 | bbloom | typical mutable unsorted maps are hash tables, which do have O(1) lookups |
| 03:12 | bbloom | trees, by their nature, provide log lookups |
| 03:12 | bbloom | clojure's hash-map is a trie, since it is assumed that hash codes will be uniformly distributed, the tree should be well balanced |
| 03:12 | bbloom | tries are just prefix trees, which is fundamentally the same thing as a sorted tree |
| 03:12 | bbloom | but clojure's sorted-map is a red black tree |
| 03:12 | bbloom | which is a special kind of sorted binary tree that is self balancing |
| 03:13 | bbloom | that's the interesting bit: since the keys can be anything (ie non uniform) then you need to pay some extra cost for balancing the tree |
| 03:13 | bbloom | so RE: the memory usage amalloy, i doubt the sorted maps are more memory efficient |
| 03:14 | bbloom | it would likely be true that a mutable TreeMap would be more memory efficient than a mutable HashMap |
| 03:14 | bbloom | but i have to assume that red black trees have the same complexity, but larger constants in both time and space when compared to tries |
| 03:14 | bbloom | hopefully that makes sense / is correct :-) |
| 06:04 | Chiron | Hi guys, would you please have a look at https://groups.google.com/forum/?fromgroups=#!topic/clojure/3XkAhC7gUP8 ? |
| 06:07 | clgv | Chiron: is that your question? |
| 06:08 | Chiron | yes |
| 06:08 | clgv | have a look at the doc of `tree-seq` |
| 06:09 | Chiron | i did, but i don't really understand how to use it in my case |
| 06:10 | Chiron | i didn't get why the guy who answered, used map? function |
| 06:12 | clgv | ,(doc tree-seq) |
| 06:12 | clgv | &(doc tree-seq) |
| 06:12 | lazybot | ⇒ ------------------------- clojure.core/tree-seq ([branch? children root]) Returns a lazy sequence of the nodes in a tree, via a depth-first walk. branch? must be a fn of one arg that returns true if passed a node that can have children (but may not). ch... https://www.refheap.com/paste/6773 |
| 06:12 | clgv | as you see there, he uses `map?` as the function that decides when to branch. |
| 06:13 | clgv | so that function will call the children function on every map of that tree structure |
| 06:14 | Chiron | yes but in my snippet, i didn't mention any thing about maps . |
| 06:15 | clgv | you did. you had the following keyword access: (:children input) |
| 06:15 | Chiron | hmmm |
| 06:15 | Chiron | true |
| 06:17 | clgv | so if you had a tree of maps you could use laurents suggestion. if you have something similar but not build of maps then you can adapt that sugggestion |
| 06:17 | Chiron | my original snippet is ok ? |
| 06:17 | Chiron | the very first post |
| 06:19 | clgv | without context yes. |
| 06:20 | Chiron | can i change (tree-seq map? :children input) to something like (tree-seq is-instance-of-class2 :children input) ? |
| 06:21 | Chiron | so if it is instance of class 2 , call :children , if not , do nothing , just pass it to the result seq |
| 06:21 | clgv | why don't you try? ;) |
| 06:22 | Chiron | well true, just chatting :) |
| 06:23 | Chiron | just one more thing please, my original snippet . it is not going to consume the stack and throw stack overflow in some cases ? |
| 06:24 | clgv | yes it will |
| 06:25 | clgv | it consumes stack, but if your tree is not too deep you probably wont get a stack overflow |
| 06:25 | Chiron | i see |
| 06:27 | clgv | just try it with representative worst case data |
| 06:29 | Chiron | oki |
| 06:29 | Chiron | thanks! |
| 07:26 | mpenet | ibdknox: in jayq.util/clj->js is there a specific reason for using coll? instead of sequential? (even tho there is a check for maps before, the later would seem more appropriate)? |
| 08:01 | jweiss | i'm trying to figure out why i can change the print-method for a function object using ^{:type ::foo} metadata, and this also changes the dispatch for pprint. but if i do the same thing for a vector, it only affects prn, not pprint. |
| 08:08 | tgoossens | is it idiomatic to use java enums in clojure. Or do you just give a keyword (which i think is allright) |
| 08:08 | tgoossens | concrete example. In clojure i'm making some kind of game. A "robot" can have an orientation (north, west, etc) |
| 08:09 | tgoossens | in java i would use an ENUM for that orientation |
| 08:09 | tgoossens | but in clojure |
| 08:09 | ucb | tgoossens: keywords or symbols are most idiomatic I'd say |
| 08:09 | tgoossens | i just used :north, :south, etc |
| 08:09 | ucb | tgoossens: especially keywords |
| 08:09 | tgoossens | which i think is fine |
| 08:09 | tgoossens | just wanted a 2nd opinion |
| 08:09 | ucb | I'd +1 keywords |
| 08:09 | ucb | tgoossens: I've also seen people use symbols directly, which is also fine |
| 08:11 | tgoossens | hmm |
| 08:11 | tgoossens | keywoards are clearer i think |
| 08:12 | tgoossens | you can see that it is not a function |
| 08:12 | ucb | oh, I understand that, I'm only saying what I've seen done |
| 08:12 | tgoossens | oh yeah |
| 08:12 | tgoossens | one thing |
| 08:12 | tgoossens | turning clockwise |
| 08:12 | tgoossens | :north -> :east , :east -> :south etc |
| 08:12 | tgoossens | counter clockwise |
| 08:13 | tgoossens | is the inverse mapping |
| 08:13 | tgoossens | currently i have |
| 08:13 | tgoossens | (inverse-orientation :north) -> :south |
| 08:13 | tgoossens | (anticlockwise : north ) == (inversre-orientation (clockwise :north)) |
| 08:14 | tgoossens | is that ok. Or should I use some kind of bimap (not sure if that exists) |
| 08:15 | ucb | tgoossens: the inverse orientation and rotation are two different things; I wouldn't conflate them together |
| 08:15 | ucb | maybe I'd have (inverse :nort) ; :south |
| 08:15 | ucb | and (rotate-right :nort) ; :east |
| 08:15 | tgoossens | hmm |
| 08:16 | ucb | unless you want (inverse ...) to be (rotate 180 ...) |
| 08:17 | tgoossens | got to go : ( (college) |
| 08:17 | tgoossens | thanks already |
| 08:18 | ucb | no worries |
| 08:44 | borkdude | I had an idea, but realized this idea must have come up before. Some people like LaTeX because what comes out of it looks beautiful. The LaTeX code itself isn't really beautiful, but the end results justifies it. What about applying the same approach to Clojure? So typing it in one half of the instarepl results in nicely looking code (without lots of parens) on the right? |
| 08:45 | borkdude | Not that I hate parens, but Clojure code could maybe be formatted into something more beautiful looking |
| 08:47 | borkdude | ibdknox maybe this is a cool idea for lighttable? |
| 08:50 | Scriptor | borkdude: it's a matter of just getting used to it :) |
| 08:51 | Scriptor | the parens are nowhere near as jarring as they used to be for me |
| 08:51 | borkdude | Scriptor don't get me wrong, I am used to it. Common Lisp since 2004, Clojure from 2009 on |
| 08:51 | Scriptor | ah |
| 08:52 | Scriptor | could it be done just by modifying the syntax highlighting? |
| 08:52 | lucian | i've pondered whether something more like yaml for data structure could work for a homoiconic language without redundant separators |
| 08:52 | Scriptor | or would it rearrange the code as well (for better whitespace and whatnot) |
| 08:52 | borkdude | Scriptor but being able to view the code in multiple ways, like in a LaTeX-ish pseudocode mathematics book kind of style could be nice |
| 08:53 | lucian | there's sweet-expressions for schemes, but it does too much i feel |
| 08:53 | Scriptor | hmm |
| 08:55 | borkdude | emacs does this already (in some modes?) by replacing fn with the lambda sign |
| 08:56 | lucian | for me, the redundancy between parens and indentation is the annoying bit |
| 08:56 | lucian | i have the same feeling when i write in a { } language |
| 08:56 | Scriptor | whitespace-aware lisp has been done before |
| 09:06 | borkdude | gtg |
| 09:11 | ivenkys | gents - (defmulti encounter (fn [x y] [(:Species x) (:Species y)])) - what is :Species in this ? |
| 09:14 | ivenkys | i understand encounter is a multi-method and takes a function with 2 args as params - but i dont get what :Species does here |
| 09:47 | andrewmcveigh|wo | ivenkys: :Species is just a keyword there. |
| 09:48 | Bronsa | but it's being used as a function |
| 09:48 | Bronsa | so (:a x) is just like (get x :a) |
| 09:48 | andrewmcveigh|wo | Bronsa: indeed, keywords can act as functions |
| 09:48 | ivenkys | andrewmcveigh|wo: Bronsa : does this mean the "assumption" here is that fn takes two maps as params ? |
| 09:49 | Bronsa | yes |
| 09:49 | andrewmcveigh|wo | yep. |
| 09:49 | Bronsa | well, more generally, a clojure.lang.ILookup i think |
| 09:49 | ivenkys | Bronsa: andrewmcveigh|wo : that was the missing link - thanks gents |
| 10:11 | TimMc | ,(- Double/POSITIVE_INFINITY Double/POSITIVE_INFINITY) |
| 10:12 | Iceland_jack | &(- Double/POSITIVE_INFINITY Double/POSITIVE_INFINITY) |
| 10:12 | lazybot | ⇒ NaN |
| 10:44 | TimMc | ivenkys: Don't assume gender. |
| 10:48 | duck1123 | Bmt^MOBv |
| 10:48 | duck1123 | at least that wasn't all the password |
| 11:07 | scottj | has anyone seen any summaries/notes on rich's keynote? |
| 11:25 | clgv | &(+ Double/POSITIVE_INFINITY Double/POSITIVE_INFINITY) |
| 11:25 | lazybot | ⇒ Infinity |
| 11:32 | seangrove | Any word on whether Domina elements can be passed to the google closure library? |
| 11:35 | seangrove | It seems that Domina elements are a special object in Javascript, and the Google Closure libraries are expecting standard html elements |
| 11:37 | seangrove | Ah, need to use domina/single-node |
| 11:43 | Stooge | hello :) |
| 11:43 | mjwhitt | greetings :) |
| 11:44 | Stooge | do you have any good tutorials/books/video clips/exercises for beginners? |
| 11:45 | joro | Stooge: I'll recommend http://www.clojurebook.com/, and then experimenting with repl using (doc and (source |
| 11:46 | Stooge | thanks :) |
| 11:53 | TimMc | Stooge: http://clojure-doc.org/ is also coming along |
| 11:54 | TimMc | Most pages aren't complete yet, but there's already some really good stuff. |
| 11:55 | Stooge | you mean there are lots of undocumented functions? :p |
| 11:56 | AdmiralBumbleBee | Stooge: are you willing to buy a book? |
| 11:56 | Stooge | ofc not :) |
| 11:56 | Stooge | i need money :) |
| 11:57 | AdmiralBumbleBee | http://java.ociweb.com/mark/clojure/article.html |
| 11:57 | AdmiralBumbleBee | that's where I started |
| 11:57 | seangrove | Goodness me, the google closure library does not lend itself well to clojure idioms |
| 11:57 | seangrove | More and more impressed with the approach of Domina |
| 11:58 | Stooge | k |
| 12:00 | joro | Do you use Clojure in your daily work? |
| 12:03 | duck1123 | I tried using Domina, but I had issues with one of the goog.dom namespaces or something. (this was a while ago) I've been using Jayq/jquery. Is there anything that domina offers that might make it worth switching? |
| 12:04 | Stooge | duck1123 ? :P is this related to closure at all? :p |
| 12:06 | duck1123 | Domina and Jayq are Clojurescript libraries. |
| 12:06 | Stooge | k sorry :P |
| 12:06 | Stooge | never heard about them :P |
| 12:06 | ivenkys | TimMc: hmm good point - my default assumption might be incorrect - i stand corrected (at least on this channel) |
| 12:06 | duck1123 | jayq is a wrapper around jquery, domina (IIRC) is a wrapper around the Google Closure dom stuff |
| 12:18 | seangrove | duck1123: It does seem to lend itself much more towards clojure idioms, it's tiny, and extendable to lots of other libraries |
| 12:18 | seangrove | I've certainly come around to the micro-library approach, domina fits well |
| 12:19 | seangrove | But I was using jayq beforehand, which is certainly great as well |
| 12:21 | Urthwhyte | Having a StreamClosed error when trying to write out to a file with the following code: https://gist.github.com/5490934e9720abc5b131 |
| 12:21 | Urthwhyte | am I meant to have a doseq or something? |
| 12:22 | hiredman | ~map |
| 12:23 | hiredman | clojurebot: ping |
| 12:24 | alexnixon | Urthwhyte: map returns a lazy sequence, which is evaluated *after* your with-open scope has closed. So you need to force evaluation before the with-open closes. So yes, doseq would be good here. |
| 12:25 | hiredman | clojurebot: ping |
| 12:25 | clojurebot | PONG! |
| 12:26 | hiredman | sometimes you can just hear the jit spinning |
| 12:26 | Urthwhyte | haha |
| 12:26 | Urthwhyte | Of course >< - thank you alexnixon |
| 12:39 | zodiak | why does compojure destructure a request in a defroute ? is it jst for clarity when defn a route ? |
| 12:40 | zodiak | I mean, I understand the functionality, jst wondering the rationale |
| 12:40 | mpenet | zodiak: you are free not to do it in the route definition |
| 12:41 | zodiak | surely.. I guess I was wondering, why is it even "there" ? |
| 12:41 | mpenet | zodiak: it is handly for extremely simple "controller", but gets hairy imho when you need to use a large number of arguments from it |
| 12:41 | zodiak | jst so it's not passing a whole hash-map/dict around ? |
| 12:41 | zodiak | mpenet, aaahh |
| 12:42 | zodiak | so, it's part of keeping the function definition 'concise' or 'clear' to other people ? |
| 12:42 | clojurebot | is there a function that is somewhat similar to partition, except that it creates a max number of groups based on a number |
| 12:42 | zodiak | as then you know it's using (say) params etc instead of 'large hash-map' |
| 12:42 | mpenet | zodiak: yep |
| 12:42 | zodiak | mpenet, gotcha :D |
| 12:43 | zodiak | (this maybe starting to make sense. vunderbar ;) |
| 12:45 | zodiak | clojurebot, I am guessing you would have to write on using partition-by |
| 12:45 | clojurebot | Pardon? |
| 12:45 | zodiak | bah.. someone talking via bot.. awesome :P |
| 12:49 | antoineB | hello, how to use the keyword this in clojurescript? |
| 12:50 | sahadev | hello, is this the right place ask clojure newbie questions? |
| 12:50 | antoineB | yes |
| 12:52 | sahadev | antoineB: thanks. when I run, (take-while #(< % 100) (fib 1 1)), I get all fib numbers less than 100, as expected. However, when add another condition, (take-while #(and (< % 100) (even? %)) (fib 1 1)), I get an empty list as the result. why? |
| 12:53 | sahadev | if I rewrite it as (filter even? (take-while #(< % 100) (fib 1 1))), it works as expected. |
| 12:53 | metellus | ,(fib 1 1) |
| 12:53 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: fib in this context, compiling:(NO_SOURCE_PATH:0)> |
| 12:53 | sahadev | metellus: fib is another function already defined. (defn fib [a b] (cons a (lazy-seq (fib b (+ a b))))) |
| 12:54 | metellus | ok, then the first element of the list is 1 |
| 12:54 | metellus | which is odd, so take-while stops immediately |
| 12:54 | antoineB | shachaf: take-while ends when it encouter a false |
| 12:55 | mpenet | antoineB: in cljs you can reach this with the this-as macro |
| 12:55 | antoineB | shachaf: (filter #(even? %) (take 100 (fib 1 1)) |
| 12:56 | sahadev | antoineB: the filter solution works. (filter even? (take-while #(< % 100) (fib 1 1))) |
| 12:57 | sahadev | but, i would like to understand what's wrong with the take-while solution. |
| 12:57 | AndR | sahadev: that's because filter does not stop on false, it takes *all* members from the collection for which the predicate is true |
| 12:57 | AndR | take-while only takes members until it finds one for which the predicate is true |
| 12:57 | metellus | ,(doc take-while) |
| 12:57 | clojurebot | "([pred coll]); Returns a lazy sequence of successive items from coll while (pred item) returns true. pred must be free of side-effects." |
| 12:57 | metellus | AndR: you mean until it finds one for which the predicate is false |
| 12:57 | AndR | compare: (take-while odd [1 2 3 4 5]) and (filter odd [1 2 3 4 5]) |
| 12:57 | AndR | yes, sorry :P |
| 12:58 | sahadev | I see. |
| 12:58 | mpenet | antoineB: (this-as that (jq/val (jq/$ that) )) |
| 12:59 | antoineB | mpenet: ok thanks |
| 13:00 | mpenet | it's also possible with (js* "this"), but not advised, as js* is an internal thing and could change/disapear |
| 13:01 | sjl | Is there a way to make drip work with Leiningen yet? |
| 13:01 | sjl | I set the LEIN_JAVA_... thing but drip creates a new JVM every time I run a lein command |
| 13:02 | sahadev | thanks all. |
| 13:06 | sahadev | I am currently running emacs + nREPL. Using this setup, I can write small snippets in emacs, and execute them using C-c C-e. How do I run the script from the command line? |
| 13:06 | sahadev | looking the process list, it looks like the repl is being run by leiningen. |
| 13:07 | sahadev | all I want to run is some form of: clojure script.clj |
| 13:09 | sahadev | ah, i managed to find the right incantation :) |
| 13:09 | babilen | sahadev: You can use "lein run" (cf. https://github.com/technomancy/leiningen/blob/master/doc/TUTORIAL.md) or create an überjar and execute that. Both approaches are discussed in the TUTORIAL |
| 13:11 | babilen | sahadev: There are also hacks/tools such as https://github.com/Raynes/lein-bin and other ways... I am sure that other have some suggestions as well. |
| 13:11 | sahadev | babilen: thanks. |
| 13:12 | babilen | sahadev: All that being said: I haven't yet found a *single* approach to create well-behaved executables easily |
| 13:13 | sahadev | a lot of the docs assume familiarity with java environments. not being a java guy, sometimes I have trouble following things that might be very obvious to a java programmer. |
| 13:13 | sahadev | is there a tutorial/doc for "getting started with clojure for non-java programmers"? |
| 13:16 | zodiak | sahadev, not really.. but.. to be fair.. clojure is pretty far removed from java in the first place |
| 13:17 | babilen | Wasn't there a nice/good "Java for Clojurists" article somewhere? |
| 13:17 | sahadev | zodiak: I am not looking for help with the clojure language per se. but, with the environment/toolsets to help me get started quickly. |
| 13:17 | babilen | And why is it not possible to query the bots in a /query (they don't answer) |
| 13:18 | zodiak | sahadev, I actually found the clojure book by oreilly to be helpful .. but it depends on what you want to do with clojure |
| 13:19 | mycelloandi | sahadev: most people use emacs and nrepl or swank for their toolset |
| 13:19 | babilen | sahadev: I wouldn't concern myself *too* much with it for now. You don't need to know much about the Java ecosystem if you use leiningen ... It *does* help to know the Java standard library though. |
| 13:19 | zodiak | if you want web programming, look at compojure and ring. you will bump into leiningen at somepoint (go for lein2) |
| 13:19 | babilen | sahadev: I second the recommendation for "Clojure Programming" (http://www.clojurebook.com/) btw |
| 13:19 | zodiak | gui I would say seesaw and ignore swing ;) |
| 13:20 | sahadev | for example, I have a very simple, short clojure script. and i want to run it from command line. but most of the docs I found talk about tools (like lein) that assume certain things. for example, presence of project.clj, which I am sure is very convenient, if I am working on a real project. |
| 13:20 | babilen | So: Is anybody aware of a good way to write command line applications in Clojure? |
| 13:20 | zodiak | and I use vim (good old vim ;) for editing .. although some people use eclipse or emacs (same thing! *zing*) |
| 13:20 | babilen | I also use vim (vim vimclojure + lein tarsier) and am very happy with it |
| 13:21 | AndR | sahadev: you probably want to make a project for anything you don't do directly from a repl |
| 13:21 | mycelloandi | sahadev: "lein run" is the easy way |
| 13:21 | zodiak | babilen, I am afraid all I can think of is lein2 uberjar and then the usual java -jar song and dance |
| 13:21 | sahadev | zodiak: babilen: I just got the O'Reilley book. looks promising. |
| 13:22 | zodiak | sahadev, you will have a learning curve if this is your first lisp |
| 13:22 | AndR | sahadev: for a single script, assuming you have clojure.jar somewhere on global classpath, you can say java -cp `path_to_clojre.jar` clojure.main /path/to/script.clj |
| 13:23 | zodiak | but, like anything worth doing, it's going to take a while to get into the groove |
| 13:23 | babilen | zodiak: I've just stumbled over https://github.com/kumarshantanu/lein-exec but have no idea if it is any good |
| 13:23 | sahadev | zodiak: I dabbled a little with emacs-lisp and scheme in the past, but I am very much a newbie when it comes to lisps. but, I am looking forward to learning it. |
| 13:23 | babilen | zodiak: I am thinking of something like that combined with a tool such as drip that minimises the pain of starting the program over an over again |
| 13:24 | zodiak | babilen, not sure. never used it. sorry. |
| 13:24 | sahadev | AndR: that's exactly what I ended up (after pruning most of the options in the lein command line that is running the repl in my emacs session) |
| 13:24 | babilen | sahadev: I would recomend to start by reading the leiningen tutorial and to take a look at interesting plugins on https://github.com/technomancy/leiningen/wiki/Plugins |
| 13:25 | babilen | gtg, good luck! |
| 13:25 | zodiak | sahadev, well.. grab lein (lein2 preferrably since it really is the future), lein2 repl (bring up repl/command line) and then .. read for the most part and play around |
| 13:26 | zodiak | remember, inside the repl you can lookup docs (doc str) or search (find-doc "str") |
| 13:26 | AndR | sahadev: I recommend making a lein project, doing work with lein repl, then to make the executable do `lein uberjar`, for which you can then do 'drip my.jar' and it should run your main class |
| 13:26 | sahadev | zodiak: my "lein --version" says 2.0.0-preview7. that's what you mean by lein2, right? |
| 13:26 | AndR | yes |
| 13:26 | zodiak | sahadev, yes sir/madam |
| 13:28 | zodiak | good show :) any questions, feel free to ask. I don't think there are too many ego's/prima donna's around this channel ;) |
| 13:28 | AndR | it seems lein is not integrating cleanly with drip (there are a number of bugs in drip saying so), so `lein run` will not take advantage of drip I'm afraid |
| 13:28 | zodiak | jark is another thought, or cake |
| 13:28 | zodiak | not that I have ever used either, right enough |
| 13:28 | sahadev | zodiak: thanks :) that's encouraging. |
| 13:29 | sahadev | what's drip? |
| 13:29 | zodiak | sahadev, it's an 'always on' jvm, so when you start your clojure or java program, there isn't a huge wait time in the jvm starting up |
| 13:29 | zodiak | basically ;) |
| 13:30 | mycelloandi | is drip like nail gun? |
| 13:30 | sahadev | ah, i see. |
| 13:30 | zodiak | mycelloandi, mostly, yes. |
| 13:31 | sahadev | thanks a lot, all. i think i'll be dropping by often. |
| 13:31 | zodiak | sahadev, surely.. I would suggest jst idling in here.. never know what you may learn |
| 13:32 | sahadev | zodiak: yep. i agree. |
| 13:45 | jonasen | I created a lein plugin for codeq: https://github.com/jonase/quantize |
| 13:46 | jonasen | If someone would try it and see if it works I'd be thankful |
| 13:54 | mudge | Hello, I am trying to use Clojure with a Java Web Start application. By default Clojure uses the context classloader but clojure-1.4.0.jar isn't in there, so I am getting this error: Caused by: java.io.FileNotFoundException: Could not locate clojure/core__init.class or clojure/core.clj on classpath |
| 13:55 | mudge | clojure-1.4.0.jar exists in the current classloader not the context classloader. I would set the context classloader to the current classloader, but I don't have control of the Java code to do that. |
| 13:56 | mudge | So I'm thinking that I should go into the source of Clojure and change *use-context-classloader* to false and rebuild Clojure and use that. I'm wondering if that is the best thing to do and if that might cause any problems. |
| 13:57 | zodiak | mudge, having been down the clojure webapp and jetty path very recently, have you tried using an uberwar ? it sounds like you are only using a war |
| 13:58 | zodiak | (if you get my meaning) |
| 13:58 | jodaro | its amazing what rm -rf'ing your ~/.m2 can fix |
| 13:59 | mudge | zodiak: I'm building a module for an existing system which has it's own unique installation/deployment scheme. I create jar files and zip them together with a configuration file and then httpPost them to the application. |
| 14:00 | zodiak | O_o |
| 14:01 | zodiak | mercy.. that's.. urm.. yeah |
| 14:01 | mudge | The problem that I have is that my clojure-1.4.0 is in my current classloader and not in my context classloader, but by default Clojure only looks in the context classloader |
| 14:02 | zodiak | changing clojure source to fix a (pardon my french) "weird deployment mechanism" is not the ~best~ idea |
| 14:02 | mudge | I would set the context classloader to the current classloader by I dont' have access to the Java to do that. So I'm thinking that the only way to do this is to tweak the Clojure source so it doesn't look in the context classloader by default. But not sure if that is the best thing to do or not. |
| 14:02 | zodiak | but, that's jst me |
| 14:02 | mudge | zodiak: I agree, but I don't know of any other way which is why I'm writing here. |
| 14:07 | zodiak | mudge, yeah.. sadly.. I don't know of anyway to do what you want to do :\ |
| 14:08 | TimMc | zodiak: clojurebot responds to something like 1 in 1000 messages as if it were the target. |
| 14:09 | TimMc | with strange results |
| 14:09 | zodiak | TimMc, no joke :D |
| 14:12 | TimMc | zodiak: And if your message contains " is " or " are " it stores it as a factoid, which then may get triggered by other messages. |
| 14:12 | zodiak | O_o |
| 14:12 | zodiak | hah! |
| 14:12 | zodiak | kinda cool but.. kinda weird :) |
| 14:12 | TimMc | Not my idea. :-P |
| 14:13 | mudge | Any idea why *use-context-classloader* is set to true by default? |
| 14:28 | mudge | just asked a Clojure question on stackoverflow: http://stackoverflow.com/questions/13423048/why-does-clojure-use-the-context-classloader-by-default |
| 14:33 | znDuff | mudge: uhh, the context classloader _is_ the default classloader. |
| 14:33 | znDuff | mudge: ...now, why it doesn't always use _that_ is an interesting question. You might find http://stackoverflow.com/questions/10941330/class-forname-in-clojure-not-respecting-contextclassloader (and its answer) worth reading. |
| 14:34 | znDuff | mudge: short form: the DynamicClassLoader wrapper Clojure provides is necessary to have a per-namespace bytecode cache, and it has to be stored somewhere. |
| 14:35 | znDuff | (provisio: This is from memory, and it was quite a while back that I was actually banging my head on this stuff; memory may have failed a bit since then) |
| 14:36 | mudge | znDuff: thanks. What would happen if I changed *use-context-classloader* to false? |
| 14:38 | znDuff | mudge: then you get the classloader that Clojure itself was loaded with |
| 14:38 | mudge | znDuff: I'm compiling (with gen-class) a Clojure application and putting it into an existing Java Web Start application and Clojure-1.4.0.jar is not in the context classloader, it is in the current classloader, so having a problem loading any clojure code |
| 14:38 | mudge | znDuff: anything bad about that? |
| 14:39 | znDuff | mudge: you might want to look at the answer on the SO question I posted a link to. And maybe the question, too. |
| 14:40 | mudge | znDuff: I'm thinking of changing *use-context-classloader* to false in the Clojure source, rebuilding it and using that. |
| 14:41 | mudge | Thanks znDuff, that SO post is about what classloader eval uses. It is good to know that eval uses a DynamicClassLoader |
| 14:41 | znDuff | mudge: it's not just about eval, that's just what I used to demonstrate. |
| 14:42 | mudge | znDuff: I will reread more thoroughly now. |
| 14:47 | alex_baranosky | what does ^:constant metadata do ? Anyone got a link to its explanation? |
| 14:48 | mudge | znDuff: i don't get what you are trying to say in this comment: but the DynamicClassLoader instance bound to clojure.lang.Compiler/LOADER when clojure.lang.Compiler/eval is called matters. |
| 14:56 | znDuff | mudge: Effectively, that comment is duplicative of the answer. Related note: The work that went into that question came out as a patch to clojure.osgi adding support for Apache Felix; if you want to see it in action, that would be https://github.com/charles-dyfis-net/clojure.osgi/blob/master/clojure.osgi/src/main/clojure/clojure/osgi/core.clj |
| 14:56 | mudge | ls |
| 14:56 | lazybot | boot dev etc lib media mnt root sbin selinux srv usr |
| 14:59 | mudge | znDuff: thanks |
| 15:03 | mudge | how do I get clojure source for 1.4.0? |
| 15:03 | mudge | I go here https://github.com/clojure/clojure but that is for Clojure 1.5.0 |
| 15:03 | hiredman | git |
| 15:04 | raek | mudge: use the 1.4.0 tag |
| 15:04 | raek | (instead of the master branch) |
| 15:05 | mudge | raek: I see clojure-4.4.0-beta7.zip, would I download that? It's the latest beta version. |
| 15:05 | Apage43 | https://github.com/clojure/clojure/tree/clojure-1.4.0 |
| 15:05 | Apage43 | https://github.com/clojure/clojure/archive/clojure-1.4.0.zip |
| 15:05 | Apage43 | if you want a zip |
| 15:05 | raek | mudge: if you have clones the repo you already have that tag in your clone |
| 15:06 | raek | just do a "git checkout clojure-1.4.0" |
| 15:07 | mudge | raek: Apage43: got it, thank you! |
| 15:08 | mudge | raek: the tags without alpha and beta in them mean that they are production ready? |
| 15:08 | raek | mudge: yes, that's the release version |
| 15:08 | mudge | raek: thanks |
| 15:09 | raek | usually it's foo-alpha1, fo--alpha2, ..., foo-beta1, foo-beta2, ..., foo-RC1, ..., foo |
| 15:11 | Foxboron | Anyone got any great books on learning Clojure which also contains tasks? |
| 15:11 | raek | weird that there isn't any obvious browse link for the tags at github... |
| 15:11 | znDuff | Foxboron: meaning exercises? Hmm -- the more exercise-focused books are mostly not as good for conceptual learning. |
| 15:12 | Foxboron | znDuff, yes exercises, forgot the word there when i typed it ^^ |
| 15:12 | Foxboron | znDuff, i find it better to read and learn by. |
| 15:12 | raek | Foxboron: btw, have you looked at http://www.4clojure.com/ ? |
| 15:12 | Foxboron | raek: havent seen it actually |
| 15:13 | Urthwhyte | I did about 60 4clojure problems and then switched to reading Programming Clojure |
| 15:14 | Urthwhyte | It's really helpful if you follow some of the people topping the leaderboards - some very beautiful (and hideously terse) solutions will give you insight into the language |
| 15:15 | Netfeed | is it possible to redifine a function in a module? |
| 15:15 | Netfeed | redefine |
| 15:15 | Mr_Bond | Netfeed: yes, you can just defun it again |
| 15:15 | TimMc | Netfeed: By modfule you mean namespace? |
| 15:16 | Netfeed | yes |
| 15:16 | Netfeed | even if it's private? |
| 15:16 | TimMc | Private only affects what users of that namespace see. |
| 15:17 | Netfeed | so it's possible to redefine it from another namespace? |
| 15:17 | TimMc | No, you can't do something like (def other.namespace/foo 5). |
| 15:17 | Netfeed | too bad |
| 15:17 | raek | but you can use 'intern' |
| 15:17 | TimMc | You would have to switch over to the other namespace first. |
| 15:18 | TimMc | Oh yeah, you could use ns interning. |
| 15:18 | TimMc | Sounds like trouble though. |
| 15:18 | amalloy | yeah, don't do that. only sadness and spaghetti lies that way |
| 15:18 | raek | Netfeed: the real question is why you want to do this, though... |
| 15:19 | TimMc | amalloy: That's a good mental image. |
| 15:19 | Netfeed | i want to just add some prints to a function in the tower-lib to understand why i get an assert error in it |
| 15:20 | TimMc | I think with-redefs might help. |
| 15:20 | raek | Netfeed: how are you interacting with clojure? a text-based repl? nrepl/slime? |
| 15:20 | amalloy | TimMc: weeping willows with cold pasta draped over their limbs, marinara sauce dripping forlornly to the ground, silent splats nobody can hear |
| 15:21 | amalloy | hm. soft splats scans better |
| 15:21 | TimMc | D: D: D: |
| 15:22 | Netfeed | raek: lein repl i guess |
| 15:23 | TimMc | clojurebot: sadness and spaghetti? |
| 15:23 | clojurebot | <amalloy> weeping willows with cold pasta draped over their limbs, marinara sauce dripping forlornly to the ground, silent splats nobody can hear |
| 15:23 | TimMc | Oops, that doesn't include your edit. |
| 15:24 | raek | Netfeed: one way is to modify the defn in an editor, enter the namespace via (in-ns 'foo), paste the new definition in the repl, and then (in-ns 'user) to get back |
| 15:24 | raek | this gets much simpler with editor integration |
| 15:26 | Netfeed | i'm fairly new to clojure so i'm not really there yet :) |
| 15:26 | raek | another way is to download the source to the library, add it as a "checkout" in lein, edit the library source code in your working copy and (require 'the-lib :reload) whenever you have made changes |
| 15:26 | Netfeed | with-redefs helped a bit tbh, cool function |
| 15:29 | krakoop | hey all... I wrote my first macro (which serves no purpose besides trying macros) and it kinda works as I expected: (defmacro noob [x] `(prewalk-replace {2 :changed} ~x) |
| 15:30 | krakoop | when I run this on, say, : (noob '[(print 1 2 3) (((print 2)))]) (once again, this serves no purpose besides trying to understand) I get what I expect: [(print 1 :changed 3) (((print :changed)))] |
| 15:31 | TimMc | krakoop: It's not really serving as a macro. |
| 15:31 | TimMc | Take off the ` and the ~ and the ' in the input. |
| 15:31 | krakoop | however I'd now like to replace not '2' with ':changed' (which works fine) but 'print' with something else. For example I'd like to replace 'print' with 'tst'. |
| 15:31 | raek | krakoop: that definition is essentially the same as (defn noob [x] (prewalk-replace {2 :changed} x)) |
| 15:32 | krakoop | I know, I know. That's not my question. My question is how can I replace not '2' with ':changed' but 'print' with another function name. |
| 15:32 | krakoop | ; ) |
| 15:32 | bbloom | krakoop: at the time the macro is evaluated, x is a list |
| 15:32 | raek | (prewalk-replace {'print :changed} ...)? |
| 15:33 | bbloom | &(let [x '(print :changed)] (cons 'not-print (next x))) |
| 15:33 | lazybot | ⇒ (not-print :changed) |
| 15:34 | bbloom | krakoop: or, with the syntax quote: |
| 15:34 | bbloom | &(let [x '(print :changed)] `(not-print ~@(next x))) |
| 15:34 | lazybot | ⇒ (clojure.core/not-print :changed) |
| 15:34 | amalloy | (defmacro noob [x] (prewalk-replace {'print :changed} x) |
| 15:34 | krakoop | @raek: {'print :changed 2 :changedtoo} won't work for 'print (but still works for '2') |
| 15:34 | amalloy | krakoop: that's because of what TimMc said. your syntax-quote shouldn't be there |
| 15:35 | krakoop | ok but what when I want to do the same in case I need the syntax quote too? |
| 15:35 | TimMc | I think it should still work... |
| 15:35 | raek | krakoop: the ` is interfering... it adds namespace parts to all the symbols |
| 15:35 | TimMc | aha |
| 15:35 | amalloy | TimMc: no, because `'print is 'clojure.core/print |
| 15:35 | amalloy | and also because he's not postwalk-replacing the form itself, but the result of evaluating the form |
| 15:35 | TimMc | syntax-quote strikes again! |
| 15:36 | raek | krakoop: if you want to experiment with postwalk-replace, start with ordinary functions and pass them quoted code |
| 15:36 | krakoop | well the point of my question is kinda precisely to understand syntax quoting etc. ; ) |
| 15:37 | raek | ah |
| 15:37 | raek | well, we can take a look at syntax quote in isolation (you don't have to be in a macro to use it) |
| 15:37 | krakoop | @raek: postwalk-replace is not what I'm interested in... a simple 'replace' example would work too: I mean, I'd be just as confused ; ) |
| 15:37 | raek | ,`[(print 1 2 3) (((print 2)))] |
| 15:37 | clojurebot | [(clojure.core/print 1 2 3) (((clojure.core/print 2)))] |
| 15:38 | raek | this is the value that postwalk-replace received in your example |
| 15:38 | krakoop | so how would I modify my map so that it replace print (which is received as clojure.core/print) with something else ? |
| 15:39 | amalloy | !!!! no it's not, raek |
| 15:39 | raek | amalloy: you are right. |
| 15:39 | amalloy | it received [(print 1 2 3) (((print 2)))], but its replace-map was {clojure.core/print :changed} |
| 15:39 | amalloy | krakoop: don't syntax-quote it :P |
| 15:39 | raek | that makes more sense |
| 15:40 | krakoop | amalloy: oooooh gotcha |
| 15:42 | estebann | so clojure.java.shell/sh seems to hang if the command run prints too much to stdout... has anyone else seen this or is it just me? |
| 15:43 | mudge | zdNuff: I set *use-context-classloader* to false in RT.java, but now I am getting this error: aused by: java.lang.ClassNotFoundException: clojure.lang.PersistentList |
| 15:44 | mudge | seems like Clojure is still looking in the context classloader even though I set *use-context-classloader* to false |
| 15:47 | ebaxt | I'm trying to understand a lazy fibs example: https://gist.github.com/4090592, I |
| 15:47 | znDuff | mudge: if you're following the OSGi example, I don't think I ever set *use-context-classloader* to false there. |
| 15:48 | ebaxt | I've tried to break down the state of the execution, and I'm wondering if either A or B is correct= |
| 15:48 | ebaxt | ? |
| 15:49 | mudge | znDuff: I'm not following the OSGi example |
| 15:49 | mudge | znDuff: I have a gen-classed class file that I want a Java application to use -- the source of which java I don't have access to. |
| 15:51 | Mr_Bond | estebann: how long does it have to be? |
| 15:52 | Mr_Bond | ,(clojure.java.shell/sh "cat" "/etc/resolv.conf") |
| 15:52 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: java.lang.ClassNotFoundException: clojure.java.shell> |
| 15:52 | estebann | looks like an out of memory exception is failing to bubble up... so bigger than you have heap space |
| 15:52 | Mr_Bond | ah, I see |
| 15:53 | estebann | you can test it with (clojure.java.shell/sh "cat" "/dev/urandom") pretty easily at least on linux |
| 15:53 | Mr_Bond | yeah, good idea |
| 15:55 | Mr_Bond | I guess it would be nice to have an alternate interface to sh, which gave a sequence, instead of it having to first fill up "stdout" variable |
| 15:55 | estebann | I definitely would appreciate it at the moment |
| 15:58 | Mr_Bond | I seems supported by http://docs.oracle.com/javase/7/docs/api/java/lang/Process.html#getInputStream(), so you could write your own "sh" using https://github.com/richhickey/clojure/blob/4bea7a529bb14b99d48758cfaf0d71af0997f0ff/src/clj/clojure/java/shell.clj#L63 but I guess there is probably something in clojure.contrib or in the repos for it |
| 16:00 | estebann | cool... should I report this somewhere? |
| 16:00 | amalloy | Mr_Bond: see Raynes's conch library. or maybe it's fs? i don't remember which one it's in |
| 16:01 | Mr_Bond | estebann: I think it's expected, but otoh it would be nice to have such a tool in core |
| 16:02 | Mr_Bond | amalloy: nice |
| 16:02 | Mr_Bond | thanks |
| 16:02 | estebann | huh.. I would have expected to get the Out Of Memory Error |
| 16:03 | estebann | rather than a hung thread |
| 16:03 | Mr_Bond | oh, right. Yeah, that's not good |
| 16:04 | Mr_Bond | mm, it looks like Raynes.fs/exec could be an option |
| 16:04 | amalloy | it's an OOME on a different thread |
| 16:04 | Mr_Bond | ah, no it just wraps clojure.java.shell/sh |
| 16:05 | amalloy | there's no real way to catch that given the rubbish implementation of sh, as far as i know |
| 16:05 | amalloy | Mr_Bond: yeah, you want conch, not fs |
| 16:06 | Mr_Bond | cool, yeah thats more like it |
| 16:07 | estebann | amalloy: cool, loooks good |
| 16:08 | Mr_Bond | there was a link pasted the other day, about a functional programming book (clojure) on PDF, for a couple of bucks |
| 16:08 | Mr_Bond | anyone happen to remember the link? |
| 16:27 | alex_baranosky | does anyone know what ^:constant metadata does? |
| 16:31 | zodiak | alex_baranosky, I ~assume~ the opposite of ^:dynamic |
| 16:31 | zodiak | marks it as a var but NOT dynamically rebindable |
| 16:31 | zodiak | (guessing here ;) |
| 16:31 | alex_baranosky | http://stackoverflow.com/questions/9162558/how-does-clojure-const-work |
| 16:31 | TimMc | I think the opposite of ^:dynamic is simply the lack of it. |
| 16:32 | alex_baranosky | it changes the way the code gets compiled |
| 16:32 | zodiak | TimMc, following the python mantra though, explicit is better than implicit so, having a ^:constant would tell me "whoa, this isn't changeable no way no how" |
| 16:33 | zodiak | and anywhere I see ^:constant is with things like pi or tau so .. as I said, guessing :) |
| 16:33 | TimMc | THis is a question of reality, not desire. |
| 16:33 | TimMc | Oh, I see why you said that. |
| 16:34 | zodiak | dynamic would have to be constantly looked up, right ? to check the value, constant should be looked up once (hopefully ;) |
| 16:35 | alex_baranosky | its actually ^:const not ^:constant |
| 16:35 | alex_baranosky | I got that one wrong |
| 16:36 | zodiak | well, shut my mouth then :) |
| 16:37 | alex_baranosky | so const attempts to embed the var in the code at compile time |
| 16:37 | alex_baranosky | I just attempted to use ^:const on a simple date format, and found out that detail (since the reader/printer don't know how to handle SimpleDateFormats) |
| 16:39 | bobry | Folks, how should I debug "Uberjar aborting because jar/compilation failed: java.lang.String cannot be cast to clojure.lang.IFn"? |
| 16:39 | bobry | All I have is a file with an empty -main function, which does nothing. |
| 16:40 | bobry | So I guess it's not my code which is causing the exception. |
| 16:41 | zodiak | bobry, have you tried calling your main from lein repl ? |
| 16:41 | bobry | I've tried 'lein run' and it seems to work fine. |
| 16:44 | zodiak | time to pastebin.com I reckon |
| 16:45 | Foxboron | doing some problems on the clojure4 site. Came to problem 22 where i am suppose to count a list without using count. |
| 16:45 | zodiak | fwiw, I almost always use lein repl and then use lib, (main) the sucker |
| 16:45 | Foxboron | #(for [x %] :let [y (+ y 1)] [y]) |
| 16:45 | Foxboron | Why wont this work :3? |
| 16:45 | Foxboron | <- total LISP noob |
| 16:47 | bobry | okay, this is nice, the problem was in the :license field of the 'project.clj' file, which was "MIT", instead of a hash-map |
| 16:47 | znDuff | Foxboron: first, y has no initial binding; second, for loops are like Python list comprehensions, so they aren't really a fit to what you're trying to do here. |
| 16:47 | bobry | time for a bug report :) |
| 16:47 | AimHere | Foxboron, I think there's about 4 reasons |
| 16:49 | znDuff | Foxboron: ...a for loop just creates a lazy sequence -- it doesn't actually force it to be evaluated -- and it doesn't retain state between steps in that loop |
| 16:49 | znDuff | Foxboron: as a hint, you might look at loop/recur. |
| 16:49 | Foxboron | was going to ask for hints ^^ |
| 16:50 | Foxboron | Started clojure today and only know Python from before, so its a rather radical change |
| 16:50 | zodiak | Foxboron, also the bracketing in the for loop is wrong ;) |
| 16:50 | Foxboron | but its actually rather fun |
| 16:50 | Foxboron | zodiak i did notice on the second look |
| 16:50 | Foxboron | spent 4 hours fixing the leining repl.... |
| 16:50 | znDuff | Foxboron: ...actually, I said "like Python list comprehensions", but they're actually closer to genexps, in terms of being lazy. |
| 16:51 | Foxboron | something bugged with the path and the 2nd version on windows FYI |
| 16:51 | raek | Foxboron: when you're using loop and recur, imagine that you are only allowed to update your variables at one point (at the end of the loop) |
| 16:51 | Foxboron | znDuff, i havent actually read up what it means by being "lazy", so will look into that aswell :) |
| 16:51 | znDuff | Foxboron: Have you tried Light Table for Windows, by the way? |
| 16:51 | Foxboron | znDuff, oh damn right. |
| 16:51 | Foxboron | I was going to, totally forgot |
| 16:52 | Foxboron | another reason why i actually started looking at Clojure, i found the syntax rather pleasant looking at when i watched the demo. |
| 16:52 | purpleguy | it is |
| 16:52 | purpleguy | the guy who writes it gave a talk just day before yesterday |
| 16:52 | purpleguy | here at my uni |
| 16:53 | Foxboron | there is a... |
| 16:53 | znDuff | purpleguy: I've seen the new version, and I still don't think it's there yet. |
| 16:53 | purpleguy | basically, he's got so many features he's implementing |
| 16:53 | Foxboron | JavaScript conf going on where they will be presenting some stuff using LightTable |
| 16:53 | Foxboron | will be livestreamed |
| 16:53 | Foxboron | znDuff, i won't really judge it before its out. |
| 16:53 | Foxboron | anyone seen the talk which the concept was based on? |
| 16:54 | znDuff | Foxboron: With the interactive game? A great many of us have. |
| 16:54 | Foxboron | saw it first time yesterday actually. |
| 16:55 | Foxboron | also, what is considered the best site for clojure documentations? i use clojuredocs.org but i find it rather messy and all over the place |
| 16:55 | dakrone | Foxboron: there are multiple sites, perhaps try clojure-doc.org or doc.clojure.org |
| 16:55 | AimHere | I find that clojure cheat sheet to be the most useful document out there |
| 16:56 | AimHere | At least as a reference |
| 16:56 | Foxboron | looked at it, but its not really fit when you dont know what you are looking for |
| 16:57 | AimHere | Well perhaps, though I do recall clicking on likely looking functions to see what's out there at times |
| 17:24 | jodaro | i wish i was conjing |
| 17:26 | Foxboron | (#(loop [x 0 lis %] (when (= (peek lis) nil) (x))(recur (pop lis) (inc x))) '(1 2 3 3 3 4)) |
| 17:26 | Foxboron | am i on the right track now <.<? |
| 17:26 | Foxboron | For those who didnt see the chat above: Trying to count items in a list without using count. |
| 17:28 | znDuff | Foxboron: that's quite a lot more involved than what you need. |
| 17:29 | Foxboron | i honestly don't doubt that. |
| 17:29 | znDuff | but that said, it's very much on the right track. |
| 17:29 | Foxboron | any hints on whats wrong? |
| 17:29 | Foxboron | i find it rather hard figureing out the error messages in Clojure. Kinda anoying |
| 17:30 | TimMc | Foxboron: (x) calls x as a function with no args. |
| 17:30 | Foxboron | i want x as a variable, trying to search around examples doing that |
| 17:30 | TimMc | so you should gets some "expected an IFn" msg. |
| 17:30 | TimMc | Foxboron: You want the value x? |
| 17:30 | Foxboron | java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IPersistentStack (NO_SOURCE_FILE:0) |
| 17:30 | TimMc | Just write x. |
| 17:31 | TimMc | Foxboron: You have your recur in the wrong order, then. |
| 17:31 | Foxboron | TimMc, i want x as a variable for counting. Basically x = 0 |
| 17:32 | Foxboron | its funny, its like trying to learn programming all over again :P |
| 17:32 | raek | Foxboron: the predicate for checking whether a seq is empty is 'empty?'. peek looks at an element in the list. |
| 17:32 | Foxboron | oh, i didnt know that actually |
| 17:33 | raek | Foxboron: the general method you are using is right. but as TimMc said you have the arguments reversed in the recur form |
| 17:33 | raek | loop has x and list, but recur has list and x |
| 17:33 | TimMc | Foxboron: I don't think you read what I wrote: (x) calls x as a fn. Note the parens. |
| 17:33 | raek | ,(empty? []) |
| 17:33 | clojurebot | true |
| 17:33 | raek | ,(empty? [1 2 3]) |
| 17:33 | clojurebot | false |
| 17:33 | Foxboron | hah, even a repl bot here. |
| 17:33 | raek | ,(rest [1 2 3]) |
| 17:33 | clojurebot | (2 3) |
| 17:34 | Foxboron | raek, i got a repl setup here too :) |
| 17:34 | Foxboron | TimMc, then i asked how i can define x as a variable inside the loop. But i never really got a hint in the right direction :P |
| 17:34 | raek | so, there's some examples of the sequence api |
| 17:34 | Foxboron | thanks raek ^^ |
| 17:35 | raek | you have been using the stack api which is related |
| 17:36 | raek | for sequences peek=first and pop=rest |
| 17:36 | hiredman | ,(pop ()) |
| 17:36 | clojurebot | #<IllegalStateException java.lang.IllegalStateException: Can't pop empty list> |
| 17:37 | raek | you can think of sequences as "iteration" in the form of data |
| 17:37 | Foxboron | i see, does make sense |
| 17:46 | DaReaper5 | Hi, what is the best/proper way to support long polling/push from a client (front end javascript) on a clojure web server backend |
| 17:47 | DaReaper5 | I am having trouble finding a library or approach that will support this |
| 17:47 | DaReaper5 | This is the closest I have found: https://github.com/shenfeng/async-ring-adapter |
| 18:05 | Foxboron | wohoo, did it |
| 18:06 | Netfeed | is it possible to split a keyword? |
| 18:06 | raek | Netfeed: into namespace and name parts? |
| 18:07 | DaReaper5 | Does anyone know the best way to facilitate long polling on a clojure web server? |
| 18:07 | DaReaper5 | Should I use threads and listeners |
| 18:07 | Sgeo | What's the best way to store a chunk of binary data? |
| 18:07 | Netfeed | just the parts, (name :foo/bar) returns "bar", and i'd like the :foo too |
| 18:07 | Sgeo | A vector of bytes? |
| 18:07 | mattmoss | ,(namespace :foo/bar) |
| 18:07 | clojurebot | "foo" |
| 18:08 | Netfeed | thanks |
| 18:08 | Sgeo | Uh. |
| 18:09 | Sgeo | I'm playing with byte on Try Clojure |
| 18:09 | Apage43 | Sgeo: depends where it comes from and where you're gonna put it |
| 18:09 | Sgeo | Why are they signed? |
| 18:09 | Apage43 | all java primitive number types except char are signed |
| 18:09 | Sgeo | That's... uh... brillant |
| 18:09 | raek | Sgeo: that's the way they are printed by default |
| 18:10 | Sgeo | And read too, apparently |
| 18:10 | Sgeo | ,(byte 0xFF) |
| 18:10 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: Value out of range for byte: 255> |
| 18:10 | Sgeo | ,(byte 0x7F) |
| 18:10 | clojurebot | 127 |
| 18:10 | Sgeo | ,(byte -0x7F) |
| 18:10 | Apage43 | yep, can't do that. |
| 18:10 | clojurebot | -127 |
| 18:11 | Sgeo | ,(char 0xFF) |
| 18:11 | clojurebot | \ÿ |
| 18:11 | Sgeo | ,(char 0x100) |
| 18:11 | clojurebot | \Ā |
| 18:11 | flying_rhino | hello folks |
| 18:11 | raek | the JVM does not have separate types for signed and unsigned primitives |
| 18:11 | Sgeo | Are chars unicode codepoints, at least? A little bit of sanity in the Java prims? |
| 18:11 | raek | yes, char != byte |
| 18:11 | flying_rhino | does anyone have a list of all immutable types available to me in clojure? |
| 18:11 | raek | byte is int8_t and char uint16_t |
| 18:11 | flying_rhino | all data types i mean |
| 18:12 | Apage43 | Sgeo: not.. really. char is really a unsigned 16 bit number, which can't cover all of unicode |
| 18:12 | Sgeo | raek, uh, 16 bits is not enough to represent all unicode codepoints. |
| 18:12 | flying_rhino | there's vector, hash table, linked list, what else is there? |
| 18:12 | raek | Sgeo: the JVM uses UCS2 |
| 18:12 | Sgeo | Can Java strings handle codepoints outside the BMP? |
| 18:12 | Apage43 | java's internal string representation is UCS-2 |
| 18:12 | Sgeo | I... uh |
| 18:13 | raek | so code points in the astral planes are represented using two JVM chars |
| 18:13 | Apage43 | Sgeo: yep, they're just more than one "char" long, awkwardly |
| 18:13 | Sgeo | Wouldn't that be UTF-16 not UCS-2? |
| 18:13 | Apage43 | JVM predates UTF-16. It's "close enough" most of the time though. |
| 18:13 | DaReaper5 | oh man still having an issue here with finding a solution to facilitating long polling on clojure |
| 18:14 | DaReaper5 | should i use "add-watch" in conjuction with a thread? |
| 18:14 | amalloy | DaReaper5: i suspect you would get better answers if you told someone what "long polling" is |
| 18:14 | raek | Sgeo: sorry. yes I got that wrong. it uses UTF-16 |
| 18:14 | flying_rhino | what are immutable types (besides vector hash table and linked list) that are available to me in clojure? |
| 18:14 | raek | surrogate pairs and all that kind of jazz |
| 18:15 | DaReaper5 | amalloy long polling is way of facilitating a PUSH to a client from a server |
| 18:15 | raek | flying_rhino: sets and queues |
| 18:15 | raek | and records |
| 18:15 | amalloy | and numbers! |
| 18:15 | amalloy | and strings! |
| 18:15 | DaReaper5 | basically (from what i understand) it is just a request that does not respond until the event |
| 18:15 | raek | mutable numbers - now that's a terrible idea! |
| 18:15 | flying_rhino | what do queues and records do? |
| 18:15 | DaReaper5 | i want to know a good way of waiting for an event and then responding |
| 18:16 | mattmoss | (def 3 4) |
| 18:16 | mattmoss | add-watch |
| 18:16 | mattmoss | ? |
| 18:16 | DaReaper5 | so this "could" be summed up (if there is no lib for it) as: "How to I do listeners in clojure" |
| 18:16 | raek | flying_rhino: you add elements to one end of the queue and take elements away at the other end |
| 18:16 | DaReaper5 | mattmoss but i can't find any good examples of it |
| 18:16 | DaReaper5 | :s |
| 18:16 | flying_rhino | I see |
| 18:16 | raek | records could be seen as "optimized" hash maps |
| 18:17 | raek | that can also implement protocols |
| 18:17 | mattmoss | DaReaper5: Sorry... I don't know the mechanics of long polling to be ableto suggest how to set something up. |
| 18:17 | DaReaper5 | mattmoss: basically this: i need to wait until something is triggered or happens |
| 18:18 | DaReaper5 | i know how to do the whole response part |
| 18:18 | DaReaper5 | but how to actually wait for the event in the same thread?! |
| 18:18 | mattmoss | Why same thread? |
| 18:18 | raek | Sgeo: since you are entering encoding problem territory, beware of the java methods that convert between bytes and chars without an explicit encoding (and remember to always provide one explicitly) |
| 18:18 | flying_rhino | raek: thanks. Is it possible to build your own datatypes in clojure (say quad trees) or do you have to do it from java? |
| 18:19 | flying_rhino | raek: I know how to do it in Java, but have no idea how to do it in immutable language |
| 18:19 | raek | flying_rhino: I think you should be able to do that using defprotocol and deftype (and possibly defrecord) |
| 18:19 | DaReaper5 | Its what i need for long polling, basically clojure will reseave the message then wait until something happens to send a responds |
| 18:19 | mattmoss | If same thread... then maybe a future... then block on it with deref and a timeout? |
| 18:19 | DaReaper5 | response* |
| 18:19 | DaReaper5 | http://stackoverflow.com/questions/6954347/how-to-implement-the-observer-design-pattern-in-a-pure-functional-way |
| 18:20 | DaReaper5 | ^ has the best example i have found on add-watch |
| 18:20 | DaReaper5 | but (possible because of my lack of knowledge of clojure) how would i get the response to be in the same thread. Would i do this: |
| 18:20 | raek | flying_rhino: you'll probably find the datastructure implementations of ClojureScript more interesting than those of Clojure. cljs relies much more on protocols |
| 18:21 | DaReaper5 | I think i should do this: |
| 18:21 | DaReaper5 | (Thread/sleep 100) then check for event then (Thread/sleep 100) etc |
| 18:21 | DaReaper5 | however that is horrible |
| 18:21 | flying_rhino | raek: clojurescript is that something like scripting lang fro clojure or what? |
| 18:21 | flying_rhino | *for |
| 18:21 | raek | flying_rhino: maybe this is a good example: https://github.com/clojure/data.finger-tree |
| 18:22 | raek | flying_rhino: it's a variant of clojure that compiles to javascript |
| 18:22 | flying_rhino | raek: nah I like execution speed and js isn't very fast |
| 18:22 | DaReaper5 | I should just listen for an event then respond in the same thread |
| 18:23 | raek | flying_rhino: it's interesting in that it relies more heavily on protocols than on host interop (clojure has lots of stuff written in java) |
| 18:23 | flying_rhino | raek: obviously |
| 18:24 | mattmoss | DaReaper5: Why same thread? And same as what... the thread kicking things off, the thread sending the event... ? |
| 18:24 | raek | so in Clojure you have java interfaces for most datatype abstractions but in ClojureScript these are "pure" clojure abstractions |
| 18:24 | DaReaper5 | thread initiating the listener |
| 18:25 | flying_rhino | raek: I see |
| 18:25 | DaReaper5 | mattmoss i cant think of any other way where i would respond to a long polling event |
| 18:25 | raek | so, the clojuresctipt data structures may be a little more ideomatic since they are more recent |
| 18:25 | DaReaper5 | again long polling is when i do a request to a server and just wait and wait for the event |
| 18:25 | raek | well, the overall structuring of them |
| 18:25 | flying_rhino | raek: I see |
| 18:25 | DaReaper5 | as the response |
| 18:26 | mattmoss | DaReaper5: So put it in a future, then deref it. It will block... or add a timeout so you can periodically do some other task and deref again. |
| 18:26 | DaReaper5 | hmm i guess this is where my lack of clojure knowledge shows |
| 18:27 | flying_rhino | raek: tbh biggest problem I have with clojure is it's singular insistence on fuctional programming. Focus on it is okay, but somethimes you need/want some mutable types. |
| 18:28 | TimMc | flying_rhino: Feel free to use transients, or even arrays. |
| 18:28 | flying_rhino | arrays? You mean like java array? |
| 18:28 | raek | sure |
| 18:29 | flying_rhino | I didn't expect clojure to have those |
| 18:29 | raek | well, you can use java arrays directly from clojure |
| 18:30 | TimMc | This ain't Haskell. |
| 18:30 | raek | but you lose the benefits of functional programming, etc |
| 18:30 | TimMc | Well... |
| 18:30 | raek | equational reasoning, thread safety, structural sharing... |
| 18:30 | flying_rhino | can I also use all other mutable types from java? (not saying that's a good thing, just asking if it is possible) |
| 18:30 | TimMc | one could certainly make an argument about whether functional programming is really about immutable data types. |
| 18:31 | raek | (if you start using uncontrolled mutation in your code) |
| 18:31 | TimMc | flying_rhino: ##(java.util.ArrayList [1 2 3]) |
| 18:31 | lazybot | java.lang.ClassCastException: java.lang.Class cannot be cast to clojure.lang.IFn |
| 18:31 | TimMc | &(java.util.ArrayList. [1 2 3]) |
| 18:31 | lazybot | ⇒ #<ArrayList [1, 2, 3]> |
| 18:31 | TimMc | Go nuts. |
| 18:32 | raek | to me referential transparancy is one of the most important characteristics of FP |
| 18:32 | TimMc | That is certainly a pretty nice one. |
| 18:32 | DaReaper5 | mattmoss thanks man, promise and future seem to be the way to go |
| 18:32 | flying_rhino | can I also use all other mutable types, like numbers and stuff? |
| 18:32 | flying_rhino | not saying ti is a good idea |
| 18:32 | TimMc | numbers aren't mutable! |
| 18:33 | mattmoss | DaReaper5: Enjoy. |
| 18:33 | TimMc | well, AtomicInteger is, I guess |
| 18:33 | raek | but what "FP" really means is disputed, of course... |
| 18:33 | flying_rhino | I mean from java |
| 18:33 | metellus | Integers are mutable, I think |
| 18:33 | TimMc | No way. |
| 18:33 | raek | flying_rhino: the variable is mutable, not the number in it |
| 18:33 | flying_rhino | I mean can I use plain java datatypes which are mostly mutable, if I am not mistaken? |
| 18:34 | flying_rhino | you mentioned array |
| 18:34 | TimMc | flying_rhino: Nothing is stopping you. |
| 18:34 | flying_rhino | good to hear |
| 18:34 | flying_rhino | look I am going to try functional way first, ofcourse but I want to know that there is ejection seat |
| 18:35 | flying_rhino | in case functional doesn't cut it. |
| 18:35 | raek | Clojure certainly has its ejection seat... :) |
| 18:35 | mattmoss | Is it a functional ejection seat? |
| 18:35 | TimMc | &(let [q (java.util.concurrent.LinkedBlockingQueue. '[a b c])] (.poll q) (.size q)) |
| 18:35 | lazybot | java.lang.SecurityException: You tripped the alarm! clojail.testers.ClojailWrapper@68b653 is bad! |
| 18:35 | TimMc | lazybot: ? |
| 18:36 | brainproxy | mattmoss: yes, it will give you happy functional ejection time |
| 18:36 | DaReaper5 | mattmoss: i just want to summarize promise and future... so i can be sure i understand them: Promise-> def creates a promise which is an object that can be passed to any thread. If a thread treis to deref the promise object it blocks until it is ready. When you deliver a promise it becomes available to the other threads. |
| 18:37 | TimMc | &(let [l (java.util.concurrent.atomic.AtomicLong. 5)] (.incrementAndGet l)) |
| 18:37 | lazybot | ⇒ 6 |
| 18:37 | mattmoss | DaReaper5: That... sounds right. Also note that you can only deliver once to a particular promise. |
| 18:37 | DaReaper5 | Future: like promise but you define the function that calculates the object which pritty much does a deliver at the end of the calculation. |
| 18:38 | DaReaper5 | mattmoss makes sence concurrance wise |
| 18:38 | DaReaper5 | This is what I am learning it from (thank god for stackoverflow) http://stackoverflow.com/questions/4623536/how-do-clojure-futures-and-promises-differ |
| 18:39 | TimMc | promise/deliver is far more powerful and flexible |
| 18:39 | DaReaper5 | timmc seems like it because you get to decide when the object is available |
| 18:39 | TimMc | and where |
| 18:39 | TimMc | or even whether |
| 18:40 | DaReaper5 | now i get the super complicated task of how to assign and delegate these promises |
| 18:40 | DaReaper5 | basically i want a certain method call to deliver a promise to a user session. |
| 18:41 | mattmoss | DaReaper5: MAke sure to read the answer by dimagog right below the first large answer. |
| 18:41 | raek | I think you could describe 'future' as a function that returns a promise-like thing and starts a thread that evaluates an expression and deliver its value |
| 18:42 | DaReaper5 | raek ya i think thats what i was trying to say |
| 18:43 | TimMc | I guess you could easily implement future using promise/deliver... but it's a actually a thing from Java-land. |
| 18:44 | alexyk | what's #_(…) as a way to comment out things? |
| 18:44 | amalloy | a way to comment out things, man. there's no other way to say it |
| 18:44 | alexyk | what's #_ ? in relation to lambdas etc |
| 18:44 | raek | alexyk: unrelated |
| 18:44 | mattmoss | It's a reader thing? |
| 18:44 | raek | #_ means "ignore the next form" |
| 18:44 | alexyk | so random syntax? |
| 18:45 | TimMc | Basically java.util.concurrent.Future + some interfaces. |
| 18:45 | raek | yes, it's done by the reader |
| 18:45 | alexyk | ok |
| 18:45 | raek | most often the first character after the # determines the "special meaning" |
| 18:45 | TimMc | ,[1 #_ #_ 2 3 4 5 6] |
| 18:45 | clojurebot | [1 4 5 6] |
| 18:46 | raek | huh, they stack? :) |
| 18:46 | TimMc | and interact badly with fn literal args |
| 18:47 | TimMc | ,(#(#_ %1) 'hello) |
| 18:47 | clojurebot | () |
| 18:47 | mattmoss | ,#'#_ |
| 18:47 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading> |
| 18:47 | mattmoss | ,#_#' |
| 18:47 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading> |
| 18:47 | TimMc | mattmoss: It's not a var. |
| 18:47 | Sgeo | ,#_#' (do) |
| 18:47 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading> |
| 18:47 | mattmoss | ,#_#'_ |
| 18:47 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading> |
| 18:48 | Sgeo | Aww |
| 18:48 | raek | alexyk: the "#" as no meaning by itself is what I was trying to say... |
| 18:48 | Sgeo | , |
| 18:48 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading> |
| 18:48 | Sgeo | ,#'do ; do is not a var |
| 18:48 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve var: do in this context, compiling:(NO_SOURCE_PATH:0)> |
| 18:48 | ivan | too many #_ will overflow your stack |
| 18:48 | mattmoss | ,#_o--o |
| 18:48 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading> |
| 18:48 | alexyk | so #(+ % 1) is also a reader thing, with spec. meaning provided by ( ? |
| 18:48 | Sgeo | ,[#'-> #'+ ; but macros and functions are] |
| 18:48 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading> |
| 18:48 | Sgeo | ,#_o--o (do) |
| 18:48 | clojurebot | nil |
| 18:49 | TimMc | This look slike a good time to head home. |
| 18:49 | Sgeo | ,[#'-> #'+] ; but macros and functions are |
| 18:49 | clojurebot | [#'clojure.core/-> #'clojure.core/+] |
| 18:49 | mattmoss | lol |
| 18:49 | alexyk | TimMc: you must be on the wrong coast |
| 18:49 | raek | alexyk: yes, #(foo %) is just a reader shorthand that means the same thing as: |
| 18:49 | TimMc | No, I'm on the right(-most) coast. |
| 18:49 | raek | ,'#(foo %) |
| 18:49 | clojurebot | (fn* [p1__325#] (foo p1__325#)) |
| 18:50 | mattmoss | ,`' |
| 18:50 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading> |
| 18:50 | alexyk | TimMc: which is the wrong one, w.r.t. startups |
| 18:50 | raek | so "#(" means "start of anonymous function shorthand" |
| 18:50 | Sgeo | ,(#(inc (#(inc %))) 5) |
| 18:50 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.IllegalStateException: Nested #()s are not allowed> |
| 18:51 | raek | you could also think of # as switching some kind of "mode" in the reader |
| 18:51 | mattmoss | ,`':' |
| 18:51 | clojurebot | (quote :') |
| 18:51 | amalloy | Sgeo: 'do is not a var, but i had a good laugh when i saw one of the monad libraries had (:refer-clojure :exclude [do]) |
| 18:52 | mattmoss | ,'':- |
| 18:52 | clojurebot | (quote :-) |
| 18:52 | mattmoss | quote smiley |
| 18:53 | amalloy | ,'(tophat :-) |
| 18:53 | clojurebot | (tophat :-) |
| 18:57 | DaReaper5 | How would I go about having a reusable/assignable promise. Here is the issue: i want to call upon the promise to retrieve the most recent event which will be stored in the promise. |
| 18:57 | DaReaper5 | Actually, could i just use a blocking queue |
| 18:57 | DaReaper5 | that would return the top item or block until there is one? |
| 18:58 | raek | yes, BlockingQueues can do that |
| 18:58 | DaReaper5 | http://clojuredocs.org/clojure_core/1.2.0/clojure.core/seque ? |
| 18:59 | raek | http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/BlockingQueue.html |
| 18:59 | raek | and |
| 18:59 | raek | http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/LinkedBlockingQueue.html |
| 19:00 | DaReaper5 | hmmm so use the java blocking queue eh |
| 19:00 | raek | blocking queues and persistent queues of promises feels like two ways of thinking about the same thing |
| 19:00 | flying_rhino | do I have threads in clojure? |
| 19:01 | flying_rhino | (I know there are better ways, I just want to know if it is available) |
| 19:01 | raek | http://clj-me.cgrand.net/2010/04/02/pipe-dreams-are-not-necessarily-made-of-promises/ |
| 19:01 | raek | flying_rhino: of course! |
| 19:01 | raek | http://clj-me.cgrand.net/2009/11/18/are-pipe-dreams-made-of-promises/ |
| 19:01 | flying_rhino | coz there are places where I might want to use some mutability and threads for some stuff (not a lot of stuff ofcourse) |
| 19:02 | raek | (let [t (Thread. (fn [] ...some code...))] (.start t)) |
| 19:02 | raek | flying_rhino: you could also use Clojure's thread safe mutation primitives (refs, atoms, etc)... :) |
| 19:03 | flying_rhino | good to know |
| 19:03 | raek | (future ...some code...) |
| 19:04 | DaReaper5 | ok ill fiure out the usage late but i think i can do a hash map of blocking queue which the long polling method request/take from. |
| 19:04 | DaReaper5 | later* |
| 19:04 | DaReaper5 | queues* |
| 19:04 | raek | flying_rhino: some Clojure features assume that certain expression don't have side-effects, though. this is usually clear from the documentation. |
| 19:04 | flying_rhino | I know |
| 19:05 | flying_rhino | basically strict functional programming is a little too hardcore for me. |
| 19:38 | ChongLi | flying_rhino: you ought to watch SICP |
| 19:38 | ChongLi | it'll change your perspective |
| 19:38 | flying_rhino | why? |
| 19:38 | clojurebot | why is the ram gone is <reply>I blame UTF-16. http://www.tumblr.com/tagged/but-why-is-the-ram-gone |
| 19:39 | ChongLi | then you'll start looking at imperative programming as this scary, weird thing |
| 19:39 | amalloy | watch it? read it |
| 19:39 | flying_rhino | links? |
| 19:39 | ChongLi | amalloy: the lectures are essential IMO |
| 19:39 | amalloy | i mean, i haven't watched it, so maybe the recording is really great. but i imagine you want the book as well |
| 19:39 | amalloy | $google sicp |
| 19:39 | lazybot | [Welcome to the SICP Web Site] http://mitpress.mit.edu/sicp/ |
| 19:40 | amalloy | $google sicp lectures |
| 19:40 | lazybot | [Structure and Interpretation of Computer Programs, Video Lectures] http://groups.csail.mit.edu/mac/classes/6.001/abelson-sussman-lectures/ |
| 19:40 | ChongLi | http://www.youtube.com/course?list=ECE18841CABEA24090\ |
| 19:40 | ChongLi | err |
| 19:40 | flying_rhino | thanks |
| 19:40 | ChongLi | http://www.youtube.com/course?list=ECE18841CABEA24090 |
| 19:42 | ChongLi | I especially enjoy the lecture where Gerald Sussman dresses up and writes the evaluator on the black boards |
| 19:42 | ChongLi | it has a very sentimental quality to it |
| 19:43 | flying_rhino | althought, ChongLi , I am not sure that my ambivalence is entirely due to paranoia. I am planning (for now just planning) to develop RTS game in clojure. Still not sure that it is a good idea. Basicaly games have a lot of changing state so immutability scares me somewhat. |
| 19:43 | ChongLi | the two of them are brilliant lecturers |
| 19:43 | ChongLi | just package your state in one of clojure's reference types |
| 19:44 | ChongLi | and then write a bunch of pure functions on different parts of the game logic |
| 19:45 | flying_rhino | althought real time strategies appear real time they are in fact turn based but turn expires quickly. I plan to have turn last 0.25 . |
| 19:45 | flying_rhino | So I generate new state every 0.25 seconds. |
| 19:45 | ChongLi | you might even consider using streams (lazy seqs in clojure) to represent the game as a series of instants in time |
| 19:46 | flying_rhino | basically different subsistems in game have to assemble new state every 0.25 seconds |
| 19:46 | ChongLi | every real-time game works like that AFAIK |
| 19:46 | ChongLi | I'm not aware of any continuous time games |
| 19:46 | ChongLi | SICP will teach you a different way of looking at a problem |
| 19:47 | ChongLi | not as decomposing something into a tree of specialized parts |
| 19:47 | ChongLi | but as a stack of successive layers of abstraction |
| 19:47 | flying_rhino | I dunno but what I want is easier to do than say shotter that has new state every 0.03 sec or some such. |
| 19:52 | ChongLi | flying_rhino: may I ask why you chose clojure for writing a game? |
| 19:54 | flying_rhino | I like lisp because I like macros as abstraction tools and code as data thingy is intriguing (and makes sense to me). I like Java as a platform (althought I havent done any Java programming in ages). Lisp + JVM seems like nice combo. |
| 19:55 | flying_rhino | I also want to see if it is acheivable (I mean game in lisp) |
| 19:55 | ChongLi | I see no reason why not |
| 19:55 | ChongLi | it all depends on what sort of performance demands you have |
| 19:55 | flying_rhino | performance IS concern |
| 19:56 | ChongLi | if you use lwjgl you can shift most of the burden onto the GPU |
| 19:58 | flying_rhino | I'll go with client server architecture with clojure as server (if I pick clojure). There is panda3d graphic engine at client side. |
| 19:59 | flying_rhino | panda3d is engine written in c++ and has nice python interface. I'll probably make very thin client in python. Almost all calculations will happen on server. |
| 19:59 | flying_rhino | so I don't have to worry about graphic card and stuff. |
| 20:00 | flying_rhino | I hope clojure has decent performance with multicore (that's kind of a point of immutability, right?) |
| 20:01 | flying_rhino | well at least that's a plan |
| 20:01 | flying_rhino | *the plan |
| 20:02 | flying_rhino | any objections to the plan? |
| 20:04 | flying_rhino | I'll take look at SICP, by the way |
| 20:04 | flying_rhino | thanks |
| 20:06 | ChongLi | hey |
| 20:06 | ChongLi | why python? |
| 20:07 | ChongLi | I think you're likely to get better performance out of clojure than python (unless you're calling only C libs from python) |
| 20:08 | flying_rhino | because panda3d only has python interface. And it won't do anything other than read stuff server send and tell panda3d to draw it. Server will do almost all the work. |
| 20:08 | flying_rhino | I might choose different 3d engine but panda3d is very easy to use. |
| 20:08 | ChongLi | ah |
| 20:09 | flying_rhino | I doubt python will turn out to be a bottleneck here |
| 20:09 | flying_rhino | but you never know |
| 20:10 | flying_rhino | but if you know engine with java bindings, let me know. |
| 20:11 | ChongLi | well there's lwjgl (which is what minecraft was written for) |
| 20:11 | flying_rhino | will take a look |
| 20:11 | flying_rhino | ultimately graphic is lesser concern |
| 20:11 | ChongLi | but it's mostly a raw library for doing opengl and input |
| 20:11 | flying_rhino | at first it will be 2d anyway |
| 20:12 | flying_rhino | 3d isn't integral to anything |
| 20:12 | ChongLi | opengl is still good for 2D drawing |
| 20:14 | flying_rhino | well I first I'll proabably stick to java native drawing tools, provided those don't completely suck. |
| 20:14 | flying_rhino | *at first |
| 20:16 | Sgeo | JNA's Pointer docs has this |
| 20:16 | Sgeo | "Create from native pointer. Don't use this unless you know what you're doing." |
| 20:16 | Sgeo | For the Pointer constructor |
| 20:17 | Sgeo | But then in that case, if a JNAerated function takes a pointer, how do I pass one to it? |
| 20:17 | flying_rhino | ChongLi: anyway thanks for your advice |
| 20:18 | ChongLi | flying_rhino: no problem |
| 20:18 | ChongLi | I think a lot of people are rediscovering SICP these days |
| 20:18 | ChongLi | since a few articles about it have been posted on reddit/HN |
| 20:38 | yedi | so i'm still tryna wrap my mind around functional programming |
| 20:39 | ChongLi | need some help? |
| 20:39 | yedi | how would I print every other element in a list if I was looping through it with doseq? |
| 20:39 | yedi | i could use let to bind a variable and just increment it |
| 20:39 | yedi | but it seems like the imperative way to go about it |
| 20:39 | ChongLi | yeah |
| 20:39 | amalloy | &(take-nth 2 (range 10)) |
| 20:39 | lazybot | ⇒ (0 2 4 6 8) |
| 20:40 | ChongLi | amalloy has the right idea |
| 20:40 | ChongLi | seqs are meant for stream processing |
| 20:40 | Sgeo | ,(doc take-nth) |
| 20:40 | clojurebot | "([n coll]); Returns a lazy seq of every nth item in coll." |
| 20:40 | yedi | take-nth seems like itll be handy |
| 20:40 | amalloy | the idea, as usual, is not to think about doing it "in doseq", but instead think of a way to transform the data non-mutably and then as a last step throw that into a doseq if for some reason you need to |
| 20:40 | Sgeo | That's a weird name for that idea. |
| 20:41 | ChongLi | Sgeo: what is? |
| 20:41 | Sgeo | take-nth. It's ... hmm |
| 20:42 | yedi | thanks guys |
| 20:42 | yedi | amalloy: that's a good way to think about it |
| 20:42 | ChongLi | yedi: stream processing is all about composing producers (such as range) with maps, filters and accumulators |
| 20:42 | wingy_ | FP is so sweet |
| 20:43 | ChongLi | the topic is covered quite well in SICP |
| 20:45 | yedi | if only I realized how interesting/seemingly intelligent FP was when I was doing my first programming class which used scheme |
| 20:46 | ChongLi | it can be a lot to take in |
| 20:47 | yedi | for mac users: nrepl in emacs uses ctrl-up and ctrl-down to go through the repl history, but mac uses that key combination to do os related stuff |
| 20:47 | yedi | how do you get around that |
| 20:48 | ChongLi | I use M-p M-n |
| 20:49 | ChongLi | it is really nice in that you can type a bit and use those keys to search history |
| 20:49 | ivan | I use up/down |
| 21:00 | yedi | i'm getting this error when i try to count the lines in a file: https://gist.github.com/4092610 |
| 21:02 | ChongLi | sounds like the lazy IO bugaboo |
| 21:04 | Sgeo | Can we just take line-seq out into a shed and burn it? |
| 21:04 | Sgeo | Or at least slap a large warning label on it? |
| 21:05 | yedi | Sgeo: what would a better alternative be for reading lines in from a file? |
| 21:05 | Sgeo | yedi, something that isn't lazy |
| 21:05 | Sgeo | Erm, I mean, hi. |
| 21:06 | ivan | something that closes the file when you reach the end and otherwise leaks |
| 21:06 | ivan | just set your fd limit really high ;) |
| 21:06 | yedi | fd limit? |
| 21:06 | ChongLi | file descriptors |
| 21:07 | Sgeo | yedi, what's going on is that line-seq isn't reading lines until they're requested |
| 21:07 | ivan | unlimit -n The maximum number of open file descriptors (most systems do not allow this value to be set) |
| 21:07 | yedi | right, aka lazy |
| 21:07 | Sgeo | They're not requested until count |
| 21:07 | ChongLi | and if the file is closed |
| 21:07 | ChongLi | they won't be able to be read |
| 21:07 | ChongLi | and an exception is thrown |
| 21:09 | yedi | so after parse-lines returns, the file closes? |
| 21:09 | ChongLi | same problem occurs in haskell (or any language where you're doing lazy stream processing with IO) |
| 21:09 | ChongLi | yeah |
| 21:09 | yedi | so I can't actually access any of those lines |
| 21:09 | yedi | i'd have to load them into memory? |
| 21:09 | Sgeo | After the with-open returns |
| 21:09 | ChongLi | or print your count inside with-open |
| 21:10 | Sgeo | Put a doall inside the with-open somewhere, that will load them into memory |
| 21:10 | yedi | is there a non lazy version of line-seq? |
| 21:10 | yedi | ah |
| 21:10 | Sgeo | (comp doall line-seq) should be non lazy |
| 21:10 | yedi | *checking with doall does* |
| 21:11 | Sgeo | (doc doall) |
| 21:11 | clojurebot | "([coll] [n coll]); When lazy sequences are produced via functions that have side effects, any effects other than those needed to produce the first element in the seq do not occur until the seq is consumed. doall can be used to force any effects. Walks through the successive nexts of the seq, retains the head and returns it, thus causing the entire seq to reside in memory at one time." |
| 21:11 | ChongLi | keep in mind though |
| 21:11 | Sgeo | Or you could do count inside with-open |
| 21:11 | ChongLi | that if your file is really big |
| 21:11 | ivan | maybe someone should write a lazy-line-slurper that works with file paths and closes/reopens fds as needed |
| 21:11 | ChongLi | you may not want it all in memory |
| 21:12 | yedi | right ChongLi |
| 21:12 | Sgeo | Someone should port the ResourceT stuff from Haskell into Clojure. |
| 21:12 | Sgeo | Well, not an exact port, that uses monads. |
| 21:12 | ChongLi | another solution might be iteratees |
| 21:14 | Sgeo | Clojure can kind of sort of fake some common monads. |
| 21:14 | Sgeo | (Idiomatically in everyday code not deliberately using monads, I mean) |
| 21:17 | gfredericks | is the IO monad impossible? does that require pervasive laziness? |
| 21:18 | gfredericks | or maybe it is just thunks that do IO... |
| 21:19 | ChongLi | I thought the real barrier to monads in clojure was the lack of return type polymorphism |
| 21:20 | ChongLi | the inability to write a function whose type is a -> m a |
| 21:20 | Sgeo | IO monad is not related to laziness |
| 21:20 | Sgeo | In Haskell or Clojure |
| 21:23 | gfredericks | Sgeo: I had the idea when I tried to think about implementing an IO monad with the motivating thought being that an IO a is a description of how to obtain an a. If I tried to imagine that as a data structure then I started thinking the data structure had to be lazy |
| 21:23 | gfredericks | but now I can't reconvince myself of it |
| 21:24 | Sgeo | Hint: There exists a data structure in both Haskell and Clojure, but one of the differences of the two is that Haskell's version of that structure is more restrictive. |
| 21:25 | Sgeo | ^^being slightly obtuse |
| 21:25 | gfredericks | "a data structure"? is there a mystery data structure that you're trying to get me to identify? |
| 21:26 | Sgeo | Yes. Although I guess you might not call it a data structure. |
| 21:26 | Sgeo | But it's an item you can pass around and return from stuff. |
| 21:26 | gfredericks | undefined? |
| 21:27 | Sgeo | It exists in Clojure but not in Java. In Java there are annoying workarounds for it not existing. |
| 21:27 | gfredericks | a function? :) |
| 21:27 | Sgeo | Yes. |
| 21:27 | Sgeo | :) |
| 21:27 | gfredericks | and an IO a is essentially an () -> a? |
| 21:28 | gfredericks | er |
| 21:28 | gfredericks | I'm not sure that communicated by thought :/ |
| 21:28 | gfredericks | s/by/my/ |
| 21:28 | Sgeo | An IO a can be represented in a non-functionally-pure language with a zero argument function. |
| 21:29 | gfredericks | yeah that's what I was going for |
| 21:29 | Sgeo | That trick doesn't work in Haskell, since functions themselves aren't supposed to do impure stuff like I/O |
| 21:29 | gfredericks | and that's why I was having trouble communicating it :) |
| 21:31 | ChongLi | unsafePerformIO |
| 21:32 | Sgeo | I did say "supposed" |
| 21:32 | ChongLi | it's actually used in a bunch of libraries |
| 21:32 | Sgeo | But ideally those libraries expose a purely functional interface |
| 21:32 | gfredericks | what sorts? |
| 21:33 | ChongLi | it's often used as a hack |
| 21:33 | gfredericks | randomized algorithms? |
| 21:34 | ChongLi | that'd violate referential transparency |
| 21:34 | gfredericks | e.g. quicksort |
| 21:35 | ChongLi | they're more commonly used in doing some mutable stuff before freezing an immutable data structure |
| 21:35 | ChongLi | similar to clojure's transients |
| 21:37 | gfredericks | I guess the only legitimate use should be for performance? |
| 21:37 | ChongLi | nah, there's other uses |
| 21:38 | ChongLi | memoization for one |
| 21:38 | Sgeo | unamb |
| 21:38 | Sgeo | ? |
| 21:38 | ChongLi | I guess that's performance related too |
| 21:40 | gfredericks | this is weird stuff. |
| 21:40 | ChongLi | conal elliott is way above my head |
| 21:58 | ForSpareParts | Is there a good way to prevent my nrepl from dying when I kill a window I created from it with Java interop stuff? Do I need to start a new thread, or...? |
| 22:13 | amalloy | don't set EXIT_ON_CLOSE on your window :P |
| 22:13 | ForSpareParts | amalloy, Ah. That would do it. |
| 22:41 | TimMc | clojurebot: hello |
| 22:41 | clojurebot | BUENOS DING DONG DIDDLY DIOS, fRaUline TimMc |
| 22:41 | TimMc | :-) |
| 22:57 | LesZedCB | hello! |
| 23:24 | mholmqvist | hi, I'm having some issues with the reader literals for records, anyone who can try to help a bit? |
| 23:25 | shachaf | I don't know anything about Clojure, but I bet you could get more people who can help you by asking your question. |
| 23:25 | shachaf | (As opposed to not asking it.) |
| 23:27 | Raynes | ~anyone |
| 23:27 | clojurebot | Just a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..." |
| 23:27 | mholmqvist | trying to serialize a record with a jodatime DateTime instance as one of the fields. I cannot get the reader to read the record after serializing it... |
| 23:28 | mholmqvist | the field looks like :timestamp #<DateTime 2012-11-17T04:17:43.675Z> |
| 23:28 | mholmqvist | and if I try with a map instead of a record it works fine and the value in the map is then :timestamp #=(org.joda.time.DateTime. 1353125863675) |
| 23:29 | mholmqvist | with #= instead of #< |
| 23:30 | mholmqvist | this causes an "Unreadable form" error in the record case |
| 23:31 | TimMc | Yeah, #<...> is never readable. |
| 23:31 | mholmqvist | that's what I thought... |
| 23:31 | TimMc | #=(...) is reader-eval syntax, which is enabled iff *read-eval* is bound to true. |
| 23:32 | TimMc | ,(read-string "#=(the bot says nice try)") |
| 23:32 | clojurebot | #<RuntimeException java.lang.RuntimeException: EvalReader not allowed when *read-eval* is false.> |
| 23:33 | TimMc | None of this deals with reader literals, by the way. |
| 23:34 | mholmqvist | yeah right, sorry about the bad question. :) |
| 23:35 | mholmqvist | ok, so how can I serialize a record and read it on the other end? including the fields? |
| 23:35 | TimMc | Hmm, that sounds like a bug to me. |
| 23:36 | TimMc | (read-string "#clj.core.MyRecord{:a #=(+ 1 2), :b 2}") does what I'd expect, so it's not that the printer is avoiding doing something the reader can't handle... |
| 23:40 | mholmqvist | well, if I do (pr-str (into {} my-record-instance)) I get "#=(clojure.lang.PersistentArrayMap/create {:timestamp #=(org.joda.time.DateTime. 1353126954623)}" |
| 23:41 | mholmqvist | and if I just do (pr-str my-record-instance) I get " #MyRecord[#<DateTime 2012-11-17T04:38:24.877Z>]" |
| 23:42 | mholmqvist | so putting everything in a map works better, but I guess I'm doing something fundamentally wrong? |
| 23:43 | amalloy | sounds like you're on some nutso version of clojure, perhaps? records don't print like that on 1.4.0 |
| 23:43 | mholmqvist | hm…only included 1.4.0 |
| 23:44 | amalloy | https://www.refheap.com/paste/6782 |
| 23:44 | TimMc | amalloy: They do with *print-dup* true on 1.3.0. |
| 23:44 | amalloy | ugh print-dup |
| 23:44 | amalloy | don't use it |
| 23:45 | amalloy | but you're right, it looks like print-dup is true for him |
| 23:45 | TimMc | https://www.refheap.com/paste/6783 |
| 23:45 | mholmqvist | is print-dup deprecated? |
| 23:46 | TimMc | I was using print-dup to get a #= in my output. |
| 23:47 | TimMc | (Array-map, since I don't have Joda Time in that project.) |
| 23:47 | amalloy | mholmqvist: not as far as i know, but it's rubbish |
| 23:47 | mholmqvist | TimMc: right. |
| 23:48 | mholmqvist | amalloy: how can I do it any other way? |
| 23:48 | mholmqvist | get something like joda DateTime in the record? |
| 23:48 | amalloy | just use pr-str, without print-dup |
| 23:48 | TimMc | amalloy: You object to the use of #=, or something else about print-dup? |
| 23:49 | Sgeo | What's *print-dup*? |
| 23:49 | Sgeo | (doc *print-dup*) |
| 23:49 | clojurebot | "; When set to logical true, objects will be printed in a way that preserves their type when read in later. Defaults to false." |
| 23:50 | amalloy | #= is not my actual objection, but is inextricably bound up in it. the objection is that each java object (or deftype) that wants to be printable with print-dup has a totally isolated part of its code responsible for printing it, which outputs a non-compiler-checkable string that has implicit dependencies on the rest of the file |
| 23:51 | amalloy | what will happen (and *does* happen in clojure.lang) is that data structures evolve, and their print-dup implementations don't change, so that calling print-dup on an object produces a string that is basically rubbish |
| 23:51 | mholmqvist | amalloy: just noticed I was using print-dup |
| 23:52 | mholmqvist | using pr-str gives "MyRecord{:timestamp #<DateTime 2012-11-17T04:47:14.25}" |
| 23:52 | Sgeo | amalloy, write about it on clojuredocs? |
| 23:52 | mholmqvist | with the # |
| 23:52 | mholmqvist | "#MyRecord{:timestamp #<DateTime 2012-11-17T04:47:14.25}" |
| 23:52 | amalloy | feel free, bro. i don't use clojuredocs |
| 23:52 | mholmqvist | but still "Unreadable form" on the reader side... |
| 23:54 | mholmqvist | amalloy: now working! |
| 23:56 | mholmqvist | missing binding of print-dup. thanks TimMc for the refheaps! |
| 23:56 | mholmqvist | amalloy: |
| 23:56 | mholmqvist | amalloy: is it possible to do in any other way? |
| 23:57 | amalloy | of course. clojure is turing-complete; you can write your own version of printing based purely on the lambda calculus. but that's not very interesting, and why would you when you already have a six-character function (pr-str) that does exactly what you want? |
| 23:59 | Sgeo | Turing-complete does not imply being able to do anything. If you take Brainf*** and remove . you can't write to the screen. |
| 23:59 | TimMc | amalloy: It sounds like the problem is that pr-str by itself produces a #<...> form, which is unreadable. |
| 23:59 | Sgeo | (And BF would still be TC) |
| 23:59 | mholmqvist | yeah I have no problem using that function. I was just curious since you said it was rubbish. :) |
| 23:59 | amalloy | no, print-dup is rubbish |
| 23:59 | TimMc | Maybe the solution actually is reader literals and print-method. |
| 23:59 | mholmqvist | TimMc: that's my impression also |
| 23:59 | TimMc | amalloy: ... |
| 23:59 | amalloy | TimMc: no, he solved it by not binding *print-dup* |