#clojure logs

2011-05-05

01:06stirfoo/quit
01:06stirfoo
01:30bhenrybefore i write it, is there already a macro or function that will print and return the result of what's inside it? i.e. (prn-ret {:a 1}) will print {:a 1} but also return {:a 1} instead of nil like prn.
01:39amalloybhenry: there are a few
01:39amalloyone in cc.logging, but it logs instead of printing iirc
01:40amalloybhenry: https://github.com/amalloy/amalloy-utils/blob/master/src/amalloy/utils/debug.clj is mine
01:40amalloythough if you want a super-simple one you can just ##(doto (inc 3) println)
01:40sexpbot⟹ 4 4
02:17thorwilsemperos: thanks for the mail, but i'm well aware of enlive'e substitute. the problem is extracting the content of the tag that is to be replaced ;)
02:17semperosthorwil: I figured
02:26semperosthorwil: I think you might find your answer by looking at the implementation of the content fn
02:26semperosas enlive deals with the HTML as maps, :content is just one of the keys
02:26semperos:tag is another
02:27semperosyou can probably put together your own little fn in the same form, replacing the :tag instead of the :content for the target enlive node
02:27thorwilgood point.
02:28thorwili saw mention of a let-select function on the enlive list, so i have a few things to try now. ty
03:09thorwilgiven (def test-html (en/html-snippet "<p><span>Previous</span> <span>Next</span></p>"))
03:09thorwil((en/transformation [:span] ((fn [& values] #(assoc % :tag (en/flatten-nodes-coll values))) "a" )) test-html)
03:09thorwilcomes close, but i need a way to insert an :a
03:11thorwilof course! ((en/transformation [:span] ((fn [& values] #(into % (en/flatten-nodes-coll values))) {:tag :a} )) test-html)
04:25clgvAre there any LISP conferences or deadlines for LISP related journals for the remaining year that one should know about?
04:37fliebelIs the clojure reader extensible?
04:37ejacksonfliebel: no reader macros
04:38fliebelejackson: Waiting for the new compiler, or by design?
04:38clgvfliebel: in a repl context you can wrap around it by passing an own function with :read to clojure.main/repl
04:38ejacksonby design - Rich believes they lead to fragmentation and difficulties.
04:40fliebelclgv: What do you mean with :read?
04:41clgvfliebel: if you are shooting for reader macros like ejackson said then I guess it wont help you. didnt read that in time ;)
04:42fliebelclgv: But what *will* it help with?
04:44clgvfliebel: as far as I thought about it - you can define own commands for your repl that do not need to be clojure functions or macros. I used it for some stuff with the debug-repl
04:45fliebelMeh, it was a bad idea anyway probably… I'm thinking about templating languages.
04:45clgvthat means?
04:46fliebelWell… scala has xml literal support ;)
04:47clgvyou could build a clojure DSL though - it just has these additional parantheses ;)
04:48fliebelclgv: that'd be hiccup, but then uglier.
04:49fliebelAre there any other exotic ones besides enlive? I mean, anything other than PHP style.
04:51clgvhmm is it really desirable to use literal xml in programs? I don't have an opinion on that myself atm...
04:51fliebelclgv: Not at all! Just a silly alternative to hiccup.
04:51clgvfliebel: ah your playing around and searching limits? ;)
04:52fliebelprobably :) But the end goal is to find some really awesome templating
05:04thorwilfrom the outside, most templating engines seem to differ mainly in how/where to handle logic.
05:05fliebelthorwil: In that case, I'm in the no-logic camp. But that is only the start. I'm not all to happy with introducing a new mini language at all.
05:06fliebelSo I say, templates should be html and clojure, .-.-.- (full stop)
05:07thorwilthat's why i really like enlive. no logic in templates, no new language (macros are on the edge, admittedly)
05:08fliebelthorwil: Yea, Enlive is great, but I was wondering if there was any competition in this space.
05:09thorwilif there's anything that might start to bug me, it will likely be the inroduction of javascript. especially in the "reverse-ajax/comet" (ain't those silly terms?) case
05:09fliebelthorwil: What?
05:10thorwilfliebel: the server triggers client code case
05:11fliebelthorwil: Yea, what about it? I haven't seen Enlive do that, which is what my confusion is about.
05:12thorwilfliebel: so far it only means that i have to insert tokens generated on the server into the JS
05:13thorwili do that with selecting the nth script tag and en/prepend to insert a single JS line
05:13fliebeloh, that :)
05:14thorwila less explicit way to handle that would be nice. the Erlang web framework Nitrogen seems to be really great at that
05:14thorwil(but has only very rudimentary templating)
05:15thorwilfliebel: i think among other more interesting template engines are http://genshi.edgewall.org/ and http://beebole.com/pure/
05:16fliebelgenshi is nice
05:27andrewcleggmorning all... I'm trying to create a Date with no arguments like this: (def *now* (Date.))
05:27andrewcleggbut I get thisL
05:27andrewclegg:
05:27andrewcleggjava.util.Date cannot be cast to clojure.lang.IFn
05:28andrewcleggAm I losing the plot? :-)
05:29Chousukethat should work just fine
05:29andrewcleggit's not :-(
05:30Chousukehow are you using *now*? :/
05:30Chousukealso are you sure you didn't typo something
05:30andrewcleggI'm passing it to a function like this:
05:30andrewclegg(crap-date-format *now*)
05:30andrewcleggwhich isL
05:31andrewclegg:
05:31andrewclegg(defn crap-date-format [date]
05:31andrewclegg "TODO: make this less crap."
05:31andrewclegg (apply str (take 19 (.toString (date)))))
05:31andrewcleggoh hang on
05:31Chousukethere's the problem
05:31andrewcleggI see it, sorry
05:31Chousukebtw, you can use subs to get a substring
05:31andrewcleggerr, thanks :-)
05:31andrewcleggoh, I hadn't seen that, thanks
05:32andrewcleggstill n00bing away
05:32Chousukeyeah, well subs is just a wrapper for the java method
05:32andrewcleggless typing is always good
05:40andrewcleggsorry chousuke, another Date q. -- should this work? (def date (java.util.Date. 0)) for 1970-01-01 00:00:00:000
05:40andrewcleggbecause I get No matching ctor found for class java.util.Date
05:42Chousukeandrewclegg: no idea, check the javadocs?
05:42andrewcleggpublic Date(long date): Allocates a Date object and initializes it to represent the specified number of milliseconds since the standard base time known as "the epoch", namely January 1, 1970, 00:00:00 GMT.
05:42andrewcleggnot casting to Long by default or something?
05:43Chousuketry doing (Date. (long 0)) then
05:44andrewcleggaha, thanks, didn't know you had to (or could) upcast ints to longs
05:44andrewcleggcheers for your patience
07:45manutterI have an enlive question:
07:46manutterIn PHP I might do something like this -- $banner = "<div class='welcome-banner'>Logged in as $user_id</div>"; echo $banner;
07:46manutterIs there an easy way to do that using enlive?
07:47fliebelmanutter: yes
07:47manutterI get the impression enlive wants me to use a template something like <div class='welcome-banner'>Logged in as <span id="user_id"></span></div>
07:47manutterbut I want to replace $user_id in the middle of the content (and possibly in more than one place
07:48manutter)
07:48fliebelmanutter: Well, the idea is that you add just the banner div with the default content, and insert that whole message using enlive. I think the content/replace do what you want.
07:50manuttercontent/replace sounds promising, I'm not familiar with that
07:51manutterI don't want to build the whole message in clojure because I'd like to use the template itself for internationalization, so the surrounding text will be different depending on the locale
07:52pareidoliaHi all! Is it possible to loop through a sequence (doseq/for) in blocks, not taking just one element? Thanks!
07:53fliebelmanutter: idk, the span seems like the way to go.
07:53fliebelpareidolia: parition
07:53fliebel*partition
07:53manutterI'm not overly averse to the idea, just want to explore the alternatives :)
07:53manuttertks much
07:56pareidoliafliebel: Nice! I haven't seen it suggested in my search results, but it's right there in the api. Thanks!
09:46bultersis it possible to create an anonmyous 'multimethod'o
09:46bulters?
09:47fliebelbulters: Yes, with a lot of manual plumbing. Check the source for defmulti and defmethod. You just need to create the object yourself.
09:57hyperboreeanwhat's the idiomatic way of storing paths to config/input files in clojure? I am using lein for building if this matters
10:06jjidohyperboreean: you can't use a Java File object?
10:06raekhyperboreean: if you want to read a resource file that is to be bundled with the program, you can put it in resources/ which is added to the classpath (and generated jar files) by lein
10:08raekhyperboreean: to load a resource on the classpath, do something like (require '[clojure.java.io :as io]) (-> "foo/bar.txt" io/resource io/reader)
10:08raekthe file should be in resources/foo/bar.txt, relative to the project directory (which becomes foo/bar.txt relative to the class path)
10:09raekfor resource file paths, / should always be used as the delimiter
10:10raekfor ordinary file system paths in a platform independent way, construct the path with io/file by giving it the path segemts
10:10raek(io/file returns a java File object, which represents a file path)
10:14raekhyperboreean: the "resources" approach is typically used for things like icons and maybe config files for libraries the app uses.
10:20pyrhi
10:20pyrwhat is the accepted best way to deploy a ring/compojure app, in terms of performance ?
10:21pyrI'm using nginx in front of the jetty handler
10:21pyrAFAIK each request is mapped to a thread from a thread-pool, right ?
10:22bultersfliebel: thanks, will try it out :D
10:22BelafHello everybody.
10:23cemerickpyr: right; FWIW, there's not really any reason to proxy jetty or tomcat, unless you have other requirements that make that convenient.
10:24pyrcemerick: yep, i just don't wanna handle the rate limiting there
10:24pyrbut point taken
10:24pyrcemerik: so this is basically the fastest way to deploy right now ?
10:25cemerickpyr: if by "fastest", you mean "least overhead", that's fine.
10:25cemerickThere's not a lot of variation in Java webapp servers, really.
10:26BelafI made an attempt at using gen-class to extend java.awt.image.RGBImageFilter. Now everything seems to work fine, only I have some doubts on the performance I get calling the new object's methods: they seem some 100 times slower than a function doing the same job (in my case very little). Is this to be expected?
10:26pyrcemerick: sometimes i wish there was an async_ring
10:26cemerickpyr: which would do what?
10:26manutterBelaf: are you using type hints on your function parameters?
10:27pyrcemerick: run requests and replies in a single thread
10:27BelafUh, no... should I give it a try?
10:27cemerickpyr: Wouldn't be too hard, but you wouldn't be able to deploy it in a servlet container like jetty or tomcat.
10:28manutterBelaf: I'm not much good at interop stuff, but whenever I hear people talking about slowdowns, type hints seem to come up a lot
10:28pyrcemerick: yes, it'd be a matter of adding some sugar on top of netty from what i gather
10:29cemerickpyr: Sure. I don't see the point, but then I don't do high-volume web stuffs.
10:30BelafYou mean adding type hints to the method definitions, right? I can try adding them, but I'm puzzled, as the methods already have their signature declared in the :methods gen-class declaration...
10:31manutterBelaf: could be, like I said I don't know all that much about interop stuff
10:31manutterPerhaps someone else can chime in? :)
10:32Belafallright, I'll try experimenting with type hints, I need to learn something about them, anyway :)
10:32BelafThanks
10:32clgvBelaf: the first step should always be measuring to get to know where most of the time is spent and possibly lost ;)
10:32pyrcemerick: high volume is an application, websockets and bindings to/from QMS's are another
10:33pyrcemerick: i'll just shut up and code :)
10:33cemerickBelaf: FWIW, if you're only using your RGBImageFilter subclass from within Clojure, proxy is recommended over gen-class.
10:34Belafclgv: I somehow measured it, actually:
10:34Belafuser> (time (dotimes [n 1000000] (gdtest.core/filter0 0 0 0)))
10:34Belaf"Elapsed time: 30.198033 msecs"
10:36hyperboreeanraek: thanks
10:36Belafcemerick: I think I couldn't use proxy, as I needed to access the protected canFilterIndexColorModel member in RGBImageFilter and proxy doesn't seem to allow it.
10:37cemerickBelaf: True enough. nm then :-)
10:39Belafthe sad point is that the filter works by calling a method once for each image pixel, so for big pictures it slows down a lot...
10:41cemerickBelaf: If there is any reflection going on, compiling with *warn-on-reflection* bound to true will emit useful warnings.
10:41clgvBelaf: you should measure inner and outer time to see if type hints might be really the reason
10:41Belafcemerick: allright, I'm going to try that, thanks.
10:42Belafclgv: sorry, what do you mean by inner and outer time?
10:43clgvBelaf: you just measured the outer time. the inner one is within the function.
10:45Belafclgv: do you have any suggestion on how to measure it? the code inside is really basic, actually:
10:45Belaf(defn -filter1
10:45Belaf [this x y rgb]
10:46hvIs there a Trie class (hopefully with collection inteface) in clojure?
10:46clgvBelaf: you tried the *warn-on-reflection* hint already? I'd do that before
10:47Belafcemerick: is this what you were suggesting "(binding [*warn-on-reflection* true] (compile 'gdtest.aux))" I got no warnings from it.
10:47clgvBelaf: do (set! *warn-on-reflection* true) after your ns-statement
10:49Belafclgv: I had some warnings, actually:
10:49BelafReflection warning, gdtest/aux.clj:24 - call to setCanFilterIndexColorModel can't be resolved.
10:49BelafReflection warning, gdtest/aux.clj:30 - reference to field filter can't be resolved.
10:49clgvtime to fix them with type hints ;)
10:50BelafAllright, going to try it... Thanks for your support!
10:55fliebelhv: http://stackoverflow.com/questions/1452680/clojure-how-to-generate-a-trie
10:55fliebelSmart use of assoc-in :)
11:44BelafJust in case it might be useful to somebody else: fixing the reflection warnings did the trick, now the (trivial) filter is 15 times faster. The only needed thing was to add a type hint to the class being defined to the 'this' parameter of method definitions.
11:44BelafThanks so much for your help.
11:44manutterThanks for the report :)
11:45manutterI'll have to add "reflection warnings" to the list of terms I mindlessly parrot whenever I hear about performance issues.
11:46BelafWell, it seems a good tool to know.
11:47clgvbut dont forget to comment them before compiling a jar ;)
11:47manutterI'd heard of it before, but was kind of hazy on the details
11:47clgv*warn-on-reflection*, I mean ;)
11:47manutterindeed
11:48BelafI might try it, but... what would the result be?
11:49Belafoh, I think I know what you mean... I compiled one of my other files with it ... :-)
11:49clgva compiler error
11:50clgvor wait. I think I get it when trying to run the jar
11:50clgvhad it with *print-length* and *print-level* so I just used (binding [*print-length* 10, *print-level* 9] ...) in my main method
11:51Belafcompiling another of my files I got a number of such warnings, but I think I'm not going to add type hints for all of them, unless they are slowing things down... I like so much using things without knowing too much what they are... ;-)
11:52clgvseems you do a lot interop then ;)
11:52manutterwhat would be useful would be some kind of mechanism that would let you conditionally compile code based on whether you were executing lein repl or lein jar
11:54zippy314Hi folks, I'm trying to write a macro or function that defines a function in a particular namespace (by calling ns) and then then switches back to the current namespace, but this: (defn x [] (ns fish) (defn y [] 1) (ns user)) doesn't seem to work. Is this possible?
11:55zippy314What I'm trying to do is to put functions into namespaces on the fly.
11:57clgvzippy314: binding *ns* to the namespace could work
11:58technomancymanutter: there's a :repl-init-script setting you could use
11:59manutterI was looking at that, hmmm
11:59manutterJust brainstorming, though, don't have an immediate use for it
12:00manutterwe were just talking about (set! *warn-on-reflection* true) and the need not to compile that into the final jar.
12:00technomancy(when (System/getenv "LEIN_VERSION") (set! *warn-on-reflection* true))
12:01manutteraha, nice :)
12:08zippy314cigv: how do you do that?
12:39zippy314Is there an opposite to refer? I.e. if you used (refer 'some-ns) and now you want to do something like (unrefer 'some-ns)
12:41semperoszippy314: :exclude can be used on individual fn's within a namespace
12:42zippy314hmm. It looks like ns-unmap actually does what I want.
12:43zippy314But it looks like if you use refer and that overwrites a reference you can't get the old one back easily.
12:43semperosyou can provide aliases and rename fn's using the ns macro, so if you see that you have a conflict, there are several ways to mitigate it
12:51raekzippy314: to get the old one: ns-unmap and then refer
12:52raekor refer to it with it's fully qualified name
12:52zippy314I'm doing this because I'm defining functions on the fly and I want them to go into their own namespaces, so it gets kind of hairy...
12:54raekzippy314: maybe you could let them have a certain prefix (assuming they can have arbitrary names which might not "respect" clojure names)
12:55zippy314hmm that might work for starters...
12:56amalloyit seems to me like you're a zillion times better off not trying to define top-level functions at runtime in the first place. why do you feel you need to do this?
12:56raekor if their usage is determined "on the fly" too (i.e. you don't have hand-written code that uses the names), put them in one map
12:57raekusing a namespace as a map is not as ideomatic in Clojure as corresponding practices are in Ruby and Python
13:00raekit's ok to have functions outside vars :)
13:02manutter,(let [foo (fn [] (println "foo")), bar (fn [] (println "bar")), fly {:foo foo, :bar bar}] ((fly :foo)))
13:02clojurebotfoo
13:02dnolenzippy314: what about your application requires these functions needs to be defined at runtime?
13:05zippy314What I'm writing is a system in which you can define grammars and semantics for those grammars as the running system. So for example I'd like to be able to do things like have lexically scoped grammatical constructs, just as we are used to lexically scoped variables.
13:06zippy314In other words I'd like to define a grammar which includes positions of things, plus functions, and have them appear to be usable lexically, as opposed to in the context of an entire file.
13:06dnolenzippy314: then why not local functions?
13:07zippy314like how?
13:07dnolen,(let [f (fn [a b] (+ a b))] (f 1 2))
13:07clojurebot3
13:08zippy314hmm. That might work...
13:08semperosthings like what clj-record does make sense for creating top-level fn's at runtime
13:09semperosbut if you just need scoping, local fn's are probably a better bet
13:09zippy314I've read a little about clj-record, I need to dig into the source for that.
13:09semperoswell, not at runtime perse, but dynamically
13:10semperosit's init-model macro dynamically generates CRUD fn's for a given database table
13:10semperosso that they're available elsewhere for CRUDdy activities
13:10zippy314But, the issue with local functions is that you can only use them once, wouldn't you have to re-declare them every time? The idea is to define the grammar for such functions, and then be able to use that grammar, lexically scoped.
13:11semperoszippy314: you might need to provide actual/pseudo code examples to get across exactly what you want
13:11raekzippy314: are you making a macro that will run once during initialization or an interpreter that will do this at run-time?
13:11zippy314the latter.
13:12raekthen you should definitely not use defs for this
13:12KirinDavezippy314: If only we could pass functions around in a map :)
13:12KirinDaveIf only we could have... functions... without names. :)
13:12zippy314although the former might work too.
13:12zippy314:-)
13:13raekif you will never write any source code that refers to the generated functions, there is no need for defs
13:14raekdefs are for programmers :)
13:38ejacksondnolen: what kind of American are you - that's FRENCH !
13:39dnolenheh, I suppose I lack that level of nationalism.
13:39manutterEh oui? Et qu'est-ce qu'ils ont, les francais? Hmm?
13:39manutter:)
13:39ejackson:)
13:42fliebeldnolen: What is the relation between OCaml and Go?
13:42dnolenfliebel: high performance systems programming languages w/ high-level features.
13:43fliebeldnolen: Oh, maybe I should check that out, I heard they have good pattern matching ;)
13:44dnolenfliebel: ;)
13:46fliebeldnolen: I have read some of the big paper by now, still not making much sense. I get the general idea, but when they start to bend equals signs ( ⊇ ), I get lost.
13:47dnolenfliebel: don't be confused, just means subset
13:47fliebelWow, awesome, my unicode pallet has names for these things that make sense
13:48fliebelMaybe I should read it again with the pallet at hand :)
13:50dnolenfliebel: you should, the math stuff is really about defining some things tersely. The only part that doesn't make sense to me is the operational semantics (?) notation. But that's not important to understand the paper anyhow.
13:52fliebelah-ha!
13:56dnolenfliebel: it also turns out that using if + instance? checks is probably going to much faster for most predicate dispatch use cases. They put us in the 90ms territory versus 2000ms for multimethods.
13:58dnoleni.e. when looking at 1e8 iterations on a 3 test dispatch.
13:58subnetmaxhello - is there an elegant way to create a sequence with each item based on a function of all the previous items?
13:58subnetmaxlazily would be nice
13:59fliebelsubnetmax: iterate, kind of...
13:59amalloysubnetmax: reductions
14:00amalloy&(reductions + (range 5))
14:00sexpbot⟹ (0 1 3 6 10)
14:01fliebeldnolen: Wait, what are multimethods using internally? And are we talking a flat if, or some hand crafted DAG?
14:01subnetmaxsorry, not able to get my head around how to use that.... i have a function next-item that takes a list of all previous items, could you show me how to use iterate or reductions to do that?
14:02amalloysubnetmax: all previous elements that you've output?
14:02subnetmaxyeah
14:02fliebel(iterate #(conj % (next-item %)) the-items)
14:03amalloyfliebel: yeah, looks good
14:03subnetmaxand the-items is [] for the first call of this?
14:03amalloysubnetmax: it depends what your input is
14:04amalloythat is: imagine this function already existed. how would you call it?
14:04subnetmaxi should say that i'm using rand to help generate each item, so my function is not referentially transparent
14:05fliebelsubnetmax: well, the-items could be [], so then it'd invoke next-item with [] and conj that onto the empty vector.
14:05subnetmaxok, i'll see if i can make that work, thanks very much
14:05amalloythis all sounds too much like unfold
14:06subnetmaxwell everything sounds like some kind of fold if you think about it enough :)
14:06fliebel&(take 10 (iterate #(conj % (reduce + %)) [1]))
14:06sexpbot⟹ ([1] [1 1] [1 1 2] [1 1 2 4] [1 1 2 4 8] [1 1 2 4 8 16] [1 1 2 4 8 16 32] [1 1 2 4 8 16 32 64] [1 1 2 4 8 16 32 64 128] [1 1 2 4 8 16 32 64 128 256])
14:06fliebelsweeet :)
14:06fliebelamalloy: Time to mention amalloy-utils :)
14:07amalloyfliebel: why would i, when you're here to do it for me
14:07fliebelamalloy: Because I don;t know where unfold lives :O
14:07amalloyaww
14:07amalloyit's in seq
14:07amalloyhttps://github.com/amalloy/amalloy-utils/blob/master/src/amalloy/utils/seq.clj#L48
14:09fliebelamalloy: How would you solve this problem using unfold?
14:09amalloynote that if you actually depend on all the previous outputs, you can never generate an infinite sequence - you'll be holding onto the head of a large sequence forever
14:10amalloyfliebel: i wouldn't, really, because unfold assumes you want to generate an infinite sequence
14:10subnetmaxi'm only looking to generate max 30 items, and performance does not matter
14:10fliebelamalloy: You can never generate infinite sequences in a finite universe :)
14:10amalloyand the assumption that element x really depends on all previous elements is anathema to me
14:11fliebelsubnetmax: What are you doing with all those ellements?
14:12subnetmaxwell for example, picking people for tasks, you need to know who has already been picked, along with other considerations
14:13manuttersubnetmax: for that you could just generate a list of people, shuffle it, and pick them off in order
14:13manutter(which will be a random order after the shuffle)
14:14subnetmaximagine that as you pick each person, you need to look at who has already been picked to avoid personality clashes
14:14subnetmaxbut the issue is not important enough to start looking a large constraints solver
14:14manutterah, ok
14:14amalloysubnetmax: don't generate a sequence of persons, imo
14:14fliebelsubnetmax: Oh, I was just about to mention Logos.
14:14amalloyreduce from a sequence of tasks into a map of assignments
14:14amalloythen you only depend on the one object: a map
14:15subnetmaxwhy is depending on a map better than depending on a list
14:15amalloyit's not, really
14:15amalloybut it's much easier to work with
14:17fliebelsubnetmax: Have a look at the readme of core.logic, especially disequallity and defining facts. https://github.com/clojure/core.logic
14:26dnolenfliebel: multimethods use a couple of things, memoization, PersistentHashMap of dispatch values
14:27dnolenfliebel: DAG -> if. but I want it to be flexible enough to goto case if we see that that'll be more efficient. shared parts of the tree are lifted into fns, like matchure.
14:28dnolenfliebel: the coolest thing about the paper is the notion of necessity from lazy evaluation - that's what makes the smaller trees possible.
14:29subnetmaxi can solve my problem like this http://pastebin.com/083aRBUe - i was just thinking that i seem to be doing something that other people do and so perhaps there is already a function for
14:32fliebelsubnetmax: Well, iterate and unfold would work.
14:33amalloyiterate *or* unfold, i think is clearer
14:35fliebeldnolen: Okay, I did not understand that necessity part at all.
14:41no_mindIf I define a record with two attributes lets say first_name and last_name. Can I define a protocol which will change the attributes of the record ?
14:41fliebeldnolen: The raging hordes are starting to respond to your question :)
14:42fliebelno_mind: records are immutable
14:42fliebelBut you can say (assoc this :first_name "foo" :last_name "bar")
14:53subnetmaxIs it right that (disj #{1 2 3} #{2}) evaluates to #{1 2 3}? I was expecting #{1 3}
14:56manutter,(doc disj)
14:56clojurebot"([set] [set key] [set key & ks]); disj[oin]. Returns a new set of the same (hashed/sorted) type, that does not contain key(s)."
14:57manutterhmm
14:57manutter,(disj #{1 2 3} #{2})
14:57clojurebot#{1 2 3}
14:57subnetmaxuser=> (disj #{1 2 3} #{2})
14:57subnetmax#{1 2 3}
14:58manutter,(disj #{1 2 3} 2)
14:58clojurebot#{1 3}
14:58manutter,(disj #{1 #{2} 3})
14:58clojurebot#{1 #{2} 3}
14:58manutterdoh
14:59manutterok, got it
14:59manutter,(= #{2} #{2})
14:59clojurebottrue
14:59manutterwell, got most of it
15:00subnetmaxsorry, what am i doing wrong?
15:00manutter#{2} != 2
15:01subnetmaxoh i see, it's not two sets, it a set and a list of keys to remove
15:01manutter#{2} is not one of the values in #{1 2 3}
15:01manutteryeah
15:01subnetmaxhow can i do a disjunction between two sets?
15:02dnolenfliebel: heh, not getting much upvotes, but noone responding w/ an interesting answer either. Except "easier" maybe.
15:03manutter,(remove #{2} #{1 2 3})
15:03clojurebot(1 3)
15:03manutterhrm, close
15:04manutter,(into #{} (remove #{2} #{1 2 3}))
15:04clojurebot#{1 3}
15:04manutter,(into #{} (remove #{1 4} #{1 2 3 4 5}))
15:04clojurebot#{2 3 5}
15:04fliebeldnolen: How do you know? (not= minutes upvotes) I wonder if anyone there knows both OCaml and Go ( and Rust?)
15:05raeksubnetmax: check out the functions in clojure.set
15:05manuttersubnetmax: "into #{}" plus "remove" seems to work
15:06bartjsubnetmax, disjunction = union of two sets ?
15:06manutterI'd have thought there'd be a built-in for that, but...
15:06bartjthere is
15:06fliebelmanutter: there is, raek said it.
15:06bartjcheck out clojure.set
15:06manutter,(disj #{1 2 3 4 5} (seq #{2 4}))
15:06clojurebot#{1 2 3 4 5}
15:06subnetmaxah, difference
15:07manuttersigh
15:07raek,(clojure.set/difference #{1 2 3 4 5} #{2 4})
15:07clojurebot#{1 3 5}
15:07manutterI thought that one might have worked
15:07subnetmaxit's just that difference and disjunction have exactly the same meaning, so why would i look for difference when i had found disj?
15:07dnolenfliebel: it doesn't look like it. But honest opinion if you know OCaml you'll think is a bad joke.
15:07dnolenthink Go
15:07manutterOh, there it is, I was looking in clojure-contrib.set
15:08raeksubnetmax: disjunction means "or", so that means the set of the elements that are in set a *or* set b
15:08raek(inclusive or)
15:08raekdisj stands for disjoin
15:08raekwhich means to separate
15:09fliebeldnolen: I'd say one needs some brains to write a language, so someone must have thought Go was a good idea. One of those people even said Rust was written in OCaml.
15:10raekhrm. but "disjoin" and "disjunction" do share a common root. I guess the meaning of "disjunction" has shifted in meaning over the history
15:15dnolenfliebel: Go is a classic example of Worse Is Better. That maybe a good or bad thing depending on your perspective.
15:39dnolenfliebel: re: necessity. it's just about figuring which column *must* be tested. if it's going to be tested in every path, test it first, turns out this can usually produce smaller trees.
15:41fliebeldnolen: But how do you ever figure that out? I mean, okay, when you write (and (< x 3) (< x 4)) you could *maybe* figure out that the first one is redundant, how can you know?
15:41fliebelIs this why the wiki said you had to define predicates and their relations?
15:42dnolenfliebel: logic programming remember.
15:42dnolenfliebel: exactly, those kinds of issues are checked before we produce the dag.
15:43fliebelSubclassing and negation is the easiest to check probably.
15:45bartjwhat does ~ and ` mean while writing macros ?
15:45bartj*do
15:46fliebel&(let [x 5] `(+ 1 ~x))
15:46sexpbot⟹ (clojure.core/+ 1 5)
15:47bartjoh, I was reading ` as a '
15:48raekbartj: syntax-quote ` is very similar to quote ' except that it resolves symbols and has a unquote feature
15:49dnolenfliebel: yeah the key bit is that you can't use just anything for a guard. You have declare the predicates you will use as guards, then we can reason about them.
15:53bartj,(doc `)
15:53clojurebotUnmatched delimiter: )
15:53fliebeldnolen: So in the end you have kind of a trie of guards instead of words :)
15:54raekbartj: it's documented here http://clojure.org/reader
16:26bartjraek, thank you, as usual
16:45lawrentDoes clojure support currying? If not, do you often find that you miss this feature?
16:46opqdonut_,(doc partial)
16:46clojurebot"([f arg1] [f arg1 arg2] [f arg1 arg2 arg3] [f arg1 arg2 arg3 & more]); Takes a function f and fewer than the normal arguments to f, and returns a fn that takes a variable number of additional args. When called, the returned function calls f with args + additional args."
16:46lawrentThat's a little clumsy, no?
16:46opqdonut_not really, no
16:46lawrentSeems to me that currying is one of the very basics of functional programming, along with referential transparency, and clojure does neither well
16:46opqdonut_I miss a real type system more than currying
16:47opqdonut_and clojure does referential transparency better than any other lisp
16:47opqdonut_or any other jvm language for that matter
16:47lawrent...but not better than haskell
16:47kephalepartial can be limiting due to ordering of arguments
16:47lawrentexactly!
16:47opqdonut_well so is ordinary currying
16:48amalloykephale: define flip, then partial a flipped version
16:48kephalebut you can get the same effect with the #( blah %1 %2 ) macro
16:48opqdonut_but yeah, there's no equivalent of flip/rcurry in the clojure standard lib
16:48kephaleamalloy: i tend to just use the function reader macro
16:48amalloyso do i
16:49amalloybut it's not hard to get partial to fill in something other than the first N arguments
16:49kephalenoted
16:49amalloyi have a reodering library for juggling around function arguments in various ways if you need something more sophisticated than flip
16:50dnolenlawrent: given fns can have variable arity how do you see currying as useful in Clojure?
16:51dnolenlawrent: a pure function in Clojure is just as referentially transparent as in any other lang, FP or not.
18:02zippy314how come (defn x.x [] 1) works, but you can't call (x.x)?
18:02zippy314heh
18:02zippy314(defn y.y [] 1)
18:03hiredmanthe code that resollves symbols to vars/classes assumes a symbol with a dot in it is a class
18:07zippy314hiredman: thanks. another q: why can't I do something like this: (def x "foo") (defn (symbol x) [] "bar")
18:09amalloybecause (symbol x) isn't a symbol, it's a list
18:09amalloydefn needs a literal symbol
18:09amalloy&`(defn ~(symbol "test") [] "data")
18:09sexpbot⟹ (clojure.core/defn test [] "data")
18:09hiredmanzippy314: the defn special form doesn't evaluate the first arg
18:10hiredmanor any of it's args
18:13amalloyhey hiredman, does clojurebot have a trigger to make him process commands or eval forms mid-message? something like, "hey zippy314, check out ~~source defn"?
18:15hiredmanno
18:21semperoswriting a Clojure api around a Java lib; what do folks thing would be a good name for a namespace that only has defmethod's of print-method to make printing the Java original objects more meaningful?
18:26amalloymyapp.tostring?
18:27lawfulfalafelcould someone recommend a good tutorial for making your first project with lein?
18:27lawfulfalafelI am having a bit of trouble finding an explicit and up to date version
18:27technomancylawfulfalafel: have you read through "lein help tutorial"?
18:28lawfulfalafeloh sweet, your the author right?
18:28amalloyhttps://github.com/technomancy/leiningen/blob/master/TUTORIAL.md
18:28technomancyaye
18:29amalloylooks like our good friend technomancy updated that yesterday. hard to get more canonical and current than that
18:29lawfulfalafeloh that looks really useful, I was stuck on the initial github page and didn't see it
18:29technomancythese days it's bundled with lein under the help task
18:33brehauthas anyone using clojure.contrib.sql or clojureql encounted "Generated keys not requested. You need to specify Statement.RETURN_GENERATED_KEYS to Statement.executeUpdate() or Connection.prepareStatement()."
18:36hiredmanbrehaut: yes
18:37brehauthiredman: any suggestions on how i might fix it?
18:37hiredmanit is a problem with c.c.jdbc
18:37hiredmanwe ended up writing our own thinner wrapper over jdbc
18:37hiredmanthat we use in conjuction with c.c.jdbc
18:37hiredmanjust some convience stuff around raw jdbc statements
18:38hiredman(not available anywhere, btw)
18:38brehautok, thanks
18:38ataggartSince the new clojure.java.jdbc is being worked on currently, it's a good time to give feedback.
18:38scgilardihttps://github.com/clojure/java.jdbc also has some code that may be helpful.
18:39hiredmanI think the new one already defaults to asking for generated keys to be returned, but I don't recall for sure
18:39technomancythe dude himself returns
18:40brehauthuh the most curious thing is that this same project works fine running locally connected to the live database via ssh tunnel
18:43clizzinany best practices for dealing with date/time in clojure? is there a wrapper for that hideous beast, the java calendar?
18:43seancorfieldhiredman: brehaut scgilardi yes, c.j.j will return generated keys by default for any single insert operation
18:43brehautseancorfield: cool
18:44technomancyclizzin: avoid j.u.Calendar and Date at any cost; you want clj-time
18:44seancorfieldthere will be a 0.0.1 release this weekend (snapshots exist right now)
18:44brehautseancorfield: is that going to be backward compat with 1.2.x?
18:44clizzintechnomany: ah yes, i remember using that once but had forgotten all about it. thanks!
18:45seancorfieldbrehaut: should be - all the new behavior is optional (naming strategies etc)
18:45brehautseancorfield: thats great, thanks :)
18:45seancorfieldoh, exceptions are no longer printed to *err* - but the print-* functions are exposed so you can leverage them
18:45seancorfieldotherwise it should be just the same by default...
18:46seancorfieldand it has its own resultset-seq so you'll be able to control how sql entity names are converted to keywords (and vice versa)
18:46seancorfieldi'd love to get some folks using it (apart from me!) so i can get more feedback :)
18:47zrilakJust saw a Clojure snippet to lazy-generate a Fibonacci sequence: (def fib (lazy-cat [0 1] (map + fib (rest fib)))) , and happened upon something superficially very similar in the SICP chapter on stream processing. Is that some kind of well-known "pattern" (for want of a better word) in functional programming? :)
18:49brehautzrilak: its (probably) not something you would want to do in clojure because the program will hold onto the head of the fib sequence
18:49brehautzrilak: meaning that as you realize more and more of it you will permenantly consume your heap
18:50zrilakI understood it will generate an embedded concatenation of [0 1] [1 [2 [3 [5... ]
18:50zrilakgotcha, yes, I thought so myself
18:51brehautzrilak: the pattern is well known; you see that sort of thing more in haskell though
18:51zrilakall right!
18:52zrilakbrehaut: that's good to know, since a good part of recognizing a piece of code lies in having been exposed to isomorphic examples
18:52zrilakisomorphous*
18:56joshua__Where can I find a project.clj file which uses clojure-contrib 1.3? I'm trying to use 1.3 priority map, but lein deps is giving me errors.
18:56VT_entitychrist are we already on 1.3?
18:56joshua__It is alpha etc.. but I need a priority queue and priority map works for that.
18:57VT_entityI dunno if I can help you... out of curiosity... what changed in 1.3?
18:58technomancyjoshua__: I don't think there's a monolithic contrib that works with 1.3
18:58joshua__technomancy, I just want clojure-contrib/priority-map
18:59technomancyif there's no AOT in it you may be able to use 1.2
18:59joshua__technomancy, alright. Thanks.
19:00joshua__VT_entity, https://github.com/clojure/clojure/blob/master/changes.txt shows some changes. The most interesting changes I've read about is the change to contrib. It is being set up so you can choose to include only the libraries you want.
19:00VT_entitythank you
19:06clizzinif i run a shell command from clojure (using java's Runtime.exec), does anyone know if that starts a separate process, or is it contained within the same java process?
19:07technomancyit's a separate process, with caveats
19:08technomancythere's a bug in the JVM where the second process temporarily requires as much memory as the parent process
19:08technomancywhich makes it usually fail in production
19:09clizzintechnomancy: i see. hmmm
19:12clizzinif i'm exec-ing several processes simultaneously using future, does each new process require the cumulative memory amount of all the previously exec-'d processes?
19:12Deranderanyone have any experience inserting piles of data w/ congomongo? I keep getting "db message size is too big (some number) max is (some slightly smaller number)"
19:13clizzin(basically, i have a ruby script that does some shell commands, and i thought i'd try to take advantage of clojure's concurrency to run some of those shell commands concurrently since they don't always depend on one another.)
19:13Deranderhttps://gist.github.com/958174 <-- this is the clojure code that I'm running. it's trying to insert a collection of hashes.
19:16technomancyclizzin: not cumulative, no. each subprocess will just take as much memory as the parent
19:16technomancyfor it to work reliably you need the ruby process to be launched independently and communicate with it over a socket or rest or something
19:17technomancyunless you know your JVM will never be using more than 50% of the system's available memory
19:19clizzintechnomancy: oh, the idea is to replace the ruby script with the clojure program. this sounds potentially dangerous though, since each of the shell commands i'm running is a hadoop job (a small hadoop job, but still, potentially bad)
19:20technomancywho's doing the launching?
19:21clizzinclojure is launching the jobs
19:21clizzinthe goal is to cut ruby out entirely
19:22technomancyisn't the point of hadoop to run jobs on a remote cluster?
19:24seancorfieldjoshua__: this monolithic contrib exists for 1.3.0 http://build.clojure.org/releases/org/clojure/contrib/standalone/1.3.0-alpha4/
19:25seancorfieldi recall it being a bit fussy due to some additional settings in leiningen
19:25clizzinyes. basically, there are a series of hadoop jobs i need to run, and i invoke them by calling 'hadoop jar job.jar class-name args' on the shell. but i want to run several of these jobs regularly, so i was hoping to automate that. i did it initially using ruby, but thought it might be easier to run several commands at once using clojure
19:25seancorfieldif you want to try, i can look in git history of project.clj to see how i used to have it setup back then
19:25clizzinthere is probably a better way to do this though -- any ideas?
19:26jnbergbash script + cron! :D
19:26clizzinjnberg: can that kick off asynchronous commands?
19:26jnbergthought you were just looking to queue up jobs for hadoop
19:27clizzinyeah. but when i run 'hadoop jar ...', the shell blocks until the job is done, no?
19:27seancorfieldjoshua__: here's what i had in project.clj for alpha2: [org.clojure.contrib/standalone "1.3.0-alpha2"]
19:28jnberghmm, not sure with hadoop honestly, sorry :( With gridengine it doesn't block, but that doesn't help :-/
19:30clizzinoh wait, duh, i can run the command with '&' at the end
19:32clizzinoh, well, ruby doesn't run that in background, but there's another easy way to do it. anyway, i'll stop talking about non-clojure stuff now.
20:30zippy314&(+ 1 1)
20:30sexpbot⟹ 2
23:43symboleWhat's the recommended way of making a Clojure application aware of the environment that it's running in, and subsequently load the correct config file (properties equivalent in the Java world)?
23:43hiredmanthere is System/env
23:45symboleI was thinking of passing -Denv=foo, and loading foo's config file. Is this idomatic, or are multiple approaches used?
23:45symboleLoading foo's config file by looking at System properties, I meant.
23:52symboleI gess Clojureland is at sleep. I'll come back later.