2011-05-20
| 00:00 | dnolen | zakwilson: the bad experiences w/ Clojure seems generally low - if they exist they're always of the obvious variety - "too many parens!" |
| 00:01 | zakwilson | I'm not new to Clojure, but I haven't used it for a customer project yet. Parens don't bother me. If I'm going to complain about something, it's the lack of user-defined reader macros. |
| 00:02 | dnolen | zakwilson: seems like a minor nit, a good overall design choice. |
| 00:02 | zakwilson | And maybe that exceptions feel too Java-ish (I'd rather have conditions that don't unwind the stack) |
| 00:03 | dnolen | zakwilson: but do conditions make sense w/ interop? |
| 00:03 | zakwilson | Not sure. Somebody did them as a library, and I haven't actually tried using it. |
| 00:03 | amalloy | dnolen: it sounds like that's not an issue for him, since he says jvm isn't a requirement |
| 00:03 | amalloy | zakwilson: cc.condition is not recommended, is my understanding |
| 00:04 | amalloy | core team really want a better exception/error system but afaik haven't figured out a good way to make it happen yet |
| 00:04 | zakwilson | Actually, the one I remembered was cc.error-kit |
| 00:04 | dnolen | zakwilson: so you would leverage Java libs in this project? |
| 00:04 | dnolen | s/would/wouldn't |
| 00:04 | sexpbot | <dnolen> zakwilson: so you wouldn't leverage Java libs in this project? |
| 00:05 | zakwilson | I can't say that I won't. I will prefer Clojure libs or wrapped Java libs, but I'm sure there will be a bit of interop here and there. |
| 00:06 | zakwilson | I'm just saying, there's no reason I couldn't do it in a language that isn't hosted on the JVM. |
| 00:06 | dnolen | zakwilson: so who are the competitiors? CL? Racket? Haskell? |
| 00:07 | zakwilson | RoR is the main competition. I'm sure that will be easier at first, but I suspect Clojure will provide more flexibility later on. |
| 00:07 | dnolen | zakwilson: so it's website w/ templates and all that? |
| 00:08 | zakwilson | Yes. CRUD app with sugar on top. |
| 00:08 | dnolen | zakwilson: for a full blown website w/ templates, ORM, I don't really think Clojure competes much, but I think it depends on project timeline. |
| 00:09 | dnolen | If the competition was say ... Sinatra, I would say Clojure 100% |
| 00:09 | zakwilson | ORM isn't a requirement, and I kinda don't like ORM. ClojureQL seems like a nicer compromise between writing SQL by hand and ORM. |
| 00:11 | dnolen | zakwilson: My point is simply that if you want RoR convenience - Clojure ain't there yet. If you understand that RoR convenience is actually a low ceiling, then yes Clojure is attractive. |
| 00:12 | zakwilson | Isn't that what I said when I mentioned RoR? |
| 00:15 | dnolen | zakwilson: heh, you did. But it's hard to make any kind of judgment w/o any understanding of project scope. Rails is now a somewhat shared domain of understanding. Clojure not so much. |
| 00:16 | zakwilson | I know. I was mostly looking for any known big problems. I've done a website with similar scope in CL before and did run in to trouble, namely that SBCL had issues with the virtualization used by some VPS hosts. |
| 00:20 | dnolen | zakwilson: perhaps others can chime in about JDK differences between platforms, there's been some mutter about it in the past, but not at the level of SBCL issues I think. |
| 00:21 | zakwilson | I don't forsee that sort of deployment difficulty with Clojure, and as platforms go, I'm hoping to do all development and production on Debianoids of some sort. |
| 00:24 | dnolen | zakwilson: well, I do RoR at work, and my experience is that most of what I do would be simpler, shorter, and faster in Clojure. |
| 00:24 | zakwilson | That has been my experience with non-trivial RoR as well. You have failed to talk me out of Clojure. Good job. |
| 00:26 | tomoj | zakwilson: so, pallet, chef, or..? |
| 00:28 | zakwilson | I'm honestly not familiar with either of them. |
| 00:30 | zakwilson | A quick look gives me the general idea of pallet. That sounds potentially useful for a project still on the drawing board. |
| 00:37 | nathanmarz | tomoj zakwilson: i'm a big fan of pallet. i use it for a lot of stuff |
| 00:40 | tomoj | guess I should try doing what chef does now with pallet |
| 00:40 | tomoj | always felt it would be better in clojure |
| 00:41 | nathanmarz | it has a learning curve, but is worth it |
| 00:41 | nathanmarz | and hugod is very helpful |
| 00:43 | tomoj | nathanmarz: was it you who pointed me to the bixo list? |
| 00:46 | nathanmarz | i don't remember |
| 01:11 | amalloy | seancorfield: we've added some new features to make it impossible for you to ever take your eyes off 4clojure |
| 01:12 | seancorfield | uh-oh |
| 01:12 | seancorfield | i've managed to get some work done over the last couple of weeks... |
| 01:12 | amalloy | i guess you're following @4clojure so you knew that already though |
| 01:16 | amac | whenever I try to jar my project with lein it blows away my lib and re-fetches the deps -- but in the process wipes out the mysql-connector.jar file I need in there. Is there a way to tell lein that this file is friendly and shouldn't be removed? |
| 01:17 | raek | amac: yes, there is an option you can add to the project.clj file (see the sample project.clj in the leiningen github repo) |
| 01:18 | symbole | Is it possible to force an evaluation of a macro parameter during macroexpansion time, i.e., outside a backquote? |
| 01:19 | raek | amac: also, I'm fairly certain that mysql-connector is in some maven repo (unless you need a homebrew version) |
| 01:19 | amac | I don't need a homebrew, I just couldn't find where it was hosted |
| 01:19 | raek | http://jarvana.com/ <-- good site for searching in maven repos |
| 01:20 | raek | http://jarvana.com/jarvana/archive-details/mysql/mysql-connector-java/5.1.14/mysql-connector-java-5.1.14.jar |
| 01:21 | amac | sweet |
| 01:21 | amac | thanks for that |
| 01:21 | amac | also; :disable-implicit-clean true did the trick |
| 01:21 | amac | :) |
| 01:21 | seancorfield | amalloy: actually i filtered out 4clojure because of all the annoying tweets about how xyz solved a problem :) |
| 01:22 | seancorfield | btw, Leagues links to http://4clojure.com/login/update is that intentional? |
| 01:22 | amalloy | yeah, the leagues page is kinda lame |
| 01:23 | amalloy | i wanted to add a new link so people would know the feature exists |
| 01:23 | seancorfield | i've slipped to 48th... *sigh* ...i guess i need to start solving puzzles again at some point :( |
| 01:24 | amalloy | seancorfield: incidenally, you can follow @4clojure (the user, not the hashtag) to get only meaningful site updates. plus, we started using the #clojure tag at most once an hour, so you can't get annoying floods all at once |
| 01:29 | seancorfield | i'm off to amit rathore's day of clojure macros training on saturday :) |
| 01:29 | seancorfield | should be fun |
| 01:30 | seancorfield | and right now, i'm off to... bed! g'nite |
| 01:30 | amalloy | ah, enjoy |
| 01:33 | technomancy | amac: you can try "lein search" in the latest git |
| 01:33 | technomancy | git lein |
| 01:35 | amac | technomancy: neat |
| 01:48 | desertman | hi, i am trying to get compore running (this is on cygwin) , following https://github.com/weavejester/compojure/wiki/Getting-Started, I added to prj file, then lein clean, lein deps, and lein ring server, , get class exception for compojure.core |
| 01:55 | amalloy | desertman: on the information provided it all sounds fine, but not much information has been provided. gist up your error message and/or your project.clj and/or the code you're using, and maybe someone can help |
| 02:18 | desertman | this is my compojure issue : https://gist.github.com/982438 |
| 02:20 | raek | desertman: you have your :use clause outside the ns form |
| 02:21 | desertman | ok, thnks |
| 02:21 | raek | since ns is a macro, it defines new meaning to the (:use compojure.core) code |
| 02:22 | raek | using the normal clojure evaluation rules, it means "look up the :use key in compojure.core", where compojure.core is a class name literal |
| 02:22 | raek | and there is no java class with the name compojure.core, hence the error |
| 02:22 | amalloy | same for the :require clause, btw |
| 02:24 | raek | if you just remove the right paren at the end of line 21, it should be fine |
| 02:42 | amalloy | raek: it's surprising how many beginners can fix their problem by removing some parens :). see, lisp's not that bad |
| 06:14 | clgv | what is the easiest way to store clojure data structures in a file for later reading and analysing? |
| 06:20 | fliebel | clgv: JSON? Or just… clojure, if it's safe data. |
| 06:20 | clgv | fliebel: just found amalloys blog entry about using pr or pr-str |
| 06:20 | fliebel | right :) |
| 06:20 | raek | clgv: (spit file (pr-str x)) or (binding [*out* (clojure.java.io/writer file)] (pr x)) |
| 06:22 | raek | the latter is problably better, since it won't make one huge string for the whole value |
| 06:22 | clgv | thx, raek |
| 06:23 | raek | ("file" can be a filename as a string or a java.io.File (a file path object), among other things. look at this page for more info on that: http://clojuredocs.org/clojure_core/clojure.java.io) |
| 06:25 | raek | the reverse would then be (read-string (slurp file)) or (binding [*in* (clojure.java.io/reader file)] (read)) |
| 07:55 | patsp | Hi, have anyone already read the 4clojure.com problem "Graph Tour"? I don't understand why the second testcase should be false. Can anyone explain? |
| 07:59 | clgv | patsp: I think you can remove the double edges since you can visit one and return on the other |
| 08:00 | clgv | patsp: if you do that you have a graph were only one edge remains from d to each of the other nodes |
| 08:01 | clgv | patsp: so there is no possibility to use all of them, since you will get stuck in one of the 3 nodes (a, b or c) and you wont be able to visit the last remaining one |
| 08:03 | clgv | patsp: I think I remember a rules that states a necessary criterion for such an euler tour but quoting that one would spoil you the fun of solving the problem ;) |
| 08:03 | patsp | but the path a->c->d->b->a->d visits all edges |
| 08:04 | patsp | and I don't think that we should find a tour but a path because otherwise the first testcase is wrong |
| 08:04 | clgv | patsp: no it does not! there are two remaining edges [a b] and [a c] that you did not include |
| 08:05 | clgv | patsp: the spedicifation as a clojure set might be the error in the problem test cases |
| 08:05 | patsp | but the edges are representet as a set --> double edges are not possible |
| 08:05 | patsp | yes exactly |
| 08:06 | clgv | they use a set but mean to have more than one edge per node pair |
| 08:06 | patsp | ok, then it's clear, thx |
| 08:07 | clgv | maybe you have to write them if you cant get that problem solved due to this error |
| 08:08 | patsp | do you think an issue on github would be appropriate, or just email? |
| 08:35 | patsp | Just a note to my previous conversation: now the testcases for the 4clojure.com problem "Graph Tour" are correct. |
| 08:45 | wastrel | /win 19 |
| 09:34 | gfrlog | okay so |
| 09:34 | gfrlog | if I want a (doall) that works on arbitrarily nested structures |
| 09:35 | gfrlog | i.e., ensure that nothing in my object is unevaluated |
| 09:35 | gfrlog | is my best bet to combine (doall) with something from (clojure.walk)? |
| 09:35 | gfrlog | or does this already exist? |
| 09:35 | chouser | hm |
| 09:36 | chouser | you don't really care about the return value, since you can just use the original objects |
| 09:36 | chouser | so I think you could use tree-seq instead, if you wanted |
| 09:36 | raek | I recall that someone made such a function |
| 09:36 | gfrlog | ,(doc tree-seq) |
| 09:36 | clojurebot | "([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). children must be a fn of one arg that returns a sequence of the children. Will only be called on nodes for which branch? returns true. Root is the root node of the tree." |
| 09:37 | raek | gfrlog: btw, what situation led to this problem? |
| 09:37 | gfrlog | raek: I am using Jena |
| 09:37 | gfrlog | um |
| 09:37 | gfrlog | I guess any database could have the same issue |
| 09:37 | gfrlog | I just need to make sure the results are all consumed before closing the connection, essentially |
| 09:38 | gfrlog | the fact that it's jena just explains why I'm not using clojureql or c.c.sql |
| 09:38 | gfrlog | I've got a number of data-access functions I've written, and I'd rather wrap them all in a general-purpose solution than reason through each one and add (doall) as needed |
| 09:39 | raek | if you have control over the code that builds the data structure, then one possibility is to let it call doall on all lazy-seqs it puts in the data structure |
| 09:40 | gfrlog | right |
| 09:40 | gfrlog | that's what I'm hoping to avoid |
| 09:40 | gfrlog | given that my automated tests are not likely to catch this |
| 09:40 | gfrlog | I'm already using a macro to def the data access functions, so adding it at that point seems simplest |
| 09:41 | raek | not likely to catch missing doalls in the generating code? |
| 09:42 | gfrlog | well I could do it if I really focused, but that's rather brittle, especially if I start changing things |
| 09:42 | raek | wouldn't (is (= [1 2 3] (with-... <generate sequence here>))) work |
| 09:42 | gfrlog | for testing you mean? |
| 09:42 | raek | yes |
| 09:43 | stuartsierra | a sequence won't be = to a vector |
| 09:43 | raek | where "with-..." is a macro like "with-open" that closes the connection before it retusn |
| 09:43 | gfrlog | stuartsierra: yes |
| 09:43 | raek | ,(= [1 2 3] '(1 2 3)) |
| 09:43 | clojurebot | true |
| 09:43 | stuartsierra | oops |
| 09:43 | gfrlog | ,(= [1 2 3] (range 1 4)) |
| 09:43 | clojurebot | true |
| 09:43 | gfrlog | stuartsierra: I take back my agreement |
| 09:44 | stuartsierra | I take back my assertion. |
| 09:45 | gfrlog | raek: yes I guess I ought to test for this too :( |
| 09:46 | raek | but laziness and resource management is indeed tricky |
| 09:46 | gfrlog | the trap is built into c.c.sql |
| 09:47 | gfrlog | I'm glad clojureql came along cause I was tired of typing (into [] (with-query-results r [...])) or making ad-hoc utility functions for it |
| 09:47 | gfrlog | also I was tired of not using clojureql |
| 09:48 | raek | if you don't need the random access of the vector, then doall is preferred here, I think |
| 09:49 | gfrlog | oh for c.c.sql? yeah that makes sense. |
| 09:49 | gfrlog | old habit I guess |
| 09:49 | gfrlog | probably saw it somewhere and never decided to think past "it works" |
| 09:51 | raek | in one of my libraries, I provide two variants of a function that parses lines from a socket: one that takes a sequence of lines and returns a lazy-seq of the parsed lines and one that uses the first which also ensures that the sequence is forced and that the stream is closed |
| 09:52 | gfrlog | and next you're going to say that you have a very intuitive way of naming the two? |
| 09:52 | raek | if the user wants to process the lines lazily, then he can use the low-level one and do the resource management himself |
| 09:53 | raek | the naming is always the trickiest part :-) |
| 09:53 | gfrlog | parse-lines and parse-lines~ |
| 09:53 | raek | I called them "directory-seq" and "read-directory", I think |
| 09:54 | raek | the first one in analogy to "line-seq" |
| 09:55 | gfrlog | that seems good |
| 09:56 | raek | I think I considered "fetch-directory" for the second one. I looked for a word that implies that you get the whole thing at once |
| 09:56 | gfrlog | injest? |
| 09:56 | gfrlog | devour? |
| 09:56 | Fossi | gulp ;D |
| 09:57 | gfrlog | slurp |
| 09:57 | cemerick | jeez, what a shit-storm on the ML |
| 09:58 | cemerick | I guess we were due |
| 09:58 | stuartsierra | now what? |
| 09:58 | raek | heh. "slurp" is not that bad... it has the right connotations if you are used to clojure.core/slurp |
| 09:59 | TimMc | slurp-dir? |
| 09:59 | Fossi | cemerick: got an archive link? |
| 10:00 | cemerick | http://groups.google.com/group/clojure/browse_frm/thread/f97699164e9be29e I gues |
| 10:00 | cemerick | guess* |
| 10:00 | Fossi | thanks |
| 10:02 | Fossi | ah, that thing again |
| 10:02 | edw | technomancy: You around? |
| 10:03 | TimMc | cemerick: Oh, "Mailing List". I kept looking for ML-the-language stuff. >_< |
| 10:03 | cemerick | Fossi: Just a vessel for everyone's particular gripes. |
| 10:03 | Fossi | yes |
| 10:03 | Fossi | got the same feeling from that last discussion |
| 10:04 | cemerick | TimMc: yeah, damn that ML shit-storm. Stupid language anyway! |
| 10:04 | cemerick | ;-) |
| 10:04 | Fossi | kinda peintless as well |
| 10:04 | Fossi | *o |
| 10:04 | cemerick | Fossi: which means it's a shoe-in for a 100-message thread |
| 10:06 | Fossi | having some experience with clojure in a java environment with lots of smart people all i can say is: lisp is not for everybody ;) |
| 10:06 | edw | Fossi: I have trouble believing that. |
| 10:06 | Fossi | the ide won't be the major problem |
| 10:07 | TimMc | Fossi: And tehrefore is doomed to never have widespread acceptance? |
| 10:07 | gfrlog | Fossi: what about people who learn FP before OOP? |
| 10:07 | Fossi | and it's still *way* harder to get a customer let you use anything but plain java anyway |
| 10:07 | Fossi | at least it's a possibility |
| 10:07 | TimMc | Fossi: Why should they care what's in the JAR? |
| 10:07 | gfrlog | somebody write a clojure-to-java translator |
| 10:08 | Fossi | i don't necessarily believe in unlimited growth |
| 10:08 | edw | Fossi: Lisp with an IDE that lacks a REPL sort of misses the point. Lisp is different from what most people know. *Un*learning is the most important part of transitioning people to a Lisp. |
| 10:08 | Fossi | TimMc: because they pay and own the code |
| 10:08 | TimMc | Oh, that kind of customer. |
| 10:08 | Fossi | and they want to have at least the illusion of taking it somewhere else |
| 10:09 | Fossi | *being able |
| 10:09 | edw | Fossi: Just say, "I'll deliver a jar with source." |
| 10:09 | TimMc | heh |
| 10:09 | Fossi | won't cut it |
| 10:09 | gfrlog | linguistic tricks are the best way to get referrals |
| 10:09 | TimMc | I don't see why any competant dev couldn't learn Clojure. |
| 10:09 | TimMc | gfrlog: haha |
| 10:09 | Fossi | at least not with "bigger" ()500+ persondays projects |
| 10:10 | gfrlog | TimMc: once you define "competant" so as to make that a tautology, I agree |
| 10:10 | Fossi | TimMc: well, that's part of the problem |
| 10:10 | Fossi | yes :) |
| 10:10 | edw | In my experience, if you want freedom to use tools that let you be productive, you're best off in an envrionment that isn't a development shop. I work for a marketing agency, and they don't care what I use. |
| 10:10 | Fossi | people are commonly having problems grokking java :) |
| 10:11 | Fossi | edw: well, i guess those aren't the target of the "enterprise integration cloud buzzword" group that typesafe targets |
| 10:12 | gfrlog | on a totally unrelated note, why doesn't (memoize) use soft references? |
| 10:12 | Fossi | that sentence makes no sense whatsoever :) |
| 10:13 | raek | gfrlog: memoization and caches are not the same thing |
| 10:13 | edw | Fossi: The enterprise. Sigh. So sad. |
| 10:14 | Fossi | true |
| 10:14 | Fossi | big moneys though |
| 10:14 | `fogus | gfrlog: That would be rude. ;-) |
| 10:14 | Fossi | and interesting problems too sometimes |
| 10:14 | raek | gfrlog: http://groups.google.com/group/clojure-dev/browse_thread/thread/227859e14deb0d7c/21414bdd6991dec6?lnk=gst&q=memoize#21414bdd6991dec6 |
| 10:14 | gfrlog | raek: thank you sir |
| 10:14 | Fossi | at least when it comes to pure numbers/traffic (me being a web developer ;) ) |
| 10:16 | gfrlog | raek: I guess the next question is why would anybody want to memoize when they could cache? |
| 10:16 | edw | Fossi: There's too much insecurity and arrogance in enterprisey environments. |
| 10:17 | gfrlog | maybe it makes the GC have to think harder? |
| 10:21 | gfrlog | is it strange that (with-open) uses (let) instead of (binding)? |
| 10:22 | TimMc | gfrlog: Because "memoize" sounds like "memorize" as pronounced by the priest from The Princess Bride. |
| 10:22 | TimMc | And "cachify" doesn't. |
| 10:22 | gfrlog | maybe it is not so strange |
| 10:23 | TimMc | Makes sense to me. |
| 10:23 | gfrlog | I just find it unusable with my *model* var |
| 10:37 | TimMc | Oh man, this is going to be interesting. |
| 10:38 | TimMc | I just started full-time at a company with a large-ish Java codebase. How long do you think it will be before I start trying to write Java macros? :-P |
| 10:42 | TimMc | Actually, there is some interest here in rewriting one internal app in Clojure. |
| 10:45 | alandipert | TimMc: do it! |
| 10:45 | TimMc | Well, it's a matter of priorities -- if the app as it currently stands doesn't suck too much to maintain, it's not gonna happen. :-P |
| 10:46 | TimMc | But the CEO and some other higher-ups have LISP background, so it's a definite possibility. |
| 10:48 | TimMc | How does Clojure's licensing interact with commercial products? I notice that core and contrib would be distributed with the product. |
| 10:49 | edw | Do something that actually works and does something useful and show some buiness owner. They'll get a hard-on and will want you to add a few features. Say, "Oh, this little thing? It's something I was working on in my spare time. You'll have to ask my boss to let me spend some more time on it." And then you're off and running... |
| 10:54 | lucian | TimMc: it's EPL afaict, so it shouldn't |
| 10:55 | lucian | TimMc: http://en.wikipedia.org/wiki/Eclipse_Public_License like a weaker LGPL |
| 10:56 | gfrlog | I wrote a bit of code for a blog post the other day and somebody commented asking what the license of the code was :-| |
| 10:56 | gfrlog | never had to think about that before |
| 10:57 | Fossi | hate people licensing javascript with gpl :> |
| 10:57 | TimMc | Fossi: My apologies. |
| 10:57 | edw | And did they complain that you're a willing accomplice to capitalism by not GPL'ing it? |
| 10:57 | `fogus | Related to the memoization dircussion: https://github.com/fogus/unk |
| 10:57 | Fossi | TimMc: huh? :) |
| 10:57 | TimMc | Fossi: I do that a lot. |
| 10:57 | Fossi | it makes no sense |
| 10:57 | Fossi | whatsoever :D |
| 10:57 | lucian | meh, i use GPL when i think it's appropriate. or AL 2.0 otherwise, usually |
| 10:58 | TimMc | It's easy to just slap on "GPL" when I have a random piece of software I want to release. |
| 10:58 | Fossi | even gpl people at the fsfe weren't able to fully grok what that means when i asked |
| 10:58 | lucian | the EPL is kinda braindead, though. it's sad that clojure uses it |
| 10:58 | TimMc | Fossi: What do you think makes the most sense for JS libs? |
| 10:58 | Fossi | dunno, bsd or epl or such |
| 10:58 | lucian | Fossi: i'd say LGPL |
| 10:58 | TimMc | How about LGPL? |
| 10:59 | Fossi | it's better than gps |
| 10:59 | TimMc | I can always relicense my stuff anyway. |
| 10:59 | lucian | no library should use an application license |
| 10:59 | Fossi | but still, what's "linking"? |
| 10:59 | lucian | Fossi: derivative work, same thing |
| 10:59 | Fossi | and what's "you have to distribute the source" |
| 10:59 | lucian | the GPL is enforceable for python just as much as for C, it's been established |
| 10:59 | TimMc | Fossi: That's the easy part. |
| 10:59 | lucian | why would JS be different? |
| 11:00 | Fossi | because you always ship the source to your "customers" |
| 11:00 | lucian | if you ship a runnable version |
| 11:00 | Fossi | and "linking" happens in their browsers |
| 11:00 | lucian | Fossi: not necessarily. it's a derivative work if it's designed to work with that, in the client's browser |
| 11:01 | Fossi | the most common interpretation was that you have to also serve an unminified version |
| 11:01 | Fossi | /unobfuscated |
| 11:01 | lucian | yes, minification counts as obfuscation, which GPL forbids |
| 11:01 | lucian | well, sort of |
| 11:01 | lucian | GPL3 makes it clearer |
| 11:01 | TimMc | Fossi: Oof, forgot about minification. |
| 11:01 | Fossi | it's all not that clear |
| 11:01 | Fossi | so it's a pita :) |
| 11:02 | lucian | it's less of a PITA than a proprietary license |
| 11:03 | Fossi | no, my client has to buy those, if i need them |
| 11:03 | Fossi | that's easy |
| 11:03 | Fossi | but i'm liable if i use something "free" and misuse it |
| 11:03 | TimMc | Hell, how does commercial licensing work with JS? |
| 11:03 | Fossi | at least it's a danger |
| 11:03 | TimMc | copyign and whatnot |
| 11:03 | lucian | TimMc: same as with anything else. most things are easily decompiled |
| 11:03 | Fossi | TimMc: they ship obfuscated personalised versions |
| 11:04 | Fossi | and some phone back |
| 11:04 | lucian | Fossi: but it's not necessarily easier. even if you pay, there's strings |
| 11:04 | Fossi | or only work on specific hostnames |
| 11:04 | lucian | GPL also has strings, seems fairplay to me |
| 11:04 | lucian | wow, that's evil |
| 11:04 | TimMc | No, I mean when a company buys a JS thingy and serves it on their site. |
| 11:04 | Fossi | lucian: yes, but those are mostly clearly defined in some contract |
| 11:05 | lucian | Fossi: again, they're reasonably clearly defined in the license |
| 11:05 | lucian | if in doubt, contact the copyright owner |
| 11:05 | Fossi | yeah, i did so a whole lot, you can believe me :) |
| 11:05 | Fossi | and most people react like TimMc :) |
| 11:05 | lucian | well, it is sad that many people don't understand licensing, or simply don't care |
| 11:06 | Fossi | sometimes it's hard to reach people though |
| 11:06 | Fossi | at least in a timely manner |
| 11:06 | lucian | yes, i know |
| 11:06 | lucian | but we have the advantage of few licenses |
| 11:06 | lucian | GPL is always GPL |
| 11:06 | Fossi | too bad that the js world never concurred to a saner standard than gpl :/ |
| 11:07 | Fossi | most intepreted language communities did |
| 11:07 | lucian | i guess you'd say that if you disliked the GPL |
| 11:08 | lucian | but really, there's no ambiguity with GPL and interpreted languages |
| 11:08 | lucian | JS's distribution is slightly different, but even that's not terribly important |
| 11:10 | Fossi | i just dislike the ambiguities of linking and minification |
| 11:10 | lucian | but there aren't any! :) |
| 11:10 | lucian | a derivative work is not defined by linking |
| 11:11 | lucian | and minification is considered runnable code, not source, usually |
| 11:11 | Fossi | the question isn't whether i have to commit back |
| 11:11 | Fossi | that's easy |
| 11:11 | lucian | i suppose the second is slightly ambiguous, but you'd offer non-minified code anyway |
| 11:11 | Fossi | it's whether my code (that's proprietary) can call a part of gpl'd js |
| 11:12 | Fossi | in the users browser |
| 11:12 | TimMc | lucian: I guess the central question is whether using JS on a web page counts as distribution. |
| 11:12 | lucian | Fossi: can't, it's a derivative work. simple |
| 11:12 | TimMc | That's the only difference, really. |
| 11:12 | lucian | TimMc: it does |
| 11:12 | Fossi | the distribution part is kinda okayish |
| 11:12 | lucian | does it get to the client, and run there? it's distributed |
| 11:14 | TimMc | I like the approach of having minification on the fly with versioned files -- foo-1.2.min.js is a minified + cached copy of foo-1.2.js, both of which are available over HTTP. |
| 11:14 | TimMc | I call that "providing source". |
| 11:14 | Fossi | TimMc: well, you also want to concat those, but yeah, mostly stays the same |
| 11:15 | TimMc | foo-1234$bar-7654.min.js |
| 11:15 | TimMc | LiveJournal was doing that at one point. |
| 11:41 | edw | Is there an idiomatic way to handle debug logging? I've written my own DEBUG function that takes a log level and a message and the message is logged if the current log level is equal to or higher than the passed in log level. I'd like to like clients of my project get this ability but don't want to unleash any new wheel designs upon the earth. |
| 11:42 | edw | clojure.logging, perhaps? |
| 11:47 | dnolen | edw: https://github.com/clojure/tools.logging |
| 11:48 | edw | Sorry, that's what I meant. It's been placed in my project.clj... |
| 11:54 | edw | Paredit and Clojure mode are not playing nicely using the clojure-jack-in command: C-k is bound to kill-line, not paredit-kill-line, and I'm getting "unbalanced parens" errors when I try to kill a line. |
| 11:55 | edw | Do I need to make sure one loads before the other? |
| 12:40 | amalloy | edw: does the modeline mention paredit? |
| 12:41 | technomancy | edw: those should be orthogonal |
| 12:49 | edw | technomancy: Hey. |
| 12:51 | wastrel | i got vimclojure working with indenting |
| 12:51 | wastrel | i just had to blow away my entire ~/.vim and install it fresh |
| 12:51 | edw | technomancy: If I start-up emacs with '-q' and install paredit and clojure-mode I get the same (problematic) behavior. I have a traditional SLIME, Clojure, Paredit set-up that works fine. To be specific typing C-k where the X is in here "(ns Xfoo.core)" will cause an unbalanced paren error. |
| 12:51 | Raynes | wastrel: You earn a shiny gold VimClojure medal! :D |
| 12:51 | wastrel | :p |
| 12:51 | wastrel | i still want that fancy repl |
| 12:53 | lucian | wastrel: i'm trying out vimana right now |
| 12:53 | TimMc | edw: But is paredit-mode on in that situation? |
| 12:53 | technomancy | edw: clojure-mode 1.9.0 and paredit 22? |
| 12:53 | edw | TimMc: Yes. |
| 12:53 | edw | technomancy: I followed your screencast instructions, and yes, Paredit 22. |
| 12:54 | wastrel | lucian: never heard of it |
| 12:54 | lucian | wastrel: it's a perl utility for managing vim packages/thingies |
| 12:54 | lucian | like pip/gem/etc |
| 12:54 | lucian | but for vim |
| 12:55 | edw | technomancy: This happens regardless of whether I set the set a clojure-mode hook or enable paredit-mode manually. |
| 12:56 | amalloy | edw: does M-x paredit-kill work? |
| 12:57 | edw | amalloy: 1. It is being invoked but 2. it will not kill if it means intelligently not killing part of the line due to the existence of parens that are needed for balancing. |
| 12:57 | amalloy | uh. that second sentence has a lot of words but i can't put them together in a meaningful way |
| 12:58 | edw | amalloy: In other words, C-k is being bound to paredit-kill. It's just not working properly. |
| 12:58 | amalloy | hm |
| 12:59 | edw | (foo |bar) + C-k should result in (foo |) but paredit reports an error and fails to kill "bar". |
| 13:00 | edw | (Pipe = "point on next character") |
| 13:00 | amalloy | edw: yeah, i know. what error does it report? and does it work for (foo baz |bar)? |
| 13:01 | edw | It reports an unbalanced paren error. And no, doesn't work for any kill that requires intelligently killing a partial line. |
| 13:02 | amalloy | and if you switch to lisp-mode+paredit it works? |
| 13:03 | edw | Hold on... Lemme write some elisp... |
| 13:04 | edw | Yup, it works fine in elisp mode. |
| 13:05 | edw | With paredit... |
| 13:05 | amalloy | bummer |
| 13:07 | edw | In fact, if I switch the buffer from clojure-mode to lisp mode, paredit works fine. |
| 13:08 | amalloy | well, i'll try upgrading to latest git and see if i have problems |
| 13:08 | edw | I pulled from github like 30 min ago. |
| 13:09 | amalloy | right. i pulled a few days ago, and it looks like there are one or two irrelevant changes |
| 13:09 | amalloy | rather, i suppose i pushed a few days ago :P |
| 13:09 | gfrlog | do defrecords have to be (import)ed? |
| 13:09 | gfrlog | that seems strange to me because I always thought of (import) as an interop thing |
| 13:10 | TimMc | gfrlog: they do |
| 13:10 | gfrlog | okeedokes then |
| 13:10 | gfrlog | things are not always what they seem |
| 13:10 | amalloy | gfrlog: defrecord is an interop thing too |
| 13:10 | amalloy | it defines a java class |
| 13:11 | gfrlog | but isn't there reason to use it even when you're not otherwise interacting with Java? |
| 13:11 | ataggart_ | With the defrecord changes in 1.3, I suspect less need to import the record classes |
| 13:11 | amalloy | gfrlog: it's a point you could argue either way on |
| 13:11 | ataggart_ | gfriog: records are java classes, hence importing |
| 13:12 | ataggart_ | but master branch has factory functions, so you could just require/use the relevant ns |
| 13:12 | gfrlog | yeah, I know that they're java classes; I just figured that they were also clojurey things and so might have some...special stuff.... |
| 13:12 | amalloy | edw: unfortunately for you, still works for me on 1.9.0 |
| 13:13 | ataggart_ | gfriog: try out clojure master. Also see http://dev.clojure.org/display/design/defrecord+improvements |
| 13:13 | technomancy | edw: I'm getting that with 1.9.0 too =\ |
| 13:13 | amalloy | technomancy: getting what? the buggy behavior? |
| 13:13 | technomancy | amalloy: yeah, error on C-k |
| 13:14 | amalloy | wth. why would it work for me, then. can one of you try checking out b53390 and see if it's still broken? |
| 13:16 | gfrlog | man now I feel bad for using records pre 1.3 |
| 13:17 | technomancy | amalloy: works fine on b53390 |
| 13:18 | gfrlog | ,(doc print-dup) |
| 13:18 | clojurebot | "; " |
| 13:18 | amalloy | rrrrgh. then it's probably my fault *somehow* |
| 13:19 | technomancy | amalloy: confirmed it's 4495e =\ |
| 13:19 | dnolen | gfrlog: amalloy: defrecord, type, protocols are definitely not "an interop thing" |
| 13:19 | technomancy | not sure how I didn't catch it sooner |
| 13:19 | amalloy | technomancy: that one is known to be buggy. db908 fixes a bug in that |
| 13:20 | dnolen | gfrlog: defrecord has a lot of clojurey stuff |
| 13:20 | technomancy | huh |
| 13:20 | gfrlog | dnolen: yeah, this improvements doc is exactly the kind of stuff I was thinking about |
| 13:21 | amalloy | if i could, i would rebase-squash db908 into 4495e so nobody can ever use it :P |
| 13:33 | gfrlog | records are making me consider using (get) for all map accesses :( |
| 13:34 | amalloy | gfrlog: (:foo m) is easier than (m :foo) since it works for records too |
| 13:34 | gfrlog | it is |
| 13:34 | gfrlog | I guess that's good when I have literals |
| 13:34 | amalloy | gfrlog: it works when you don't, too? |
| 13:34 | gfrlog | but if it's a generic algorithm that can't assume the keys are keywords |
| 13:34 | amalloy | ah |
| 13:35 | gfrlog | then traditionally I would use (m k) instead of (k m) |
| 13:35 | gfrlog | but now it could be a record in which case (m k) doesn't work either |
| 13:35 | gfrlog | stuff about to get clunky |
| 13:36 | amalloy | yeah, get is the only real choice. you want to get things from an arbitrary k/v store |
| 13:36 | gfrlog | I can't think of a reason why records shouldn't be IFns just like maps... |
| 13:36 | gfrlog | oh wait |
| 13:36 | gfrlog | I guess you might want to do IFn yourself for some unrelated purpose? |
| 13:37 | amalloy | gfrlog: you lose perf |
| 13:37 | amalloy | records don't encourage slow usages of them |
| 13:37 | gfrlog | you lose performance if they're IFns at all, or just if you use them that way? |
| 13:37 | amalloy | and treating them as ifn couldn't be nearly as fast as using the keyword and/or hinted field access |
| 13:37 | amalloy | the latter |
| 13:38 | gfrlog | don't we prefer slick-looking code before performance? |
| 13:38 | amalloy | yes. so use a hash-map, not a record, please :P |
| 13:38 | amalloy | records exist *specifically* for perf |
| 13:38 | gfrlog | oh. |
| 13:38 | gfrlog | ...and for programming to interfaces? |
| 13:39 | amalloy | reify, deftype...i mean, yes, they're good for interop too |
| 13:39 | gfrlog | I guess you can do that with maps too... |
| 13:40 | amalloy | yay |
| 13:40 | gfrlog | man I was feeling all good about having safer and more structured code |
| 13:41 | amalloy | you didn't really, though |
| 13:41 | cemerick | If the keys in your domain aren't "names" (broadly writ), then records were never really appropriate. |
| 13:41 | amalloy | you can still assoc/get arbitrary fields in a record |
| 13:42 | gfrlog | it does all feel a little loose. Maybe getting older and retreating to static languages is like getting older and becoming a conservative |
| 13:43 | gfrlog | I was just thinking the other day it'd be nice to have a jvm language that's static like scala and immutable/concurrent like clojure and something like haskell |
| 13:43 | dnolen | amalloy: gfrlog: you might want to do IFn yourself, has nothing to do w/ perf. |
| 13:44 | dnolen | amalloy: those things aren't for interop, you gotta stop saying that. |
| 13:44 | gfrlog | dnolen: what's not for interop? records? |
| 13:44 | amalloy | dnolen: explain? |
| 13:44 | dnolen | gfrlog: deftype/record, protocols have nothing to do w/ interop. |
| 13:44 | gfrlog | yeah I never thought they did |
| 13:45 | gfrlog | I thought protocol/record was about programming to interfaces, while deftype was about clojure-in-clojure |
| 13:45 | dnolen | gfrlog: deftype is not about clojure-in-clojure tho it's useful for that too. |
| 13:46 | gfrlog | what else is it about? |
| 13:46 | dnolen | gfrlog: light weight data structures. |
| 13:46 | cemerick | gfrlog: Horse's mouth: http://clojure.org/datatypes :-) |
| 13:46 | amalloy | edw: what version of emacs are you using? |
| 13:46 | gfrlog | cemerick: yeah, that's where I got my impressions from |
| 13:46 | gfrlog | cemerick: any discrepancies are due to cognitive limitations |
| 13:47 | edw | 24.0.50.1. Ubuntu + OS X. |
| 13:47 | cemerick | gfrlog: welcome to the club. We're having jackets made. |
| 13:47 | edw | (Just got back, btw,( |
| 13:47 | gfrlog | cemerick: gonna think real hard about what color mine should be, but not sure if I can figure it out |
| 13:49 | edw | When I tried it under Ubuntu and flakiness resulted, I went to my OS X install and tried it. Same problem. |
| 13:53 | dnolen | gfrlog: amalloy: the statement that IFn will be slower than the provided keyword access is also not true. |
| 13:53 | gfrlog | dnolen: he was probably contrasting with direct field access |
| 13:53 | gfrlog | but that's a good point, since keyword access is provided |
| 13:54 | gfrlog | I'm not sure whether it's better to leave off the IFn implementation for consistency, or allow the user to override it |
| 13:55 | dnolen | gfrlog: done properly IFn can be made nearly as fast as direct access. milliseconds of difference even at 1e8 iterations. |
| 13:56 | gfrlog | that sounds like a good thing. |
| 13:59 | amalloy | edw: update: it works on emacs 23, but not 24. working on figuring out why |
| 14:00 | dnolen | gfrlog: amalloy: https://gist.github.com/983429 |
| 14:02 | gfrlog | dnolen: Think I'm gonna have to run that more like 100000 times before the numbers mean anything to me |
| 14:02 | gfrlog | oh wait |
| 14:02 | gfrlog | I just saw the outer bit |
| 14:02 | edw | amalloy: Thanks for looking into this. FWIW, clojure-plug-in fails on the Emacs that ships with Snow Leopard, but does anyone even use that? |
| 14:03 | technomancy | edw: emacs 22? |
| 14:03 | edw | Ah yes. |
| 14:04 | technomancy | that's 4 years old; strongly considering dropping support for it across the board |
| 14:04 | gfrlog | dnolen: when I run it, the direct access version gets up to ten times faster |
| 14:05 | edw | technomancy: The 18 yo, comp sci freshman from '91 in me cries a little tear. |
| 14:05 | gfrlog | now that I think about it these numbers are rather disturbing... |
| 14:06 | dnolen | gfrlog: not on my setup, OS X 10.6 JDK 7 64bit |
| 14:06 | gfrlog | it is saying that clojure did something 100,000,000 times in 0.002374 milliseconds? |
| 14:07 | ataggart | lazy? |
| 14:07 | clojurebot | lazy is hard |
| 14:07 | gfrlog | ataggart: nope, dotimes |
| 14:07 | ataggart | quantum computer? |
| 14:07 | dnolen | gfrlog: my point is simply that this is the kind of thing that the JVM can detect and aggressively optimize. |
| 14:08 | dnolen | method dispatch is cheap, if is cheap, identical? is cheap. |
| 14:08 | gfrlog | dnolen: that sounds plausible, but 1) my computer reports different times, and 2) how the hell are these times so low for so many operations? |
| 14:08 | amalloy | dnolen: case is surely faster than cond there? |
| 14:08 | dnolen | amalloy: it is not. |
| 14:08 | amalloy | but yes, fair point |
| 14:09 | dnolen | gfrlog: vtable lookup, 3 branch tests, integer comparison, doesn't sound like the computer has to do much. |
| 14:10 | gfrlog | dnolen: I changed it from 1e8 to 1e9 and it got faster |
| 14:10 | gfrlog | I don't think those are physically realizable times even in assembly |
| 14:11 | gfrlog | dnolen: times for 1e5 are about the same as 1e9 |
| 14:11 | gfrlog | something else is going on |
| 14:11 | dnolen | gfrlog: not on my machine, 1e5 is 0.08 milliseconds for me. |
| 14:11 | gfrlog | so 1e8 should be 80 milliseconds |
| 14:12 | TimMc | gfrlog: 1.763 sec and 0.358 sec for me (1e8) |
| 14:12 | dnolen | gregh: it's 70ms on my machine which is what you'd expect. |
| 14:12 | dnolen | oops. |
| 14:13 | gfrlog | I'm getting 0.005 msecs for just about everything |
| 14:13 | gfrlog | which is insane. |
| 14:13 | dnolen | gfrlog: what's your setup? |
| 14:13 | technomancy | edw: is 22 commonly used? I guess I honestly don't know. |
| 14:13 | TimMc | gfrlog: Can you factor some numbers for me? :-P |
| 14:13 | gfrlog | uh some kinda thinkpad |
| 14:13 | gfrlog | ubuntu 64 bit |
| 14:13 | gfrlog | okay let's see |
| 14:13 | gfrlog | if something does 100 million operations in 0.01 milliseconds |
| 14:13 | gfrlog | lemme ask wolfram alpha what that is |
| 14:14 | TimMc | 10 GHz |
| 14:14 | gfrlog | that's all? |
| 14:14 | ataggart | dnolen: case should be faster than cond for keywords and (in master) int-sized integers. |
| 14:14 | dnolen | ataggart: yeah I'm on alpha7 |
| 14:15 | gfrlog | TimMc: WA says 10 terahertz |
| 14:15 | TimMc | gfrlog: Ah, you're right... milliseconds, not seconds. |
| 14:15 | gfrlog | http://www.wolframalpha.com/input/?i=1e8+%2F+%280.01+milliseconds%29 |
| 14:16 | gfrlog | so like I said, this is not physically realizable even if we optimize it to one instruction per field access |
| 14:16 | TimMc | gfrlog: So... you can crack some rar files for me, yeah? :-P |
| 14:16 | gfrlog | nobody else is getting those numbers? |
| 14:17 | gfrlog | here's my output: https://gist.github.com/983477 |
| 14:18 | dnolen | gfrlog: perhaps your JVM sees that the loop doesn't do anything. |
| 14:18 | gfrlog | that's the only thing I can conclude |
| 14:18 | gfrlog | so I think we need a different way to compare the performance |
| 14:18 | gfrlog | I was watching disclojure the other day and he did something similar |
| 14:19 | gfrlog | was measuring the performance of different (rotate) functions, but they were both lazy and I don't think he ever consumed them |
| 14:59 | manutter | part |
| 14:59 | manutter | doh, that's the second time I've done that. |
| 15:00 | offby1 | could have been worse |
| 15:10 | arj | does anyone know how to handle java.nio.channels.ClosedChannelException in aleph? |
| 15:26 | gfrlog | is there a strong use case for reader-evaluation? |
| 15:59 | TimMc | gfrlog: What is reader-evaluation? |
| 16:00 | amalloy | yes |
| 16:00 | amalloy | it lets you define print-dup for new types |
| 16:00 | amalloy | TimMc: #= notation |
| 16:02 | TimMc | Ah, that. |
| 16:03 | gfrlog | huh. |
| 16:04 | ataggart | disabled by binding *read-eval* to false |
| 16:06 | TimMc | How do I get a reader again? |
| 16:06 | amalloy | &(read-string "1")? |
| 16:06 | sexpbot | ⟹ 1 |
| 16:06 | TimMc | thanks |
| 16:06 | TimMc | I tried read and read-str. :-P |
| 16:06 | gfrlog | amalloy: does "defining print-dup for new types" mean serializing something as a string that starts with #=(...)? |
| 16:07 | amalloy | yes |
| 16:07 | amalloy | $google amalloy xml json clojure |
| 16:07 | sexpbot | First out of 14 results is: Don't use XML/JSON for Clojure-only persistence/messaging |
| 16:07 | sexpbot | http://hubpages.com/hub/Dont-use-XML-JSON-for-Clojure-only-persistence-messaging |
| 16:07 | gfrlog | okay. I guess that is a good use. |
| 16:07 | amalloy | gfrlog: ^ has an example |
| 16:08 | TimMc | And I suppose the de-serializer has to have the right environment for the evaluation to succeed. |
| 16:08 | gfrlog | amalloy: that there is a good dang example |
| 16:08 | ataggart | recently added to master is support for literal construction of arbitrary types, so you don't need to add a print-dup |
| 16:08 | gfrlog | yeah that part is not immediately clear |
| 16:08 | gfrlog | I at first assumed you'd just get clojure.core etc. |
| 16:09 | ataggart | correction, don't need to use the read-eval macro |
| 16:09 | gfrlog | what? we got a finger-tree syntax now? |
| 16:09 | amalloy | &(binding [*print-dup* true] (pr-str *ns*)) ;; gfrlog |
| 16:09 | sexpbot | ⟹ "#=(find-ns sandbox11964)" |
| 16:09 | amalloy | TimMc: how do you mean? |
| 16:09 | gfrlog | amalloy: holy cow! |
| 16:10 | TimMc | amalloy: Oh, for instance your constructor function would need to be in scope. |
| 16:10 | TimMc | And isn't there something about eval not getting lexical stuff? |
| 16:10 | gfrlog | yeah it's probably just the deffed stuff |
| 16:10 | amalloy | yes, print-dup is very much not intended for use with lexical anything |
| 16:10 | gfrlog | but I think that'd be okay |
| 16:10 | amalloy | it's for persisting objects |
| 16:11 | amalloy | &`String |
| 16:11 | sexpbot | ⟹ java.lang.String |
| 16:11 | TimMc | &(type `String) |
| 16:11 | sexpbot | ⟹ clojure.lang.Symbol |
| 16:11 | TimMc | right |
| 16:12 | amalloy | TimMc: that's why the recommended way to implement print-dup is like ##(str "=#" `(String. 10)) |
| 16:12 | sexpbot | ⟹ "=#(java.lang.String. 10)" |
| 16:12 | amalloy | means you don't need to have String imported in order for reading to work |
| 16:13 | TimMc | I bet it works even better with #= instead of =#. :-) |
| 16:13 | TimMc | Ah, nice trick. |
| 16:13 | ataggart | is there a bot running master? |
| 16:13 | amalloy | ataggart: neither sexpbot nor clojurebot |
| 16:13 | ataggart | k |
| 16:16 | hiredman | I'd like to have clojurebot's sandbox run has a seperate process, possibly connected via queue, which would make changing the version of clojrue available much easier, and possibly support multiple versions, just have work and five or six other projects and life competing for time :/ |
| 16:17 | amalloy | ataggart: what's needed to get master running? git fetch, compile, mvn install, then depend on that version? |
| 16:18 | ataggart | I think alpha7 is only one commit back from master, you can just use that |
| 16:18 | amalloy | i'll fire up my fork of sexpbot with alpha7 if you want |
| 16:18 | ataggart | but otherwise, yes |
| 16:18 | ataggart | oh I was just curious. no need to bother |
| 16:18 | amalloy | otoh it uses contrib stuff and i don't know how to migrate |
| 16:18 | amalloy | ah |
| 16:19 | ataggart | I have master local anyway. bugs aren't gonna close themselves. |
| 16:19 | amalloy | ataggart: since i have you here, what is the story for using contrib in 1.3? if i have a project that needs pr-xml, can i just use alpha7 and contrib 1.2? |
| 16:20 | ataggart | thinking... |
| 16:20 | arohner | amalloy: I think I had problems with that because of some AOT code |
| 16:20 | ataggart | the only issue you might run into is that *foo* won't be dynamically rebindable |
| 16:22 | ataggart | acually there are quite a few breaking changes, but you're unlikely to run into them. the ^:dynamic thing is main one. |
| 16:22 | amalloy | yeah, i've been tagging my code with :dynamic in preparation for eventually migrating |
| 16:22 | amalloy | though pr-xml probably doesn't |
| 16:23 | amalloy | yeah, looks like it doesn't. i guess i can patch that myself, except i don't know where i'd send the patch to |
| 16:25 | ataggart | amalloy: is this what you're referring to? http://richhickey.github.com/clojure-contrib/prxml-api.html |
| 16:31 | amalloy | yes |
| 16:31 | gfrlog | amalloy: print-dup couldn't be used to print reconstructible lazy seqs could it? because there's already a seq implementation? |
| 16:31 | amalloy | ataggart: in contrib 1.2.0 it includes things like (def ^{:private true} *prxml-tag-depth* 0) |
| 16:34 | amalloy | gfrlog: print-dup is a multimethod; you can derive it |
| 16:34 | amalloy | but it would be hard, if not impossible, to do in general |
| 16:34 | gfrlog | right, I'm just thinking special cases like iterate |
| 16:35 | amalloy | gfrlog: and if the base case of iteration is itself a lazy-seq? |
| 16:35 | gfrlog | punt |
| 16:35 | arohner | anyone have experience using c.c.zip-filter.xml? |
| 16:36 | amalloy | arohner: very briefly, several months ago |
| 16:36 | amalloy | gfrlog: six. i'm a terrible kicker |
| 16:36 | gfrlog | you could get half of a two-point-conversion |
| 16:36 | arohner | amalloy: I can't figure out why chouser's examples in c.c.z-f.x.clj don't require zf/descendants, but all of my code does |
| 16:38 | amalloy | arohner: possibly xml1-> instead of xml->? |
| 16:39 | TimMc | clojure.core.zermelo-fraenkel.xml ? |
| 16:39 | gfrlog | TimMc: of course |
| 16:39 | gfrlog | that's the version without AOC |
| 16:39 | TimMc | with, I believe |
| 16:40 | gfrlog | no with you want "zfc" |
| 16:40 | TimMc | Ah! Right. |
| 16:40 | dnolen | so who's gonna implement Generic Zippers for Clojure? http://okmij.org/ftp/continuations/zipper.html |
| 16:40 | arohner | amalloy: that only seems to affect whether I get "foo" or ("foo"), it doesn't change whether descendants is needed |
| 16:40 | TimMc | From an infinite directory of XML file, pick one element from each. |
| 16:41 | amalloy | arohner: i'm short on psychic powers. can you gist some of your code and a sample of your xml? |
| 16:41 | gfrlog | TimMc: and then use them to duplicate a spherical xml file |
| 16:42 | hiredman | dnolen: what is the difference between that and clojure.zip? |
| 16:42 | dnolen | hiredman: clojure.zip doesn't work w/ all data structures right? |
| 16:42 | amalloy | dnolen: it's pluggable, no? |
| 16:43 | hiredman | ,(doc clojure.zip/zipper) |
| 16:43 | clojurebot | "([branch? children make-node root]); Creates a new zipper structure. branch? is a fn that, given a node, returns true if can have children, even if it currently doesn't. children is a fn that, given a branch node, returns a seq of its children. make-node is a fn that, given an existing node and a seq of children, returns a new branch node with the supplied children. root is the root node." |
| 16:43 | wastrel | is clojurebot written in clojure |
| 16:43 | amalloy | yes |
| 16:44 | gfrlog | is sexpbot witten in sexp? |
| 16:44 | ataggart | dnolen: clojure.zip should make sense for any structure for which left/right/up/down make sense |
| 16:44 | dnolen | hiredman: amalloy: doesn't the returned zipper only work on one type? |
| 16:44 | wastrel | sexybot eh. |
| 16:44 | amalloy | dnolen: define branch as a multimethod if you have mixed data types? |
| 16:44 | TimMc | gfrlog: Why yes it is. |
| 16:44 | dnolen | correct me if I'm wrong, but there is no zipper for [{}] |
| 16:45 | ataggart | dnolen: maps don't fit since left/right doesn't apply |
| 16:45 | dnolen | ataggart: k no zipper for [()] |
| 16:45 | hiredman | some people have done zippers for maps, but there is not universal accepted zipper for them |
| 16:46 | amalloy | &(clojure.zip/zipper sequential? seq list [()]) |
| 16:46 | sexpbot | ⟹ [[()] nil] |
| 16:46 | amalloy | dnolen: ^ should be able to traverse that structure just fine |
| 16:46 | dnolen | amalloy: does the zipper preserve the types? |
| 16:46 | amalloy | yes |
| 16:47 | hiredman | amalloy: I don't think it will |
| 16:47 | ataggart | newly added child types depend on what make-node fn you gave it |
| 16:47 | amalloy | i could be wrong, then |
| 16:47 | hiredman | any edits will turn the outer [] into a list |
| 16:47 | hiredman | since you gave it the list function for constructing nodes |
| 16:47 | amalloy | hiredman: ah. yes, you're right for edits |
| 16:47 | amalloy | it should preserve types for walking though, right? |
| 16:49 | dnolen | anyways, good argument for real generic zipper. would also put walk to it's much needed rest. |
| 16:50 | gfrlog | buncha clojure folk going to strange loop? |
| 16:50 | timvisher | hey all |
| 16:50 | hiredman | ,(require '[clojure.zip :as z]) |
| 16:50 | clojurebot | nil |
| 16:50 | timvisher | is it possible to import package.foo.*? |
| 16:51 | ataggart | no |
| 16:51 | dnolen | timvisher: no |
| 16:51 | timvisher | whoo! |
| 16:51 | timvisher | ok |
| 16:51 | hiredman | ,(-> [()] (zipper sequential? seq list)) |
| 16:51 | clojurebot | java.lang.Exception: Unable to resolve symbol: zipper in this context |
| 16:51 | timvisher | thanks :) |
| 16:51 | amalloy | hiredman: ->>, btw |
| 16:51 | hiredman | ah, right, ahem |
| 16:52 | ataggart | timvisher: if you're using emacs, check out https://github.com/technomancy/slamhound |
| 16:52 | ataggart | or nvm, emacs not required |
| 16:52 | amalloy | lein, though |
| 16:52 | ataggart | time to go stock up for the canucks game |
| 16:53 | hiredman | clojure.zip also tends to have bugs, since it isn't used a lot |
| 16:53 | technomancy | you can use it from the repl; kinda a pita though |
| 16:54 | amalloy | i wonder if whatever was breaking my slamhound/emacs integration has fixed itself yet |
| 16:55 | hiredman | ,(-> (z/zipper sequential? seq list '(())) z/next (z/replace ()) z/root) |
| 16:55 | clojurebot | ((()) (())) |
| 16:55 | amalloy | hiredman: that's not a bug, is it? |
| 16:56 | hiredman | amalloy: I believe it is, should result in (()) |
| 16:56 | amalloy | oh. i was assuming root returned the zipper, not the node |
| 16:56 | hiredman | ,(-> (z/zipper sequential? seq list '(())) z/nex z/node) |
| 16:56 | clojurebot | java.lang.Exception: No such var: z/nex |
| 16:57 | hiredman | ,(-> (z/zipper sequential? seq list '(())) z/next z/node) |
| 16:57 | clojurebot | () |
| 16:57 | hiredman | if I replace () with () I should get (()) out again |
| 16:57 | amalloy | yeah, i think you're right |
| 16:57 | hiredman | lots or corner cases |
| 16:58 | amalloy | hiredman: might be caused by (seq ()) yielding nil instead of (), i dunno |
| 16:58 | amalloy | ,(-> (z/zipper sequential? identity list '(())) z/next (z/replace ()) z/root) |
| 16:58 | clojurebot | ((()) (())) |
| 16:59 | amalloy | guess not |
| 16:59 | hiredman | *shrug* |
| 16:59 | amalloy | oh. my use of (list) is what's broken |
| 16:59 | amalloy | ,(-> (z/zipper sequential? identity identity '(())) z/next (z/replace ()) z/root) |
| 16:59 | clojurebot | java.lang.IllegalArgumentException: Wrong number of args (2) passed to: core$identity |
| 17:00 | amalloy | ,(-> (z/zipper sequential? identity (fn [node children] children) '(())) z/next (z/replace ()) z/root) |
| 17:00 | clojurebot | (()) |
| 17:00 | hiredman | ah, so you could use multimethods to create a generic zipper |
| 17:00 | amalloy | yes, it looks like |
| 17:01 | hiredman | dnolen: so done |
| 17:01 | amalloy | hiredman: the power of clojure: you and i implemented a generic zipper in just ten minutes :) |
| 17:01 | amalloy | the time it took to discover that one already exists |
| 17:06 | amalloy | dnolen: anyway the conclusion is you can make a fully generic zipper in the existing framework with just multimethods or protocols |
| 17:11 | stuartsierra1 | Announcement: Clojure builds on JRockit 1.5, but the tests don't pass. |
| 17:11 | dnolen | stuartsierra1: very cool. |
| 17:13 | dnolen | stuartsierra1: is there a specific nature to those tests that fail? |
| 17:13 | hiredman | so far the only difference is jrockit is slower to start |
| 17:14 | arj | clojure is jrockingIt :-) |
| 17:14 | stuartsierra1 | dnolen: something related to I/O classes, but I'm not sure what yet. |
| 17:14 | dnolen | hiredman: benefits? |
| 17:15 | dnolen | amalloy: ah, I follow now, cool! |
| 17:15 | hiredman | dnolen: none so far |
| 17:16 | dnolen | generic zipper via protocols blogpost brewing ... |
| 17:16 | pjstadig | can someone explain to me why i should be excited about jrockit? |
| 17:16 | amalloy | the name sounds a lot like rocket |
| 17:16 | amalloy | that's exciting enough for me |
| 17:17 | seancorfield | does alex taggart hang out here much? i have a Q about clojure.tools.logging |
| 17:17 | hiredman | ~seen ataggart |
| 17:17 | stuartsierra1 | I think the excitement is about the potential for various JVM commercial enhancements becoming open source in the near future. |
| 17:17 | clojurebot | ataggart was last seen in #clojure, 24 minutes ago saying: time to go stock up for the canucks game |
| 17:17 | amalloy | seancorfield: he's here pretty often. was here just half an hour ago or so |
| 17:17 | seancorfield | darn... my timing sucks :) |
| 17:19 | pjstadig | stuartsierra1: ok...so that leads to my next question...why should i be excited about jrockit? |
| 17:19 | pjstadig | are there actual features that add value? |
| 17:19 | stuartsierra1 | Probably not yet. |
| 17:20 | stuartsierra1 | For certain applications, it may offer faster performance and better garbage collection strategies. |
| 17:20 | pjstadig | ok ... that's cool |
| 17:20 | pjstadig | that sounds more incremental to me than revolutionary...the way people have been raving about the announcement |
| 17:21 | pjstadig | the JRockit Virtual Edition looks kinda cool |
| 17:21 | technomancy | pjstadig: maybe it has more to do with shock that oracle is doing something right |
| 17:21 | stuartsierra1 | yes, what technomancy said |
| 17:21 | stuartsierra1 | It's a positive sign for the future of the JVM under Oracle, which had a lot of people nervous. |
| 17:21 | pjstadig | duly noted |
| 17:33 | wastrel | the clojure list is filling up my inbox :p |
| 17:34 | technomancy | digest mode. it changed my life. |
| 17:34 | amalloy | i just subscribe to the rss feed and tell it not to email me |
| 17:35 | pjstadig | yeah i've done digest mode for a while |
| 17:35 | pjstadig | clojure-dev is low volume and high enough signal-to-noise that i'll take that as single messages |
| 17:39 | amalloy | i don't get it. do you receive them straight in your regular inbox mingled with the rest of your mail? that's the only way i could see the volume being prohibitive, and it's easily fixed by adding a filter |
| 17:39 | danlarkin | aye, I filter all mailing lists into their own folders |
| 17:39 | danlarkin | and browse at my convenience |
| 17:39 | danlarkin | don't be a slave to your email! |
| 17:40 | technomancy | sometimes it's hard to ignore the fact that there's a number in the sidebar! |
| 17:40 | amalloy | i try to avoid receiving mail from mailing lists, and read them as rss/news, but same idea |
| 17:40 | technomancy | even if it isn't in the inbox |
| 17:40 | pjstadig | yeah but if it's not coming into your inbox then you may never read it |
| 17:40 | amalloy | pjstadig: sounds like that's exactly what you want :P |
| 17:40 | pjstadig | so you might as well take a digest |
| 17:40 | danlarkin | I have 33 thousand unread emails in my clojure mailing list folder |
| 17:40 | pjstadig | or just unsubscribe and search for what you want |
| 17:40 | pjstadig | danlarkin: my point exactly |
| 17:40 | pjstadig | just do the digest |
| 17:41 | amalloy | digests aren't as easy to work with. you can't have your mail client filter by thread, for example |
| 17:41 | danlarkin | exactly |
| 17:41 | technomancy | yeah... once I get back to gnus I'll probably go back |
| 17:41 | amalloy | or by sender. one day soon i'll get tired of ken wesson |
| 17:41 | pjstadig | i scan the ToC for any interesting threads an click the links to read them on the google groups site |
| 17:41 | technomancy | gnus lets you just chew through mailing lists like nobody's bizniss |
| 17:41 | pjstadig | i can scan 10's of messages in the blink of an eye |
| 17:42 | danlarkin | I only read threads I'm interested in |
| 17:42 | danlarkin | to each his own I guess |
| 17:42 | pjstadig | right... |
| 17:42 | pjstadig | so just do the digest |
| 17:42 | danlarkin | ...but my way is obviously better |
| 17:42 | pjstadig | no its not |
| 17:42 | pjstadig | it's worse |
| 17:42 | amalloy | *baffled* |
| 17:42 | pjstadig | actually i don't really care |
| 17:49 | dnolen | it's funny because according to google groups the peak of ML activity happened around Jan 09. |
| 17:51 | technomancy | back in the day you couldn't really use clojure without following the list though |
| 17:51 | dnolen | around which time I was posting horrible dribble about adding OO inheritance to structs. |
| 17:52 | danlarkin | silly, silly times |
| 17:52 | technomancy | we all have our embarassing pasts |
| 17:53 | pjstadig | hehe |
| 17:57 | amalloy | one of my first posts was about how to create circular structures for quickly looking up "all Xs in group G" and "what group is element X in" |
| 17:57 | amalloy | i'm still not entirely sure how i ought to have done that |
| 17:58 | danlarkin | two hash maps |
| 17:58 | amalloy | danlarkin: i might prefer one hashmap |
| 17:59 | hiredman | with some kind of composite keys? |
| 18:00 | amalloy | hiredman: there was no danger in my use-case of needing the same key more than once. eg, all Xs have "ids" that are strings, and all Gs have "ids" that are ints |
| 18:00 | hiredman | {[:group 'G] 'xs [:element 'x] [:group 'G]} |
| 18:01 | amalloy | *nod* |
| 18:01 | amalloy | but you don't even need the :element/:group classifiers if there's never any overlap |
| 18:01 | amalloy | {'G 'xs 'x 'G} |
| 18:02 | amalloy | two hashmaps might be less unwieldy in practice, though. i don't remember exactly how i was going to use them; i haven't touched that project in a while |
| 18:03 | danlarkin | you could use the crazy db code I wrote for subrosa! |
| 18:03 | danlarkin | it "indexes" hash maps |
| 18:04 | danlarkin | I think it's actually pretty cool |
| 18:04 | danlarkin | I just have no documentation for it |
| 18:04 | danlarkin | which makes it pretty useless to anyone else |
| 18:11 | technomancy | te |
| 18:11 | technomancy | oops |
| 19:53 | seancorfield | ataggart: i missed you earlier... had some Q's about tools.logging |
| 19:53 | ataggart | shoot |
| 19:54 | seancorfield | i have an app that currently does some fairly complex logging stuff - different levels going to different log appenders, including a DB log appender and an email log appender for different levels |
| 19:54 | seancorfield | it's not written in clojure right now |
| 19:54 | seancorfield | do you think it's worth creating a LogFactory for that and using tools.logging as i migrate the code around it to clojure |
| 19:55 | seancorfield | or should i just write custom logging functions |
| 19:55 | ataggart | what's the underlying implementation? |
| 19:55 | ataggart | e.g., log4j |
| 19:56 | seancorfield | currently? mostly custom log appenders... the rotating file log appender may be based on log4j, possibly |
| 19:56 | seancorfield | the main difference i could see in approach is that what i'm using right now allows you to specify multiple log appenders per namespace |
| 19:57 | ataggart | well let's clear one thing up first, clojure.tools.logging doesn't actually do any logging. If your logging is based on log4j, then you can make your logging calls via tools.logging and it will automatically use log4j |
| 19:57 | seancorfield | so i figured i needed a custom LogFactory but i'm not sure whether it's worth the effort for the amount of customization we have in our app :( |
| 19:57 | seancorfield | i understand that |
| 19:57 | ataggart | k |
| 19:58 | ataggart | I bring it up because the notion of appenders, etc., deals with the underlying implementation config |
| 19:58 | ataggart | which is orthogonal to tools.logging |
| 19:59 | ataggart | so the app you currently have is using its own custom stuff for logging or log4j? |
| 19:59 | seancorfield | like i say, i think part of it is using log4j |
| 19:59 | seancorfield | but it also has logging to the database and logging via email, all for different levels |
| 19:59 | ataggart | is the latter stuff also configured via log4j? |
| 20:00 | seancorfield | and the ability to have logging for a specific namespace go to multiple places |
| 20:00 | seancorfield | not yet... but if i can standardize it all on log4j it might be worth the effort |
| 20:00 | ataggart | yeah, I'd suggest that |
| 20:00 | seancorfield | i'm not familiar enough with log4j (yet) |
| 20:00 | ataggart | then you let the config do the work of routing stuff around. |
| 20:00 | seancorfield | so i'd hate to write a bunch of custom code, only to find i _could_ leverage something standard :) |
| 20:01 | seancorfield | so i might not even need to write a LogFactory...? |
| 20:01 | ataggart | I'm fairly sure any logging you want to do someone has already done an appender for |
| 20:01 | ataggart | and yeah, no need to write a custom LogFactory |
| 20:01 | ataggart | log4j is already provided |
| 20:02 | ataggart | as is apache commons-logging, slf4j, and java.util.logging |
| 20:02 | seancorfield | at some point we want to be able to log arbitrary maps of data to a noSQL store as one of the appenders... |
| 20:02 | ataggart | tools.logging doesn't force anything to be a string |
| 20:03 | ataggart | unless the underlying impl requires it |
| 20:03 | ataggart | so if the "message" is a map, that object should make it to the underlying impl |
| 20:04 | seancorfield | as long as i use (log ...) and not (trace ...) etc? |
| 20:04 | seancorfield | those seem to call (logp ...) |
| 20:04 | ataggart | ya |
| 20:04 | seancorfield | 'k, good to know |
| 20:04 | seancorfield | log4j doesn't seem to support logging to a DB...? |
| 20:05 | seancorfield | ah, that's an optional extra... |
| 20:07 | seancorfield | very optional it seems... hmm... maybe i will end up writing my own log appenders after all... |
| 20:08 | seancorfield | there's a DBAppender available but it uses a very specific format that doesn't match what we want / already use |
| 20:09 | ataggart | it's been a while since I looked but it was fairly straightforward |
| 20:09 | seancorfield | it'll be a nice challenge to write a log appender in clojure for use with log4j :) |
| 20:10 | seancorfield | or i might just write a custom LogFactory and wrap log4j so i can still delegate to it for all the things it can do... |
| 20:11 | ataggart | how is the db appender currently configured? |
| 20:16 | seancorfield | not thru log4j |
| 20:16 | seancorfield | the current logging implementation mimics a lot of log4j it seems |
| 20:16 | seancorfield | it's a 3rd party logging library |
| 20:17 | seancorfield | looks like i can do most / all of what i want with standard log4j as long as i don't mind writing a custom appender for some of our more esoteric stuff... |
| 20:17 | seancorfield | it'll be a long weekend of research i suspect :( |
| 20:19 | seancorfield | ugh! now i dig into this third party code, it does not actually use log4j, it pretty much replicates the entire thing :( |
| 20:20 | seancorfield | good grief... it's a near-complete port of log4j... why oh why would they do that :( |
| 20:21 | seancorfield | oh well, dinner and a few beers and then i'll start to tackle that... |
| 20:22 | ataggart | heh have fun |
| 20:22 | ataggart | ,(doc with-meta) |
| 20:22 | clojurebot | "([obj m]); Returns an object of the same type and value as obj, with map m as its metadata." |
| 20:23 | amalloy | ataggart: the only with-* in clojure.core that doesn't establish dynamic scope |
| 20:28 | ataggart | amalloy: elaborate please |
| 20:28 | amalloy | ataggart: with-open, with-bindings, etc, all deal with dynamic vars |
| 20:29 | ataggart | hmm, yeah, some form of "set" seems appropriate |
| 20:30 | amalloy | &(->> (ns-map *ns*) (map (comp name first)) (filter #(.startsWith % "with-"))) |
| 20:30 | sexpbot | java.lang.SecurityException: You tripped the alarm! ns-map is bad! |
| 20:30 | amalloy | ,(->> (ns-map *ns*) (map (comp name first)) (filter #(.startsWith % "with-"))) |
| 20:30 | clojurebot | ("with-open" "with-in-str" "with-meta" "with-out-str" "with-loading-context" "with-bindings*" "with-precision" "with-local-vars" "with-bindings") |
| 20:31 | amalloy | ataggart: this is not my own insight; chouser posed it as a puzzle some time ago |
| 20:43 | hiredman | you could argue that the meta data create with with-meta has dynamic extent, even more dynamic than bindings created with binding, while the metadata created with-meta has no scope limitations |
| 20:44 | hiredman | but that would be a ridiculous argument |
| 21:54 | hugod | seancorfield: you might also want to look at logback http://logback.qos.ch/, which has an slf4j api - it has a sifting appender, and allows multiple contexts for a log message (MDC) |
| 22:01 | davidplumpton | Anybody got a couple of minutes to give me some feedback on how to make this code more idiomatic? https://github.com/davidplumpton/alert-sim/blob/master/sa.clj |
| 22:20 | seancorfield | thanx hugod |
| 22:27 | jweiss | is there a way to 'flatten' that also will flatten sets? |
| 22:27 | jweiss | i want to flatten a sexp to get all the symbols out of it, including those used in list/map/set literals. |
| 23:19 | seancorfield | quick java interop Q: i have an abstract class (in java) that I want to complete in clojure - possible? how? (a pointer to an example or the appropriate bit of docs is fine) |
| 23:19 | seancorfield | i thought reify would work but that requires an interface |
| 23:20 | seancorfield | is it proxy? |
| 23:22 | seancorfield | this seems to work: (def test-logger (proxy [AppenderSkeleton] [] (append [event] (println (.getMessage event))))) |
| 23:22 | seancorfield | now i just need to figure out how to get log4j to use my clojure appender :) |
| 23:42 | mprentice | i added clojure-contrib to the classpath in ~/.lein/bin/swank-clojure, so i could develop one-off scripts with lein oneoff but still have contrib in my repl |
| 23:42 | seancorfield | w00t!!! log4j is now using my clojure "class" |
| 23:42 | mprentice | is there a plugin like swank-clojure that includes contrib already? |