#clojure logs

2009-10-13

00:05ambienthttp://paste.pocoo.org/show/144638/ anyone know how to do these highpass and lowpass filters better?
00:05ambientthose functions just seem so awkward
00:05durka42what is it you're trying to do?
00:05ambientthey're basically IIR filters
00:05ambientfor example (lo-pass-crappy 0.2 (take 10000 (map #(- (* % 2.0) 1.0) (repeatedly rand)))) gives 10k samples of low-pass filtered noise
00:05ambienthttp://en.wikipedia.org/wiki/High-pass_filter
01:29wavis~def deref
01:41peter_12"Symbols beginning or ending with ':' are reserved by Clojure." Reserved for what?
01:43chousergenerally later use
01:44chouserif you try to read a symbol starting with : you'll get a keyword instead
01:49peter_12chouser: so a keyword is its own datatype in clojure?
02:32gilbertleunghi everyone
02:38gilbertleunghow do i find the first thing in a list that satisfies a certain predicate?
02:38gilbertleungis there a function for that?
02:38arbscht_,(doc find-first)
02:38clojurebot"([pred coll]); Returns the first item of coll for which (pred item) returns logical true. Consumes sequences up to the first match, will consume the entire sequence and return nil if no match is found."
02:38arbscht_that's in contrib
02:39arbscht_http://richhickey.github.com/clojure-contrib/seq-utils-api.html
02:39durka42note it's just (comp first filter)
02:43gilbertleungwould filter work on an infinite list?
02:43Chousukeyes.
02:43gilbertleungcool, thanks
05:21liwp~max
05:21clojurebotmax people is 182
05:21jdznice, a disciple of AWizzArd
05:21gerryxiaohello
05:22jdz~max
05:22clojurebotmax people is 182
05:22jdzfail
05:22gerryxiao(def board (proxy [JPanel] [] (paintComponent [g] (proxy-super paintComponent g) ...
05:23gerryxiaohow to type hints for proxy-super?
05:23gerryxiaoclojure complains paintComponent method can't be resovled
05:23Chousuketypehint g?
05:24gerryxiaonot work
05:24Chousukehow are you doing it?
05:24gerryxiao#^Graphcis2D g
05:25Chousukein the proxy-super call or in the argument list?
05:25gerryxiaoin the proxy-super call
05:25Chousukeboth should work, though, but perhaps not :)
05:26gerryxiaook, let's try args
05:27gerryxiaonot work
05:27gerryxiaoi have typetints for board, also not work
05:28gerryxiaoneither work
05:29gerryxiaoReflection warning, Personal/Gerry/GoBoard1.clj:99 - call to paintComponent can't be resolved.
05:29Chousukehm. maybe proxy-super has a bug then :/
05:29gerryxiaodoes macro support type hints?
05:30Chousukewhat do you mean?
05:30Chousukeyou can attach a type hint to any clojure form, but it's up to you to ensure that it's the correct one :)
05:30arbscht_gerryxiao: paste your code?
05:31gerryxiaoi mean whether i use type hints in defmacro
05:31gerryxiaoarbscht_: what code?
05:31Chousukegerryxiao: remember that the macro is a function that returns clojure code to be evaluated.
05:31arbscht_your proxy form
05:32gerryxiaook
05:32arbscht_lisppaste8: url
05:32lisppaste8To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.
05:32Chousukegerryxiao: you must ensure that the clojure code *returned* is the one that has the type hints
05:34Chousukefor example, (defmacro foo [x] `(.someMethod #^Type ~x)) would fail because the type metadata doesn't get attached to the symbol that is the value of x
05:35Chousukeyou'd need to do `(.someMethod ~(with-meta x {:tag 'Type}))
05:36lisppaste8gerryxiao pasted "proxy hints" at http://paste.lisp.org/display/88580
05:37Chousuke~def proxy-super
05:38Chousukeah, that would be the problem
05:38Chousuke"this" in the proxy-super is not type-hinted
05:40gerryxiaoproxy-super line not include this
05:40Chousukeyeah, but the implementation does
05:41Chousukeyou need to do it manually: (proxy-call-with-super #(.paintComponent #^JPanel this g) #^JPanel this "paintComponent")
05:41ChousukeI hope that's correct :P
05:42gerryxiaook, no this type hints, i can live however :)
05:53Fossiis there a doall map/for wrapper that signals sideeffects? in contrib or such?
05:54Chousukehmm
05:55Chousukewhat do you mean signals?
05:56Fossii still often find myself forgetting the doall
05:56gerryxiaois clojure github reps broken?
05:56Fossiespecially with constructs like (if (map println ["foo]) "something") where i more or less just want the side effect
05:57Chousukeyou want a strict map?
05:57Fossiso i wonder if there's a "realize" or such in contrib
05:57Fossiwhich does (doall (map func! data))
05:57Chousuke(def s-map (comp doall map))?
05:58Fossiyeah, i know how to define it, i just wondered whether there is a "standard" function for that in contrib yet
06:00tomojis map really OK for side-effects?
06:01Fossieh, we just kinda had the same discussion. why shouldn't it be?
06:02tomojI guess by itself it's ok
06:02Chousukeit is, but you must not forget to force it :)
06:02Chousukeunless you specifically want lazy side-effects
06:02tomojbut (doall (take 10 (map println ...))) is not so OK I think
06:03tomojit's certainly not OK
06:03tomojthis makes me want to avoid mapping over side
06:03tomojer, mapping over side-effects altogether
06:04tomojbut I guess if you force it immediately without passing it anywhere or doing anything else with it, it's OK
06:04tomojisn't doseq sorta like what you're asking for?
06:05tomojfor a "doall for" wrapper anyway
06:19licoresseI need some input regarding compiling clojure files
06:20licoresseI've set the *compile-files* to true, and the *compile-path* is set to "classes"
06:20licoressethe full path has been added to the classpath
06:21licoressedoes *compile-path* need to be the full path or is it enough with "classes"?
06:23tomojmy compile-path is just "classes"
06:24licoresseok
06:24LauJensenMorning gents
06:24licoresseso a M-c-k should in theory produce a .class file then
06:29ankouis there a possibility to refer to the current line number/source file?
06:49raek,(class *in*)
06:49clojurebotclojure.lang.LineNumberingPushbackReader
06:51raek,(.getLineNumber *in*)
06:51clojurebot55
06:51raekI'm not too familiar with the line numbering readers
06:53raekbut there should be some info in the javadocs, I think
06:54raekor here: http://github.com/richhickey/clojure/blob/master/src/jvm/clojure/lang/LineNumberingPushbackReader.java
06:56raekankou: You can wrap your FileInputStream with that one, if you like
06:59djpowell,(disj! (transient #{1 2 3}) 1)
06:59clojurebot#<TransientHashSet clojure.lang.PersistentHashSet$TransientHashSet@f9a36a>
06:59djpowell,(disj! (transient #{1 2 3}) 1 2)
06:59clojurebotjava.lang.ClassCastException: clojure.lang.PersistentHashSet$TransientHashSet cannot be cast to clojure.lang.IPersistentSet
07:00djpowellhmm, a bug in disj! there
07:00ambientcan someone help me build better IIR filters as infinite seqs? http://paste.pocoo.org/show/144638/
07:01ambientneed just some suggestions where to go from there
07:01octeif anything throws an exception in the repl i will see it if there's no try/catch involved right?
07:02djpowellif the exception isn't caught, the repl will print the exception name and message
07:02djpowellfor more details type (.printStackTrace *e)
07:02octestrange
07:02LauJensenambient, looks like you can implement both using reduce
07:03ambientLauJensen i dont know if i can make infinite seqs with reduce
07:03ambientwait..
07:03ambienti mean lazy
07:03ambientsorry i just woke up, i've yet to had my coffee
07:03ambienti'll check reduce
07:04LauJensenreduce is not lazy - which is evident from its wonderfully clear docstring :)
07:04ambienthere's the whole code http://paste.pocoo.org/show/144676/ my purpose here is to make lo-pass and hi-pass part of a lazy infinite sequence
07:05ambientthe audiochan-play part at the bottom
07:05ambienti don't really know if that's possible but i'm going to try anyway
07:06Maddas(assuming you actually want to compute the exact result)
07:06ambientsome wise guy said to me yesterday that in clojure.contrib there's some code that can be used to implement this
07:07ambientMaddas i dont really care about exactness, just some way to filter high or low frequencies
07:08raekambient: I think your project is really awesome!
07:08ambientraek heh, thanks :)
07:08raekyou're making a synth, right?
07:08ambientyep
07:09raekI like the use of infinite sequences
07:09ambient*dB
07:09ambientthey're basically streams
07:09ambientusing the stream mental model i _should_ be able to program a modular synth
07:10ambientand streams in scheme are just infinite lazy seqs afaik
07:10Maddasambient: I don't know any clojure, but won't your hi-pass function never return if coll is an infinite sequence?
07:11ambientMaddas that's because both hi-pass and lo-pass are not lazy infinite seqs at the moment. it's where i'm trying to go but am not yet
07:11djpowellif you can write it using cons and recursion, then you can slip the lazy-seq macro in to make it lazy
07:11djpowellsee: http://clojure.org/lazy
07:13tomojambient: what are you using to make sound? some java lib?
07:13ambientjavax.sound.sampled.*
07:13ambientcore
07:14raeklazy-cons?
07:15tomojsounds like fun
07:17djpowelllazy-cons is dead; you use lazy-seq + cons now
07:18raekoh
07:24gerry_hello
07:24raekhi
07:25gerry_why not defclass in clojure?
07:26gerry_as like ocaml or f#, both is fp language
07:26tomojwhat do you need defclass for?
07:27gerry_i want define java class from clojure
07:27gerry_or interface
07:27gerry_especially interfaces
07:29tomojyou can define java classes without a defclass
07:29rhickey,(doc gen-class)
07:29clojurebot"([& options]); When compiling, generates compiled bytecode for a class with the given package-qualified :name (which, as all names in these parameters, can be a string or symbol), and writes the .class file to the *compile-path* directory. When not compiling, does nothing. The gen-class construct contains no implementation, as the implementation will be dynamically sought by the generated class in functions in an impleme
07:29rhickey,(doc gen-interface)
07:29clojurebot"([& options]); When compiling, generates compiled bytecode for an interface with the given package-qualified :name (which, as all names in these parameters, can be a string or symbol), and writes the .class file to the *compile-path* directory. When not compiling, does nothing. In all subsequent sections taking types, the primitive types can be referred to by their Java names (int, float etc), and classes in the java.lan
07:31gerry_that's great
07:33LauJensenhttp://groups.google.com/group/clojure/browse_thread/thread/d8064dbb94c5cd2c
07:33LauJensenDoes anyone know why this year old suggestion to bring spit into core has not been accepted?
07:35gerry_rhickey should knew why :)
07:41octethis is probably dumb but.. how do i change this function to return the struct? http://pastebin.ca/1617651
07:45hoeck1octe: just make conn the last expression in the let form
07:46hoeck1octe: like: (let [conn (struct ...))] (.connect ...) conn)
07:48gerry_octe: not need get for map
07:50octehoeck1, gerry_: thanks :)
07:52spuzif I have a vector such as [1 2 3 5 6 7 8], how can I write a function which returns a list of elements n for which the previous element is equal to n-1. In otherwords, a list of all the numbers that are 1 greater than the previous number?
07:53LauJensenocte I think you can eliminate 3x (get conn :channel) by wrapping your statements in (doto (get conn :channel)...) and instead of 'new' suffic the class with a period "."
07:55Maddas.oO( And I thought you needn't be worried about getting homework questions in #clojure ;-P )
07:55tomojspuz: not exactly sure what you mean, but maybe:
07:56tomoj,(map first (filter (fn [[x y]] (= (inc x) y)) (partition 2 1 [1 2 3 4 5 6 7 8])))
07:56clojurebot(1 2 3 4 5 6 7)
07:56tomoj,(map first (filter (fn [[x y]] (= (inc x) y)) (partition 2 1 [1 2 5 6 3 3 4 7 8])))
07:56clojurebot(1 5 3 7)
07:56eevar2,(map inc [1 2 3 4 5 6 7])
07:56clojurebot(2 3 4 5 6 7 8)
07:56tomojeh, I got it backwards, map second instead of first
07:56eevar2might be what he ment? ;)
07:57spuzit should return (2 3 6 7 8)
07:57tomoj,(map second (filter (fn [[x y]] (= (inc x) y)) (partition 2 1 [1 2 5 6 3 3 4 7 8])))
07:57clojurebot(2 6 4 8)
07:57eevar2^^ nm
07:57spuz,(map second (filter (fn [[x y]] (= (inc x) y)) (partition 2 1 [1 2 3 5 6 7 8])))
07:58spuzum...
07:58clojurebot(2 3 6 7 8)
07:58tomojI don't see where (2 3 6 7 8) could come from
07:58spuzwell it works :)
07:58tomojah, yes
07:58spuzthanks tomoj :)
07:59spuznow, I've just got to understand it
07:59tomojjust play around on the repl with the parts
08:00tomoj(partition 2 1 ..) takes partitions of size 2 stepping 1 each time, so it gives ((1 2) (2 3) (3 5) ...)
08:00spuzok, yeah it makes sense. I've just got to figure out a slightly more complex version of that
08:18AWizzArdIs there a way to kill a running agent?
08:18AWizzArdWithout checking in the agent fn for some signals which will then simply exit the function.
08:20LauJensenAWizzArd, one particular or can it be all agents?
08:21AWizzArdOne particular. For example when my agent swap!s the value of an atom I might want to end its job from outside.
08:21LauJensenIts a self-calling agent ?
08:21AWizzArdNo
08:21LauJensenSo altering some shared 'running' variable is out of the question?
08:22AWizzArdIf there is not already a built in function for that I will simply ask in the agent fn if (= *running* true) or something like that. I just thought there might be some other way.
08:22tomojhow do you know from the outside when the agent swap!s the value?
08:22AWizzArduhm (if *running* ...) :)
08:22LauJensen(when *running*...) :)
08:23AWizzArdLauJensen: oki, I will do just that then.
08:23LauJensenI don't know of a function which does what you want specifically, but you're welcome to post the code if you want some more input
08:27licoresse,(doc *compile-path*)
08:27clojurebot"; Specifies the directory where 'compile' will write out .class files. This directory must be in the classpath for 'compile' to work. Defaults to \"classes\""
08:27ambientanyone know the fate of http://clojure.org/streams ?
08:27ambient(doc stream) is nil
08:27clojurebot"clojure.contrib.http.agent/stream;[[http-agnt]]; Returns an InputStream of the HTTP response body. When called by the handler function passed to http-agent, this is the raw HttpURLConnection stream. If the default handler function was used, this function returns a ByteArrayInputStream on the buffered response body."
08:27licoressewhen I "touch" this symbol with the cursor, emacs crashes
08:30raekAWizzArd: if you want to controll the "running" on a per-agent basis, you might want to let the agent keep track of it's own running-value
08:30raeklike this: (def a (agent {:running true}))
08:30raek(send-off a assoc :running false)
08:31raekbut then, all it's actions must eventually time out
08:31raekotherwise, the agent will never run the "stop action"
08:32raekI use this approach in an agent reading from a socket
08:45AWizzArdBtw, is there a way to exit a doseq before it traversed its collection(s)?
08:47LauJensenAWizzArd, you mean like :when or :while ?
08:58AWizzArdLauJensen: good thx
09:00LauJensennp
09:06ambientdoes there exist a profiler in clojure that can identify which functions take how much time in the entire program execution?
09:06LauJensenI know JSwat does that, but I also think you can get it from jvisualvm
09:07ambienthmm, i thought that basic java profilers couldn't tell about defn funcs
09:07LauJensenif you followed by brians transient brain blogpost, you'll see future, deref, filter, concat etc all show up
09:08liwpambient: each clojure function compiles into a java class with a bunch of invoke methods, so those should definitely show up
09:08ambientok, thanks
09:08liwpseems like LauJensen has actually tried this ;-)
09:10ambientim super lazy, i think i need to do my own lib that i can just (use clojure.profiler) and (profile foobar) :p
09:11liwpthat would be nic
09:11liwpnice even
09:11LauJensenc.c.profile aint doing it for you?
09:11ambientumm
09:11ambientthere are plenty of things i'm unaware of
09:12LauJensenhttp://blog.bestinclass.dk/index.php/2009/10/brians-transient-brain/
09:12LauJensenread the last comment
09:13ambientgreat :)
09:14liwpseems like you have to annotate your code when you use c.c.profiling which is a bit icky
09:14liwpOTOH I guess you get more control that way and you can concentrate on those bits of the code that you want to work on
09:16LauJensenEverythings a trade in some regard
09:17ambientunless you steal and cheat
09:17LauJensenhehe
09:17LauJensentrade your soul for a gold watch
09:17ambientthat actually holds true for programming also
09:18ambientyou dont actually have to implement _the_ algorithm. just implement _an_ algorithm that _looks like_ the original one
09:18ambientwhen it comes to human interaction
09:20ambientlow-pass filter with clojure: (reductions #(/ (+ %1 %2)) (oscillator))
09:21ambient* (/ (+ %1 %2) 2)
09:25ambient(defn lo-pass [d coll] (reductions #(+ (* %2 d) (* %1 (- 1.0 d))) coll))
09:25ambientthis is just so amazing...
09:26raekambient: that's beautiful
09:31churib /help
09:31ankouI'm using a function, that defines a macro, does this also work with aot-compilation? Or is macroexpansiontime with aot-compilation completly at compiletime?
09:32chouserunless you call compile or eval, no macros will be expanded after AOT
09:34raekambient: do you have a repository for your synth project?
09:37raekI want to try your code...
09:37ambientraek: http://bitbucket.org/amb/clojure-snippets/src/tip/audio.clj
09:37ambientit's just in my random-code folder, might make a separate project if it grows larger
09:39raekbitbucket looks an awfully lot like github...
09:40raekI like github, so that's good, I guess
09:50LauJensenraek, Gitorious is the best though
09:52noidiwhat advantages does it have over github?
09:52LauJensenSpeed, Speed and a consitent use of markup across the site. It's more community-oriented
09:55noidihmm.. those merge requests with a status flag look handy
09:55LauJensenOn ClojureQL we use the merge-request system to do code-reviews
10:29octewhen writing code that is inherently stateful, for example an irc client, how would one structure that?
10:29octein an oo-language you'd create a stateful object containing the socket connection, etc
10:29octei've started a bit by creating a struct that holds those stateful objects, with a connect-function that creates it and returns it
10:29octethen define the other functions to take it as a parameter
10:29octeis that a good design?
10:32arbschtocte: interesting coincidence. that's -exactly- what I'm working on right now, and pretty much with the same approach
10:33octemaybe i'm on the right track then :)
10:34octearbscht: exactly as an irc-client too, or rather just the same issue?
10:34arbschtirc client
10:34octeah
10:34octeit's usually a good learning project..
10:35arbschtI suppose. I just got sick of pircbot :)
10:35drewrarbscht: that's what drove me to it too :-)
10:35chouseri've done a couple of these stateful connection-oriented things now, and they all look pretty much like this.
10:35chouserI suppose it's inevitable.
10:36arbschtthe pattern shows up in my Swing code, too
10:36chouserIt's very easy, though, to let the statefulness and mutation leak into more of your code than necessary. Be viligent.
10:36arbschtdrewr: what came of it? have you published a library?
10:37drewrarbscht: heh, I'd show you if github weren't down...
10:39octedrewr: perhaps you could link it anyways so i won't forget to check it out when it comes back up..
10:40drewrhttp://github.com/drewr/clot/tree/master
10:42octethanks
10:42drewrexperimenting with sockets and dynamic message dispatch
11:25kefka,(ns a)
11:25clojurebotnil
11:25kefka(def x 4)
11:25kefka,(def x 4)
11:25clojurebotDENIED
11:25kefkaAh, right.
11:25octegithub back up..
11:25clojurebothttp://github.com/richhickey/clojure/tree/master
11:26kefkaSo here's a question. If I create a namespace a with x bound to 4, then create a namespace b that uses a, then when I'm in b, x will resolve to 4. However, outside of b, b/x does not resolve to 4.
11:26kefkaWhy is this?
11:27Chousukehave you required the namespace?
11:28kefkait's not a file. Actually, I meant _refer_, not _use_
11:29kefkaanyway, use is supposed to be require + refer, right?
11:30Chousukehm
11:30kefkaHow do I do the Lisp-paste again? I'll show an example.
11:30drewrevery time I use defnk I want it to be in core
11:30Chousukelisppaste8: url
11:30lisppaste8To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.
11:30drewrkotarak ftw
11:31chouserkefka: That is the designed behavior, so that your main app namespace isn't cluttered with names from secondary libs.
11:32kefkachouser: Got it. Thanks. That makes sense. So I guess combining multiple namespaces into one is bad form?
11:33kefkaWhat I have is multiple files that usually should go together in one namespace.
11:33kefkaThe files are broken apart because they're large (1000+ loc).
11:33chouserah, well, you can do that with 'load'
11:33chousersuch as core.clj, core_proxy.clj, core_genclass.clj
11:37kefkaOk. We're trying to avoid loading a bunch of files, except when we want to (e.g. reloading clj files).
11:37kefkaMy understanding of the advantage of require/use is that things are only loaded once.
11:38chouserhm. Well, I think there's a thing in contrib that allows you to pass values along from one namespace to the next, but I'm not sure its use is recommended.
11:40tomojimmigrate?
11:40chouserthat's the one.
11:41chouserI haven't used it.
11:41kefkaOk, thanks. I'll look into that.
11:41chouserThere was a thread on the group recently where it sounded like a couple people who had in the past no longer use it because they didn't like how it behaved.
11:41tomojit does weird things
11:42tomojhttp://groups.google.com/group/compojure/browse_thread/thread/400aac94e536e633#
11:42kefkaI guess it's just odd to me that x, when in b, resolves to something different than b/x when outside of b.
11:45cemerickis it right that proxy has no access to protected methods/members, and gen-class is the only available route?
11:46chousercemerick: yes
11:46chousercemerick: or reify
11:46cemerickreify isn't fully baked yet though, right?
11:47chouseryeah, the bridge method stuff isn't there, and it's all in a side branch. which is why I started with "yes" :-)
11:48cemerickis it planned on for the nebulous 1.1, or is it on the back burner for now?
11:48chouseriirc, it's the main feature defining 1.1
11:49cemerickyeah, that's what I thought. I didn't know if things had changed of late, though.
11:49cemerickI've been stupidly busy.
11:49chouserstupidly?
11:50cemerickYeah...doing a lot of work treading water, or so it feels like.
11:50chouserbleh
12:02octedrewr: i found your use of agents interesting
12:02rhickeyjust to fill you all in, I've been actively looking at something like dynamic type classes for Clojure. This driven by concerns that reify will leave us with the same limitations Java has re: extensibility - you can't add interfaces to existing classes. So reify won't help the if/else stuff in RT to have the abstractions reach java things
12:02rhickeybut dynamic type classes would
12:02rhickeythey're not quite type classes, I've been calling them 'protocols'
12:04leafw_sounds like "interface".
12:05rhickeyleafw_: abstractly yes, but that has a meaning already that includes some thing that protocols wouldn't - requires derivation (at type definition time), creates isA relationship, non-injectable
12:05rhickeya protocol could be extended to any class after the fact
12:05rhickeyand wouldn't create an isA relationship
12:06leafw_I understand, the vocabulary is taken. The definition you gave is that of an interface, yet not a java interface (since yours would be injectable)
12:06leafw_the protocol as you want it is a formalized duck-typing then.
12:06rhickeyleafw_: not at all, not match by name
12:07leafw_then I'll shut up and wait what you come up with.
12:07chouserrhickey: out of curiosity, is there a forum (presumably offline) where you discuss such things, or is this the first you've said it "aloud"?
12:07rhickeyyou'd need a (implement protocol aClass fns)
12:07rhickeychouser: first aloud
12:07chouserok
12:08chouserthanks for sharing. :-)
12:08rhickeyI'm still working out the dispatch design, but it will be really nice, definitely what I would want, protocols orthogonal to types
12:08rhickeycould do a lot of what Haskell type classes do, but not all, since no inference and dynamic
12:09cemerickthis is in addition to reify, or is reify's usage of interfaces a subset of protocols?
12:09rhickeycemerick: I'm still working out the relationship between a protocol and an interface - obviously having some connections to interfaces enables extension from Java
12:10rhickeybut they are truly different in that protocols aren't types (except as an implementation detail)
12:11rhickeyand protocols much more Clojure-centric in directly yielding callable fns, aa opposed to host-world .callable things
12:12cemerickSounds nice.
12:12cemerickof course, insofar as that "implementation detail" is stable, protocols are a superset of interfaces
12:13rhickeyso there would just be a protocol for Seqable and it would define clojure.core/seq
12:13cemerick(which has the pleasant characteristic of fitting into my head easily :-))
12:13rhickeyand you could say (implement Seqable String ...)
12:13lpetitrhickey: just to be sure I'm not mistaken things, this really has nothing to do with the way Qi allows to create types, one other feature you were talking about some day ?
12:14rhickeyand there would be no need for RT.seqFrom and all the conditionals there
12:14lpetitrhickey: is there literature that comes close to what you have in mind ?
12:14rhickeylpetit: not about types
12:15rhickeylpetit: you could get to protocols by looking at CL literature about generic functions and grouping them (there is no construct, but often desired), or from interface injection, or from Haskell type classes (think dynamic)
12:16chouserso clojure.core/seq would be a IFn created when the Seqable protocol is defined?
12:16rhickeythe critical thing is that they support orthogonal extension in the type or function dimensions, without intrusion into existing stuff
12:16rhickeychouser: yes
12:16lpetitrhickey: OK. I remember discussions between you and someone which haven't shown up for a couple months on the ml , don't remember his name, but he was always talking with you about orthogonality of protocols v/s types, and he also wanted to port more or CLOS to multimethods (or as one of the "out-of-the-box" multimethods dispatching strategies)
12:16chousersort of multimethods in batches.
12:17rhickeychouser: a little bit yes, with some restrictions (dispatch function built-in)
12:17rhickeybut much easier than dealing with multiple multimethods, and yielding a proper abstraction in a set
12:17chouseryep, makes sense.
12:18rhickeyI spent a lot of time thinking about this on my Denmark trip, just working out the gory details now
12:18rhickeybut I am still focused on cinc, and what facilities the language should have to enable that. RT indicates reify is not enough
12:19rhickeyadopting interfaces is easiest and most like the current impl, but could be not the best fit for Clojure (of course there will always be a way to implement interfaces)
12:20rhickeyI really like moving away from isA as the only way to share abstractions
12:22rhickeyI don't like the auto-adapter-wrapper technique of Scala implicits
12:22cemerickisn't this something that could be implemented with some sugar on multimethods?
12:22ambienthow would i go about introducing side effects to a closed stream (lazy-seq)?
12:23ambientvalue stream from user-controlled swing slider
12:23cemerick(not as an actual impl strategy, just getting my head around it)
12:23rhickeycemerick: first pass might be just to try out the syntax etc, but no, there will be some heavy lifting under the hood for perf probably
12:25rhickeythat's what Im working on now (dispatch strategy), with an eye towards perf and possibly leveraging JSR292
12:25lpetitrhickey: to say it differently (so that I can check I understand the basics), is it ok to start with "it's a way to group related multimethods together, a more structured way than to just place them together in their own namespace" ?
12:27rhickeylpetit: except they are only available/extensible as a set, have a fixed dispatch strategy, and possibly some relationship to an interface for extension via Java
12:28lpetitrhickey: ok, I can see the plus. If you can think of a design that can make it possible to also do some static analysis for IDEs :-) (ok in this case this would really resemble what java interfaces do, but java interfaces are not bad, AFAIK)
12:28rhickeyit would provide a very clear option for people coming from OO wondering how to encode their abstractions
12:29rhickeyI like interfaces except for isA and not being able to add them to existing things
12:30lpetitrhickey: ok, "not being able to add them to existing things", => the new "protocol" concept is a dynamic extension (a superset) to interfaces in this area, right ?
12:30rhickeyperf a critical question, as interfaces are very fast. so there's the static/dynamic tension
12:31rhickeylpetit: they differe in critical ways, so not/super/subsets. Interfaces imply an isA relationship
12:31lpetitrhickey : one more time please on the "isA" issue = do you mean there will be no such thing ? I guess I still don't totally understand in this area (Ah, java background)
12:32rhickeywhen you implement Seqable for String that won't make a String a Seqable
12:32rhickeybut String will implement the Seqable protocol
12:33rhickeyi.e. code written to Seqable will work for Strings
12:33cemerickrhickey: are you really aiming to make protocol dispatch performance on par with interface dispatch?
12:33rhickeyand all of the things I have to go into RT to do now you will be able to do yourselves
12:33lpetitrhickey: but that would make a String implement the Seqable protocol. No speaking about types, but about protocols/behaviours, can't a behaviour be defined as an extension to an already existing protocol (interfaces do that, and I don't see that as the same "isA" relationship as "extends" conveys for java classes)
12:34rhickeycemerick: probably not possible without JSR292, and not sure even then
12:34cemerickOK, that sounds sane. :-)
12:34rhickeycemerick: but it needs to be really fast if to be the base for Clojure's abstraction set
12:35cemerickRight.
12:36rhickeylpetit: I haven't decided on extending protocols, not sure there's as much need in a dynamic lang, since oyu can always just create another protocol and implement that, the only time you care is if asking - do you implement protocol Z? you'd like the answer to imply something about X and Y
12:36lpetitrhickey : this indeed would be awesome, if the core does this.
12:37lpetitrhickey: I mean, for such generic protocols as Seqable, ..., really awesome !
12:38rhickeyI'm trying to eliminate the closed extension I had to do in RT, which falls out of the limitations of interfaces
12:38cemerickI can't say I have a use case for this right now. Maintaining RT can't be fun, but I worry about the implications (esp w.r.t. perf) of pushing RT stuff down into clojure.
12:39cemerickor, the skeptic's, anyway
12:40rhickeya Clojure encoding of the RT conditional logic would have identical perf, it has more to do with interfaces vs (more dynamic) protocols
12:40rhickeybut I totally agree, needs to be well considered. I think the interface bridging might provide a way to get the best of both worlds
12:41cemerickI've no idea what "interface bridging" is, but that's OK. :-)
12:41rhickeycemerick: having an interface fall out of defprotocol
12:42rhickeyan implementing that interface would sidestep the more involved dispatch
12:42rhickeyand
12:43Chousukewould you be able to "map" protocols to arbitrary interfaces then? Like the C++ concept map idea.
12:43cemerickah, indeed, back to my thinking of protocols as a superset. Sure, they aren't is-a, but if you can map protocols to a basket of interfaces, that might be good enough for fast dispatch.
12:43rhickeyChousuke: I don't know, not a priority. The point is to provide a Clojure abstraction mechanism. Interfaces are a host thing
12:44Chousukeright. The quest to define Clojure without any mention to Java :)
12:45rhickeycemerick: right, the point though is that you can't rely on and should never ask if x isA protocol, because not all implementations can be
12:45cemerickrhickey: aside from your distaste of is-a, is getting away from interfaces really necessary for cinc? What potential hosts don't have interfaces or something similar?
12:45rhickeycemerick: It would make me sad for cinc to have the if/else stuff from RT still
12:46octewhat is cinc?
12:47rhickeyit seems like a fixed set (Clojure's abstraction * Java's built-ins), but represents a bigger problem (the expression problem)
12:47ChousukeI suppose the gist of it is that if cinc were defined in terms of interfaces, it would limit any implementation to emulating interfaces, but if we use something more "Clojurey" at the high level, the implementation could then use interfaces, or whatever fits
12:47rhickeyI've been banging my head against the expression problem my whole career, would love to be done with that.
12:47cemerickrhickey: I'll buy you a beer to make you happier, then. I'm just saying, it's really OK if the host platform needs a bit of a hairball underneath. I'm just offering a cost/benefit sanity-check here.
12:48ambientocte: clojure in clojure afaik
12:48lpetitocte: Clojure IN Clojure
12:48rhickeycemerick: the problem will reappear in large Clojure apps and libs, just like it does now in Java - ever get an API that says 'just derive from this' that you want to use with classes you don't control?
12:48octeoh, thanks
12:49rhickeyif interfaces are the way Clojure users create abstractions, we'll have that problem, plus the dot-or-not dichotomy
12:49cemerickaren't multimethods (or perhaps some sugared multimethods) the answer there, especially for app-level stuff?
12:50rhickeycemerick: sure, this is just a multimethod variant, but consider how often people wish certain Clojure fns were multimethods
12:51rhickeythey're not because they are interface + hand-switch based
12:52lpetitrhickey: so for example, with protocols, one would be able to make new "types" adaptable to the protocols really used on defns arguments ?
12:52cow-orkerIs there a way to use unqualified symbols in a macro? I have (defmacro mkfoo [name] `(defn ~name [param#] (foobar param#))) and it works, but the argument list shown by (doc some-made-function) is quite ugly (gensym'd param)...
12:53cow-orkerAs this macro is only called at the toplevel in a ns i control I guess I don't have to worry about capture?
12:53rhickeylpetit: right, a protocol is an extensible fn set, much like a multimethod is an extensible fn
12:53lpetitcow-orker: explicitly specifying a :args entry to the attrs-map is generally what is done by people which build such macros
12:54lpetittoo sad I must leave the chat now, bye all
12:56lpetitcow-orker: I guess capture should always be intentional, your macro could be encapsulated in a complex 'let some day ?
12:57Chousukecow-orker: lpetit's advice is good. (defmacro mkfoo [name] `(defn foo [param#] {:arglists ~'([param])} ...) should work
12:57cemerickrhickey: IIUC, that sounds just a little scary, on its way to python monkey-patching or somesuch. The nice thing about multimethods is that the hierarchies are naturally safe (using namespaced keywords, etc), and your ill-conceived hierarchy can't touch mine. But if core fns are hierarchies, then someone adding a dispatch to + for [:plum :heat] to return :prune is going to get messy.
12:57Chousukeyou can also do (defn foo [~'param] ...) but that's evil. :)
12:57cemericks/hierarchies/multimethods
13:00cow-orkerChousuke: yes I just found that in some example code by SH. Thank :-)
13:00rhickeycemerick: it is definitely not monkey-patching, in that fns are namespaced. I'm not sure what you mean by fns being hierarchies
13:00rhickeyprotocol fns are namespaced
13:00cemerickyeah, I meant s/hierarchies/multimethods there
13:01rhickeyso right now someone can extend seq to some bizarre thing by deriving from Seqable
13:01cow-orkerAs for evil.... I consider this macro to be an implementation detail for the ns.... but can I count on this behaviour in future versions?
13:01rhickeyusing proxy e.g.
13:02rhickeyalso, I doubt + will become a protocol
13:03Chousukecow-orker: which behaviour do you mean?
13:04Chousukecow-orker: the evil example will just capture the name "param" from its environment, so for example (let [param 2] (mkfoo somefoo (stuff-with param))) would not work as expected
13:06cow-orkerthat ~'sym works like that and is allow - that there won't be an effort to disallow this in the name of macro hygiene :-)
13:06cow-orker...allowed....
13:06Chousukeah, yes.
13:06Chousukeof course.
13:07Chousukethere's no way to disallow it, actually.
13:07Chousukewithout adding special logic to how ~ works. and even then you could find ways around it.
13:08cow-orkeryes... I guess so... so, use it sparsely and responsibly :-)
13:08Chousukevariable capture can be useful when desired
13:09Chousukewith the clojure syntax-quote it's also easy to spot
13:09Chousuke~'foo looks ugly enough that it'll make people stop and think whether it's really the right thing to do.
13:13serp_does clojure have macros?
13:15cow-orkerChousuke: true. I hope I do the right thing... the functions I create are part of the API for the ns so I think the (doc) should be nice.
13:15Chousukeserp_: of course. it's a lisp after all :P
14:09ambienthow would i make this into a lazy sequence modifier: "y[i] := a* x[i] + (1-a) * y[i-1]" where a is constant, y is new seq, x is old seq
14:09ambientwith reductions it seems to be "y[i] := a * x[i] + (1-a) * x[i-1]"
14:09ambientmanually with rec-seq?
14:10chouserreductions should be passing you your previous return value, the the previous input value
14:11ambienti think i have to read the source some more to actually get it
14:11chouserhm, not sure that's the easiest.
14:12ambientim dealing with algorithms where i need to have more than one items of history for both new-sequence and old-sequence
14:13chouser(reductions (fn [yi-1 xi] (+ (* a xi) (* (dec a) yi-1))) init-y y)
14:13chouserthat ought to do it, I think.
14:14ambienti already had (reductions #(+ (* %2 d) (* %1 (- 1.0 d))) coll) but i was doubtful of its correctness
14:14ambientit sounds right but i can't be sure if it actually _is_ right
14:14ambientand that really bothers me
14:15ambientand this is the simplest algorithm i have...
14:15tomojcan't you test it out?
14:15ambienti already threw the correct function into trash
14:17chouser,(reductions + 10 (range 5 10))
14:17clojurebot(10 15 21 28 36 45)
14:18tomojambient: what kind of audio algorithm is that?
14:18ambienthere's the other one. "y[i] := a * (y[i-1] + x[i] - x[i-1])"
14:18ambientlow-pass iir filter
14:18tomojjust do reductions on (partitions 2 1) for that one, I think
14:22tomojexcept.. what's y[0]?
14:22ambienthead of new-sequence
14:22ambienthmm no, tail
14:23ambientwhat value it is, doesn't really matter
14:23tomojwell, I dunno, but
14:23tomoj,(reductions (fn [y [x1 x2]] (* 2 (+ y (- x1 x2)))) 0 (partition 2 1 [1 2 3 4 5 6]))
14:23clojurebot(0 -2 -6 -14 -30 -62)
14:26ambient[0.3 -0.1 0.9 0.95 0.7 -0.99] original seq ... [0.3 0.15 -0.05 0.5750000000000001 -5.551115123125783E-17] correct seq when a=0.5
14:26ambient,(reductions (fn [y [x1 x2]] (* 0.5 (+ y (- x1 x2)))) 0 (partition 2 1 [0.3 -0.1 0.9 0.95 0.7 -0.99]))
14:26clojurebot(0 0.2 -0.4 -0.22499999999999998 0.012500000000000011 0.85125)
14:28ambientthere might be some errors in my "correct-seq" though
14:28tomojyour correct sequence has a different length than the original
14:29ambientit's because y[i-1] when i=0 is not defined
14:29tomojI see, so you need to skip one
14:29ambienti can also use default values, like 0
14:30ambientit doesn't make a large difference in audio quality
14:31tomojwell you have to have some initial arbitraty y
14:32tomojif y[-1] is not defined, then neither is y[0], and so on
14:32tomojlooks like you're saying y[0] = x[0]
14:32ambienti used to do C so i wasn't so particular about reading from obscure memory locations if the value had no significance ;)
14:33ambient(+ nil 1)
14:33ambient,(+ nil 1)
14:33clojurebotjava.lang.NullPointerException
14:35ambienti can't tell the difference between the correct one and yours by ear
14:36ambientgood enough ;)
14:36ambientthanks for the help
14:36tomojgood luck
14:36tomojI can't figure out where that correct seq is coming from
14:36ambienthttp://paste.pocoo.org/show/144753/
14:42ambientnext up: converting this https://ccrma.stanford.edu/courses/220b-winter-2003/lectures/9/examples/moog.lisp into lazy-sec ;(
14:55hiredmanclojurebot: protocols?
14:55clojurebotTitim gan éirí ort.
14:55hiredmanclojurebot: protocols is <reply>http://clojure-log.n01se.net/date/2009-10-13.html#12:02
14:55clojurebotc'est bon!
15:04lpetitrhickey: currently multimethods have the insanely powerful property of being able to do multiple (and even more, arbitrary) dispatch on the arguments. What about protocols ? All these considerations of protocols being compared to java interfaces leaves me perplex. Is protocol a grouping of functions with a dispatch restricted to the first argument, as are java interfaces ? I guess there's a...
15:04lpetit...piece of the puzzle that's still missing in my head ...
15:06chouserlpetit: yeah, he said protocols would not have customizable dispatch function
15:06rhickeybut might allow dispatch on other than the first arg
15:07rhickeymultimethods will still be there for more advanced things, but protocols are likely to be simpler for others
15:08lpetitrhickey: do you have some "surface" example of what coding to protocols could look like ?
15:09rhickeylpetit: not that I want to share just yet, but would look like gen-interface with less cruft
15:10lpetitrhickey: ok, and the restriction on the dispatching mechanism certainly will make it just work with the concept of 'type, I guess ?
15:11rhickey(defprotocol Seqable [coll] (seq [coll] "Returns a seq on the collection"))
15:12rhickeylpetit: the interaction with type is something I'm still thinking about, including making type a more proper slot like meta
15:14lpetitrhickey: is using a capital letter as the first letter of the protocol name a convention suggestion, or is it just to make the parallel with the current java type name ?
15:14rhickey(implement Seqable [String] (seq [s] (StringSeq/create s))
15:15rhickeylpetit: dunno right now
15:16lpetitrhickey: wouldn't using a name like implement break the convention of prefixing such things with 'def: defmulti/defmethod ?
15:16chouserimplement isn't interning any new name in the namespace like the other defs
15:16chouserthat was done with defprotocol
15:17lpetitchouser: does defmethod intern a new name in the namespace ?
15:17chousernope
15:17chousergood point.
15:17chouserthen again, I tend to trip over that :-)
15:17rhickeydon't worry about the names just yet, will be easier once there are semantics :)
15:18lpetitchouser: but maybe it's defmethod which breaks the convention, given your arguments :)
15:18chouserI have to think of both defmulti and defmethod before I can remember which to use for which.
15:18LauJensenrhickey, Is there a wiki entry coming up on assembla on this ?
15:19lpetitrhickey: thanks for all the input. I think I'll now refrain myself from asking more, and wait for something more elaborate on your part (and by not asking more questions myself I'll leave you some time to do so ;-) )
15:22rhickeyLauJensen: not yet, needs more think-time
15:36itistodayanyone here used compojure?
15:36itistodayused or uses actually
15:41LauJensenYea, all the time, its great :)
15:43mwoelkerHere's a minimal prototype base "type system" for clojure: http://gist.github.com/209477
15:43itistodayLauJensen: what happens if you want to change a file? do you have to restart the server to recompile and load it?
15:43mwoelkerI hope it's not considered heresy to put objects into a functional language...
15:44mwoelkerHas anyone ever tried something like this?
15:44opqdonuthehe
15:44opqdonuthave you heard of haskell, ocaml
15:44LauJensenitistoday, if you're working locally, usually you just re-eval whatever function your working on, at changes are immediate. On my server I don't have a live repl, so I change the file and restart
15:44opqdonutthey are strongly typed functional languages
15:45hiredmanthat's not a type system
15:45hiredmanthat there is an "object" system
15:45itistodayLauJensen: (i'm new to clojure) do you get the repl the same way you get the repl to a running clojure program, by running it with a property to connect on a port?
15:45kotarakmwoelker: ocaml has objects ("Objective" Caml)
15:46hiredmanmwoelker: don't do it
15:46mwoelkerI meant specifically for clojure...
15:47LauJensenitistoday, you start a repl as you normally would, hopefully M-x slime, then you define your servlet and eval (run-server servlet params), that'll leave you with a repl and a running server
15:47hiredmanwhat you have is the most naive way to implement objects
15:47Chousukemwoelker: your mutate function is badly named :)
15:47itistodayLauJensen: but i mean if you're running this on a remote server
15:48LauJensenon a remote server I don't keep open repls
15:48mwoelkerhiredman: I thought it might be a nice way to get some polymorphism in there, but maybe I'm just still to stuck in my OO ways
15:48hiredmanthere is a spinoza
15:48Chousukemwoelker: it mutates nothing. (which is a good thing)
15:48hiredmanbut spinoze is also a mistake
15:48hiredmanmwoelker: multimethods
15:49Chousukepolymorphism doesn't imply object-orientation
15:49mwoelkerChousuke: yeah I am not quite happy with the mutate name or implementation really
15:49mwoelkerhiredman: multimethods have global effects don't they?
15:49hiredmanmwoelker: global effects?
15:51mwoelkerhiredman: well if I defmethod to handle vectors for instance, all future calls are gonna call that method, this approach allows only local effects
15:51mwoelkerAsked another way what would the example code look like in idiomatic clojure?
15:52Chousuke(def a {:given-name "John" :surname "von Neumann"}), similarly for b :P
15:53mwoelkeri.e. two pieces of "data/stuff" that should somehow behave differently
15:53hiredmanmwoelker: it depends on your dispatch function
15:53mwoelkerChousuke: okay and full-name?
15:53Chousukemaybe with a :name-classification 'hungarian key as well
15:55lpetitmwoelker: hello!
15:55Chousukethen just (defmulti full-name :name-classification) (defmethod full-name 'hungarian [thing] (str (:surname thing) " " (:given-name thing)))
15:56lpetitmwoelker: from now on, have you already read through defmulti/defmethod, or is it a new are for you ?
15:56lpetitmwoelker: I found some detail (and some documentation parts) not easy to follow on, but the intent of defmulti is really super-powerful
15:57Chousukemwoelker: Clojure generally doesn't use camelcase btw.
15:57Chousukeso identifiers like fullName are nonidiomatic
15:57Chousukeexcept when dealing with Java interop.
15:57mwoelkeror is my premise wrong: mixing data and behaviour?
15:57lpetitChousuke: is your use of 'hungarian rather than e.g. ::hungarian intentional ?
15:58Chousukelpetit: hmm, good point. no. :)
15:58lpetitmwoelker: yes, it's wrong
15:58chouserif you *really* want to attach functions to your data (ala javascript prototypes), idiomatic use of multimethods isn't going to get you all the way there.
15:58Chousukelpetit: I just thought I should use something other than a keyword
15:58chouseris it wrong? have you looked at clojure.zip?
15:58Chousukeif you want to attach functions to your data, do so, but don't make so big a deal over it.
15:59Chousukeafter all, functions are just another kind of data.
15:59mwoelkersorry afkphonecall
15:59lpetitChousuke: but I can understand - currently using raw keywords has its pro, but one big cons is that you're not helped at all with typos. In other areas the clojure compiler already does a good job of informing you (e.g. var symbols)
16:01lpetitof course data must be manipulated somewhere :)
16:02mwoelkerI'm back, I still think the defmulti approach is somehow less clean and functional
16:02lpetitmwoelker: can you explain ?
16:03mwoelkerthe key keyword approach has the advantage that it adds a layer of indirection between caller and callee
16:03lpetitmwoelker: did you miss the recent IRC discussion on protocols, initiated by rhickey ?
16:03mwoelkerlpetit: yeah I missed the protocols, was aware of multimethods though
16:04mwoelkerwith the prototype approach you could replace plain data with functions and vice versa
16:04chouserclojure.zip's implementation is relevent here.
16:04lpetitmwoelker: I'm not sure : the key keyword should be a matter of the library provider, something that "tags" the object when created -> so the caller would certainly prefer to use a builder function anyway :)
16:04hiredmanlpetit: if he doesn't like multimethods, I doubt he will be interested it protocols
16:04hiredmanand protocols don't exist yet
16:04chouserit manipulates vectors, each of which has a bunch of fns in its metadata
16:04hiredmanso I don't think bringing them up is helpful
16:05lpetitchouser: can you elaborate, I don't know the implementation of clojure.zip very well
16:05chousermost of the public api fns simply turn around and call functions stored in the vector's metadata
16:05Chousukechouser: do you think that was a successful approach?
16:05mwoelkerno I do think multimethods have their uses, but I think in cases like these a different approach might be more viable...
16:05hiredmannope
16:06mwoelkerI actually think protocols might be what I am looking for
16:06chouserChousuke: well, it's immutable, extensible, and seems to have lived up well under a fair amount of use.
16:06lpetithiredman: you seem to have strong thoughts, can you elaborate a little bit more in your answers ?
16:06hiredmanif you reall want objects I recomend something like http://gist.github.com/209514
16:06kotarakchouser: in which way is this better than a multimethod?
16:07lpetitchouser: (real question, I don't have the answer) Had he had protocols at the time, would Rich have implemented clojure.zip with them ?
16:07hiredmanlpetit: protocols apear to be a specialization/optimization on multimethods
16:07chouserkotarak: it probably predates multimethods :-P but besides that, it's just a different solution to similar problems.
16:07lpetitmwoelker: yes, protocols will give atomicity and cohesion to a set of multimethods
16:08mwoelkerlpetit: anywhere I can read up on them?
16:09lpetithiredman: not just a specialization, protocol have the added property of grouping multimethods. But a specialization in the sense that they will be (apparently, and certainly with performance and uniformity in mind) less open in the dispatching area
16:09chouserlpetit: I don't know, but it would seem reasonable. Had he had protocols he would have implemented much of RT and core in them, too. :-)
16:09hiredmanhanding people things that don't exist is not cool
16:09Chousukemwoelker: scroll up your backlog :)
16:09Chousukemwoelker: protocols don't exist yet and anything anyone says about them is subject to change
16:09lpetitclojurebot: protocols
16:09clojurebothttp://clojure-log.n01se.net/date/2009-10-13.html#12:02
16:09Chousukeeven the name :P
16:09kotarakchouser: yeah, there are a lot of relics in Clojure, like .. (double-dot). I would prefer a simple multimethods approach over a (maybe overly) clever metadata approach.
16:09lpetitmwoelker: clojurebot is your best spy/friend :)
16:11hiredmanclojurebot: what does the world need?
16:11clojurebotwhat the world needs is more higher order functions
16:11chousermwoelker: it seems likely to me that there are use cases where something like clojure.zip's approach, or one like javascript's prototype "inheritence", might fit better than anything else that is more commonly used in Clojure.
16:12mwoelkerclojurebot: what is the meaning of liff?
16:12clojurebotHuh?
16:12mwoelkeralmost
16:12lpetithiredman: I guess mwoelker is on the learning curve, and not trying to solve a real problem at hand, that's why I point him to "topnotch" stuff :)
16:12chouserI think one of the features of Clojure (and maybe lisps in general) is that they allow you to easily experiment with alternate solutions to problems like this.
16:13chouserif you can write three functions and suddenly have a new design option, why not try it out?
16:14chouserdon't expect everyone else to start using it of course, but it if makes your life easier then by all means...
16:14chouseractually, lots of dynamic languages provide that feature to some level or other.
16:14mwoelkerlpetit: Learning curve indeed.
16:15lpetitchouser: good point. lisps indeed are about freedom. I should not have said "it's wrong". I should have said : it may be a smell that you're trying to reproduce something from your java background. You may miss a better (or more functional or more idiomatic) solution by doing so. But in the end of the day it's only mwoelker who knows his problem domain best.
16:15lpetitchouser: thank you for reminding us to be modest. (I mean it, really)
16:15chousermwoelker: if you're not yet comfortable with multimethods, I would recommend working with them a bit more.
16:15Chousukemacros are still my favourite feature of lisp
16:15hiredmanwoa, who is being modest?
16:16Chousukeyou don't need them all that often really but when you do you'll be very grateful of them :P
16:16chouserlpetit: yes, of course you're right as well -- it's easy to reach for what you know and miss something that might be better.
16:16Chousukeor rather, when you'd need them in other languages you'll go "graah" and then resign to your fate.
16:17ChousukeOR start writing some code-generating preprocessor.
16:17chousermwoelker: multimethods split apart objects type, type inheritence, object data, and behvaior in a way that provides you a lot of power and flexibility.
16:18Chousukealso you can dispatch on more than the object's type
16:18Chousukehow about the types of all the parameters, for instance?
16:18hiredmanwell
16:18hiredmanjava does that
16:18chouserChousuke: that's why I listed behavior and object type separately. :-)
16:18mwoelkerchouser: it's not really that I feel uncomfortablle with them, I just think they solve a different problem. To solve "my problem" with multimethods would mean annotating the data with extra markers so the multimethod can figure out what actual function to call. "Storing" the function in "slots" in the object itself allows for IMHO a neater solution while also sidestepping possible naming collisions
16:18Chousuke(and not the object itself :P)
16:19hiredmanhttp://www.sics.se/~joe/bluetail/vol1/v1_oo.html <-- "Why OO Sucks"
16:19rstehwienchousuke: I learned ANTLR and read code generation in action because of parts of languages that made me go "graah". ActionScript does that to me daily
16:19lpetitmwoelker: I currently like to think about it as this from less abstract to more abstract: defn -> higher order functions -> multimethods. But indeed I recon I would still be annoyed if I had to do plain "database driven" programming with clojure. Though in database-driven code I've seen in the past (I mean java code), domain graphs generally were very anemic, and the business functions were...
16:19lpetit...methods of "static" (or singleton) service layer classes.
16:20rstehwienchousuke: so I do Clojure (and ruby) on the side to feel better
16:20lpetitmwoelker: of course this was a pity, but it was the reality of what I saw.
16:20chousermwoelker: one of the trade-offs there is that multimethods allow others to add methods on your "types" without touching your objects
16:20ambienthow do i make (map + [[1 2] [2 4]]) into (map + [1 2] [2 4])?
16:20hiredmanambient: apply
16:21ambienti've used map too much that i try to now do everything with it :p ty
16:21rstehwienchouser: I really like multimethods... maybe too much (sometimes an if statement will do).
16:21chouserrstehwien: heh.
16:21rstehwienchouser: next up is abuse of macros :)
16:23chouserrstehwien: you're allowed to abuse macros as much as you want as long as you never ask for help.
16:25mwoelkerlpetit: maybe I am looking at it up from too much of an encapsulation and abstraction standpoint
16:25mwoelkerlpetit: I blame years of C++ and Java ;)
16:27ambienthow can i know in which line in my source code a runtime error happens?
16:27raek(.printStackTrace *e) might be useful...
16:27kotarakambient: look for "caused by" lines. The stacktrace of the bottom one, is near the culprit.
16:27ambientraek nil
16:27chouserhm... without mutation of something you can't change the behavior of a whole class of existing objects. multimethods keep that mutation at the namespace and (one step down ) at the multimethod.
16:28kotarakambient: look also in clojure.stracktrace/print-cause-trace
16:28chouserto do that with prototypes would require mutation at each object that might be used as a prototype, right?
16:28raek(doc *e)
16:28clojurebot"; bound in a repl thread to the most recent exception caught by the repl"
16:29raekambient: or did it occur in an agent?
16:29raekin that case you'll want (agent-errors my-agent)
16:29raekand then (clear-agent-errors my-agent)
16:30ambienti have nothing but functions inside functoins at the moment
16:30mwoelkerchouser: well you could do it as far up in the prototype hierarchy as required
16:30ambientraek emacs C-c C-k
16:30mwoelkerchouser: of course this would not work at runtime which may or may not be a good thing
16:31raekambient: I think I use "the other" emacs mode
16:31raekC-c C-k is not bound for me
16:31mwoelkerchouser: of course you can always add another layer of indirection
16:33hiredmanclojurebot: literal [0] problem
16:33clojurebot<reply>"There is no problem in computer programming which cannot be solved by an added level of indirection." -- Dr Maurice Wilkes
16:35lpetithiredman: what did you mean by "java does that" ?
16:36hiredmanlpetit: java dispatchs on object type and argument type
16:38lpetitmwoelker: I also have the samel feeling, something along those lines = If I use clojure on a big project, and follow what 'seems' to be the convention to just use keywords on maps as the sole way to access data slots, wouldn't I, at some point of the project, face a wall for not having encapsulating the slot access ?
16:38lpetits/encapsulating/encapsulated/
16:39lpetithiredman: I don't think so ? java dispatches on object type at runtime, but it does not dispatch on argument type at runtime. This one is the stuff of the compiler, isn't it ?
16:39lpetithiredman: that's why there are books and blog posts about the Visitor pattern, when you can do that so easily with multimethods in clojure or generic functions in CLOS ?
16:40mwoelkerlpetit: not only big projects, libraries as well. This might be a neat way to hide implementation details (like: is this value stored or computed) and allow for producers of library to perform updates while staying backward compatible
16:41hiredmanlpetit: in java a method that takes a String is different from a method that takes an Integer
16:42hiredmanso, void add (String a) {} and void add (Integer i) {}
16:42lpetithiredman: but the choice of calling void add (String a) {} or void add (Integer i) {} is done at compilation time.
16:42mwoelkerhiredman: yeah but which method gets called is decided at compile time
16:43hiredmanso?
16:43hiredmanit's still selected via the argument types
16:43mwoelkerthe thing is if you only have an Object at hand (which may be either an Integer or a String) the compiler will complain
16:43mwoelkerObject=Object reference
16:43lpetithiredman: so if you have A extends B and in a class void something(A a) [} and void something(B b) {} the compiler will choose the method not on the real dynamic type of the arg that is passed, but based on the declared type of the variable definition of the argument that is passed
16:44hiredmanso?
16:45hiredmandispatch is still via argument type
16:45lpetithiredman: so argument dispatch is not available at runtime in java.
16:45hiredmanstatic, dynamic, whichever
16:45lpetithiredman: the difference is big
16:45hiredman13:42 hiredman : lpetit: java dispatchs on object type and argument type
16:46hiredmanI understand that the difference is big
16:46hiredmanbut the fact remains, java dispatches on object type and argument type
16:47lpetithiredman: if you want, I'm bored by this no-end discussion, and it's late here, so 'night
16:48lpetithiredman: but still, I consider the discussion was not about compilation dispatch, but really about runtime dispatch. You're playing with words
16:49hiredmanwell, nice of him to leave
16:50hiredman~botsnack
16:50clojurebotthanks; that was delicious. (nom nom nom)
16:52ambientif d is a sequence this gets a bit difficult: (reductions (fn [y [x1 x2]] (* d (+ y (- x1 x2)))) 0 (partition 2 1 coll)))
16:53hiredman(apply * (+ y (- x1 x2)) d)
16:54hiredman(reduce * (+ y (- x1 x2)) d)
16:54hiredmanetc
16:54ambientit's all lazy
16:54hiredmanwell, * is not lazy
16:54ambientthat's why it gets difficult
19:12Dawgmatixwhats the recommended way to parse xml in clojure ?
19:17hiredmanDawgmatix: clojure.xml/parse
19:17Dawgmatixcool thanks :)
19:22Dawgmatixis there someway to modify the classpath from the slime repl ?
19:22clojurebotclasspath is (System/getProperty "java.class.path")
19:23hiredmanDawgmatix: there is add-classpath, but it is best not to get into the habit of using it
19:23Dawgmatixi am coming from a lisp background and just trying to wrap my head around what the development cycle looks like for clojure
19:24piccolinoIs there something like a 1.0 release of clojure-contrib?
19:24hiredmanrepl -> repl -> repl -> repl -> repl -> store -> repl
19:24hiredmanthere is a 1.0 compat branch of contrib
19:25piccolinoBut doesn't that change as development happens?
19:25DawgmatixSo if i want to use something like compojure, i add the directory to my actual classpath ?
19:25Dawgmatix(in my ~/.bashrc ? )
19:25hiredmanpiccolino: yes
19:25hiredmanDawgmatix: depends
19:26hiredmanmy classpath is "/home/kpd/*.jars"
19:26hiredmaner
19:26hiredmanmy classpath is "/home/kpd/.jars/*"
19:26piccolinoHm. I'm trying to make a portfile for clojure-contrib, but I think I need some sort of zip file I can download for it (total macports amateur, though).
19:26Dawgmatixis there a startup file that clojure reads that I can use to set classpaths and do random other inits (for example (use ... ) statements)
19:27hiredmanby the time clojure loads, the jvm is already running
19:27hiredmanyou can use some kind of script or what have you
19:27Dawgmatixoic - and the classpath isnt thought of as a dynamically changeable entity ?
19:28hiredmanclasspaths are, I belive, a property of ClassLoaders
19:28Dawgmatix(sorry if these are dumb questions, i am as much a java noob as i am a clojure one)
19:28hiredmanand you cannot muck with the system classloader, you can do stuff like spin off your own classloader, but that can lead to issues
19:29Dawgmatixi see, so in short its better off to just have a jar folder like yours
19:29hiredmantechnomancy has some setup where he just unpacks the jar files
19:29hiredman*shrug*
19:30hiredmanthe jar directory approach has some issues to, classpaths with wildcards like only work with 1.6+ jvms
19:30hiredmanbut you can always just write a bit of code to generate a classpath from a bunch of jar files
19:31hiredmanyou can also do CLASSPATH="./libs/*" which is hand for a project specific classpath
19:31DawgmatixI see.
20:29froogis there a unit testing framework that is still in active development?
20:36jhawk28junit?
20:36jhawk28define active development
20:37chouserfroog: clojure.test is in clojure proper now, and all clojure's own tests us it
20:38chouserused to be test-is
20:41Dawgmatixis there any documentation for compojure ? i cant seem to find any on github ?
20:42froogjhawk28: it's just that fact states: "no longer in active dev", so that doesn't seem like the right tool to start using :)
20:42Dawgmatixalternatively are there other competing web frameworks ?
20:43froogchouser: thanks, will look into it
20:44jhawk28froog: junit is stable and doesnt need active dev (they did just release 4.7 in august)
20:45froogjhawk28: I thought that was for java
20:46chouserfroog: I have a set of test written in clojure for junit so that they can plug into the junit runner suite at work.
20:47mroweDawgmatix: there's also conjure, which is pretty much a line-by-line clones of Rails
20:48mroweDawgmatix: and I believe there's a newer one, cascade, but I don't know anything about it
20:48DawgmatixI see.
20:50chouserhow much framework do you want? I'm using (a small part of) ring and like it very much so far.
20:50DawgmatixI just want basic url routing
20:51froogchouser: ok, I just wanted something simple, but maybe junit is simple.
20:51mroweDawgmatix: sounds like compjure is what you want... there's a draft tutorial on the mailing list that should help get you started
20:52mroweDawgmatix: http://groups.google.com/group/compojure/browse_thread/thread/3c507da23540da6e
20:52Dawgmatixthanks :)
20:53chouserfroog: I'd recommend you look at clojure.test. I mentioned junit only because it can be used, but it's a bit of a pain -- worth it only if using it buys you something else (like integration)
20:53froogjhawk28: thanks for pointing out junit.
20:53chouserring and multimethod gets you very simple url routing. *very* simple
20:58froogchouser: yes, clojure.test looks very much like what I want
22:57tomojmaybe something is wrong with my brain. I can't figure out how to convert a char to a byte/int/whatever so I can do bit-test on it
22:57hiredman,(int \a)
22:57clojurebot97
22:57hiredman,(-> \a int byte)
22:57clojurebot97
22:57tomojah
22:57tomoj,(byte \a)
22:57clojurebotjava.lang.ClassCastException: java.lang.Character cannot be cast to java.lang.Number
22:57tomojwhy doesn't that work?
22:58tomojchars are too big I guess?
22:58hiredmana Character cannot be cast to a Number
22:58hiredmannah
22:58hiredmanI am pretty sure chars can be cast to ints no problem
22:58clojurebotPeople have a problem and think "Hey! I'll use a regular expression!". Now they have two problems....
22:58hiredmanclojurebot: everybody!
22:58clojureboteverybody looks good in a sheinhardt
22:58tomojyep, just not bytes
22:58hiredmanwell, and int can be cast to a byte
22:59tomojright, but why not straight to byte?
22:59hiredmanthe issue is, bascially, boxing
22:59tomojah well, int will work fine for me anyway
23:00tomojthanks
23:03danlarkin<3 30 rock
23:04hiredman:D
23:10tomojthis is profoundly ugly :( http://gist.github.com/223d4f377d4b3e7d6dab
23:10tomojmaybe I need to stop coding and go to sleep
23:11tomojproblem is to convert a (positive) integer to a big-endian two's complement string, so you have to add a 0x00 char if the leftmost bit is 1, and for 0 you're supposed to return 0x00, not just ""
23:11hiredman:(
23:12tomojI wonder why the hell they use two's complement when all the integers are positive
23:12tomojmaybe btwoc is a standard function elsewhere?
23:12hiredmanhmmm
23:13hiredman,(.getBytes "foo")
23:13clojurebot#<byte[] [B@265e47>
23:13danlarkin,(seq (.getBytes "foo"))
23:13clojurebot(102 111 111)
23:13hiredman,(-> "foo" .getBytes ((partial map int)))
23:13clojurebot(102 111 111)
23:14danlarkinI like mine
23:14danlarkin:-p
23:14tomojthat's backwards
23:14hiredman,(-> "foo" .getBytes ((partial map int)) ((partial map #(Integer/toBinaryString %))))
23:14clojurebot("1100110" "1101111" "1101111")
23:15tomojthough I'll have to do that eventually too
23:15hiredman,(-> "foo" .getBytes ((partial map #(Integer/toBinaryString %))))
23:15clojurebot("1100110" "1101111" "1101111")
23:18danlarkin,(map #(Integer/toBinaryString %) (.getBytes "foo")
23:18clojurebotEOF while reading
23:19danlarkin,(map #(Integer/toBinaryString %) (.getBytes "foo"))
23:19clojurebot("1100110" "1101111" "1101111")
23:19hiredman:(
23:19danlarkinso much less complicated
23:19hiredmanparens are not complicated
23:20hiredmanactually
23:20hiredman,(->> "foo" .getBytes (map #(Integer/toBinaryString %)))
23:20clojurebot("1100110" "1101111" "1101111")
23:20hiredman:D
23:31durka42(doc ->>)
23:31clojurebot"([x form] [x form & more]); Threads the expr through the forms. Inserts x as the last item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the last item in second form, etc."
23:31durka42(doc ->)
23:31clojurebot"([x form] [x form & more]); Threads the expr through the forms. Inserts x as the second item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the second item in second form, etc."
23:41tomoji uinai mi manci na'e jimpe la'oi ->> doi durka
23:44durka42tomoj: clojure does that :)
23:45durka42it makes sense when you look at what hiredman gave ->> as an alternative to
23:45tomojI will have to play around with it sometime
23:47durka42i hadn't seen ->> before, is it in the standard core or is it a clojurebot original (tm)?
23:47hiredmanit was added to the core sometime is last month or so
23:49rboydwhat's that operator called? arrow operator?
23:53arbscht_-> and ->> are 'threading'
23:54hiredman'awesome'
23:54arbscht_:)
23:54hiredmanalso the thrush combinator