#clojure logs

2011-08-17

00:17srid(def very-lazy (-> (iterate #(do (print \.) (inc %)) 1) rest rest rest))
00:17sridI understand what `iterate` does, and even read (doc ->) - but I still cannot understand what the above form does.
00:17sridWhy is a *function* (rest) in place of *sequences* as (2nd, 3rd, 4th) arguments to `->`?
00:25sridah, the documentation confused me; reading the examples at http://clojuredocs.org/clojure_core/clojure.core/-%3E clarified it better.
00:53livingstonanother library has provided a hook to get a callback for each result it generates. if I just want to count them what's the best way in clojure? in commonlisp I' would just (let [count 0] and the pass the callback function (fn [result] (incf count))
00:54amalloyyech, a callback? they can't just provide you with a lazy-seq of results?
00:55livingstonit's what I've got to work with.
00:55amalloyyeah
00:55amalloyi think the best you can do is ape the CL version using an atom
00:55amalloy(let [count (atom 0)] (fn [result] (swap! count inc)))
00:56livingstonwouldn't it be cheaper to use a var and set! ?
00:57amalloyi think the difference would (a) be so small as to be undetectable, (b) i don't know which would be faster
00:57amalloyand actually using set! would be awkward and (not that it matters) not-thread-safe
00:58livingstonbut the var is thread local?
00:59amalloygood point. i guess that means that instead it wouldn't work at all, if they called your callback from any thread but the current one
01:01livingston,(doc set!)
01:01clojurebotExcuse me?
01:01livingston,(doc 'set!)
01:01clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.ClassCastException: clojure.lang.Cons cannot be cast to clojure.lang.Symbol>
01:01livingstonthat was helpful
01:02amalloyit has no doc; it's a special form
01:14amalloyanyway, the performance gain from using a var vs atom is known-small, unknown-sign; and using a var instead of an atom will be harder to read, harder to manage, and might have problems in the face of multithreading. i'm not sure why you're worried about performance here to begin with, since this is such a tiny amount of work
01:16livingstona tiny amount of work times millions or billions of results is a lot of work. and it's easy with the var, I'll show you ...
01:17amacyay, I'm in the top 100 on 4clojure...
01:17livingstonwhat's 4clojure?
01:17amacIf you make the list gigantic I'm on the first page ;)
01:18amacits a bunch of interactive clojure problems, worth a look
01:18amacI only found out about it yesterday
01:18amalloylivingston: if you have billions of results, then for god's sake *benchmark* both approaches instead of debating and speculating about which might be better
01:20livingstonhere's the gist: https://gist.github.com/1150860
01:20amalloy&(with-local-vars [v 1] (let [update (fn [] (var-set v (inc (var-get v))))] (time (dotimes [_ 1e7] (update)))))
01:21lazybot⇒ "Elapsed time: 4001.617115 msecs" nil
01:21amalloy&(let [a (atom 0) update (fn [] (swap! a inc)] (time (dotimes [_ 1e7] (update))))
01:21lazybotjava.lang.IllegalArgumentException: let requires an even number of forms in binding vector
01:21livingstonvar has to be faster - no thread locks. also I need the data by yesterday... probably will only get to run this once
01:21amalloy&(let [a (atom 0) update (fn [] (swap! a inc))] (time (dotimes [_ 1e7] (update))))
01:21lazybot⇒ "Elapsed time: 2519.085785 msecs" nil
01:21amalloylivingston: it looks like you're wrong
01:22livingstonhow is that possible?
01:22livingstondon't atoms have to play with the STM?
01:22amalloy*shrug* fewer function calls? don't worry about the internals
01:23livingstonI'll have to repeat that test a few times though to be sure...
01:29livingstonhow do I get the value of an atom?
01:29tufflax@the-atom
01:30livingstonthanks
01:30livingstonthanks for the help ... gotta run.
01:56sridcaffeine and the-joy-of-clojure to spend the evening. perfect.
01:57sshackHi. So I'm trying to install leiningen. I've cloned the git repo and tried to run leon self-install, but get a 404 when maven tries to download stuff.
01:57sshackOn first impression, I'm underwhelmed.
01:58sshackFrom the documentation this seems to be the correct thing to do. From practice, it isn't. What's the correct way to install leiningen?
02:01sridI never had to clone the repo; just downloaded https://github.com/technomancy/leiningen/raw/stable/bin/lein and ran it.
02:13ibdknox_sshack: yeah, you shouldn't download the repo.
02:13sshackibdknox_: Yeah I got it. Works now.
02:13sshackNow is there a way to download plugins in advance? (for disconnected work)
02:13ibdknox_lein plugin install?
02:13ibdknox_what do you mean by plugin exactly?
02:13ibdknox_like project dependencies?
02:17sshackYeah.
02:18sshackLike ring, or clj-stacktrace or whatever.
02:18ibdknox_assuming you always use the same version
02:18ibdknox_and it's not a snapshot
02:18ibdknox_it caches the dependencies in ~/.m2/
02:18ibdknox_so yes
02:18ibdknox_you would be fine
02:19ibdknox_though that would only matter if you were creating new projects
02:19bool_hello
02:20sshackWell, say I want to add a frequently used library to a new project. That's when It'd come in handy.
02:20sshackBut okay, I can live with this for now.
02:20bool_if anyone here has a spare minute or two
02:21bool_mind critiquing my first program? https://github.com/bool-/clojure-irc-bot/tree/master/src/anthony/ircbot
02:22amalloywell, your syntax for if/else is broken
02:22bool_mind explaining? =O
02:23ibdknox_bool_: you use an awful lot of java string functions
02:23bool_ibdknox_ are their clojure-alternatives?
02:23bool_there*
02:23ibdknox_clojure.string/split
02:23bool_oh alright
02:23bool_i was unaware
02:23ibdknox_,(doc subs)
02:23clojurebot"([s start] [s start end]); Returns the substring of s beginning at start inclusive, and ending at end (defaults to length of string), exclusive."
02:24amalloybool_: the syntax for if is (if test then else)
02:24ibdknox_bool_: no worries, it's not wrong, you just asked for critique
02:24bool_oh
02:24bool_okay
02:24bool_makes more sense
02:24bool_i was thinking a macro for else was kind of a ridiculous solution
02:25ibdknox_bool_: you should use condp instead of cond in your on-connected
02:25amalloy(if test (then)) (:else (whatever)) executes (then) if test is true, and then returns the result of looking up :else in the map returned by (whatever)
02:25bool_p = predicates?
02:25ibdknox_actually, I don'w know what the p is for, do you amalloy?
02:25amalloypredicate
02:26amalloy(condp < x 4 "4 is less than x")
02:26amalloyie, compare x with each clause (here there's only one) using the < predicate
02:26ibdknox_though that's not really a long-term solution
02:27bool_ibdknox_ i was going to map server to a list of channels
02:27sshackibdknox_: I figured it out. lein plugin install ring 0.3.11 Installed on a per user basis.
02:27bool_so the cond there is temp
02:27sshackI'm very happy now.
02:27ibdknox_sshack: I'm not sure that's doing what you actually want
02:28ibdknox_sshack: that will only be available to you if you are running leiningen. If you tried jaring that project, it will be missing ring
02:28amalloyi'd say it's pretty reasonable bool_. plenty of things to improve, but missing most of the horrendous gaffes you tend to make in your first program
02:28amalloyare you aware that keywords and maps can be called as functions, instead of using get?
02:28bool_i've used haskell before so i'm familiar with functional programming (to a certain extend)
02:29bool_nope, i was unawake of that
02:29amalloy&(let [m {:test 1}] (:test m))
02:29lazybot⇒ 1
02:29bool_so i can just do (:keyword map) ?
02:29sshackibdknox_: So those jars won't be available if i'm disconnected from the net?
02:29amalloy*nod*
02:29bool_oh cool
02:30amalloybool_: you can actually do better still in most of your uses of get
02:30amalloybecause of the super-duper destructuring feature. a teeny tiny bit like haskell's pattern-matching, but not really
02:30ibdknox_sshack: yes, they will. but they are not a part of your project, they are a part of leiningen
02:30bool_i see
02:31ibdknox_sshack: to have jars downloaded locally all you need to do is add them to your project.clj and call lein deps
02:31sshackibdknox_: Great. so I can pull them into a project at any time? That's what I'm looking for.
02:31amalloy&(let [m {:host "irc.freenode.net" :writer "whatever"}] (let [{:keys [host writer]} m] (println host writer)))
02:31lazybot⇒ irc.freenode.net whatever nil
02:31ibdknox_sshack: lein deps will then just read from your cache in ~/.m2/ and you'll be fine
02:31ibdknox_so the right way to do it is add the deps you will need to your project and call lein deps.
02:32ibdknox_sshack: after that, you're good to go :)
02:32alex`hey.. ibdknox.. you wrote socket.io-netty, right?
02:32ibdknox_uhoh
02:32ibdknox_lol
02:32ibdknox_alex`: yes
02:32amalloybool_: that is, anytime you could (let [var-name value]), you can substitute a destructuring form/pattern for var-name, and it will break apart value in the way that you specify
02:32alex`heh.. nice work.. do you know if it works cross domain?
02:32sshackibdknox_: Oh. hrm. So leon will cache everything once I use it?
02:32ibdknox_sshack: correct
02:33bool_intersting
02:33ibdknox_alex`: yep
02:33amalloy&(let [[x y z] (range 10000)] (+ x y z))
02:33lazybot⇒ 3
02:33sshackThat gets the desired behaviour then. Cool.
02:33alex`sweet.. good to know.. i might be using it
02:33ibdknox_alex`: it's rough around the edges, but it works well enough
02:34depyworkwhat's the difference when you do &(expr) or ,(expr) ?
02:34sshackibdknox_: The use case was I'm on an airplane and suddenly think "Shit I forgot to add foobar-clj to my project. But I'm away from internet, so I can't do it"
02:34amalloydepywork: a different bot wakes up
02:34amalloy,1
02:34amalloy&1
02:34lazybot⇒ 1
02:34clojurebot1
02:34depyworkOh.. Didn't notice that :)
02:34ibdknox_sshack: it'll be fine as long as you've downloaded that version for some other project before
02:35sshackThat Works for me.
02:50bool_is there a clojure-equivalent of indexOf
02:56amalloyi mean, maybe, but one generally tries to write clojure so that indexes aren't relevant
02:56amalloybool_: link me to the line where you want indexOf?
02:57bool_https://github.com/bool-/clojure-irc-bot/blob/master/src/anthony/ircbot/irc.clj#L6
02:57bool_and wow the destructuring makes code a lot cleaner
02:58amalloybool_: probably use re-seq there to pull it apart with a regex
02:58bool_regex is hardly an appropriate solution to parsing irc messages imo
02:59amalloybool_: you're using .indexOf, you don't really get moral high ground
02:59bool_i suppose
02:59bool_it seems more appropriate than regex
02:59jblomobool_: you can just use .indexOf. clojure strings are java strings
02:59bool_i know jblomo
02:59jblomo(.indexOf "string" (int \s))
02:59bool_i was just wondering if there was an alternative
03:02amalloy$javadoc String split
03:02lazybothttp://download.oracle.com/javase/6/docs/api/java/lang/String.html#split(java.lang.String,%20int)
03:06amalloy&(let [line "foo!bar@baz test", [nick more] (.split line "!" 2), [user host] (.split more "@" 3)] [nick user host])
03:06lazybot⇒ ["foo" "bar" "baz test"]
03:07amalloy&(let [line "foo!bar@baz test", [nick more] (.split line "!" 2), [user more] (.split more "@" 2), [host] (.split more " ")] [nick user host]) ;; more like what you want, i guess
03:07lazybot⇒ ["foo" "bar" "baz"]
03:07amalloybool_: ^?
03:07bool_hmm
03:07bool_that is quite a bit better
03:08jblomoanyone know if ns-resolve, ns-aliases, *ns* are going to make it into clojurescript?
03:08amalloyi'm sure we can do better with something like ##(doc reductions)
03:08lazybot⇒ "([f coll] [f init coll]); Returns a lazy seq of the intermediate values of the reduction (as per reduce) of coll by f, starting with init."
03:13amalloybool_: https://gist.github.com/1151010 is longer but less tedious and micromanaged
03:16bool_i ended it just going with the split solution
03:16bool_UP*
03:16bool_up*
03:16amalloy*laugh*
03:17amalloywell, this is the split solution, but less dense and more extensible. i prefer it, but i can see how you might not
03:17bool_i don't see any need to extend it
03:17bool_lol
03:17bool_it's not like the rfc is going to change that
03:18bool_i don't see a new irc standard any time soon breaking that
03:18amalloyfeh. irc is such a fad
03:18ibdknox_amalloy: I didn't know about reductions, that's fun
03:19bool_i just pushed an update per (all?) of your suggestions
03:19amalloyi'm only here b/c i heard miley cyrus uses irc
03:20amalloyibdknox_: it's neat, isn't it? i rarely get a chance to use it; reduce is usually enough
03:20amalloyas, indeed, it was here
03:20ibdknox_yeah, I'm trying to think of when I would *need* to use it
03:20bool_well, it's midnight i'm off to bed
03:20bool_good night
03:20bool_thanks for the help
03:21amalloyibdknox_: the classic (if there is one?) is to keep reducing until you hit some cutoff accumulator value, and then stop
03:22ibdknox_yeah, there have been a couple of times when I've wanted that
03:22ibdknox_often when parsing arg collections
03:22amalloylike maybe ##(last (take-while #(< (count %) 10) (reductions str ["a" "sfdsa" "bvmez" "sdfewce"])))
03:22lazybot⇒ "asfdsa"
03:22ibdknox_though I think dnolen's match will be better for that
03:24amalloyparsing arg collections? when is reductions useful for that?
03:24amalloyfor that sort of task i'd usually reach for split-with, if i understand what you mean
03:26ibdknox_so like in noir you can do (defpage foo [:post "/blah"] [] ...)
03:26ibdknox_but you can also do
03:26ibdknox_(defpage "/blah" [] ...)
03:27ibdknox_I could imagine you could use reductions to homogenize all the different forms of those definitions
03:27ibdknox_maybe not though
03:27amalloyhm
03:28ibdknox_it's a great place for match though
03:28ibdknox_I think that would be the cleanest solution
03:30ibdknox_my current implementation is essentially like a reduction
03:30ibdknox_https://github.com/ibdknox/noir/blob/vnext/src/noir/core.clj#L26
03:32amalloyibdknox_: whoa, are you using tabs for indentation or something? the indentation of the last line of parse-fn-name makes it look like part of the let
03:32ibdknox_oh weird
03:33ibdknox_I've been trying this emacs thing you guys keep talking so much about ;) and switching between vim and emacs over and over again hasn't been friendly
03:33amalloy*chuckle*
03:33amalloyi went through a period like that with eclipse and emacs
03:34amalloymaking me less old-school hard-core, i guess
03:34ibdknox_haha
03:37manuel_the good thing about emacs is that both eclipse and macosx have the same basic navigation shortcuts
03:37manuel_+ killring
03:37somejan\
03:37amalloyhow are emacs, macos, and eclipse related?
03:38somejan\join #python
03:38manuel_they're all computer programs
03:38amalloycome to think of it that sounds like a setup for some weird joke
03:38ibdknox_lol
03:38manuel_heh
03:39thorwilibdknox: with noir's defpage, how is the order in which routes are matched defined?
03:39gstamp   while we're on the topic of emacs… anyone a mac emacs user? I have this slight annoyance that if I move the carot too quickly the screen updates don't keep up so I can't tell where my carot is
03:39manuel_gstamp: which emacs variant?
03:39amalloyoh, you mean the way that most macos apps support readline-style commands like C-w, in addition to Cmd-x?
03:39manuel_i'm using emacs23 in terminal
03:39ibdknox_thorwil: it's intentionally not defined
03:40manuel_amalloy: i have ctrl-space + ctrl-w yes
03:40manuel_i think i hacked something in a plist somewhere to enable it
03:40gstampthe one from here: http://emacsformacosx.com/
03:40ibdknox_thorwil: but you have the ability to define pre-routes for filtering and as of last night post-routes for special catch alls, but those should be used sparingly
03:40amalloyright. i'm on linux, but during my very brief stint on macos i did find that quite nice
03:40manuel_gstamp: i guess it's the cocoa build, right? dunno about that
03:41manuel_i'm using the terminal version with iterm so that i will find the same environment on every machine i possibly can come into contact with
03:41thorwilibdknox: what happens if you use neither pre-routes nor post-routes, but have to deal with a request where more than one defpage matches?
03:42gstampmanuel_: I think so. I tried building with brew a weeks back but the compilation was failing.
03:42manuel_yeah, i had to fix the emacs.rb
03:42ibdknox_thorwil: can you give me an example where that's true?
03:47thorwilibdknox: hmm, for example, if you have a "catch-the-rest" handler to present a 404, after all other routes failed. the way i use that with moustache, this one must be last in the list
03:48ibdknox_that already exists :)
03:49ibdknox_thorwil: there's a route at the end that will return a 404 code, and then a piece of middleware picks that up and gets the right page for that status
03:49ibdknox_thorwil: to change what that page's content is, you'd used this: https://github.com/ibdknox/noir/blob/master/src/noir/statuses.clj#L15
03:50thorwili admit i have a hard time of thinking of another case where several routes might match
03:50ibdknox_:)
03:51ibdknox_thorwil: I did too
03:51thorwilso it seems if you special-case 404, order doesn't matter elsewhere
03:51ibdknox_exactly
03:51ibdknox_and there's power in that
03:51amalloyibdknox_: hrm. i instinctively feel it's evil for you to decree that a 404 has *only one* static output
03:51ibdknox_amalloy: it doesn't
03:51ibdknox_amalloy: I only do that if you haven't given me a body
03:52amalloybut i assume you can always return actual content with a code of 404
03:52ibdknox_yessir
03:52amalloyokay. well, you're off the hook this time
03:52ibdknox_:D
03:54amalloyi keep forgetting to check whether (defn foo [x] [:bar :baz]) computes the result at compile time or rebuilds it every time the function is called
03:54amalloyif anyone else is excited to know the answer to that question, feel free to check it out and report back to me
03:54ibdknox_lol
03:58ibdknox_alright, g'nite #clojure. :)
04:00pyrok i get how easy it is to make DSLs which look like they are providing functions when doing everything inline
04:00pyryou just have a dispatch match {'fun1 (fn [] ...), 'fun2 (fn [] ...)}
04:00pyrand apply to these functions
04:01pyr(map (fn [[fname & fargs]] (apply (dispatch fname) fargs)) some-forms)
04:01amalloywhut. i cannot imagine anything that comes after this introduction can be good news
04:02pyrthat makes macros easy when they're inline
04:02pyr(i.e: not using `)
04:03pyrbut is it just me or it becomes a world of pain once you want to introduce user supplied symbols in there
04:05amalloypyr: of course it's a pain. you're doing something crazy
04:06amalloyi don't understand even a toy use-case for what you're describing
04:07pyri was starting from the example macro in joy of clojure
04:08pyrwhich reduces a DSL to a string (an SQL query)
04:08amalloyif anyone's curious: (fn [x] [:foo :bar]) stores :foo and :bar at compile-time, but builds the vector every time
04:09pyramalloy: (SELECT [a b c] (FROM ...))
04:10pyrwhich reduces to a vector of query string and arguments
04:10amalloyright. that's not a very flexible macro, and iirc they say so
04:11pyryes
04:11pyrso, just use keywords instead to dispatch
04:12amalloykeywords won't make it any easier
04:12amalloyor not much, anyway
04:12amalloyjust...if a macro does extensive manipulation/replacement of the form you pass it, don't expect it to handle many corner cases
04:13amalloyinstead, write smaller macros or functions that do simple things, and combine them into a bigger thing
04:13pyrmy reasonning was this
04:13pyri have a schema to describe
04:13pyrmy internal storage is a record
04:14pyrwhich would be painful to write
04:14pyrso i provide a macro to reduce forms into this record
04:15pyr(schema :foo (entity :bar) (entity :baz (unique)))
04:15pyrfor instance
04:16pyrargs are mapped to an entity function, whose args are mapped in this case to unique (which sets a flag to true)
04:16pyrtwo levels of reduce are then done to get the final correct representation
04:16pyrmaybe that's completely crazy
04:17amalloythe general idea isn't crazy, but the implementation might be
04:17pyr:)
04:18pyryou mean it has to be crazy
04:18pyrbecause there's no sane way of doing it
04:18amalloyi write such macros as (schema :foo :entities {:bar [], :baz [:unique]}) or some such
04:18pyror
04:18pyryeah
04:18pyri went that way but thought it wasn't readable
04:18pyr(or you mean you think i'll do a crazy implementation)
04:20amalloyi mean that (a) asking the user to write (entity) over and over is rude, and (b) an implementation that parses this input format is going to have to be more complicated than my map-based approach
04:20pyryes totally agreed
04:20pyri initialy went with a map
04:20pyrmaybe i'm overthinking it
04:20pyrindeed
05:24fliebelI found 3 HTTP clients, but I can't decide. http.acync.client, clj-http and Aleph.
05:28clgvthe name aleph sounds nice. no other opinion here ;)
05:32fliebelclgv: Okay, I'll go with aleph :)
05:33ejacksonaleph has a really nice library behind it
05:33fliebelActually, that's more because I figured I might use the server as well, and I need streaming as well.
05:33fliebelBut Aleph looks more complicated than clj-http
05:34fliebelChannels are weird, I wonder where this is leading: http://dev.clojure.org/display/design/Asynchronous+Events
05:37ejacksoni think they're awesome
05:37ejackson:)
05:37ejacksoni use a more basic idea in my own code
05:38ejacksontake async thingies and get a seq over em, nice
05:48fliebelHuh, the Aleph client *uses* clj-http! https://github.com/ztellman/aleph/blob/master/src/aleph/http/client.clj#L17
07:33lnostdal_hi guys, so theres dynamic variables and then there's with-local-vars .. with-local-vars would be what i'm after, but it's lexical only (hm, right?) .. so not quite .. dynamic vars are not mutable; not even thread-locally, so i got to wrap the value in an atom e.g. to mutate even when there is no concurrency going on .. i'm probably missing something, but what?
07:33lnostdal_..with-local-vars would be what i'm after because it has var-set
07:34leo2007how large is clojuredocs git repo?
07:35manutterlnostdal_: what are you looking for, mutable vars?
07:35lnostdal_manutter, something like "mutable dynamic vars"
07:35lnostdal_i mean since they're dynamic and thread bound; there's no concurrency issues to begin with
07:35manutterleo2007: I don't remember how big the clojuredocs repo was, but it was something like a couple meg I think?
07:36sliloleo2007: "Receiving objects: 100% (2419/2419), 1.98 MiB | 332 KiB/s, done.
07:36sliloResolving deltas: 100% (978/978), done."
07:36leo2007for offline usage, do I need mysql?
07:36manutterlnostdal_: I'm confused maybe: I thought dynamic vars *were* mutable, using set!
07:36leo2007silven and manutter: thanks.
07:37clgvlnostdal_: thread local binding with atoms works for that use case
07:38manutterleo2007: I forget what db it uses, but I know you need rake to run the search engine
07:39lnostdal_manutter, odd, i was attempting to tab-complete "set" , but no result .. but it's really there anyway .. that's what i was looking for
07:39lnostdal_thank you
07:40manutterlnostdal_: I usually use atoms myself, just to keep myself in the "vars == immutable" frame of mind :)
07:41lnostdal_reset! || set! ... meh .. :)
07:42manutterleo2007: found the docs: clojuredocs uses Ruby 1.8.7, Rails 2.1.5, MySQL 5.1, bundler, Sphinx 0.9.9 and optionally RVM.
07:43leo2007yeah, setting that up is a painful process. I love plain html. The common lisp hyperspec works splendidly.
07:43manutterI think it's time ClojureDocs was re-written in Clojure ;)
07:46leo2007How can I download https://github.com/clojure/clojure/tree/gh-pages using the download button?
07:47leo2007It downloads clojure not the docs.
07:47vijaykiranleo2007: just clone the repo ?
07:48leo2007vijaykiran: sure. I was just wondering why clojure.org gives that advice.
07:52vijaykiranleo2007: I guess the download does contain the docs .. from the gh-pages branch (sorry If I missed context of your question)
07:52leo2007vijaykiran: it doesn't.
07:53sliloleo2007: https://github.com/clojure/clojure/tarball/gh-pages
07:53vijaykiranleo2007: I just clicked on download on https://github.com/clojure/clojure/tree/gh-pages and clocked on Download .zip
07:53vijaykiranleo2007: the branch in the dialog says Branch:gh-pages
07:54leo2007vijaykiran: I see this http://imagebin.org/168351 when clicking on the downloads button on the top-right corner.
07:56slilothere are two buttons, for tar.gz and zip archives
07:58vijaykiranleo2007: you can try the link slilo posted - should download the tar.gz directly
08:00leo2007silven: I see. I was confused by that. the interface at http://repo.or.cz is better.
08:00slilono way )
08:16leo2007can special forms contain doc-string?
08:16leo2007(doc def) => Please see http://clojure.org/special_forms#def
08:16clojurebotexcusez-moi
08:20clgvleo2007: why do you ask?
08:20leo2007because (doc SPECIAL-FORM) always points to a link
08:20leo2007instead of just show me the doc-string
08:21clgvI guess that's because it's described their in more detail than they could within the docstring I guess
08:22clgvspecial forms are as well not implemented in clojure but defined by the clojure compiler
08:27leo2007Can someone give me an example of making a doc* macro that is the same as doc but eval its arg
08:32clgv(defn doc* [arg] (doc arg)) -> argument gets evaluated before the call and doc is called on it afterwards
08:32slilo(/ 1 0)
08:32clojurebot#<ArithmeticException java.lang.ArithmeticException: Divide by zero>
08:33clgvhumm doesnt work that well. doc expects a var
08:33clojurebothttp://haacked.com/images/haacked_com/WindowsLiveWriter/IConfigMapPathIsInaccessibleDueToItsProt_1446B/works-on-my-machine-starburst.png
08:34clgvleo2007: try that one (defn doc* [arg] (-> arg meta :doc))
08:34slilo(iterate inc 0)
08:34slilois there a manual for bot? :)
08:35clgvyou have to prefix calls to clojurebot via ,
08:35clgv,(+ 1 2)
08:35clojurebot3
08:35slilo,(iterate inc 0)
08:35clojurebot(0 1 2 3 4 ...)
08:35clgvfor lazybot it is &
08:35clgv&(+ 1 2)
08:35lazybot⇒ 3
08:35slilothank you, clgv
08:56simonjHow can I pass a Seq to a Java method where each item in the seq is a different argument to the method?
08:57clgvsimonj: I guess you can't.
08:57leo2007clgv: but (doc* (symbol "defn")) still fails
08:57leo2007sorry I am not familiar with clojure yet.
08:58clgvleo2007: what exactly are you trying to do?
08:59cemericksimonj: There's no built-in way to do that. Java methods do not have an equivalent of apply.
08:59clgvthat works pretty well as it is: ##(doc defn)
08:59lazybot⇒ "Macro ([name doc-string? attr-map? [params*] body] [name doc-string? attr-map? ([params*] body) + attr-map?]); Same as (def name (fn [params* ] exprs*)) or (def name (fn ([params* ] exprs*)+)) with any doc-string or attrs added to the var metadata"
08:59cemerickWriting an apply-interop macro wouldn't be tough, tho.
08:59simonjcemerick: bother. What about constructors? Same deal I would imagine.
09:00cemericksimonj: Indeed; Java has no apply, and everything is positional.
09:00leo2007clgv: using your definition of doc*, (doc* (symbol "defn")) returns nil here.
09:01clgvleo2007: thats right since the symbol has no metadata
09:02clgvleo2007: so again, what exactly do you want to do?
09:02simonjcemerick: ok, thanks.
09:03clgvis there some built-in identity macro? I could use it within a "(->" statement
09:04leo2007clgv: I want to see if documentation-symbol in swank-clojure can be more helpful.
09:04leo2007it uses print-doc and seems to return nil for many things
09:05clgve.g.?
09:06WeisshauptGot a quick Leiningen question. I have generated some protocol buffer classes in src/models/Models.java and added :java-source-path "src" to my project.clj.
09:07WeisshauptHowever, when doing "lein compile" javac doesn't seem to add the jars in libs to its classpath.
09:07leo2007clgv: def
09:07clgv,(doc def)
09:07clojurebotexcusez-moi
09:07clgv&(doc def)
09:07lazybotjava.lang.SecurityException: You tripped the alarm! def is bad!
09:07clgvI get:
09:07clgvuser=> (doc def)
09:07clgv-------------------------
09:07clgvdef
09:07clgvSpecial Form
09:07clgv Please see http://clojure.org/special_forms#def
09:08clgvand thats ok since it's described their in detail ;)
09:10leo2007clgv: I am talking about the documentation-symbol in swank-clojure: see basic.clj line 250
09:11clgvleo2007: ok. cant help you with that since I do not use it
09:11leo2007alright.
09:11clgvbut I have a feeling that you might waste your time with that "task" ;)
09:11cemericksimonj: somethign like this should work: https://gist.github.com/1151504
09:13simonjcemerick: awesome! Thank you.
09:14cemericksimonj: You're welcome. That is pretty trivially adaptable to do the same sort of thing with ctors as well.
09:14cemerickor maybe a separate apply-new macro would be better *shrug*
09:15xian,`foo
09:15clojurebotsandbox/foo
09:15clgvcemerick: that won't work for list that are not evaluated until runtime I guess
09:15xianis it possible to use the backquote templating syntax (i.e. ` and ~) without symbols expanding to their fully qualified names?
09:16cemerickclgv: Right, it's a macro. If you want a runtime apply, then a corollary fn would be required.
09:16clgvcemerick: ok, thats what I thought. just wanted confirmation
09:17dnolenxian: `(~'foo)
09:17dnolen,`(~'foo)
09:17clojurebot(foo)
09:17dnolen,`(foo)
09:17clojurebot(sandbox/foo)
09:18xiandnolen: thanks
09:21cemerickclgv: Actually, in that case, just a simple eval will do.
09:21clgv,(doc eval)
09:21clojurebot"([form]); Evaluates the form data structure (not text!) and returns the result."
09:22clgvso building the list of the call and evaling it then
09:22cemerickIt's simpler than it sounds. :-)
09:22cemerick,(let [k [0 4] string "foobar"] (eval `(.substring ~string ~@k)))
09:22clojurebot#<Exception java.lang.Exception: SANBOX DENIED>
09:22cemerickeh, whatever
09:23cemericksandboxes aside, if you need to spread args of unknown length at runtime, you're going to either use reflection or eval.
09:24cemerickof course, simonj is gone :-P
09:26clgvI don't do that much interop anyway. just curiosity - who knows if it can be useful later ;)
09:37WeisshauptSo, leiningen. Trying to compile some java I've got included via :java-source-path. It doesn't seem to add the jars in libs/ to the javac classpath. Anyone familiar with this?
09:38clgvWeisshaupt: by default that folder is called "lib" but you may specify a different one in the project.clj
09:39WeisshauptSorry, it is the default "lib".
09:40WeisshauptIt's a generated file which references classes in "lib/protobuf-java-2.4.1.jar", if I go "javac src/Models.java -cp lib/protobuf-java-2.4.1.jar" it works cleanly.
09:51clgvhumm strange.
09:52manutterWeisshaupt: version of leiningen?
10:10TimMcamalloy_: I went through the rest of that paper. It seems to me that one should speak of the *minimum* order of a function, which is defined as 1 + the highest minimum order of any functions in its contract.
10:18Weisshauptmanutter: Leiningen version 1.6.1
10:19WeisshauptI can see, when doing "lein classpath" that the specific jar is in there. I dunno, maybe I screwed up somehow..
10:19manutterWeisshaupt: yeah, it should work when used as you describe
10:20manutterwhat's the exact symptom that makes you say it's not finding the jar?
10:20WeisshauptWell, doing a "lein cokmp
10:20flazzwhere can i download the vimclojure.jar?
10:20WeisshauptDoing a "lein compile" gives me a bunch of "cannot find symbol: class BuilderParent".
10:21WeisshauptBut when I simply go "javac source -cp libs/protobuf-java-2.4.1.jar" it compiles/
10:24manutterAre you pulling in the jars by adding a "protobuf" line to project.clj?
10:33raekRaynes: there seems to be a problem with try-clojure.org. (try to evaluate anything)
11:07Weisshauptmanutter: Yeah, the protobuf jars are in project.clj.
11:07WeisshauptI think I saw an option in project.clj to ignore classes you've built manually, somehow. I guess I can go that route.
11:09manutterYeah, I'm out of clues, best I can do at this point is wish you luck.
11:09Weisshaupt:)
11:44jcromartiehow would I instantiate a java.lang.ProcessBuilder from Clojure?
11:45clgvjcromartie: using its constructor like (ProcessBuilder. param1, param2, ...)
11:46jcromartieits constructors are: ProcessBuilder(List<String> command) and ProcessBuilder(String... command)
11:46jcromartieso it's not that simple
11:49jcromartiehow do you create a List<string> from Clojure? is that possible?
11:50dnolen,(bases (class '(1 2 3)))
11:50clojurebot(clojure.lang.ASeq clojure.lang.IPersistentList clojure.lang.IReduce java.util.List clojure.lang.Counted)
11:51jcromartiegot it
11:51jcromartieI didn't realize that Java generics were purely compile-time, so at runtime it doesn't care what you pass!
11:51jcromartieawesome
11:51manutter:D
11:51jcromartieso (ProcessBuilder. ["foo" "bar"])
11:52sleepynateamalloy_: is there a "Run" hotkey on 4clojure?
12:01sleepynateanyone know if there's a big speed difference between lambdas partials, and #() ?
12:02sleepynatei'm guessing not
12:05mdeboardsleepynate: #() == lambda
12:06sleepynate(fn) is what then?
12:06mdeboardan anonymous function
12:07sleepynatefair enuogh... so any major difference between (fn), #(), and partial?
12:07clgv#() is a reader macro that is expanded to a fn-form afaik
12:07sleepynateclgv: yea, i don't have a repl handy
12:07mdeboardYeah that's what i"m saying
12:08lucian&(type #())
12:08lazybot⇒ sandbox7610$eval12974$fn__12975
12:08mdeboarda lambda function is an anonymous function is (fn) is #()
12:08clgvpartial is a function returning a fn
12:08lucian&(type (fn []))
12:08lazybot⇒ sandbox7610$eval12983$fn__12984
12:08sleepynateok so they're all pooping out the same thing
12:08sleepynateessentially
12:08lucian&(partial + 1)
12:08lazybot⇒ #<core$partial$fn__3678 clojure.core$partial$fn__3678@104cfd0>
12:08lucianuh, forgot type
12:08sleepynatealmost
12:09sleepynate:/
12:09luciansleepynate: partials are slightly special, but fn and #() are the same
12:09sleepynatethe question i want to get to the root of "is there one that is preferred speedwise?"
12:09sleepynatefor example coming feom clisp and haskell, i'm fond of partials, but i know the same pattern in pythong costs
12:10luciansleepynate: python partials are ok
12:10luciansleepynate: and premature optimisations are indeed the root of all evil :)
12:11luciansleepynate: #() and fn are just java methods. partial, i don't know
12:11clgvsleepynate: measure their performance for your usecase.
12:11lucianwhat clgv said
12:11opqdonutclojure.contrib.profile is nice
12:12opqdonut( http://richhickey.github.com/clojure-contrib/profile-api.html )
12:12opqdonutfor simple benchmarks
12:12sleepynateahh the classic stodgy programmer way of saying "i don't know" :)
12:12opqdonutI would assume that fn and partial are as fast
12:13sleepynateyea. my interest at the moment is purely academic
12:13mdeboardsleepynate: Clojure's 4 years old, infancy for a language. If you want to know you'll almost certainly have to benchmark it yourself
12:13sleepynatesince you have a dynamic language built on top of a static language, how do you rectify not being super slow in creating partials
12:13sleepynatemdeboard: sure, and that's fair
12:14mdeboard"built on top of a static language" is not right
12:14luciansleepynate: java's object system is totally dynamic
12:14luciansleepynate: so all clojure fns implement IFn
12:14lucianclojure is very "close to the metal"
12:15sleepynateIFn is a jvm thing or clojure thing?
12:15st3fanput the pedal to the metal
12:15manutterIFn is a Java interface
12:15sleepynateok
12:16sleepynateso in haskell and i *believe* scala, we know that it's safe to always create a partial because not only everything is a function, but everything is a typed function
12:17luciansleepynate: how would it not be safe to make a partial?
12:17sleepynate(str (partial + 10) "derp")
12:18sleepynatethis would (i'm assuming) raise an exception
12:18clgvtry it ;) ##(str (partial + 10) "derp")
12:18lazybot⇒ "clojure.core$partial$fn__3678@1ebea8derp"
12:18dnolensleepynate: partials are not slow in Clojure if that's what you're asking.
12:19sleepynatednolen: partially. more asking myself "how would i design this same thing"
12:19luciansleepynate: i don't see how that's less safe than calling a function with the wrong args
12:19sleepynatei'm sure many of you wrote lisp interpreters in non-lisps for shits and giggles ;)
12:20dnolensleepynate: never bothered. Clojure fortunately is compiled.
12:23manutterI've done lots. Well, actually, I've written buggy and slow implementations of small portions of LISP.
12:23manutterI call it "PHP code"
12:24jcromartiecheck out my super-slick 100%-true-to-original Markdown lib for Clojure https://gist.github.com/1151940
12:24sleepynatelucian: well, in haskell, you can see whether it's going to fit the type where it's applied, and then consider it to be the equivalent of a constant of that type. in clisp using comething like cl-op, you lose a lot of time by essentiall re-expanding a buttload of anonymous functions
12:25sleepynateso while they'll both explode eventually, if you can you probably want to explode before you get to the nth level down
12:25luciansleepynate: it still seems pointless to me
12:25lucianperhaps i like python too much
12:25sleepynateok
12:25manutterjcromartie: lol, love it
12:26jcromartie (and no it doesn't leave processes hanging around)
12:26sleepynatelucian: that said, until i got sucked up as an android developer, i was doing cython on robots :D
12:26luciansleepynate: in a dynamic language, you tend not to care
12:27jcromartiesleepynate: that sounds like a fun job
12:27sleepynatejcromartie: it was fuckin' sweet
12:28lucianawesome indeed
12:28sleepynatejcromartie: i got to do a bunch of benchmarking on stuff ported from old LISP ai papers into itertools and then compiled
12:28luciansleepynate: btw, clojure is useless on android atm, sadly
12:28sleepynatelucian: yea, i already found out :(
12:29lucianmaybe an approach similar to clojurescript might work instead
12:29sleepynatehowever... if we can improve the speed by pondering over the type system's effect on the creation of partials...
12:29sleepynate;D
12:29luciansleepynate: then we'd waste time we could better spend on useful things! :P
12:29sleepynatethat is not a very good hacker attitude
12:30mdeboardwhat.
12:30luciani think it's great. i've always been wrong when i guess what could be slow
12:30lucianprofiling is the only way to know, so caring about the performance of one particular construct seems silly to me
12:31mdeboardsleepynate: Is a better hacker attitude to spend half an hour asking about performance instead of just testing it yourself?
12:31sleepynateahh i misunderstood the direction of your "useful things" statement
12:31dnolensleepynate: a type system will not make much Clojure faster, Clojure is designed be as very fast w/o such things.
12:32dnolensleepynate: the only place where I think it would be interesting is automatically placing type hints for interop calls.
12:32sleepynatemdeboard: wel, at the same time i've got the source for cl-op open, i'm looking for the Patrial assembly in scala
12:32sleepynateso, from a mental excercise point of view... yes i think so
12:37sleepynatednolen: but there is a type-system pre-existing that it sits on top of, no? as far as i can tell clojure is relying on java most of the time to explode-as-needed
12:37sleepynatenot that i feel like putting a type system on a standard lisp is a good idea
12:37luciansleepynate: well, clojure does have a type system. a dynamic, strong type system
12:38lucianit shares bits with java's (also dynamic, mostly strong) type system
12:39sleepynateare we talking about through Javarelfector and Coercion protocols? or something i'm not familiar with
12:39rpgAs a lisper coming to clojure, I'm used to checking what my functions do by using TRACE. Is there something similar for me in Clojure? contrib.trace seems to be a much more cumbersome beast involving recompilation...
12:40sleepynaterpg: good question
12:40dnolensleepynate: don't follow. And some people have had succeeded quite well at combining Lisp w/ sophisticated type systems.
12:41sleepynatednolen: for example...
12:41sleepynate&(+ 5 "derp")
12:41lazybotjava.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number
12:41dnolensleepynate: Typed Racket, Qi/Shen
12:41sleepynate^ not a clojure error
12:42dnolensleepynate: Clojure doesn't mess w/ the JVM exception mechanism for good reason. That *is* a Clojure error.
12:44rpgHm. Looks like maybe dotrace does what I want w/o recompilation.... not sure...
12:46rpganyone by any chance using MCLIDE with Clojure? it seems by default not to be configured to find clojure.contrib....
12:51dnolenwow Clooj is coming along
12:52sleepynate#((format "hi, %s" %))
12:52sleepynatewhy does that raise an exception>?
12:52sleepynate&#((format "hi, %s" %))
12:52lazybot⇒ #<sandbox7610$eval13014$fn__13015 sandbox7610$eval13014$fn__13015@64fb8d>
12:52sleepynatehm
12:52sleepynatei'll wait til i'm at a real repl :)
12:53dnolen,(#((format "hi, %s" %)) "foo")
12:53clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn>
12:53sleepynateright.
12:53dnolen,(#(format "hi, %s" %) "foo")
12:53clojurebot"hi, foo"
12:54dnolen,((partial format "hi, %s") "foo")
12:54clojurebot"hi, foo"
12:54sleepynateahh i see
12:54sleepynatethe macro expander expects an implicit ()
12:55dnolen,(macroexpand '#())
12:55clojurebot(fn* [] ())
12:56dnolen,(macroexpand '#(%1))
12:56clojurebot(fn* [p1__3037#] (p1__3037#))
12:56dnolen,(macroexpand '#((f %1)))
12:56clojurebot(fn* [p1__3064#] ((f p1__3064#)))
12:56sleepynatethanks
12:56TimMc,#()
12:56clojurebot#<sandbox$eval3091$fn__3092 sandbox$eval3091$fn__3092@1001b77>
12:56sleepynatedo either of the bots support the repl's "source" ?
12:56TimMc,(#())
12:56clojurebot()
12:57dnolenclojurebot: source vec
12:57rpgWhat does a "no message" error mean? I have a recursive function, and it seems like a recursive call is failing, but I'm not understanding the error...
12:58dnolenrpg: the error is at runtime?
12:58sleepynatednolen: nice thanks :)
12:58rpgdnolen: yes.
12:58rpgI'm trying to write my first function that takes a variable number of arguments....
12:58dnolenrpg: paste please.
12:59TimMcclojurebot: paste?
12:59clojurebothttp://gist.guthub.com
12:59TimMc>_<
12:59sleepynate:D
12:59TimMcclojurebot: forget paste |is| http://gist.guthub.com
12:59clojurebotI forgot that paste is http://gist.guthub.com
13:00TimMcclojurebot: paste?
13:00clojurebothttp://gist.guthub.com
13:00TimMcfeh
13:02TimMcOK, I think I fixed it (in privmsg).
13:04rpgdnolen: https://gist.github.com/1152035 --- I see what I'm doing wrong, but not how to do it right...
13:04rpg(Fogus & Houser book introduces "&rest" arguments, but w/o (AFAICT) an example of their idiomatic usage...)
13:07dnolenrpg: you should add your datatype + the case that fails to yr gist.
13:09rpgdnolen: OK, done....
13:10rpgdnolen: But I think all I need is an example of a function that takes an arbitrary number of arguments through the use of &, and processes them as, e.g., Lisp's +....
13:10TimMcrpg: Idiomatically, I'd probably define add to use reduce with a base value. :-)
13:11rpgTimMc: I was going to do that, but then I realized "I should understand how to unpack an &rest argument, even if this isn't the best case for it."
13:11TimMc*nod*
13:11dnolenrpg: consider this
13:12dnolen,((fn [a b & c]) 1 2 nil)
13:12clojurebotnil
13:12rpgTimMc: And I want to know what that "no message" means....
13:12dnolen,((fn [a b & c] [a b c]) 1 2 nil)
13:12clojurebot[1 2 (nil)]
13:12TimMcOh, I see the problem. But I'll be quiet.
13:12dnolenrpg: ^ this is what is happening to you.
13:12raekrpg: what is the type of the exception?
13:12raekrpg: also: (.printStackTrace *e)
13:12rpgraek: Error in Clojure process 1: No message. (maybe this is a SLIME confusion?)
13:13TimMcrpg: In REPL I get an NPE.
13:13raekhrm. you should get a stack trace in slime
13:13dnolen,(nil? '(nil))
13:13clojurebotfalse
13:13rpgdnolen: Right. I need the equivalent of Lisp's APPLY
13:13raekrpg: it's called apply in clojure too
13:14dnolenrpg: you have apply.
13:15rpgdnolen: Thanks! That does it....
13:15raekrpg: you also want to check for seq or empty?. (if (empty? x) ... ...)
13:15TimMcYou've had apply all along, Dorothy.
13:15raek,(empty? ())
13:15clojurebottrue
13:15raek,(nil? ())
13:15clojurebotfalse
13:15arohneranyone here use fnparse?
13:16rpgTimMc: Right. I'm trying to use the Fogus and Howard book and having some trouble....
13:16rpgPossibly it's not a good fit for me...
13:16TimMcrpg: Basically, you need apply anytime you write a recursive function with restargs.
13:16rpgTimMc: Right. Hence my remark that it would have been appropriate to introduce that topic (or a pointer thereto) when introducing restargs in the book....
13:17TimMcIndeed.
13:17jolyarohner: I did a little with fnparse recently, pretty small though
13:17arohnerjoly: do you understand how followed-by works?
13:17TimMcHmm, I don't see fogus in here...
13:18chouserHoward's here though
13:18rpgraek: Should I be using empty? in preference to nil?
13:18dnolenheh
13:18chouser:-)
13:18dnolen,(nil? ())
13:18chouserrpg: not everything that is empty? is nil?
13:18clojurebotfalse
13:19raekrpg: yes. there are seqable objects that haven't desided if theey're going to be nil
13:19jolyarohner: haven't used that, but it sounds like it might be the lookahead operator of PEGs
13:20raekrpg: http://kotka.de/blog/2011/06/On_types.html
13:20jolyarohner: I would expect it to match the subrule but not consume it
13:20jolyarohner: but I'd want it tested before you quote me on that ;)
13:21rpgraek: I was confused by being told that the seq API is just first and rest.... In particular, not empty? So what's the API for "there is no rest"?
13:22rpg(nil? <seq>) right?
13:22raekrpg: almost. (nil? (seq x))
13:22raekwhich is what empty? is defined as
13:23raekarohner: what about followed-by is confusing?
13:23arohnerraek: I just don't understand how it works
13:24jolyarohner: the docstring for followed-by confirms it. It'll match a subrule but not consume it
13:24arohnerright, so how do I use that?
13:24arohner(conc (rep* anything) (followed-by "foo") (lit-conc-seq "foo"))?
13:25arohneror, more concretely, how would I emulate #".*foo"?
13:25raekit's lookahead. (def a (lit "x")) (def b (lit "y")) (def c (followed-by a b))
13:26raekthis matches "x", but only when "y" follows. "y" remains in the remainder
13:26arohnerraek: your example followed-by takes two arguments. the fn takes one
13:26arohnerso (conc a (followed-by b))?
13:26rpgraek, dnolen: thanks.
13:27raekhrm, in the api example it takes two... :/
13:27jolythe code for followed-by has one arg, but for some reason the api mentions 2
13:27rpgchouser: In the Joy of Clojure, on p. 27 you introduce &restargs --- in a new edition it might be helpful to point the reader to some treatment of how to manipulate the restarg sequence idiomatically....
13:27raeklooks like it justs stores the state, matches and then restores the state
13:27rpgchouser: Probably just a forward reference....
13:28raekso (conc a (followed-by b)) looks like the way to use it, when reading the source
13:29raekfollowed-by seems to behave as if it would be named "match-but-do-not-consume"
13:29arohnerraek, joly: ok, thanks
13:30chouserrpg: good point, thanks.
13:30chouserIn fact, it looks like we never really give apply sufficient direct treatment. The fact that it is lazy for example seems to never be mentioned.
13:30rpgBTW, since Clojure is a Lisp-1, it might well be a Bad Thing to call your restarg "rest," right?
13:31technomancyrpg: for a small function it's usually not a problem
13:31chouserrpg: 'more' is perhaps the most common name. 'rest' works as long as you're careful never to try to then use 'rest' as a function.
13:31technomancythe errors you get for accidentally shadowing are pretty obvious
13:32rpgtechnomancy: but in the case of restargs, where you might well be unpacking a sequence.... I just mention it because there was an example on the web where someone (as I, a lisp-2 user, did) made the restarg "rest".
13:33raekarohner: have you opened an issue for the doc error?
13:33technomancyrpg: it's not very common to explicitly call rest as a function since you usually just destructure those things away
13:33rpgThat would have worked poorly for this case where the function is processing the restarg seq....
13:33arohnerraek: no, I don't think fnparse is being actively maintained
13:34rpgtechnomancy: This is making me more and more convinced that I need to find a good example of idiomatic use of a restarg.....
13:34rpg(or multiple examples...)
13:35dbushenkohi all!
13:35technomancywe call rest about ten times in a codebase of ~20kloc
13:36dbushenkois it possible to make hiccup generate just a part of an html-page, I mean without the headers like "<html><body>"
13:36pjstadigit makes much more sense to do something like item & items
13:36pjstadiginstead of using a generic variable
13:49thorwildbushenko: yes, easily
13:49dbushenkothorwil: oh, really? how?
13:50thorwildbushenko: like the very first example on https://github.com/weavejester/hiccup#readme ;)
13:51dbushenkoOMG... how could I miss that?
13:51dbushenkothanks!
13:55sridis there one for css representation?
13:56rpgtechnomancy: wrt 'rest', if you don't call it, what's the idiomatic alternative? I think in my case, probably 'reduce'....
13:56thorwilsrid: see CSS-style sugar at https://github.com/weavejester/hiccup/wiki/Syntax
13:57thorwilsrid: or do you mean a way to generate the CSS? there are at least 2 clojure libraries for that (i don't recall the names right now)
14:02arohnersrid: cssgen
14:09sridyes, cssgen fits the description.
14:10technomancy,((juxt (fn [[_ & rest]] rest) (fn [x] (rest x))) (range 10))
14:10clojurebot[(1 2 3 4 5 ...) (1 2 3 4 5 ...)]
14:11technomancyrpg: ^
14:11technomancyit depends on the context, but you can usually fold it into a destructuring call above
14:19rpgtechnomancy: I guess what I don't get is the way to distinguish the basis case from the recursion. I suppose (def ([x y] ..) ([x y & rest] ...)
14:21rpgNew question: is there some way that I can find out about the math-related protocols? (I'm learning some clojure while relearning some complex algebra...)
14:21rpgSo I know there's a fragmentary complex number library, but I want to avoid it for pedagogical reasons....
14:24kephaleis there a way to find out the memory footprint of a hash-map? where a hacky approximation would be (count (str my-map))
14:32cemerickkephale: In general, no.
14:33cemerickProfiling tools provide some approximation, but they can be off too, especially when things like direct buffers, weak references, etc. are involved.
14:35symboleDoesn't PersistentMap contain all its data? So looking at the object size would give an approximation?
14:38amalloyno
14:38amalloynot a good one, anyway
14:39arohnersymbole: you'd have to use a memory profiler to find the real size
14:40amalloymost objects have more than one reference to them; how does the memory for them get counted? version X of my 1M-element hash-map gets a new key assoc'ed in, creating version Y
14:40amalloydoes version Y take up as much memory as X, plus a little for new items? no, it mostly just takes up a small chunk of what's used by X
14:43kephalehrm i see… well, for all intents and purposes it is just a single map (the previous version is discarded as soon as the new one is created)
14:43rpgCan someone point me to a discussion of how to take a class of mine (that's mathematical) and extend the = protocol over it?
14:43kephalecemerick: i do see what you're saying about the complications though
14:45technomancyrpg: = is not currently a protocol
14:45technomancyyou'll have to look at how clojure.lang.Util/equiv is implemented
14:45cemerickkephale: determining sizeof for simple Java objects is nontrivial; what if your map had a lazy seq in it, etc? It's not a simple question. :-)
14:46kephalecemerick: oh, i don't expect it to be trivial, but in this case nothing is actually lazy anymore
14:46rpgtechnomancy: Thanks! Here's a more general question: We see discussions of how to implement protocols in our types and libraries. How do we find protocols in the wild that we should extend? I suppose the clojure-contrib site?
14:47danlarkinwhat.
14:47kephalebut maybe i just need to poke around the java Object API a bit
14:48symboleCan't profilers track down references such that one could find all the references that make up a map? I remember using a profiler that would give me all references from object A and to object A.
14:49symboleI might be imagining things.
14:50kephalesymbole: know of anyway to do that dynamically? reference counts might be sufficient
14:50cemerickYes, profilers can provide instance counts as well as an approximation of memory allocation.
14:50amalloyso what? how much memory is taken up by a one-element vector that contains a 1MB object in it somewhere?
14:51amalloya few bytes, or one meg? what if three other people also have a pointer to that object?
14:51raekdoes anyone know of any ClojureScript wrappers for any of the Google Closure libraries?
14:52amalloyit's a problem without a well-defined answer, let alone a well-known solution
14:52ibdknoxraek: I've started on pinot. http://github.com/ibdknox/pinot
14:53rpgtechnomancy: Is this an odd thing to want to do? Define a struct that might be, e.g., equivalent to a number? I was just doing my complex numbers and it seemed like I would want a complex number with no imaginary part to be = to its real number equivalent....
14:54technomancyrpg: it's reasonable to want, but I don't know if Clojure's own numerics are open in such a way as to allow that
14:54technomancystatic public enum Category {INTEGER, FLOATING, DECIMAL, RATIO}; // <= not terribly promising
14:55technomancyeventually in the promised land of Clojure-in-Clojure everything interesting (except IFn) will be an extensible protocol
14:55technomancywe're still a ways away from that though
14:56rpgtechnomancy: ah. Thanks. that's helpful.... I just assumed that I could extend the equiv protocol by defining the real-part and imag-part accessors on numbers and then it seemed that clojure.lang.Util/equiv was the right way to stitch it all toegether.
14:56dnolenrpg: if you want to understand the common protocols you need to look at the Clojure source.
14:57symbolekephale: I don't.
14:57rpgdnolen: I was just wondering if there was a table of protocols or something. Sounds like "no," is the answer...
14:57technomancythere aren't too many protocols in clojure itself yet as the move towards self-hosting has only barely begun
14:57technomancythe last stable release was the first to even have protocol support at all
14:57dnolenrpg: I meant Java interfaces. but getting familiar with them via the source is fine.
14:57rpgtechnomancy, dnolen: thanks. That helps me understand a bit....
14:58technomancyso naturally it's going to take a few releases before it takes advantage of them internally
14:58rpgCan I extend a protocol like my real and imaginary parts to the built in numbers?
14:59dnolenrpg: try equiv.
15:00kephalecemerick: any tip on which profiler would be efficient for very frequently estimating the memory allocation (possibly at the cost of accuracy)?
15:00cemerickkephale: VisualVM is a reasonable first choice. You already have it installed.
15:00rpgThanks, all. I must run out for a moment. You have been very helpful. Cheers!
15:02kephalecemerick: ah, yeah I've used that one in GUI mode, but never called it directly from clojure. FYI, by frequent I mean on the order of 1k checks per second
15:03kephalepresumably there will be some slowdown though, it isn't a real-time application
15:03cemerickkephale: "calling it directly from clojure" doesn't make any sense; profilers aren't *called*, they receive telemetry from the VM itself.
15:04kephalecemerick: ah, then it wont work. i need to get the estimates during run-time
15:05cemerickkephale: all profilers operate at runtime.
15:06kephalecemerick: you probably know the code I'm working with, Clojush
15:06cemerickheh, Lee's GP stuff?
15:06kephale<- kyle
15:06kephaleyeah
15:07kephaleso the interpreter is just a map, and thus far we just evaluate them for N instructions
15:07kephaleI'd like to run the Push interpreter forever, but detect if it is going to overflow the heap
15:08cemerickI've never looked at Clojush, so I don't know anything about its internals.
15:09cemerickThe bottom line with profilers is that you attach one to a JVM process at runtime, and it captures data about its operation — # of allocations, live instances, an approximation of memory allocation, runtime perf, etc.
15:09cemerickYou can't control profilers from "userland" code (at least, I'm not aware of any method of doing so).
15:11kephalehrm… i'll have to poke around at calling visualvm from within clojure, i don't see why one couldn't do it from userland
15:12cemerickkephale: Seriously, you can't "call" a profiler. It provides no library, no API.
15:13kephalecemerick: worst case : P http://download.oracle.com/javase/1.4.2/docs/api/java/awt/Robot.html
15:14cemerickkephale: sorry, you have me baffled. :-)
15:15kephalecemerick: thanks though, i think i'm on the right track now, i'll keep you posted… visualvm does seem to have an api though (designed for plugins)
15:16cemerickoh, sure, but that plugin code will be running in a different JVM than the one you're profiling
15:16cemerickAnyway…good luck. Say hi to Lee for me. :-)
15:16kephalemmm will do
15:20TimMckephale: When the JVM runs out of heap, does it throw an Error of some sort?
15:21amalloyanyone know of a library that will analyze a clojure expr and determine which variables are "free" in the closure sense? i'm playing with the idea of turning (fn [x] (conj [:foo :bar] x)) into (let [v [:foo :bar]] (fn [x] (conj v x)))
15:22kephaleTimMc: yes, i guess catching the heap exception might work. i haven't tested that yet, but the concern is that there are a bunch of agents possibly overflowing the heap. i think your instinct is right, that should be the first thing to test
15:24amalloy(and i speculate that knowing what variables are free would help me do that, by pulling expressions about them up as high as possible)
15:25cemerickamalloy: A Clojure analyzer will do. :-P
15:25amalloycemerick: i don't think i follow
15:30dnolenamalloy: hmm seems like you write a fairly simple core.logic program to do something like that ;)
15:36PPPaulcan 'join' do something similar as 'index' if i join a table on itself on 1 key?
15:41amalloydnolen: aha, interesting point. damn it, now i have a reason to learn core.logic instead of just letting all the news blow by
15:50gridaphobedoes anyone know what's happening to clojure.contrib.http.agent in 1.3?
15:51dnolenamalloy: would be fun to figure out, thinking something along these lines, https://gist.github.com/1152441
15:52dnolenamalloy: since running backwards isn't so important here, could probably use conda/u and it would be pretty efficient.
15:53amalloydnolen: i'm afraid i'm a fish getting tips about space exploration, here. none of that means anything yet. i've got a lot of basics to catch up on first
16:05amalloyfwiw though i think you'd have to operate on let*/fn*, since you want to look at the macroexpanded tree
16:06dnolenamalloy: you'd probably want to handle all cases since I don't think you'd want to depend on where in the macroexpansion you are.
16:07amalloydnolen: you don't have to; (defmacro fold-constants [form] (let [expanded (macroexpand-all form)] ...))
16:08dnolenamalloy: macroexpand-all is the devil
16:08amalloyaw, i thought flatten was the devil. but i can see how they might be related
16:08dnolenunless it's just for analysis.
16:08dnolenany macroexpansion inside of a macro forces users of your macro to consider macroexpansion order. ARGH
16:11amalloyi'm not sure i get it. as long as i'm not doing something weird like expanding just parts of the expression, isn't it the same as what the compiler would do later anyway? then i work with the post-expanded form and do semantic-preserving operations like constant folding; so it should be equivalent to having no macroexpand at all
16:11ibdknoxdoes anyone know where (show) ended up from repl.utils?
16:14dnolenamalloy: heh, it's usually not a big deal :) however things get tricky in my experience when the macro involves code-walking.
16:15amalloywell, yes. i suspect any macro that involves code-walking (as this one would have to) will get complex no matter what else you do
16:18PPPaulhow do i limit what fields are used when doing a clojure.set/join ???
16:23TimMcPPPaul: Take a look at the last example of http://clojuredocs.org/clojure_core/clojure.set/join
16:23upwardindexIn common lisp when I wanted recompile my project and have a fresh start i would restart-inferior-lisp and (require 'project). What is the equivalent in clojure? (restart-inferior-lisp says No inferior lisp)
16:23TimMcTHat might do the trick.
16:25technomancyupwardindex: how did you start swank?
16:25upwardindextechnomancy: M-x clojure-jack-in
16:26upwardindextechnomancy: Is that the preferred way?
16:26technomancyupwardindex: that's fine. you can kill the *swank* buffer and re-run clojure-jack-in.
16:26upwardindextechnomancy: ah so simple, thank you!
16:26symboleWill Clojure be at JavaOne?
16:27technomancyupwardindex: you should be able to just re-run clojure-jack-in, but there's a bug in some versions of emacs that makes it more reliable if you just kill *swank* first
16:28technomancynext version of clojure-mode will fix that
16:29TimMcPPPaul: Pass a keymap in with identical keys and values.
16:33upwardindextechnomancy: yes I believe I ended up with 2 swanks when just rerunning clojure jack-in
16:33technomancyit's on the hit list.
16:36ibdknoxamalloy: one of us are gonna end up on it one day...
16:37technomancypew pew pew: http://fuckyeahfingerguns.tumblr.com/
16:37ibdknoxlol
16:49aaelonyI have a silly question. How can I issue a unix system call from clojure? I am trying the following but still not quite there....
16:49aaelony(reader (BufferedInputStream. (.getInputStream (.exec (Runtime/getRuntime) "ls -l" ) )))
16:51technomancyaaelony: it's impossible afaict to stream input to a subprocess on the JVM
16:51technomancyaaelony: without crazy JNI stuff anyway; JRuby manages it somehow
16:51amalloytechnomancy: whattttt, i don't think that's true at all
16:51technomancyoh nm; you are talking about getting output from the process
16:52technomancyamalloy: all the APIs I've seen only let you use a byte array or a stream as stdin
16:52technomancy*or a string
16:52aaelonyjust a simple "ls -l" given that we are on a *nix box
16:52technomancy(doc clojure.java.shell/sh)
16:52clojurebotI don't understand.
16:52technomancywat
16:52technomancy,(doc clojure.java.shell/sh)
16:52clojurebotCool story bro.
16:52aaelonywhere "ls -l" could be any valid command
16:52technomancyclojurebot: botsmack
16:52clojurebotOwww!
16:53amalloy$javadoc Process getOutputStream
16:53lazybothttp://download.oracle.com/javase/6/docs/api/java/lang/Process.html#getOutputStream()
16:53Scriptorhttp://clojuredocs.org/clojure_core/clojure.java.shell/sh
16:53Raynes&(doc clojure.java.shell/sh)
16:53lazybot⇒ "([& args]); Passes the given strings to Runtime.exec() to launch a sub-process. Options are :in may be given followed by a String or byte array specifying input to be fed to the sub-process's stdin. :in-enc option may be given followed by a String, used as a charac... http://gist.github.com/1152603
16:54aaelonylooks cool.. will try it out :)
16:54amalloytechnomancy: short version: Runtime/exec returns a Process; a Process has an outputstream you can send bytes to
16:54technomancyamalloy: hum... interesting.
16:55technomancyI believe I had problems when I tried that
16:55technomancybut I don't remember the details
16:57aaelonyhmmm... so how would I actually see output from an "ls -l" ?
16:57aaelonythis doesn't do it: (clojure.java.shell/sh :in "/bin/ls -l")
16:58amalloy(:out (clojure.java.shell/sh "/bin/ls" "-l")) iirc
16:58amalloyyeah
16:59aaelonycool, also found this http://clojuredocs.org/clojure_core/clojure.java.shell/sh
16:59amalloyalthough, wait, what? you want to use ls to look at a directory? please tell me this is just a contrived example and not your actual use case
17:00aaelonycontrived example
17:00technomancydon't go judging now
17:00aaelonyhaha
17:00ibdknoxamalloy: the shell is the only thing you can trust...
17:01ibdknoxamalloy: I try to do everything relating to IO that way ;)
17:03aaelonybtw, this is awesome. works really well.
17:04amalloyibdknox: great, now you've created a shell addict
17:04ibdknoxBWAHAHAH
17:04ibdknoxI will burn this world to the ground ;)
17:05ibdknoxone ridiculous shell invoking program at a time
17:05aaelonybeats head-scratching over archaic java deprecated library classes... nice executable, very nice...
17:06Hodapp9_9
17:07ibdknoxaaelony: what are you actually trying to do?
17:11aaelonyibdknox: just need a simple way of querying an S3 bucket. Also pulling files down, and pushing files back up.
17:11aaelonywas using org.jets3t.service but its turning out to be a huge pain
17:12aaelonyrest calls reply that buckets are empty when I know they are not, etc..
17:13ibdknoxaaelony: I have something in Noir that does some basic S3 stuff
17:13ibdknoxand I know it works
17:14ibdknoxit also uses jets3t though
17:14aaelonycool, pls pass it on
17:14ibdknoxhttps://github.com/ibdknox/noir/blob/master/src/noir/util/s3.clj
17:14ibdknoxnot much there lol
17:15ibdknoxit was just whatever I needed for image uploading on typewire
17:15aaelonybasically the listObjects method is too opaque for me (http://jets3t.s3.amazonaws.com/api/org/jets3t/service/S3Service.html#listObjects%28org.jets3t.service.model.S3Bucket,%20java.lang.String,%20java.lang.String%29)
17:15aaelonycool thanks, will take a look
17:16aaelonylooks nice. I admit I haven't used noir yet
17:16ibdknoxaaelony: it's awesome ;)
17:16ibdknoxhaha
17:17aaelonylooks nice
17:17amalloynever admit that you don't use noir. the cool kids will never let you live it down
17:17amalloyi'm a broken shell of a man after my confession
17:17aaelonyhaha, will be trying it shortly
17:19aaelonywhat is the most lightweight way to get the s3 functionality?
17:19ibdknoxcopy that file
17:19ibdknoxlol
17:20ibdknoxI didn't separate it out
17:20ibdknoxthat one is probably one that should be though
17:20aaelonyhaha... hell I'll try the whole kit...
17:20ibdknoxsince it's not noir specfic
17:25aaelonyibdknox: so to list files in a bucket, I wrap list somehow? I likely need an idiot proof example...
17:27rpgIs there a way (akin to instance? ) to check if an object participates in a protocol?
17:27ibdknox,(doc satisfies)
17:27clojurebotIt's greek to me.
17:27ibdknox,(doc satisfies?)
17:27clojurebot"([protocol x]); Returns true if x satisfies the protocol"
17:28ibdknoxaaelony: I'm looking
17:28aaelonyibdknox: cool
17:30ibdknox(with-s3 {:secret-key "blah" :access-key "blah"} (list "somebucket"))
17:30ibdknoxshould work
17:30ibdknoxbasically just wrap all of your calls in that with-s3 macro
17:31aaelonycool
17:36rpgibdknox: thanks!
17:40rpgcan defrecord take a docstring? The clojure.org doc suggests not...
17:41amalloyi don't think so. where would it go? classes don't have metadata
17:56TimMcAnd I guess defrecord doesn't introduce a var.
17:58TimMc,(macroexpand-1 '(defn foo "hello" [n] n))
17:58clojurebot#<Exception java.lang.Exception: SANBOX DENIED>
17:58TimMcaw
17:58scottjanyone setup their emacs to use inferior-lisp for cljs files but slime for .clj files?
18:01TimMcAnyway, that expands to (def foo (.withMeta (clojure.core/fn foo ([n] n)) (.meta (var foo))))
18:02TimMc...which confuses the hell out of me. The initialization expression apparently use the var it is initializing?
18:02amalloyTimMc: i agree, it's madness
18:03TimMcI suppose that means that the compiler handles the var itself and then goes back and initializes it.
18:03amalloynot afaict. this causes behavior that seems to me like a bug
18:04amalloya couple months ago seancorfield (i think) had an issue where when he redef'd a var with new meta, the meta didn't "stick" until the second time
18:05TimMcAnyhow, the :doc sticks to the var, not the fn -- that's what I was originally investigating.
18:05amalloybecause (.meta (var foo)) was sneaking the old meta back onto it or something
18:05TimMcyuck
18:06TimMcAnyway, hometimes.
18:06TimMcI'll check backlog for any rebuttals, etc. :-)
19:06upwardindexElementary question here, I get the dreaded "Can only recur from tail" on this but I don't understand this seems to me to be ok: http://pastebin.com/PjNgbYs2
19:09amalloyyou're not returning the result of recur
19:09amalloyyou're returning one plus that result
19:10amalloythus, the recur is not in tail position
19:10upwardindexahhh ok thank you!
19:10amalloyonce you fix that you'll want to fix the infinite loop
19:11ibdknoxlol
19:11amalloyupwardindex: you come from common lisp, right?
19:11ibdknox,(doc next)
19:11clojurebot"([coll]); Returns a seq of the items after the first. Calls seq on its argument. If there are no more items, returns nil."
19:11upwardindexamalloy: yes
19:12ibdknoxempty list is false in CL, right?
19:12amalloythe short answer is to use next instead of rest (in this case; not in all cases), because an empty list is not the same as nil
19:12upwardindexibdknox: that is right
19:12amalloyand next implicitly calls seq on its argument, which converts empty seqs to nil
19:12upwardindexamalloy: ah ok rest will return an empty list at the end and next will return nil
19:13ibdknoxyep
19:13amalloy&((juxt rest next) [1])
19:13lazybot⇒ [() nil]
19:30upwardindexamalloy: Are you the one who created 4clojure?
19:30amalloykinda
19:30amalloyi'm the current maintainer, and was contributing about 50/50 as it was being built
19:30upwardindexamalloy: Should there be a restriction on apply for number 24?
19:31amalloyi don't see why. learning that you can use apply is good for you
19:32amalloy"ohhhh, *that's* why clojure doesn't have a built-in `sum` operator"
19:32ibdknoxamalloy: who built the other half?
19:32amalloydbyrne
19:32upwardindexamalloy: I guess, just depends on the objective of the exercise. Most previous numbers put restrictions on functions that are good to learn.
20:10amalloyupwardindex: i have to wonder about the person who found a 120-character solution to "sum it all up"
20:11upwardindexamalloy: very descriptive variable names perhaps ;)
20:15upwardindexamalloy: or if spaces are counted, maybe its a matter of placing parenthesis on their own line (like you would do in java for example)
20:15amalloynah, we only count real characters
20:16amalloyand whoever it was, they did it before we started saving solutions; i just checked and nobody's solution is that long
20:16amalloyso i guess we'll never know
20:49tufflaxwhat a shame, we probably could have learned a lot from it
21:18ndimiduki have a question about extending protocols
21:19ndimiduki'd like to augment the clojure.java.io/IOFactory for String
21:19ndimidukadding support for a new URI scheme
21:20ndimidukwhich mean, in effect, i want to call (extend String io/IOFactory ...) such that i can locally bind the existing implementation of :make-input-stream so that i can call it in the negative case
21:21ndimidukit looks like i can use find-protocol-method to do this
21:21ndimidukbut i'm troubled because, after (require 'clojure.java.io)
21:21ndimidukerr
21:21ndimiduk(require '[clojure.java.io)
21:21ndimiduk:as io])
21:22ndimiduk(= (find-protocol-method io/IOFactory :make-input-stream String) (find-protocol-method io/IOFactory :make-input-stream Object)) => true
21:23ndimiduki can invoke (io/make-input-stream "path/to/file") and that works
21:24ndimidukbut invoking ((find-protocol-method io/IOFactory :make-input-stream String) "path/to/file" {}) falls back on the Object impl
21:24ndimidukwhat gives?
22:00rpgI am having a problem with the use of defprotocol and defrecord as illustrated in https://gist.github.com/1153123 A call to (modulus (complex. 1 1)) there bombs, but what seems like the exact same code as (mod2 (complex. 1 1)) works fine.
22:01rpgFor some reason, when I use the defrecord + defprotocol I end up trying to interpret an integer as a function (as far as I can tell from the error message). Can anyone see my mistake?
22:02rpgI'm completely stumped by this, and my attempts to trace do me no good.
22:12amalloyrpg: shadowed symbols
22:13rpgamalloy: oh, dear. Is my lisp-2 heritage showing?
22:13amalloynah, it's a clojure-specific thing
22:13rpgwhat's shadowed?
22:13amalloyinside the body of (defrecord Foo [value]), the symbol 'value maps to the value field of the record
22:13amalloyso (real c) is calling the real-part field of the record
22:14amalloyrather than the protocol-function real
22:14rpgamalloy: Ah. So I had better rename the real and imag fields, so that they don't collide with the accessor names, right?
22:14amalloyright
22:15amalloythis also implies that you can implement the accessor as just (real [c] real)
22:16rpgBut if I do that, I can't reference the accessor in the body, right?
22:17amalloyyeah, don't use the same name. i was just pointing out that you don't need to call (:real c)
22:17rpgso I'm better off with something like (defrecord complex [real-part imag-part] CPARTS (real [c] real-part))
22:17amalloyright
22:18amalloyis just what i'd write
22:18rpgI NEVER would have figured that out. Thanks a million!
22:18amalloyi usually forget about that feature of records too
22:18amalloybut once the stacktrace appears...
22:22mjonssonrpg: btw, you may want to use Math.atan2 instead of Math.atan
22:24rpgmjonsson: Thanks! I hadn't known about this (I'm not much of a hand with Java).
22:24amalloyMath also has Math.sqrt
22:27sridwhat is the most interesting use of lazy seq in clojure?
22:34amalloyuh. i think the answer to that is "clojure"
22:38amacsrid: I would say the idea of being able to process infinite sets of data without having to manage how/when the data is created or consumed.
22:39amaca good example that's used in sicp is the sieve of eratosthenes
22:39sridah ok, an example is what I was looking for.
22:40amacbasically its a function that conceptualizes every prime number (infinetly many) but only produces the next result when its needed to be consumed
22:41amacps -- sicp is a good book if you want to understand why functional languages (lisp in particular) are designed the way they are
22:44sridi read 3.5 chapters of sicp a few years ago, actually. that's when I got a feel for lisp.
23:26sridinteresting. noir is not listed in http://disclojure.org/projects/
23:27scottjnoir is newish
23:27tbatchellisrid, that page need a serious, serious update
23:27tbatchelli:(
23:27sridso, what is the currently popular web framework for clojure?
23:28scottjnoir and compojure or just plain ring
23:28kephalemoustache is another
23:28pcavssrid: messing around with noir, and I find it alright
23:28tomojrouting looks funky
23:28pcavsin noir?
23:28sridtbatchelli - i wonder why http://clojars.org/ doesn't have categorization of popular libraries.
23:29tomojyeah
23:29pcavstomoj: or in ring in general?
23:29tomojnoir
23:29tomojthere is no routing in ring, is there?
23:29scottjsrid: http://www.clojure-toolbox.com/
23:29tbatchelliright, http://www.clojure-toolbox.com/
23:29sridah nice.
23:29scottjof course noir isn't on there either :)
23:29tomojI guess it is supposed to be for simple stuff anyway so strings are OK?
23:29sridwait, is this manually maintained or auto updated from clojars?
23:30tbatchelliwell, people keep putting awesome libraries out every week, it's hard to keep up with that!
23:30pcavstomoj: noir routing is okay for basic stuff, haven't really pushed it around much yet
23:30sridtbatchelli - heh, neither does that site have noir.
23:30tbatchellisrid, noir is very new
23:31tbatchellinoir is nice, but it pays to know compojure and ring
23:31sridhttps://github.com/hlship/cascade is advertised as webframework for "idiomatic" clojure
23:32tomoj"Cascade templates are an embedded DSL directly in the Clojure code"
23:32tomojis this really idiomatic clojure? seems like _popular_ clojure
23:32tomojis the popular idiomatic?
23:33pcavssrid: interesting, uses buildr too it looks like
23:34pcavsbuildr=gradle, wow how did I screw that one up
23:34tbatchellisrid, although this article doesn't include noir, it is a very good survey of what's popular and available http://brehaut.net/blog/2011/ring_introduction
23:35scottjthe only problem with it being it leaves off slice :)
23:35tomojI guess you can write idiomatic clojure even when it is a bad idea (not that it necessarily is in that particular case..)
23:36scottjthere used to be a graphic that showed the different layers and options for web dev
23:36sridtbatchelli - excellent, thanks!
23:47scottjis there a standard clj->js function? (cljs)