#clojure logs

2010-10-24

01:03defnoh my god. so much email to catch up on post-conj
02:01woobydefn: sup!
04:51_ulisesmorning
05:50_uliseshow can I reset an ns so that I don't get illegal bindings?
06:54raek_ulises: either (in-ns 'some-other-ns) (remove-ns 'the-ns) or (ns-unmap 'the-ns 'conflicting-var)
07:54_ulisesraek: thanks
08:10uliseswhy am I getting 'unmatched delimiter )' here: http://paste.lisp.org/display/115855
08:10ulises:(
08:14MayDanielulises: The metadata needs to come before the namespace.
09:07raek_ulises: also, it is possible to do it like this: lastfm-clj.core
09:07raekeh
09:07raek(ns lastfm-clj.core "Core functions for lastfm-clj" {:author "Ulises Cervino Beresi"} ...)
09:41bytesourceHi all! I am currently reading the chapter on HBase of 'Clojure in Action'. I downloaded HBase but have no idea of how to install it on Linux. I couldn't find a simple manual either on the web. Does anybody know how to do the install? I am using Leiningen and Emacs.
09:46kumarshantanuubuntu has apt-get for HBase/Hadoop?
09:48tomojno
10:02ulisesMayDaniel: thanks
10:32SweetsharkHow do I access the static "class" member of a class object, i.e. what I write "Object.class" in Java returning the type?
10:33_ulises-I believe it's class
10:33_ulises-,(class "foo")
10:33clojurebotjava.lang.String
10:33tomoj,String
10:33clojurebotjava.lang.String
10:33_ulises-oh, wait
10:33_ulises-(,String/class)
10:33_ulises-,(String/class)
10:33clojurebotjava.lang.NoSuchFieldException: class
10:34_ulises-,String/class
10:34clojurebotjava.lang.Exception: Unable to find static field: class in class java.lang.String
10:34_ulises-hrm
10:34tomoj,(class String)
10:34clojurebotjava.lang.Class
10:34kumarshantanu,(String/getClass)
10:34clojurebotjava.lang.NoSuchFieldException: getClass
10:35tomojSweetshark: (just write "Object")
10:35kumarshantanu,(.getClass "Whatever")
10:35clojurebotjava.lang.String
10:37Sweetsharktomoj: actually (class String) looks like what I want ...
10:41Sweetsharkmeh, not quite ... but (Class/forName "java.lang.String") should do for now ...
10:43_ulises-Sweetshark: what are you trying to do anyway?
10:44Sweetshark_ulises-: http://api.openoffice.org/docs/java/ref/com/sun/star/uno/UnoRuntime.html#queryInterface%28java.lang.Class,%20java.lang.Object%29
10:44tomojSweetshark: what?
10:44tomoj,(= (Class/forName "java.lang.String") String)
10:44clojurebottrue
10:44tomojjust write "String"...
10:45_ulises-right
10:48rdeshpandeanyone else having issues getting labrepl to 'lein deps'?
10:50Sweetsharktomoj _ulises-: well it parses of the repl, thanks so far ...
10:52_ulises-rdeshpande: I've cloned a fresh labrepl and doing lein deps as we speak
10:52_ulises-so far, no issues
10:57_ulises-rdeshpande: right, lein deps has finished without issues, what issues are you encoutering? what arch? which version of labrepl? etc.
11:03defnhey all
11:06_ulises-hey defn
11:08rdeshpande_ulises-: im seeing this http://pastie.org/1245060 - but where is 1.2.0beta1 coming from? i dont' see 'beta1' anywhere grepped in the repo. shouldn't it just be getting 1.2?
11:09raekhttp://build.clojure.org/releases/org/clojure/clojure/ it exists here
11:09_ulises-this is what I have on my project.clj: http://pastie.org/1245065
11:09_ulises-see if there's anything different with yours?
11:10maravillasperhaps it's a transitive dependency
11:12rdeshpande_ulises-: nope, same exact ting
11:12maravillasis your labrepl up to date?
11:12rdeshpandeyep
11:12rdeshpandejust cloned
11:12_ulises-rdeshpande: tried pulling from ... oh
11:13_ulises-I can also see you're on OS X, like me :/
11:13maravillashm, i just grabbed its deps and got 1.2, not beta1
11:13maravillasoh, nevermind
11:13_ulises-same for me
11:13maravillasit's a dev-dep
11:13rdeshpandecould it be something in my home dir?
11:13maravillaseither autodoc or swank-clojure must depend on it
11:14maravillasregardless, though, i was able to grab it
11:14rdeshpandehmm
11:14rdeshpandevery odd
11:15maravillashm, nope
11:15maravillaswell, that's beside the point anyway
11:15maravillasactually, i bet i had mine cached locally
11:18_ulises-rdeshpande: I suppose that telling you to start afresh is pointless?
11:19rdeshpandenot sure how much fresh it could be :/
11:19rdeshpande*how much more
11:19_ulises-did you *just* do a clone?
11:19_ulises-I did mine when you asked the question actually
11:20defnCan someone refresh my memory on :use in the (ns) macro
11:20defnspecifically how to use :as with :use
11:20maravillas_ulises-: the latest isn't working for me either, after i deleted the cached copy in ~/.m2
11:21defn(:use clojure.contrib [io :as foo])
11:21_ulises-maravillas: oh :(
11:22_ulises-what about leiningen? do you have the latest version?
11:22maravillasi don't understand why, unfortunately, since beta1 is still available on the build site
11:27maravillasrdeshpande: as a workaround, you could try downloading clojure-1.2.0-beta1.jar, .jar.sha1, .pom, and .sha1 from http://build.clojure.org/releases/org/clojure/clojure/1.2.0-beta1 and putting them in ~/.m2/repository/org/clojure/clojure/1.2.0-beta1
11:27maravillasit's not the right answer...someone else might have more insight
11:32woobydefn: http://gist.github.com/284277
11:32KLllguys
11:33KLllI have a vector
11:33KLll(def some-vec [1 2 3])
11:33KLllwhat's the best way to modify it
11:33defnwooby: !!
11:33_ulisesKLll: you don't?
11:33KLll(def some-vec (assoc some-vec 2 3))
11:33KLllor what?
11:33defnwooby: you sir, are a saint
11:34_uliseswhy do you need to modify it?
11:34KLllI want to add to it
11:34KLllor change it
11:34KLllfor instance I have a vector of maps or listeneres to events
11:35_ulisesassoc is possibly what you want
11:35woobyKLll: in clojure the modification of things by re-deffing them is discouraged, there are special types for handing variables that can change over time. atom is probably the one you should check out
11:35KLlladding a listener requires changing a map, then associng that map into the vector, then I have to rebind the vector
11:35_uliseskeep in mind that if you do (assoc [] 1 1) you'll get out of bounds exceptions
11:35_ulisesalso what wooby said
11:35wooby(def my-vec (atom [1 2 3]))
11:36woobyKLll: http://clojure.org/atoms
11:37woobyi now giggle every time i see fib used as an example anywhere
11:38maravillasit's now possible to reference fib ironically
11:39KLllthe thing is
11:39kumarshantanuis it possible to access clojure.repl/source in code? (instead of REPL)
11:39KLllin nearly every program I have some state
11:39kumarshantanu,(source source)
11:39clojurebotjava.lang.Exception: Unable to resolve symbol: source in this context
11:39KLllthat changes
11:39KLllso the atoms are the way to do it?
11:39kumarshantanu,(clojure.repl/source source)
11:40clojurebotSource not found
11:40raekkeyword args question: if I do a (foo :a 1 :b 2) call, I want to get 'options' bound to {:a 1, :b 2}. is (defn foo [& {:as options}] ...) the correct way to do that?
11:40woobykumarshantanu: (use 'clojure.contrib.repl-utils) (source atom)
11:41raekor, I guess my question is "when does function arguments automagically become maps="
11:41woobyKLll: not always - there are also refs and agents
11:41KLllhow do you decide between using an atom and using a ref
11:42raekKLll: refs are for when you might need to coordinade changes of multiple refs
11:42raekwith atoms, you can't do that
11:42KLllI see that
11:43raekso, if you have something internally that only you use, (like a counter or something) you could use an atom
11:43raekbut when others need to use it too, it might be better to use refs to be on the safe side
11:44woobygood screencasts that cover the use cases for refs/atoms/agents: http://www.pluralsight-training.net/microsoft/olt/course/toc.aspx?n=clojure-concurrency-tutorial
11:44bmhdoes clojure have a function like Haskell's zip or zipWith? (map over two collections simultaneously)
11:45opqdonut,(map + [1 2 3] [4 5 6])
11:45clojurebot(5 7 9)
11:45bmhoh. That's convenient.
11:45opqdonut,(map vector [1 2 3] [4 5 6])
11:45clojurebot([1 4] [2 5] [3 6])
11:46woobybmh: there's also zipmap
11:46opqdonutwhich is mostly unrelated
11:46woobydoes the haskell thingy not return a map?
11:46bmhit doesn't
11:47woobyah
11:47raekzip returns tuples
11:47bmhThe type of zip is: [a] -> [b] -> [(a,b)]
11:47woobyignore me :)
11:47opqdonuthaskell's zip does what map vector does
11:47opqdonutzipWith does what clojure's map does
11:48bmhsometimes I think programming in clojure would be easier if I didn't know scheme/haskell
11:48bmhI'd have read the manual.
11:54KLllhi
11:56KLllsup
11:56TheAnimal4Yo yo yo KLll
12:01defnwooby: fib is important to programming
12:01defnfactorial is also really important to what we do everyday.
12:02defnthinking out loud: im not sure what i'd do if i didnt have factorial, probably just code hello world over and over
12:03rdeshpandebmh: what is your impression so far coming from haskell?
12:04bmhrdeshpande: from scheme might be a little more fair. I really dig the loop-recur construct
12:04bmhmultimethods are wonderful
12:07defni like functions :D
12:07_ulisesI recently found a use for protocols ... go figure :D
12:07defnim making a conscious effort post-conj to use some more protocols in my code
12:07_uliseswell, more like I just came across a case where I thought "thank god for protocols"
12:08defnchouser's finger tree code makes some nice use of protocols
12:09jarpiainOk, my port of the clojure compiler into clojure seems now capable of compiling itself. Time to release :)
12:09jarpiainhttp://github.com/jarpiain/cljc
12:09bmhrdeshpande: I think the interop is my favorite feature. At the absolute worst, it makes clojure as good as java.
12:09bmhPraise be to Technomancy for giving us Lein.
12:09defndon't forget the cake :)
12:10gfrlogclojure is not as good as java at worst
12:11gfrlogit lacks most of the static benefits
12:11defnif i wanted to use statics i wouldnt be using clojure in the first place
12:11opqdonutwhy not
12:12defni want a dynamic language.
12:12gfrlogmy point was that if I'm going to resort to using clojure by just calling java, I'll get a lot more benefit out of using java as java
12:12opqdonutclojure could be a great dynamic language with optional static features
12:12opqdonutcommon lisp is quite good at being both static and dynamic
12:12defngfrlog: it depends.
12:12bmhI want a type system ;-)
12:13gfrlogdefn: what do you mean?
12:13bmhIt's absurd that the jvm doesn't support tco
12:13gfrlogbmh: it makes sense to me, assuming they designed it for java
12:13defngfrlog: it depends on what you care about. if you're only concerned with the benefits of statics then okay, but who the heck cares about just one thing?
12:14defni want an expressive language. i want maintainable code.
12:14bmhgfrlog: Not in the slightest. Java is an OO language. You program in an OO language by calling methods.
12:14gfrlogdefn: nobody of course, but static benefits are huge
12:14gfrlogdefn: I'm assuming a hypothetic world (i.e., "at worst") where the best use you can make of clojure is to pretend it's java using the interop
12:14bmhgfrlog: If you don't have tail-calls, eventually your method calls smash the stack. Therefore, you can't write OO java!
12:14KLllI find my code less maintainable in clojure
12:15defngfrlog: yeah, in the real world things are a bit different ;)
12:15gfrlogbmh: clearly you can -- you use for loops instead of recursive algs
12:15gfrlogdefn: they are. I spend too much time on theory sometimes.
12:15KLllany recursion can be changed into iteration
12:15somniumbmh: have you read GVR's manifesto against tail calls and fp in general?
12:15kumarshantanuany CCW user here?
12:16bmhsomnium: I did. I don't think much of him.
12:16bmhsomnium: Have you read Xavier Leroy's rants about kernel threads in Ocaml?
12:16defnwho is GVR
12:16defnoh... nvm
12:16bmhGuido
12:16defnguido
12:16defnif you have a link ill entertain it :)
12:16somniumbmh: I have not. I just wanted to mention my amazement that a language designer would be openly hostile to such fundamentally useful features
12:17bmhsomnium: I think Guido is a turd.
12:17defnsomnium: the human condition sucks
12:17defnyou make a decision so you have to hate all other decisions or something
12:17defnit's ludicrous
12:18gfrlogsunk cost fallacy
12:18gfrlogor something similar
12:18_ulisesperhaps larry wall is the king of inflammatory remarks
12:18bmhXavier is a bit of a different story. Fire up your favorite GNU/Linux distro and type 'man pthread'
12:18defnperhaps larry wall is the worst speaker i've ever seen
12:18bmh"linuxthreads-0.10 by Xavier Leroy", it makes his opposition to kernel threads seem slightly less insane
12:18gfrlog$ man pthread
12:18bmhdefn: I agree entirely.
12:18gfrlogNo manual entry for pthread
12:18bmhpthreads, sorry
12:18defnbmh, did we meet yesterday?
12:19gfrlogmuch better
12:19bmhdefn: We didn't.
12:19defnheh sorry -- im trying to do post-conj association
12:19defnso many twitter handles and nicks and names in my head atm
12:19bmhI last saw Larry Wall speak in... 2007?
12:19gfrlogI was that guy sitting in one of the chairs
12:19defngfrlog: omg. same.
12:20gfrlogdefn: damn, we should've talked
12:20defni know. next time you're at a conference talk to the guy in the chair, that'll be me.
12:20gfrlogokay
12:20defnunless he's not, in which case: keep trying.
12:20gfrlogtwo or three tries max I'm sure
12:21defnthe sarcasm is palpable
12:21gfrlogand sticky
12:21defnindeed. *investigates the palp closely*
12:22defnas in palpus
12:22bmhDoes clojure have a function like "conj-with" for shoving things into a map? (i.e. If a key already exists, then use some function to combine the values)
12:22_ulisesbmh: merge-with
12:22_ulises,(doc merge-with)
12:22clojurebot"([f & maps]); Returns a map that consists of the rest of the maps conj-ed onto the first. If a key occurs in more than one map, the mapping(s) from the latter (left-to-right) will be combined with t...
12:23defnwill be combined with the mapping in the result by calling (f val-in-result val-in-latter).
12:24KLllHi
12:24TheAnimal4Greetings KLll
12:24KLllmy greeter bot :P
12:24defnepic.
12:24defnHi
12:24TheAnimal4Greetings defn
12:24KLll:P
12:24gfrlogclojurebot: hey
12:24clojurebothey is for horses
12:25bmh_ulises: sure, but merge with noms a pile of maps, oh, I guess it'll work
12:25KLllhello
12:25TheAnimal4Greetings KLll
12:25KLllsup
12:25TheAnimal4Yo yo yo KLll
12:25_ulisesbmh: you can always use {} as one of the maps
12:25_ulisesbmh: I suppose you could also use reduce?
12:26defnheh -- any new language, if it wants to be successful, needs to have a separate channel for the inevitable irc bot experimentation that will occur
12:26_ulisesI'm not familiar with conj-with unfortunately
12:26KLllnext up: let's plug it into Warhammer item database so it will quote stats into the channel :P
12:26bmhKLll: why don't you write a bot that finds arbitrage opportunities in Warhammer? ;-)
12:26KLllmaybe I should look into some textual analysis
12:27defnlinkparser maybe?
12:27KLllso it picks out buzzwords out of random chat
12:27KLllthen repeats statements about that buzzword from weeks ago
12:27defn"web 2.0", "agile", etc.
12:27KLllthat would troll many people
12:28defnset up some future/promise or agent type thing that, when someone responds, tells them in no uncertain terms they have been trolled
12:28KLllhahahah
12:29defnthere's this hillarious library for clojure that generates business BS, like "synergizing business ROI with gold futures"
12:29defnerr for ruby, it's called "faker"
12:30KLllsomething like that
12:30KLllI recall a channel where they had a bot named
12:30KLllgothgirl19
12:30KLllor something like that
12:31KLllit regurtiated back statements converted into questions
12:31defnheh yes ive seen that trolling mechanism in action -- i used to know someone who did a similar thing with a bot named "cutie5484"
12:31KLllwhen they looks at chat logs there were a surprising amount of people trying to pick up the bot and talking to the bot for hours
12:32kumarshantanuis it possible to get the name of a function as string? map? --> "map?"
12:32defnsure
12:33gfrlogum
12:33gfrlogreally?
12:33kumarshantanudefn: how?
12:33gfrlogis it in the metadata?
12:33somniumkumarshantanu: from the runtime representation?
12:33defnthere are a few ways
12:33defn,(str (:name (meta #'and)))
12:33clojurebot"and"
12:34kumarshantanu,(str (:name (meta map?)))
12:34clojurebot""
12:34KLllwhy the #'?
12:34defninteresting...
12:34KLllisn't ' enough??
12:35gfrlog'(let [my-fun vector?] (str (:name (meta #'my-fun))))
12:35KLll,(str (:name (meta 'map?)))
12:35clojurebot""
12:35gfrlog,(let [my-fun vector?] (str (:name (meta #'my-fun))))
12:35clojurebotjava.lang.Exception: Unable to resolve var: my-fun in this context
12:35gfrlogI suck at commas
12:35defn,(meta 'map?)
12:35clojurebotnil
12:35defn,(meta #'map)
12:35clojurebot{:ns #<Namespace clojure.core>, :name map, :file "clojure/core.clj", :line 2079, :arglists ([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & colls]), :added "1.0", :doc "Returns a lazy sequence consisti...
12:35gfrlog,(let [my-fun vector?] (str (:name (meta my-fun))))
12:35KLll,(str (:name (meta #'map?)))
12:35clojurebot""
12:35clojurebot"map?"
12:35defnthere ya go :)
12:35KLll,(meta 'map)
12:35clojurebotnil
12:35defnthere's another way too but im failing to remember it
12:36KLllseriously, what's the difference between ' and #'
12:36raek,(class 'conj)
12:36clojurebotclojure.lang.Symbol
12:36raek,(class #'conj)
12:36defnquote, var quote
12:36clojurebotclojure.lang.Var
12:37kumarshantanuhow do I #" inside a macro?
12:37defnKLll: #' is var quote, ' is quote
12:37somniumah, map? is defined with `def', not `defn', so I guess the metadata doesn't get attached to the function object?
12:37raekthe metadata usually go on the var object rather than the fn object
12:37KLllcould be
12:38raekbut since 1.2, fns can have metadata too
12:38defn,(meta #'map?)
12:38clojurebot{:ns #<Namespace clojure.core>, :name map?, :file "clojure/core.clj", :line 149, :arglists ([x]), :doc "Return true if x implements IPersistentMap", :added "1.0"}
12:38somniumI think defn commutes the metadata now
12:38somnium,(meta map?)
12:38clojurebot{:line 153}
12:38defngotta var quote
12:38kumarshantanudefn: how can i var-quote inside a macro?
12:39defnkumarshantanu: i have code somewhere, one sec
12:39kumarshantanu#'~fn-name
12:39woobyjarpiain: re: compiler, neat!
12:39somniumdefn: if you don't know the name it's hard to var-quote :P
12:39KLlldoes clojure have date stuff, or do I have to use java.util.Date?
12:39defn;)
12:39raekkumarshantanu: it is not known at macro expansion time what var the symbol fn-name will refer to
12:39defnsomnium: oh right
12:40raekKLll: clj-time is a neat lib (a wrapper for Joda time)
12:40raekjavas date classes are a mess
12:40defnno doubt
12:41KLllnot really once you use GregorianCalendar :P
12:41raekjoda time makes the dates immutable, so they work pretty well with clojure
12:41KLllI really like the mutators on GregorianCalendar
12:41KLllthey are really neat
12:42defnim outta here, folks
12:42raekkumarshantanu: if you have the symbol foo and want "foo", you can simply use the function 'name'
12:42raek,(name 'foo)
12:42clojurebot"foo"
12:43kumarshantanuraek: I am passing a function to a macro, and want to find out the name inside that macro
12:44defnkumarshantanu: where does the function come from
12:44defnwhat if you get an anonymous function?
12:44raekkumarshantanu: the fn object itself does not know wich names are bound to it
12:44kumarshantanuactually I am trying to diagnose some defects -- so the macro asserts few values and then (should) tell which function failed -- so I need the name
12:45raeka macro could of course look at the unevaluated argument and if it is a symbol, treat that as the name for it
12:45somnium,(meta (resolve 'map?))
12:45clojurebot{:ns #<Namespace clojure.core>, :name map?, :file "clojure/core.clj", :line 149, :arglists ([x]), :doc "Return true if x implements IPersistentMap", :added "1.0"}
12:45KLll(re-find #"time" "don't have time")
12:45KLll,(re-find #"time" "don't have time")
12:45clojurebot"time"
12:46raekkumarshantanu: you could store the unevaluated argument. in that case, you get the code for the expression that failed
12:46somnium,(let [fname 'map?] `(prn ~(meta (resolve fname))))
12:46clojurebot(clojure.core/prn {:ns #<Namespace clojure.core>, :name map?, :file "clojure/core.clj", :line 149, :arglists ([x]), :doc "Return true if x implements IPersistentMap", :added "1.0"})
12:46somniumkumarshantanu: perhaps that will work?
12:47kumarshantanuAH! got it -- (:name (meta (resolve (quote ~f?))))
12:48kumarshantanuf? is the function name the macro accepts
12:50kumarshantanusomnium: raek: thanks
12:50KLll!time
12:50somniumkumarshantanu: cheers
12:50KLll!time
12:53KLll!time
12:53UpperI need a help here pleaseI can't find the error - http://pastebin.com/JvZgH1E7
12:54Upperwas created a loop/when to print a different message in each iteration
12:55KLllso if I do (defn fun1 ....)
12:55KLllthen make some vector [fun1]
12:55KLlland then re-def it (defn fun1 something else ...)
12:55KLllthe vector now holds the old one ?
12:56KLll!time
12:56TheAnimal4Time is java.util.GregorianCalendar[time=1287939389109,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Europe/Prague",offset=3600000,dstSavings=3600000,useDaylight=true,transitions=141,lastRule=java.util.SimpleTimeZone[id=Europe/Prague,offset=3600000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,startDayOfWeek=1,startTime=3600000,startTimeMode=2,endMo
12:56raekUpper: you don't have any call to recur
12:56KLlloops :P
12:57raekUpper: see http://clojure.org/special_forms#Special%20Forms--%28recur%20exprs*%29
12:58Upperhm right
13:01raekUpper: the basic code building block of a functional programming language is an expression, not a statement
13:01raek(+ 2 i) means take i and add two and return that. it does not change i
13:14kumarshantanuis it a bug that pos? throws exception on nil?
13:15kumarshantanu,(pos? nil) ; expected false, right?
13:15clojurebotjava.lang.NullPointerException
13:15gfrlog,(pos? "haha I'm a string")
13:15clojurebotjava.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number
13:15gfrlog,(num nil)
13:16clojurebotnil
13:39riddochcAnybody got suggestions for decent reading material to understand Java IO, nio, netty, etc. from a Clojure context? Got a little project I'm playing with, and aleph seems nicely suited to it, but I'm running up against a pretty steep learning curve here.
13:41riddochcI suspect non-Clojure contexts would do, too, since I'm familiar enough with the Clojure side of things to be able to translate it... but I'm not very familiar with the Java APIs, and they seem tremendously more complicated than I would've expected.
13:47rhudsonriddochc, I suspect you'd do well to start with the netty documentation.
13:47rhudsonI don't think you really have to understand the details of nio (thankfully!) to grok netty
13:48rhudsonAll you really need to know about nio to start with is that the asynch stuff is based on the OS select
13:49riddochcrhudson: Hm. I'll try reading it again, then.
13:49riddochcrhudson: Is it just me, or does everything seem to assume that a protocol will be layered on top of HTTP?
13:50rhudsonSeems the way of the world these days...
13:50rhudsonThe advantage is that the server only needs to open ports 80 & 443
14:00KirinDaveHey
14:00gfrloghi
14:00KirinDaveEarlier someone had been linking some new screencasts to all different parts of clojure
14:00KirinDaveLike several on vars, several on refs, etc
14:00KirinDaveDoes anyone still have that link? I lostit
14:01maravillasthe full disclojure screencasts?
14:01raekthis one? http://www.pluralsight-training.net/microsoft/olt/course/toc.aspx?n=clojure-concurrency-tutorial
14:01maravillashttp://vimeo.com/channels/fulldisclojure
14:01KirinDaveraek: Those, idneed.
14:01KirinDaveThanks
14:01raekKirinDave: this is a goldmine: http://alexott.net/en/clojure/video.html
14:02KirinDaveDang
14:02KirinDaveThat's solid.
14:03TakeVWhat is exactly meant by "synchronous" and "unsynchronous" when talking about the difference between refs and atoms? And coordinated for that matter.
14:04gfrlogI can explain it after this chess game
14:05TakeVSure. :)
14:05KirinDaveSo my webmachine->clojure port is in basic working order.
14:05KirinDaveIt doesn't handle everything and the tests aren't there, but I'm considering open sourcing it.
14:05gfrlogcrap I lost
14:05KirinDaveI'm not sure if I should do so today or tomorrow.
14:06KirinDaveLike today is the tail-end of the conj, so...
14:06gfrlogTakeV: refs and atoms are both synchronous, so I think that issue should only come up when comparing either to agents
14:06gfrlogdoes that sound right?
14:06KirinDavegfrlog: Yeah
14:07TakeVgfrlog: I'm not sure what that term means, though. Likewise when discussing if they are coordinated or not.
14:07gfrlogTakeV: okay, so a for the synchronous ones (refs/atoms)
14:07KirinDaveTakeV: Where did you see this?
14:08gfrlogthey are evaluated in the current running thread, so your code doesn't proceed until the expession is finished evaluating
14:08gfrlogin contrast, when you send a function to an agent, the (send) call returns immediately, and the function gets evaled later on some other thread
14:09gfrlogso that's the sync/async distinction -- did it make sense?
14:09TakeVIt does. Sounds somewhat like how locking works.
14:09gfrlogI think the explainer part of my brain is a bit muddled
14:09KirinDaveTakeV: While it might involve locks, that's not what's going on
14:10KirinDaveTakeV: Agents receive work queues.
14:10KirinDaveTakeV: Atoms and refs do not.
14:10KirinDaveTakeV: Agents work in the threadpool, atoms and refs do not
14:10gfrlogthe fns sent to atoms and refs get evaled immediately while your thread execution waits
14:11TakeVWhat about coordination?
14:11gfrlogonly refs are coordinated
14:11TakeVWhat does it mean?
14:11gfrlogwhat it means is that you can update several at once, and the whole action is atomic, like a database transaction
14:11KirinDaveIf you make a transaction over multiple refs, they all get updated or do not
14:12gfrlogand no other thread can see them in some intermediate state
14:12TakeVThank you for the explanations. :)
14:12gfrlogno probalo
14:14gfrlog,(deref (ref 10))
14:14clojurebot10
14:15gfrlog,(detain (tain 10))
14:15clojurebotjava.lang.Exception: Unable to resolve symbol: detain in this context
14:49polypus~ping
14:49clojurebotPONG!
14:49Upperwhat the difference between (juxt) and (do) ? with both I can execute two operations
14:49gfrlogwoah
14:50Upperi dont know juxt exectly
14:50gfrlogjuxt combines some functions into a new function
14:50gfrlog,(juxt first last)
14:50clojurebot#<core$juxt$fn__3661 clojure.core$juxt$fn__3661@11a74ef>
14:50gfrlogso that returns a new function
14:50gfrlog(let [f (juxt first last)] (f [6 7 8 9 10]))
14:51Upperhmm i got
14:51gfrlog,(let [f (juxt first last)] (f [6 7 8 9 10]))
14:51clojurebot[6 10]
14:51Uppercool
14:51gfrlogthe new function calls both of the functions supplied to it and returns a vector of the results
14:51raekUpper: do is useful when you need to do side-effects
14:51gfrlog,(do (+ 3 4))
14:51clojurebot7
14:52gfrloghmm
14:52raek(defn trace [x] (do (println "value: " x) x))
14:53raekUpper: you can then wrap that trace function around an expression to make clojure print it when it is evaluated
14:53rhudson,(let [f (first second last)] (f [1 2 3 4 5]))
14:53clojurebotjava.lang.IllegalArgumentException: Wrong number of args (2) passed to: core$first
14:53Upperinteresting
14:54rhudson,(let [f (juxt first second last)] (f [1 2 3 4 5]))
14:54clojurebot[1 2 5]
14:54raekUpper: however, function bodies alreade has an "implicit do", so you don't need to write the do in that case
14:56Upperusually I use do like a "then" of a cond, If I just open two parenthesis the second turn an else
14:57UpperI understood
14:58raekah, ok... sorry for over-explaining... :)
14:58serabehi
15:01raekanyone happen to know if a java.net.Socket is completely closed when both its InputStream and OutputStream are closed? or do I have to close the Socket object too?
15:02somniumraek: you might need an AbstractSocketCloserFactoryFactory to really be safe
15:03raek:P
15:04raekman... factory-factories... do they really exist?
15:05raekno wait. don't tell me. I don't wanna know...
15:05dakroneraek: http://ws.apache.org/xmlrpc/apidocs/org/apache/xmlrpc/server/RequestProcessorFactoryFactory.html
15:05somniumhttp://www.docjar.org/docs/api/org/outerj/pollo/xmleditor/FactoryFactory.html
15:05firepoetOuch
15:14rata_hi
15:15Uppercan i break a code in clojure? I need to stop because it is returning two values.
15:16drewrUpper: (throw (Exception.))
15:18Upper:) works
15:19rata_Upper, for debugging?
15:28Upperno. to final use
15:28Upperlazy to find a good solution
15:30gfrlogcreating an infinite seq of primes elegantly is surprisingly tricky
15:31rata_gfrlog, why?
15:32gfrlograta_: particularly if by "elegantly" we mean something you can create with (iterate), such that it doesn't require much memory and doesn't compute in large chunks, and is efficient (i.e., doesn't use division)
15:35gfrlogit took me several tries over the course of the conj
15:35Upper, (doc yield)
15:35clojurebotExcuse me?
15:35gfrlogclojurebot: are your responses hard-coded?
15:35clojurebotIt's greek to me.
15:35Upperlol
15:35gfrlogclojurebot: you mean coded in greek?
15:36clojurebotexcusez-moi
15:48technomancyicey: I think I missed you at the conj; bummer.
15:48technomancyhow goes the plugin task?
15:54polypusanybody here done server push (comet, websockets, etc) from clojure?
15:58Upperare the something wrong here? (dotimes [n 100] (test 0 1 n))
15:58Upperit returns "nil" executing 1 time only
15:58Upperneither call my function
15:58jackdempseytechnomancy: fwiw that deps issue didn't matter. (use 'compojure) is no longer valid i guess since 0.4 or something. thx for the help
15:59qbgUpper: Are you sure your function isn't being called?
16:00Upperi guess, my function always return a message with println
16:00technomancyjackdempsey: good to know.
16:01Upperexist other ways to make a loop?
16:01qbgUpper: Post the code that isn't working
16:02qbgIncluding the definition of test
16:02qbgDo you get an error when loading your code? test is also the name of a function in clojure.core
16:06Upperqbg: see http://pastebin.com/g2HkDdP4 - and I do (loopTest 100)
16:09qbgIt looks like quadradoPerfeito is broken
16:12qbgWhen I run your code it is throwing the exception that you throw, so that is why it is only being run once
16:13Upperah maybe
16:13qbgAlso, the cond has two :else conditions statements
16:13qbg*conditions
16:13qbgAnd the return value of the cond form isn't even used!
16:14qbgIf the first :else case of the cond is ever invoked, you will get a NullPointerException because you have an extra set of parens
16:15qbgThat first :else condition also does some math, but then throws away the value
16:16qbgThe code is also not formatted idiomatically
16:17Uppertks, i will try to fix it
16:29jjidoWhat are the dates of the Clojure conj? Is it finished?
16:30FFUseryep
16:30jjidowas it good?
16:31qbgThere are reports that it was very good
16:32nickikform what I read on twitter it was fantastic
16:32nickikim really waiting for the videos
16:32jjidonickik: thanks
16:33qbgDoes anyone know of a syntax-rules implementation for Clojure?
16:37rata_I don't understand why when I compile a file for the first time in swank, it goes smoothly, but when I compile it for the second time the test (is (expression? p)) fails, but nothing has changed
16:41gfrlogclojure conj featured muffins
16:46technomancyivey: I must have missed running into you at the conj; how goes?
16:46iveytechnomancy: nah i wasn't there, sadly.
16:47iveyit's going well.
16:47iveyhow was it?
16:52amalloyafternoon, jackdempsey
16:56FFUserok I have a problem here
16:56FFUserlet's say you have a fn
16:56FFUserand you have this: (dotimes [num (count some-list)]
16:56FFUser(let [elem (some-list num)]
16:57iveytechnomancy: i spent the conj fighting with google reader XML. working on a tool to fetch my starred items and send them to readitlater, but reader API is undocumented.
16:57FFUser(if (= (:name elem) the-search-string) elem nill)
16:58FFUserthe problem here is of course that this doesn't make the function return the right element
16:58FFUserbut just the result of the last if
16:58FFUserin other words how do I jump out of the loop and return the result
16:58raekI think you are reimplementing 'some'... :)
16:59raekor a more specialized variant of it
16:59FFUserdoesn't some just return true/false?
16:59MayDaniel,(some #{3} [1 2 3])
16:59clojurebot3
16:59rata_,(doc some)
16:59clojurebot"([pred coll]); Returns the first logical true value of (pred x) for any x in coll, else nil. One common idiom is to use a set as pred, for example this will return :fred if :fred is in the sequence,...
16:59qbg,(some #(= (:name %) "foo") [{:name "bar"} {:name "foo"}])
16:59clojurebottrue
16:59FFUsersee? true / false
17:00qbg,(some #(if (= (:name %) "foo") %) [{:name "bar"} {:name "foo"}])
17:00clojurebot{:name "foo"}
17:00FFUseroh ok
17:00FFUserstill in general
17:00rata_is it possible that (class obj) returns x and (instance? x obj) return false?
17:00FFUserhow do you deal with loops and lack of return / break statement?
17:00amalloyFFUser: can you make a gist or something? i can't quite follow what you're trying to ask
17:01amalloyFFUser: nm, i see it was answered already; i was stuck in some scrollback :P
17:01qbgFFUser: loop/recur would be primitives to use
17:01raekFFUser: loops return, unless you do a recur
17:01FFUserok
17:02FFUserso basically if I want to end loop prematurely I can't use stuff like doseq and dotimes
17:02qbgMost functions that you would want are just a composition of some pre-existing ones though.
17:02qbgFFUser: Don't try to think in terms of loops
17:02raekFFUser: also, there is rarely any need to iterate over the indicies of the items and then get the item of that index
17:02FFUserok but I need that
17:02mrBlisswhen you do (first (something-lazy ...)) it also ends prematurely
17:03FFUserI can find if item is in the coll (some) but I also need the index
17:03FFUserbecause I want to swap it
17:03qbg,(first (filter #(= (:name %) "foo") [{:name "bar"} {:name "foo"}]))
17:03clojurebot{:name "foo"}
17:03rata_FFUser, you need the function indexed and some
17:04raekFFUser: you happen to have the book "Programming Clojure"? it has an exmaple of just that
17:04FFUserI have a vector of maps and I want to update the map with :name = parameter
17:04FFUserbasically replace it with a new map
17:05raekFFUser: ah, that chapter is available for free: http://media.pragprog.com/titles/shcloj/flow.pdf
17:05qbgFFUser: only the first one with (= :name parameter) or all of them?
17:06FFUserfirst one will suffice
17:06raekFFUser: 2.6 "Where's My for Loop", page 7
17:06raekor 72, if you follow the books own page numbering
17:06FFUserI have Clojure in Action
17:07rata_FFUser, (for [m maps] (assoc m :name parameter))
17:07raek(defn indexed [coll] (map vector (iterate inc 0) coll))
17:07amalloyor (map #(assoc % :name param) maps)
17:08rata_for is lazy, so it doesn't matter whether you want the first one or everyone... it will do you just the work you need
17:08rata_(map also)
17:09qbg(defn foo [pred f coll] (map #(if (pred %) (f %) %) coll))
17:09rata_is it possible that (class obj) returns x and (instance? x obj) return false?
17:09qbgWhere pred is a predicate function for updating, and f is the update function (applies to all matches)
17:10qbgrata_: Do you have a case where that happens?
17:10FFUser:)
17:10FFUserI think I like the solution where you append indexes :)
17:10FFUserI better not time this solution though
17:10FFUserso many allocations it will make your head spin :D
17:14amalloyrata_: no, that should be impossible
17:14qbg(defn foo [x] (instance? (class x) x)) will throw a NullPointerException if you pass in nil though
17:15rata_qbg, yes, but it's difficult to make a gist of that
17:16qbgDue you use classloaders?
17:16rata_the most weird thing about it is that when I compile it for the first time it works perfectly
17:18rata_I really don't get it... it seems to be a problem with swank
17:18rata_maybe I use (ns ... (:use ...)) too much
17:21rata_if I compile the file twice, the (instance? x obj) doesn't work anymore
17:21rata_`_´
17:21qbgWhat is x?
17:22qbgI suspect either x or obj are being redefined and the other isn't
17:23NafaiAre there any tools that use nREPL yet? It's an interesting looking project.
17:23rata_x is Agent where Agent is (defrecord Agent [...])
17:24qbgReevaluating defrecord will replace the old class with the new one
17:24qbg(IIRC)
17:25amalloyqbg: that's correct
17:25qbgIf obj isn't being redefined, that could be it
17:26SweetsharkHi all, I want to call stuff in a clojure jar from Java. I created a jar in netbeans with enclojure and it compiles just fine. I added the jar file to the project where I want to use it from. I see the symbols and everything compiles fine. However, when I run it, the call fails. With a Java jar file it works fine the way I did it. Any hints?
17:28qbgSweetshark: Are you using a class generated in Clojure from Java, or are going through clojure.lang.RT to invoke a function?
17:30rata_qbg, and is there any way to make defrecord not to generate a new class when it already exists one?
17:31Sweetsharkqbg: I tried both (I am now using RT). Right now I have a Java class in the clojure jar but it does not even get enter that (plain Java) method. Hang on, I have a suspicion ...
17:33qbgIf you are going through RT, make sure the namespace has been required
17:33Sweetshark... *puff* there goes my suspicion: no, that was not the problem ...
17:34Sweetsharkqbg: How? Do you have a link?
17:34qbgI've only done this once, but I just invoked require from clojure.core
17:34qbg(probably a better way)
17:36rata_is there any way to make defrecord not to generate a new class when it already exists one?
17:36Sweetsharkwell, I now have a plain java wrapper class in the clojure jar an call that ... should at least that always work?
17:37FFUsercan someone tell me if I'm using clojurebox, where do I have to put my Irc.clj with namespace spur.irc to get it to load in repl with require spur.irc
17:37amalloyrata_: i don't think so. you could probably wrap the defrecord in a (when) of some kind that checks whether the class already exists?
17:38amalloybut then if you changed the field list, that would prevent it from getting updated on your next compile
17:44amalloyhey Raynes, wb. did you end up having pants leftover after the flight? :)
17:44rata_amalloy, I prefer that it doesn't get updated than this annoying problem with its redefinition
17:44Raynesamalloy: I kept them all, actually.
17:45amalloywell done. i left you a present on sexpbot
17:45RaynesI'm sick as hell at the moment.
17:45RaynesI'll probably get to that tomorrow if I feel like it.
17:45RaynesThanks. <3
17:45amalloyaww
17:47rata_I'm looking now for a function that check if a class is defined... I don't like try and catch :P
17:52qbgrata_: Reflection?
17:52rdeshpandehowdy all
17:54rata_qbg, do you know of a way to do it?
17:54mister_robotorata_: what do you mean "defined"? if it's available on the classpath to be loaded?
17:54rata_I was hoping java.lang.Class/forName could help, but it throws ClassNotFound
17:54jackdempseyamalloy: hey there, just got internet back
17:54jackdempseyhow's it goin
17:54rata_mister_roboto, if it's in the environment
17:55mister_robotorata_: the JVM can't possibly tell you about classes that are not on the classpath since it doesn't magically know about them. The "environment" is the classpath
17:56Sweetsharkqbg: got a bit further, however now i get an "Var clojure.core/refer is unbound" error. Any idea on how to fix that?
17:56mister_robotorata_: i guess you could go around and open every jar you can find at the OS level and see if it contains the class :)
17:56amalloyjackdempsey: nothing special. i've been here since june, and this is the first time it's rained. need to buy an umbrella, i guess :P
17:56rata_mister_roboto, after you do a (defrecord x ...), x is in the environment
17:57jackdempseyamalloy: wow ok. i was going to say, is it like this? feels like a light storm
17:57mister_robotorata_: ah, ok. i thought you meant regular java classes from outside your program
17:57rata_mister_roboto, no
17:58rata_mister_roboto, that'd require some magic
17:58mister_robotorata_: exactly :) aren't there namespace functions to search for such bindings? (clojure newbie here)
17:59rata_mister_roboto, I hope so, but I don't know either
18:00mister_robotorata_: does this help? http://stackoverflow.com/questions/2012651/clojure-namespace-method-to-see-defined-objects
18:03rata_mister_roboto, no, that's only useful for vars, not for classes
18:03rata_(i.e., records)
18:05amalloyrata_: you could check for the instance of the var you don't want redefined
18:05amalloypresumably if you don't want the class redefined it's because you have a var that's an instance of the old class already
18:07rata_amalloy, I don't even understand why the var doesn't get updated when I compile it for the second time
18:08rata_maybe :import should go before :use
18:10rata_no, putting :import before :use doesn't help either
18:12rata_:reload-all goes after :use? :import? :require?
18:15Raynes(:use my.stuff :reload-all)
18:20rata_yes, it seems to work now with (:use ... :reload-all) :) the only negative side-effect it's that now takes ~20 secs to run the tests, because it has to recompile everything
18:23FFUsertime
18:23TheAnimalFFUser: 25.10.2010 12:24:00 +0200
18:24FFUserdebugging clojure is challenging
18:31zakwilsonI'm trying to upload files with compojure/ring. I'm not sure how to access the uploaded file (it appears to be a string containing the filename)
18:33FFUsercan someone give me some pointers
18:33FFUserhttp://pastebin.com/YMSy62sZ
18:34FFUserI find myself losing track of what's a data structure and what's a function
18:34FFUsersince it's all same nameing convention
18:34rata_FFUser, are you using emacs?
18:35FFUseryep
18:35rata_in which function do you have the problem?
18:36FFUserjust general readability problem
18:36FFUserthe code works fine
18:36nickikformat your code write for one
18:37FFUserwith java I usually keep things organised by splitting into classes
18:37FFUserand by limiting the number of public methods
18:38FFUserwhich limits the amount of way the classes can interact with each other
18:38rata_in clojure you have namespace and private and public functions
18:38FFUserloose coupling
18:39FFUserin OOP you want the classes loosely coupled and I have to somehow make my clojure programs do the same
18:40rata_yes, in dynamic languages you have loosely coupled objects by default (IIRC)
18:40FFUsernot really
18:40FFUserit's a design thing
18:40nickikin clojure everything is loosly coupeld because every function (should) be indipendend
18:40FFUserone that my coworkers fail badly
18:40amalloyFFUser: not an answer to your actual question, but i notice you do the following a lot: (first (filter #(= (:name %)) coll))
18:40FFUserthat's not what loose coupling is
18:40rata_FFUser, why?
18:41rata_FFUser, what's loose coupling for you?
18:41amalloythis can be replaced with (some (comp #{target} :name))
18:41amalloy(where target is the name you're looking for)
18:42FFUserin OOP it is when classes (larger unit of functionality than function) have limited number of
18:42nickik@amalloy wanted to say that to
18:42nickik*too
18:42FFUserexposed methods through which other classes can influence them
18:42FFUserin clojure every function can pretty much call any other function usually
18:42rata_FFUser, that's not true if you use namespaces and private functions
18:43nickikdefine data and some functions on those data then put that stuff in a namespace and define some of the functions privat and some public
18:43FFUserthanks ammaloy
18:43rata_also, you definition of loose coupling resembles more the one of encapsulation
18:43nickiktrue
18:43FFUserthey are related concepts
18:45nickikjust think of it like this in FP a Class is a namespace. Then you can define private and public functions with defn or defn-. Its the same as in java just without protected.
18:46rata_FFUser, they don't seem to be related: http://en.wikipedia.org/wiki/Loose_coupling
18:47FFUsernickik: in that case I'd easily split my code into 4 namespaces with 3 functions each
18:47rata_loose coupling is the use of interfaces in Java
18:47nickiki agree that the are related if you encapsulate a object the write way its easy to have loose coupling
18:47FFUserif you asked me to craft classes out of it
18:48FFUseryes that's what I meant
18:49rata_FFUser, then do that if you want your code more organized
18:49FFUserseems like it
18:49FFUserI was also looking for some kind of coding convention
18:49FFUserlike in C++ you have hungarian notation
18:50mister_robotoFFUser: Hungarian notation is for encoding types in the name. functions are just functions though
18:50nickik@FFUser that seams to be alot. namespaces a usually a little bigger for conventions you can look at http://www.assembla.com/wiki/show/clojure/Clojure_Library_Coding_Standards
18:50zakwilsonLoose coupling means that if A doesn't need to know about B, it doesn't. How you communicate that in your code is up to you, though namespaces do provide a mechanism to make it easy.
18:51FFUsermister roboto: clojure doesn't have types but it has vars that are bound to data, vars bound to FNs and vars bound to mutables (atoms, refs)
18:52zakwilsonClojure has types. They're attached to the data, not the variable.
18:52mister_robotozakwilson: loose coupling means something a bit stronger than that. it means that if A uses B, it doesn't depend on how B is implemented. i think that falls out of FP automatically if your function is referentially transparent
18:52FFUserit was my idea to make different name prefixes for these 3 kinds
18:53nickiki would do that look into :"Follow clojure.core's example for idiomatic names like pred and coll" in the document i linked
18:54nickikin general: functions should read like verbs and data should read like nouns
18:54FFUseryeah I use same thing in java
18:55FFUsersometimes these names can be hard to craft though
18:55rata_mister_roboto, that isn't it... it that if A uses B, probably you mean that A uses an interface that have the methods you need
18:55mister_robotoFFUser: why would you need a special idiom for mutable var names when you already have to use a special form to access them? doesn't that tell you everything?
18:55FFUsermaking function name verb-like but not too vague often results in extremely long names :D
18:56FFUserit tells me everything when reading correct code
18:56mister_robotorata_: the only reason interfaces enable loose coupling is BECAUSE they make it impossible to depend on the implementation
18:56FFUserthe problem is forgetting to use the special form
18:56FFUserthe compiler won't warn me
18:57mister_robotorata_: the only visibility you have to the "used" class is the "protocol"
18:57rata_yes, that is
18:58rata_OOP is about procedural abstraction
18:58mister_robotorata_: oops is about many things. encapsulation, data hiding, inheritance, locality of data and methods which operate on the data, etc
18:59mister_robotos/oops/OOP/
18:59sexpbot<mister_roboto> rata_: OOP is about many things. encapsulation, data hiding, inheritance, locality of data and methods which operate on the data, etc
18:59rata_I think a good read about that is http://www.dcc.uchile.cl/~etanter/ooplai/adt-oo.html
19:00rata_I don't think encapsulation, data hiding, inheritance and locality of data are much related to OOP in general... they are related to some kinds of OOP implementations
19:01mister_robotorata_: http://en.wikipedia.org/wiki/Object-oriented_programming like I said, OOP is about many things. sure you can leave out the bits you don't want to talk about but they are still part of OOP
19:01rata_FFUser, I think you'll enjoy this article (by Stuart Halloway): http://www.nofluffjuststuff.com/blog/stuart_halloway/2009/08/rifle_oriented_programming_with_clojure
19:02nickikthe three thinks alan kay said are the base of OO are: Encapsulation, Subtype polymorphism, Object inheritance
19:04FFUsertoo bad people I work with only use Encapsulation and even that one badly
19:04rata_nickik, then every language that's based on delegation instead of inheritance isn't object-oriented?
19:04rata_I don't think so
19:05nickikno, I'm just pointing out what the original definition is. Today everthing is diffrent.
19:06nickikFP isn't the same as it was 40-50 ago.
19:06FFUserimagine a bunch of void return methods on a single class named "processSomething" with no arguments, which load stuff from DB and then mutate half a dozen huge java beans, some dealing with state (data) storage and some dealing with UI state
19:06rata_nickik, thus I think the core of OOP is message passing and procedural abstraction
19:06mister_robotorata_: i think the key thing is that some features of traditional OOP, like reuse through inheritance only, is bad. so delegation is preferred. however, even a modern OOP like java and .NET has inheritance.
19:07rata_FFUser, that's gonna be difficult to test for sure
19:07FFUserI am tasked with adding functionality to such existing projects
19:07nickikthats the problem with descutions like this everybody means something else when he sais OO or FP
19:07FFUserI have absolutely no idea which beans any of these functions affects under which conditions
19:08rata_mister_roboto, that's not modern OOP... also inheritance and classes is just one way to implement OOP
19:08mister_robotoFFUser: you mean like adding new functionality without changing the existing code? that kind of code isn't testable
19:09FFUseradding new business logic into existing UI
19:09FFUserwell JSFs
19:09FFUserand I don't understand the business logic already implemented, it's domain specific and you need experts to make specifications
19:09mister_robotorata_: what is a modern OOPL that you are talking about then that doesn't have inheritance, for example?
19:10FFUseranyway, clojure is like my vacation from work
19:10FFUserand work is my nightmare
19:10mister_robotoFFUser: that's a bad spot to be in, but all too common. can you modify the existing code to start injecting dependencies?
19:10rata_JavaScript doesn't use inheritance... Scala uses inheritance and is more modern than Java or C#
19:10FFUserdon't have enough hours allocated to refactor code
19:11mister_robotorata_: javascript uses prototype based inheritance
19:11FFUserbonus points: people who did this call me an academic when I talk about OOP. Needless to say, none of them have an actual degree in CS
19:12rata_mister_roboto, that's not inheritance, that's delegation
19:13rata_this is an interesting topic, but I'm going now to eat something... see you later guys :)
19:13mister_robotorata_: prototype inheritance is still reuse by depending on implementation of the prototype
19:14mister_robotorata_: i suggest reading about javascript and inheritance
19:14nickik@FFUser i'm doing boring database IO with ASP classic thats no fun either
19:15rata_one has to be cautious when reading about those topics... there's a lot of people (even academics) out there that mix up ADTs and objects
19:15mister_robotoFFUser: i know exactly the kind of code you're dealing with. if you can't refactor, at least try to write some good tests before modifying it
19:15mister_robotoFFUser: although it's damn hard to even test such code
19:16mister_robotoFFUser: everything is a giant integration test - can't tease apart the components in a big ball of mud
19:16rata_if they confuse ADTs and objects, to mix up inheritance and delegation would be even easier
19:17FFUserI'm not optimistic about the future of dealing with other developers
19:17nickikso good night i have to get up early to do some more boring stuff at work :)
19:18FFUserin my coutry about 10% of developers have BS in CS, 45% have associate's degree(I think that's what it's called) in CS and 45% have high school education
19:21mister_robotorata_: http://www.cs.rit.edu/~atk/JavaScript/manuals/jsobj/ javascript prototype inheritance is true inheritance. you aren't holding onto a prototype handle and delegating to it, unless you also count c++ vtables as holding on to ancestor references and doing delegation
19:21FFUsertime
19:21TheAnimalFFUser: 25.10.2010 01:22:18 +0200
19:28mister_robotoFFUser: and in every other country, more and more development is outsourced to countries with lots of degreed programmers who, unfortunately, just started programming professionally on the program you're giving them :)
19:31FFUserIt's terrible here. And the CS faculty had 180 spots, 360 applicants and you needed to be a mixed C grade/D grade student to get in.
19:31FFUsera lot of them drop out and work as programmers
19:32FFUsernow imagine dropouts who had high school math graded C work as programmers
19:33FFUseranyway, enough griping about the state od development around here
19:33FFUsergood night
20:03yayitsweiIs there a way to splice a list into arguments (what the splat operator in Ruby does) without using a macro? I'm trying to turn a list into arguments for recur.
20:04amalloyapply
20:05amalloythough i'm not sure that works for recur. recur is probably a special form
20:05amalloy,(doc recur)
20:05clojurebotGabh mo leithscéal?
20:05yayitsweiit is a special form
20:05yayitsweiso I don't think I can use apply
20:05amalloyno, you can't
20:06jackdempseyis it a variable list? can't destructure it
20:06amalloyi think the usual way to do this would be destructuring
20:07amalloy,(loop [[a b] (range)] (if (= 10 a) b (recur (map + [a b]))))
20:08clojurebotExecution Timed Out
20:08amalloyer, that's not what i meant
20:08amalloy,(loop [[a b] (range)] (if (= 10 a) b (recur (map inc [a b]))))
20:08clojurebot11
20:10amalloyyayitswei: does that help?
20:10yayitsweiamalloy: still reading it :)
20:13yayitsweiamalloy: what's the (range) for?
20:13amalloyjust a convenient initial value for the loop
20:13amalloysets a=0, b=1
20:14yayitsweioh i see
20:15yayitsweiso the recursive function should take one argument, a list, instead of arbitrarily many
20:16amalloyright
20:16amalloyand then pull apart the list however you want
20:17yayitsweiamalloy: got it-- thanks!
20:17amalloyor, have your arbitrarily-many function public, internally implemented as a loop around a list
20:17yayitsweiif I really wanted to make it a
20:17yayitsweioh yeah that's what i was just going to ask
20:23rata_mister_roboto, I think that link shows how to simulate inheritance in javascript
20:23rata_many features of class-based languages, such as inheritance, can be simulated in a delegation-based language
20:24rata_http://en.wikipedia.org/wiki/Prototype-based_programming
20:24mister_robotorata_: no, it shows how inheritance DOES work in Javascript. it's just showing how to you structure that sort of inheritance hierarchy, comparing Java to Javascript, where the first is class-based inheritance and the second is prototype-based inheritance
20:24mister_robotorata_: that's just how it works. look up constructors and prototypes in javascript. that's what they are for
20:25rata_mister_roboto, look at the prototype-based programming article in wikipedia
20:26mister_robotoreading
20:28mister_robotorata_: ok, so i'll buy that it's an ambiguity :) it's not like typical delegation where you are explicitly delegating calls to some delegate, however. you only reference the prototype in javascript typically to set up the prototyype chain so this inheritance of behavior happens automatically when you construct an object
20:29mister_robotorata_: the rest of the time you just use the instance directly. if you still want to call that delegation, it seems to me that it's j ust a non-useful blurring of concepts
20:31rata_mister_roboto, that's why I said that use of prototypes is an emulation of inheritance :)
20:31rata_also the OOPLAI book (a work in progress yet) explains the differences between class-based and prototype-based languages very well IMHO http://www.dcc.uchile.cl/~etanter/ooplai/
20:32rata_do you have read PLAI?
20:32mister_robotorata_: ok ok, i see your point. if the language is hiding the "delegation" from you when you are accessing an instance behavior, it seems to me no different than c++ hiding it by internally accessing the vtable
20:32mister_robotorata_: i mean insofar as discussing whether a language has "inheritance" proper
20:33mister_robotorata_: it's just an implementation detail. to call it "emulated" doesn't enhance understanding of what it is or does
20:34mister_robotorata_: what does inheritance mean if not having behavior and properties automatically propagate through the chain of dependent objects?
20:34rata_it's not hiding the delegation at all... it's just using it to implement inheritance-like constructs
20:35mister_robotorata_: when i call jsobject.someproperty, i don't know if it's a local or coming from the prototype
20:35mister_robotorata_: that's not hiding it?
20:35rata_that's not hiding it... that's how delegation works
20:36rata_inheritance definition depends on classes
20:36mister_robotoor setting up the prototype chain
20:36mister_robotomy example... is that not hiding the delegation?
20:36rata_yes, that's not hiding the delegation
20:37mister_robotorata_: ok, then i guess we cannot agree on that point
20:38rata_if object jsobject doesn't know how to interpret the message 'someproperty', then it's going to delegate that message to other object
20:38rata_we can't agree on that point
20:38mister_robotorata_: just like the c++ object delegates via the vtable. it's a language implementation detail of how to locate hte property
20:38mister_robotoi totally agree with what you just said
20:39rata_the important difference between them is that delegation occurs between objects and inheritance happens between classes
20:39rata_the vtable is an implementation detail
20:47mister_robotothis is actually kind of interesting because earlier you were claiming that inheritance isn't part of OOP but you seem to be saying that class-based OOP is actually the only way to do inheritance
20:50rata_yes, I was saying inheritance isn't part of OOP, but part of class-based OOP
20:52amalloyummmm, no offense guys, but could you take this discussion to #oop or something? i don't want to miss any clojure-related messages in the flood
20:52mister_robotosorry amalloy, you're right
20:52rata_sorry amalloy
20:53ymasorywhy is there no "lein run"? what am i missing?
20:53mister_robotomy final statement is only that i think it is pointless to draw a line between "true" and "emulated" inheritance. i will shut up now
20:54amalloyymasory: how does lein know what function you want to run? or do you want it to start up a repl and then eval everything in your project, maybe?
20:55rata_just-in-time for the clojure-related question :)
20:55ymasoryamalloy: not sure if there's a dedicated start point in clojure. sbt runs the first main function it can find with the matching signature
20:56ymasoryit seems like a pretty slow procedure to say lein repl and then type out a start point
20:57amalloyymasory: you can specify the main function in project.clj, and then when you java -jar the result of lein jar, it should call that function
20:57ymasorythanks
20:57raekthere is some feature to set the starting namespace. I do not know if that also automatically requires that namespace
20:59Adamantclojurebot: do you have a neural net processah lahk Ahnold?
20:59clojurebotHuh?
20:59mister_robotoamalloy: how does that work? does it put that function inside a main()?
21:00amalloymister_roboto: every clojure function turns into a java class. i imagine it renames the main class's function main, and it certainly puts an entry in the jar manifest
21:00raekif you add :main your-namespace-here, the repl will start in that namespace
21:01raekah, and there's also :repl-init-script
21:02amalloyraek: cool. does that affect swank too?
21:03raekno idea :)
21:03mister_robotoif I had to decide between using lein or cake, is there any clear advantages to choosing one? i haven't used them, only did some reading and they seem to do the same thing
21:05rata_raek, where do you put that ":main your-ns"?
21:05amalloymister_roboto: one nice feature of cake is that it will keep jvms running in the background to speed up launch time of all cake tasks
21:05amalloyotoh, if you're strapped for RAM, it's probably inconvenient to keep killing those
21:06raekymasory: one common way seems to be to only have function and constant definitions at the top level of the source files. (i.e., when you load a file, the application doesn't start.) then, you provide a -main function to start your application.
21:06raekrata_: in your project.clj file
21:07raekbut still, when launcing the repl you have to type stuff
21:07mister_robotoamalloy: so if you're not tight on RAM then cake has the lead :)
21:07rata_raek, in (ns ...)?
21:08amalloythat's been my experience. but lein is a little older and more stable/tested. they also have incompatible plugin architectures, so if someone's written a lein plugin you really want...
21:08amalloybut for the most part they're compatible so it should be easy to switch if that happens
21:08raekrata_: I'm sorry... what in (ns ...)?
21:08amalloyrata_: no, in the project.clj file at the top level of your lein/cake project
21:09rata_raek, that ":main your-ns"
21:09rata_ah ok
21:09rata_sorry
21:09rata_read only the first msg
21:11raekok, I can confirm that setting the main namespace will cause that namespace to be loaded when you start the repl
21:12raekso, you could see the main namespace as a startup script, if you want to
21:34mister_robotohow do i make an entity bean using cake? (kidding!) is it a fairly typical thing to use any old editor (emacs or whatever) to create the code and then use lein/cake to package it for release?
21:34hiredmanyes
21:36amalloymister_roboto: yep, pretty normal. CCW users might have their own thing, but a lot of us use emacs/cake
21:37mister_robotoamalloy: so far i only used CCW to build fairly small programs that i just ran at the repl by typing it in. i really need to go to the next step of having a full automated build process and i cake seems to be a very good choice
21:38amalloyit certainly is a good choice. but laurent might have something that integrates better with eclipse, i don't know
21:39mister_robotoamalloy: when i use CCW, i tpically just execute the clj file and leave the resulting repl running. then i've been copy/pasting new code down into the repl rather than killing it and re-running the script file(s). this sounds clumsier than emacs with its repl integration (Swank?) but i haven't tried that approach
21:41hiredmanthats fine for dev
21:41hiredmanbut when you deploy you build a jar
21:52mister_robotohiredman: right. i've been doing java development for too many years now :)
21:53mister_robotohiredman: maven and ant before that. need something for clojure now and i guess it's gonna be cake
21:59amalloymister_roboto: cake and lein are both built on top of maven
22:00amalloyeg, lein/cake pom creates a pom.xml file you can manage with maven if you prefer
22:01mister_robotoamalloy: that's good in that i'll understand what's going on underneath and i can point it to our in-house artifactory repo for the dependencies. however, i think all the management looks like it will be best done via project.clj
22:11ymasorywhy can't clojure put in the "recur" bit by itself? at least in some simple cases?
22:16somniumymasory: there are a few threads on the mailing list about it. the principle reason seems to be that since it would only be possible in some cases, better to make it explicit everywhere.
22:17somniumymasory: plus you can always use scheme :P
22:19ymasorygotcha. thanks. seemed a little funny in the simple cases
22:22ymasorycan i get the previous line back in the repl?
22:28mister_robotoinstall rlwrap like here: http://programmingzen.com/2010/07/13/how-to-setup-clojure-from-scratch/ or use "cake repl" like here: http://github.com/ninjudd/cake
22:29mister_robotoymasory: maybe there's an easier way but rlwrap worked well for me. a standalone repl is annoying without history
22:33ymasoryno kidding, thanks
22:35ymasorywhile i'm at it. why doesn't clojure allow forward-references to functions? other lisps do
22:38mister_robotoymasory: you mean like this or something else? http://en.wikibooks.org/wiki/Clojure_Programming/Concepts#Mutual_Recursion
22:40somniumymasory: you can use declare for forward declarations
22:41ymasorysomnium: do other lisps require forward declarations?
22:41somniumymasory: I don't think so
22:42somniumI don't know how CL does it, but I do think R6RS scheme really got that part right (scoping of top levels)
22:42somniumstill, adding (declare ...) isn't so painful
22:45ymasorypainless as C :)
22:49somniumymasory: aw, surely Clojure isn't in the same league as C in terms of inflicting pain on programmers :)
23:36ymasorywhat does the & mean in function signatures?
23:37dsantiagoIt means any number of additional arguments, which will all be put into the name given after the & as a list.
23:38ymasoryah thanks