#clojure logs

2010-04-27

00:02defnwrite code first, optimize later
00:07pdkno defn we gotta keep up the proud legacy of C
00:08pdkplanning in advance whether every integer variable will be int or short
00:10slyphoni really like the name 'throwf' it kind of sounds like an exception "barfing"
00:33slyphonman, the guys that write this Atomikos JTA lib are dicks
00:33slyphonfrom the javadocs:
00:33slyphon"All non-transient errors (i.e., those that happen each time a message is delivered) indicate problems at the application level and should be dealt with by writing better application code."
00:33slyphongee
00:33slyphonthanks
00:41remleduff_technomancy: Best commit ever ;)
01:40slyphonARGH
02:53vegaiare there any active projects for bringing clojure to The Shootout?
03:39LauJensenvegai: Not to my knowledge
03:42hircuswhen using Leiningen, is there a way to specify a version number once and avoid repeating oneself?
03:44ordnungswidrighircus: repeat where?
03:44vegaiI guess you mean that you wanna get the version number of your app in project.clj to your app code
03:45hircusordnungswidrig, vegai : I'm using several Incanter modules and I don't want to keep saying "1.2.3-SNAPSHOT"
03:46vegaiohhh
03:46irfnhircus project.clj is plain clojure code
03:46vegaicannot you just (def ver "1.2.3-SHAPSHOT")
03:46irfnso you should be able to def it
03:46hircusI tried (def *ver* "1.2.3-SNAPSHOT") and then :dependencies [[incanter/incanter-core *ver*] ...] but it fails, saying symbols can't be cast into strings
03:46irfnyeah
03:47hircushaven't used Clojure macros for a while, an dI forget my macro expansions
03:51hircusvegai: so after defining ver, how do I use it within defproject, given the problem I stated?
03:52Borkdudetechnomancy|away: I got leiningen working on XP now, just to let you know
03:53BorkdudeClojure is a seqsy language
03:54vegaihircus: odd
03:55hircusvegai: yeah. looking at the Leiningen source right now to see what's going on
03:56RaynesBorkdude: That was clever. I think sexpy is more clever though, hence the name of my bot.
04:04hircusvegai: so I guess the problem is that the arguments have to be quoted, because org.clojure/clojure etc. do not refer to anything in the namespace, but if they are quoted then the version numbers cannot be macro-expanded
04:04hircusvegai: the other solution, the Polyglot Maven syntax, requires you to quote the namespaces instead. gah.
05:24stilkovwhat would be the idiomatic way to do map over something that can either be a list of strings or a single string?
05:24stilkovthe 'if' I currently use somehow feels ugly
05:26BorkdudeIf you map over a single string, it maps the function over the characters of that string
05:27Chousukestilkov: I don't think there's an idiomatic way to do that :P
05:27Chousukestilkov: just use an if
05:28stilkovBorkdude: exactly my problem
05:28Chousukebut in general, why is your function accepting both a string and a list of strings?
05:28stilkovChousuke: destructured command line args - can either be a single file or a list of files
05:29Chousukeusually in those cases you want a (fn foo [& strings] ...) so that you can call either (foo "string") or (apply foo list-of-strings)
05:30Chousuketry and see if you can change your code so that it always gives you a list of strings, even if there is only one
05:30ChousukeI think that would be the most idiomatic approach
05:31Chousukein general if you have a function that works with sequences of something, special casing it for one of something is probably unidiomatic.
05:32stilkovFair enough. Is there an idiomatic way to turn a single element into a list? Or can the let destructuring do this on its own?
05:32LicenserI'd go with (fn foo [string & strings] ...) so it forces at least one argument
05:34stilkovLicenser: and what would go in the body then? (map #() (conj string strings)) ?
05:34Licenserwell that depends on what you want to do with it :P
05:34Licenserbut you've a point there
05:35Chousukestilkov: (list element) :P
05:35stilkovChousuke: that will turn a list into a list with an element that's a list
05:35Chousukebut I could help you better if I knew how you're doing your destructuring
05:36Chousukestilkov: sure. but then why is your data at one time a list and other times a single element? Is there no way to fix that?
05:36stilkov(defn -main [& args]
05:36stilkov (let [[pattern & files] args]
05:36stilkov (great-function pattern files)))
05:37Licenserwhy not go with defn -main [pattern & files] ?
05:37Chousukeand what part of that will sometimes be a list and sometimes a single string?
05:38stilkovChousuke: the "files" part, depending on how many arguments are passed on the cmd line
05:38Chousukeno, it'll always be a list.
05:38Chousukeor nil
05:38Chousukebut still, always a list
05:38stilkovhm
05:38stilkovchecking ...
05:39Chousukeright, you could just (apply great-function args) :P
05:39stilkovLicenser: you're right, left-over from some earlier iteration
05:39Licenser*nods*
05:40stilkovLicenser: Ah, I remember: I had a check as to the number of arguments; but I can obviously do this with a nil check as well
05:40Chousuke,(count nil)
05:40clojurebot0
05:40stilkovLicenser, Chousuke: thanks for the help so far, I guess I'll play some more
05:40Licenserit gives the advantage (in my eyes) that the signature of -main already tells you what it wants (a pattern and files) and not just that it wasnts something :)
05:41Licenserstilkov: have fun and you're welcome
06:21kzarSupposing you have a map and either another map or a list of maps and in either situation you need to return a list of maps how would you do it?
06:23rhudsonDepends on how you get "either another map or a list of maps"
06:24kzarso either (list map1 map2) or (cons map1 list-of-maps) but I thought there might be a better way to write it
06:24LauJensenAny Linux Firefox users here who can help me out for 10 secs?
06:24kzarrhudson: Well I'm writing a function recursively that has a past-result parameter, usually it's just one map but sometimes it might be a list of a few maps.
06:25kzarrhudson: I thought of always wrapping the past-result map in a list but I thought that's a bit ugly
06:25LauJensen,(flatten (cons [1 2 3] [[4 5 6] [7 8 9]]))
06:25clojurebot(1 2 3 4 5 6 7 8 9)
06:26rhudsonkzar: you could define your function (defn whatever [ & maps ] ...)
06:27LauJensenkzar: that flatten demo was for you :)
06:28rhudsonLauJensen: I run Firefox on Linux at work
06:28LauJensenrhudson: Are you at work ?
06:28rhudsonthankfully no
06:29rhudsonnot at this ET hour
06:29RaynesLauJensen: I run firefox on Linux.
06:31kzarRaynes: Cool idea, so maps would always be a list of the parameters given in that example?
06:31kzaroops sorry I meant rhudson
06:31RaynesIt's okay. I love to hear my name.
06:32rhudsonkzar: right
06:32kzarheh
06:32rhudsonreins rains reigns
06:35stilkovI'm trying to turn this into idiomatic clojure, I'm sadly pretty sure it's not: http://gist.github.com/380602
06:35stilkovany comments appreciated
06:37arbschtstilkov: I think you can replace numbered-lines with indexed in clojure contrib
06:37arbschtthat will get rid of the atom too
06:38LauJensenYea, zero need for mutability for that specific task
06:40stilkovthanks, neat use of map with two args
06:40arbschtstilkov: you can use destructuring inside print-matches to abbreviate binding stuff
06:42Chousukestilkov: (if (or (nil? pattern) (empty? files)) ...) <- (if-not (and pattern files))
06:43stilkovarbscht: you mean something like (let [[fname matches] matches] ??
06:43stilkovChousuke: thanks
06:44arbschtstilkov: you can destructure within doseq itself
06:44Chousuke(doseq [[fname submatches] matches, match submatches] ...)
06:45stilkover ? chewing on that for a second
06:45Chousukeor even (doseq [[fname submatches] matches, [first-part, second-part] submatches] ...)
06:46stilkovah ? beautiful
06:47Chousukeit's similar to (for [row (rows matrix), element row] ...) except it's doseq :P
06:48Chousukealso you might want to use format instead of manually constructing the string with str
06:49Chousukeeither is fine, but I think format strings are easier to read and modify
06:50kzarrhudson: I had a question about your idea to define the function using "& maps"; it works fine until I need to recur but then instead of passing the new map and all the old maps I end up passing back a new map and a list of all the old maps
06:51patrkrisrhickey: Hey. Did you ever experiment with other contention mangement strategies than the one Clojure's STM currently employs?
06:51stilkovChousuke, arbscht: thanks a lot, that surely looks a lot better
06:51rhickeypatrkris: not much
06:52patrkrisrhickey: so you don't have any idea how implementing e.g. karma would affect it?
06:53rhudsonkzar: yes, that's what's wrong with my suggestion.
06:53rhickeypatrkris: my guess is, not a lot. Clojure's STM is coarse-grained, so it's not going to be used on the inner bits of a concurrent collection, e.g. as in a lot of the STM literature
06:55kzarrhudson: Hey well macros let you expand a list, I could create a macro that took a list and just expanded it and then use that on the list of old maps?
06:55patrkrisrhickey: ok, I believe you are right - but we'll try out a few different strategies and see how they work out. We're doing it as part of our studies.
06:57rhickeypatrkris: If you are interested in doing something cool and new with Clojure's STM, and leveraging it being MVCC, one thing I have been thinking about is visible transaction timestamps
06:57patrkrisrhickey: nice - I'll note that
06:57rhickeypatrkris: so, rather than returning a value d-timestamped-sync would return a token representing the world at a point in time
06:58rhudsonkzar: (defn f [m old-ms] (let [ms (cons m old-ms)] ... )
06:58rhickeythe nyou could run a read transaction as of a point in time
06:58patrkrisrhickey: you meant do-timestamped-sync?
06:59rhickeythis matters when someone does something in a transaction and needs to communicate it to someone for use later. Given long enough histories, they can go back and see the same world
06:59rhickeypatrkris: yes, do-timestamped-sync or something
06:59patrkrisrhickey: thanks man, cool suggestion
06:59rhickeyanother thing I am interested in is independent ref worlds
07:00rhudsonkzar: then ms is always a list -- (cons x nil) => '(x)
07:00rhickeyfor some apps you might have small independent ref worlds of critical data for which you'd keep very large histories
07:00patrkrisrhickey: so you'd have the ability to rewind?
07:01rhickeypatrkris: not so much rewind as see the past
07:01patrkrisrhickey: e.g. for undo operations?
07:01patrkrisrhickey: oh ok
07:02rhickeypatrkris: consider event-driven systems where the event receiver adds the even to a collection transactionally, then notifies others. If they race to look at the collection something might have happened in the interim, wheras is the producer could communicate the world time, they could see his result
07:03patrkrisrhickey: ok, got it
07:04Licenser,(doc flatten)
07:04clojurebot"([x]); Takes any nested combination of sequential things (lists, vectors, etc.) and returns their contents as a single, flat sequence. (flatten nil) returns nil."
07:05patrkrisrhickey: so your two suggestions are actually related somewhat, right?
07:06rhickeypatrkris: not really, separate ref pools just let you get more concurrency when you have never-overlapping sets of data
07:06Licenserout of curiosity, why does flatten not take multiple lists, it is kind of what people use a lot
07:07rhickeypatrkris: given that history length is per ref you don't need separate pools for that
07:08patrkrisrhickey: Ok, I was just focusing on the history thing :)
07:08rhickeypatrkris: timestamped transactions are something likely to make it into Clojure, ref pools probably not for a while
07:08patrkrisok
07:08rhudson,(var flatten)
07:08clojurebot#'clojure.contrib.seq-utils/flatten
07:11rhudson,*clojure-version*
07:11clojurebot{:interim true, :major 1, :minor 1, :incremental 0, :qualifier "master"}
07:12patrkrisrhickey: so in independent ref worlds, you'd be able to see a consistent view of a pool of refs at a given point in the past, or am I misunderstanding?
07:14rhickeypatrkris: sorry I confused you. Independent ref pools simply make it so one set of refs has no interaction at all with another, e.g. can't be part of the same transaction. At very high concurrency levels, that would ease the pressure on the single timestamp CAS inside the STM, since each pool would have its own
07:14rhickeypatrkris: really nothing to do with timestamped transactions
07:14patrkrisrhickey: oh ok, thanks :)
07:15rhickeyas long as you have sufficient history for any refs you need to see in the past, you can do timestamped reads
07:15patrkrisyes, but clojure doesn't allow to look in the past as of now, right?
07:15rhickeytalking about one just made me think of the other
07:16patrkrisyes
07:16rhickeypatrkris: right, that would be the enhancement - runs this read-only transaction as of this point in the past
07:16rhickeyas id
07:16rhickeyas if
07:16patrkris:)
07:16Raynesrhickey: It's called too-early-in-the-morning syndrome.
07:17rhickeyRaynes: it doesn't get better later :(
07:17RaynesIt can't get any worse.
07:17patrkrisstart drinking coffee
07:21Raynesrhickey: What kind of tea?
07:21RaynesI love me some tea.
07:22rhickeyRaynes: in the morning - an Assam, today it's Mangalam
07:22RaynesNever heard of either of those. My teafoo is weak, but I'm learning.
07:22vu3rddrhickey: Indian Tea looks like?
07:23Raynesvu3rdd: You Indians sure are proud, aren't you? :p
07:23rhickeyvu3rdd: right
07:23RaynesYou should be, with such awesome teas.
07:23vu3rdd:)
07:23vu3rddWe don't get as good coffees here as you have in Europe and the US.
07:24vu3rddI am sad that I am missing meeting all you great clojure hackers. You are all in the west. May be you can visit me and I will give you loads of Tea
07:25Raynesvu3rdd: I'd totally visit you. You're watching Irclj. One of the few. <3
07:25Licenserheh
07:26vu3rddRaynes: Sure. I am quite interested in both sexpbot as well as irclj.
07:26Licenservu3rdd: a colegue of mine was supposed to go to India the other weak but that silly vulcano thing keeped him in germny
07:26vu3rddOh..
07:26RaynesVolcanoes are so silly!!!
07:26vu3rddI am in Bangalore. If any of you are coming this way, please ping me at this handle @ gmail
07:26LicenserSOmeone from kuwait here?
07:31Raynesvu3rdd: Sexpbot is actually my biggest project ever. It started out as a little toy script to connect to IRC.
07:31RaynesAnd then I got bored.
07:31RaynesThat's how all good projects start. "I got bored."
07:34LicenserWhich would explain why I never have good projects :P I can't remember when I was boored the last time
07:34patrkrisrhickey: in the software engineering podcast you talked about how STM couldn't be made to work correctly in certain other languages. One of the reasons, aside from MVCC and the persistent datastructures, would also be because of the "coarse grainedness" of Clojure's transactions? In C and Java STM implementations, the STM *has* to work at a finer granularity. Am I right in my understanding?
07:34Raynesclj-sandbox is great.
07:34RaynesLicenser: Ever figure out what was up with StringWriter?
07:35patrkrisrhickey: sorry, 'correctly' is not the word here
07:36rhickeypatrkris: right, my comment was directed at efforts to make ordinary mutating Java/C code safe by wrapping in transactions. The granularity would have to be at the field level, and most important, you'd need to be in a transaction to read. Clojure emphasizes programming with values, such values perfectly valid outside a transaction.
07:39patrkrisrhickey: so how about haskell for instance? Could you hope to get MVCC working well in that language? Clojure's force with regard to MVCC is structural sharing and thus efficient 'copying', right? (I'm just sorting out the arguments we'll use when we write our paper.)
07:41rhickeypatrkris: Haskell's STM is somewhat like Clojure's, sans MVCC. It is ref+value oriented, and can be used coarse grained, and of course the language emphasizes values
07:42rhickeypatrkris: and Haskell's data structures are similar. So, nothing to knock on Haskell here, we're on the same side of this I think
07:43patrkrisrhickey: Ok, I better read up on Haskell :)
07:43rhickeyHaskell has orElse (or something) which I considered but rejected
07:43patrkrisyes orElse
07:44rhickeyThe big diff with Haskell's STM is that in order to do orElse you need to do read tracking. Clojure doesn't need to do that
07:44rhickeyClojure is I think still unique in having commute
07:45patrkrisand MVCC?
07:45rhickeythere are other MVCC STMs I think
07:45rhickeyat least now there are
07:46rhickeyhttp://multiverse.codehaus.org/overview.html
07:46sexpbot"Multiverse - Java based Software Transactional Memory implementation"
07:46patrkrisyeah you are probably right, but I can't see how you can get that to work as efficient as in clojure's case, unless the data structures have the same characteristics
07:46rhickeypatrkris: exactly, the whole design works together
07:47patrkrisrhickey: yes, and when I finally saw that, I was pretty amazed, rich :)
07:47patrkrisi've been wanting to ask you if these things was all one epiphany for you, or did things just follow each other naturally? :)
07:47patrkris*were
07:48rhickeypatrkris: took too long to be an epiphany :)
07:49rhickeyI do think it is a natural outcome of the reconciliation of a bunch of forces
07:50rhickeylooking backwards of course
07:50patrkrisyes
07:50rhickeynothing about Clojure is really new
07:50patrkrisbut probably the combo is
07:51wlangstrothpatrkris: beat me to it.
07:51wlangstrothrhickey: first lisp I've liked, fwiw
07:51patrkrisfirst lisp I did serious programming in :)
07:52patrkris(for some definition of serious)
07:52patrkris^ that wasn't a lisp expression, in case you wondered
08:04cemerickrhickey: thank you for that last commit :-)
08:04rhickeycemerick: you're welcome!
08:04rhickeyprotocol variadics will be harder
08:05Raynespatrkris: Looked more like python without the parens.
08:05cemerick...and I was just about to (jokingly) suggest auto-hinting of % in fn literals in protocol fn maps :-P
08:07rhickeycemerick: extend-type auto-hints
08:07cemerickrhickey: yeah, I know :-)
08:07rhickeybut extend doesn't look at the map at all
08:08cemerickso I figured. That's why it would have been a joke. :-)
08:08rhickeycemerick: but is there some real need?
08:08cemerickheh, no
08:21wlangstrothrhickey: I'm still catching up on your design ideals - Bagwell and Huet were new to me - any more required reading?
08:26stilkovrhickey: can I use the Clojure logo in a public presentation about the language?
08:27rhickeywlangstroth: tough to say, you learn from everything, even those things you reject
08:27rhickeystilkov: sure
08:27stilkovrhickey: thanks
08:27rhickeystilkov: what are you talking about?
08:29stilkovrhickey: I'm doing an intro to Clojure's concurrency features at JAX 2010 in Germany
08:29rhickeystilkov: good luck!
08:30stilkovrhickey: thanks!
08:30wlangstrothrhickey: true enough - thanks
09:02Licenserhmm the protocll stuff is pretty neat
09:05Raynestechnomancy|away: I need you. Wake up.
09:05LicenserSo could the rule of thumb for when to use protocols and when to use multimethods be: If you don't need the crazy stuff you can do with multi methods you should do it in protocols?
09:06RaynesDeftypes can't implement a multimethod.
09:06Chousukean easier way: try protocols first, if they don't work, use multimethods
09:06LicenserChousuke: but that is so simple :P
09:07Chousukeideally you'd keep the fact that there is a protocol or a multimethod an implementation detail
09:08Chousukethey're all functions, and if you don't advertise the protocol as part of your API, no-one's going to notice the difference :P
09:08clojurebotapi examples is http://en.wikibooks.org/wiki/Clojure_Programming/Examples/API_Examples
09:08Raynes(start-repl 4005 :host "localhost") <-- Confusing.
09:08Raynesstart-repl takes any number of optional arguments, but doing that tosses a "Wrong number of arguments" error.
09:09LicenserChousuke: muahaha
09:09RaynesI can't win for losing it seems.
09:11_atoRaynes: older version of swank-clojure didn't accept options
09:12_ato1.0 just takes a port, nothing else
09:12_atolooks like 1.1 is the same
09:12_atohttp://github.com/technomancy/swank-clojure/blob/1.1.0/src/swank/swank.clj#L60
09:12Licenserhmm question: is every namespace in clojure a class in java?
09:13RaynesOh.
09:13RaynesThat's the problem.
09:13Raynes_ato: Thanks.
09:13RaynesDidn't know my version was old.
09:15_atoLicenser: no, each namespace has many classes. Usually at least one for each function/lambda and one for __init
09:15Licenserah sneaky
09:40qbgDid anyone come to Clojure without a Java background?
09:40esjme
09:41qbgDid Clojure's java based exceptions confuse you?
09:43bytecoderclojure's exception/error reporting is still evolving if i'm not wrong. not just exceptions; i've had difficulty comprehending other issues reported as well. it's not a turn off for me though.
09:43Raynesqbg: Yes. It irks everybody at first.
09:44RaynesEventually you get used to shitty error messages and start paying attention to the stack traces.
09:45Raynes$sed #clojure i s/shitty/shoddy/
09:45sexpbotEventually you get used to shoddy error messages and start paying attention to the stack traces.
10:07jwr7Anybody know if clojure-jna (and JNA in general) places any limitations on multithreading? I tried to use pmap with a piece of code that uses JNA and it looks like something gets synchronized.
10:09chouserjwr7: clojure-jna doesn't sync anything, but I don't know about JNA itself.
10:11jwr7chouser: I searched the docs, but couldn't find anything. And yet YourKit clearly show me a checkerboard pattern — I get 16 threads or so, but only one seems to be running at a time.
10:17chouserjwr7: http://gist.github.com/380762
10:18chousercould the native lib you're calling be locking?
10:20jwr7chouser: it isn't — it's just one C function, reentrant and fairly simple. I'm looking at JNA source now, perhaps it's because I was using jna-invoke instead of deifning a jna-fn? (com.sun.jna.Function/getFunction might be blocking me)
10:21chouseryou saw my gist? that uses jna-invoke without apparent blocking
10:22jwr7chouser: Right. That proves it, I guess. So why do I get blocking with pmap — it's the same mechanism, after all…
10:26chouserwell, there are a few more variables there...
10:27chouserpmap uses a different thread pool. Is your input seq chunked? How are you forcing the pmap output seq?
10:28jwr7chouser: I forced the output with doall and the inputs were real lists by then. I'm trying to work out a test case right now.
10:29chouserok
10:54powr-tocWhat's the best way of interacting with databases currently in clojure?
10:54powr-tocclojureql seems like it's a short way off being prime-time...
10:55powr-tocand c.c.sql has warts, but seems to be more stable... is this a fair assessment?
11:01RaynesYeah, I have trouble writing small ones.
11:01RaynesCheck out defrecord's docstring in Clojure.
11:01RaynesOops.
11:01RaynesWrong channel.
11:10AWizzArdà propos defrecord... they they now have a print-dup representation. But there is no constructor which could rebuild them.
11:11chouser,(condp = 99, 1 :a, 2 :b, #_else :unknown)
11:11clojurebot:unknown
11:11chouseris #_else helpful or confusing?
11:11AWizzArdconfusing
11:12AWizzArdOh cool, defrecords are now serializable :)
11:13rhickeyAWizzArd: it would be cooler if http://www.assembla.com/spaces/clojure/tickets/281-make-more-datastructures-serializable patch applied - I was al set to do this Serializable stuff this morning
11:13stuartsierrachouser: confusing
11:13sexpbot"#281 - Make more datastructures serializable (Test) | Clojure | Assembla"
11:15foguschouser: confusing
11:15chouserwow
11:15chouserok then
11:15chouser:-)
11:16chouser,(condp = 99 1 :a 2 :b :unknown) ; it is then!
11:16clojurebot:unknown
11:18stuartsierrachouser: If your condp spans multiple lines, ";;else" before the last line would be helpful
11:18rhickeyick
11:18chouserhm.
11:19rhickey(if x
11:19rhickey ;;then
11:19rhickey y
11:19rhickey ;;else
11:19rhickey z
11:19rhickey ) ;;endif
11:20hiredmanyou could also include the docstring for condp in a comment :P
11:25moshisushirhickey: :D
11:25chouserI'm having far too much fun with :inline
11:25chouserbut I need a better macroexpand
11:26hiredmanmexpand-all?
11:26chouserhm, I don't trust it. But it doesn't do :inline's anyway, does it?
11:26hiredmanno idea
11:26hiredman,mexpand-all
11:26clojurebot#<macro_utils$mexpand_all__4397 clojure.contrib.macro_utils$mexpand_all__4397@b0b955>
11:26hiredman,(mexpand-all '(+ 1 2))
11:26clojurebot(+ 1 2)
11:26fogusrhickey: What did "end." expand to?
11:26The-Kennyrhickey: There's a guy who wants to implement something very similar to lisp macros for c++. His syntax looks like @#wenn a ist 42 dann def b = a+@# ("wenn a ist 42 dann..." translates to "when a is 42 then ..."
11:26hiredmanguess not
11:27The-KennyHe's writing a pre-processor for this
11:28rhickeyfogus: nothing, it just made him happy to see it
11:32stilkovwhat's the point of most macros being defined with (defmacro [& body] ...) instead of (defmacro [body] ...) ?
11:32LauJensenpowr-toc: correct assesment
11:33bsteuberstilkov: you can then offer implicit do for multiple statement (side effects)
11:33chouserif you want real macros on C++, this is interesting: http://voodoo-slide.blogspot.com/2010/01/amplifying-c.html
11:33sexpbot"voodoo slide: Amplifying C"
11:33LauJensenThe problem with ClojureQL is, that at 0.9.7 we decided to rework the entire frontend. And when thats done it will be great, but we have to put in a lot of work and unfortunately we're all very busy atm
11:34AWizzArdWhen should I write a method for print-dup (vs. print-method)?
11:34rhickeystilkov: [body] can only take one form
11:35rhickeyoften macros need to manipulate a variable number of forms
11:36stilkovrhickey: the reason then would be the one pointed out by bsteuber. is it idiomatic to expect macros do wrap the body in an implicit (do ...)?
11:36stilkovs/do wrap/to wrap/
11:36stuartsierrachouser: try "wtf" from Halloway's circumspec
11:37stuartsierraIt's a macroexpansion, name is short for "what the form"
11:37rhickeystilkov: not necessarily, (defmacro add [& body] `(+ ~@body)) doesn't even emit a block
11:38rhickeystilkov: macros like defrecord take variable forms, not related to statements/do
11:38AWizzArdbtw, with print-method go away in 1.2 and get replaced by Protocols?
11:39stilkovrhickey: I see; I may have been thinking of the wrong examples
11:40rhickeystilkov: there are plenty that just dump ~@body into something like a let or do as well
11:41stilkovrhickey: I was wondering about those that don't, yet use [& body] and ~@body anyway
11:41rhickeystilkov: searching for ~@ in core.clj can be instructive into the various uses
11:43stilkovrhickey: thanks
11:43bsteuberI've just been discussing the idea of having and/or being a function that just gets inlined to short-circuit evaluation
11:43bsteuberwould that be a bad idea?
11:44bsteuberI'd love to write (map and boolean-seq1 boolean-seq2)
11:44chouserbut it would *not* short circuit when used as a function
11:44chousersounds confusing to me
11:45bsteuberchouser: I thought so, too, at first - but if you pass sth. as a function to apply etc., the arguments would get evaluated anyways
11:45bsteuberso you'd expect it to do so
11:46chouser(partial and foo) would be greedy on all args
11:46stuartsierrabsteuber: your example could be written (map #(and %1 %2) seq1 seq2)
11:47bsteuberstuartsierra: sure, the idea is just about simplifying this a little
11:48AWizzArd,(every? boolean (concat [1 2 3] [4 5 6]))
11:48clojurebottrue
11:48joshua-choi(doc boolean)
11:48clojurebot"([x]); Coerce to boolean"
11:48joshua-choiI did not know about that
11:48stuartsierraSo (defn add* [& args] (every? identity args))
11:48chouser(map and boolean-seq1 boolean-seq2) used to return something, once upon a time.
11:48stuartsierraI mean defn and
11:49stuartsierraand*
11:49stuartsierrawhatever
11:49chouserbut ... it returned code.
11:49bsteuber:)
11:50bsteuberat least after I thought of it I found the idea less confusing than in the beginning :)
11:50bsteuberbecause in function-land you expect anything to be eager
11:51hiredman(map (comp eval #'and) bseq bseq2)
11:51chouserI'm not sure the boundary between function-land and inline-land is very clear to a lot of people
11:52bsteuberhmm, maybe
11:53chouserhiredman: have you tried that in a recent version of clojure?
11:53chousercalling macros manually is more complicated than it used to be.
11:53hiredmannope
11:53bsteuberchouser: btw, do you think it's ok to use images (with citation, of course) from JoyOfClojure in a talk I give at my university?
11:53hiredmanwhy would I try such a silly thing?
11:54bsteubernot familiar with copyright on images in books
11:54chouserbsteuber: I'd think normal fair-use rules apply.
11:54stuartsierrajust ask the author
11:54stuartsierrawho's not likely to sue you anyway
11:55chouserwell, the publisher has a legal interest, for now anyway.
11:55fogusstuartsierra: Soeak for yourself! ;-)
11:55fogusSpeak that is
11:56stuartsierraSeriously, no publisher is going to bother to sue you for using images in one talk.
11:56bsteuberok, then I'll just do it :)
11:56hiredmanit's a setup
11:56stuartsierrabut it would be considerate to ask the author's permission
11:57bsteuberhm right, I just asked one of them so far :)
11:57fogusMy plan is to make more money off of litigation than book sales.
11:57hiredmansierra talks you into giving the talk, and peddles his expert clojure legal opinions to the publishers law firm and you can turned into a smoking crater
11:57bsteuberchouser, fogus: so you personally wouldn't mind?
11:57stuartsierrahiredman: darn, you've figured out my secret plan!
11:58bsteuberhaha
11:58fogusbsteuber: I do not. Which image(s)?
11:58stuartsierraIANALAIAPOTFETIWAALS
11:59stuartsierraI Am Not A Lawyer And I Am Proud Of That Fact Even Though I Work At A Law School
11:59hiredman* see back of card for consulting rates
12:00bsteuberfogus: at least the mutable runner for now
12:01bsteuberfogus: and maybe the three circles from the start
12:01chouserbsteuber: yeah, as long as you credit the book, I don't mind in the least.
12:03bsteuberchouser: I will for sure :)
12:04LuytHmmm, I think I found a typo in Stuarts book, on page 39 it says "syntax for shorter anonymous function: (#body)" but I think that should be "#(body)"
12:04Luyt,(#(print "Yup"))
12:04clojurebotYup
12:05stuartsierraWhich Stuart?
12:06bsteuberstuartsierra: do you have a book, too?
12:06stuartsierrayes
12:06stuartsierranot published yet
12:06stuartsierraNo one has ever heard of it.
12:06stuartsierraNot even me.
12:06bsteuberhaha
12:07bsteuberbut it's great there's already at least two very good clojure books out there
12:07bsteuber(can't talk about Clojure in Action, yet)
12:07stuartsierrayse
12:07LuytStuart Holloway, "Programming in Clojure"
12:08stuartsierra2010 will be the year Clojure goes mainstream.
12:08Luyteh, "Programming Clojure"
12:08stuartsierraWe'll all have to shop for ties.
12:08LuytISBN 101934356336
12:08chouseris clojureconj still on for this fall?
12:09stuartsierrachouser: what's this?
12:09chouserthe conference
12:09stuartsierraI vaguely remember some talk about that
12:09stuartsierraThen I heard it wasn't in New York, and I stopped paying attention. :)
12:09chouserheh
12:10chouserIf I only paid attention to things around here, I'd have a lot more free time...
12:10stuartsierraBut who knows where I'll be in the Fall.
12:10LuytIf I kept myself to C++, I'd also have more free time. What makes me interested in Clojure?
12:10technomancysupposedly it's still on, but with no call for talk proposals yet I have my doubts
12:15maravillasI'm trying to work with the change in c.c.str-utils* => c.c.string from 1.1 to 1.2, as well as the changed signature for c.c.str-utils2/drop and c.c.string/drop. There's something happening here that I don't understand...any thoughts? http://gist.github.com/380924
12:16stuartsierradon't do that
12:16maravillasWhich part? :)
12:16stuartsierrathe whole thing
12:16stuartsierrajust copy the old namespaces from 1.1
12:17stuartsierraI got to make a ticket for that
12:17maravillassorry, I'm not sure what you're suggesting
12:18stuartsierraIf you want to use the 1.1 contrib functions, use 1.1. I'm nudging people toward copying the old 1.1 namespaces into 1.2 master, with a deprecation warning.
12:19stuartsierraDon't try to support two different versions in one piece of code. That way lies madness.
12:22maravillasHm, I see. Will 1.2 generally be considered a breaking upgrade? That is...should libraries not worry about supporting both? I'm not up to date on all the changes, but it seems silly for me to select one if this particular function is the only difference.
12:22stuartsierraCurrent trend is that 1.2 contrib will deprecate a bunch of namespaces, but will try not to break anything.
12:23stuartsierraCurrent master branch breaks a lot.
12:23stuartsierraThat needs to change.
12:24maravillasAlright, fair enough. I'm still curious what's going on in that snippet, though...I can reference string/drop outside of the try, but I get the exception on the inside.
12:25raekmaravillas: this might be useful: http://blog.licenser.net/2010/04/22/on-clojure-libs-and-versions
12:25sexpbot"lice! : On clojure libs and versions."
12:26danlarkinlol at contrib ticket #20
12:26maravillasI saw that, but it doesn't deal with my second issue, where the signature for the respective drop functions changes
12:28raekah, ok...
12:29digash,(byte 255)
12:29clojurebot-1
12:29digash,(apply byte [255])
12:29clojurebot-1
12:29digashin the latest 1.2
12:29digashuser> (apply byte [255])
12:29digash-1
12:29digashuser> (byte 255)
12:29digash; Evaluation aborted.
12:29digash
12:30digashthe second one throws an exception Value out of range for byte: 255
12:30stuartsierrahttps://www.assembla.com/spaces/clojure-contrib/tickets/79-forward-port-deprecated-1-1-namespaces
12:30sexpbot"#79 - Forward-port deprecated 1.1 namespaces (New) | Clojure Contrib | Assembla"
12:31chouser,(.byteValue 255)
12:31clojurebot-1
12:31digashcool, but i am still confused why the apply works?
12:32stuartsierrabyte is actually a type cast to primitive byte.
12:32chouserit's the difference between function-land and inline-land
12:32stuartsierraIt also happens to work as a function, in which case it coerces to byte. But they're different operations.
12:32digashfeels like a bug to me
12:32chouserwhen used as a function (as with apply), it just does .byteValue on a boxed Number
12:33stuartsierraI kinda wish the primitive coercions looked more like type hints.
12:33stuartsierrae.g. #^byte 127
12:33stuartsierraonly that wouldn't work in the current reader
12:33chouserwhen used inline-ably, it does a cast and thus works with primitives
12:34stuartsierraCould the reader support read-time metadata on non-Clojure types by wrapping them in a special "MetaFoo" object?
12:34digashmaybe (^byte 127) vs (byte 127)
12:35stuartsierraack no
12:35stuartsierrathat would expand to (127)
12:35rhickeydigash: that is a bug, I didn't realize the fn defs weren't calling through RT
12:36stuartsierrarhickey: what do you think of #^byte 127 ?
12:37rhickeystuartsierra: #^ is so day-before-yesterday
12:37stuartsierraok, fine, ^byte 127
12:37stuartsierraone innovation at a time
12:37rhickeyare we talking for literals only?
12:38stuartsierrayse
12:38stuartsierrayes
12:38chouseroh, only literals?
12:38rhickey127b ?
12:38stuartsierrahm, maybe
12:38maravillasIs there a set approach for dealing with deprecated symbols & namespaces? I appreciate that copying the old namespaces helps with 1.2, but when should we expect that we'll have to actually fix things to reference the new ones?
12:38stuartsierraactually, no, I was thinking for symbols too
12:38stuartsierraoh, never mind
12:39stuartsierramaravillas: what else could we expect?
12:39chouserI actually think it's pretty clever how primitive casts are built directly on interop support -- no explicit reader or compiler code needed.
12:40maravillasOf course they'll go away at some point, I'm just wondering if there's a guideline for how long deprecated stuff sticks around.
12:41Licensermaravillas: you can work around it with try catch
12:42stuartsierraDon't 'require' in try/catch!
12:42stuartsierraThat will drive you maaaaad.
12:42Licenserstuartsierra: ma ma ma maaaad
12:42stuartsierraIf you want to use the new stuff, you've got to abandon some old stuff.
12:42stuartsierraIf you don't need the new stuff, you can stick around with an old version as long as you like.
12:45rhickeydigash: fixed
12:46dnolen127b and 1f would be cool for literals
12:47rhickey[b]yte, [s]hort, [i]nt, [l]ong, [f]loat [d]ouble ?
12:48stuartsierral for long is hard to read, but it is consistent
12:48chouserthat'll be the default eventually, right?
12:48rhickeyBigDeci[M]al . BigInteger?
12:48dnolenrhickey: yes! graphics/audio code would benefit from less typing.
12:48chouserlong will be the default eventually, right?
12:49rhickeychouser: I hope so
12:49fogusI think 131l will be tough to catch
12:49digashrhickey: so now it throw an exception always?
12:49chouserif the suffix letter is case-insensitive, 131L is a possible
12:49rhickeydigash: yes
12:50chouserrhickey: If I understand your idea for default primitive literals, throwing on overflow, etc. I've grown to like it.
12:50rhickeydigash: so now these are safe coercions. I'd take a patch for bit-casts
12:50rhickeychouser: I really wish now I had done that up front
12:51rhickeyIt's a big break with Lisp tradition, but much more practical
12:51fogusWhy not make the suffix require caps?
12:51rhickeyfogus: could do, but how would one as for Integer, Long etc?
12:51rhickeyask for
12:51chousercombined with a syntax for literal non-defaults types (50i, etc.) a bunch of tricky problems become easier to handle
12:52fogusrhickey: L131 is long, 131L is Long... :( I got nothing
12:52rhickeyfogus: also I becomes a problem then
12:53stuartsierraif primitives are the default, then there would rarely be a reason to ask for boxed literals
12:53digash(.byteValue n) is the way to get unsigned byte value then?
12:53stuartsierraAnd you could write (Integer. 127) when you need to.
12:53chouserdigash: no such thing as unsigned byte on the JVM. :-/
12:54somniummaybe 123L <- primitive, 123<L> <- boxed ?
12:54stuartsierraugh
12:54fogus131L 131^L
12:55stuartsierraerg
12:55fogusHmmm, nothing looks nice
12:55stuartsierramaybe we should stick with (long 131)
12:55Licenserstuartsierra: but not using require for namespaces would mean we can't make libraries and such that are version independant - that is kind of bad
12:56stuartsierrathere is no such thing as a library that is version independent
12:56Licenserover certain version ranges, yes there is
12:56stuartsierraThen releases within those version ranges should aim for some backwards compatibility.
12:56digashchouser: i meant in java (byte)177, will "translate" int into byte
12:56stuartsierraIn other words, the onus of library compatibility should never be on client code.
12:57Licenserand if I publish my lib for 1.1.0 and somene has a project in 1.2.0 he want's to use the lib for their thing they should be able to do so witout forking the project I think
12:57stuartsierrano
12:57Licenseryes
12:57rhickeystuartsierra: I agree (long 42) is both verbose and not really making it to the compiler
12:57Licensernot on client code stuartsierra but on library code
12:57stuartsierraIf 1.2 contrib becomes supports backwards compatibility with 1.1, then that problem goes away.
12:57LicenserI would not make a app that uses require to work with 1.1 and 1.2. But I certenly made 2 libs arelday that do and they can nicely be included in any 1.1 or 1.2 project
12:58stuartsierraThen they should target 1.1.
12:58rhickeydigash: wow, the spec for byteValue is really bad: http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Number.html#byteValue()
12:58sexpbot"Number (Java 2 Platform SE 5.0)"
12:58Licenserthey should 'just work' for most of the people :P
12:59Licenserif 1.2 c.c becomes backwards compatible, yes the problem goes away but will it?
12:59stuartsierraIf I get my way.
12:59Licenser:P
12:59stuartsierraAnd I have commit access, so who's going to stop me?
12:59Licenserrhickey might
13:00dnolenfor those that will be casting literals to primitive long often, 131l is fine I say, also seems like something that's not hard to highlight with syntax highlighting
13:00Licenserif I support your effort will you make a clojure.controb.silly namespace for me? where can go funtions like (defn rand [& _] 4) ;from xcdk or (defn cokkies [] (println "*nom nom nom*"))?
13:00rhickey1.2 cc becoming backwards compatible is me getting my way too
13:01Licensershush rhickey I was about to con stuartsierra in making a silly namespace!
13:01Licenserdon't backstab my efforts :P
13:01digash,(.byteValue 1234)
13:01clojurebot-46
13:01slyphonso, in the repl (and only in the repl), is it possible to say, add 'pp' and 'pprint' to clojure.core so that it's available everywhere?
13:02stuartsierraLicenser: there's some pretty silly stuff in there already
13:02Licenserstuartsierra: you know if you do that and make 1.2 cc backwards compatible my only usefull blog post in the last 2 years will become meaningless *shakes fist*
13:02stuartsierraheh
13:02stuartsierraThe best code needs no blogs.
13:03stuartsierraYou can quote me.
13:03chouserin your blog
13:03slyphonthat's the main problem with ruby
13:03Licenserheh
13:03slyphoneveryone confuses blogging-about-code with code quality
13:03Licenserstuartsierra: well you can still use a blog to tell people nice things?
13:03stuartsierrasure
13:03livingstonwhat's the correct way to shutdown the repl / swank / etc. from emacs swank-clojure-project ?
13:04stuartsierraBut blog posts are no substitute for good documentation.
13:04dnolenlivingston: I use slime-quit
13:04stuartsierraLicenser: you want silly, check out c.c.apply-macro
13:04tomojlivingston: at the repl, type ',', then type 'sayoonara'
13:04Licenserslyphon: no I don't confuse that but when I started my blog I decided not to make a whine girl dairy but write about things that matter (for me) IT wise so if I don't blog aobut code I blog about hardware and my little cluster of atom boards seemed not to be of interest :P
13:04slyphonhahaha
13:04slyphonwell, i salute your intentions
13:05Licenserthank you
13:05Licenserso the atom cluster was pretty cool even so noone liked it
13:05stuartsierraI have a blog too. I hate myself for it.
13:05livingstondnolen: I don't have that defined? there's a slime-quit-lisp
13:05dnolenlivingston: that's the one
13:06slyphonstuartsierra: yeah, i do too, i just never really update it
13:06Licenserabout 95% of all blogs go along the line 'oh my god a bird pooped on my shoe, my life is so horrible meh meh meh'
13:06stuartsierralivingston: ,quit at the REPL also works
13:06slyphonunless i *really* get annoyed at ubuntu
13:06stuartsierraLicenser: heh :)
13:06livingstondnolen: that'll tear everything down, right?
13:06dnolenlivingston: yes
13:06tomojfor some reason I always use ,sayoonara
13:06LicenserI could blog about cooking too but then I never can write down my recepies
13:06Licenser,sayoonara
13:06clojurebotjava.lang.Exception: Unable to resolve symbol: sayoonara in this context
13:07stuartsierraIt's a SLIME feature.
13:07livingstonstuartsierra: I tried forms of that but you mean with the comma too? (I thought maybe (quit) or (exit) would be bound
13:07stuartsierrano
13:07stuartsierracomma+command is a SLIME feature, there are several commands
13:07Licenser,cookies
13:07clojurebotjava.lang.Exception: Unable to resolve symbol: cookies in this context
13:07kzarIs there an easy way to "map" a tree?
13:08stuartsierraTo kill a standard REPL, Ctrl-C or Ctrl-D usually does the trick.
13:08stuartsierrakzar: (into {} (map (fn [key value] ...)) is the easy way
13:08Licenserkzar: I wrote some code for that
13:08livingstonstuartsierra: yeah I'm in emacs - so that won't cut it
13:09stuartsierrakzar: (reduce (fn [result [key value]] (assoc result...)) {} ...) is the fun way
13:09Licenserhttp://github.com/Licenser/clj-sandbox/blob/master/src/net/licenser/sandbox.clj#L15
13:09livingstonkzar: look at the "zip" routines
13:09tomojlivingston: get at the repl. type ','. now type 'quit' or 'sayoonara', your choice. now hit RET.
13:09Licenserif yo actually mean what I ment by that
13:09stuartsierralivingston: killing the *inferior-lisp* buffer also does it
13:10tomojsimilarly ,i will let you change the namespace
13:10rhickeyseq-contains? for sequential equality lookup?
13:11stuartsierralinear, right?
13:11rhickeyyes
13:11tomojwonder what pushd and popd do, they seem to be undocumented
13:11stuartsierraadding contains-key? or has-key? for associative would be clearer, I think
13:11rhickeythen at least find-doc "contains" will find it, vs includes?
13:11rhickeyor apropos
13:12stuartsierrabut can't break 'contains?' right now, so yeah
13:12Licenserwell people I hop in the bath see you alter
13:13kotarak,(doc tree-seq)
13:13clojurebot"([branch? children root]); Returns a lazy sequence of the nodes in a tree, via a depth-first walk. branch? must be a fn of one arg that returns true if passed a node that can have children (but may not). children must be a fn of one arg that returns a sequence of the children. Will only be called on nodes for which branch? returns true. Root is the root node of the tree."
13:13kotarakkzar: maybe that is what you need?
13:14livingstonkzar: there is a set of stuff in clojure.walk that will help you
13:14stuartsierraclojure.walk must die
13:14stuartsierraI gave birth to a monster.
13:15rhickeytechnomancy: so the performant, often used one should get the long name and the inefficient use-at-your-own-risk one the short name?
13:15chouserhas-key? is shorter than contains?
13:15technomancyrhickey: no, I think "contains?" should be dropped eventually
13:16technomancynot that it should become seq-contains?
13:16rhickeytechnomancy: but it should become contains-key?
13:16technomancyactually yeah, has-key? is probably better than contains-key?
13:16powr-tocwill has-key return the key if present?
13:17rhickeypowr-toc: you have the key in hand when you ask, and what about nil?
13:17kotarakpowr-toc: kind of like not-empty ?
13:17stuartsierrapowr-toc: no, 'get' does that
13:17stuartsierrano
13:17stuartsierraignore that
13:18rhickey,(doc find)
13:18clojurebot"([map key]); Returns the map entry for key, or nil if key not present."
13:18stuartsierraright
13:18powr-tocstuartsierra: yes, fair point
13:19stuartsierra,(contains? #{1 2 3} 2)
13:19clojurebottrue
13:19rhickeywell, the only thing on the table right now is the name for what c.c.seq/includes? does right now, moving into core
13:20rhickeyI don't like includes?
13:21chouserseq-contains? seems nice for that.
13:21stuartsierrayeah
13:21chousercan some remain idiomatic though?
13:21rhickeywhat about rand-nth for rand-elt?
13:21rhickeykotarak: the problem with some is that few will think of that before they've been shown it
13:23kotarakMaybe there should be a Cookbook. "How to do FOO in Clojure..." "Chapter 21: Linear search: (some #(= % x) ys)"
13:23powr-tocrhickey: that happened to me today... It's been a while since I've been coding clojure, and it took a few minutes digging before I found 'some' again.
13:24stuartsierraseq-contains? is good enough
13:25technomancyseq-contains? is nice in that it highlights the fact that it's slow/sequential
13:25kotaraklinear-search-which-is-slow-use-at-own-risk, but jokes aside: seq-contains? sounds ok to me, too
13:25rhickeytechnomancy: great! that's what I was going for
13:26rhickeyso, I have the same concern with readn-elt, thinking rand-nth. Then at least you know that if nth is fast, rand-nth is too
13:26rhickeyrand-elt
13:26stuartsierraImagine if all fns were annotated with metadata describing their big-O performance: could useful metrics be devised from that information?
13:26rhickeya;so, we don't use elt anywhere else
13:27livingstonsome has always gone nice with every, etc.
13:27chouserI don't like "elt"
13:27rhickeychouser: does that mean you like rand-nth?
13:27chouserrand-nth seems nice, yeah
13:27livingstonby the way is there a parallel some? (I know there is a parallel map) I could see myself looking for that in the very near future
13:27technomancyhow about rand-from ?
13:27stuartsierra"elt" is good for situations like (rand-elk herd-of-bison)
13:28rhickeyouch
13:28stuartsierraheh
13:28kotarakmaybe choose
13:28kotarakno, rand-nth is better
13:28stuartsierrayes, joking aside
13:29chouserrand-nth will work on seqs, but force the whole thing and do O(n) lookup?
13:29stuartsierrathat would be more or less consistent with nth
13:30rhickeychouser: whatever nth does, given some random n
13:30rhickeyin range
13:30stuartsierrabut it's got to count first, so that's going to force a lazy seq
13:31rhickeystuartsierra: that doesn't change the big-O
13:31stuartsierratrue
13:32rhickeypeople that use these things on large seqs are asking for trouble. Just want to make that clear to them
13:32stuartsierraRight, (rand-nth (range 100000000)) will blow heap unpredictably!
13:32stuartsierrano, predictably
13:32stuartsierranever mind
13:32rhickeyI can't help people that do that
13:34chouserwell, ranges could be Indexed. :-)
13:34stuartsierraactually, having a real Range object might be useful someday
13:35rhickeywe had one, and it implemented Counted
13:35stuartsierraoh, what happened?
13:36rhickeyit became a testing ground for chunks
13:36LauJensenrhickey: chunks going away soon? :)
13:37stuartsierraoh, so it was cut up into chunks and sold?
13:37rhickeyLauJensen: no
13:37LauJensenrhickey: Thats sad. I was hoping your new cell construct could eliminate the need for them
13:38rhickeyLauJensen: only so many hours in a day here
13:38stuartsierra:)
13:39LauJensenrhickey: Yea we're all feeling it. My question didn't have an end-date, so I was just poking at whether or not it was in the pipe for 1.3 or 1.4 etc
13:39rhickeyhow much do people care about group-by returning a map that is sorted?
13:39stuartsierranever noticed it did
13:39arohnerrhickey: I wrote my own unsorted group-by so I could use transients
13:39rhickeyarohner: exactly
13:39Licenserwell night people
13:41kotarakrhickey: never needed sorted group-by, got bitten by it once.
13:42rhickeykotarak: bitten how?
13:42rhickeynon-comparables?
13:42kotarakrhickey: I think so. IIRC. Was a while back.
14:06slyphonyou know, the java interop stuff would be a little easier to use if calling it could be more dynamic
14:07mefestohey everyone, i have a newbie style question. with the names invoice-inc, invoice-str... am i not using namespaces the way i should be? should names that match core function names be avoided? http://pastie.org/937655
14:07slyphoni.e. pulling the literal symbol as the method that . is going to call makes it kind of difficult for a non-lisp-master
14:08mefestoi guess i'm wondering if invoice/str is preferred to invoice-str ?
14:09joshua-choimefesto: The answer is not clear-cut.
14:09slyphonwell
14:09slyphonshadowing core function names is probably a bad idea
14:09chouserslyphon: I don't quite know what you mean yet
14:09chousernot necessarily. nothing wrong with invoice/str
14:10chousernot really much wrong with invoice-str either. :-)
14:10joshua-choislyphon: Actually, shadowing core function names was actually preferred when possible, according to a draft of Clojure style people were making on clojure-dev.
14:10slyphonchouser: it's very difficult to do this: (. blah (some-method-name-that-i-constructed-elsewhere arg1 arg2))
14:10slyphonjoshua-choi: uh, wut?
14:10chousermefesto: invoice-inc is (update-in inv [:num] inc)
14:11slyphonjoshua-choi: seriously?
14:11stuartsierraslyphon: that's explicitly not allowed
14:11slyphonstuartsierra: but why?
14:11joshua-choislyphon: Let me try to find it
14:11stuartsierrareflection
14:11slyphoni'm confused
14:11slyphonthere are legitimate reasons for wanting to do stuff like that
14:11stuartsierra(. object (method ...)) can become a bytecode method call, with appropriate type hints.
14:12slyphonok, but what if you're willing to take the performance hit?
14:12stuartsierraThen use reflection.
14:12stuartsierraRT/invokeMethod or something
14:12slyphonhrm
14:12slyphonis that documented?
14:12stuartsierrano
14:12joshua-choislyphon: http://groups.google.com/group/clojure-dev/browse_frm/thread/d090b5599909497
14:12slyphon...
14:12stuartsierrabut java.util.reflection is
14:13slyphonyeah, but that's a pain in the balls
14:13joshua-choiMy language was too strong; it's not "preferred", but "don't be afraid to".
14:13slyphonstuartsierra: sorry, i know that's a poor argument
14:13chouser,(clojure.lang.Reflector/invokeInstanceMethod 4 "toString" (to-array []))"4"
14:13clojurebot"4"
14:13stuartsierrasorry, that should be java.lang.reflect
14:13slyphoni don't mean to be a whiny bitch
14:14chouserslyphon: there are legitimate reasons to do that, but not as often as you might think, and doing it efficiently can be tricky
14:14stuartsierraThe dot special form can't be dynamic and avoid the reflection at the same time.
14:14chouserit's a kind of meta-programming and should be approached with caution, or at least that appears to be Clojure's take. Other (slower) JVM languages may take other approaches.
14:15chouseron techinque I've used is to (eval `(fn ...)) and cache the resulting fn.
14:15chouserthis is relatively succinct and quite fast after the initial eval
14:15stuartsierrahuh
14:16slyphonso (eval `(fn [] (. ~thing ~@arglist)))
14:16slyphon?
14:16chouseryeah
14:16chouser,(let [s (eval `(fn [n#] (. n# ~(symbol "toString"))))] (map s (range 4)))
14:16clojurebotDENIED
14:17chouser:-( he hates my metaprogramming.
14:17slyphonhahaha
14:17slyphoni'll try that in my repl
14:17stuartsierraIt makes a kind of sense: you're generating thunks that contain compiled method calls.
14:17kotarakThe lesson for using eval...
14:17chouserstuartsierra: exactly
14:17stuartsierraActually similar to what the compiler itself does, I think.
14:17slyphonah
14:18slyphonok, well, that makes sense
14:18cgrandrhickey: (joining the party late) on group-by, I'd like it to take 4 args: [key-fn f seed coll], the 2-args case would then call (group-by key-fn conj |] coll)
14:18chouserwell, not a thunk exactly, but yeah -- implementing IFn via eval :-)
14:18stuartsierraright
14:18slyphonstuartsierra: and the argument for performance is a compelling one
14:18slyphonas long as there's "a way to do it" that doesn't require pulling out the "big gun" of Reflection
14:19slyphonwell, it's kind of a big gun to me
14:19chouserslyphon: depending on the circumstances, a macro or :inline fn may work and be easier than caching eval results
14:19slyphon:inline ?
14:19chousermore undocumented compiler fun. :-)
14:19slyphoni've tried that above with a macro and didn't get far
14:20cemerickouch; at some point Region lost its DEFAULT value, so the ebs wrapper is now broken; gotta get some AOT-compilation into the build process so that stuff gets caught...
14:20kotarakslyphon: macros only get you to compilation
14:20cemerickugh, sorry, wrong channel
14:20slyphonmmarczyk and i tried that for a while
14:20chouserfor both macros and :inline, it only works if you can compute the method name at compile-time.
14:20slyphonahh
14:20slyphonyeah, that's probably not gonna work here
14:20chouserwhere are you getting your method name from?
14:21slyphonin this case it's pretty static, but the number of args changes
14:21slyphonin the case with mmarczyk, i was trying to write a complement to the 'bean' function that let you update a bean
14:21slyphon(i wound up using reflection)
14:22chouserI've been doing some crazy/fun stuff along these lines with Google protobufs.
14:22slyphonoh yeah?
14:22chouserBut it's for work, so I'll have to jump through some hoops to get it open-sourced.
14:22slyphoni've been meaning to look at those
14:23slyphonit sounds really interesting
14:23chouserif you can get away with slinging clojure s-exprs around as text or something, I highly recommend that.
14:23chouserprotobufs are all static and java-y
14:23slyphoni was gonna ask
14:23stuartsierrachouser: tried avro?
14:24chouserbut if you need them (in my case for interop with other services that use protobufs) they can be made pretty fast and convenient in Clojure.
14:24slyphonif i wanted to serialize a clojure data structure and stick it in a javax.jms.TextMessage, how do i do that, then un-freeze-dry it
14:24slyphon?
14:24stuartsierraslyphon: prn-str, then read-string
14:25lancepantzwe use protobufs
14:25slyphonok, i kinda thought that was it
14:25chouserstuartsierra: no, I haven't. I wasn't involved in choosing protobufs, just using them.
14:25stuartsierraprn/read only works for simple cases, though
14:25stuartsierraah
14:25lancepantzthey are really really fast, we use atomic appends as well
14:26chouseravro sounds interesting though
14:26slyphonoy, *another* apache project?
14:26slyphon;)
14:27slyphonguys, give someone else a chance!
14:27stuartsierraI think Avro grew out of Hadoop, actually.
14:27slyphonyeah, looks like it
14:27stuartsierraHadoop had its own binary serialization protocol that nobody used.
14:27LauJensennobody used?
14:28stuartsierraYeah, it was called Hadoop Records or something.
14:28lancepantzhas hadoop switched to avro now?
14:28stuartsierradunno
14:28LauJensenOh that one. They had that Binary format where you could munge a bunch of files together which was quite useful
14:29stuartsierrano, that's still there
14:30LauJensenI should really blog more about Hadoop, so much cool data to be crunched
14:37LauJensenWhat is this ibm-jdk-clojure-build stuff on build.clojure.org?
14:37dysingerI added it
14:37dysingerfor stuart holloway
14:37dysingerto test for bugs in clojure 1.2
14:37LauJensenits a test suite of sorts? Or just targeting a different jvm ?
14:38dysingerdiff vm
14:38LauJensenah ok, thanks
14:43livingston_afki messed with protobufs for a while in common lisp, mostly because I wanted to make it into a tutorial on how you could hack the reader to read the format file - it was panning out to be pretty straightforward (only a few files of code), but I let it die
14:44livingston_afkconsidering it was mostly thesis-avoidance it kinda had to go -- maybe I'll pick it up again someday
14:47livingstonis there a convenient way to give struct-map a default map to extend?
14:48livingstoni mean I can merge, I just thought there might be something else
14:54stuartsierrano
14:55livingstonyeah now that I look at it, I kinda like the merge anyway
15:07LauJensenWhen you guys are running off the latest versions on github, which version of swank do you use with that ?
15:07stuartsierra1.2.0-snapshot
15:08LauJensenstuartsierra: Do you pull everything via deps or build yourself?
15:08stuartsierraI use maven
15:08LauJensenHow?
15:08clojurebotwith style and grace
15:08technomancyLauJensen: you should be fine using the version on clojars
15:09LauJensenk
15:09Chousukeheh, sometimes clojurebot amuses me :P
15:09technomancyand there should be a new release soon
15:09technomancyfingers crossed.
15:09LauJensennew release as in ?
15:09technomancy1.2.0 stable
15:10LauJensenah ok. How often are the snapshots pushed to clojars?
15:10technomancyit's not automated, but it happens often enough
15:11technomancythe swank-break stuff is in there, but not a lot has been committed since then
15:12LauJensenIf not I'll email your employer explaining why he must fire you so that the opensource community can live on :)
15:12technomancymoar free time!
15:12technomancylast time I lost my job I wrote the Clojure PeepCode screencast =)
15:14technomancyLauJensen: hugod is also a committer on swank now, so if I am a bottleneck there is a workaround =)
15:14LauJensenlein new produces a bad :dependencies (old version?) and searching clojars for the clojure line is impossible
15:14LauJensenhugod: Its a privilegde watching hugo go, man that guy works fast :)
15:14LauJensenprivilige
15:14LauJensenprivilege
15:14LauJensenhmm, thats looks right
15:15hugodLauJensen: :), I built a time machine in my free time
15:15LauJensensensible place to start
15:15technomancyLauJensen: interesting; could you submit an issue for that?
15:15LauJensenI could... :)
15:16LauJensentechnomancy: can you drop the lines for lein, for the latest and great clojure, contrib and swank ?
15:17dakronewhat's the best way to expand something like (my-func '(2 3 4)) into (my-func 2 3 4) ?
15:17technomancysure: [[org.clojure/clojure "1.2.0-master-SNAPSHOT"] [org.clojure/clojure-contrib "1.2.0-SNAPSHOT"] [leiningen/lein-swank "1.2.0-SNAPSHOT"]]
15:17technomancythough you want lein-swank in dev-dependencies actually
15:17kotarakdakrone: apply
15:17LauJensenthanks
15:18dakronekotarak: cool, thanks
15:19LauJensentechnomancy: issue reported
15:19technomancythanks
15:20LauJensentechnomancy: btw - Loved that post you did on your pedantic requirements for contribs
15:25chousertechnomancy: looks like you're using c.c.condition -- how's that going?
15:26technomancychouser: I like it quite a bit
15:26dysinger"LauJensen: If not I'll email your employer explaining why he must fire you so that the opensource community can live o" <- lol
15:26dysingerno emails needed
15:26dysinger:)
15:26LauJensenok, phil is *poof* :)
15:27dysingerno we need phil
15:27technomancyoh noes!
15:27chousertechnomancy: excellent. I've been hesitent to walk away from vanilla throw/catch
15:27technomancychouser: with contrib ticket #80 you can catch vanilla Exceptions in handle-case forms
15:28technomancywhich makes them mesh fairly naturally
15:28chouseryeah, I saw that. looks good.
15:29hugodwhat's the distinction between condition and error-kit?
15:29chousercondition is might lighter-weight
15:29chouser-might +much
15:29LauJensenand condition is might heavier-weight
15:30LauJensen(sorry couldnt resist =)
15:30technomancyI like the idea behind error-kit, but it seems like it would be more useful if everyone else used it. it seems like it's subject to more of a chicken/egg dilemma
15:30LauJensenwhat dilemma? chicken came first
15:30stuartsierradinosaurs had eggs
15:31chousererror-kit provides rarely-used features around outer dynamic scopes controlling the behavior of inner 'raises' and handlers.
15:31chouserand for free you also get a clumsy undocumented object system
15:32ordnungswidrigre
15:33hugodI miss CL restarts, very useful in slime
15:33LauJensenhugod: go implement, chop chop
15:34chouseryou might be able to do something interesting with debug-repl + error-kit
15:34hugodwell, patching condition/raise to call swank-break would be easy
15:34chouserbut you'd probably be better off just using a Java debugger
15:34LauJensenchouser: only problem is, that they're hard to fit into Emacs
15:35chouserJava debuggers? Someone did it already.
15:35cemerickis JDEE still unpleasant?
15:35chouserall java is more pleasant from Clojure, even JDEE. :-)
15:36algoriffichi all, how do i print out all nodes at a certain depth of an arbitrary tree structure?
15:36hugodLauJensen: haven't had time to do that yet...
15:37LauJensenk
15:40digashhmm, interesting message from defprotocol: Warning: protocol #'bar.foo/PacketHeaderReader is overwriting method foo of protocol MessageHeaderReader
15:40digash
15:40chousertechnomancy: would there be any value in the Condition instance printing its values?
15:40stuartsierradigash: that's a bug with AOT-compiled protocols
15:41stuartsierraI think
15:41chouserreally?
15:41stuartsierraif the method names are the same
15:41stuartsierrabut that's not what digash posted
15:41chouseryou can't have two protocol methods with the same name for two different protocols in the same namespace
15:41chouserAOT or not
15:42digashwhy is that?
15:42chouserthey're namespaced to the namespace, not to the protocol.
15:42digashhmm, i am generating protocols in the macro, need to figure out how to do it then.
15:43chouserjust think about how you'd call the protocol method and it should make sense.
15:44chouser(defprotocol Foo (bar ...) (baz ...)) (my.ns/bar ...) ; note no Foo in the method call
15:45digashah, i see, it is different from deftype fields
15:46digashi need to generate accessors to my generated deftypes
15:46digashfields
15:48chouserhm... or have them implement ILookup so you can do (:my-field obj)
15:48fogusSo for type (deftype Foo [a b])
15:48fogusand (def x (Foo. 1 2))
15:48foguswe can currently do (.a x)
15:49fogusBut maybe that is not going to be true tomorrow?
15:51chouserfogus: That's documented and pretty well guaranteed I think
15:51chouser"The class will have the immutable fields named"
15:51fogusSo accessor problem solved then?
15:53digashwhat about definterface, are the names of methods also namespaced?
15:53digashalso what is hms? hash-map-set?
15:54chouserdefinterface produces an interfaced ("namespaced" in a Java package) with Java methods ("namespaced" in the interface)
15:56digashmaybe i need that, then the java api would make more sense
16:04digash,(definterface Dig (foo-bar []))
16:04clojurebotjava.lang.Exception: Unable to resolve symbol: definterface in this context
16:05digash(show Dig)
16:05digash=== public abstract interface user.Dig ===
16:05digash[ 0] foo-bar : Object ()
16:05digashshouldn't it put _ in the name?
16:05chouserI think there's a ticket for that
16:06digashchouser: cool, thanks, just making sure my expectation is correct
16:07chouserthough I'm not finding it now
16:08chouserdigash: https://www.assembla.com/spaces/clojure/tickets/306
16:08sexpbot"#306 - definterface does not convert - to _ (Fixed) | Clojure | Assembla"
16:09tcrayfordthat's been fixed recently that one
16:09tcrayfordjust saw it when I was looking through the commit log for clojure
16:11tcrayford,(doc group-by)
16:11clojurebot"([f coll]); Returns a sorted map of the elements of coll keyed by the result of f on each element. The value at each key will be a vector of the corresponding elements, in the order they appeared in coll."
16:13digashhmm, it is still broken in clojure-contrib-1.2.0-20100427.200505-82.jar
16:15chouserwell, turns out that patch only munges package names, not method names.
16:16rhickeydigash: might I ask why you would have an interface with an invalid Java name?
16:16rhickeydo you really want to expose name munging to Java clients?
16:17digashi started with defprotocol but ran into issue of namespace methods
16:17digashthey i thought let me use interface
16:17rhickeythe only reason we are supporting -/_ in packages is because people are already in my-ns...
16:17rhickeydigash: what was the namespace methods issue?
16:18digashand make it also available to java people
16:18digashyes
16:19rhickeydigash: what was the namespace methods issue?
16:19digashsorry, i misread you question
16:19digashi would not call it an issue, more ignorance on my part of protocol
16:20digashi though protocols are like interfaces
16:20digashand will generate java interface classes
16:20rhickeythey will
16:21digashthen i am confused about the method names in the protocol being namespaced NOT including the protocol name
16:22rhickeymy.ns/Protocol becomes my.ns.Protocol interface, protocol method foo becomes interface method foo
16:23digashmy.ns/Protocol1, method foo gives me a warning
16:23rhickeyyou wanted my.ns.Protocol interface, Protocol_foo method?
16:23rhickeywhat warning?
16:23digash<digash> hmm, interesting message from defprotocol: Warning: protocol
16:23digash #'bar.foo/PacketHeaderReader is overwriting method foo of protocol
16:23digash MessageHeaderReader [15:39]
16:23digash
16:24rhickeyright, protocols put fns in the current namespace, so two protocols that define the same-named fn must be in different namespaces
16:25rhickeyyou can think of protocols as a way to define a set of fns in your ns
16:26rhickeystill subject to the one def of name per ns
16:27digashthe interface = protocol thing confused me, since it is possible in java to do it with interfaces
16:27rhickeyto do what?
16:27rhickeytwo interfaces in same package with same method name?
16:28digashmy.ns/Interface1 (foo) and my.ns/Interface (foo)
16:28digashyes
16:29chouserdigash: depending on what you're trying to do, you could have your macro generate a whole namespace for your protocol.
16:30digashyes i guess i can do it, but I prefer it to be javaish
16:30digashsince people are going to use it from java
16:31chousermaybe you want to use definterface and munge the method names yourself. my-method -> myMethod
16:31rhickeychouser: this seems independent of the munging
16:32rhickeydigash: how would you use it from Clojure?
16:33chouserI haven't seen much pushback on the inability to share proto-method names in multiple protos of the same ns. digash seems to be running into it because of generating the names in a macro
16:34digashI would generate deftype or defrecord and the implementation for them
16:34digashit is like a small compiler
16:35digashthe methods are very repetitive, it is a parser for the byte array and each method have offset and length and datatype
16:35rhickeychouser: I could see it coming from requirements that the Java side look like a.b.C and a.b.D interfaces, both with method foo. Couldn't deliver with protocols as it stands
16:36chousersure, I can see that. Though it's an interop concern that definterface deals with already.
16:37digashchouser: i am implementing munging with definterfaces as we chat...
16:38chouserdigash: where are you getting these method names (with dashes in them) from?
16:38digashdata dictionary based on the spec
16:39chouseris there a reason you don't want them to have javaCamelCase names in the spec?
16:40digashthere are hundreds of them and i copied it from the spec with spaces and replaced spaces with -
16:40digashso now i need to do camel-case on them
16:40rhickeyJava devs wouldn't expect _s usually
16:41chouserso even from the clojure code you'll be using camelCase and java interop syntax?
16:43rhickeyyes, that's what I'm missing, how do you intend to implement and consume on the Clojure side?
16:44digashi made it a macro, so i can bounce off the client, the names of methods
16:45digashthe consumption would be to call a constructor with byte buffer
16:45rhickeyand the method calls via interop?
16:45digashand then call any accessor and get a field value back
16:46digashah, i see, another ignorance on my part
16:46rhickeydigash: not necessarily, it could be some missing feature
16:47chouserheh, I guess you could generate one protocol per namespace (with dashed-names), and extend it to all the generated interfaces (calling camelCase methods)
16:47digashthe methods on the defrecord are not available in java ?
16:47rhickeye.g. it would be easy to let defprotocol specify the name of the interface type
16:47rhickeydigash: the only methods you can have in defrecord are those in interfaces, and thus consumable in Java via those interfaces
16:48digashnot the ones on the protocol
16:48rhickeydigash: yes, those too via its interface
16:49chouserif it feels like magic, that's because it is.
16:49rhickeyall methods of a deftype/record are available from Java
16:50rhickeynot extends of course
16:50digashok, let me restate my understanding of protocols
16:51digashdefprotocol will give me java interface
16:51chouserdigash: if I understand what you're implementing now, you'll have an interface with camelCase accessors, and you'll be able to call those on an record that implements it from both java and clojure
16:51mtmbefore I roll my own, does anyone know of a GML (Graph Modeling Language, not Geography Markup Language) parser for Clojure (or, barring that, one for java)?
16:51chouserbut from clojure, it'll look like java interop: (.foo myrecord)
16:51rhickeydigash: yes, with interface type name my.ns.Protocol
16:52digashdefrecord "implments" that protocol and gives me class
16:52digashthen i can call the methods on the class through the interface
16:53rhickeydigash: when you implement the protocol inline, the resulting record isA my.ns.Protocol. You never leverage that from the Clojure side explicitly
16:53rhickeydigash: you'd call them that way from Java, but use my.ns/foo from Clojure usually
16:54rhickeydoing so does away with all of the interop cruft and need for type hints, (foo x) is the same as (.foo ^my.ns.Protocol x)
16:56digashnow, i see where the requirement for the namespace coming from
16:56clojurebotnamespaces are (more or less, Chouser) java packages. they look like foo.bar; and corresponde to a directory foo/ containg a file bar.clj in your classpath. the namespace declaration in bar.clj would like like (ns foo.bar). Do not try to use single segment namespaces. a single segment namespace is a namespace without a period in it
16:58slyphonwith .. do you have to wrap thunks in () ?
16:58chouserwe haven't deprecated .. yet?
16:58slyphon:(
16:58slyphonuh
16:59slyphonshould i use -> then?
16:59stuartsierraslyphon: to answer your question, no
16:59chouserI always recommend it, but I've been shot down on that point by Important People, so take it for what it's worth.
16:59digashi think i am going to stick with interfaces for now, since one of my goals is a java api and create names to look like java accessors getField, etc.
16:59slyphoni like ->
17:00digashrhickey: thank you for clarifications
17:00chouserwhat do you mean by thunks in .. ?
17:00digashchouser: thank you for suggestion
17:00slyphon(.. thing getSomething (add blah))
17:00slyphonbeing thing.getSomething.add(blah)
17:01slyphoner
17:01slyphonbeing thing.getSomething().add(blah)
17:01chouserah. right, what stuartsierra said. no need for parens if you only have the method's name there
17:01slyphonkk
17:01Borkdude-> is like a spear which forces your objects to accumulate through functional spheres
17:01slyphonBorkdude: :D
17:01slyphon->> is that but harder
17:01slyphonblasts them clear to the other side of the parens
17:07ataggartI liked the notion that -> is for banging on an object and ->> is for banging on a stream
17:08ataggartinferred from something Rich wrote once
17:08Chousukehm, why does that sounds painful to me?
17:08Chousukelike, you're mutating an object by banging it with a hammer or something
17:08Borkdudeslyphon, how does Clojure's -> behave in comparison with C's --> operator? http://www.guyrutenberg.com/2007/11/19/c-goes-to-operator/ ;-)
17:08sexpbot" C’s “Goes To” Operator by Guy Rutenberg"
17:08chouserI always thought it was about how many open-mouthed people were trying to eat the cookie on the left.
17:09chouserno, actually, I didn't.
17:09slyphonhahahhaa
17:09slyphonwhere is the -?> hiding?
17:10slyphonBorkdude: wow, nothing like that
17:10slyphonBorkdude: that's kind of cool, though
17:10slyphonBorkdude: in a "Oh my god C syntax is totally retarded" kind of way
17:10Borkdudehaha
17:10slyphon"Please stop doing that, it's going to fall off eventually"
17:16Borkdude"Most programmers know Lisp for its parentheses. Few programmers know their power."
17:18BorkdudeI was thinking, while reading The Joy of Clojure about vectors being so ubiquitous in Clojure, if Lists to present code is still the right choice? Probably, because you always start with the head of a program and then the rest?
17:20stuartsierraIn general, Clojure uses lists for things that will get evaluated somehow.
17:20stuartsierraAnd vectors for things that won't.
17:24Borkdudestuartsierra: things that will get evaluated... I can think of one example: code
17:24stuartsierrayeah
17:24stuartsierraI think I misunderstood your question.
17:25BorkdudeI'm just checking if you had other things than code in mind
17:27Borkdudeputting code into vectors instead would be back to GW-Basic: goto 10 ;P
17:29Borkdudestuartsierra: it isn't entirely true btw, Clojure uses vectors for argument 'lists
17:29Borkdude', those will get evaluated first
17:30BorkdudeBut I'm just thinking out loud while being very tired, I better not do that
17:36rich_holygoathi folks
17:36rich_holygoatI just ran into an annoying impedance mismatch; thought I'd run it past the IRC brains before hitting the list
17:37rich_holygoatdeftype generates final classes; JAX-WS mandates that its classes be non-final. Is there any way to force deftype's classes to be non-final?
17:38chouserand an interface won't do?
17:39rich_holygoatchouser: it's the implementing class that gets annotated as a WebService, not its interface
17:39rich_holygoat"implementing class must not be declared final and must not be abstract... must have a default public constructor... must not define a finalize method..."
17:40rich_holygoatI don't know why, but there it is
17:44BorkdudeCool, Clojure in Action MEAP update
17:48rich_holygoatah, reading the compiler source it looks like individual fields can have final removed by marking them as mutable, but the class as a whole is always emitted as final (and public, for that matter)
17:50chouserrich_holygoat: you might have to use gen-class to meet such specific requirements.
17:50rich_holygoatfalling between two stools -- gen-class doesn't yet have annotations (though I see the patch in Assembla)
17:51rich_holygoatI do wonder precisely why the generated class is final -- it might just be that all other classes generated by Clojure using this mechanism are final, so it's this way by default
17:52rich_holygoatperhaps I'll ping Rich and see if he has a reason; I'm not averse to doing the patch work.
17:53chouserClojure doesn't like implementation inheritence.
17:53chouserpure virtual abstract interfaces or concrete final implementations -- take your pick. :-)
17:54rich_holygoatand neither do I -- but it does allow volatile and mutable fields in deftype to allow "rolling up the sleeves". In this case it wouldn't be used for inheritance; merely to satisfy JAX-WS's demands
17:54rich_holygoatit would be a shame to have to add another layer of passthrough
18:05livingstonI'm assuming alter-var-root is thread safe and will alter for all threads like this: (def foo 5) (binding [foo 2] (pr foo)) ;some other thread alters foo with inc (pr foo) -- I expect to see 2 and 6 printed right?
18:05rhickeyrich_holygoat: what are JAX-WS's demands?
18:05livingstonas long as I'm not under the scope of a binding form I always get the current root value, right?
18:05BorkdudeI made a foolish little program that runs things like this: (def ops ['(goto 2) '(goto 4) '(println "two") '(goto 1) '(println "end")])
18:05Borkdude
18:06rhickeylivingston: yes
18:06technomancylivingston: yes, but in general if you've already got multiple threads running I would say it's too late to be thinking about alter-var-root
18:06technomancyit's a matter of taste, but that's my take on it
18:06rhickeytechnomancy: not really, with no bindings it still makes sense
18:07technomancyrhickey: ok, maaaaybe, but it still needs big caution signs all over =)
18:09livingstonI've got this problem where RDF databases can communicate with an abbreviated URI, using an identifier for the namespace instead... I can query the server for the current mappings - constantly. but since my code is creating them, it'd be nice instead to juse cache them as they are created
18:09livingstonas long as the mapping is cached before it's used, that seems like it'll be ok
18:12livingstonthe problem I'm worried about is one thread stores with a piece of short-hand, and later another thread gets it back, either the mappings have to be cached somewhere, or the threads have to ask every time they talk for the mappings in case new ones were added -- I think
18:12rich_holygoatrhickey: just sending you an email; saves spamming the channel. In short: non-final classes and a bunch of other things.
18:15livingstonI'm also assuming binding something to itself is relatively benign?
18:49sattvikrich_holygoat: I am guessing that once the gen-class annotation patch is in, that should solve your problems. It gen-class generates non-final, public classes. It should also allow you to have some state and a default constructor.
18:50vinHow can I find out if "hell" is in "hello world"
18:51dakronevin: (re-find #"hell" "hello world")
18:51rich_holygoatsattvik: yes, that's one option; but if non-final deftypes are simply an omission, I'll take that route.
18:52woobyChousuke, thanks for the tip on that futures macro gist
18:54sattvikrich_holygoat: deftype certainly is nice. The other problem is that if you want to have fields with a deftype, you cannot have a no-arg constructor.
18:55rich_holygoatsattvik: yup. fortunately I don't need fields (servlets etc. typically use a session for that -- they're stateless). deftype is really nice by comparison to gen-class for my purposes.
18:56sattvikrich_holygoat: That's good. I ran into the no-arg issue when trying to extend my EJB example with a stateful EJB.
18:58rich_holygoatah, tricky :)
18:58slyphonwoah, it never occurred to me, you can put a start-fn in a struct
18:58slyphon~ wacky! ~
18:58clojurebotExcuse me?
18:58slyphon:)
18:58slyphonclojurebot: botsnack
18:58clojurebotthanks; that was delicious. (nom nom nom)
19:07raekvin: a non-regex version (not= (.indexOf "hello world" "hell") -1)
19:36livingstonis there a reason this is giving me a NullPointerException? (def *kb* nil) (alter-var-root *kb* #(if *kb* *kb* a-kb))
19:37livingstoncan I not refer to something in it's alter form? (I guess I could call defonce, but this may get called a lot, I thought the alter seemed "cleaner")
19:47zakwilson_Is there a built-in (or in contrib) more performant way to persist built-in data-structures to disk than (spit (str foo))?
19:47technomancylivingston: your function needs accept one argument, the current root value of the var
19:48technomancynot sure if that would cause a NPE
19:50livingstontechnomancy: that just dawned on me but... there still seems to be an issue:
19:50ataggart(alter-var-root #'*kb* #(if-not % "something"))
19:50livingstonoooooh I have to #' the var?
19:50ataggartya
19:51ataggartcuz *kb* isn't a var
19:51ataggartor rather, it doesnt resolve to a var
19:51ataggartif I jave my lingo correct
19:51rhudsonlivingston: is there a reason you're not doing something like (def abbrevs (ref {})) -- I mean, using a ref or atom for your URI abbrev data?
19:52livingstonthere's no reason for it to be a ref, that I can tell
19:52rhudsonatom then?
19:52livingstona var does the same thing, right? just no transaction support, right?
19:53rhudsonSeems like atoms are designed for what you're trying to do.
19:55livingstonI guess atoms would work, but if I wanted to cover the values up with a binding I would then need to bind over it with a new atom etc. I just don't see what it buys me?
19:56livingstonan atom would allow the threads to stay in sync, but I don't think that's really needed in my case
20:04_rata_how do I get the minibuffer information that clojure-swank gives while at the REPL buffer in the other buffers as well?
20:05livingston_rata_: you mean the function call signatures and things?
20:07_rata_livingston: yes
20:08livingstonmy buffers are in mode: (Clojure Slime[clojure]) and seems to work fine for me (w/ AquaMax) it's autodetected on .clj files you might have to add hooks in your .emacs
20:08livingston(add-hook 'lisp-mode-hook (lambda () (slime-mode t))) (add-hook 'inferior-lisp-mode-hook (lambda () (inferior-slime-mode t)))
20:09livingstonthat's pretty standard though, nothing special
20:15_rata_oh thanks, livingston :)
20:16livingstonnp, did that work?
20:17_rata_I did work before, but I had to press the spacebar after defn for it to show the help... I was standing over a piece of code already written
20:38livingstonif I have (defmulti clj-ify type) is there a way to then define a defmethod that will accept any of a list of types? or do I defmethod for each type?
20:41mmarczyk(map #(defmethod clj-ify % [_] :foo) [String Integer])
20:41mmarczykalso, how about calling it clojurify? :-)
20:42mmarczyk(just checked that map at the repl -- seems to work; perhaps it would be best to wrap it in a dorun, though)
20:42Blktsounds like a World of Warcraft spell
20:43mmarczykit *is* a World of Warcraft spell! cast clojurify on your sword and it becomes imbued with a spirit, which you can programme in Clojure
20:43BlktPerl monk style?
20:43Blktcasting spells with Clojure
20:43Blktomg
20:43mmarczyk:-)
20:44livingstonyeah, I'm not sure that's worth doing .. it's just one liners, I'll think about it though if I get annoyed with this though
20:44Blkt(is it forbidden here to to use acronyms?)
20:44mmarczyklivingston: the proper way would probably be to derive a new relationship
20:44mmarczykfrom the types to, say, ::MyGroupOfTypes
20:44mmarczykand than use that as the dispatch value
20:46livingstonyes I could isa them together... might do that
20:46mmarczyk(Blkt: forbidding acronyms!? doesn't that get one lynched in the IT community?)
20:47mmarczyklivingston: that buys you one more thing, namely you only have the one implementation of the multimethod
20:48mmarczykif you change that, the change will work for all the types involved
20:48mmarczykand there's always underive to kick out a type from the club
20:51livingstonyeah I think I will create a pseudo class for this
20:52livingstonit's kinda cool, in java there are like 10 classes but they all implement the same 3 functions, and clojure doesn't care when it comes time to call those 3 functions what it's being passed, it'll find the right thing
20:52livingstonso I can treat the 10 or whatever things as if they are the same
20:56mmarczyk:-)
21:05slyphonman, i just suck at recursion
21:09livingstonwhere there are multiple java methods with call signatures that maybe could be ambiguous to clojure, how can I make sure the right one is being called
21:10livingstone.g. this method has signatures Object Object Object Object and boolean Object Object Object and I think it may be calling the first instead of the second is there anyway to verify / force it
21:10slyphoni would imagine reflection is one way
21:10somniumlivingston: you can use type hints
21:11slyphonyeah, that'd probably be easier
21:11slyphonBoolean/TRUE
21:11mmarczyk(boolean first-argument) instead of first-argument
21:12mmarczyk,(boolean 1)
21:12clojurebottrue
21:12mmarczyk,(boolean true)
21:12clojurebottrue
21:12slyphon,(boolean 0)
21:12clojurebottrue
21:12slyphonhah!
21:12slyphonsuck it, C!
21:12livingstonsomnium: could you give me an example I tried (.method obj #^boolean true ... and it says Metadata can only be applied to IMetas
21:12mmarczykyeah
21:12chouserthat's not a type hint, but might help at runtime
21:12mmarczyklivingston: use (boolean true)
21:13slyphonreally? there's nothing built-in that converts an Enumeration to a seq?
21:13chouser(doc enumeration-seq)
21:13clojurebot"([e]); Returns a seq on a java.util.Enumeration"
21:13slyphonoh ffs
21:13slyphonreally?
21:13chouser:-)
21:13mmarczykalso see
21:13mmarczyk(doc iterator-seq)
21:13clojurebot"([iter]); Returns a seq on a java.util.Iterator. Note that most collections providing iterators implement Iterable and thus support seq directly."
21:15slyphonok, i need some functional-fu here, i want to walk a NamingContext and print out, recursively, the tree
21:15livingstonhmmm... ok looks like I have yet more problems then oh but wait, (boolean true) gives me a big-B Boolean
21:15slyphonfor some reason this is stumping the hell out of me
21:15livingstonthe call signature seems to want an little-b boolean
21:15mmarczyk(doc tree-seq
21:15clojurebotEOF while reading
21:15mmarczyk(doc tree-seq)
21:15clojurebot"([branch? children root]); Returns a lazy sequence of the nodes in a tree, via a depth-first walk. branch? must be a fn of one arg that returns true if passed a node that can have children (but may not). children must be a fn of one arg that returns a sequence of the children. Will only be called on nodes for which branch? returns true. Root is the root node of the tree."
21:15livingston(at least that's what show is telling me)
21:15slyphonhrm
21:16mmarczykalso see clojure.zip
21:16slyphonsee, now you guys are just makin me feel dumb
21:16slyphon:)
21:16mmarczyklivingston: when you pass (boolean true) to a method which expects a primitive Boolean
21:16mmarczykit gets a primitive Boolean
21:16mmarczykbut when you do (class (boolean true))
21:16slyphonmmarczyk: thanks
21:17mmarczykthen that (boolean true) gets boxed before being passed to the class function
21:17livingstonyeah but there is also a method signature for that slot being an Object
21:17livingstonand I think that instance of the method then becomes preferred
21:17mmarczyklivingston: I don't think so
21:17livingston(or at least that's what I'm trying to figure out - not my library)
21:18mmarczykin fact
21:18mmarczykhttp://stackoverflow.com/questions/2722856/how-do-i-call-overloaded-java-methods-in-clojure
21:18sexpbot"How do I call overloaded Java methods in Clojure. - Stack Overflow"
21:21anair_84how do i do an import *
21:21anair_84in clojure
21:22RaynesYou can't import all the classes from a package.
21:22anair_84:(
21:22livingstonI'm reasonably confident because it's producing a Boolean instead of a boolean it's calling the the method with the Object signature and not the one with the boolean (little b) signature
21:22anair_84Raynes: any thing close ?
21:22anair_84can i list all classes in package and then import those ?
21:22RaynesYou can do (:import [java.package Class1 Class2 Class3])
21:24RaynesIt's better to be explicit, even if it does require quite a bit of typing. Others don't have to guess where a class that you use comes from, and you always know which classes you have imported.
21:24RaynesAt least, I assume that's the rationale for not being able to do what you want.
21:24RaynesAnyone, correct me if I'm wrong. :)
21:24anair_84Raynes: yeah i understad the reasoning but in the repl importing explictly can be painful
21:25anair_84extremely painful
21:25Raynes:\
21:27mmarczyklivingston: have you visited that SO link?
21:27mmarczykthere is an example of a method overloaded on int vs. Object being called with 10 first, then with (int 10)
21:28livingstonyes I looked
21:28mmarczykright
21:28livingstonI don't know - I'm just saying what I think I'm seeing on my machine
21:29mmarczykthat's consistent with everything else I've read on the issue
21:30livingstonit's not my library so I can't get in there and muck with it and know for sure, but it's giving me an error that's consistent with it trying to do some object like stuff to my poor Boolean
21:30slyphonget a Method object through reflection and call it explicitly?
21:30livingstonI have some workarounds for now, I think
21:30slyphoni think wall-hack will let you list the explicit signature
21:31mmarczyk(inc slyphon)
21:31slyphon:)
21:32mmarczykhope it feels good to be incremented ;-)
21:32slyphonindeed :D
21:32slyphoni'm one more now!
21:32mmarczykyeah; in time, one can grow by a thousand!
21:32slyphonhahaha
21:36livingstonif I have the instance of a java object how do I get the member field foo (not the method foo, but a member variable?)
21:36chouser(.foo obj), and hope there's not also a method of no args named foo
21:37livingstonno... but that's just great, it's not set
21:38livingstonthanks
21:41chouserlivingston: http://gist.github.com/381625
21:42slyphonwhen you call a variadic method in java, do you have to terminate the array you pass in with a nil?
21:43livingstonchouser: cool thanks for checking that. just for the sake of argument can you change that to be 4 objects and 1 boolean and 3 objects.
21:43livingstonI'm sure it won't matter but that's the situation I'm in
21:44livingstonactually there's like 10 methods signatures with excruciatingly minor variations (I hate this api already)
21:46rhudsonchouser: lines 11-16 in that gist disturb me. Do you know why it behaves that way?
21:46hiredmanslyphon: uh, no
21:47livingstonrhudson: why? those lines seem fine?
21:48rhudsonline 13 in particular
21:49livingston13 is output? 11 creates an instance and sets it to u and 12 calls a method on that instance
21:50rhudsonRight. It seems like u being dynamically typed in 12 is losing the conversion of the argumen to a primitive type.
21:50chouserwithout a hint on the target, the clojure compiler can't generate a single method call and has to generate reflection code instead
21:51chouserrhudson: I think that's right.
21:51rhudsonBut in the process converting back to boolean
21:51rhudsoni mean Boolean -- missed the shift key
21:52livingstonOH wait I read that wrong 11-13 are *exactly* my problem
21:53livingstonit didn't work in those lines
21:53mmarczykohhh
21:53mmarczykthat's good to know
21:54mmarczykwould (.foo (cast mypkg.Ugly u) (boolean true)) work?
21:54chousermmarczyk: no
21:55chouseryou need a type hint
21:55livingstonand line 15 is the fix
21:55livingstonwow that's ugly
21:55mmarczykok, thanks
21:56chouseryou can hint u
21:56livingstonthat's really unfortuante, so it's because it's using reflection to figure it out? and it's doing so at compile time?
21:56mmarczykchouser: would you care to add this to this SO question: http://stackoverflow.com/questions/2722856/how-do-i-call-overloaded-java-methods-in-clojure ?
21:56sexpbot"How do I call overloaded Java methods in Clojure. - Stack Overflow"
21:56chouser(def #^mypkg.Ugly u (mypkg.Ugly.))
21:57chouserlivingston: not quite
21:58livingstonyeah I seem to be back to rhudson 's question because yeah, that certainly doesn't seem right
21:58slyphonwow, java, you complete me
21:58livingstonor at least doesn't seem like something that should confuse clojure
21:59chouserat compile time when it can't figure out exactly one correct method to call, it generates code to do reflection at runtime, and by then it seems to have lost track of the fact that the arg is a primitive.
22:00mmarczykchouser: that's if you do SO, of course, otherwise I could post a link to your gist myself -- seems directly relevant to that question
22:02livingstonwhy doesn't it know that the arg is primitive? - i mean it makes sense that it didn't know, that was my problem BUT ... even with the type hint that only tells it the class the method is attached to not the method signature which still must wait until runtime I would think?
22:03mmarczykthat would make sense if you could compile the code without having the class on your classpath
22:03slyphonor, you could be explicit and use wall-hack-method...?
22:03livingstonit seems like if it can compute any method signatures at all, it should be able to get past this particular problem without much trouble at all?
22:03slyphonand Boolean/TYPE
22:04slyphonwrapped in a parital...?
22:04hiredmanlivingston: the method signature definitely does not have to wait until runtime
22:04mmarczyklivingston: well actually this isn't at all different from what happens when you compile Java code
22:04chousermmarczyk: eh, go ahead.
22:05chouserI started an answer, but I should be doing other things.
22:06mmarczykchouser: if it's a certain book you have in mind, I'm definitely interested in removing any distractions you might face :-)
22:07livingstonhiredman: it doesn't have to, but it sometimes it must right? if it doesn't know and and has to dispatch
22:07rhudsonAt this point I'd be tempted to wrap the pesky overloaded methods, in Java or Clojure, give them distinct names (f-yes-I-mean-the-one-with-little-b-boolean-first-arg-dammit) & use those
22:08hiredmanlivingston: what do you want?
22:08livingstonmmarczyk: I suspect not, but one of the most unattractive things about java is how about 50% of your code is type information (hell even Ada wasn't that bad)
22:09pdkcouldve been haskell :p
22:09livingstonhiredman: I'm just confused as to how this is confusing to the compiler
22:09mmarczyklivingston: well that (.foo ^TypeHint stuff more-stuff) business hardly seems to suffer from this problem
22:09mmarczykit's just one hint, you know :-)
22:11livingstonif the compiler can't figure it out at compile time and has to generate some reflection code to dispatch at run time, and it gets the arguments bool I would expect it to quite easily call the bool one, I mean why should that change if it knows the base class or not?
22:11livingstonthat's what's weird about this
22:12chouserit's actually already some pretty gnarly code. dynamic method invocation on the jvm is a bit of a mess.
22:13chouserBut I'm only suggesting why it doesn't, not that it couldn't or shouldn't handle this.
22:15livingstonso is this just a limitation of the clj compiler? or of the jvm or something else in general?
22:15mmarczykdoes the unhinted code generate a reflection warning?
22:17livingstonmmarczyk: it just breaks at runtime (from what I can tell) at the repl - I didn't try compiling it any other way
22:17rhudson,*warn-on-reflection*
22:17clojurebotfalse
22:17rhudson(doc *warn-on-reflection*)
22:17clojurebot"; When set to true, the compiler will emit warnings when reflection is needed to resolve Java method calls or field accesses. Defaults to false."
22:17defnfor someone with very limited java experience is reading effective java worth the time, or should i start with a more introductory text first?
22:17chousermmarczyk: yes, you get reflection warnings
22:18defn,(set! *warn-on-reflection* true)
22:18clojurebotjava.lang.IllegalStateException: Can't change/establish root binding of: *warn-on-reflection* with set
22:20mmarczykok, thanks
22:20mmarczykin that case it's fairly easy to catch
22:21mmarczykI'd expect the compiler to become more sophisticated when it transitions to Clojure, no?
22:21chouserit will certainly become less painful to change.
22:21mmarczykshould be more pleasant adding stuff in Clojure than in Java
22:24mmarczykok, posted that SO answer, hope it's accurate
22:27rhudsondefn: I'd say start with something else besides Effective Java. (I think the best way to write effective Java is to write Clojure :) )
22:27chouserok, it looks like when it generates reflection code, it just stuffs the args into an array (Object[]), and that's all it uses to find the correct method at runtime.
22:29livingstonthis is the clojure compiler? so it just gets the class'es then and the big-B Boolean wins as an Object?
22:30livingstonOH wait I see so it need to use reflection when it doesn't know the object's type, BUT when it does it just hands it off to the jvm for normal dispatch?
22:31chouserhttp://github.com/richhickey/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#LID1278
22:32chouserno, not quite.
22:33chouserif it knows the type of the target and the types of enough of the args *at compile time* (which it does by using reflection at compile time), then it generates a normal java method call which at runtime is handled by the normal jvm dispatch stuff.
22:34defnrhudson: any recommendations?
22:34defnrhudson: i dont wanna learn java so much as i want to learn enough java to use it properly in clojure
22:35livingstonI hate the API that lead me to this even more now ... for one class they have .getNameSpace and another is .getNamespace - so I can't just use one simple clojure function that doesn't care which class it gets - blech
22:35livingstonchouser: ok that's starting to make sense
22:35chouserif it doesn't know enough at compile time, it stuffs the args into an Object[] and generates code that at runtime will do reflection to find the right method and call it via refleciton
22:35defnlivingston: i think you can do that with a multimethod
22:36defnlivingston: are you talking about inheritance?
22:36rhudsonThe intro stuff in Java in a Nutshell is pretty good, then you have a good reference to the standard library as well
22:36livingstonchouser: ok that also makes sense
22:36defnrhudson: cool! thanks
22:36chouserbut since all its got is an Object[], primitives have gotten autoboxed and so the Object,Object,Object signature matches
22:36livingstondefn: I know i can but it'd be nice not to have to
22:37livingstonchouser: ok good, at least this is telling a sane story as to why this works this way
22:38defnlivingston: idk, i think the control over polymorphism is pretty cool -- i like having that fine grain control
22:38defnid almost prefer clojure *not* do that for me
22:40slyphondefn: it's easy to make it do "dumb polymorphism" too, just dispatch off the class or (obj :type) of the first arg
22:41livingstonchouser: this is odd though, because getParameterTypes must return something where primitives are discernible? because clojure.contrib.repl-utils/show knows the difference between big-B and little-b boolean
22:41slyphoni remember that kind of blew my mind the first time i played around with CLOS
22:41livingston(unless it's just calling toString or something)
22:43mmarczyklivingston: sure, but if the compiler postpones reflection until runtime and then at runtime all you've got is Object[], then the fact that reflection could find a (boolean, Object, Object) method is irrelevant by that point
22:43mmarczykyou'd have to not stuff everything into Object[], basically
22:44mmarczykincidentally, the new ^foo syntax for reader meta data is Really Pretty :-)
22:44chouserright. or include flags indicating which args were primitives and should unboxed again.
22:44livingstonor route it through the regular dispatch code?
22:45livingstoncouldn't you just scan for things that could be primitive?
22:45chouserlivingston: The jvm doesn't have "regular dispatch code" that's dynamic
22:45chouseryou have to name a specific method of a specific class or interface at compile time
22:46livingstonalthough that presumes it's illegal to have a Boolean and a different little-b boolean - because you couldn't tell between those...
22:46livingstonchouser: I meant the clojure dispatch code, basically dynamically build a multi-method
22:46mmarczykhttp://blogs.sun.com/jrose/entry/dynamic_invocation_in_the_vm
22:46sexpbot"dynamic invocation in the VM - John Rose @ Sun"
22:47mmarczykI am under the impression that invokedynamic will make all of this easier
22:47mmarczykis this correct?
22:47livingstoninteresting
22:48livingstonwell there's still a problem though if you can have two signatures one with a little b and one big B because you won't know to unbox or not, right?
22:49chouserlivingston: that's why I was suggesting a separate set of info about which args were primitives before being stuffing into the Objectp[
22:49chouserObject[]
22:49dnolenis contrib being continuously rebuilt as well?
22:49dnolenthat is, how can I get the latest in my lein project?
22:50mmarczykclojure-contrib-1.2.0-SNAPSHOT
22:50mmarczykI believe
22:50livingstonchouser: yeah, I think that is the right thing. clojure could do that today and get around this problem
22:50dnolenmmarczyk: is that coming from hudson as well?
22:50mmarczykit is, afaik
22:50mmarczykI mean it must be, since there's no c-c in maven central or clojars to the best of my knowledge
22:51dnoleni see, somewhat confusing the lack of master in the name when clojure has it.
22:51mmarczyktrue
22:51chouserlivingston: I pasted a link to the code. feel free to write a patch and try to get it in.
22:51chouser:-)
22:52mmarczykthe last c-c build is from ~7 hrs ago
22:52livingstonalthough I'm still a bit confused, why there isn't a simpler solution? since somewhere somehow with an array of objects show is able to show me the difference between a Boolean and a boolean
22:52chouserI suspect rhickey won't want this kind of change so close to 1.2 release, but I could be wrong.
22:52mmarczyklivingston: I'm not sure what you mean
22:52livingstonhttp://github.com/richhickey/clojure-contrib/blob/4f9a78d13217a8de4c29221d74aca0a67cec8c1a/src/main/clojure/clojure/contrib/repl_utils.clj#L59
22:52mmarczyki.e. what use of show you have in mind
22:52chouserlivingston: there's two different things that have to be matched up. Clojure's got to find the declared method that matches the actual args.
22:53livingstonright
22:53mmarczykyeah, I use show all the time, but that's at the REPL to find out what methods a class has
22:53chouser'show' and the Clojure compiler and the Clojure runtime reflection code all have no problem finding which declared methods have primitive args.
22:53mmarczykwhich has nothing to do with matching the correct method with a given set of arguments
22:53chouserthe problem is knowning what the actual args being passed in are.
22:54livingstonright and show can tell me the difference between little and big B, but I'm looking at the code and they seem to use an array of objects, which suggests there's a way to pass the little b boolean around without losing it's type...
22:54chouserOnce the actual args have been put in an Object[], clojure.lang.Reflector/invokeInstanceMethod looks at the type of each actual object there to see if it can find a matching declared method
22:55livingstonoh wait I see where I went wrong, the object coming out of getParameters aren't objects, duh
22:55livingstonthey're something else Parameters or something (probably)
22:56livingstonno yeah I get it - I was just over generalizing or something about how show worked
22:56livingstonblech
22:57livingstonyeah your vector of what was / wasn't boxed is good, also meta type hints on the parameters themselves to suggest a call signature to force it would be fine too
22:58livingstonI would have liked (.foo (mypkg.Ugly.) #^boolean true)
22:58livingstonbut your can't type hint there currently
22:59livingstonalthough, the auto un/re boxing should really fix this up (that's something I like about lisps, is not having to crud up my code with types)
23:01mmarczyklivingston: actually (boolean true) does ensure that the true is unboxed -- and it will be used unboxed if non-reflective code can be generated
23:02mmarczykso the key hint becomes the one on the object you're calling the method on
23:03livingstonalthough one would think the literal true would be sufficient for that
23:03mmarczykhm? why would you think that?
23:03chouserall literals in Clojure are currently boxed
23:03slyphonwah-wah
23:03mmarczykwith both little-b and Big-B Booleans around
23:04mmarczykincidentally, having both little-b and Big-B Booleans seems crazy to me
23:04livingstonwell the first problem is that booleans and other types need two forms
23:04mmarczykI'm not saying it doesn't make sense
23:04chouser,(expression-info true)
23:04clojurebot{:class java.lang.Boolean, :primitive? false}
23:04chouser,(expression-info 5)
23:04clojurebot{:class java.lang.Integer, :primitive? false}
23:04chouser,(expression-info (long 5))
23:04clojurebot{:class java.lang.Long, :primitive? false}
23:04chouserheh
23:04mmarczykI'm perfectly prepared to believe that it makes sense in a very deep way due to performance considerations or whatever
23:04mmarczykor just history
23:04chouser,(expression-info '(long 5))
23:04clojurebot{:class long, :primitive? true}
23:04mmarczykbut it makes it no less crazy
23:04livingstonthe second is even needing boolean at all, common lisp has gotten along just fine with nil being false and everything else is true
23:05mmarczykwhy expect straightforward literal behaviour in this situation :-)
23:05mmarczyklivingston: the Java world is doing reasonably well despite the ridiculous decision to have a separate notion of Booleans ;-)
23:05livingstonall this boxing only makes sense when you live in the Kingdom of Nouns
23:05slyphonhah
23:06mmarczykincidentally, coming from Scheme, I still find it somewhat surprising that we have two false objects :-)
23:06mmarczykor should I say falsey
23:06slyphonit makes sense when your design has made tradeoffs for performance reasons
23:06slyphonmmarczyk: coming from ruby it's very natural
23:07slyphonmmarczyk: although, i must say, i'm very happy that '{} and nil aren't equivalent
23:07slyphoner '()
23:07mmarczykslyphon: I'm actually trying to learn a bit of Ruby now
23:07slyphonmmarczyk: ruby is fun
23:07mmarczykslyphon: just because so many Clojurians seem to have strong Ruby backgrounds
23:07slyphon:)
23:07livingstonthe only reason there's a performance issue is that java decided that everything needed to be objects and that numbers et. al can't play where everything else is allowed to play without a big brother object to hold it's hand
23:07mmarczykmakes me curious :-)
23:07slyphonyeah, i've been a ruby developer for about 4 years
23:07mmarczykbut it does look *really weird* to me :-)
23:07slyphon(primarily)
23:08slyphonhahahaha
23:08dnolenlivingston: that's not the problem at all, IMO. fns should accept and return anything, that means boxing.
23:08dnolenthe only time you don't want that behavior is truly performance critical code.
23:09mmarczyklivingston: if you're proposing to have a Java-bashing session, I'm at one with that :-)
23:09livingstonmmarczyk: no I do that enough at work (we're a java shop)
23:10mmarczyklivingston: yeah, I guess your Java must be thouroughly bashed then
23:10mmarczykthat must be some really atrocious api you're trying to use, btw
23:10livingstondnolen: only if you assume that an object is somehow different from a number - common lisp doesn't have this issue, it has a type hierarchy with numbers in it - things work just fine
23:11mmarczyksomehow the .getNamespace vs. .getNameSpace thing really gets to me
23:11livingstonmmarczyk: it's Jena and AllegroGraph's bastardization of Jena
23:11mmarczykfiled under "try not to need to use"
23:11slyphonlivingston: it's different when you're referring to an Object and when you're referring to a location in memory
23:12livingstonit makes me want to gouge my eyeballs out that it takes about 4-9 method calls (and a lot of objects) to do the equivalent of '(ex/a rdf/type ex/b)
23:12livingstonI'm working on that though
23:14livingston_awesome - web client died
23:15livingston_not sure what I missed but I was going to say:
23:15slyphonlivingston_: what client are you using?
23:15livingston_I don't have to worry about when I call this method I get Triples back but when I call that one I get Statements back they are exactly the same, except completely different
23:15livingston_http://webchat.freenode.net/
23:15sexpbot"freenode Web IRC (qwebirc)"
23:15slyphonoh, nice
23:15livingston_port 6667 is blocked here
23:15slyphonmy buddy has the same situation
23:15slyphon"hackers use irc"
23:16slyphon(schmucks)
23:17livingston_I wonder if I'm still here
23:17rhudsonyep
23:17livingston(it just told me I timed out so I was confused - that was the old client I guess)
23:18defnslyphon: are you ming slyphon?
23:19slyphondefn: hahahahaha
23:19slyphondefn: i haven't heard that in ages
23:19mmarczyk"hackers use irc and we *certainly don't* want to employ hackers, do we"
23:19defnslyphon: im not even sure why it's funny! i just realized i have you on my google talk contact list
23:19mmarczykmakes perfect sense for an it shop
23:20slyphondefn: orly!?
23:20defnslyphon: we talked in ruby-lang ages ago
23:20slyphondefn: ahhh
23:20slyphondefn: i used to go by mingus also
23:20slyphonin #twisted
23:20defnahhh
23:20defna fan of charles?
23:20slyphonindeed!
23:21livingston99% of the people here don't program - so it doesn't kinda make sense and a good preventative measure against worms - I can't say I don't understand why
23:21slyphonunless someone decides to run their CNC server on port, say, 6668
23:21slyphonor 80
23:21slyphonor 53 :D
23:22slyphonEVIL
23:22dnolenlivingston: I see, I suppose that's what rhickey means when he says breaking with Lisp tradition. I do note that that even Common Lisp requires you to declare types in fns that use them. Clojure's deftype does avoid that. always tradeoffs I suppose.
23:22livingstonI haven't checked but my guess is that everything that isn't http or ssh related is blocked - even skype's blocked
23:22slyphonwoah, skype is hard to block
23:23slyphonthey go out port 80 if necessary
23:23livingstondnolen: you don't have to put types in function signatures in CL
23:23slyphonis deftype in 1.2?
23:23livingstonyou do if you want to dispatch but then...
23:23dnolennot in signatures, but inside the fn to hint the compiler no?
23:24livingstonsome CL compilers will generate unsafe code with type info and (speed 3) (safety 0) set
23:24dnolenlike SBCL i imagine.
23:25livingstondnolen: no no types unless you need the compiler to be more efficient (rare) - in fact it's genearally advisable to avoid them - then you can reuse and maintain code easier
23:25livingstonditto with clojure
23:28dnolenlivingston: but that's more of an issue with CL, with so many compilers with different capabilities. In Clojure I only ever want type hints on arithmetic.
23:30livingstondnolen: it's the same thing - only hint when a bottleneck is found otherwise don't worry about it and don't waste your time - that's what the profiler is for
23:32dnolenlivingston: except un-type hinted arithmetic is dog slow. I've seen it enough times first hand (doing graphics stuff) that I never want to do arithmetic with boxed numbers.
23:33dnolenyou also never want to add non-binary arithmetic. the slowness is horrifying
23:33livingston,(+ 3 4 5 )
23:33clojurebot12
23:33dnolenthat won't be inlined
23:34mmarczyk,(+ (+ (int 3) (int 4)) (int 5))
23:34clojurebot12
23:34mmarczykoh, but so ugly
23:34mmarczyk,(unchecked-add (unchecked-add (int 3) (int 4)) (int 5))
23:34clojurebot12
23:34dnolenthat's what macros are for
23:34livingstonHow do you know what + creates?
23:34mmarczykoh, but even more ugly
23:34hiredmanthere is some possibility that the reduce protocol stuff will make reducing over an array of ints the fastest way to add
23:34mmarczyktrue
23:35dnolen(prim float (+ 1 2 3 4 5 6 7 8 9 10))
23:35dnolenis one macro I wrote to do the right thing
23:35mmarczykhiredman: oh, that's a cool idea
23:35livingstonmost functions like that have multiple dispatch for 1 2 3 and many parameters to optimize for the common cases
23:35mikem~def int
23:36slyphonchouser: where do inline functions live?
23:36hiredman+ has one inline, which calls the binary add in Numbers
23:36hiredman,(:inline (meta #'+))
23:36clojurebot#<core$_PLUS___4516 clojure.core$_PLUS___4516@183ccdb>
23:36hiredman,(:inline-arities (meta #'+))
23:36clojurebot#{2}
23:36livingstonI don't do enough math in code where it's ever been the case that I could get significant speed by altering my numbers my run-time goes to other things
23:37slyphonwow, ok
23:37dnolenlivingston: as rhickey has said, if Clojure get's unboxed arithmetic everybody's code is going to get way faster, not just math code.
23:37dnolenbillions of operations per second, instead of tens of millions
23:38slyphondnolen: pfft, how often do computers have to "add things"?
23:38slyphonc'mon
23:38dnolenslyphon: heh, a good joke if you meant it :D
23:39slyphon:D
23:39slyphoneyebrows, even
23:39mmarczykwell now
23:39livingstonin my world not that often only for bookkeeping (like how long did this take) - I do symbolic AI - it's all lists and symbols
23:40mmarczykchouser: livingston: it appears that locals don't need type hints
23:40mmarczykhttp://gist.github.com/381686
23:41mmarczykwhen their type can be inferred, that is
23:42mmarczyk(let [t u] ...) would still use the Object method
23:42livingstonmmarczyk: wait what how the hell is that possible?
23:42livingstonright ok
23:43livingstonpresumably code that wasn't the constructor in that let would also wreck some havoc
23:43mmarczyk(.foo (foo.TestInterop2.) true) uses the bool method too
23:43mmarczykso apparently the compiler checks whether it's actually just emitted the code to construct the object in question (in which case it knows all about it)
23:43mmarczykin addition to using type hints
23:48livingstonwell this has been fun everyone
23:48mmarczykright
23:48mmarczykone more thing
23:48mmarczyk(see my gist)
23:48livingstonI'm going to go get some food and cuss about Triples not be the same as Statements
23:48mmarczykyou can also type-hint a Var
23:48mmarczykthen wherever you use this Var
23:48livingston*looking
23:48mmarczykthe type hint will be taken into account
23:49mmarczykfrom what I gathered from experimenting at the repl, anyway
23:50livingstonoh huh
23:50livingstonmost of my things are coming out of maps, but there might be a way to hint those too
23:51livingstonbut like i said, things are a little fluid now so I'd like to avoid having to lock things down too soon
23:51mmarczyksure
23:51livingstonthanks again everyone