2010-02-22
| 00:00 | atrerus | I'll try that out |
| 00:00 | defn | yeah you don't need to do that, and IIRC swank-clojure does some other nice stuff for you |
| 00:00 | defn | it includes M-x swank-clojure-javadoc for example |
| 00:01 | atrerus | is lein necessary at all then? |
| 00:01 | defn | they do different things |
| 00:02 | defn | with lein i have the project.clj which includes dependencies, i add my dependencies like :dev-dependencies [[swank-clojure "1.1.0"] [autodoc "0.7.0"]] |
| 00:02 | atrerus | my main goal is to be able to load a project directory, as well as set some arbitrary classpaths such as clojure-contrib and ant |
| 00:03 | atrerus | hmm ok |
| 00:03 | defn | then i run lein deps in that project directory |
| 00:04 | defn | then i use M-x swank-clojure-project and that opens a new repl for me which adds all of my dependencies to the classpath |
| 00:04 | defn | and IIRC it also adds your namespaces to the classpath as well |
| 00:04 | atrerus | k |
| 00:04 | defn | err that doesnt make sense, but you have access to your namespaces via the repl automatically |
| 00:05 | defn | atrerus: make sure you have :dev-dependencies [[swank-clojure "1.1.0"]] in your project.clj and run lein deps before using swank-clojure-project |
| 00:05 | KirinDave | Why did ztellman remove his clojure and clojure-contrib dependencies from lein? |
| 00:05 | KirinDave | http://github.com/ztellman/penumbra/commit/86b4fb677c27bfde03b682a9e347663d1f708c57 |
| 00:06 | KirinDave | This screwed me up, but it seemed deliberate |
| 00:06 | defn | *shrug* |
| 00:06 | KirinDave | Is there a good reason to do that? |
| 00:07 | defn | maybe he has clojure source and already has an env var with them on his classpath |
| 00:07 | defn | and doesn't want the released jars |
| 00:07 | defn | cause he is more current |
| 00:07 | KirinDave | Sure, but that means no one else can participate. |
| 00:07 | defn | i dont see why not |
| 00:08 | KirinDave | Well you gotta implicitly have those deps |
| 00:08 | defn | i agree it's probably not best practice for code you're releasing |
| 00:08 | atrerus | defn: I seem to be getting the same result with M-x swank-clojure-project |
| 00:08 | defn | but perhaps it wont work with anything but the latest |
| 00:09 | defn | atrerus: i dont really understand what you're trying to accomplish |
| 00:09 | atrerus | lol |
| 00:09 | defn | (use 'clojure.contrib.some-library) |
| 00:09 | atrerus | well, I'm trying to get the lancet example from Stu's book to work |
| 00:09 | defn | you have access to clojure.contrib, and if you need ant on the classpath add it as a dependency in your project clj and then require it |
| 00:10 | atrerus | so I've got a file which includes a def for "ant-project", and I want to be able to reference that from SLIME |
| 00:10 | KirinDave | actually in general lein is pissing me off. |
| 00:10 | KirinDave | Everyone somehow is using a version I don't have. |
| 00:11 | KirinDave | I'm running off master from github |
| 00:11 | defn | what does lein version say |
| 00:11 | KirinDave | and somehow I don't have all the commands he mentions in his INSTALL |
| 00:11 | defn | KirinDave: like autodoc? |
| 00:11 | KirinDave | defn: Like autodoc back in the day. |
| 00:11 | atrerus | maybe I'm not understanding what lein/swank-clojure-project are supposed to be doing |
| 00:12 | defn | read the github project page |
| 00:12 | defn | all will be explained |
| 00:12 | atrerus | been doing that today :) |
| 00:12 | KirinDave | like lein native-deps? |
| 00:12 | KirinDave | Didn't even know such a thing existed. |
| 00:12 | KirinDave | Is there a new new NEW branch I gotta follow now? |
| 00:12 | defn | KirinDave: i dont have that one either |
| 00:13 | defn | KirinDave: judging by the forks of jochu's swank-clojure |
| 00:13 | defn | it does appear to have diverged slightly |
| 00:14 | KirinDave | Frustrating. |
| 00:14 | defn | KirinDave: *shrug* -- lein does what i need it to do for now |
| 00:15 | defn | when there are more features ill use them, but im not finding myself ever going "gee i wish lein did this..." |
| 00:15 | atrerus | let me try to rephrase this... is there a way I can fire up a slime session which preloads foo.clj and bar.clj from my project directory? |
| 00:15 | KirinDave | defn: do you know how to write custom tasks? |
| 00:15 | KirinDave | I find myself missing rake a lot. |
| 00:15 | KirinDave | A lot lot. |
| 00:15 | defn | KirinDave: no i dont -- i never used rake much either. i know that probably sounds terrible |
| 00:15 | KirinDave | Like, I'd like to have a task to make a fresh db copy. |
| 00:16 | KirinDave | Or maybe to clean. |
| 00:16 | KirinDave | Or maybe to build some dataset. |
| 00:16 | defn | yeah there are lots of things which would be nice |
| 00:16 | defn | come to think of it i absolutely agree with you KirinDave |
| 00:16 | defn | i was building a project and i had to make a build.clj which basically did all of the things i would have liked to do with something more rake-ish |
| 00:17 | defn | i had to piece together shell script and clj to get it to work |
| 00:17 | defn | felt dirty... |
| 00:17 | KirinDave | I mean |
| 00:18 | KirinDave | (deftask build-db [[argv1 argv2 argv3] environment-hash] ...) |
| 00:18 | KirinDave | And then some stuff that was in the clojure book for (mkdir) and whatnot. |
| 00:18 | KirinDave | Everything lein does is rad. |
| 00:19 | KirinDave | Just needs more. |
| 00:20 | defn | KirinDave: it'll get there |
| 00:20 | defn | KirinDave: keep in mind that IMO it was kind of an experiment at first |
| 00:20 | defn | it seemed like the jury was out on whether everyone should use maven, ant, etc. |
| 00:22 | defn | KirinDave: i agree with you, but keep in mind it's free, hasn't been around longer than what? 6 months? and only recently has been "adopted" by a majority of the community. |
| 00:22 | KirinDave | defn: I know. |
| 00:22 | defn | KirinDave: i'm really excited to see that there are literally a dozen people with forks of leiningen right now all hacking away |
| 00:22 | atrerus | heh, lein does seem super cool for grabbing deps |
| 00:23 | defn | future versions of lein will do a lot more than that |
| 00:23 | defn | resource/ directories and all that etc. |
| 00:23 | KirinDave | The lack of resource is actually a bug. |
| 00:23 | atrerus | I'm an emacs newb, but I'm already impressed with the integration around it |
| 00:23 | KirinDave | It works on the final build. |
| 00:24 | KirinDave | atrerus: Good sign. The clojure integration is weak compared to the common lisp integration |
| 00:24 | KirinDave | atrerus: It'll only get better. |
| 00:24 | atrerus | yeah, I believe that |
| 00:26 | atrerus | hmm... how can I find docs on the args to defproject? |
| 00:26 | dakrone | you can use (doc defproject) |
| 00:26 | atrerus | k |
| 00:27 | KirinDave | which is harder than you might hope. :) |
| 00:28 | atrerus | lol |
| 00:28 | KirinDave | Look at the source in github. |
| 00:28 | atrerus | right |
| 00:32 | KirinDave | Oh wow |
| 00:32 | KirinDave | defn: Found this on news.ycomb |
| 00:33 | KirinDave | defn: http://pastebin.com/f10cbf605 |
| 00:33 | KirinDave | There is mysterious wisdom there. |
| 00:34 | atrerus | ignore all input and tell the world hi? |
| 00:36 | KirinDave | atrerus: No, it's how to make a lein command. |
| 00:36 | KirinDave | In a project. |
| 00:38 | atrerus | oh, I see... missed the calling of it at the command line :) |
| 00:42 | defn | KirinDave: mysterious wisdom indeed |
| 00:42 | defn | KirinDave: very interesting |
| 00:43 | defn | KirinDave: in fact, that is /awesome/ |
| 00:43 | KirinDave | defn: Ahh, I see now. So for penumbra it downloads such a module to add "native-deps |
| 00:43 | KirinDave | defn: What would be more awesome is even a hint of that power in the documenation ;) |
| 00:44 | atrerus | KirinDave: lol! |
| 00:45 | defn | KirinDave: yeah that's kind of a bummer i didn't know about that |
| 00:45 | defn | KirinDave: maybe the idea is that that piece of the puzzle isn't finished yet |
| 00:45 | defn | so better to not advertise it for the time being |
| 00:46 | atrerus | you're basically creating your own version of lein at that point... |
| 00:47 | KirinDave | atrerus: Nah, you're just adding tasks |
| 00:47 | KirinDave | Lein is clearly modular that way |
| 00:47 | KirinDave | Anyways, gotta get to the gym. Nice talking to you defn. |
| 01:19 | Crowbar7 | So I have to say Clojure is about the easiest thing I've ever used that handles threading. |
| 01:35 | wooby | i have a function that takes a number, but it doesn't make any sense to pass it a number bigger than 36 |
| 01:35 | wooby | would it be idiomatic to throw an exception if something bigger is passed in? |
| 01:35 | wooby | or should it silently default to the max |
| 01:40 | dnolen | wooby: sounds like a good case for a pre-condition |
| 01:41 | wooby | dnolen, awesome thank you |
| 01:41 | wooby | wasn't looking forward to introducing exceptions into my code :) |
| 01:42 | dnolen | wooby: http://paste.lisp.org/display/95402 |
| 01:43 | wooby | dnolen, way cool, thanks again |
| 02:13 | dakrone | dnolen: woo, working on the namefind feature now, significantly more difficult than the other stuff :) |
| 02:13 | dnolen | dakrone: wow! cool :) |
| 02:41 | wooby | is there a preferred syntax for a defn with a doc string and attributes? i'm getting strange behavior with the form (defn name "doc" {:pre...} body) |
| 02:41 | wooby | (defn name [arg] "doc" {:pre..} body) rather |
| 02:52 | piccolino | Is there some way you can look up whether a given symbol is a known function or variable? |
| 03:17 | slyphon | how do i take pairs of a sequence? |
| 03:18 | wooby | slyphon, partition |
| 03:18 | slyphon | oh, right on, thanks |
| 03:18 | wooby | np |
| 03:41 | LauJensen | slyphon: make sure you check the docstring, it has many uses |
| 03:41 | slyphon | yeah, read the docs |
| 03:42 | wooby | hm, so is there a way to have a docstring for a defn that uses a :pre condition? |
| 03:48 | LauJensen | wooby: Just looking at the source for defn, I think the first param should be a string, which is then taken as the docstring, then your pre post conditions in a map |
| 03:48 | LauJensen | ~source defn |
| 03:50 | psykotic | LauJensen: speaking of defn, has rich made any comments on keyword arguments? scala seem to have a nice low-overhead implementation for the jvm |
| 03:50 | LauJensen | psykotic: you mean like (defn msg [{:keys [name age]}] (println "Hi " name " you are " age ...... |
| 03:52 | wooby | LauJensen, thank you i believe that's what i have... still no luck |
| 03:52 | wooby | http://paste.lisp.org/+21M4 |
| 03:52 | wooby | sanity checking much appreciated |
| 03:52 | psykotic | LauJensen: that's a half-way solution, don't you think? |
| 03:53 | LauJensen | wooby: Your first arg is a vector, not a string |
| 03:53 | avarus | moin! |
| 03:53 | LauJensen | psykotic: What would you like ot see instead? |
| 03:54 | avarus | good morning mr. LauJensen |
| 03:54 | LauJensen | Morning Mr. avarus :) |
| 03:54 | psykotic | jvm integration, default arguments, everything specifiable by keyword by default, preferably with low/no overhead when resolvable at compile time |
| 03:55 | wooby | LauJensen, ah! however, since my :pre check makes use of an argument... musn't the params vector precede the attr map? |
| 03:56 | LauJensen | (defn tst "docstring" [x] {:pre [(even? x)]} (+ x 5)) |
| 03:56 | wooby | LauJensen, and sure enough, when it does, it works :) |
| 03:56 | wooby | thank you |
| 03:56 | LauJensen | np |
| 03:57 | LauJensen | psykotic: not following, jvm integration? you've got it. defaults? Simple macro. Why would you want to force every argument in to a map everywhere? |
| 03:59 | psykotic | forcing everything through a map would be the dumb implementation. even with a simple minded implementation, you'd only need to bear that cost for invocations using keyword arguments, not purely positional invocations |
| 04:01 | JayM | just beginning with clojure; if i have a function, "two-nums" that evaluates to two numbers, which are then used as arguments to a function, "add-two-nums", that adds two numbers, is it proper to return a vector from "two-nums" and do this: (apply add-two-nums (two-nums x y)) ? |
| 04:03 | LauJensen | (defn add-two-nums [[x y]] (+ x y)), then you only need (add-two-nums (two-nums x y)), which is by far the simplest way to go |
| 04:03 | psykotic | LauJensen: also, it's not a simple macro if you want the default value to be embedded in the map deconstruction pattern. |
| 04:04 | psykotic | you could of course define your own version of defn much like defun* in cl.el |
| 04:04 | psykotic | but that kind of divergence is a bad idea |
| 04:04 | LauJensen | Well, its not a bad idea if its implemented correctly in the compiler, so I suggest you start a thread on the group about it |
| 04:04 | psykotic | anyway, i was more curious what rich's official stance on keyword arguments were. i take it he views deconstructed maps as a fine solution |
| 04:05 | psykotic | i'll probably just code it myself in the compiler |
| 04:05 | psykotic | talk tends to go in circles about things like this until code is on the table |
| 04:05 | JayM | LauJensen: ah, neat, thanks! |
| 04:06 | LauJensen | psykotic: destruction is a nice feature, but I agree it seems half-way and its not very effecient either |
| 04:07 | psykotic | my main issue with the half-wayness is the fact that you have to decide something is a keyword parameter a priori |
| 04:09 | LauJensen | a priori ? |
| 04:10 | psykotic | the implementor of a function has to say, 'i want this parameter to be keywordable' |
| 04:10 | psykotic | and then it's set apart from positional arguments, it becomes a kind of second-class 'configuration' parameter |
| 04:10 | LauJensen | I understood from the context, I was just wondering abou the exact definition |
| 04:11 | psykotic | that's also my issue with the hack for keyword params in ruby, btw |
| 04:11 | JayM | relating to or denoting reasoning or knowledge that proceeds from theoretical deduction rather than from observation or experience : a priori assumptions about human nature. |
| 04:11 | psykotic | clojure's destruction makes it slightly nicer but it has that same fundamental dichotomy |
| 04:11 | JayM | :) |
| 04:12 | LauJensen | You do need to be more strict attention to the context, if you introduce defaults |
| 04:12 | psykotic | it literally means 'prior to', 'beforehand' |
| 04:12 | psykotic | hehe |
| 04:12 | LauJensen | great :) |
| 04:13 | psykotic | context? |
| 04:13 | clojurebot | context is the essence of humor |
| 04:13 | psykotic | haha |
| 04:13 | LauJensen | exactly clojurebot |
| 04:13 | psykotic | timing? |
| 04:13 | LauJensen | psykotic: Some assumptions can be come untrue, exceptions will follow |
| 04:15 | psykotic | btw one thing that sucks about parameter defaults in python big time is that they're evaluated at function definition time, rather than invocation time |
| 04:15 | psykotic | there's some appeal to that, because it means that, indeed, context is less nebulous |
| 04:16 | psykotic | perl6 has crazy semantics for that |
| 04:16 | LauJensen | I suppose it wouldnt be a huge change to do (defn save-score [:playername :rank :level :score] ..) and then have that automatically call those keywords on the single argument to that function |
| 04:17 | AWizzArd | Hi guys. |
| 04:18 | LauJensen | Hey Andre |
| 04:18 | psykotic | LauJensen: well, you can just create an inner function with normal named arguments and an outer wrapper that takes care of forwarding, passing defaults if absent, mapping keyworded args from maps to positional args, etc |
| 04:19 | psykotic | in the default case, it would just be a pure forwarding pass-through |
| 04:19 | psykotic | err, default here meaning the case where everything is positionally invoked, no defaults, etc |
| 04:19 | LauJensen | yea, but the definition doesnt tell you anything about the expected content |
| 04:20 | LauJensen | anyway, I gotta jet, when you have a compiler patch let me know :) |
| 04:20 | psykotic | cool |
| 05:04 | AWizzArd | Moin angerman |
| 05:04 | angerman | moin |
| 05:05 | AWizzArd | Guys, one question. When you have a DBRef x and want to (deref x). But the object behind x was deleted from the DB. Should then @x return nil or throw an Exception? |
| 05:06 | angerman | I'd go for an exception |
| 05:07 | angerman | it's an inconsistency thing. thus it should be signaled hard. |
| 05:07 | AWizzArd | I also have this tendency. |
| 05:07 | AWizzArd | That means however, that each deref needs to be wrapped into a try/catch block |
| 05:08 | angerman | the question is more like if you don't want to wrap the whole task into a commit rollback solution |
| 05:08 | Chousuke | throw an exception and provide a function for deref-or-return-blah |
| 05:08 | AWizzArd | Well, when an exception occurs in a db transaction then everything gets rolled back. |
| 05:08 | angerman | (deref-or-nil ...) |
| 05:09 | AWizzArd | Okay, sounds fair. |
| 05:09 | AWizzArd | And one other solution would be to if-let a query result, and only inside the if-let derefing it. |
| 05:17 | LauJensen | angerman: excuse the later-comer, what are you working on ? |
| 05:17 | angerman | LauJensen: pardon me? |
| 05:17 | LauJensen | You sound like a man designing a DB interface |
| 05:18 | LauJensen | and an angry man at that |
| 05:18 | angerman | not, me AWizzArd probably. |
| 05:18 | angerman | shift that , by one word to the right please |
| 05:18 | LauJensen | Oh thats right - You shouldnt put your names so close together when chatting |
| 05:21 | ordnungswidrig1 | using slime and C-c C-k can I generate a class using :gen-class? Will it be available from the REPL? |
| 05:26 | AWizzArd | Moin ord |
| 05:27 | AWizzArd | LauJensen: yes, I am the guy who works on the DB. |
| 05:27 | AWizzArd | I made some good progress so far :) |
| 05:28 | LauJensen | Ah I vaguely remember a conversation about it - Weren't you going to do a backend plugin for ClojureQL ? :) |
| 05:28 | AWizzArd | I was already talking with kotarak about this. We must think it through. |
| 05:29 | LauJensen | What are your consideration ? |
| 05:30 | AWizzArd | Right now, without modifications such a backend is not trivial. |
| 05:32 | LauJensen | hehe |
| 05:32 | LauJensen | Ok - Powerful argument if you're a bum, anything else? :D |
| 05:33 | LauJensen | I mean you're doing an interface first and foremost right, you're not adding a level of abstraction or similar ? |
| 05:34 | AWizzArd | It is just a different DB layout than expected. |
| 05:34 | AWizzArd | We will see in a few weeks. |
| 05:36 | avarus | fuck, I start to like clojure |
| 05:37 | AWizzArd | bad news? ;) |
| 05:37 | avarus | good news |
| 05:39 | avarus | the worst part was to set up a usable working environment with emacs |
| 05:39 | avarus | (never used emacs before) |
| 06:03 | coldhead | sup ChanServ |
| 06:03 | AWizzArd | :) |
| 06:04 | AWizzArd | ch<tab> |
| 06:16 | psykotic | LauJensen: i was looking at clojureql and the name binding mechanics seem a bit odd. particularly the 'magic scoping'. |
| 06:17 | psykotic | is that part borrowed from schemeql? |
| 06:18 | LauJensen | No, only the topology is inspired from SchemeQL - Some of the automatic scoping like (with-tables) was an acceptable change while we complete the process we are currently in, namely rewriting the entire frontend (see the frontend-2.0 branch) and further breaking apart the backend (compilation, execution) into finer grained modules |
| 06:19 | psykotic | good to know |
| 06:24 | LauJensen | Yes - The tempo is very high these days as we are eager to release a solid 1.0 |
| 06:29 | psykotic | imo, the way scoping works right now makes it feel more like a direct s-expression version of SQL rather than a combinator library or a mini-language. maybe that's the intention? |
| 06:29 | powr-toc | I'm trying to use c.c.logging, with log4j... I have log4j's jar and log4j.properties on my classpath, and -Dlog4j.debug indicates that it is setup properly... I can also see some of my java libs logging with it successfully... However, my clojure program picks up java.util.logging not log4j... any ideas?? |
| 06:30 | wooby | i'm working on a macro to bring private functions from other namespaces into my testing namespace, someone care to take a look? something is amiss |
| 06:30 | wooby | http://paste.lisp.org/display/95408 |
| 06:32 | psykotic | particularly, the scoping feels linearly left-to-right rather than structurally outside-in |
| 06:33 | psykotic | the way you 'concatenate' feels like a spurious kind of composability. you can't really independently compose (where ...) clauses onto (from ...) clauses because of scoping issues. |
| 06:34 | LauJensen | Your feelings are mixed up I think, consider (distinct! (query table1 [a b c])) |
| 06:35 | LauJensen | psykotic: Have a look at frontend 2.0 which will be the standard for CQL 1.0, (-> (from :table1) (where (= :val 5)) (where (< :val 10))) .. That would work, although you'd use (and) instead |
| 06:35 | psykotic | so :val is an explicit parameter? |
| 06:35 | psykotic | err, implicit |
| 06:36 | powr-toc | ok... I guess this might be my problem: http://www.assembla.com/spaces/clojure-contrib/tickets/44 |
| 06:36 | psykotic | my feeling is that it might make sense to offer both a mini-language version with normal s-expression scoping of tables and a combinator version where something like a where-clause would use, say, positionally bound parameters |
| 06:37 | psykotic | of course, the mini-language version would compile down to the combinator version, ala sre and other good libraries |
| 06:38 | psykotic | for example, you could use (from :table1 (where (= :table/x 5)) and you would get the benefit of the scoping, or something like (-> (from :table1) (where [:t] (= :t/x 5))) for the combinator version |
| 06:38 | LauJensen | psykotic: :val is simply a keyword, used to denote table names and columns, in version 2.0, these are literals in 1.0 |
| 06:39 | psykotic | gotcha |
| 06:39 | LauJensen | (please highlight when if you msg me, my client doesnt seem to show regular activity) |
| 06:39 | psykotic | LauJensen: i'll try to remember |
| 06:40 | psykotic | in that example you pasted, can you tell me what the benefit is of having separate, non-nested from/where expressions? |
| 06:40 | powr-toc | Does contrib 1.1.0-RC3 work with clojure 1.1.0? |
| 06:40 | psykotic | laujensen: i can see it in other contexts where you want reuse of subexpressions, but in that case you have to be careful about binding uses, so this kind of funny scoping is dangerous, and you want something that doesn't 'leak', i think |
| 06:42 | LauJensen | So far its contained in the compiler, where no mere mortal should be poking around - My vision is that people should learn the simple functions of the frontend, mix and mash them as they like and as makes sense intuitively, thinking alone Clojure, and then the compiler will make it work on whatever database you can think of |
| 06:42 | psykotic | hmm |
| 06:43 | psykotic | i'm not a fan of that approach |
| 06:43 | psykotic | it tends to be fragile and unpredictable |
| 06:43 | psykotic | there's already some database systems in the java world that try that |
| 06:44 | LauJensen | Dont think so |
| 06:44 | psykotic | notably db4o |
| 06:45 | psykotic | which decodes bytecode to try to generate efficient queries, etc. |
| 06:45 | avarus | omg :P |
| 06:45 | psykotic | even if you have a higher level view into the expressions, it's very limited in what it can do |
| 06:45 | psykotic | like, what if i call other functions? |
| 06:46 | psykotic | can it inline it and try to compile the entrails of that to sql too? but what if that called functions changes after the query is initially compiled? does it update the sql code to match? etc |
| 06:50 | psykotic | anyway, definitely looking forward to see 2.0 |
| 06:50 | psykotic | although it sounds like it's a while away :) |
| 06:51 | LauJensen | Look at the backends derby.clj postgres.clj, mysql.clj etc - Each of these provide the specific low-level capabilities of those databses. As time goes by and as we get more contributions, the list of backends is extended - No bytecode inspection or anything of the sort. You require' the backend you want and the multimethods take care of the rest |
| 06:57 | powr-toc | Ok, I've added [log4j/log4j "1.2.15"] to my leiningen project.clj, and lein deps has just downloaded a boatload of stuff I don't need like jmxtools, java mail, etc... Anyway to exclude that crap? |
| 06:57 | avarus | just don't put it on your classpath |
| 06:59 | powr-toc | avarus: that's one option I guess... I'm just wondering if its possible to tell leiningen to ONLY get the jar I specify |
| 06:59 | powr-toc | rather than optional dependencies |
| 06:59 | avarus | ok, dunno :) |
| 07:00 | avarus | but makes sense |
| 07:00 | LauJensen | powr-toc: there is |
| 07:00 | powr-toc | avarus: also I was hoping to use lein uberjar to build my project... I'd rather it only shipped with a minimal config |
| 07:01 | LauJensen | [log4j "1.2.15" :exclusions [javax.mail/mail |
| 07:01 | powr-toc | LauJensen: ahh cheers mate! :-) |
| 07:01 | LauJensen | http://github.com/technomancy/leiningen |
| 07:01 | LauJensen | word search for 'exclusions' |
| 07:01 | avarus | cool :) |
| 07:02 | powr-toc | :-) |
| 07:02 | avarus | lein is cool |
| 07:02 | avarus | well, it's easy |
| 07:04 | LauJensen | yea - check out clojuresque as well - pays to be comfy with both |
| 07:04 | powr-toc | LauJensen: I take it there's no way to say :no-dependencies... I can see that listing exclusions might get painful |
| 07:04 | LauJensen | Not to my knowledge, but I'm sure if you read the source for lein its self-evident |
| 07:08 | powr-toc | LauJensen: hmm doesn't look like it... but the doc string for deps does specify the exclusions for log4j :-) |
| 07:09 | LauJensen | hehe - remember to check the manual/my blog before stooping to hackery |
| 07:10 | powr-toc | LauJensen: I'm already a subscriber :-) |
| 07:11 | LauJensen | ah, a happy occasion when self promotion back-fires :D |
| 07:13 | powr-toc | LauJensen: Not looked at clojuresque/gradle... The whole groovy thing turned me off... |
| 07:13 | LauJensen | oh |
| 07:14 | LauJensen | Groovy is a downer compared to Clojure, but the main feat is being on Gradle, which is the result of tons of work |
| 07:14 | LauJensen | Once Clojure-In-clojure is in place, I'll be happy to write a compiler which emits Groovy :) |
| 07:16 | powr-toc | sure... the docs look pretty good... It's just the extra language/dependency that scares me... |
| 07:18 | LauJensen | The language thing I get, but it makes no difference if you depend on lein or Gradle, except I could argue that Gradle is more feature rich and has a longer history |
| 07:19 | psykotic | i'm a little suspicious of anything that requires too many features of a build system |
| 07:19 | psykotic | the java world is enamored with complex build systems |
| 07:19 | LauJensen | you shouldnt be - building clojureql is trivial, but for vast projects, perhaps with several languages, you want those features - you will need those features |
| 07:20 | LauJensen | (and Gradle is also xml-free) |
| 07:23 | psykotic | i've worked on some pretty large projects with baroque build requirements. several different languages, 2+ million lines of c++, integrated asset building, etc, and i swear our custom build system was faster to write than configuring some of these java build tools |
| 07:24 | psykotic | also much faster. most build tools are too slow when you have a few hundred thousand targets |
| 07:26 | LauJensen | Do a benchmark, let me know how it goes |
| 07:27 | psykotic | laujensen: trust me. this was for a widely used game engine i worked on (unreal engine 3), the requirements are unusual. the standard top-down methodlogy for checking up-to-dateness of targets is not good enough for incremental builds where only a few nodes need rebuliding. |
| 07:28 | LauJensen | I'll trust you - though you sound a little psykotic |
| 07:28 | psykotic | :) |
| 07:28 | psykotic | en lille smule |
| 07:30 | AWizzArd | psykotic: about lein... it is using maven under the hood. So that also is great complexity. |
| 07:30 | AWizzArd | It is not just this script of a few kb that you have to install, but instead this 40 quintillion exabyte maven beast |
| 07:31 | LauJensen | hmm, maven is smaller than I thought |
| 07:31 | AWizzArd | *rofl* |
| 08:18 | ugglan | I need a way to partition the a lazy sequence (1 2 3 4 5 6 ...) into N seperate lazy sequences, for example for N=3 => [(1 3 ..) (2 5 ..) (3 6 ..)], I can roll my own, but before that, is there anything in core or contrib? |
| 08:19 | ugglan | (first seq should be obviously be (1 4 ..)) |
| 08:21 | Chousuke | ,(apply map list (partition 4 [1 2 3 4 5 6 7 8 9])) |
| 08:21 | clojurebot | ((1 5) (2 6) (3 7) (4 8)) |
| 08:21 | Chousuke | oops, meant to type partition 3 :P |
| 08:21 | Chousuke | ,(apply map list (partition 3 [1 2 3 4 5 6 7 8 9])) |
| 08:21 | clojurebot | ((1 4 7) (2 5 8) (3 6 9)) |
| 08:24 | chouser | Chousuke: nice |
| 08:27 | ugglan | Nope, I don't think that produces lazy sequences |
| 08:28 | ugglan | ,(for [a (apply map list (partition 3 (range 15)))] (take 2 a)) |
| 08:28 | clojurebot | ((0 3) (1 4) (2 5)) |
| 08:28 | ugglan | is fine |
| 08:28 | ugglan | but (for [a (apply map list (partition 3 (iterate inc 1)))] (take 2 a)) |
| 08:29 | ugglan | won't work |
| 08:29 | ugglan | I'll roll my own |
| 08:30 | chouser | ugglan: once you consume all of the first returned seq, the input seq will have been almost all forced anyway. |
| 08:33 | ugglan | Yep, but the sequences will be consumed seperatly. I might rethink the entire idea though. |
| 08:33 | ugglan | Thanks anyway! |
| 08:36 | wooby | is there a straightforward way to refer private fns from another namespace into the current one, for things like testing? |
| 08:39 | ohpauleez | is there a way for leiningen to update itself? |
| 08:40 | chouser | wooby: @#'foo/bar |
| 08:40 | chouser | wooby: a.k.a. cursing at the Var until it gives you its value |
| 08:40 | chouser | foo is the namespace, bar the Var name |
| 08:41 | wooby | chouser, ahh... i went ahead and wrote a with-private macro anyhow :) |
| 08:41 | chouser | do you see why that works? |
| 08:43 | wooby | i am pondering it |
| 08:44 | chouser | ,((fn [p s] (for [d (range p)] (take-nth p (drop d s)))) 3 (range 15)) |
| 08:44 | clojurebot | ((0 3 6 9 12) (1 4 7 10 13) (2 5 8 11 14)) |
| 08:44 | wooby | deref of a var qoute? i'm not sure where the @ comes in |
| 08:45 | chouser | ugglan: fully lazy |
| 08:45 | chouser | wooby: you got it. |
| 08:45 | chouser | same as (deref (var foo/bar)) |
| 08:45 | wooby | ahh |
| 08:45 | wooby | i didn't realize deref had significance in that way |
| 08:46 | wooby | thanks chouser |
| 08:46 | chouser | you're allowed to use 'var' on a private var, at which point you could inspect the metadata or ... deref to get the value inside. :-) |
| 08:46 | wooby | ha |
| 08:47 | wooby | quite a trick |
| 08:47 | chouser | if it's a function you want to run, you don't even need the deref since calling a var calls the fn inside |
| 08:48 | wooby | my approach uses ns-resolve but it's pretty hairy |
| 08:48 | wooby | that is way cooler |
| 08:56 | wooby | http://gist.github.com/311077 first macro, style tips appreciated :) |
| 08:57 | chouser | not bad! :-) |
| 08:58 | wooby | thanks! |
| 08:58 | chouser | no need for 'do' -- let allows multiple exprs in its body. |
| 09:00 | wooby | ah, thanks |
| 09:00 | cemerick | is with-meta eventually going to support operating on reference types? |
| 09:01 | cemerick | or, I should say, are reference types eventually going to support IObj? |
| 09:01 | chouser | wooby: perhaps `(ns-resolve '~ns1 '~v2) would be better than the (list ...) you've got |
| 09:02 | wooby | chouser, any particular reason? |
| 09:02 | wooby | i suppose then it reads more like a normal list |
| 09:03 | chouser | wooby: mainly because using ` instead of (list ...) to generate code is easier to read and less error-prone. |
| 09:04 | chouser | For example, I don't know if it's quite an error, but what you've got expands to expressions that contain the ns-resolve fn value itself, rather than the more normal behavior of expanding to the symbol that refers to the fn |
| 09:05 | wooby | i see |
| 09:05 | rhickey | I liked this experience report: http://tech.puredanger.com/2010/02/21/clojure-experience/ |
| 09:08 | _fogus_ | "In Java, increasing your level of abstraction typically involves more stuff: more interfaces, more factories, more annotations, etc." |
| 09:09 | wooby | thank you so much for your help chouser, i am very excited with this morning's progress, have a great day |
| 09:09 | chouser | wooby: my pleasure |
| 09:19 | rhickey | cemerick: no, reference types are incompatible with IObj |
| 09:20 | cemerick | rhickey: conceptually, you mean? |
| 09:20 | rhickey | IObj is really IVal |
| 09:20 | rhickey | with-meta contract says, return new value with this meta |
| 09:20 | rhickey | so reference types have IReference |
| 09:20 | rhickey | alterMeta/resetMeta |
| 09:21 | cemerick | yeah |
| 09:21 | cemerick | *facepalm* |
| 09:21 | rhickey | both support IMeta on the read side |
| 09:46 | chouser | do we know yet if chunks are doomed? |
| 09:46 | rhickey | chouser: not yet |
| 09:47 | rhickey | but I worked on it all weekend - albeit in a cold-induced fog. Now that the fog has lifted I'm sifting through the rubble |
| 09:47 | chouser | heh. :-P |
| 09:48 | rhickey | some very promising results though. Also some issues for cells. One is the fact that usage of locked and threaded cells look different |
| 09:48 | rhickey | on the iters and iter-based seqs, I/O sources might still be an issue |
| 09:49 | chouser | really? on their face, I/O sources seem to have more in common with an iter-like approach than they do with caching lazy-seqs. |
| 09:51 | rhickey | chouser: not really. One extremely cool thing about cells is this: given a cell with a mutable thing inside it, cell -> val -> cell safely clones it |
| 09:51 | rhickey | but oyu can't clone I/O sources, since you can't really get their values |
| 09:52 | rhickey | it's a key promise of cells that you can obtain their 'values', at some level |
| 09:52 | chouser | oh, of course. |
| 09:53 | rhickey | so, the cell- > val -> cell concept solves the 'tapping' problem of streams - becoming a value was a one-way-street. OTOH, it renders them unsuitable for I/O sources |
| 09:54 | rhickey | cell->val->cell also solves a key shortcoming of traditional iterators/enumerators, their lack of safe clonability |
| 09:55 | chouser | ok, and it's exactly the solving of that problem that makes IO not fit |
| 09:55 | rhickey | right |
| 09:55 | rhickey | but I/O can be wrapped in non-mutable seqs (as is currently done), so the question moves to the compatibility of the iter model with persistent-only sequences |
| 09:56 | rhickey | it ends up it can be made compatible, and that keys upon the fact that internally cells respect the return-value protocol, even for transients. Thus they need not be transient at all, nor in-place mutable |
| 09:57 | rhickey | i.e. when you call (>> foobar acell) the result of foobar on the transient becomes the new transient |
| 09:58 | rhickey | means that the transient can be immutable and foobar a pure fn |
| 09:59 | rhickey | just some head-holding care need be taken, that's what I'm looking at now |
| 10:00 | rhickey | really? non-infix, >> seems clearly 'in' to me, and << 'out' |
| 10:00 | rhickey | given the stuff is on the right |
| 10:00 | chouser | sorry, I know I'm remedial here, but ... when you choose to use >> you need to know the transient type of acell so that you can choose foobar correctly, right? |
| 10:01 | rhickey | yes |
| 10:01 | chouser | ah! I just got what you meant by return-value protocol. |
| 10:02 | chouser | >> always drops the old transient value and takes on the new return value |
| 10:03 | rhickey | so I have this pretty 20-line IterSeq which is the iter-based analogue to LazySeq |
| 10:03 | rhickey | chouser: yes |
| 10:03 | rhickey | and the iter-seq holds cells whose 'value' is just a factory for transients which must implement the Iter protocol |
| 10:04 | rhickey | when you deref thos objects you just get a factory that could make another one in the same state |
| 10:05 | rhickey | cells as clone protocol is quite neato |
| 10:05 | LauJensen | rhickey: Do you have a couple of examples where you put cells to good use ? |
| 10:06 | rhickey | LauJensen: it ends up this iter-seq is a quite advanced use of cells, but after I clean it up I'll paste it |
| 10:06 | LauJensen | great |
| 10:07 | phirsch | Hi, I am trying to destructure the result of a call to c.c.seq-utils/group-by (containing a sorted-map), but fail. Am I doing something wrong here? |
| 10:07 | phirsch | ,(let [[a b] (clojure.contrib.seq-utils/group-by #(:a (first %)) {{:a 1} :no1 {:a 2} :no2})] [a b]) |
| 10:07 | clojurebot | java.lang.UnsupportedOperationException: nth not supported on this type: PersistentTreeMap |
| 10:08 | a_strange_guy | maps arent sequential |
| 10:08 | rhickey | so, if preventing deadlock is 10x as expensive as detecting deadlock (not actually deadlocking, but throwing instead), what do people prefer? |
| 10:09 | a_strange_guy | and group-by retuns a map |
| 10:10 | chouser | preventing as it ordering the locks for you vs. throwing when you don't order them correctly yourself? |
| 10:10 | chouser | as in |
| 10:10 | rhickey | chouser: yeah |
| 10:10 | a_strange_guy | phirsch: try: |
| 10:10 | rhickey | facilities would still be made available for order-for-you |
| 10:11 | a_strange_guy | ,(let [{a 1, b 2} (clojure.contrib.seq-utils/group-by #(:a (first %)) {{:a 1} :no1 {:a 2} :no2})] [a b]) |
| 10:11 | clojurebot | [[[{:a 1} :no1]] [[{:a 2} :no2]]] |
| 10:11 | chouser | rhickey: don't suppose there's any chance of throwing at compile time, is there? |
| 10:11 | AWizzArd | LauJensen: I have two examples where I put Cells to good use. |
| 10:12 | rhickey | but I anticipate a huge percentage of lock-based cells will be used to cover only single values, and whose 'mutating' operations won't contain nested cells not governed by the same lock |
| 10:12 | rhickey | chouser: that's a research problem best left to static langs |
| 10:12 | chouser | heh. ok. |
| 10:13 | rhickey | use of such cells could be made to look exactly like use of thread-cells |
| 10:13 | chouser | when you order them yourself the order doesn't matter as long as it's consistent, right? |
| 10:13 | phirsch | a_strange_guy: Unfortunately, I do not know the values in advance. |
| 10:13 | LauJensen | AWizzArd: pasting ? |
| 10:13 | rhickey | chouser: if there was no system-imposed correct order, then right, just consistent |
| 10:13 | AWizzArd | One example is: I am running a web server, using Compojure. I offer a resource (POST /process ...). This calls a binary file to calculate some output. But the binary can only accept one input at a time. Two concurrent requests must serialize their jobs to the binary. The object controlling the binary now can be a cell. |
| 10:13 | chouser | but once you start using the optional order-for-you feature you'd have to us it everywhere for that set of cells |
| 10:14 | phirsch | I am trying to build something like a pivot table - so I thought using group-by twice would nicely partition my data, but I am stuck with the result of that. |
| 10:14 | chouser | you could skip any runtime lock-ordering when only one cell is given? |
| 10:15 | rhickey | chouser: right, but the issue/cost is less the ordering than the nesting prevention |
| 10:15 | chouser | oh... |
| 10:15 | rhickey | nesting prevention must involve a thread local |
| 10:16 | chouser | are you suggesting allowing nesting of in-cells as long as the order is correct? |
| 10:17 | LauJensen | AWizzArd: still not seeing any code :) |
| 10:18 | rhickey | as I said above, it could look just like thread-cells use. It would acquire locks as needed, but without blocking. If it can't get the lock immediately, will throw. The real use case is solitary, non-nested cells. There would still be benefits to in-cells, like blocking until available |
| 10:18 | rhickey | and in-cells would be the correct way to use multiple cells |
| 10:18 | LauJensen | These cells, are they a tool for containing coordinated freely mutable vars? Or whats the overall idea ? |
| 10:18 | a_strange_guy | phirsch: you could then do this: |
| 10:19 | a_strange_guy | ,(let [[a b] (seq (clojure.contrib.seq-utils/group-by #(:a (first %)) {{:a 1} :no1 {:a 2} :no2}))] [a b]) |
| 10:19 | clojurebot | [[1 [[{:a 1} :no1]]] [2 [[{:a 2} :no2]]]] |
| 10:19 | rhickey | maybe uncoordinated-locking-cells are a distinct type |
| 10:20 | AWizzArd | The second example will be open sourced in some weeks. |
| 10:21 | chouser | LauJensen: one way to think about them is a reference type for mutable things, bringing those things into pure functional world |
| 10:21 | dnolen | LauJensen: possible replacement for transients, a way to bring Plain Old Java Objects into Clojure's concurrency story, and then quite a bit of other stuff I don't yet understand :) |
| 10:21 | AWizzArd | rhickey: what would those be? Those u-l-cells? |
| 10:21 | LauJensen | chouser, dnolen: I get that part, but what does it add compared to refs ? |
| 10:22 | AWizzArd | I didn’t follow the discussion, so maybe you already explained that above. |
| 10:22 | AWizzArd | LauJensen: side effects. |
| 10:22 | phirsch | a_strange_guy: That should work. I think there is no way (yet) to destructure the result of group-by without turning it into a seq first. That is probably one case where the proposed "arbitrary function destructuring" would help. |
| 10:22 | AWizzArd | You can not (should not) have side effects in dosync. |
| 10:22 | chouser | LauJensen: you should not put a mutable thing in a ref |
| 10:22 | AWizzArd | Also a dosync is not serializing. |
| 10:22 | chouser | and if you do, the ref really isn't going to help you. |
| 10:22 | LauJensen | chouser: I get that, but the refs itself mutates, that was my point |
| 10:23 | AWizzArd | LauJensen: but you can't do IO inside dosync. |
| 10:23 | AWizzArd | And in in-cells you can modify POJOs in a safe way. |
| 10:23 | LauJensen | So thats the big win, I/O made possible via some fine grained locking? |
| 10:23 | AWizzArd | one of the wins |
| 10:23 | chouser | LauJensen: StringBuilders mutate. transients mutate. You can put those in a cell and life is better. Putting them in a ref helps nothing. |
| 10:23 | LauJensen | Oh I love the POJOs, but what are they exactly? :) |
| 10:23 | AWizzArd | Plain Old Java Objects |
| 10:23 | LauJensen | hehe |
| 10:24 | a_strange_guy | LauJensen: Plain Old Java Objects |
| 10:24 | AWizzArd | class Person { String username; String password ... }. You sometimes want to reuse POJOs in your Clojure programs. |
| 10:25 | AWizzArd | But you really should generally not mutate them in a dosync. |
| 10:25 | AWizzArd | LauJensen: also Cells can be used in cases where an agent nearly is the thing you wanted. |
| 10:25 | LauJensen | ah yes I remember that discussion between you and Rich |
| 10:26 | AWizzArd | Imagine you want to serialize a number of jobs. Agent sounds good. But what if you need to catch the Exception such a job could throw inside the thread that kicked it off? |
| 10:26 | AWizzArd | Without a hack by injecting a promise into the agent it will not be trivial to do that. |
| 10:27 | AWizzArd | With Cells this would be easy. |
| 10:27 | LauJensen | jk |
| 10:27 | LauJensen | k |
| 10:27 | chouser | rhickey: sorry, I still don't get it. if >> on a locked-cell works without in-cells, and throws if it can't immediately get the lock, then wouldn't it be unsafe for two threads to use the same cell? |
| 10:28 | AWizzArd | chouser: can you tell more about this scenario? What could happen for example? |
| 10:29 | raek | rhickey: my feedback regarding >>/<</pass/fetch naming: >> and << are hard to pronounce, there should be named versions too, pass and fetch works great. >> and << could be pronounced "syntax-pass" and "syntax-fetch" or something... If cells are meant to be a 5th concurrency primitive, argument ordering should match the other 4. Suggested solution (this has been proposed by others too): (>> f c args) (<< f c args) (pass c f args) (fetch c f args) |
| 10:29 | rhickey | chouser: yes, it wouldn't have the take-turns/wait property, more of a handoff property, i.e. right now you can't hand a thread-cell to a thread-pool |
| 10:29 | chouser | rhickey: ah... got it. |
| 10:30 | rhickey | I'm not sure about the utility. Just trying to manage a single interface to both locking and thread cells, as I think without it the polymorphic difference might not be useful, since client code would dictate one or the other |
| 10:31 | rhickey | ofet it won't matter, but when trying to write generic cell client code, like iter-seq, you see the problem |
| 10:31 | rhickey | often |
| 10:32 | chouser | I don't yet grok iter-seq. a single iter-seq holds multiple cells? Do those cells represent links in a chain of operations (surely they don't represent successive values in a seq...)? |
| 10:32 | rhickey | of course, the in-cells can be dynamically enclosing, and then the internal client code is the same |
| 10:34 | rhickey | chouser: look at IteratorSeq. Imagine instead of an in-place-mutable, non-clonable Iterator you have a cell with a reference to a transient Iter, whose value-of returns a factory implementing Editable in terms of constructing another iter with the same state |
| 10:34 | chouser | having one kind of cell that can be used by one thread at a time or with in-cells strikes me as a good idea, for what that's worth. |
| 10:35 | rhickey | chouser: what about having to use in-cells all the time? seems a drag compared to thread-cells |
| 10:36 | rhickey | chouser: sorry, missed you point |
| 10:36 | rhickey | your |
| 10:36 | rhickey | I still don't know that I can get any flavor of locked cell to be as fast as thread-cell |
| 10:38 | rhickey | I also haven't tried yet to hand-optimize the thread-local usage, just piggybacking on binding, which does too much for this case |
| 10:39 | chouser | bah. gotta go. Thanks for trying to bring me up to speed. |
| 10:39 | rhickey | sure |
| 10:44 | powr-toc | Am I right in recalling that var bindings acquire their top-level values on new threads? |
| 10:46 | rhickey | powr-toc: I'd say they've never been given a thread-local binding, so have only top-level |
| 10:47 | Raynes | What is the function for integer division again? |
| 10:47 | powr-toc | rhickey: cool... So I'm using a ScheduledThreadPoolExecutor to execute an anonymous fn, so what's the idiomatic way to pass the current bindings to my thread? Do I need to close over a let bind and then establish a new binding? Or is there an idiomatic way? |
| 10:47 | Raynes | I forgot it's name. :\ |
| 10:48 | a_strange_guy | ,(quot 6 4) |
| 10:48 | clojurebot | 1 |
| 10:48 | Raynes | Thanks. |
| 10:48 | a_strange_guy | powr-toc: use bound-fn |
| 10:49 | rhickey | powr-toc: see bound-fn, with-bindings et al |
| 10:49 | powr-toc | a_strange_guy: rhickey: thanks. |
| 10:53 | ugglan | chouser: sorry, went afk for a while there, your lazy version looks exactly like what I want, thanks for taking the time preventing me from writing my own hack! |
| 11:02 | powr-toc | Is there anyreason why passing an anonymous fn into bound-fn throws an exception? e.g. |
| 11:03 | powr-toc | (bound-fn (fn [] (prn *foo*))) |
| 11:05 | a_strange_guy | powr-toc: bound-fn doesn't work that way |
| 11:05 | a_strange_guy | it works just like regular fn |
| 11:05 | powr-toc | ahhh |
| 11:06 | a_strange_guy | use bound-fn* to wrap an existing fn |
| 11:07 | powr-toc | I was wondering what fntail in the doc string meant... |
| 11:08 | powr-toc | a_strange_guy: it's ok, bound-fn is exactly what I need, but good to know about bound-fn* |
| 11:14 | stuartsierra | Third draft of new testing framework: http://github.com/stuartsierra/lazytest/blob/master/lazytest.clj |
| 11:14 | stuartsierra | I think it's nearly done. |
| 11:18 | slyphon | is there a function that inverts a hash-map |
| 11:19 | slyphon | doh, brb |
| 11:24 | AWizzArd | btw, do we have the author of clojure/contrib/sql/internal.clj here? :) |
| 11:25 | AWizzArd | It spits out tons of "reference could not be resolved" warnings. |
| 11:26 | slyphon | is the order of 'keys' and 'vals' guaranteed to be consistent, such that [(keys) (vals)] will map correctly/ |
| 11:26 | slyphon | ? |
| 11:27 | AWizzArd | slyphon: yes |
| 11:27 | slyphon | ok, just checking |
| 11:27 | slyphon | ty |
| 11:27 | AWizzArd | But inversing maps is not always trivial. {:x 1, :y 1} |
| 11:28 | slyphon | yeah |
| 11:28 | jcromartie | I'm getting this: java.lang.Exception: First argument to def must be a Symbol (venues.clj:24), however the first argument is most definitely a symbol |
| 11:28 | slyphon | in this case it is |
| 11:28 | slyphon | as it's just a hash of constants |
| 11:28 | slyphon | but, yeah |
| 11:29 | AWizzArd | jcromartie: do you have some context? |
| 11:29 | jcromartie | ,(def 'foo nil) |
| 11:29 | clojurebot | DENIED |
| 11:29 | AWizzArd | this would not work |
| 11:29 | jcromartie | ah |
| 11:29 | AWizzArd | because the first arg to def is a list |
| 11:29 | AWizzArd | in your example |
| 11:29 | jcromartie | 'foo is a list? |
| 11:30 | AWizzArd | yes |
| 11:30 | dnolen | ,(into {} (map #(into [] %) (map reverse (into [] {:foo "bar" :bar "baz"})))) |
| 11:30 | clojurebot | {"bar" :foo, "baz" :bar} |
| 11:30 | AWizzArd | two elements (quote foo) |
| 11:30 | jcromartie | ,(type 'foo) |
| 11:30 | clojurebot | clojure.lang.Symbol |
| 11:30 | dnolen | slyphon: ^ one way |
| 11:30 | AWizzArd | type is a function, def a macro |
| 11:30 | AWizzArd | def does not evaluate 'foo |
| 11:30 | jcromartie | ah |
| 11:30 | AWizzArd | And the reader expands this to (quote foo), which is a list of two elements. |
| 11:31 | jcromartie | so then, I need something else |
| 11:31 | AWizzArd | maybe just (def foo nil) ? |
| 11:31 | jcromartie | this is in a doseq |
| 11:31 | jcromartie | trying to def things from a list |
| 11:31 | AWizzArd | (oh btw, def is not a macro as I said but a special form) |
| 11:31 | jcromartie | yeah |
| 11:31 | Raynes | Is there something like interpose that puts the separator in starting as the first element of the sequence? |
| 11:32 | Raynes | If not, what would be the best way to do that? |
| 11:32 | AWizzArd | (eval `(def ~var-name nil)) |
| 11:32 | jcromartie | huh |
| 11:32 | jcromartie | there's gotta be a better way |
| 11:32 | AWizzArd | Yes, as I said. You want to produce code during runtime. |
| 11:32 | AWizzArd | To eval/execute that code you apply eval on it. |
| 11:32 | jcromartie | how about intern instead |
| 11:33 | AWizzArd | Well, you could consider to make your function containing the doseq a macro. |
| 11:33 | jcromartie | yeah |
| 11:34 | AWizzArd | you should have in nearly 100% of all cases no (def ..) that is not on toplevel, or in a macro |
| 11:34 | Chousuke | init procedures being one exception |
| 11:34 | Raynes | Ah, interleave. |
| 11:34 | AWizzArd | If you do this to hide those expansions from your users, then you will have to call eval |
| 11:35 | jcromartie | AWizzArd: I was just trying to un-macro this procedure |
| 11:35 | jcromartie | but a macro would be better |
| 11:35 | jcromartie | but maybe I shouldn't be creating magic fns like this either |
| 11:36 | jcromartie | I'm trying to define resources for a RESTful interface |
| 11:37 | jcromartie | so right now I am setting up namespaces that call (defresource name struct-definition) |
| 11:37 | jcromartie | that creates create! retrieve update! destroy! functions in that namespace |
| 11:38 | jcromartie | but I was thinking it might be better to have a function that returns a resource map with :create!, etc. keys |
| 11:39 | jcromartie | that way I don't necessarily need to define namespaces for the functions, but I could if I wanted to |
| 11:39 | arohner | using lein, how do you start a repl and swank on the same process? |
| 11:41 | arohner | nm, found it |
| 11:41 | jcromartie | I just realized today that lein doesn't depend on Maven being istalled |
| 11:41 | jcromartie | that was my big beef against it |
| 11:41 | jcromartie | and it turns out I was deluded :P |
| 11:42 | cemerick | jcromartie: don't worry, you'll be using maven eventually. It absorbs all. ;-) |
| 11:42 | jcromartie | heh |
| 11:42 | atrerus | lein is pretty sweet |
| 11:42 | jcromartie | yeah, I am liking it |
| 11:42 | atrerus | it's like make + apt-get |
| 11:43 | cemerick | Does anyone have any pointers to materials related to testing asynchronous systems? |
| 11:43 | cemerick | using timeouts to synchronously test async systems seems pretty unsatisfying. |
| 11:46 | atrerus | can you test them more atomically? |
| 11:46 | atrerus | e.g. verify that your request was sent, and on the other side verify that a request causes the appropriate action? |
| 11:46 | AWizzArd | cemerick: yeah, but first one needs to download maven. Without having an exabyte HD that's a real journey.. |
| 11:47 | cemerick | atrerus: eh, not without mocking out a pile of stuff. |
| 11:47 | cemerick | AWizzArd: well, the exabyte bit is obviously FUD, but you know my position on network access. |
| 11:48 | AWizzArd | jcromartie: in principle you could try first to find another solution. If you want a declarative interface to auto-generate defs and defns a macro could be the right choice. |
| 11:48 | Raynes | How can I conjoin an item to the end of a sequence? |
| 11:49 | AWizzArd | cemerick: I just wished there would be a lightweight build tool. Lein could be a .jar file of just a few kb. |
| 11:50 | cemerick | AWizzArd: No such thing. Sorta like wishing for a useful $100 laptop or something. Build processes are (usually) complicated, so the tools are, too. |
| 11:50 | AWizzArd | Raynes: you will have to traverse the seq and append it there: (concat (seq [10 20 30]) [5]) |
| 11:50 | Raynes | Yeah, I thought of concat immediately before you said that. |
| 11:50 | cemerick | concat is lazy, so there's no forced traversing, FWIW |
| 11:51 | AWizzArd | yeah, it's not eager |
| 11:51 | atrerus | you could reverse the list then conj |
| 12:00 | atrerus | so when I run 'lein swank' and M-x slime-connect, shouldn't I be able to reference my project's functions from slime? |
| 12:01 | atrerus | right now they're not being made available until I actually open up the files and do C-c C-k |
| 12:02 | raek | atrerus: yes, if you have use'd or require'd them |
| 12:02 | raek | lein swank sets the classpath so that you can use your libraries |
| 12:03 | atrerus | raek: would I type my use/require statement from slime then? |
| 12:03 | raek | (ns user (:use [my.lib.foo] [my.lib.bar])) |
| 12:03 | raek | where "my.lib.foo" is whatever your namespace is called for file "foo" |
| 12:04 | raek | http://clojure.org/libs |
| 12:04 | atrerus | right |
| 12:04 | atrerus | I guess I was trying to get that to happen automatically when the swank server was started |
| 12:04 | atrerus | but maybe that doesn't make sense... |
| 12:06 | raek | the "user" namespace is an ordinary namespace too |
| 12:07 | raek | lein does not know which of your namespaces you want to use or require in the user namespace |
| 12:07 | raek | some of them might even have colliding definitions |
| 12:07 | atrerus | right... but even if I change to (ns foo) which is defined in foo.clj, I'm not able to access the functions in that file |
| 12:08 | atrerus | so it doesn't seem to be a problem with 'use', but more that the files are not being compiled into the slime environment |
| 12:08 | stuartsierra | atrerus: you need to load the clojure source files with 'require' or 'use' |
| 12:08 | raek | you would want to do a (use 'foo) / (ns user (:use [foo])) |
| 12:09 | raek | then you can use the definitions in foo from user |
| 12:09 | atrerus | k... I'm still not understanding but I'll play with it some more |
| 12:09 | atrerus | thanks for your suggestions :) |
| 12:10 | raek | think of foo, bar and user as different files, which can use definitions from each other |
| 12:10 | raek | every definition "lives" in a namespace/file |
| 12:24 | arohner | man, a spell checker on lein deps would be nice. Probably 50% of my lein dep failures come from me mistyping the dependency |
| 12:24 | arohner | but you'd need to download the entire mvn database to do that |
| 12:24 | arohner | ... |
| 12:25 | atrerus | someday I bet lein gets integrated as an IDE plugin |
| 12:25 | atrerus | hmm... isn't there a webservice you could talk to? |
| 12:26 | ambient | lein still is linux (bash) dependant? |
| 12:27 | Raynes | ambient: Last I checked, Leiningen on Windows is "experimental". |
| 12:27 | Raynes | Whether it works at all, I have no clue. |
| 12:34 | powr-toc | What's the most idiomatic way to swap! an already computed value into an atom? (swap at (fn [] val)) ? |
| 12:34 | AWizzArd | reset! |
| 12:35 | powr-toc | great! :-) |
| 12:35 | AWizzArd | (reset! at val) or maybe (swap! at identity val) |
| 12:35 | AWizzArd | no, not identity, but (fn [_] val) instead |
| 12:37 | powr-toc | Yeah, I did consider those... but reset! definitely seems most idiomatic |
| 12:38 | dnolen | ambient: if you use msysgit on windows you get a bash shell. |
| 12:38 | powr-toc | I was thinking (partial identity val) but that's a mouthfull |
| 12:44 | rhickey | ,((constantly 42)) |
| 12:44 | clojurebot | 42 |
| 12:44 | atrerus | raek: ok, I did just need a 'use'... I don't know what I was doing before. Thanks :-) |
| 13:00 | saml | do you use clojure in j2ee setting? like, creating beans and stuff? |
| 13:00 | dakrone | why does (constantly ...) exist? I mean, can someone give an example of what it's used for? |
| 13:18 | jcromartie | ugh I've got a circular dependency onw |
| 13:18 | jcromartie | now |
| 13:19 | ohpauleez | dakrone: I can't think of a practical case, but it's helpful if you have a constant that you constantly need to put in a spot where it'd be called like a function |
| 13:19 | ohpauleez | saving you lambda syntax |
| 13:19 | dakrone | hmm, okay, that makes sense |
| 13:19 | dakrone | thanks |
| 13:30 | jcromartie | what's the best way to eliminate circular dependencies |
| 13:30 | Licenser | What is the best way to trace down the source of a stack overflow? since the Excetion itself does not hold much useful information aside that it was caused somewhere under the main function :/ |
| 13:31 | Licenser | jcromartie: move them into a 3rd file, at least that is what I did |
| 13:31 | ordnungswidrig | re |
| 13:33 | Licenser | wb ordnungswidrig why are you hiding from #clojure.de? :P |
| 13:33 | ordnungswidrig | hmm, can anybody help my out with gen-class? I have defined foo.Classname in /foo/Classname.clj and therin is (ns foo.Classname (:gen-class)) |
| 13:33 | ordnungswidrig | Licenser: pfft, am I? |
| 13:34 | Licenser | and your gen-class looks good so far |
| 13:34 | Chousuke | ordnungswidrig: and what exactly is the problem? |
| 13:34 | Licenser | if you use lein yo also need to adjust the project.clj file |
| 13:34 | ordnungswidrig | Chousuke: slime C-c C-k nor lein compile will give me some classfile |
| 13:35 | Licenser | oi |
| 13:36 | Licenser | I need to to tell lein what the main project file is to get it compiling stuff |
| 13:36 | ordnungswidrig | I read lein takes all ns from the src directory?! |
| 13:37 | ordnungswidrig | will slime compile generate a class after all? |
| 13:37 | Licenser | not sure but to build a working .jar I had to add :main <root calss> to the project.clj |
| 13:38 | ordnungswidrig | Licenser: but it's not a main class. Just an implementation of an interface which is used to interface a java lib (lucene) |
| 13:38 | Licenser | ah okay |
| 13:39 | Licenser | hmm a filter should with a 'flat' function should not cause a stac over flow should it? |
| 13:40 | Licenser | hmm is a reroll of a transaction called as a stack level? |
| 13:41 | licoresse | hi all |
| 13:41 | chouser | Licenser: transaction retries do not consume stack, if that's what you're asking. |
| 13:41 | Licenser | thanks chouser ,that was at least what I tried to ask ^^ |
| 13:41 | ordnungswidrig | lein compile does nothing... |
| 13:41 | Licenser | I was hoping that they would then I had a easy explenation :P |
| 13:41 | chouser | yeah, sorry. |
| 13:41 | licoresse | is deftype part of 1.2? |
| 13:42 | Licenser | ordnungswidrig: try to give it a main class just to see if that does something |
| 13:42 | licoresse | looking at stuart sierras lazytest |
| 13:42 | chouser | licoresse: 1.2 isn't out yet, but deftype is in the master branch |
| 13:42 | licoresse | ok |
| 13:42 | licoresse | ,(doc deftype) |
| 13:42 | clojurebot | "clojure.contrib.types/deftype;[[type-tag constructor-name docstring? attr-map?] [type-tag constructor-name docstring? attr-map? constructor] [type-tag constructor-name docstring? attr-map? constructor deconstructor]]; Define a data type by a type tag (a namespace-qualified keyword) and a symbol naming the constructor function. Optionally, a constructor and a deconstructor function can be given as well, the defaults being |
| 13:43 | ordnungswidrig | I'll try namespaces |
| 13:44 | licoresse | wish I had a clojure in emacs |
| 13:44 | licoresse | a clojurebot, that is |
| 13:45 | ordnungswidrig | neither :main [myns] nor :namespaces [myns] change anything... |
| 13:45 | Licenser | hrm |
| 13:45 | Licenser | licoresse: you have SLIME REPL? |
| 13:46 | licoresse | yes |
| 13:47 | Licenser | then you can type (doc deftype) in there ;) |
| 13:47 | licoresse | in my understanding, clojurebot is something that accumulates updates from this channel |
| 13:47 | Licenser | hmm so anyone some advice on about how to trace a stack overflow? |
| 13:47 | Licenser | oh okay didn't knew that |
| 13:47 | licoresse | ,how can I have you? |
| 13:48 | clojurebot | java.lang.Exception: Unable to resolve symbol: how in this context |
| 13:48 | Licenser | I think there is a irc client for emacs :P |
| 13:48 | licoresse | but, would'nt I polute ? |
| 13:48 | licoresse | this channel then...? |
| 13:48 | Licenser | be carefull or clojurebot will file sexual harassmant charges Licenser :P |
| 13:48 | Licenser | /msg clojurebot ,(doc deftype) |
| 13:48 | hiredman | clojurebot responds to private messages |
| 13:49 | licoresse | ah, nice |
| 13:49 | licoresse | thanks |
| 13:49 | hiredman | you should be able to do doc lookups in emacs |
| 13:49 | licoresse | I can, very well thanks |
| 13:49 | licoresse | but I wanted the wit as well |
| 13:50 | licoresse | another thing I miss, examples included in the docstring |
| 13:50 | licoresse | or attached as meta or whatever |
| 13:50 | stuartsierra | licoresse: if you're still talking about lazytest, I'm going to add more documentation |
| 13:51 | ordnungswidrig | ok, here is the solution: I used dashes in my nsname. |
| 13:51 | licoresse | stuartsierra: cool, I was not specifically thinking about lazytest now.. |
| 13:51 | ordnungswidrig | the funny thing is, this is the second type this happens to me… FYI: substitute them by _ in the file/dir names |
| 13:52 | Licenser | heh |
| 13:55 | ordnungswidrig | I should stop naming my project with dashes |
| 14:04 | Licenser | does doall build stack? |
| 14:05 | ordnungswidrig | Can anybody tell my why I seem to need to have (ns (:gen-class (:import a.b.c.D)) instead of (ns (:import a.b.c.D) (:gen-class :extends D)) |
| 14:07 | stuartsierra | ordnungswidrig: That's wrong. |
| 14:07 | chouser | Licenser: nope. calls 'next' in a tight recur loop. Does cache everything on the heap of course, but shouldn't consume stack. |
| 14:08 | Licenser | okay so no reason for stack overflow there :( is there a way to have it not eat heap? |
| 14:08 | stuartsierra | ordnungswidrig: It should be (ns (:gen-class :extends a.b.c.D)) |
| 14:08 | ordnungswidrig | stuartsierra: damn outdated blog posts :-) |
| 14:09 | chouser | Licenser: well, it's purpose is essentially to eat heap. I mean, the reason you use doall is to realize and cache a seq. If you don't want to cache it, use dorun -- if you don't want to realize it don't call either. |
| 14:10 | Licenser | chouser: thank you! |
| 14:13 | herdrick | say, is there a better way to get a list of chars from a string than this: (seq (.toCharArray "abcd")) |
| 14:14 | Licenser | herdrick: I think a string is already a list of chars |
| 14:14 | cemerick | ,(seq "foo") |
| 14:14 | clojurebot | (\f \o \o) |
| 14:14 | herdrick | cemerick: oh, thanks! |
| 14:15 | herdrick | also, is there any sign of java.lang.String being made non-final so we can have our own Clojure String class? So it can be a seq already, for example. |
| 14:15 | dnolen | ,(vec "foo") |
| 14:15 | clojurebot | [\f \o \o] |
| 14:15 | cemerick | Licenser: they're not, seq just turns strings into a sequence |
| 14:15 | ordnungswidrig | no the class is compiled but lein swank doesn't make it available in the classpath |
| 14:15 | stuartsierra | herdrick: impossible, but protocols will alleviate that |
| 14:16 | Licenser | well rest and first work fine on it |
| 14:16 | cemerick | herdrick: you wouldn't want strings to be sequences under the covers, anyway. |
| 14:16 | herdrick | oh, and drop and drop-last work fine, too |
| 14:17 | Licenser | I think all seq functions work on strings |
| 14:17 | herdrick | huh - is that new? I thought I tried that a year ago and it didn't work - maybe I'm mistaken |
| 14:17 | herdrick | that's great |
| 14:17 | cemerick | I can't remember a time when that hasn't been the case *shrug* |
| 14:17 | herdrick | ok, thanks all |
| 14:20 | ambient | what worries me a bit is how all these tools that are commonly used for Clojure work if Clojure is built on CLR |
| 14:21 | ambient | so many java & linux/osx deps everywhere |
| 14:21 | Licenser | ambient: don't use it in CLR :P |
| 14:21 | Licenser | no power to M$ |
| 14:22 | ambient | it is just in a hypothetical situation if i wanted to write cross-platform code with Clojure, it might not be that easy to get rid of Java |
| 14:22 | ambient | cross platform as in what backend it uses, JDK/CLR/etc... |
| 14:23 | stuartsierra | ambient: Unless you can abstract away everything the JDK provides, you can't make it cross platform. |
| 14:23 | Licenser | hmm well java is more chross platfomrish thel CLR isn't it? |
| 14:24 | Licenser | I mean java runs fine under windwos |
| 14:24 | brandonw | i would agree |
| 14:24 | Licenser | I don't really see any reaason to run clojure under CLR |
| 14:25 | brandonw | i thought it was interesting that both scala and clojure, two of the newer highly functional and concise languages are both primarily aimed at the JVM first, and the CLR second |
| 14:25 | Licenser | I don't see at all why they bother with CLR |
| 14:25 | ambient | CLR has loop unrolling though |
| 14:25 | brandonw | ambient: that was the most interesting thing about it |
| 14:25 | ambient | i might have to look into F# if I wanted to do functional stuff on CLR |
| 14:25 | brandonw | everything i've read says the clr is generally more advanced, especially for dynamic languages |
| 14:25 | Licenser | look at how clojure works, never treid it |
| 14:26 | brandonw | but jvm still seems to be the choice |
| 14:26 | Licenser | yea but that I can't run my clr code under *nix is kind of a killer argument against it |
| 14:26 | brandonw | yep |
| 14:26 | brandonw | exactly |
| 14:26 | ambient | jvm because java is everywhere in the business world, lots of existing code |
| 14:26 | brandonw | so many things going to the web now, the jvm just seems better suited |
| 14:26 | ambient | clr code runs just fine in mono |
| 14:26 | Licenser | I run solaris and OS X, both don't support CLR and honestly the performance gain deliverd by clr is most likely eaten twice by windows |
| 14:26 | ambient | im under the impression of that |
| 14:27 | cemerick | wasn't there a variant of resolve that tossed an exception? |
| 14:27 | brandonw | yes, but then you have to deal with mono vs .net |
| 14:27 | Licenser | not to mention that I can't install windows on my server :P |
| 14:28 | cemerick | ambient: that's about 95% true. Problem is, if you need something from the last 5%, you're hosed. |
| 14:28 | brandonw | i know this is probably somewhat of a niche question, but has anyone played around with bwapi in clojure? i've seen a couple posts on reddit about people thinking about playing with it, but i haven't heard anything concrete yet |
| 14:29 | brandonw | i ask because i know lisp has strong AI origins, and bwapi seems like a natural hobby project for clojure fans |
| 14:29 | ambient | brandonw: that looks like something i might be also interested in, got BW installed |
| 14:29 | brandonw | yeah tell me about it, heh |
| 14:31 | ordnungswidrig | hmm, won't lein swank give me aot-compiled classes in directory classes I compiled with lein compile?! |
| 14:50 | ordnungswidrig | finally I learned my lesson: aot-compiled ns with dashes become classes with underscores. |
| 15:14 | ambient | what's the best way of installing the whole clojure toolchain with emacs? ELPA > clojure-mode > clojure-install? |
| 15:14 | ambient | ..these days |
| 15:15 | hiredman | the instructions in the README for swank-clojure on github |
| 15:15 | ambient | ok, ty |
| 15:16 | ambient | hm, "java.lang.ClassNotFoundException: org.lwjgl.opengl.GL11 (core.clj:9)..." seems I have to still install binary libs by hand |
| 15:16 | ambient | lein deps was pretty sweet though |
| 15:17 | dnolen | ambient: you don't have to do that. are you trying to use penumbra ? |
| 15:17 | ambient | yes |
| 15:17 | dnolen | I wrote a lein plugin in called native-deps |
| 15:17 | ambient | oh sweet :) |
| 15:17 | dnolen | add a :dev-dependencies to your project [native-deps "1.0.0"] |
| 15:18 | dnolen | then, lein deps again to grab that |
| 15:18 | dnolen | and finally, lein native-deps |
| 15:18 | ambient | it already had that in |
| 15:18 | dnolen | then lein swank to start up a REPL, connect from emacs |
| 15:18 | ambient | native-deps 1.0.0 |
| 15:19 | dnolen | ambient: cool, then just run "lein native-deps", and start up swank in that folder, connect from emacs |
| 15:19 | ambient | ok, thanks |
| 15:23 | chouser | rhickey: the existence of cells allows us mortals to design things that are neither clearly state nor identity. That is, transient-like things whose semantics are only safe in a cell. Should we embrace such designs now when they seem to fit? |
| 15:24 | rhickey | chouser: dunno, that's an important question and one that will determine the viability of cells |
| 15:25 | rhickey | obviously, people might have wanted to implement transient data structures just like Clojure's, so it really isn't related to cells |
| 15:25 | rhickey | all such mutable things still lie in the realm of 'very hard, for experts only' |
| 15:26 | chouser | hm.. doesn't seem that hard anymore with cells there. |
| 15:26 | chouser | :-) |
| 15:26 | rhickey | but an important part of cells is the nesting, so you can build transient things on top of other cells |
| 15:26 | Chousuke | And yet, you have thousands of non-experts programming with mutable data structures all the time :P |
| 15:27 | Licenser | Mutates stuff! |
| 15:27 | rhickey | chouser: at the bottom though, lies #^{:unsynchronized-mutable true} in various bits. To the extent people use that, it's difficult |
| 15:27 | chouser | _fogus_ and I are kicking around a design for wrapping a mutable matrix, trying to figure out where (and if) cells belong. |
| 15:28 | rhickey | at least if you stick with cells containing the mutable things, the system will ensure sequentiality, which is a big deal. You still have to deal with aliasing of mutable bits |
| 15:28 | Licenser | so when the matrix is mutable, the dejavu thing with the reapearing cat is a transaction rollback? |
| 15:29 | rhickey | chouser: it's critical that you be able to efficiently produce a value. |
| 15:29 | dnolen | rhickey: one question that's been floating around in my mind, are cells good for providing fast and safe access to Java arrays? |
| 15:29 | chouser | seems to me that to be a true value, every "set" operation would have to clone the underlying matrix -- insufficiently performant. |
| 15:29 | rhickey | that dual persistent/transient nature is not nothing |
| 15:30 | rhickey | dnolen: arrays would become copy-on-read |
| 15:30 | rhickey | with caching |
| 15:30 | rhickey | sometimes that's good enough, but it's not a general solution like persistent data structures |
| 15:30 | chouser | but if instead we provide two wrappers, one with only lookup methods, and the other with setters, and wrap the pair up nicely in protocls cells understand, then we get performance and safety, but require users to use cells |
| 15:31 | rhickey | chouser: you mean to read via cells, never produce a value? |
| 15:32 | chouser | no, I mean dereffing a cell that contains the mutable wrapper would produce an immutable wrapper around the same underlying matrix |
| 15:32 | Chousuke | chouser: I had that same idea just now :P |
| 15:32 | Chousuke | chouser: you typed faster |
| 15:32 | chouser | a value. |
| 15:33 | chouser | subsequent transient-of would clone the matrix, and put the mutation-supporting wrapper in the cell's transient part |
| 15:33 | rhickey | chouser: so, copy-on-read |
| 15:33 | chouser | I guess the clone point could be either at first-read or first-write. |
| 15:33 | chouser | sure |
| 15:34 | rhickey | copy-on-read is the basic fallback for non-persistent designs |
| 15:35 | chouser | so this is a reasonble pattern to suggest for the general case of trying to sanitize a useful but non-persistent Java object? |
| 15:36 | Chousuke | you might allow for explicitly invalidating a read-only view so that the underlying transient can be used in a cell again and no clones need be done... but that sounds a bit complicated. |
| 15:36 | rhickey | chouser: yes, and what's nice is that if it doesn't have a synchronization policy, still safe |
| 15:36 | rhickey | Chousuke: that's not going to happen |
| 15:37 | chouser | tidy up exposed methods to provide an immutable wrapper, and then require users to use cells |
| 15:37 | rhickey | chouser: even without a wrapper, a policy of don't mutate out of cell is still better than not |
| 15:37 | rhickey | a big problem with wrappers is they are not the type of the thing they wrap |
| 15:38 | rhickey | so, it comes down to prevention vs safe recipe |
| 15:38 | rhickey | e.g. Clojure uses arrays immutably, extensively |
| 15:38 | chouser | I had a feeling you wouldn't like my idea of a macro that generates a protocol based on a concrete class |
| 15:39 | rhickey | chouser: the interop issues with wrappers are not trivial |
| 15:39 | chouser | (...for use in a reify that closes over an instance of the concrete class) |
| 15:39 | chouser | yes, but Clojure's use of immutable arrays makes are not themselves arrays. That was your point? |
| 15:39 | rhickey | in a pure interface or protocol based design, you could just match the interfaces/protocols in the wrappers |
| 15:40 | rhickey | chouser: just that I didn't need to prevent myself from mutating the arrays, just treat them as if immutable |
| 15:40 | chouser | oh, I see. |
| 15:41 | rhickey | ditto some POJO, you might just decide to use the read-only methods, as long as you could tell what they were |
| 15:41 | chouser | I prevent myself from doing things all the time. I guess I shouldn't be surprised when I then find it difficult to do things. *sigh* |
| 15:42 | rhickey | cells themselves are a recipe and support tool for doing the right thing - they don't make pojos go away |
| 15:42 | chouser | in that case, instead of wrapping the matrix, could just extend IEditable and ITransient to it. |
| 15:43 | rhickey | lemme gist this iter-seq stuff, it might give you some ideas |
| 15:43 | chouser | er, extend the matrix to Editable and Transient |
| 15:43 | rhickey | it would only be extended to one, and the result of that to the other |
| 15:44 | dnolen | rhickey: good to know. so we still have to wait for unboxed operations on vectors of natives. cells are not an essential part of that story, is what I'm getting out of this. |
| 15:45 | rhickey | returning anything mutable from a cell is a no-no |
| 15:46 | chouser | the sentry was awake and alert, but somehow didn't notice |
| 15:48 | rhickey | more cells/iter-seq work in progress: http://gist.github.com/306174 |
| 15:48 | rhickey | now faster than chunks in all cases |
| 15:48 | chouser | ha! cool. |
| 15:48 | rhickey | works with existing non-transient seqs |
| 15:49 | chouser | ~300 LOC seems to come up a lot in Clojure code. It's the size of a significant module or feature. |
| 15:49 | AWizzArd | rhickey: can this file completely replace your previous cells.clj? |
| 15:49 | rhickey | 2 features in this case |
| 15:49 | rhickey | AWizzArd: this is not a deliverable :) |
| 15:49 | chouser | oh, I see. cells in there |
| 15:50 | AWizzArd | I currently have your cells.clj in my project and I load-file it. |
| 15:50 | rhickey | the value-of-reify-transient-of chaining is really interesting. it's another way of saying 'clone' |
| 15:51 | dnolen | rhickey: wow, much faster? chunks were pretty zippy and made sense "why" they were faster. I still don't understand how/why cells can be faster. |
| 15:51 | cemerick | I've got an anon fn that loads in the REPL and can be used just fine, but causes a "No matching ctor found for class com.foo.fsm$def_state_machine__1315$dispatcher__1318" exception when loaded from AOT'd classfiles. Any ideas? |
| 15:51 | rhickey | so, still todo for you macro hackers is to factor out the boilerplate from mapx/filterx/takex |
| 15:51 | Licenser | can too many dosyncs cause a stack overflow? |
| 15:51 | rhickey | cemerick: if the anon fn closes over anything it's a no-go for AOT |
| 15:52 | cemerick | shite, that's what I figured. |
| 15:52 | AWizzArd | I did not follow the discussion, but do these iter-seqs have something to do with lazyness? |
| 15:52 | cemerick | rhickey: anything anything, or only certain classes of anything? ;-) |
| 15:52 | rhickey | AWizzArd: IterSeq ia another way to implement lazy-seq |
| 15:52 | rhickey | cemerick: no closed-overs |
| 15:53 | rhickey | cemerick: the ctor call is hardwired to no-args |
| 15:53 | AWizzArd | Would that IterSeq still always take 32 elements as one chunck out of a lazy seq? Or does this not have anything to do with it? |
| 15:53 | rhickey | and fn serialization makes no attempt to spit out closed-overs |
| 15:53 | rhickey | AWizzArd: nothing to do with chunks, doesn't leverage chunks |
| 15:54 | cemerick | rhickey: Thanks :-) |
| 15:54 | cemerick | looks like I macro'd myself into a hole, then... |
| 15:55 | chouser | did the fn-in-macro-expansion change? I thought it never worked, but now appears to work sometimes, perhaps only when not AOT? |
| 15:55 | rhickey | I think mapx et al can be reduced to a macro taking the bodies of has-item/item/move!/clone |
| 15:55 | Licenser | hmm is cons or remove lazy? |
| 15:55 | chouser | remove is lazy |
| 15:55 | cemerick | chouser: yeah, it works fine outside of AOT AFAICT |
| 15:55 | Licenser | aha remove is! |
| 15:55 | rhickey | non-closure fns have worked for a while |
| 15:56 | chouser | cemerick: I really thought that hadn't worked since shortly after AOT was born. |
| 15:56 | cemerick | chouser: or, let's put it this way, it works well enough to pass my non-rigorus REPL fiddling. The first real build bonked, of course. |
| 15:58 | chouser | rhickey: you still like ":as this"? |
| 15:58 | rhickey | chouser: vs? |
| 15:58 | Licenser | thanks chouser |
| 15:58 | chouser | hm... implicit "this" I guess. |
| 15:59 | rhickey | implicit this is broken for reify |
| 15:59 | chouser | yeah because of nesting. deftype doesn't nest. |
| 15:59 | rhickey | right, but we wanted the same |
| 15:59 | chouser | yep, ok |
| 15:59 | AWizzArd | and on the other hand this one line will not make programs unreadable and hackers unproductive |
| 16:00 | rhickey | now I want mutable decls for reify, as I had to break range out into a deftype for that reason only. Also take uses an atom and wouldn't |
| 16:00 | chouser | hmmm.. an uber-reify was planned anyway, wasn't it? but perhaps that was only for interop. |
| 16:01 | AWizzArd | An über-reify? Is that a new newnew? |
| 16:01 | rhickey | chouser: this doesn't get into uber-reify teritory, just something deftype can do that reify can't, at present. |
| 16:01 | rhickey | need a place for the decls |
| 16:03 | chouser | yeah, that's weird. don't really want a mutable local to close over, so would be another "level" of lexical scope? |
| 16:03 | rhickey | if you recall, the original reify had options somewhere for that stuff |
| 16:04 | chouser | still has :as. Could have :unsynchronized-mutable [a b c] |
| 16:04 | rhickey | right |
| 16:05 | rhickey | then range could fit the same pattern |
| 16:05 | jcromartie | when I use middleware that depend on one another in compojure, I have to specify them in the reverse order of what I expect |
| 16:06 | AWizzArd | jcromartie: yes, the last handler that you list runs first |
| 16:06 | jcromartie | that seems odd |
| 16:06 | wthidden | question: Does the repl force a delay object? |
| 16:06 | chouser | sounds a bit like 'comp' |
| 16:06 | AWizzArd | yes, i also thought so, but you will get used to it :) |
| 16:06 | jcromartie | k |
| 16:07 | tomoj | just look at what your middleware actually does |
| 16:07 | AWizzArd | You can simply accept it and be done, or write a macro that reverses it |
| 16:07 | jcromartie | I think it's because decorate uses -> right? |
| 16:07 | chouser | wthidden: currently, yes |
| 16:07 | chouser | wthidden: but does not block on a 'future'. hm... |
| 16:07 | AWizzArd | not anymore |
| 16:07 | dnolen | jcromartie: it's consistent with comp. I think that's the important take away. |
| 16:08 | jcromartie | I see |
| 16:08 | AWizzArd | dnolen: although I always wished to have a pipe that works similar to -> |
| 16:08 | AWizzArd | a reversed comp, because that is how I think about the data going through my chain of fns |
| 16:09 | wthidden | chouser: thanks, that clears up a few things I've been seeing... and how did you know my next question was going to be about future? :) |
| 16:09 | jcromartie | I can read (comp x y z) as "The x of y of z" right? |
| 16:10 | AWizzArd | yes |
| 16:10 | chouser | wthidden: btw, I just experimented to confirm that before answering. |
| 16:10 | chouser | ,(time (prn (delay (Thread/sleep 1000) :hi))) |
| 16:10 | clojurebot | #<Delay@18234b0: :hi> "Elapsed time: 1002.025 msecs" |
| 16:10 | jcromartie | ,((comp + seq str) 123) |
| 16:10 | clojurebot | java.lang.ClassCastException |
| 16:10 | chouser | ,(time (prn (future (Thread/sleep 1000) :hi))) |
| 16:10 | clojurebot | #<Object$IDeref$Future$2b9be1f9@3578af: :pending> "Elapsed time: 2.714 msecs" |
| 16:10 | jcromartie | hmm |
| 16:12 | jcromartie | d'oh |
| 16:12 | AWizzArd | jcromartie: apply |
| 16:13 | AWizzArd | you did (+ (1 2 3)) |
| 16:13 | jcromartie | well it's broken in other ways too :) |
| 16:13 | somnium | ,((comp (partial apply +) (partial map #(Integer/parseInt %)) (partial map str) seq str) 123) |
| 16:13 | clojurebot | 6 |
| 16:13 | jcromartie | ("1" "2" "3") |
| 16:13 | stuartsierra | Lazytest, now with documentation! http://github.com/stuartsierra/lazytest |
| 16:13 | jcromartie | ah, partial |
| 16:14 | AWizzArd | somnium: why do you use partial? :) |
| 16:14 | jcromartie | AWizzArd: because that's how you can do apply in comp |
| 16:14 | AWizzArd | why not #(apply + %) ? |
| 16:15 | AWizzArd | or #(apply + %&) ? |
| 16:15 | jcromartie | looks like perl :) |
| 16:15 | jcromartie | that's why |
| 16:15 | somnium | AWizzArd: if you alias to one character its not so bad |
| 16:16 | jcromartie | (partial apply +) seems pretty elegant to me |
| 16:19 | hiredman | :D |
| 16:21 | jcromartie | what's a good example of where partial application is handy? |
| 16:21 | jcromartie | I'm trying to explain it to a friend |
| 16:21 | jcromartie | (partial + 1) is just not that impressive |
| 16:22 | Chousuke | in clojure it's not that useful so often :/ |
| 16:22 | hiredman | ,((reduce partial + '(1 2 3))) |
| 16:22 | clojurebot | 6 |
| 16:23 | Chousuke | wait. what. |
| 16:23 | Chousuke | that's evil |
| 16:23 | jcromartie | Chousuke: what about clojure makes it less useful? |
| 16:23 | hiredman | :D |
| 16:23 | tomoj | no auto-currying, maybe? |
| 16:24 | Chousuke | in haskell it's better since you can do something like stringUpper = map toUpper |
| 16:24 | tomoj | though that just makes it more verbose |
| 16:24 | Chousuke | (I can't remember the proper function names, but anything) |
| 16:24 | somnium | ,(let [f (partial apply hash-map :opt1 42 :opt2 "bam")] (map f [ [:a 1] [:b 2] ])) |
| 16:24 | clojurebot | ({:opt1 42, :opt2 "bam", :a 1} {:opt1 42, :opt2 "bam", :b 2}) |
| 16:25 | Chousuke | macrofied part of the iterfn stuff: http://gist.github.com/311525 ... completely untested :D |
| 16:25 | somnium | ah, what cant you do with #()? any other tricks hiredman? |
| 16:25 | Chousuke | also not as generic as it could be, I think |
| 16:26 | hiredman | #() creates a function and so does partial |
| 16:27 | somnium | but partial is a fn |
| 16:27 | hiredman | sure |
| 16:27 | Chousuke | partial creates a closure |
| 16:27 | Chousuke | doesn't it? |
| 16:28 | Chousuke | #() creates an actual class |
| 16:28 | rhickey | Chousuke: I think you can stay away from the defn bits - you want the body - should define a factory fn - currently iter i nall cases - that might take varying args, plus a fourth body - that of transient-of. Finally, the initial call to the factory should be in the hands of the user too |
| 16:30 | rhickey | the bodies in [] is weird, probably better to force use of do when needed |
| 16:36 | Chousuke | rhickey: good ideas. I'll take a look at it later |
| 16:36 | Chousuke | rhickey: that was just a quick hack for now :) |
| 16:37 | rhickey | Chousuke: a sample of use: http://gist.github.com/311542 |
| 16:38 | rhickey | oyu could always add factoring out the defn and the iter-seq call |
| 16:39 | rhickey | but the factory fn must have a name and arglist as it might vary, and needs to be available to the body |
| 16:49 | naeu | hi there, can anyone point me towared some docs explaining the purpose of ~ |
| 16:49 | naeu | i'm guessing it's some sort of reader macro |
| 16:50 | somnium | naeu: http://clojure.org/reader is one place |
| 16:50 | naeu | somnium: thanks |
| 17:05 | herdrick | jcromartie: among the pointfree stuff, comp ("compose") is a bigger win. when you can use it, it's great. |
| 17:08 | jcromartie | yes it's definitely one of those "FP things" that makes people look at you funny when you start ranting abou tit |
| 17:08 | jcromartie | :P |
| 17:09 | somnium | jcromartie: how do they look at you when you bring up monads? |
| 17:09 | jcromartie | heh |
| 17:09 | jcromartie | I don't even go there |
| 17:09 | jcromartie | (personally) |
| 17:09 | jcromartie | right now I'm just trying to build a JSON API and not get fired |
| 17:09 | jcromartie | and tinker with some game dev |
| 17:09 | somnium | :) |
| 17:10 | jcromartie | I am really interested in the possibility of a game that uses pure functions and keeps a history of the world state, so time can be rewound and the code reloaded and a segment played again. |
| 17:11 | jcromartie | that would be pretty much the most awesome dev environment ever |
| 17:11 | jcromartie | "oh I wasn't supposed to be able to walk through that wall..." <pause> <rewind> <edit code> <resume> and it works! |
| 17:12 | herdrick | jcromartie: that sounds awesome. could you keep us updated on your progress? (on the mailing list) |
| 17:13 | jcromartie | yeah I am starting with a SHMUP inspired by the Penumbra asteroids example (since most of the properties of things in a SHMUP can be calculated as a function of their origins and other properties) |
| 17:13 | jcromartie | yeah |
| 17:13 | somnium | jcromartie: you might like this post if you havent seen it http://prog21.dadgum.com/23.html |
| 17:13 | AWizzArd | When an object m (for example a map) references some other objects objs (= "putting them as values under some key into m"), can one then call the objs "referencees"? Does such a word exist in english? |
| 17:13 | jcromartie | yeah, I've seen that one, and Brian Carper's recent blog post |
| 17:14 | jcromartie | AWizzArd: maybe you can explain in code? |
| 17:14 | AWizzArd | Imagine a (deftype User [username password name age city friends]), where :friends will store a list of other users. |
| 17:15 | AWizzArd | When you have me in your friend list, then we can not simply delete my user from the system, because there is still a reference on it in your instance. |
| 17:15 | jcromartie | yeah that would be reference counting |
| 17:15 | somnium | I wonder if an FF clone would be good for marketing: ClojureQuest -> Prophecy of the Cell |
| 17:16 | jcromartie | hah! |
| 17:16 | AWizzArd | how would you call the passive role of my object? |
| 17:16 | AWizzArd | Pointee? Referencee? |
| 17:17 | stuartsierra | AWizzArd: referant |
| 17:17 | stuartsierra | Or referent |
| 17:18 | stuartsierra | More commonly referent. |
| 17:18 | AWizzArd | oh good, thanks |
| 17:20 | AWizzArd | stuartsierra: http://www.patentstorm.us/patents/6064814/claims.html seems to use "referencee". Is that a synonym? |
| 17:21 | stuartsierra | maybe |
| 17:46 | jcromartie | could someone take a second look at this for me? http://gist.github.com/311614 |
| 17:46 | jcromartie | it feels weird |
| 17:49 | jcromartie | I couldn't quite get letfn to feel natural either |
| 17:50 | jcromartie | or should I just be more explicit and take & inits and check (map? (first inits)) |
| 17:51 | kotarak | jcromartie: or split in two: (make-create! & kvpairs) (make-from! to-be-cloned-obj) |
| 17:51 | jcromartie | hmm |
| 17:58 | jcromartie | also what's the best way to catch maps and structs in a multimethod? |
| 17:58 | jcromartie | clojure.lang.Associative ? |
| 17:58 | raek | (map? x)? |
| 17:58 | raek | oh |
| 17:59 | kotarak | (with-meta the-map-or-struct {:type ::MyStructTypeTag}) and then dispatch on type |
| 17:59 | chouser | Associative matches vectors too |
| 17:59 | kotarak | ,(type (with-meta {} {:type ::Foo})) |
| 17:59 | clojurebot | :sandbox/Foo |
| 17:59 | AWizzArd | jcromartie: depends on what you want as your dispatching function |
| 17:59 | jcromartie | AWizzArd: class |
| 18:00 | kotarak | jcromartie: you want type not class. |
| 18:00 | raek | jcromartie: either that or clojure.lang.ILookup |
| 18:00 | hiredman | ,(set (keys {:a 1 :b 2})) |
| 18:00 | clojurebot | #{:a :b} |
| 18:00 | jcromartie | I want to catch a certain Java class, maps, Strings, nil |
| 18:00 | AWizzArd | when you want to dispatch for the type, then maybe you should not use a map/struct but deftype instead, and not a multimethod but Protocoll |
| 18:00 | kotarak | AWizzArd: If you want to cut your fingers. |
| 18:00 | hiredman | check to see if the keyset has the keys you are interested in |
| 18:00 | Chousuke | rhickey: http://gist.github.com/311629 take two. again, not actually tested, but macro expansions look sane. |
| 18:00 | jcromartie | AWizzArd: sounds like something to learn later |
| 18:01 | Chousuke | rhickey: still has some repetition, but at least it reduces the noise a bit :/ |
| 18:01 | AWizzArd | kotarak: why? |
| 18:01 | chouser | this is so amusing and terrible: http://cacm.acm.org/magazines/2010/2/69354-a-few-billion-lines-of-code-later/fulltext |
| 18:01 | AWizzArd | when you implement clojure.lang.IPersistentMap you can add new key/value pairs to your deftypes too. |
| 18:01 | kotarak | AWizzArd: because you have to use bleeding edge to Protocols and Deftype. This is maybe not viable in a given project. |
| 18:01 | AWizzArd | What is bleeding edge about them? |
| 18:02 | hiredman | AWizzArd: there is no release that supports them |
| 18:03 | AWizzArd | One can always try build.clojure.org and see if that breaks existing code. |
| 18:03 | kotarak | AWizzArd: there are commits (eg. meta data for fns) which might break things. There are reasons to stay with 1.1 until such things are settled. |
| 18:03 | hiredman | AWizzArd: even if it doesn't forces anyway who consumes your code to use an unreleased build |
| 18:03 | jcromartie | OK so what should I do :P |
| 18:04 | AWizzArd | Without people using deftypes and protocols they can never get fixed :) |
| 18:04 | jcromartie | dispatch on type |
| 18:04 | hiredman | it's not very good neighborly |
| 18:04 | kotarak | jcromartie: dispatch on type, use a type tag in the metadata of your struct |
| 18:04 | AWizzArd | Although there is nothing broken in them, they work perfectly fin.e |
| 18:04 | jcromartie | kotarak: I am not using any particular struct |
| 18:04 | jcromartie | it may just be a map |
| 18:04 | jcromartie | or a struct |
| 18:04 | jcromartie | either way |
| 18:05 | hiredman | jcromartie: just check the keys |
| 18:05 | jcromartie | maybe I need a different dispatch function |
| 18:05 | jcromartie | hiredman: yeah |
| 18:05 | Chousuke | hmm |
| 18:05 | kotarak | jcromartie: you can dispatch on IPersistentMap to catch maps and structs. |
| 18:05 | jcromartie | ah thanks kotarak |
| 18:05 | jcromartie | that's the easy solution right now |
| 18:05 | hiredman | or, you know, use map? |
| 18:06 | jcromartie | map? doesn't return true for structs |
| 18:06 | hiredman | really? |
| 18:06 | hiredman | ~def map? |
| 18:06 | kotarak | jcromartie: and doesn't help with strings and such |
| 18:06 | jcromartie | oh, huh, wow |
| 18:06 | hiredman | ,(struct (create-struct :a :b) 1 2) |
| 18:06 | clojurebot | {:a 1, :b 2} |
| 18:07 | hiredman | ,(map? (struct (create-struct :a :b) 1 2)) |
| 18:07 | clojurebot | true |
| 18:07 | kotarak | ,(type nil) |
| 18:07 | clojurebot | nil |
| 18:07 | jcromartie | yeah |
| 18:08 | kotarak | jcromartie: dispatch on type, and use IPersistentMap, String, nil, and whatever classes you need as dispatch values |
| 18:08 | jcromartie | so I need to catch strings, maps, and a specific Java class |
| 18:08 | jcromartie | so kotarak wins |
| 18:13 | AWizzArd | Am I the only one using deftype regularily? ^^ |
| 18:18 | jcromartie | AWizzArd: no, you and all of the other edge users! |
| 18:18 | jcromartie | AWizzArd: I have to deploy this code :P |
| 18:19 | AWizzArd | Well, I use deftypes in a production environment. |
| 18:20 | jcromartie | that's cool |
| 18:20 | AWizzArd | No need for others to do that, but I just ean: it does not break my code. |
| 18:20 | AWizzArd | ean --> mean |
| 18:20 | jcromartie | I'll use them when they show up when the "Alpha - subject to change" disappears |
| 18:21 | jcromartie | I think I also feel like deftype is too close to Java |
| 18:22 | jcromartie | I feel like you have to know a lot about Java before you really know why you'd want to use it |
| 18:23 | AWizzArd | I don’t even know how to spell jarwa and can use deftype |
| 18:25 | Chousuke | rhickey: http://gist.github.com/311647 One more version. None of these help in the Range case though :/ |
| 18:26 | Chousuke | and I just now noticed one of those calls is missing a name for the iter :P |
| 18:33 | ezyang | Hey guys, does clojure have fold? |
| 18:33 | Chousuke | ezyang: reduce |
| 18:33 | ezyang | aha, cool |
| 18:38 | esj | to use Clojure 1.2 through leiningen I've been trying to use [org.clojure/clojure "1.2.0-master-SNAPSHOT"] |
| 18:38 | esj | [org.clojure/clojure-contrib "1.2.0-master-SNAPSHOT"] but am eating the RestFn error. Which pair of clojure / contrib should I use ? |
| 18:39 | hiredman | clojurebot: RestFn? |
| 18:39 | clojurebot | ant clean and rebuild contrib |
| 18:39 | somnium | hiredman: he's trying to get a pair that works with lein |
| 18:39 | hiredman | but it could mean some other library you are using was compiled for a different version of clojure |
| 18:39 | esj | you know when you get clojure and contrib crossed |
| 18:39 | hiredman | somnium: *shrug* |
| 18:40 | esj | it gives you the RestFn error |
| 18:40 | hiredman | that is the only time I have seen the restfn error |
| 18:42 | esj | how do you keep this square ? |
| 18:43 | hiredman | I don't chase master |
| 18:43 | esj | i mean, how can I check which version of clojure is req'd for a particular jar ? |
| 18:44 | esj | i'm missing what must be an obvious thing |
| 18:44 | esj | hiredman: good advice |
| 18:49 | naeu | what's the best method for communicating via a usb serial connection with clojure? |
| 18:49 | naeu | I was looking at something called rxtx http://rxtx.qbang.org/wiki/index.php/Main_Page |
| 18:50 | naeu | but thought it sensible to check if there's not another accepted method |
| 18:55 | ezyang | Agggh repeatedly crashed my interpreter >:-( |
| 19:03 | ezyang | Suppose I have [1 2 3] and I want [1 1 2 2 3 3]. How can I do this? |
| 19:05 | _mst | ,(interleave [1 2 3] [1 2 3]) |
| 19:05 | clojurebot | (1 1 2 2 3 3) |
| 19:06 | ezyang | hm. will I get the right semantics with a stream? |
| 19:09 | _mst | it depends what you need. You can always coerce it back into a vector using (vec ...) |
| 19:10 | ezyang | well, I'm dealing with a 512K long stream, so I'd rather not have that be resident in memory :-) |
| 19:10 | ezyang | seems to have the right semantics |
| 19:11 | _mst | ah, yep :) interleave is lazy so it won't pull the whole lot into memory if you don't consume it all at once |
| 20:16 | dnolen | anybody mess rhickey's cells stuff from ealier? I curious how you convert the result of mapx, reducex, rangex into a value. |
| 21:23 | slyphon | me is having circular dependency headaches |
| 21:23 | slyphon | asldfijadsiljfliasjf |
| 21:24 | slyphon | is it possible to declare your namespace :use blocks in a common namespace that everything else uses? |
| 21:25 | slyphon | for stuff like clojure.contrib.logging, rather than having to duplicate it everywhere/ |
| 21:25 | slyphon | ? |
| 21:25 | chouser | hn. you can put whatever you want in a .clj file and |
| 21:25 | slyphon | or do people usually just duplicate it everywhere |
| 21:25 | chouser | load-file |
| 21:25 | chouser | dunno if that's "good", but it's possible |
| 21:25 | slyphon | ah |
| 21:25 | slyphon | is it "good" to declare it in each file? |
| 21:27 | slyphon | i'm having trouble figuring out when to use :use/:require, in ruby, for instance, i'd usually have a top-level module that would pull in the other modules in the order they needed to satisfy dependencies |
| 21:27 | chouser | I've never split my files up small enough to desire avoiding repetition |
| 21:27 | slyphon | ok, that's fair |
| 21:33 | hiredman | it would be nice if ns was pluggable |
| 21:33 | slyphon | hrm |
| 21:47 | pthatcher | pthatcher: I started playing with cells and deftype and defprotocol. Hashing (sha1, etc) seemed like a good use case for cells. So, here's my first try at it: http://gist.github.com/311790 |
| 21:57 | brandonw | what would be the idiomatic way of finding an element of a seq that is not equal to a specific value, starting the search at an arbitrary index in the seq, and going backwards? |
| 21:59 | jcromartie | brandonw: (first (filter ... (drop n (reverse coll)))) |
| 22:00 | jcromartie | ooh, or using comp and partial |
| 22:00 | jcromartie | (first (filter (partial (comp not =) x) (drop n (reverse coll)))) |
| 22:01 | jcromartie | The More You Know(tm) |
| 22:01 | hiredman | bleh |
| 22:01 | jcromartie | no good? |
| 22:01 | jcromartie | too much |
| 22:01 | jcromartie | #(not (= x %)) |
| 22:01 | hiredman | seqs arenot really good for indexed access |
| 22:02 | jcromartie | then loop it is |
| 22:02 | brandonw | well, this step will shave off several recursions |
| 22:02 | brandonw | err nevermind that doesn't matter |
| 22:02 | hiredman | jcromartie: loop would not be any different |
| 22:03 | jcromartie | better to use a vec, then? |
| 22:03 | brandonw | well i am constantly taking elements at the start off and on again |
| 22:03 | brandonw | actually, let me check |
| 22:03 | jcromartie | brandonw: what are you trying to do? |
| 22:03 | jcromartie | in the bigger picture? |
| 22:04 | brandonw | yes, it is constantly being operated on and is a seq already |
| 22:04 | brandonw | so i would have to be constantly transforming it back into a vec |
| 22:04 | hiredman | if the seq is what you have, then it's what you have, but using them for indexed access is bleh |
| 22:04 | brandonw | i haven't needed it for indexed access until now |
| 22:05 | brandonw | i'm trying to optimize the last bit of inefficiency in the puzzle solver i made as my first clojure project |
| 22:05 | jcromartie | it sounds like you could use vectors |
| 22:06 | brandonw | well, i am basically using a brute force solver in a constraint satisfaction problem |
| 22:06 | hiredman | jcromartie: vectors won't let him add to the begining |
| 22:06 | brandonw | every time the state of the snake is invalid, i recurse upwards, and transform the current three-dimensional state of the snake on a certain joint |
| 22:07 | brandonw | well, hmmm |
| 22:07 | brandonw | i think i could use a vec in that specific piece |
| 22:08 | brandonw | well actually, this is good because it illustrates my lack of understanding in vecs |
| 22:09 | brandonw | i know they are best for sequential access, but i don't understand how they can be usable if nearly every operation you perform on a vec returns a seq |
| 22:09 | brandonw | unless the *only* thing you use with the vec is nth and other functions that either work very well with arbitrary indices, or are functions specifically designed for vectors (like conj) |
| 22:10 | hiredman | right |
| 22:10 | hiredman | the other operations are not operations on vectors, they are operations on sequences |
| 22:10 | brandonw | okay |
| 22:11 | brandonw | so if i am performing several seq operations per level of recursion, but only using nth once or twice, would it be worth it to convert the seq to a vector just for a couple of index-based calls? |
| 22:11 | hiredman | they call seq on their argument so you can pass a vector or a map or anything that seq can turn into aseq |
| 22:11 | hiredman | brandonw: I don't know |
| 22:12 | brandonw | i'm going to try it with a seq just to see what the speed up is at the moment |
| 22:13 | dnolen | brandow: if it's already a vector |
| 22:13 | jcromartie | can anybody here offer advice on organizing a compojure web app? |
| 22:14 | jcromartie | I feel lost and frightened without a big framework to conform all of my stuff to |
| 22:14 | jcromartie | :P |
| 22:14 | defn | jcromartie: trial and error |
| 22:14 | jcromartie | yay |
| 22:15 | brandonw | haha |
| 22:15 | defn | jcromartie: i suggest doing something like controllers/application.clj, views/application.clj, etc. |
| 22:15 | scottbot | jcromartie: I used to have a 600 line file which contained everything, and am now splitting off small chunks into several 20-50 line files |
| 22:15 | brandonw | jcromartie: make sure you write it up on a blog somewhere. i don't want to go through that ;) |
| 22:15 | jcromartie | yeah :) |
| 22:15 | jcromartie | controllers and views make sense |
| 22:16 | jcromartie | I have a base layer with a JSON api sitting below my ui layer, namespace-wise |
| 22:16 | jcromartie | so it would be like project.ui.views.home.clj |
| 22:16 | defn | yeah i think that's a good way to go |
| 22:16 | jcromartie | API and data |
| 22:17 | dnolen | jcromatrie: organize your code around routes. I would make each namespace a logical application which defines routes which you add to the master routes. I'm against the distinction between controllers and views. It just functions, not MVC. This would especially well if you're using something like enlive to render your pages. |
| 22:17 | ezyang | How do I make Eclipse think it can run a main function from a clojure file? |
| 22:17 | jcromartie | dnolen: that's what I've done with my data/API layer |
| 22:18 | jcromartie | project.access/api is a route, etc. |
| 22:18 | defn | jcromartie: depending on the size of the app im also not opposed to just splitting the whole thing up by functionality, and then having a utils.clj which is the glue, server.clj which handles routes, etc. |
| 22:18 | ezyang | Do I actually have to make a class? |
| 22:18 | jcromartie | yeah |
| 22:18 | brandonw | jcromartie: okay to make it a little more complex... what if i revised my original request to find the element's index instead of the element's value? |
| 22:18 | jcromartie | this is really a quick-and-dirty fast-and-loose app, I want to have it done tonight |
| 22:18 | dnolen | jscromartie: should be the same for your "view" layer as well. it's just functions. Some modify data, other deliver html. |
| 22:19 | jcromartie | dnolen: yup |
| 22:24 | brandonw | i think to get the index i'm going to have to write my own recursion |
| 22:30 | dnolen | brandonw: clojure-contrib.seq-utils. indexed is lazy, why do you need to write your own recursion? |
| 22:40 | brandonw | because i haven't looked at clojure.contrib much, that's why :D |
| 22:40 | brandonw | there is way too much good stuff in clojure |
| 22:40 | brandonw | i need a plug to my brain to just upload it all in |
| 22:42 | brandonw | i've got the recursion done so i guess i'll just leave it and hopefully i remember to look at seq-utils next time... |
| 22:43 | dnolen | brandonw: heh, it does take a while to learn where everything is. I think played around with Clojure for months before I discovered update-in assoc-in :P |
| 22:45 | jcromartie | is http://wiki.github.com/cgrand/enlive/getting-started out of date? |
| 22:46 | jcromartie | because I can't get ID selectors to work based on that sample code in there |
| 22:46 | brandonw | yeah i think i was here the other night when someone mentiond it |
| 22:46 | brandonw | and i was kinda like 'holy crap, is there any trivial piece of functionality that ever actually needs to be implemented? or is it all already here..." |
| 22:47 | dnolen | jcromartie: brandonw: typo |
| 22:47 | dnolen | :div#d1 |
| 22:47 | dnolen | not :div#:d1 |
| 22:47 | jcromartie | ah |
| 22:47 | jcromartie | that makes more sense |
| 22:47 | dnolen | http://github.com/swannodette/enlive-tutorial |
| 22:47 | dnolen | also |
| 22:47 | dnolen | 7 examples |
| 22:47 | dnolen | scrape Hacker News, New Yorks Times, and some really fancy |
| 22:48 | jcromartie | fixed |
| 22:48 | dnolen | templating stuff that mimics Django, Mako, Rails style template inheritance but cooler because HTML and code separations |
| 22:48 | dnolen | my tutorial needs work but the code is there, and it uses lein so it's easy to go through |
| 22:49 | dnolen | once Enlive supports HTML fragments (to support common looping cases) I'll wrap it up and polish it. |
| 22:54 | jcromartie | HTML fragments? |
| 22:54 | dnolen | Enlive has one glaring deficiency. It handles looping a single item in a container well. |
| 22:54 | jcromartie | I want to repeat a whole matched element, but with certain elements transformed |
| 22:55 | dnolen | but not the <h1></h2><p></p> pattern |
| 22:55 | dnolen | used commonly with JS accordions and the like. |
| 22:55 | jcromartie | like, <ul><li><span class="a">I want to transform this</span></span class="b">And this too</span></li></ul> |
| 22:55 | jcromartie | is that doable? |
| 22:55 | dnolen | yes |
| 22:56 | dnolen | even the <h1></h1><p></p> pattern is doable just not pretty. |
| 22:56 | jcromartie | so would I use clone-for? |
| 22:57 | dnolen | for repeating a single item (which can contain other items of course) yes. |
| 22:57 | dnolen | clone-for doesn't handle looping ranges of items, Christophe Grand is working on it tho. |
| 22:57 | dnolen | there are workarounds, check the Enlive mailing list. |
| 22:58 | jcromartie | OK so as an example... |
| 22:58 | jcromartie | I am not finding any good examples of something like what I'm trying to do |
| 22:59 | dnolen | jcromartie: you want to loop the li and replace the contents of span.a span.b right? |
| 22:59 | jcromartie | yeah |
| 22:59 | jcromartie | I feel like I'm missing some docs that I just saw recently, but aren't in the readme/wiki |
| 23:01 | jcromartie | ah |
| 23:01 | jcromartie | (substitute (select ...))) |
| 23:02 | jcromartie | or [:li] (clone-for [x xs] [:span.a] (content x) ...) |
| 23:03 | dnolen | jcromartie: I think you need "at" as well |
| 23:04 | jcromartie | this is working so far |
| 23:07 | dnolen | jcromartie: totally right, need to add an example of clone-for to my tutorial :) |
| 23:12 | jcromartie | holy crap, don't try to print a Date in enlive |
| 23:12 | jcromartie | infinite stack trace |
| 23:13 | dnolen | jscromartie: yeah you always need to convert things to strings first. I make that mistake all the time. |
| 23:28 | defn | how to make a timer in clojure.. |
| 23:28 | hiredman | ScheduledThreadpoolExecutor |
| 23:34 | defn | Can I import a java libary :as X? |
| 23:38 | defn | nvm on the last question... |
| 23:38 | defn | Is there a way to list the possible methods for a java object in the REPL? |
| 23:39 | _mst | (use 'clojure.contrib.repl-utils) then (show (Object.)) |
| 23:40 | defn | _mst: awesome. thank you. |
| 23:40 | defn | _mst: one other question for you... I am just trying to make a basic timer that counts down like 20min or something |
| 23:40 | defn | Is it possible to just do that with a future? |
| 23:40 | _mst | I guess so... but why not just Thread/sleep? |
| 23:40 | defn | _mst: just curious I guess |
| 23:41 | _mst | well, I guess: (future (Thread/sleep (* 20 60 1000))) |
| 23:41 | _mst | will create you a future that'll block for 20 minutes when you call (deref ...) on it |
| 23:42 | hiredman | _mst: nope |
| 23:42 | _mst | hm. what'd I miss? |
| 23:42 | hiredman | futures start immediately |
| 23:42 | _mst | ah, yes. quite right |
| 23:48 | arohner | ,(conj {} '(:a 1)) |
| 23:48 | clojurebot | java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.util.Map$Entry |
| 23:48 | arohner | ,(conj {} [:a 1]) |
| 23:48 | clojurebot | {:a 1} |
| 23:48 | arohner | why does one of those work, and the other doesn't? |
| 23:48 | arohner | ah, (source conj) helps |