#clojure logs

2012-06-01

00:03wei_what's the idiomatic way to include something in a hash only if it's not nil? e.g. {:a a :b b} but if b is nil, then the map should just be {:a <value of a>}
00:08wei_^ nevermind, this helped: http://stackoverflow.com/questions/3937661/remove-nil-values-from-a-map
00:15irc2samushmm the shutdown hook fires on normal program exit but does not when receiving SIGINT (which was my original goal) :/
00:16irc2samustechnomancy: your version works too and it's prettier, thanks
00:18technomancyirc2samus: you may be able to catch an InterruptedException or something
00:26irc2samusnope, even with try/catch it just aborts
00:27irc2samusI'm running with "lein run" and Clojure 1.2 would that matter?
00:28technomancyshouldn't
00:33irc2samusit doesn't work on te repl, neither 1.2 nor 1.3
00:34irc2samusweird, the whole internet agrees on that solution regarding specifically SIGINT (they talk Java but should apply here as well)
01:04amalloywell mostly you can't 100% rely on anything that happens after a SIGINT
01:05amalloythough the usually-works solution for java should also mostly-work for clojure
01:06amalloyuseful.java has a signal-handler function, which is not portable across all JVMs
01:06amalloyhttps://github.com/flatland/useful/blob/develop/src/useful/java.clj#L10
01:08estebanni am almost completely ignorant about functional programming, and am suffering a failure of imagination
01:08estebannhow are large scale projects organized in a functional scheme
01:09estebann?
01:09devnis it evil to use &(resolve ((comp symbol str) "ns/my-fn-prefix-" "ends-like-this"))
01:09devnwill that break across namespaces?
01:11devnfor instance: in x.core I have (:require [x.abc :as abc]) -- later on I use the above to get a fn out
01:12devnin x.def I (:require [x.core :as core]), then I go to use core/fn-which-uses-resolve-in-its-body
01:12devnwill it still resolve properly in this scope?
01:18brainproxyestebann: are you asking in general or you're specifically interested in how clojure addresses the issue?
01:18amalloyseems like that would be faster to try out than to ask about, devn
01:23estebannbrainproxy: a bit of both. I've come from an OO and messy procedural background and I cant really imagine how to organize code better in clojure than I did in C
01:25estebannif you could point me to some sort of overview of functional design principals I would be grateful
01:27brainproxyestebann: first of all, don't worry, you'll catch on ... I'm only a few weeks in myself, coming from a mostly javascript background
01:28brainproxyestebann: in clojure, code is organized using namespaces; namespace members can be used in the context of other namespaces with the help of `require`, `use`, and so on
01:29gfrederi`you don't even have to instatiate them!
01:29brainproxyin other words, namespaces allow groups of related values to be organized, "modularized"
01:30brainproxyalso, a dependency management framework as provided by the "leiningen" tool which is popular in the clojure community
01:31brainproxyallows authors to declaratively indicate what their packages will need in place in order to work properly
01:32brainproxythis allows rather efficient organization, modularization of code
01:33devnamalloy: come on man, do you see any obvious deficiency with it? I ran into an issue earlier while I was hacking around with it, but I'm not sure if that is the reason.
01:33estebannbrainproxy: ok, I believe I will be able to get to the code I need when I need it.
01:33brainproxyestebann: yep, and w/ leiningen it's really easy
01:33amalloy*shrug* i don't think it will work, but i dunno
01:33amalloyinstead you probably want (ns-resolve (the-ns ns) (str "prefix-" fn-name))
01:34brainproxyestebann: I've had a great experience with the Clojure Programming book from O'Reilly; readint it with clojuredocs.org and clojureatlas.com close at hand
01:34brainproxy*reading
01:34devnyeah, probably right on that one. i used resolve because when i was mucking around i didnt care about passing in the ns if i could get away with "foo/bar"
01:34devnamalloy: thanks
01:34estebannbrainproxy: my problem is that I'm not really sure how to think about complex systems without agency.
01:35estebannbrainproxy: I tend to think of things doing verbs.
01:35devnestebann: for what it's worth, don't get focused on organization
01:35estebannit seems a lot harder to think just in terms of nested verbs
01:35devnlet organization *fall out*
01:36estebannhmm... I'm willing...
01:36devnestebann: i was used to tens of files when i came to clojure and spent time thinking about how id split up all of the fns by file and so on, and found it to be a headache, not because it is "hard" so much as I think it's just fundamentally wrong
01:37brainproxyestebann: honestly, I think if you work through the (sometimes super challenging!) examples in a book like http://www.clojurebook.com/ you'll be able to decide wether this func prog stuff is for you or for the birdss :D
01:37brainproxyestebann: btw, I'm not one of the authors, nor trying to sell you on it, just had a super good experience with it, and it seems like you need something that will "show you the ropes"
01:37devnestebann: one last thing on organization. use clojure, but just follow the rules and only use one file.
01:38devnuse one file until you hit about 1000 lines. at that point the fns which can be in their own file(s) will be obvious
01:38devnthat's how it has worked out for me anyway
01:39devnexcess code organization leads to headaches if you overdo it early on. im stealing from rich or stu or someone recently
01:39devnbut it's a bit like pouring concrete on your code
01:39devnyou will have less freedom if you over-organize early in the process
01:39estebanndevn: i can totally see that
01:40devnthe same is true for other languages, but i think we ignore it because it's "how things are done"
01:40devnin clojure you feel the pain of it
01:40devnit hurts, but i think it produces more manageable code in general
01:40brainproxydevn: in NodeJS, the modules system encourages breaking things up into ~100 - 250 LOC files
01:41estebanndevn: on the other hand when I'm confronted with a complex process that I need to design all at once functions alone seem rather a sparse vocabulary for doing that.
01:41brainproxydevn: and by encourages, I mean that doing so is pain free and seems to help individual pieces from turning into giant hairballs
01:41devnbrainproxy: yes, this is not a surprise, right? this happens all over the place. big files can become cesspools. In Clojure I don't feel this way. I am comfortable reading a clojure file that is a few thousand lines because the ordering of fn declarations and so on makes it straightforward, story-like
01:42devnin other languages that lack the same functional properties of clojure i find this to be unnerving and painful
01:42gfrederi`estebann: not only functions but also data!
01:42brainproxyestebann: clojure gives you protocols and types also
01:43devnestebann: functions are verbs. what other vocabulary do you need?
01:43estebanndevn: subject and object
01:43devn(defn embiggen ...) (defn make-party-hat ...) (defn retrieve-headers ...) and so on
01:43devnestebann: think in terms of data, not abstractions that hide data
01:44estebanndevn: I come ultimately from a philosophy background so maybe I am suffering under a disadvantage
01:44brainproxyestebann: what I've learned so far is that you can go a *long* way using the built-in collections for data structures
01:44devni found it helpful to think to myself: "I have [1 2 3]. I want [3 2 1]. How do I get from [3 2 1] to [1 2 3]?"
01:44abp_I would even say that it's not very likely to get many LOC's with Clojure while learning anyway. The language is just to terse and especially so while learning with little pet problems and projects.
01:45devnestebann: i almost wrote a macro yesterday. i almost wrote a multimethod the day before. i didnt need either of them.
01:45devnfunctions win. you just need to live with them in harmony for awhile and they will become your faithful servants
01:45abp_Just reiterate and improve your code while learning. Will shrink everything to nearly nothing.
01:45estebannall: I believe, help thou my unbelief
01:46brainproxy:)
01:46devnestebann: nothing helps like *knowing*
01:46devn:)
01:46devni think it honestly took me 3-4 months before i started to go "ah-ha"
01:46devnand that was just the beginning
01:47devnthis is the beauty of learning a functional language. you keep saying ah-ha. it feels better and better as time goes on. it's like learning to play a violin instead of feeding a player piano.
01:47devnor at least i have...
01:48devnruby is a tremendous bore compared to clojure and its community.
01:48devnthat should be reason enough to feel like awkward for awhile. :)
01:48devnlike the awkward kid*
01:48estebannok I'm hoping to re-implement some existing code in clojure (mostly be because I want to give it a try) is the best way to go about converting from oo to functional to just go one step at a time from entry point onward
01:48estebann?
01:49estebannthat was pretty incoherent
01:49devnestebann: nono, i know where you're coming from
01:49devnit's a vague question with a vague answer
01:49devnthe question id ask of you is: what is your problem? what do you want as a solution? talk about input and output in here.
01:50devnit's helpful to say: "I have [1 2 3]. I want to get [3 2 1]. How do I do that?"
01:50devnSmall steps.
01:50devnthat lets you start building tiny functions, and then you can start composing them and see how things build up.
01:52devnestebann: if you can legally post the code you're interested in reimplementing in clojure, that might be a start, for instance.
01:52estebannok, maybe I'm being too ambitious. I have an execution path that esentially turns a large number of numbers into a simplified cumulative distribution function
01:52estebannit seems like an ideal target for a functional approach
01:53estebannbut there are a lot of steps between the first set of numbers and the final result
01:53devnestebann: it's okay to have an ambitious goal, but i felt like i got a bit monk-like when i started to grok clojure. id take a deep breath, think about the values i had in my hand at the repl, and think about the transformation id need
01:53devnthe first step. that is the important one. it's hard to go wrong with pure functions.
01:54devn,(map Integer/parseInt ["1" "2" "3"])
01:54clojurebot#<CompilerException java.lang.RuntimeException: Unable to find static field: parseInt in class java.lang.Integer, compiling:(NO_SOURCE_PATH:0)>
01:55devn,(map #(Integer/parseInt %) ["1" "2" "3"])
01:55clojurebot(1 2 3)
01:56devn"I have '(1 2 3). I want to sum them."
01:56AimHere,(map read-string ["1" "2" "3"])
01:56clojurebot(1 2 3)
01:56brainproxyestebann: it's probably helpful to learn a little bit about the basic containers that clojure provides you, and the facilities they afford you
01:56devn,(reduce + '(1 2 3))
01:56clojurebot6
01:56devnAimHere: lol. why?
01:57AimHereit's an inbuilt first-class function that does roughly what your parseInt example does; though perhaps more flexible and slower
01:57brainproxyin other words, knowing about lists, hash maps, vectors and sequences, and the kinds of things you can do with them and expect from them
01:57devnmore flexible to a fault. i guess if you're damned sure of your inputs it's fair, but it just feels... i dont know... filthy.
01:57devnlike eating pizza in a sewer ;)
01:58estebanndevn: AimHere = NinjaTurtle?
01:58devnhahaha
01:58devndonatello? is that you?
01:59AimHereCaravaggio. I'm the fifth Ninja Turtle
01:59devnestebann: you need to know about str, map, filter, reduce, apply, [], '(), #{}, {}, and a handful of other fns, and you should be able to start hacking stuff together
01:59devnestebann: also, (use 'clojure.repl)
01:59devn,(doc filter)
01:59clojurebot"([pred coll]); Returns a lazy sequence of the items in coll for which (pred item) returns true. pred must be free of side-effects."
01:59brainproxyi would say that coming to some terms with regard to laziness is quite important also
02:00devn,(apropos "map")
02:00clojurebot(sorted-map ns-unmap zipmap mapv map ...)
02:00devnthat will let you explore a bit
02:00devnbrainproxy: i think you can defer that
02:00devnfwiw
02:00gfrederi`devn: aw you don't need #{} to hack things together
02:00devngfrederi`: you dont, but man it's cool if you're not used to a set literal
02:00riley526Hello all, complete noob here. Quick question: How do I switch from clojure 1.2.1 to 1.3 in the Leiningen 1.7.1 REPL?
02:00brainproxydevn: i dunno, seems like otherwise, you might shy away from things that are super nice
02:00brainproxylike ranges and what not
02:01brainproxywhich in non-lazy langs could be prohibitive if they're large
02:01devnbrainproxy: yes, but you have to do it wrong to know how to do it right!
02:01devnthis is what good math professors teach us
02:01gfrederi`(alter-var-root *clojure-version* (constantly {:major 1 :minor 3 :incremental 0}))
02:01brainproxyiow, if you assume eager evaluation, like with most other languages
02:01devnCS skirts this discipline in the classroom all the time
02:01devndo it the hard way. then realize you have real ultimate power.
02:01brainproxyyou're perspective on what's possible would have a much narrower horizon
02:02devnbrainproxy: yes, but narrow makes you focus.
02:02devnand for beginners there is so much already, narrow is good
02:02gfrederi`riley526: you want to change the version of clojure in the project.clj file and restart the repl
02:02AimHereWell this guy is going to be converting oo code to clojure to 'try it out'; he might end up with that narrow focus just by the way he's starting otu
02:02estebanndon't worry if you have hegel or kant questions come to me. pure cs questions... I learn on the job
02:03estebannthe summa was kind of awesome, imho
02:03devnestebann: dialectic. explain it.
02:04devnthe hegelian ones i mean
02:04estebanndialectic is process by which multiple oposing ideas are able to
02:04estebann...
02:04brainproxyestebann: i think so too, but have a philo prof who is a thomist and cringes at the very mention of kant
02:04devnalfred north whitehead?
02:05devnanyone actually take up rich's suggestion to read it from Are We There Yet?
02:05devnthat book is...jesus.
02:05devnincredible ideas. but it took me 30 minutes per page in some cases.
02:05estebannthat's how you know it's the good stuff
02:07devnhe makes a cool argument about how all arguments are flawed because they presuppose the existence of the universe
02:07devnwhich makes you head into thought loop territory
02:07riley526gfrederi`: do I need to create a project before I run `lein repl` then? there is no existing project.clj that I can find.
02:08estebanni've never read "are we there yet" but I enjoyed meditations on first philosophy. in a popcorn sort of way
02:08antares_riley526: you can run lein repl without generating a project
02:09riley526antares_: right, but gfrederi` says I need to edit project.clj in order to change the clojure version.
02:09estebannit seems embarissingly obvious that descartes wanted someone to solve the problem of mortality before he died
02:09brainproxyestebann: and a friend and I set out to read Copleston's series, but I only got through the 1st volume before getting too weighed down with work to properly commit the time to it everyday
02:10estebannbrainproxy: you are a better man than I
02:10estebannall: thanks! i'm encouraged
02:10brainproxyestebann: good luck, ask questions any time
02:11antares_riley526: that is correct. if you want to run lein repl with a particular version outside of a project, you need a version of leiningen that is compiled against that Clojure version
02:11antares_riley526: so, clojure version is specified per-project. Globally you can only change it with leiningen 2 via profiles.
02:11devnestebann: yeah. seriously. i hope ive been helpful. this is a great group of people who genuinely want to help, so dont be shy.
02:11devncheers
02:12estebanndevn: super helpful.. gnight
02:12devnciao
02:13riley526antares_: ok, so it's a lein 2 thing then. I wonder if I'd be better off just upgrading to a 2.0.0 preview now.
02:14antares_riley526: it's not hard, I think most of active Clojure projects are on lein2 by now
02:15riley526antares_: yeah, I'm really just starting out anyway, so I don't need *everything* to be supported.
02:15antares_riley526: it is not a lein2 thing per se, it's just for lein repl, Clojure is a library that's loaded. It can be managed like other dependencies but outside of projects, there is no "list of dependencies" in lein1. Lein 2 has :user profile that is always loaded.
02:16antares_riley526: https://github.com/technomancy/leiningen/wiki/Upgrading, download 1 script, put it on PATH, run lein self-install
02:17antares_interesting, I haven't tried to force a particular Clojure version outside of a project
02:37antares_riley526: there seems to be a regression in lein2 preview5 (just released) that breaks lein2 repl. I suggest putting together a small project and using either 1.7 or 2.0 preview 4 for now.
02:38riley526antares_: thanks for the heads up. I decided to stick with 1.7.1 for now, and just work out of a generic project.
02:38antares_good idea
02:39PeregrinePDXOk I've thought myself in circles three times. I have a list of anonymous functions. I want to execute each function in the list passing into each of them an arguement.
02:39PeregrinePDXI think I need one of the do functions but I've confused myself.
02:41antares_PeregrinePDX: doseq + (apply f arg)
02:41antares_PeregrinePDX: that's if you want to invoke them for side effects. If you care about returned values, use map + apply
02:42PeregrinePDXYeah, I care about the returned values. Thanks
02:59antares_PeregrinePDX: something like (map #(apply % [10]) [(fn [x] (* 5 x)) (fn [x] (* 2 x))])
02:59hiredmanwhat a waste
03:00hiredmanantares_: justify your use of apply
03:00antares_hiredman: it just an example
03:01antares_(map #(% 10) [(fn [x] (* 5 x)) (fn [x] (* 2 x))]) can work just as well
03:01emezeske&(doc juxt)
03:01lazybot⇒ "([f] [f g] [f g h] [f g h & fs]); Takes a set of functions and returns a fn that is the juxtaposition of those fns. The returned fn takes a variable number of args, and returns a vector containing the result of applying each fn to the args (left-to-right). ((juxt a b c) x) => [(a x) (b x) (c x)]"
03:01muhoo((juxt (fn [x] ...) (fn [y] ..) (fn [z] ...)) somearg) ?
03:02antares_yeah, yeah. juxt is exactly what you don't show people who are only getting started.
03:02emezeskePeregrinePDX: juxt is what you want
03:02antares_because it takes them 5 minutes to just read through that docstring
03:02emezeskeantares_: I for one, am always happy to be introduced to a function that does exactly what I want, rather than writing it myself...
03:02emezeskeantares_: And have been since day one.
03:03antares_emezeske: when you study a language, do you first learn words or sophisticated idiomatic expressions that involve not-so-standard use of tenses and so on?
03:03antares_juxt is exactly that kind of thing for functional programming
03:04emezeskeThat's a ridiculous comparison
03:04antares_it's ridiculous to feed newcomers juxt and call one extra "apply" call a waste
03:05emezeskeThe apply call was a waste though, with no purpose
03:07emezeskeAnyway, it's nothing personal if someone corrects your code in here, it happens to me all the time, and I learn from it
03:08emezeskeI actually am happy when I see a hiredman or an amalloy calling me out on stupid code, it's like a code review for free :)
03:08antares_I don't mind if my code is corrected. For whom it was pasted, it does not matter if there's a direct call or via apply or juxt. The person wants to get a feel of what it's like to pass function as values, starting with a simple example of iteration.
03:09emezeskeSo there's no problem with me answering the question "how do I print hello world" with this code snippet?
03:09emezeske&(apply apply apply str (list (list (list "hello " "world"))))
03:09lazybot⇒ "hello world"
03:10antares_emezeske: dude, go to some fucking haskell mailing list and show yourself off there
03:10antares_together with all "what a waste" and other comments
03:10emezeskeantares_: Okay, I'll exit this conversation at least, before I get cursed at again. Happy coding.
03:11antares_instead of provisioning lein2 preview 5 on travis-ci.org I have to listen to nonsensical comparisons of Clojure elitists
03:13abp_emezeske:
03:14emezeskeabp_: Did you send me a message? I don't see anything.
03:15abp_emezeske: sorry, were about to and hit return to early..
03:15emezeskeabp_: ^_^
03:15emezeskeabp_: I thought maybe my IRC client couldn't display it or something.
03:33clojure-newcomerhey guys, I'm having trouble working with JTidy (or adding as dependency to lein). I've got '[org.clojars.jmeeks/jtidy "r938"]' in project.clj, but I can't resolve Tidy in the REPL
03:33clojure-newcomerany ideas ?
03:36antares_clojure-newcomer: what does the exception message say?
03:36clojure-newcomerantares: if I use '(use '(org.w3c.tidy)) ' and then (new Tidy) I get 'Unable to resolve classname: Tidy'
03:37antares_clojure-newcomer: when you run lein repl (or lein deps), are there any exceptions?
03:37antares_clojure-newcomer: plus, is it '(use …) or (use …) ?
03:37antares_the former isn't evaluated (executed)
03:38clojure-newcomerhmm… its (use...
03:38clojure-newcomersorry was quoting in here...
03:38antares_clojure-newcomer: no problem. Can you please gist your project.clj?
03:38antares_I see that jtidy is available from oss.sonatype.org
03:39antares_that repo is not on the default leiningen list
03:39clojure-newcomersure
03:39antares_so you may need to add it like so: https://gist.github.com/29f6942b7a1ec5e2bd45
03:39antares_but if REPL starts, it probably means that the jar was resolved and downloaded
03:40clojure-newcomerantares: http://pastebin.com/FYABxJtp
03:40clojure-newcomeryes, I spotted it had resolved
03:40antares_clojure-newcomer: wait, I think I get it. you need (import org.w3c.tidy.Tidy), then (Tidy.) and (new Tidy) should work
03:41antares_use is for clojure namespaces
03:41clojure-newcomerI'll try it now
03:41antares_while you want to use a Java class
03:41clojure-newcomerantares: thanks
03:41clojure-newcomersorry newb here
03:41clojure-newcomernot really worked with java classes yet within clojure
03:41antares_clojure-newcomer: no problem, that's what this channel is for
03:46kralnamaste
03:46bobrya question about CA: is it possible to email a scan? or postal mail is the only option?
03:49antares_bobry: 4 months ago I was told that postal mail is the only option
03:53bobryoh, okay
04:21ro_sttechnomancy: i want to use clojure-swank's buffer <-> repl keybinding actions across frames (instead of across windows)
04:21ro_stis this possible?
04:22ro_sti already have the repl up in a separate frame on a new monitor, but the keybindings open up the repl in the active frame in a new window instead
05:24ro_stanyone using monger, in here?
05:25ro_sti want to know how to refer to nested fields in the find function
05:26ro_stusual mongo says use "item.field". monger uses :field to refer to fields. does this mean use :item.field? "item.field"?
05:55clojure-newcomerhey guys… how do I access the content of byte[] maybe iterating over a collection contained in it ?
05:57clojure-newcomerin this case its coming back from clojure.java.jdbc
06:04digcon9clojure-newcomer: you can call seq on that array and use any functions on sequences
06:05clojure-newcomerdigcon9: oh, cool
06:05clojure-newcomerthx
06:18DrakesonImagine that I need to define an object that needs to be evaluated just when it being consumed (a bit similar to lazy sequences; this one needs to interact with a bunch of caches and filesystem). Can I implement it without resorting to java?
06:20borkdudeDrakeson http://richhickey.github.com/clojure/clojure.core-api.html#clojure.core/delay maybe?
06:20lazybotNooooo, that's so out of date! Please see instead http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/delay and try to stop linking to rich's repo.
06:25DrakesonThanks. not exactly what I need, but close enough.
06:27borkdudeDrakeson maybe you can find more helpful things using Clojure Atlast ;) http://www.clojureatlas.com/org.clojure:clojure:1.4.0?guest=t#concept/delay
06:27DrakesonWhat would it take to get clojure.repl/doc to print documentation for java classes, methods, fields, packages, etc.?
06:28ro_sti believe doc is simply a metadata reader shortcut
06:28borkdudeDrakeson currently in reply you can just type (javadoc String) and it will point your browser to the javadoc online
06:29DrakesonNote: Opening javadoc in a browser does not count as *print*ing documenation
06:29ro_stthat's handy!!
06:29borkdudeDrakeson you can also get members, etc
06:30DrakesonI have used reflection to augment clojure.repl/doc to print members, fields, and constructors of a class, but haven't found a way to get at javadoc in a clean way.
06:32borkdudeDrakeson I guess you can take a look at https://github.com/clojure/clojure/blob/master/src/clj/clojure/reflect/java.clj
06:33borkdudeDrakeson ok yes, reflection is about as far as it goes I think
06:34Drakesonborkdude: That is interesting. Thanks.
06:34DrakesonIs there a clean way to get at javadoc, at all? In a related matter, is it possible to automatically rebuild [many] jars, but with javadoc enabled?
06:36borkdudeI wouldn't know, sorry
07:41zomgHm the doto macro is pretty nice :)
07:42KvaksWhat's the best way to install Clojure on Ubuntu? I suspect using the Ubuntu apt repos won't get me the freshest version. I believe I can also get Clojure with git or through leiningen (get leiningen first)? Which is the preferred way?
07:43florianoveruse leiningen
07:44KvaksA'ight.
07:49antares_Kvaks: installing leiningen is all you need typically. For production env, JDK is sufficient (apps are commonly packaged as "fat jars" with all the dependencies included, Clojure, too)
07:50KvaksThanks.
08:09bordatouehello
08:10bordatoueI have got a problem with clojure setup on emacs, everytime when i restart emacs i need to reinitalise the marmalade package
08:11bordatoueso on restarting emacs i lose clojure-mode
08:17vijaykiranbordatoue: what do you mean by reinitializing package ? load ?
08:19clojure-newcomerhey guys, I've got a clojure.java.jdbc result coming back as a byte[] its from a GROUP_CONCAT on an int(10) field. In the mysql client the result is '1,2,4,6,7,19,24,32,54,152'. I am unsure how to extract this result properly in clojure… (println (seq (samovar))) gives me an unexpected result
08:22antares_clojure-newcomer: that should be handled by the driver. Post more details to the mailing list?
08:23clojure-newcomerantares: ok, will do
08:23clojure-newcomerfor '1,2,4,6,7,19,24,32,54,152' I get (49 44 50 44 52 44 54 44 55 44 49 57 44 50 52 44 51 50 44 53 52 44 49 53 50)
08:23clojure-newcomerpretty confused
08:32Kototamahi, when using emacs+slime is there a way to have the exception during executions being displayed just like the errors during compilation?
08:32Kototamaie, in the slime debugger
08:32Kototamaand not just in the *swank* buffer for instance?
08:40bordatoueeverytime when i restart emacs, I am having to reinitialise package manually and install clojure mode. For some reason it is not saving package references installed . My current configuration is http://hastebin.com/menodiputi.lisp
08:41vijaykiranwhich version of Emacs are you using ?
08:42bordatouevijaykiran: emacs 23.1
08:42vijaykiranbordatoue: do you have elpa folder with clojure-mode in your .emacs.d ?
08:42bordatouevijaykiran: yes
08:43bordatouevijaykiran: elpa also contains archives
08:43vijaykiranbordatoue: I just have (load "~/.emacs.d/els/package.el") in my config
08:44vijaykiranbordatoue: may be you can try loading/requiring clojure-mode
08:44hoeckclojure-newcomer: that looks like the bytes of a string
08:44bordatouevijaykiran: that is what i am speculating ,is it necessary to have package.el under a subdirectory
08:45clojure-newcomerhoeck: yeah, I figured, unfortunately being a clojure newb I can't do much with them yet
08:45hoeckclojure-newcomer: mysql group concat produces a string, the driver probably fails to convert it to a java string
08:46clojure-newcomerhock… there is a mysql issue where if I also use a group_by it produces a binary result
08:46vijaykiranbordatoue: does M-x list-pacakges list the clojure-mode as installed ?
08:47clojure-newcomerhoeck: sorry, just had a typing incident unsure where the hock… came from
08:48hoeckclojure-newcomer: if you know the encoding you are using (probably utf-8, but for comma-separated numbers it doesn't matter), (String. <the-bytes>) should work
08:49clojure-newcomerhoeck: I'll try it thanks
08:49hoeckclojure-newcomer: by binary result you mean an array of bytes?
08:49clojure-newcomerhoeck: yes
08:50hoeckand its a group-by over a stringy column?
08:50clojure-newcomerhoeck: over an int(10) column
08:51hoeckmysql or the java driver probably mess up type information then, which type has the column in the resultset?
08:51clojure-newcomerhoeck: String. <the bytes> is getting me there
08:52clojure-newcomerhoeck: I get (\1 \, \2 \, \4 \, \6 \, \7 \, \1 \9 \, \2 \4 \, \3 \2 \, \5 \4 \, \1 \5 \2), which is almost there
08:52hoeckI'd rather not mess with manually building integers from byte seqs, who knows what the driver will return in the next minor release :/
08:53hoeckclojure-newcomer: huh? are you calling seq on the created string?
08:53clojure-newcomerhoeck: yeah, forgot to remove that, had just fixed it while chatting in here
08:53hoeckdo you need the string or the list of ints?
08:54clojure-newcomerhoeck: your earlier fixed things for me, String. <the-bytes>, thanks for your help
08:55hoeckclojure-newcomer: your're welcome
08:55clojure-newcomerhoeck: java interop is still like magic with me :-)
08:59clgvclojure-newcomer: it's just java with different syntax ;)
08:59clojure-newcomerclgv: I am getting there very slowly :-)
08:59clojure-newcomerclgv: it's my first Lisp too, and I'm new to Emacs, so its a big deal all at once
09:00bordatouevijaykiran: yes,
09:00clgvclojure-newcomer: oh, then you are one step ahead of me. I am foreign to emacs ;)
09:00bordatouevijaykiran: I tried everyting i can
09:01bordatoueclgv: you are not alone, I am new to clojure and emacs
09:01clgvbordatoue: oh well, I program clojure for 2 years now ;)
09:02bordatoueclgv: well done
09:06clgv$findfn [nil nil nil 70 79] [111 83 78 nil nil 59] [111 83 78 70 79 59]
09:06lazybot[]
09:06clgv:(
09:07clgv $findfn [111 83 78 nil nil 59] [nil nil nil 70 79] [111 83 78 70 79 59]
09:07clgv$findfn [111 83 78 nil nil 59] [nil nil nil 70 79] [111 83 78 70 79 59]
09:07lazybot[]
09:07clgv(map or [111 83 78 nil nil 59] [nil nil nil 70 79]) doesnt work since `or` is a macro^^
09:08ivanmap is also tricky because it'll run out on the shortest sequence
09:08Bronsa,(mapv #(or % %2) [1 2 nil 4] [nil nil 3 nil])
09:08clojurebot[1 2 3 4]
09:08ivan,(mapv #(or % %2) [1 2 nil 4 5] [nil nil 3 nil])
09:08clojurebot[1 2 3 4]
09:09clgvyeah as function it works ;)
09:09clgvit's a pity there is no function or ^^
09:09clgvdefinline would do, I guess
09:09clgv ivan:oh right^^
09:11clgvivan: but I have a version for that one ^^
09:24dnolenPersistentVector construction now 10x faster in CLJS master.
09:25KIMAvcrpI have to start exploring clojure-script
09:32clgvdnolen: how did that happen?
09:33dnolenclgv: just better construction, in particular JS engines that are not V8 seems to poorly with many object instantiations - this happens when we convert a PV to a transient.
09:34dnolenclgv: if the vector being constructed is less than 32 we can just set the tail and cnt, no need to bother transients.
09:34dnolen"seem to perform poorly"
09:34clgvdnolen: ah ok. interesting.
09:36dnolenclgv: makes PV construction under V8 competitive with the times under the JVM
09:36dnolenclgv: I suspected PV construction time was a problem after some perf issues lynaghk mentioned.
09:36clgvdnolen: wow, thats awesome
09:37dnolenmmarczyk: ping
09:37mmarczykdnolen: pong
09:37dnolenmmarczyk: PV construction got 10X faster :)
09:39mmarczykdnolen: I've noticed the commit, yeah -- I guess most vector literals are <= 32 elements, so that should be very cool :-)
09:40dnolenmmarczyk: should address the slowness of the various fns that return small vectors - which is a lot of code out there :)
09:40mmarczykdnolen: exactly :-)
09:40dnolenmmarczyk: including lynaghk issues with the regex fns
09:40mmarczykdnolen: did you notice CLJS-290 ?
09:40mmarczykdnolen: right
09:41dnolenmmarczyk: looking
09:44dnolenmmarczyk: you'll need to redo the patch, was too close to my PV optimizations
09:44mmarczykdnolen: ah, sure; just a sec
09:47mmarczykdnolen: done
09:47mmarczykdnolen: ah, wait
09:52mmarczykdnolen: ok, working patch attached
09:54dnolenmmarczyk: started working on source-map support
09:56mmarczykdnolen: marvellous! with source maps, cljs just might have a better debugging/profiling story than Clojure :-)
09:57dnolenmmarczyk: yeah, profiling is already ok, browsers make it easy.
09:57dnolenmmarczyk: source-map support require some kind of merging which will be interesting.
09:57dnolenrequires
09:59mmarczykdnolen: merging? you mean cljs-to-js with js-to-adv-comp-js ?
10:00dnolenmmarczyk: cljs-to-js with js-to-any-comp-mode-js
10:00mmarczykhm, right
10:01dnolenmmarczyk: one big perf issue I'm very unhappy with is update perf of small maps - so slow.
10:03mmarczykdnolen: well, PHM is faster for updates, so making the conversion thresholds smaller would help here
10:04dnolenmmarczyk: I don't think it will really solve the problem.
10:04borkdudehow can I pull in some changes from a origin/master branch until a certain commit?
10:04dnolenmmarczyk: tiny maps are common {:x n :y n}
10:05dnolenmmarczyk: even under V8 you can't update a map more than 100000 times in under 1s.
10:05mmarczykdnolen: even a PHM, no hash collision? hm
10:05dnolenmmarczyk: actually you're probably right, should make a benchmark for this.
10:06mmarczykdnolen: yeah, some plots would be nice
10:10mmarczykdnolen: do you mean small obj maps primarily or maps in general (possibly w/ complex keys)?
10:10mystiiqhow can I generate partial sums of a list (example: [1, 3, 6, 2, 7, 4] -> [0, 1, 4, 10, 12, 19, 23] I know it's very basic but I haven't done any functional programming tbh
10:11KIMAvcrpmystiiq: take a look at the reduce function
10:11mfex,(reductions + [1 3 6 2 7 4])
10:11clojurebot(1 4 10 12 19 ...)
10:11dnolenmmarczyk: small maps, simple keys
10:12mfexmystiiq, see reductions and reduce
10:13KIMAvcrpcool haven't heard of reductions before
10:13mfex,(reductions + 0 [1 3 6 2 7 4])
10:13clojurebot(0 1 4 10 12 ...)
10:14mystiiqmfex: thanks :>
10:14mfexKIMAvcrp, I like your paip with clojure blogpost. I also went through paip and translating to clojure, I found it to be a very helpful way to go through the material
10:32dnolenmmarczyk: I'd also like to see PHMs get to PV level perf, currently they seem like 10X too slow for all operations.
10:38mmarczykdnolen: heh, certainly a goal worth pursuing :-)
10:39mmarczykdnolen: I'll look into some possible optimizations, both for small maps and PHMs
10:47dnolenmmarczyk: haha! checkout these graphs for PV construction :) http://www.50ply.com/cljs-bench/#plot15
10:48mmarczykdnolen: yeah, that's great :-)
10:50mmarczykdnolen: hm, I wonder what's the deal with (get {:foo 1 :bar 2} :foo) suddenly getting slower? (which I'd have never noticed w/o the graphs -- soooo cool)
10:52dnolenmmarczyk: well SM and JSC got slower V8 didn't change.
10:54dnolenmmarczyk: oh, maybe I'm not looking at the right one - which graph?
10:54mmarczykdnolen: apparently (:foo {...}) got slower across the board
10:54mmarczykdnolen: [coll {:foo 1, :bar 2}] (:foo coll) is most interesting
10:57dnolenmmarczyk: hmm not sure what's going on there all those commits are PV related.
10:57mmarczykdnolen: right
10:58dnolenmmarczyk: so one thing that's really slow in CLJS is hashing strings
10:59mmarczykdnolen: we inherit that from gclosure lib, I believe?
10:59dnolenmmarczyk: I believe the JVM caches string hash codes somehow? but clearly that's not the case for us.
11:00mmarczykdnolen: ah, yeah, that's true unfortunately :-(
11:00dnolenmmarczyk: I have a simple optimization here that caches strings makes things 10X faster for hashing strings - but of course that proably won't scale in real programs.
11:02dnolenmmarczyk: doubles PHM access performance
11:03mmarczykdnolen: no native hashing function in JS? :-(
11:04dnolenmmarczyk: I wonder how hard a fast weakmap implementation would be?
11:08mmarczykdnolen: there's no native support for weak refs, right?
11:08mmarczykdnolen: apparently Mozilla is playing around with native weakmaps though, https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/WeakMap
11:09mmarczykdnolen: also googled http://code.google.com/p/es-lab/source/browse/trunk/src/ses/WeakMap.js which claims to implement what's needed in JS, ~450 lines
11:23bosiei am trying to get leiningen to run but all i get is this: "- klass: 'java/lang/classnotfoundexception'"
11:23bosiei installed lein with homebrew (macosx here)
11:27bosieclojure was installed with homebrew as well
11:27S11001001no need to install clojure if you have lein
11:27S11001001lein won't even use it
11:27bosiehttps://gist.github.com/2852929
11:28bosieS11001001: well, uninstalled clojure now
11:29S11001001hmm, try lein new bosie/clojure-stuff
11:30S11001001I am not sure what running lein without a subcommand does :)
11:30bosieS11001001: i executed "lein new bosie/clojure-stuff"
11:30S11001001lein --version and lein help are also helpful
11:30bosieS11001001: i can't run lein --version
11:30bosieS11001001: the same Trace/BPT trap thingie appears
11:31S11001001how about a ~/.lein/? There should be a leiningen jar in that tree somewhere
11:31bosieS11001001: under self-isntalls there is leiningen-1.7.1-standalone.jar
11:32S11001001from which you can try java -cp path/to/leiningen.jar clojure.main -e '(pr "hello")'
11:32bosieworked
11:32bosieprinted hello
11:32bosie ~ » java -cp ~/.lein/self-installs/leiningen-1.7.1-standalone.jar clojure.main -e '(pr "hello")' "hello"%
11:34S11001001hmm, does homebrew's lein script deviate from the standard one?
11:35bosieS11001001: beats me
11:35S11001001(I'm hinting towards installing the standard way, which I know to work on OS X)
11:35bosieS11001001: i went to homebrew cos the standard way didn't work
11:36bosieS11001001: if by standard you mean the script
11:36S11001001if the standard way didn't work your system config has bigger problems
11:37bosieS11001001: i put the script into my bin, made it 755, and executed "lein repl"
11:37bosieresult: https://gist.github.com/2852988
11:37S11001001like this thing is suspicious -Xbootclasspath/a:"$CLOJURE_JAR"
11:38S11001001definitely nonstandard
11:38bosiemy os is actually a fresh install (< 7 days)
11:38ivanputting clojure.jar in Xbootclasspath reduces startup time
11:39S11001001someone trying to be clever and speed up startup at the cost of screwing anyone who wants to run a different clojure
11:39bosieS11001001: its in the script
11:39bosieS11001001: https://raw.github.com/technomancy/leiningen/stable/bin/lein
11:39S11001001weird, that's not in mainline
11:40S11001001and, er, it only works if you have that clojure jar
11:40bosiehm
11:41bosieS11001001: so what is THE standard way then?
11:41S11001001you've got it, grab the script, stick it somewhere, lein self-install
11:41bosieS11001001: i can't. any "lein X" command goes to the same trap-excpetion
11:42bosieclassnotfound shit
11:42bosiegah
11:42dnolenmmarczyk: https://github.com/clojure/clojurescript/compare/master...string-hash-cache
11:43bosieanyone else has a brilliant idea?
11:44TimMcbosie: What does `which lein` tell you?
11:45bosieTimMc: /Users/bosie/bin/lein
11:45bosiesuccess
11:45bosiehad to nuke both .m2 and .lein
11:45TimMcheh
11:45bosienow "lein version" installed something and "lein version" gives me
11:46S11001001cool
11:46bosieLeiningen 1.7.1 on Java 1.6.0_31 Java HotSpot(TM) 64-Bit Server VM
11:46TimMcNuking .m2 always helps.
11:46bosieTimMc: seems to be the clojure installation or sth?
11:46TimMcHelps keep your system regular.
11:46S11001001wagon likes to leave empty/incomplete files lying around
11:46bosiewhat is wagon?
11:46TimMcbosie: .m2 the Maven local cache.
11:46S11001001bit of maven that downloads stuff
11:46bosiek
11:47TimMcLein uses Maven behind the scenes to manage dependencies.
11:47S11001001it's an enterprise file copying framework
11:47mmarczykdnolen: very cool!
11:47TimMcclojurebot: Maven is <reply>Help, I'm trapped in an XmlFactoryFactory!
11:47clojurebotOk.
11:47S11001001there's a chart and everything https://maven.apache.org/wagon/
11:48bosieTimMc: speaking of ... "Couldn't find project.clj, which is needed for deps" haha ;)
11:48mmarczykdnolen: is it faster than hash on short strings once mru is filled though?
11:49dnolenmmarczyk: mru is only used for populating the cache after it exceed 256 keys.
11:50mmarczykdnolen: hm, it's being pushed onto and shifted once per add op
11:51dnolenmmarczyk: yes it always holds most recent new keys.
11:51dnolenmmarczyk: open to better ideas! :)
11:52dnolenmmarczyk: on V8 getting hash-code for strings is down to 4ms, JSC strangely lagging.
11:52mmarczykdnolen: hey, I'm not claiming I have any :-)
11:53mmarczykdnolen: basically bashing stuff at random to see if an idea jumps at me
11:53mmarczykdnolen: how about hashing, say, 1000 different strings in sequence?
11:53mmarczykdnolen: I guess each of them twice to match map-related usage patterns
11:53clojurebotPardon?
11:55dnolenmmarczyk: that's a good idea
11:55mmarczykdnolen: also, which string length are you testing this with?
11:56dnolenmmarczyk: very short key :f0
11:56mmarczykdnolen: oh, that's great :-)
11:56dnolenmmarczyk: 8-10X faster for V8 and SM, 2X faster for JSC
11:57dnolenmmarczyk: you're hash-coll test idea is a good one checking that now.
11:58mmarczykdnolen: hm, I guess the smallest dynamic use case is construct map with a string key in one place, pass it to another place, look at same key again fairly soon... in a more "static" case the map might be constructed very early, so maybe no help from early hashing (assoc time) once the code gets around to late caching (lookup time)
11:59mmarczykdnolen: obviously some loops hash the same string all the time, so these will benefit like crazy
11:59mmarczykdnolen: meaning, seems like a good idea :-)
12:00dnolenmmarczyk: yes, it trying simulate what we get from the JVM for free for most programs.
12:01dnolenmmarczyk: nice Brendan Eich gave CLJS a shoutout at FluentConf
12:02mmarczykdnolen: cool :-)
12:09bosiethanks S11001001 , TimMc
12:09dnolenmmarczyk: hmmm given that we hash caching for all collections, I'm not sure hashing perf matters much :) but I'm checking anyway.
12:19dnolenmmarczyk: http://github.com/clojure/clojurescript/compare/master...string-hash-cache
12:20dnolenmmarczyk: excellent point about hash-coll, neglible hit now, hash takes a second parameter which can be used to skip the cache check.
12:28mmarczykdnolen: hm, it seems that caching logic would fit nicely in string's -hash
12:29mmarczykdnolen: clearly problematic if an extra arg is needed... hm
12:30mmarczykdnolen: also, I think hashing moderate-to-large numbers of strings in sequence is a reasonable usage pattern outside of hashing colls -- I don't mean in one place: in total
12:32mmarczykdnolen: so I'm wondering about the perf of something like (dorun (map #(dotimes [_ 4] (hash %)) [...lots of strings...])) (or maybe 8-16?) as an approximation of the usage pattern where lots of strings are hashed with relatively poor "locality"
12:32dnolenyes CLJ JVM baselines! http://www.50ply.com/cljs-bench/
12:33dnolenmmarczyk: yeah, I'm sure this idea needs tweaking further thought / testing, thus in a branch for now.
12:38JanxSpiritcan I ask a dumb newb question about clojure dev workflow?
12:38RickInGAJanxSpirit: Sure, and cool name
12:39JanxSpiritI keep reading about the tight integration with the REPL - and I've tasted a bit of that sweetness playing around with the ClojureOne project
12:39dnolenmmarczyk: http://dev.clojure.org/jira/browse/CLJS-291, one PHMs are slow.
12:39JanxSpiritRickInGA thanks :)
12:39JanxSpiritso I get that you can dynamically modify the running program with the REPL - that's indeed cool
12:40JanxSpiritbut when I get something I want to save - something that works - do I still go back and edit source files to add the things I liked from the REPL?
12:40JanxSpiritor is there some slicker workflow I'm missing?
12:41mmarczykdnolen: ah, interesting
12:41mmarczykdnolen: will look into it, and also test out another idea about find that I had
12:41llasramJanxSpirit: The part you're missing is that usually the things you evaluate in the REPL are bits of the actual source file(s) for the poject you're working on
12:42mmarczykdnolen: incidentally, I've been playing with chunks & array-reduce
12:42JanxSpiritworkflow I'm used to (in Scala) is - edit source, SBT auto compiles for me, deploys, rinse, repeat
12:42mmarczykdnolen: didn't manage to squeeze out much of a perf win so far though.
12:42llasramJanxSpirit: In any of the full-on Clojure environments you edit a snippet of code, evaluate, and you're already-running environment is updated with the new code, without skipping a beat
12:42llasrams,you're,your,
12:43JanxSpiritllasram but essentially I'm "trying things out" in the REPL and if I want to keep them in the project, I go into Emacs and add them to my various source files, correct?
12:43RickInGAJanxSpirit: The way I do it, is I will write the new code in a source file in emacs, and then I use C-M-x to send a form to an inferrior lisp repl
12:43llasramJanxSpirit: Yes and no. I v v rarely type things into the REPL directly. Instead I just type them into a file and evaluate from there.
12:44JanxSpiritoh - OK - the evaluate from a file bit is something I'm missing I think
12:44PeregrinePDXYeah, actual code you want to use goes into the file.
12:45RickInGAJanxSpirit: yeah can use either swank/slime or inferrior lisp in conjunction with the source file in emacs.
12:45PeregrinePDXI occasionally test a function or whatever from the repl.
12:46JanxSpiritcool - so the upside is that you can evaluate a single form in a source file and have that reflected in the running process
12:46JanxSpiritthat's a step up from my Scala workflow - maybe 2
12:48TimMcI just write everything correctly the first time. Way faster.
12:49TimMcI don't know what you people are on about. ;-)
12:49RickInGATimMc: I can see why that would be a good workflow, I have never once been able to implement it though
12:49RickInGATimMc: can you teach that? I bet that would be a popular class
12:51TimMcHaha! "The first step is, be a rock star."
12:51TimMc"There is no second step."
12:51RickInGA:)
12:52TimMcJanxSpirit: In reality, I tend to write a bunch of stuff in Emacs -- including tests -- then run and debug until it works.
12:52technomancythe Feynman problem solving method
12:52technomancy1. Write down the problem
12:52technomancy2. Think very hard
12:52technomancy3. Write down the answer
12:52RickInGATimMc: I just saw this video yesterday, think it sums up your work flow http://www.youtube.com/watch?v=jFUYYNVZuek
12:53TimMc"This video is currently unavailable."
12:54cshellIs congomongo the best clojure library for MongoDB?
12:56BronsaFeynman was a good man.
12:57RickInGAjcrossley3: Just read your interview on the Clojure/core blog. Cool stuff. you definitely will have to host an immutant coding session
12:59jcrossley3RickInGA: thanks, man. that would be fun!
13:04fbru02Hi all, stupid question probably does anyone know if Datomic supports idempotent writes/deletes?
13:13cemerickdnolen, mmarczyk, et al.: remarkable results you guys are getting out of cljs. Phenomenal work.
13:30dnolenmmarczyk: yeah chunks need careful inspection to determine what's slowing things down.
13:32dnolencemerick: thanks, lot more work to do. hopefully we be very close or surpassing JVM on all benchmarks by StrangeLoop
13:33dnolenat least on V8 anyhow, with a good show on JSC and SM
13:33mmarczykcemerick: thanks, lots of fun to be had in the process :-)
13:33mmarczykdnolen: agreed
13:35mmarczykdnolen: as for surpassing jvm, for now I'm not sure what the deal is with (list) -- the others must surely be due to :opts :adv compiling things away? (except transients which don't have to deal with (AtomicReference. (Thread/currentThread)))
13:37dnolenmmarczyk: I think there are very few benchmarks where we'll beat the JVM, but I wouldn't be surprised if we have a couple legitimate cases.
13:39mmarczykdnolen: yeah, and the 2x - 4x target does seem realistic
13:39mmarczykdnolen: and V8 is getting better, so... :-)
13:40mmarczykok, must dash off for now
14:38devthsetup a simple logger according to https://github.com/malcolmsparks/clj-logging-config but I see no log output in my console when i "lein run". am I missing something?
14:44ezyangDo Clojure sorted maps have a range query mechanism?
14:46turbofailyes, though i can't remember the name of the function off the top of my head
14:48gtrakanyone have an example of extending a protocol to a record by delegating to a member field?
14:48amalloy&(doc subseq)
14:48lazybot⇒ "([sc test key] [sc start-test start-key end-test end-key]); sc must be a sorted collection, test(s) one of <, <=, > or >=. Returns a seq of those entries with keys ek for which (test (.. sc comparator (compare ek key)) 0) is true"
14:50antares_ezyang: yes, for example: (subseq (sorted-map :a 1 :b 2 :c 3 :d 4) > :b < :d)
14:54borkdude,(subseq (sorted-map :a 1 :b 2 :c 3 :d 4) > :b < :d)
14:54clojurebot([:c 3])
14:55borkdude,(into {} (subseq (sorted-map :a 1 :b 2 :c 3 :d 4) > :b < :d))
14:55clojurebot{:c 3}
14:56borkdude,(< :a :b)
14:56clojurebot#<ClassCastException java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.lang.Number>
14:57borkdudeok, it selects based on the values
14:57ezyangAh, I see, you have to use the Seq mechanism. OK.
14:57borkdudeor not? no
14:59amalloyborkdude: it selects on keys, using ##(doc compare)
14:59lazybot⇒ "([x y]); Comparator. Returns a negative number, zero, or a positive number when x is logically 'less than', 'equal to', or 'greater than' y. Same as Java x.compareTo(y) except it also works for nil, and compares numbers and collections in a type-independent manner. x must implement Comparable"
14:59antares_ezyang: technically subseq is part of the "sorted" abstraction. But not knowing that totally fine ;)
15:00borkdudeamalloy ok
15:00ezyangActually, that is kind of important, since I'm interacting with the Java classes not in Clojure.
15:03antares_ezyang: sorted maps implement Map and Iterable. Do you think you'll need something else from them?
15:04ezyangIterators don't support iteration from specified element (e.g. range query)
15:06antares_ezyang: so you need to do subseq from Java?
15:07ezyangYep.
15:08ezyangLooks like ISeq doesn't have an iterator method, which makes sense, I suppose.
15:08antares_ezyang: subseq implementation is pretty small but relies on take-while
15:08ezyangright, I think I'll just reimplement that in Java.
15:08antares_ezyang: ISeqs may or may not be ordered
15:08antares_ezyang: ok
15:09KIMAvcrpfinally managed to port Chapter 4 of PAIP to clojure, enjoy
15:09KIMAvcrphttp://kimavcrp.blogspot.de/2012/06/porting-paip-to-clojure-chapter-4-gps.html
15:10amalloychouser: i just made an update to http://dev.clojure.org/jira/browse/CLJ-865 - you were screening it for me months ago, and i think i just addressed the main issue you had, thanks to a suggestion from andy fingerhut on the mailing list. i'd appreciate it if you could take a look and see if i'm headed the right direction
15:10ezyangHmm, I wonder what the 'Seq' that is returned contains.
15:11ezyangIs it nodes? If that's the case, this will be kind of annoying...
15:13ezyang(since TreeMap nodes are not a public type...)
15:14antares_ezyang: Map.Entry?
15:16TimMc&(class (first (sorted-map :a :b)))
15:16lazybot⇒ clojure.lang.PersistentTreeMap$BlackVal
15:17TimMc&(bases (class (first (sorted-map :a :b))))
15:17lazybot⇒ (clojure.lang.PersistentTreeMap$Black)
15:17tomojsuppose (last (into [] (persistent! (doto tcoll (conj! x) end!)))) returns x
15:18tomojbut (into [] (persistent! (doto (-> tcoll (conj! x)) end!))) and (into [] (persistent! (-> tcoll (conj! x) end!))) return []
15:18tomojare these persistent/transient semantics seriously broken?
15:18TimMctomoj: I don't think you're supposed to use doto there.
15:18TimMc&(doc conj!)
15:18lazybot⇒ "([coll x]); Alpha - subject to change. Adds x to the transient collection, and return coll. The 'addition' may happen at different 'places' depending on the concrete type."
15:18antares_tomoj: conj does not add stuff to the end for all specific collection implementations
15:19hiredmantomoj: doto is bashing in place
15:19S11001001ah yes, that would be a problem
15:19tomojI know
15:19TimMc&(isa? (class (first (sorted-map :a :b))) java.util.Map$Entry)
15:19lazybot⇒ true
15:19TimMcezyang: ^ You're in luck.
15:20tomojconj adds on the end for these collections
15:20ezyangHuh, I guess they are MapEntry.
15:20tomojand bashing in place is part of the example
15:20S11001001,(doc end!)
15:20clojurebotExcuse me?
15:20tomojend! is extra
15:20S11001001I agree clojurebot
15:20ezyangthat's handy.
15:20amalloytomoj: what example?
15:20TimMcezyang: https://www.refheap.com/paste/2961
15:20amalloybashing in place is absolutely not the intended/working use pattern for transients
15:21tomojthe example I gave of the three bits of code
15:21amalloyokay. then those are broken, yes
15:21ezyangIt is too bad ISeq is not iterable though >:-)
15:23amalloynew clojure.lang.SeqIterator(someSeq)
15:23tomojmainly because the supposedly persistent collections are not immutable?
15:25S11001001tomoj: assuming that end! uses transient funcs on its arg, the only example with reliable semantics you gave was the last one
15:26ezyangamalloy: Hmm. They should've added implements Iterable to ISeq then...
15:26amalloyno, yuck
15:27TimMcWhy the heck not?
15:27amalloybecause then everyone who implements ISeq would have to implement Iterable too
15:28amalloythis way, you can just wrap it in a pre-built iterator
15:28amalloycomposition, not inheritance
15:28TimMcHmm...
15:28ezyangaight
15:28kmicuamalloy: bottom-up FTW
15:28TimMcOK, that makes sense.
15:29S11001001tomoj: as for the mutability of immutable collections, such situations do exist, but it's highly unlikely you've found one
15:29tomojI am implementing a new collection
15:29ezyangI mean, if it were an abstract class, you'd just put in a default implementation and that'd be it.
15:29ezyangIt's mostly a convenience thing ^_^
15:30TimMcezyang: Exactly, that's what I was thinking.
15:30ezyangAnd you can even overload it so that something more efficient happens later.
15:30ezyangThis would be how you'd probably do it in Haskell.
15:30tomojI have basically future seqs from cljque (a future seq is an element and a watchable promise for a future seq). except I want to uncomplect the INotify and ISupply interfaces inside the fseq impl. so you have say a "builder" (corresponding to a transient) exposing the ISupply into which you can conj! an element, returning a new builder for the next fcons
15:31tomojthen you have a future seq (corresponding to the persistent?) into which you could maybe conj a new element, but that would not add it statefully
15:32tomoji.e. it would create a new fcons cell, not resolve the fcons cell of the fseq's builder
15:32hiredmantomoj: transients are essentially for optmizing birthing of new collections, sounds like what you want is an atom
15:34tomojhmm
15:35hiredmanhttps://blogs.oracle.com/jrose/entry/larval_objects_in_the_vm
15:39llasramThis may be more of a Java question than a Clojure question, but:
15:39llasramI've got a deftype implementing Comparable, but sort time for it is ~2x sorting the equivalent String representations, even after re-writing the comparison itself as a Java static method, and AOTing the Clojure to verify that the .compareTo implementation isn't doing anythin crazy
15:41tomojno clue if this is relevant, but did you also turn on reflection warnings?
15:41llasramtomoj: Oh yeah. No reflection. The AOTing was so I could verify the bytecode :-)
15:41llasramThe compareTo implementation ultimately walks two byte-arrays, comparing byte-by-byte
15:42llasramIs that just ultimately going to be slower in Java than the java.lang.String's compareTo, or is there anyhing else I might be missing?
15:42llasramI guess I need to compare a pure Java version, for completeness
15:43amalloyllasram: have you looked at the implementation of String/compareTo?
15:44llasramI found *an* implementation in Java, but I don't know my JVM well enough to know if this is ultimately what's being used
15:45llasramhttp://hg.openjdk.java.net/jdk7/build-gate/jdk/file/tip/src/share/classes/java/lang/String.java
15:45amalloyllasram: https://gist.github.com/a3af4bd957fc1545483d is the jdk6 impl
15:45borkdude,(javadoc String)
15:45clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: javadoc in this context, compiling:(NO_SOURCE_PATH:0)>
15:45borkdudehehe
15:46amalloy$javadoc String
15:46lazybothttp://docs.oracle.com/javase/6/docs/api/java/lang/String.html
15:46llasramWell, looks the same. Is that actually what gets used? No funky speed-ups from swapping in native code for core classes?
15:47amalloyyes
15:47llasram(well, I guess I could try to determine that for myself as well)
15:47llasramOk
15:47llasramHmm
15:47amalloyor at least, i know of no mechanism that would make this not get used
15:48llasramOk. Well, thanks for the information. That gives me hope that if I keep poking at it, I can find the issue
16:08ethanisis it possible to write a regular expression that spans multiple lines in clojure?
16:08ethanis(the expression itself, this is not a question about matching multiple lines)
16:09ethanisis the most idiomatic way to do this by using the (re-pattern) function explicitly?
16:10borkdudeI guess strings can span multiple line in clojure
16:10borkdudeso..?
16:10matthaveneranyone have any opinions/papers/blogposts/presentations they could recommend on the balance between hammock-time/planning and overplanning/ http://en.wikipedia.org/wiki/Analysis_paralysis
16:10ezyang"Think until you understand, code until you don't."
16:11bbloomezyang: nice. who said that?
16:11matthavenerezyang: damn thats good :)
16:11technomancymatthavener: one thing that's helped a lot for me with Leiningen is being willing to wait for the right solution to come
16:11bbloomethanis: are you asking about regexp options? like ignore case & multiline and stuff?
16:11technomancysometimes you need something right now that works, but if you don't you'll be much happier in the end
16:11ethanisno, I'm talking about writing a regexp literal itself over multiple lines
16:11ethanis#"bla
16:12ethanisnew line
16:12ethanis..."
16:12ezyangbbloom: Me. :P
16:12matthavenertechnomancy: i like that too :) but sometimes 'schedules' interfere :P
16:12bbloom:-)
16:12bbloomethanis: that seems to work fine
16:12borkdudeibdknox wow you passed 300k :)
16:13ethanis(re-matches #"a
16:13ethanisb" "ab")
16:13bbloomethanis: yeah, you need the multiline option :-)
16:13bbloom1 sec while i find those docs
16:13duck1123ethanis: create your pattern as a string then pass to re-pattern
16:13ethanisah, ok, thanks bbloom
16:13ethanisyep, i can definitely make it as a string
16:13borkdudeethanis it will match a followed by a newline I guess this way and then b
16:14bbloomethanis: use (?m) like this
16:14technomancydoes anyone know of any maven repos with self-signed SSL certs?
16:14duck1123,(let [pattern "foo\nbar"] (re-pattern pattern))
16:14clojurebot#"foo
16:14clojurebotbar"
16:14bbloom#"(?m) ....
16:15borkdudeethanis https://gist.github.com/2854854
16:15ethanisvery cool, thanks for the tips everyone
16:15bbloomhmm… that's just multiline mode
16:15bbloomnot "verbose" mode where you can have whitespace and comments
16:16bbloom(?x) maybe
16:16bbloomuser=> (re-matches #"(?x)a
16:16bbloomb" "ab")
16:16bbloom"ab"
16:16bbloomyup that works
16:17ethanis,(re-matches #"(?x)a
16:17clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading regex>
16:17ethanisb" "ab")
16:17bbloomclojure bot doesn't support multi line, use this:
16:17ethanisno worries, definitely works in the ole' repl
16:17bbloom,(re-matches #"(?x)a\nb" "ab")
16:17clojurebotnil
16:17bbloomhmm
16:17bbloom,(re-matches irc://irc.freenode.net:6667/#"(?x)a\\nb" "ab")
16:17clojurebot#<CompilerException java.lang.RuntimeException: No such namespace: irc://irc.freenode.net:6667, compiling:(NO_SOURCE_PATH:0)>
16:17bbloomguess not on the \n heh
16:18bbloomdocumented here: http://docs.oracle.com/javase/1.4.2/docs/api/java/util/regex/Pattern.html#COMMENTS
16:18borkdudebbloom you should put #" in front of that
16:19bbloomborkdude: ?
16:19borkdudenm
16:19bbloom,(re-matches #"a\\nb" "ab")
16:19clojurebotnil
16:20bbloom*shrug*
16:20borkdudebbloom in clojure you don't have to escape \n I think
16:20bbloomyeah, but didn't seem to work w/ clojurebot
16:20bbloomthought maybe clojurebot was doing funky line handling
16:20bbloom&(re-matches irc://irc.freenode.net:6667/#"a\\nb" "ab")
16:20lazybotjava.lang.RuntimeException: No such namespace: irc://irc.freenode.net:6667
16:21bbloomwhy is my dopey irc client copy pasting poorly
16:21bbloom…. grrr
16:21bbloom&(re-matches #"a\\nb" "ab")
16:21lazybot⇒ nil
16:21borkdude,(re-matches #"a\nb" "a\nb")
16:21clojurebot"a\nb"
16:21bbloom&(re-matches #"(?x)a\nb" "ab")
16:21lazybot⇒ nil
16:21borkdudebbloom there is a \n in your pattern, so it has to match that
16:22bbloomborkdude: the point is to get the ?x mode working :-P
16:22bbloomit works in my repl w a real newline instead of \n
16:22bbloomno biggie, glad it worked for the guy asking about it :-)
16:23borkdude,(re-matches #"(?x)a\nb" "ab")
16:23clojurebotnil
16:23borkdudethat should return "ab"?
16:24bbloomyes
16:24bbloomtry it with a newline instead of \n in your repl
16:24bbloom,(re-matches #"(?x)a\rb" "ab")
16:24clojurebotnil
16:24bbloom,(re-matches #"(?x)a\\rb" "ab")
16:24clojurebotnil
16:24borkdudebbloom with spaces in between it works
16:25bbloommakes sense
16:25solussdin korma can I rename the key populated by a (with …) clause? e.g. (select user (with address :as addresses)) ?
16:25bbloom,(re-matches #"(?x)a b" "ab")
16:25clojurebot"ab"
16:25bbloomthe ?x mode also supports # comments
16:26borkdude,(re-matches #"(?x)a b #well, this is a very cool pattern, don't you think?" "ab")
16:26clojurebot"ab"
16:26borkdude,(re-matches #"(?x)a b #well, this is a very cool pattern, don't you think?" "ababab")
16:26clojurebotnil
16:32coventry`Is there a framework for clojure which somehow tracks the functions with side effects for you? Kind of like the IO monad, but without the bondage and discipline?
16:34borkdudecoventry` I don't think s
16:38coventry`Am I right that to do that it would be enough to lexically track which functions call which, and having a configurable whitelist of pure functions, propagating all impure calls back along the call graph?
16:38coventry`*and have*
16:38abpDo Leiningen 1.7.1, lein-newnew 0.2.6. and cljs-template 0.1.5 work together? When i create a new project using lein new cljs-template cljsperiments the template isn't applied (seems like the template files aren't copied).
16:38technomancycoventry`: you basically would need a type inference engine for that
16:39technomancycoventry`: even then it would break in the presence of runtime resolve/eval, but it would certainly be nice
16:39borkdudecoventry` als you could automatically add functions ending with ! to the blacklist
16:42coventry`Hmm, maybe it would be easier to depend on a callgraph pulled out of profiling data. Thanks technomancy, borkdude.
16:43bbloomcoventry`: yeah, an "online" analysis process would be more reliable and easier to create.
16:43amalloycoventry`: lexical analysis wouldn't be sufficient anyway because of higher-order functions
16:45coventry`Hmm, good point.
16:46amalloy(map do-side-effects coll) - you can't tell just by looking at the source of map that it might have side effects
16:48borkdudewhy doesn't dissoc work on vectors
16:48borkdudesince ##(associative? [])
16:48lazybot⇒ true
16:51S11001001borkdude: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Associative.java
16:52amalloyneat. that file hasnt' been touched for three years, and the last commit to touch it involved IMutableAssociative
16:52borkdudeso basically only get, assoc and contains are guaranteed to work I guess
16:54borkdudewell you can also partially implement an interface so no guarantees whatsoever ;)
16:55TimMcYeah, it's annoying. You have to do crap like ##(let [v (vec (range 20))] (into (subvec v 0 10) (subvec v 14 19)))
16:55lazybot⇒ [0 1 2 3 4 5 6 7 8 9 14 15 16 17 18]
16:56TimMcs/19/20/, whatever
16:56TimMc&(let [v (vec (range 20))] (class (into (subvec v 0 10) (subvec v 14 20))))
16:56lazybot⇒ clojure.lang.APersistentVector$SubVector
16:57TimMcInteresting that it stays a subvector.
16:59gtrak(dissoc [1 2 3] 0)
16:59gtrak,(dissoc [1 2 3] 0)
16:59clojurebot#<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to clojure.lang.IPersistentMap>
17:00borkdudedissoc only works for… maps and sets?
17:00borkdude,(doc dissoc)
17:00clojurebot"([map] [map key] [map key & ks]); dissoc[iate]. Returns a new map of the same (hashed/sorted) type, that does not contain a mapping for key(s)."
17:00borkdude,(dissoc {:a 1})
17:00clojurebot{:a 1}
17:00borkdude,(dissoc {:a 1} :a)
17:00clojurebot{}
17:01borkdude,(dissoc #{:a :b} :a)
17:01clojurebot#<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentHashSet cannot be cast to clojure.lang.IPersistentMap>
17:01borkdudenope, only for maps
17:01borkdude,(disj #{:a :b} :a)
17:01clojurebot#{:b}
17:01borkdude,(disj {:a 1 :b 2} :a)
17:01clojurebot#<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentArrayMap cannot be cast to clojure.lang.IPersistentSet>
17:02borkduderight
17:02borkdudewhy??
17:02lazybotborkdude: What are you, crazy? Of course not!
17:02borkdudelazybot a bit, yes
17:09TimMcYeah, I don't get it either.
17:09TimMcdisj shouldn't exist, for that matter.
17:11patrkristhis must be easy: how do I convert the result of an (and …) in to true or false, depending whether the result is logical true (i.e. nil or not nil)? i mean, what's the idiomatic way. sure I could do a (not (nil? (and …)))
17:12borkdudepatrkris ##(boolean (and nil "true"))
17:12lazybot⇒ false
17:13patrkristhanks!
17:13borkdude,(boolean (or nil "true"))
17:13clojurebottrue
17:13michaelr`returns a lazy seq which when realized returns paged records from database: https://www.refheap.com/paste/2967 <----- can this be written in a better way?
17:15michaelr`I used [nil] to signify end-of-seq
17:16michaelr`And then test for it using (take-while identity...
17:16michaelr`i feel that there must be some function which already does what i wrote there//
17:16michaelr`..
17:16TimMcmichaelr`: Not seeing the need for take-while identity...
17:17TimMcJust return [] instead of [nil].
17:18michaelr`TimMc: you are right regarding take-while identity! thanks :)
17:18michaelr`but [] instead of [nil] won't work
17:19TimMcWorked for me.
17:19michaelr`really?
17:19michaelr`what clojure version?
17:19amalloyTimMc: i think you are probably crazy
17:20TimMcamalloy: I think michaelr` hasn't given me a good explanation of what's happening.
17:20amalloyit should return a lazy sequence with three fast elements, and then one infinitely-slow decision about whether or not there's another element
17:20amalloybecause you'll be calling (lazy-cat [1 2 3] (lazy-cat [] (lazy-cat [] ...)))
17:21TimMcOh, now I see it.
17:21TimMcDidn't realize it was recursive. >_<
17:22TimMcSo yes, I am probably crazy.
17:22S11001001(lazy-cat a ...) => (concat (lazy-seq a) ...)
17:22hiredmanif you know you've reached the end, can't you just stop recursing?
17:23hiredman(yes you can)
17:23michaelr`but then you would use something else than lazy-cat, right?
17:24borkdudelazy-cat is deprecated right?
17:24hiredmannope
17:24TimMcmichaelr`: (I thought rows was some external thing, since I wasn't expecting recursion -- so I didn't run the full sample.)
17:24borkdudeoh….. what was the thing that got deprecated in the context of lazy sequences then?
17:24michaelr`TimMc: okay, i don't blame you ;)
17:25borkdudemaybe I remember it wrong
17:26abpAnswering my own question: Installed Leiningen 2 and lein new cljs-template cljsperiments worked out of the box. Template autofetch is really nice. :)
17:28TimMcborkdude: lazy-cons, I think
17:29borkdudeTimMc I thought that as well, but couldn't find the docs on it anymore
17:29TimMchttp://clojure.org/lazy
17:30michaelr`TimMc: so i can't remove take-while identity
17:30hiredmanyou can
17:30michaelr`hiredman: how?!
17:30michaelr`how do i make it stop?
17:30hiredmanthink about it
17:30TimMcAh, the Feynman approach. :-P
17:31michaelr`hehe
17:31michaelr`hiredman: and still keep lazy-cat?
17:31hiredmanyou could
17:31hiredmanI would switch to just plain concat
17:31hiredmanbut that doesn't really change anything
17:32michaelr`okay, let me think about it :)
17:33TimMcWould that end up with nested concats? Thinking about stack overflows...
17:33hiredmanmichaelr`: why don't you write it as a recusive function with an accumulator (no laziness) and see where it goes from there
17:35michaelr`hiredman: you mean loop recur recursive function?
17:35hiredmansure
17:36michaelr`well, i don't want to accumulate. my use case it to "run over" a large table in the database, processing each row
17:36michaelr`without retaining the result
17:36hiredmanI am not suggesting that as a final product
17:37hiredmanI am suggesting it as a learning exercise
17:37borkdudelazyness and resources are often a problem right
17:38michaelr`oh, i know how to write loop recur stuff, the learning excersize for me right now is to use lazy seqs :)
17:38hiredmangood
17:38hiredmanso write it with loop/recur
17:38michaelr`why?
17:38clojurebotmichaelr`: because you can't handle the truth!
17:38michaelr`clojurebot: no one can
17:38hiredmanmichaelr`: then don't
17:38clojurebotRejectedExecutionException is fixed in Leiningen 1.6.1.1, so give it an upgrade
17:39michaelr`hmm
17:48tomojhttps://gist.github.com/9ac8496e40ed7cdbdd6e
17:53michaelr`clojurebot: no one can
17:53clojurebotJust a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..."
17:54michaelr`clojurebot: RejectedExecutionException
17:54clojurebotRejectedExecutionException is fixed in Leiningen 1.6.1.1, so give it an upgrade
17:55TimMcmichaelr`: It might be a misfire of the inference feature.
17:55TimMcclojurebot: (+ 2 2)
17:55clojurebot5 (for large values of 2)
17:55hiredmanmisfire?
17:56TimMcNot in the technical sense.
17:56TimMcIn the "what the hell, clojurebot!" sense.
18:04michaelr`hiredman: check this: https://www.refheap.com/paste/2968
18:05hiredmanexcellent, now wrap the body of rows in a lazy-seq, and change the if to a when in get-rows, and remove the call to seq
18:05hiredmanthen you're done
18:06michaelr`;)
18:09michaelr`hiredman: i still like lazy-cat better, just i don't like the ugly [nil] stop condition
18:10michaelr`every time i have to write a let for it feels like a bump in the flow of the language
18:10michaelr`s/let for/let form
18:11hiredmanmichaelr`: lazy-seq+concat is better in this case
18:11bbloommichaelr`: why?
18:11hiredmanif you do it with lazy-cat you'll lose some level of laziness
18:12michaelr`hiredman: how so?
18:12michaelr`bbloom: why it feels like a bump?
18:13hiredmanlazy-cat has to go inside the let, so the work done in the let will happen has soon as you call the row function, but if you use lazy-seq you can wrap the whole body, so the work in the let doesn't happen unless you actually start traversing the seq
18:14solussd_ibdknox: does readyforzero.com still use noir?
18:14michaelr`hiredman: i like the lazy-cat without the let, i want to get rid of the let form
18:14ibdknoxsolussd_: yes
18:14hiredmanmichaelr`: no you don't
18:14solussd_ibdknox: excellent. ammo for work. :D
18:15michaelr`hiredman: of course i do
18:17michaelr`hiredman: but i don't mind writing a version of lazy-cat which inside uses a let to do the real work :)
18:24cshell,(= 1.1 1.09)
18:24michaelr`here both versions side by side, the first one reads much easier imho: https://www.refheap.com/paste/2970
18:24clojurebotfalse
18:24cshellDoes anyone know how to check if a double is approximately equal?
18:25cshell,(== 1.1 1.09)
18:25clojurebotfalse
18:25S11001001cshell: is 0.4444 approximately 0.4445?
18:25S11001001moreover
18:25S11001001doubles are inexact
18:26S11001001so comparison of them is, by definition, approximate
18:26cshellS11001001: Correct, but when I'm doing a unit test, I want to say (= x 11.2) rather than (= x 11.192343221341)
18:26S11001001use an evenly represented num
18:27S1100100111.5 has a clear exact representation
18:27cshellS11001001: Okay, maybe a better question is how to go from 11.499999 to 11.5?
18:27S11001001round
18:27TimMccshell: Check that the delta is < an epsilon. :-)
18:27S11001001or subtract abs compare epsilon
18:28S11001001remember not transitive though
18:28cshellWhat namespace is round in?
18:28S11001001compare with round is transitive, but has sharp edges
18:29S11001001math.numeric-tower
18:30cshellS11001001: Thanks!
18:30cshellTimMc: Thanks as well!
18:31TimMcS11001001: What do you mean re: transitive?
18:31S11001001a = b = c implies a = c
18:31TimMcAh, you mean that approx= is not transitive.
18:31S11001001with epsilon
18:35S11001001(constantly true) is a perfectly transitive approx=, so is (constantly false) :)
18:41brainproxywondering if i understand correctly ... if I define protocols P and Z and (some of) their methods have the same names, then I need to define them in distinct namespaces
18:42S11001001brainproxy: yes, think of them as functions before methods
18:43hiredmanprotocols don't have "methods", the are collections of functions, and yes, if you want to have two functions bound to the same name, you will need to put them in different namespaces
18:43brainproxycool, thanks
19:01technomancyanyone on OS X with jdk7 able to help test a leiningen fix?
19:02kiloni am
19:02kilonbut i think i got 1.7
19:02kiloni mean lein
19:03technomancythat's fine; mind if I /msg you?
19:03kilonsure
19:14gtraki wonder how hard it would be to have like a background on-the-fly compilation in slime that doesn't stop on the first error? for instance, say I rename a method and I want a list of affected code locations.
19:14gtrakIs it something I could whip up in a few hours?
19:15technomancygtrak: slamhound does something sort of like that
19:15technomancyI guess it's kind of the inverse
19:15technomancyI've had dreams of making it go both directions though
19:16gtrakinteresting
19:17gtrakwe don't really need a full compilation though for something like that, right? just identify affected namespaces by walking a tree, then reading in and checking vars, right?
19:18gtrakI'm trying to think of ways to automate refactoring a little better, more like what I'm used to with java
19:18technomancyswank needs to expose restarts on compilation exceptions
19:19technomancy"looks like you're missing this defn; want to add it?"
19:20gtrakright now, I'm just making a breaking change, then running 'lein compile' and fixing things one-by-one
19:20S11001001technomancy: what would you add?
19:23technomancyhaven't thought it through
19:25scottjgtrak: not sure if it even works, but clojure-refactoring has a global-rename
19:26gtrakscottj: right, so, the problem is not that I want to rename... but I want to know what I should consider fixing when I make a breaking change to a function, basically I want to rename locally then fix all the callers up, then perhaps rename it back
19:27scottjgtrak: but not M-x slime-who-calls?
19:27gtrakdoing a local rename achieves the breaking-at-compile-time instead of runtime, and would aid a systematic approach
19:27gtrakhmm
19:28gtrakdoes that work across files?
19:28gtrakdoesn't seem to
19:29scottjgtrak: when called on reduce it shows me several functions from various files
19:29gtrakplus, with slime there's the added complication of actually having to recompile all the ns's to pick up a change
19:30gtrakI actually get an exception when I try it on reduce :-)
19:31scottjgtrak: http://jaderholm.com/tmp/2012-06-01-slime-who-calls.png
19:31gtrakinteresting, not sure why mine's broken
19:57cshellIs there a better web security framework for Clojure than Spring Security?
19:58cshellI'm using noir as my web server
20:00PeregrinePDXcshell, friend by cemerick maybe?
20:00technomancycshell: look at cemerick's friend
20:00technomancyjinx
20:00PeregrinePDXLol
20:01xeqithe noir mailing list has a couple of threads about how to use friend
20:01PeregrinePDXI almost went for the let me google that for you link since all I did was use google to answer the question.
20:01zakwilsonibdknox: congratulations on that kickstarter. That's... a lot of money.
20:01xeqiuse as it get them to work together
20:03badjeris there a way to reload a namespace in clojure, even if the source file hasn't changed?
20:08tmciverbadjer: use the :reload keyword with require.
20:10badjertmciver: thanks - that's working for me. I thought :reload only worked when the .clj had changed - I must be loosing my mind
20:18cshelltechnomancy: Thanks, I hadn't heard of that but I like Chas' work
20:18cshellPeregrinePDX: Thanks as well!
20:19cshellPeregrinePDX: I must have searched on something else :)
20:30PeregrinePDXcshell, it's easy to do I admit.
20:45technomancyI think I've addressed the issues in the bad leiningen 2.0.0-preview5 release
20:46technomancywill probably release current master as preview6 tonight or tomorrow; would be great if you could give it a try if you were having trouble earlier
21:00bbloomHiccup does a neat thing with defhtml which lets you define multiple arity functions with the html wrapping logic, but it seems surprisingly complicated
21:00bbloomi find myself wanting multiple arity functions somewhat regularly that come out of a def macro of sorts
21:00bbloomi kinda want a defdefn macro-writing macro :-)
21:02S11001001bbloom: easier to go with fn alone
21:02bbloomS11001001: what do you mean?
21:03S11001001defn is the amalgamation of multiple concepts, whereas fn is just the one, so the latter makes a better basis for composably expressive macros
21:04S11001001well, destructuring and recur-targeting is thrown into fn, but no worries
21:04S11001001bloody recur.
21:04bbloomso let's say i have:
21:04bbloom(defn f [x] {:x 1})
21:05bbloomand i want a macro defoo which expands to (defn f [x] {:foo f :x 1})
21:05bbloomas a sort of contrived example
21:06bbloomit's pretty easy to define a macro that does that for a single arity function, you have a macro of the form (defmacro [name [& args] & body] …)
21:06bbloombut for multiple arity, you need to do funky stuff like: (split-with #(not (or (list? %) (vector? %))) fdecl)
21:08bbloomsee: https://github.com/weavejester/hiccup/blob/master/src/hiccup/def.clj#L5
21:08bbloomi find myself wanting to write a macro similar to defhtml about once per project :-P
21:09aperiodici have that urge about half as often, but usually i realize it should just be a function
21:10bbloomaperiodic: should that defhtml macro be a function?
21:10aperiodicthe urge to write macros in general, that is, they're usually not extending defn and such
21:11aperiodicbut what's the end goal here?
21:12bbloomso i'm defining a domain specific data model that don't feel like getting into explaining… however i have several different types of nodes in this tree structure that have a few common keys
21:12bbloomone of those keys always matches the constructor's name
21:12bbloomso for example:
21:13bbloomhm… need to have a good examplee before saying "for example"
21:13aperiodicwhy not just use what the macro you want to write expands to, and then mention the added key in the docstring if you're worried about discoverability?
21:13S11001001bbloom: you should consider the possibilities offered by partial, comp, and other combinators
21:14S11001001macros are the hammer to the function screwdriver, as aperiodic says
21:14ethanisdoes anyone have experience using noir-cljs? ibdknox: quick question about advanced-compilation.
21:14bbloomS11001001: so yeah, usually the combinators get the job done. if you're just adding a key or something to the result it's pretty easy
21:16bbloomS11001001: can just expand (defx foo x y z) to (def foo (comp #(…) (fn foo x y z)))
21:16bbloomthe problem comes in when you want the expansion to add a macro inside each of the fn bodies, like with defhtml
21:17S11001001that's just macro pollution
21:17bbloomS11001001: it's just going to be a single macro that's going to be used in 25 places or so...
21:18bbloomdo you think that defhtml is macro pollution?
21:19S11001001macros aren't so amenable to combinators, so defining something as a macro tends to pollute the stacks of its users, by preventing them from using combinators. I don't know what defhtml is, so wouldn't speculate on the possibilities
21:19bbloomsimilar in noir with defpartial https://github.com/ibdknox/noir/blob/master/src/noir/core.clj#L103
21:20bbloomtake a look at defhtml here: https://github.com/weavejester/hiccup/blob/master/src/hiccup/def.clj#L5
21:20bbloomi understand the downsides of macros… i don't expect to need to combine these things at all
21:20S11001001programming is combination
21:21bbloomim defining a macro that defines top levels....
21:21S11001001no, I don't think html should be a macro either
21:23bbloom…. why?
21:23bbloomit's the only macro in hiccup/core
21:23bbloomit seems like a perfectly reasonable use case to me
21:24aperiodicyeah, i think that's a legitimate macro use-case, assuming you really need that reference back to the constructing fn in the map. that seems sort of fishy to me, but i don't know how you're planning on using it. regardless, why doesn't that split-with thing do the trick?
21:24S11001001no, it is definable as an ordinary defn with a metadata inliner
21:25S11001001in fact the macro seems to be merely simulating a less powerful version of that
21:25bbloomS11001001: metadata inliner?
21:25S11001001see `zero?' and many other :inline places in clojure.core for examples
21:25bbloomaperiodic: it does in fact do the trick
21:27bbloomS11001001: I'm looking at zero? now
21:27bbloom… how exactly is that not just a macro? :-P
21:29ethanisdoes anyone here have experience with using external libraries in clojurescript and doing advanced compilation?
21:30bbloomethanis: a *tiny* bit what's up?
21:30ethanisI've written a teensy wrapper around the javascript Facebook api in cljs
21:30ethanisand I'm now trying to do advanced compilation
21:30ethanisI understand I need an externs file
21:30aperiodici appear to have a project that does that
21:31ethaniswhich explicitly specifies all of my javascript function/object calls
21:31ethanisoh yeah?
21:31aperiodici'm using my external library as my externs file
21:31aperiodicit's working out fine so far
21:31bbloomethanis: 1) you're not trying to compile the fb lib, right? just call into it?
21:31ethanisright
21:32ethanisI'm using the copy of the lib on fb's servers
21:32bbloomok
21:32bbloomhow did you produce the externs file?
21:32bbloomis it provided by facebook? or you made it by hand? or some other way?
21:32ethanismade it by hand
21:33bbloomcan you pastebin it somewhere?
21:33ethanishttps://gist.github.com/2856072
21:33ethanisbarebones, only refers to the functions/objects I use
21:33bbloomsimple enough
21:33cemericktechnomancy, PeregrinePDX: feel free to use "say hello to my little friend" when pointing people at the project :-P
21:34cemerickhrm, maybe wrong crowd for that movie anyway ;-)
21:34ethanisok, now facebook's library puts an object called FB in the global namespace
21:34bbloomethanis: and can you also paste the code you're using for compilation?
21:35ethanissure, sure
21:35PeregrinePDXScarface?
21:35ethanishttps://gist.github.com/2856072#file_main.cljs
21:35ethanisit's a bit of a mess
21:36ethanis(def FB (.-FB js/window))
21:36bbloomethanis: no worries
21:36ethanisis there a more correct way to do that?
21:36PeregrinePDXcemerick, since you're at keys. I have the kindle version of the clojure book. Unfortunatly it doesn't show page numbers or paginate the same way as the paper book. Which makes it impossible to take advantage of the clojureatlas offer.
21:37bbloomethanis: just checking that you're not sending any functions to fb by name, if you did that you'd need exports too
21:38ethanisoh, I am
21:38ethanisexample
21:38ethanis (.login FB login-response (clj->js {:scope "user_about_me,user_relationships,email"})))
21:38ethanissending login-response by name
21:38ethanisif that's what you mean
21:38bbloomethanis: no, there you're sending the value inside login-response
21:38bbloomethanis: which will be a reference to a function
21:38cemerickPeregrinePDX: yeah, that was an unforeseen flaw in the game :-(
21:39PeregrinePDXOk
21:39bbloomethanis: if you had done something like with html where you did: <a href="javascript:foo();">
21:39ethanisah yeah, understood. I don't do that anywhere.
21:39bbloomethanis: in that case, you need to "export" the name, which tells google not to rewrite those symbols
21:39ethanisyep, got it.
21:39cemerickPeregrinePDX: check your PMs for a shibboleth.
21:39cemerickoh, nm :-)
21:40bbloomethanis: anyway — how do you invoke the compiler?
21:40PeregrinePDXClojureatlas looks amazing for helping find things in the clojure libraries for us newbies.
21:40ethanisnoir-cljs
21:40bbloomvia cljs build? manually via code? cljsc or anything?
21:40bbloomk i dunno anything about noir-cljs, but you need to pass through an :externs key somehow
21:41bbloomif you ran gclosure's compiler directly, you need a —externs flag or a the java api equiv
21:41ethanishttps://gist.github.com/2856072#file_server.clj
21:41ethanisnoir-cljs calls cljsbuild for me
21:41ethanisright
21:42ethanis(def cljs-options {:advanced {:externs ["externs/facebook.js"]}})
21:42ethanisand my understanding is that this directory is relative to my class path?
21:42bbloomi *think* so
21:42bbloommos tof the code uses io/resource to load files
21:42ethanisyeah, this is where things get spotty for me
21:43ethanistrying to grok https://github.com/ibdknox/noir-cljs/blob/master/src/noir/cljs/compiler.clj
21:43bbloomyeah, load-externs in cljs/clsoure.clj
21:43aperiodicethanis: it is relative to the project root
21:43ethanisah!
21:43ethanisok
21:43aperiodicit least, in my project.clj i use with lein-cljsbuild, it is
21:43aperiodics/it/at/
21:44bbloomhttps://github.com/clojure/clojurescript/blob/master/src/clj/cljs/closure.clj#L146
21:44cemerickPeregrinePDX: I use it myself, which has surprised me. It's developed a reasonable following. At some point, I need to revisit the visualization.
22:05muhoowhere would the options to clojure.java.io/writer be documented?
22:09TimMcmuhoo: http://clojuredocs.org/clojure_core/clojure.java.io/iofactory
22:09TimMc...although that took a little source reading.
22:24muhoothanks
23:47Omer()
23:47Omer(+ 5 2)
23:47clojurebot*suffusion of yellow*
23:52Omer(= 1 1)
23:52amalloy&(= 1 1)
23:52lazybot⇒ true
23:52OmerOh, I see.
23:52Mango_Man(* 42 42)
23:52clojurebot*suffusion of yellow*
23:52Mango_Manwhat
23:52ivan(*
23:52Mango_Man&(* 42 42)
23:52amalloyyou gotta ask 'em nicely
23:52lazybot⇒ 1764
23:53Omer&(not (= 1 1))
23:53lazybot⇒ false
23:53Mango_Man&(* 335235235 2352352352)
23:53lazybot⇒ 788591393525522720
23:53Mango_Manhehe this is fun