#clojure logs

2008-12-09

03:20Lau_of_DKMorning gents
03:24AWizzArdwhat wiki software does clojure.org use?
03:44oudeisAWizzArd: a quick glance at the code suggests it is http://www.wikispaces.com/
03:46AWizzArdAh oki, thx
04:25danlarkinooof, nesting syntax-quote inside syntax-quote gets tricky fast
08:49AWizzArdIs there already a clojure lib for swing?
08:50arbschtAWizzArd: clojure can use swing directly
08:50AWizzArdyes, but I would not want to do it this complicated way. For example when I want to add an event handler for buttons.
08:51AWizzArdWhy should I use (proxy ...) for that?
08:51AWizzArd(swing-add-handler my-button (fn [..] ...))
08:53AWizzArdNot that it is difficult to write. I was just curious if someone with swing knowledge did that.
08:56blackdogi'm curious if anyone's doing a javafx clone api
08:56gnuvinceAWizzArd: as far as I know, no. And I am not sure a lot of people consider it a priority. There was an interesting exchange between Rich and Slava Pestov of the Factor language on Reddit a few months ago where Slava deplored the lack of language-specific idioms in Clojure. Rich replied that saying (.close fd) instead of (close fd) was not a big deal and that the real important thing was to be able to Get Things Dones (tm)
09:02AWizzArdYes, I agree with that. What I have in mind would probably be 50-250 LOC of Clojure code. Just a simple helper tool, to make Java (and interop) pain go away. Definitly this is nothing for Rich to do, as it is really not very important for Clojure.
09:14RSchulzAWizzArd: Wouldn't your (swing-add-handler ...) be forced to proxy a local type to match the type required of the particular Swing handler?
09:15RSchulzI mean, that's probably a good thing to have in a helper, but proxying is unavoidable when interoperating with existing Java APIs, right?
09:15AWizzArdyes probably, I didn't look deeply into it yet
09:15AWizzArdyes
09:15AWizzArdthe helper would do this proxy stuff though and hide it from us
09:15RSchulzRight. I think that would be pretty helpful.
09:16RSchulzHas anybody ever used MPW? Do you know what its Commando utility was?
09:16AWizzArdI'll see if I can get something like that ready, as I will need to do a little bit of Swing anyway.
09:16RSchulzIt was a simple way to defining parameter-gathering dialogs for invoking CLI tools (within MPW).
09:16RSchulzI was thinking my CLI-phobic end users would like to have such dialogs, but writing them all by hand would be very tedious for me without such a DSL.
09:17RSchulzAlso, it would get me out of my current Unix (Linux) requirement for the CLI tools.
09:24AWizzArdwhat do you prefer? (.method obj arg1 arg2) vs (. obj method arg1 arg2)?
09:25RSchulzI'm not sure I have strong preference. Probably the first, since it's more Lisp-like: (functor args...)
09:25AWizzArdyes
09:26gnuvinceThe first form is preferred.
09:31ChouserRSchulz: are you familiar with the library of ant tasks?
09:32RSchulzNo. You mean the ones built into Ant?
09:32Chouseryes
09:32RSchulzI try to minimize my exposure to build.xml files...
09:32RSchulzI can never modify one without consulting the Ant documentation.
09:33RSchulzI can't usually get it right the first time.
09:33ChouserI only know what I've read in Stuart's book, it looks like they have a bunch of OS-indepedent operations that might be good candidates for wrapping in a dialog box.
09:34ChouserThe book has a running example of building a DSL in Clojure so you can write build processes for ant without touching any XML.
09:35RSchulzAh. Right. I actually looked at his ... what was it called? ... Ant DSL for ideas about another DSL I need to write.
09:35ChouserLancet
09:35RSchulzRight. Lancet. I kept thinking "enchantment."
09:36ChouserIt's still not clear to me if he made up the specs and name just for the book, or if it's some kind of re-implementation of some other "lancet".
09:37RSchulzI think he did it for the book. There were some messages about it on the mailing list.
09:40clojurebotsvn rev 1148; support :when and :while together in for, patch from Chouser
09:41AWizzArd*thumbs up*
09:41Chouserhandy!
09:41AWizzArdvery
09:41RSchulzYou name in lights!
09:41Chouserah, yes, that too. :-) but I meant clojurebot announcing.
09:42AWizzArdChouser: why are the dots in front of add, setSize and so on left out at http://clojure.org/jvm_hosted
09:44ChouserAWizzArd: that's old-style 'doto'. Much of the site documents the release (where that syntax is correct) rather than SVN.
09:44AWizzArdoh right, for the downloadable clojure.jar, this old one
09:45RSchulzRich mentioned that the API page, http://clojure.org/api, is generated from the source code, so it remains up-to-date, though no more detailed than what you get from (doc ...)
09:54whiddenWhat is the process for generating the API page and would it be "easy" to do for a local copy? -- for long tain rides.
10:02RSchulzI don't know. I'd start by looking at the Clojure build.xml file. If it's not there, ask Rich.
10:02RSchulzI'd like to get the text flowed, for one thing. And I'd like a more printer-friendly format for that page (no sidebar TOC, e.g.)
10:02whiddenOk I'll look into the build.xml when I have a free moment..
10:03RSchulzI suppose someone will write a ClojureDoc at some point.
10:06Chouserwhidden: there is this: http://clojure.googlegroups.com/web/manual.pdf
10:06Chouserthough that's a bit out of date by now, I suppose.
10:08rhickeyRSchulz: there is a print stylesheet - I don't get sidebars etc when I say print
10:08RSchulzReally?? Huh. How long has that been the case?
10:08RSchulzIs Tom around?
10:09RSchulzAnyway, that's great. But without allowing the doc text to flow, there's still a lot of wasted space and it takes too many pages.
10:09ChouserFor nearly a month now: http://clojure-log.n01se.net/date/2008-11-13.html#14:29b
10:10RSchulzAh. Fabulous. I was hoping I hadn't just hallucinated the last time I tried printing (or print previewing).
10:11RSchulzRight now, it would be 41 pages for me (according to Firefox's print preview).
10:11stuarthallowayChouser: A lancet fluke controls the mind of an ant. Dan Dennett talks about it at: http://blog.ted.com/2007/07/dan_dennett_on_2.php
10:11RSchulzThat could probably be cut nearly in half if the doc text flowed.
10:11Chouserstuarthalloway: ha! great.
10:12RSchulzYikes. Biology is gruesome.
10:13rhickeyRSchulz: text not flowing on API page is my bad from last time I generated it. It flows on other pages for me when printing
10:14stuarthallowayThe other Ant-mind-controlling organism is a Cordyceps fungus. There is stunning time-lapse video of Cordyceps in the BBC's Planet Earth series. It's even cooler than a Lancet fluke but I decided it was too hard to spell.
10:15RSchulzOK. Then I'm happy. (Don't shoot me, but I like paper documentation...)
10:15rhickeyactualy looks very screwy - get through ns are all underlined for me...
10:16rhickeyI'll try to regen later
10:17RSchulzOK, thanks. No particular hurry.
10:17RSchulzI'm not seeing that. It's usually a missed close tag, obviously.
10:18rhickeyNo, it's some wiki markup thing, that's what I generate
10:20tomhickeyrhickey & RSchulz: I just got caught up on the discussion, let me know if i need to update anything
10:20Chouserrhickey: the code that generates the wiki markup isn't available anywhere, right?
10:20ChouserThat question came up last night.
10:21rhickeyChouser: I should put it somewhere since I keep losing it :) Then finding and using broken old versions
10:21Chouserheh
10:23rhickeyThat's really old
10:26lisppaste8rhickey pasted "wiki doc gen" at http://paste.lisp.org/display/71857
10:27rhickeyProbably broken, given the lack of wrapping (should remove non-double newlines), plus the underline thing - help welcome
10:28RSchulzrhickey: What did you think of the patch proposed to allow doc strings in defmulti? Chouser was the only one to respond, noting the potential breaking nature for some existing defmulti applications.
10:30stuarthallowayrhickey: FYI when I wrote the multimethods chapter, the number of (visible open source) multimethods that dispatched on anything other than type was vanishingly small, so now's the time for any breaking changes
10:32AWizzArdyou mean the dispatch function was class ?
10:32stuarthallowayright
10:32AWizzArdic
10:33rhickeyclass-or-tag will become prevalent
10:33stuarthallowayand most of the ones that weren't on class were on other things that server similar purpose, e.g. dispatch on identity to match keywords
10:33rhickeythen people will start figuring out hierarchies and multi-argument dispatch. It's early days and people are doing the common thing
10:34rhickeyI don't see why defmulti doc strings can't be done in a non-breaking way
10:36rhickeythough changing default from positional to :default foo would be more extensible
10:40rhickeyno one saw the sneak peak at streams in this? - http://groups.google.com/group/clojure/msg/53227004728d6c54
10:40ChouserI did. I love it.
10:41rhickeystill working on timeout handling, since I want these to work well over queues
10:41Chouserall this agent/stm stuff is nice -- an insurance policy against the future. But it's the immutable collections and seq stuff that mean something to me today.
10:42rhickeyI like *timeout* dynamic var, and (with-maximum-timeout 1000 ...)
10:42tomhickeyrhickey: the wiki markup for gensym currently on site doesn't match what's coming back when i run your code (extra double underscores causing unclosed <u>)
10:43Chouserdoes 'stream' build a mutable iterator-type-thing over coll?
10:44rhickeyChouser: yes, a stream generator - next! is a one-shot read
10:44rhickeyeos is a sentinel
10:45rhickeythe key diff with iterators is that iterators have a built-in race condition: hasNext/next
10:45rhickeynot so these generators
10:45rhickeymeans you can multiplex them
10:45Chouserah, so you solved the 'map' problem?
10:46rhickeythere's still the inversion of control issue, but having banged my head against it a good bit, I'm unconvinced that LFE for resource management is any easier than with-open
10:47rhickeyand with-open could easily handle multiple reasource, and yes, map for streams multiple streams
10:47rhickeyin any case, I'm shooting for a simple protocol
10:48rhickeyThe trick is to avoid duplicate effort - every seq fn should have a stream version, so I want the former to be mechanically generated from the latter
10:50RSchulzThe only thing I can (quickly) find for LFE is Lisp Flavoured Erlang. Is that what you meant?
10:51lisppaste8rhickey pasted "more stream teasers" at http://paste.lisp.org/display/71858
10:51ChouserLeft something Enumerator, I think.
10:52rhickeyRSchulz: left-fold enumerators - http://okmij.org/ftp/Streams.html#iteratee
10:52RSchulzThanks.
10:52rhickeyesp: http://okmij.org/ftp/Haskell/Iteratee/DEFUN08-talk-notes.pdf
10:54rhickeyoutstanding issues are: what to do with a timeout - exception or return sentinel, and naming - should map et al be overloaded for streams or have map-???, filter-??? etc
10:55RSchulzIf you write individual xyz-??? calls, they can be unified under a multimethod, right? But if you write them as a multimethod, they cannot easily be used directly? (Splitters vs. Lumpers)
10:56Chouseris the fn given to 'stream' guaranteed to get an (eos?) => true to handle resource cleanup?
10:57rhickeyRSchulz: not sure what you mean, I'm just talking about (map f x) doing something special if x is an IStream
10:58RSchulzIsn't a type check an indication you should be using a multimethod?
10:58rhickeyChouser: the fn given to stream is responsible for producing an eos, if it's not an infinite stream
10:59rhickeyRSchulz: how it branches isn't relevant at this point, the overloading vs non, e.g. map-stream, is the issue
11:00rhickeystreams are actually very dangerous things to share, so it's nice to have their use called out. But inside a pipleline they can speed things up significantly
11:00ChouserIsn't the resource management issue about the flow of "I'm done" messages from stream consumers down into stream producers?
11:00RSchulzBut that's the point. If you write map-stream it can still be unified through a multimethod and remain open to extension. But if you bury that inside map, it's no longer open.
11:00RSchulzOr am I still missing the point?
11:01ChouserRSchulz: if we're ever allowed to write code that uses 'map' on a stream, any change to that would be a big breaking change.
11:01rhickeyright, it's an API thing
11:01Chouserregardless of how its implemented
11:02Chouserhm, and putting it that way sounds like an argument for starting with them called out as 'map-stream'
11:02RSchulzWhich, I think, is my point.
11:02Chouserif it becomes obvious later that 'map' should be able to handle streams, that would be a non-breaking change.
11:02ZephtarI think a better approach would be a func that lazily turned a stream into a seq of bytes
11:03RSchulzWe're not assuming byte streams, are we? Isn't this an abstract stream?
11:03rhickeyChouser: not really, I'm done helps, but not all scenarios work that way, ultimately all resource management is - you init, you clean up, even if by explicitly assigning the responsibility to someone else
11:04rhickeybut context comes into play as well, can't let resources leak, and there is no solution for unbounded usage context for anything other than memory
11:04rhickeyso, LFE or with-open
11:04rhickeymy lfe has you getting passed a stream inside, guaranteed to be bad outside
11:05rhickey(reduce-lines fn-of-a-stream afile-spec)
11:06rhickeystream-lines a better name
11:07rhickeyfile closed when done
11:07rhickeythis vs line-seq, which must be paired with with-open
11:07duck1123I just added Clojure to the Java template on wikipedia. Should drive more people to that page. (and clojure.org in turn)
11:10rhickeyRSchulz: right stream as in generator as in ephemeral sequence
11:11RSchulzRight. I was just clarifying for Zephtar's sake.
11:12rhickeyit's really just the old file read protocol, seems well worn and understood
11:12rhickeyI'm still ponderng unread/pushback
11:13whiddenfor what its worth I like thinking of streams as "ephemeral" sequences. It reminds me a little of the Sun OS device streams.
11:13whiddenIn the Sun streams you could push/pop consumers/producers on to the "stream"
11:14whiddento allow for arbitrary processing, etc.
11:14RSchulzYou mean the old SVR3 streams model?
11:14RSchulzIs that still around?
11:14RSchulzIt was pretty cool.
11:14whiddenyes
11:14RSchulzIt actually came out of Bell Labs.
11:15whiddenI think the Sun model added a bit to original Bell Labs stuff, but I could be wrong, or mis-remember :)
11:16RSchulzThat all was near the end of my Unix kernel days, so I don't know what happened after it got into Sun's kernel.
11:17whiddenI think what sun added was to allow for consumers/producers of streams to get out the kernel space for most of their processing, akin to what the Mach Microkernel wants/wanted to do.
11:44mibuis there a mirror for clojure.org?
11:52danlarkinthere's always the google cache
11:53RSchulzIs there any particular need for mirror?
11:58duck1123If I'm using gen-class, does the classloader need any funky permissions to load the implementations?
11:59duck1123possibly something that might be turned off in some situations?
11:59Chousukedoesn't gen-class just use the regular java classloader? :/
12:00Chousukethe classes are AOT compiled so they should be no different from java classes, right?
12:01duck1123that's what I was thinking, but I remember reading something about some security situations where AOT gen-class wouldn't work right now.
12:01duck1123IIRC, android had that situation
12:01duck1123I'm still trying to figure out why my servlet works in Jetty, but not in Tomcat
12:02duck1123a guy in #tomcat suggested it may be a classloader issue
12:03duck1123all of my classes are on the classpath, so that's not the issue
12:03stuarthallowayduck1123: "all classes on classpath" does not imply "not classloader issue" :-)
12:05stuarthallowaycheck the classloader delegation of the class that successfully loads, closest to the point of the problem
12:06stuarthallowayone possible problem is that some classes are on *more than one* classpath
12:06stuarthallowaylast I checked, Tomcat has 6 classpaths: core, extensions, system, tomcat-core, webapp-shared, and webapp-specific
12:07stuarthallowaywith the "system" being the one configured by the CLASSPATH variabile
12:08duck1123$CLASSPATH is empty, I'm not sure I follow the rest of your suggestion
12:09duck1123fair enough. I'll keep hacking at this
12:12duck1123it's not a runtime codegen issue. Hibernate uses RTCG, and since Hibernate works with Tomcat, that can't be the issue
12:36stuarthallowayduck1123: do you have a stack trace?
13:03duck1123stuarthalloway: no, I'm not getting any exceptions
13:04stuarthallowaywhat's the symptom, then?
13:04duck1123All I'm getting is a 404 error when I try to load my servlet
13:04duck1123It works in Jetty, but not in Tomcat
13:05stuarthallowayhave you tried placing a Java-created servlet or JSP in the web app to see if that works?
13:05duck1123yes. Works fine
13:05stuarthallowayand nothing in the logs?
13:05duck1123nope
13:06stuarthallowayif I simply use Clojure to stub the servlet interface will the be close enough to what you have to be a useful comparison?
13:08duck1123my code is at http://paste.lisp.org/display/71768#2
13:15stuarthallowayI'll give it a try
13:16duck1123I can paste the web.xml file too if you need it, but it's quite simple
13:34Lau_of_DKDo we have a Clojure-func for dumping a string to file?
13:34AWizzArdin contrib, (spit ...)
13:35Lau_of_DKThanks
13:39Lau_of_DKIs there a function to download a page like www.google.com ?
13:39AWizzArdyes, in contrib
13:40AWizzArd(duck-stream/reader "https://www.google.de/&quot;)
13:40AWizzArdit can also read files, http and ftp
13:45stuarthallowayduck1123: how are you compiling the servlet, and do you get an error?
13:46stuarthallowayI tried (compile 'net.mycyclopedia.Servlet), which created some classes but also reported an error: java.lang.ClassNotFoundException: net.mycyclopedia.Servlet$_doGet__78
13:46duck1123I wasn't getting any errors
13:47duck1123I think you might need to add the tomcat libs to your classpath
13:47duck1123servletapi in particular
13:47Lau_of_DKAWizzArd: Do I pull the new jar in with (use 'clojure.something) ?
13:48AWizzArdwhen you have the clojure-contrib.jar in your CP then you can immediately use it next time you start up Clojure.
13:48AWizzArduse and require are there to allow you to call functions with a shorter name
13:48AWizzArdnot to make it possible to use them... that's what the cp is for. As soon stuff is in there your app can call all functions from the libs in the .jar
13:50AWizzArdinstead of typing always (clojure.contrib.duck-streams/reader ...) you can say (require '[clojure.contrib.duck-streams :as ds]) and then (ds/reader ...)
13:50Kerris7I wanna buy rhickey_ a copy of the Qi book, let him flip through it, see what he thinks of it
13:51Lau_of_DKGood tip, thanks AWizzArd
13:51kotarak1:6 user=> (clojure.contrib.duck-streams/reader "http://www.google.de&quot;)
13:51kotarakjava.lang.ClassNotFoundException: clojure.contrib.duck-streams (repl-1:6)
13:51kotarak1:7 user=> (require 'clojure.contrib.duck-streams)
13:51kotaraknil
13:51kotarak1:8 user=> (clojure.contrib.duck-streams/reader "http://www.google.de&quot;)
13:51kotarak#<BufferedReader java.io.BufferedReader@a8f100>
13:51kotarakSo it's not totally optional.
13:52stuarthallowayduck1123: Tomcat is on the classpath, it's something else
13:52stuarthalloway...and different from the problem you have :-)
13:53duck1123ahh! (set! *compile-path* "WEB-INF/classes")
13:54stuarthallowayoh, you aren't putting the files there?
13:54AWizzArdkotarak: ah okay right, I already forgot that because I added that guy in my (ns ... (:require ...)) anyway
13:55duck1123did it create the class files for you?
13:55stuarthallowayyes, but perhaps not correctly
13:55duck1123I think by default it'll put them in classes/ not WEB-INF/classes
13:56stuarthallowayI put them in my working directory and copied them over myself
13:56duck1123ok, I had them build right into the correct location
13:57stuarthallowayhere'
13:57stuarthallowayhere is what I am seeing: http://paste.lisp.org/display/71866
14:02stuarthallowaynevermind, reading the docs saves the day once again
14:08Lau_of_DKDidnt we used to have a not-nil? ?
14:09Lau_of_DKnevermind
14:31Lau_of_DKIsnt (org.apache.commons.io FileUtils) standard when you have apache2 installed?
14:33hiredmanI imagine it depends on who you get your apache from
14:33stuarthallowayLau_of_DK: what do apache2 the webserver and Apache Commons the Java library have in common?
14:34Lau_of_DKstuarthalloway: trick question?
14:34stuarthallowayother than a brand name...?
14:34stuarthallowayno, seriously
14:34hiredmanthey are part of the apache foundation, whatever that means
14:34hiredmanprojects of the "
14:34stuarthallowayall the Java "Apache" packages are former "Jakarta" packages
14:34Lau_of_DKI found a simple example in Java to dump a file, where they import (org.apache.commons.io) so I figured it was some kind of bundle since no special notice was made about the import
14:35stuarthallowayjust google "Apache Commons" --it's a single jar
14:35hiredmanuh, really?
14:35stuarthallowaywell, commons is anyway
14:36stuarthallowayapache the web server isn't written in Java, so I don't see why it would ship with much in the way of Java libs
14:37Lau_of_DKthanks stuarthalloway, right you were
14:42Lau_of_DKhttp://www.kodejava.org/examples/55.html
14:42Lau_of_DKCan somebody tell me why they dont close the File. object ?
14:42hiredmanspite?
14:43hiredmanjava.io.File objects are not opened or closed
14:43hiredmanthey are not an io stream, they are a file
14:43Lau_of_DKAs I recall, file objects are closed so guarantee the final flush
14:44hiredmanand the writestring method must take care of opening an io stream
14:44hiredmanLau_of_DK: I pretty sure you are thinking of iostreams
14:44Lau_of_DKk
14:45hiredmanhttp://java.sun.com/j2se/1.4.2/docs/api/java/io/File.html <-- doesn't have a close method
14:45RSchulzDoesn't have one. Never will...
14:45Lau_of_DKRight you are
14:45Lau_of_DKRSchulz: What an incredibly useful comment :)
14:45hiredmannever say never
14:45RSchulzI can't be helpful 100% of the time.
14:46RSchulzExcept, of course, to utter the timeless phrase: "Never say never."
14:46Lau_of_DKhehe
14:47danlarkinand the phrase explaining it
14:48RSchulzWhich one?
14:48RSchulzPTV was just one the other day. So hilarious.
14:49hiredmanis there anything in contrib for csv munging?
14:50hiredmanor does anyone know of a nice java lib for it?
14:50danlarkinlisppaste8: url
14:50lisppaste8To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.
14:51lisppaste8danlarkin pasted "OT time wasting" at http://paste.lisp.org/display/71869
14:51danlarkinRSchulz: that's the quote I'm thinking of
14:58RSchulzYup. I know that episode.
15:00Lau_of_DKlol
15:35Lau_of_DKIs there a simple way to download an .html file and have the javascript evaluated? It will generate some tables which I need the data from
15:37danlarkinLau_of_DK: simple way? no
15:40Lau_of_DKdanlarkin: Alright, I just need to have it done by midnight, 2� hours from now, where do I look ?
15:41danlarkinwell you'll need to evaluate the javascript
15:41danlarkinso you can either embed a javascript engine or try to shell it out to somewhere
15:59RSchulzDoes anybody know of work similar to http://okmij.org/ftp/Streams.html that isn't phrased in terms of Haskell? I don't know the language and find it entirely abstruse.
16:06hiredmanI am trying to write a macro the defns some functions,
16:06hiredmanjava.lang.Exception: Second argument to def must be a Symbol (NO_SOURCE_FILE:591)
16:07hiredmanit seems like the first argument to def is supposed to be a symbol?
16:08mfredricksonRSchulz: which part specifically -- not that I have anything for you, I'm just curious
16:09mfredrickson(i've been thinking about linear algebra in Clojure for the last few days, so that caught my eye)
16:09RSchulzWell, as a language heavy in syntactic sugar, I find I can't get past line one of any example.
16:09RSchulzHowever, I just found a "cheat-sheet" (13-page tutorial) on Haskell, which should prove helpful.
16:10duck1123that's a hell of a cheat sheet
16:10RSchulzExactly what someone remarked on the comment page where I found it...
16:11RSchulzI see that it is written "quick reference card" format (three-column landscape)
16:11RSchulzFor those interested: http://blog.codeslower.com/2008/10/The-Haskell-Cheatsheet
16:31AWizzArdIs there a java lib for obfuscating a database?
16:31AWizzArd(as in oracle, postgres, mysql, ...)
16:31RSchulzWhat sort of obfuscation?
16:36AWizzArddatabase obfuscation that will semantically leave all data inside the db, but rename tables, fields, contents, etc.
16:36AWizzArdSo that someone who is not dedicated into finding out the scheme behind this won't be able to read the db
16:37danlarkinAWizzArd: you are asking for a maintenance _nightmare_ by doing that
16:37AWizzArdCan you tell me more about this?
16:38RSchulzI can't see the virtue. Unlike Java code, you don't have to (and should not want to) expose your DBMS to arbitrary client use.
16:41Chousukedatabase obfuscation sounds like something you should never need :/
16:41Chousukebut I can't say for sure, people have had need for many weirder things :P
16:59jawolfehi, i'm new to clojure and have a performance question, if anyone can help ...
17:00danlarkindon't ask to ask, just ask :)
17:00jawolfe(defn mypow [x n]
17:00jawolfe (let [x (double x)]
17:00jawolfe (loop [ret (double 1.0) n (int n)]
17:00jawolfe (if (= n 0) ret (recur (* ret x) (unchecked-dec n))))))
17:00RSchulzWoo-Hoo! "[Pragmatic Bookstore] An updated version of Programming Clojure (PDF) is available"
17:01RSchulzChanges in this version include:
17:01RSchulzChapter 7, Macros
17:01jawolfeis my best attempt at an efficient clone of the pow function for ints
17:01jawolfeint exponents i mean
17:01jawolfebut its still 10 times slower than the same code in SBCL
17:01whiddenRSchulz: gee you're behind the times... already 1/2 trough that chapter :)
17:01RSchulzI'm probably just further down the email distribution list...
17:01jawolfeIs there something I'm doing wrong?
17:01RSchulzNow I have to wait for the gerbils.
17:02jawolfe(of course, I'm not writing for its own sake, just to get an idea how much performance hit I may take switching to Clojure from SBCL)
17:03whiddenjawolfe: there looks to be an unchecked "times" in the recur.
17:04Chouser(doc unchecked-multiply)
17:04clojurebotReturns the product of x and y, both int or long. Note - uses a primitive operator subject to overflow.; arglists ([x y])
17:05jawolferight, thanks. but x is a double ... is there a corresponding version of unchecked-multiply for doubles?
17:05Chouseroh. :-P doesn't appear to be.
17:06Chouserjawolfe: you're running mypow multiple times (hundreds or thousands) with -server on your java command line?
17:06RSchulzjawolfe: I'm not an expert on numerics, but for a floating-point value, isn't all the same? You'll get an infinity if you overflow, not an exception, right?
17:07jawolfeChouser: I'm running it 3 times, with very large arguments
17:07jawolfeChouser: (dotimes [i 3] (time (print (mypow 1.00000001 100000000))))
17:08jawolfeRSchulz: I don't really care about overflow, I'm wondering about speed. I can't get the clojure version to run better than 10 times slower than the corresponding SBCL version.
17:08RSchulzMy point is that there's not difference. The checking doesn't happen in machine code, it happens in the FPU.
17:09jawolfeChouser: yes, with -server
17:09RSchulz(If I understand correctly, which I'm not really sure I do.)
17:09jawolfeOK, that sounds right to me ... I'm not sure where the slow-ness is coming from
17:09Chousertry (zero? n) instead of (= n 0)
17:09jawolfeJust that adding type declarations only sped things up less than 25%, when I was hoping for more like 20x.
17:10RSchulzFor kicks, did you try it with float instead of double?
17:10RSchulzWhat hardware are you running on?
17:10jawolfeChouser: you win.
17:10jawolfethat cuts down by a factor of 10
17:11RSchulzWow.
17:11Chouserthe problem there was both = and 0
17:11RSchulzThe 0 is a BigInt?
17:12jawolfe0 is an Integer I guess?
17:12ChouserI think = always uses Object, so it boxes its args. You could use == instead.
17:12RSchulzAcquired using valueOf(0)?
17:12ChouserRight 0 is also a boxed integer, so (== n 0) isn't any faster.
17:12RSchulzThis is one of the things that Cliff guy was talking about in his presentation at the JVM summit.
17:12ChouserBut (== n (int 0)) lets everything stay primitive
17:12jawolfe(= (int 0) n) is slow too
17:13jawolfeYeah, you're right ... (== (int 0) n) does it.
17:13jawolfeThanks for your help, I probably would never have figured that out.
17:14Chouserand of course 'zero?' is prettier
17:14drewrMore Schemey anyway.
17:15jawolfeI didn't know about == either, I don't recall seeing it in any of the docs I've read
17:16ChouserBut when trying to decide if Clojure is a good risk, don't forget that for tight loops like this that really matter in your real app, you can always drop to Java or even use JNI and native code if you can't find any other way.
17:17ChouserIn practice I think it's unlikely you'll ever need to.
17:17jawolfeYeah, I realize that ... but I tend to do a fair amount of probabilistic stuff and so having at least the possibility of efficient math without dropping into Java (shudder) makes me much happier.
17:18hiredmanlisppaste8: url?
17:18lisppaste8To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.
17:18jawolfeOne more quick question: my SLIME interrupts don't seem to work with Clojure, does anyone know what gives?
17:18Chouserhopefully the JVM will get tagged numbers eventually and make staying on the fast path less tricky.
17:19lisppaste8hiredman pasted "getters macro" at http://paste.lisp.org/display/71878
17:19jawolfeyes that would definitely be nice
17:19hiredmananyone up for some macro help?
17:20RSchulzWhat help do you have?
17:20jawolfehaha
17:20hiredmanyou are truly hilarious sir
17:20Chouserjawolfe: sorry, I don't use SLIME. But plenty of others do, surely they'll speak up any moment now...
17:21jawolfeChouser: no worries, thanks ... what do you use?
17:21hiredmansomehow I seem to be not evaluating something in my macro instead of accidently evaluating twice
17:21Chouservim and a repl in a terminal.
17:21RSchulzI'll see if I can read ahead fast enough in chapter 7 of Stu's book to give you an answer.
17:22drewrjawolfe: I use SLIME, but don't much experience with CL. What do you mean by interrupts? You mean restarts?
17:22RSchulzIs it the 71878
17:22RSchulz?
17:22hiredmanRSchulz: yess
17:22Chouserclojurebot: macro help?
17:22clojurebotmacro help is http://clojure-log.n01se.net/macro.html
17:22Chouserhiredman: ^^^
17:23jawolfedrewr: I mean, how do you interrupt what's running at the REPL
17:23RSchulzDoesn't a def have to appear at the top level? You've got it in a let body.
17:23jawolfedrewr: like, if you type (repeat 0)
17:24hiredmanChouser: the macro works fine if I just use it, but I try to use it in a map and I get something not right
17:24RSchulzdefn is itself a macro...
17:24drewrjawolfe: I think someone was working on that, but I'm not sure the JVM is going to play nicely.
17:25Chouserjawolfe: setting *print-length* helps
17:25hiredmanRSchulz: the macro forks fine if I call it directly (not using map)
17:25hiredmaner
17:25hiredmanworks
17:25RSchulzI think it has something to do with when the macro is applied. It's happening once, not once per iteration of the map.
17:26lisppaste8hiredman annotated #71878 with "no map" at http://paste.lisp.org/display/71878#1
17:26RSchulzSo you get the same result repeatedly.
17:26jawolfeChouser: thanks
17:26drewrWhen it's unresponsive, I kill the java process and restart. :-/ You can write a function to do it automatically.
17:26jawolfedrewr: hmmm, so you have to killall lisp and start over?
17:26hiredmanRSchulz: there is no :x key to that map
17:26jawolfeer i mean killall java
17:27hiredmanthe X must be the x paramter to the (fn [x] ...) in the map
17:27RSchulzIt's suspiciously similar to (up-first-letter "x")...
17:27hiredmanthat is the only place x is anywhere in the code
17:27drewrjawolfe: Yeah, but I tend to keep my code in buffers where I can do a quick C-c C-k and keep going.
17:27RSchulzChange it to y and see if the result under map changes similarly...
17:28jawolfedrewr: makes sense, just a bit annoying ... interrupting can be especially nice for debugging
17:28hiredmanRSchulz: uh, there is no (up-first-letter "x")
17:29RSchulzYou know what I mean.
17:29Chousertry: `(name ~k)
17:29jawolfedrewr: but i'll take what i can get
17:29hiredmanno I don't
17:29RSchulzJust try it. change that x to something else and see what happens under map.
17:29drewrjawolfe: Definitely. That's really my only complaint with Clojure compared with CL. Debugging feels more cumbersome. But you learn tricks that at least make it scientific. :-)
17:29hiredmanChouser: Unable to resolve symbol: k in this context
17:30Chouseroh. uh.
17:30RSchulzYou don't think the X in the result, the up-first-letter and the x in your macro definition are suspicious?
17:30RSchulzSuggestive of some relation between them?
17:30Chouser`(name ~ky)
17:30ChouserRSchulz: I think you've got your finger on it.
17:30jawolfedrewr: Good to know, thanks!
17:31lisppaste8hiredman annotated #71878 with "x to y" at http://paste.lisp.org/display/71878#2
17:31jawolfeOK, thanks for your help all. Time to try to write my first real clojure code ...
17:31hiredmanoh
17:31hiredmanwoa
17:31hiredmanbug
17:32drewrjawolfe: No problem. Don't be afraid to ask for help. We all usually learn something.
17:32hiredmanstill doesn't work, but what I pasted as k where ky should be in the macro
17:36Chouserky is the object passed in. ':id' in one case, 'x' or 'y' in the others.
17:37Chouserall of that has nothing to do with a value that may or may not be stored in a local or global var by that name.
17:37gnuvince_I thought ky was what was used to pass objects in ;-)
17:37hiredman?
17:37gnuvince_</bad joke>
17:37Chouserouhc
17:37Chouserouch
17:37Chouseror not, I suppose.
17:38hiredmanthe only place in my code the getter macro could be getting the
17:39hiredmanx or y is from the fn surrounding the call to getter
17:39Chouserhiredman: think about it this way. The whole 'map' expression gets compiled once, so you macro gets run once.
17:40hiredmanChouser: if the macro gets compiled once, how come I get a whole list of the result of (defn) stuff?
17:41Chouserthe expression your macro returns gets evaluated for each item in the seq
17:41RSchulzThe code it produces gets mapped across the sequence supplied.
17:41hiredmanok
17:41hiredmanI guess
17:41hiredmanthanks
17:42Chouserto see what that expression is, use: (macroexpand '(getter f "family" x))
17:42RSchulzBut keep in mind that macroexpand only expands until the top level of an expansion is no longer a macro application.
17:43RSchulzIf there are nested macros, they won't be expanded by macroexpand.
17:43Chouserright, which is why you want to run it directly on the macro you wrote
17:43RSchulzSomeone posted a pevasive macro-expander.
17:43AWizzArdyou need to manually expand all macros if you want to write a code analyzer tool
17:44RSchulzI'd rather wait for someone else to write a code analyzer tool.
17:44AWizzArdRSchulz: eval must be doing it
17:44RSchulzI have code to write...
19:24clojurebotsvn rev 1149; added :exposes-methods to gen-class, patch from Matt Revelle
20:25pjb3Has anyone tried building an Android app with Clojure yet?
20:26ChouserAs far as I know, if Android worked applets would as well.
20:27ChouserThe last time I tried an applet it did not work, as a dynamic classloader is still created.
20:28RSchulzDo the Android tools operate at the JVM bytecode level, or at the Java source-code level?
20:28RSchulzWait, I guess it must be bytecode, 'cause I heard of people getting Scala code working on Android.
20:29RSchulzSo with AOT it should work, in principle, right?
20:38ChousukeRSchulz: bytecode AFAIK.
20:40ChouserRSchulz: yes, I think once the dynamic classloader is fully optional, applets and android ought to work
20:40ChousukeGoogle's being pretty clever. apparently they have their own bytecode to get around some restriction imposed by sun; so they're not officially Java-compatible, just de facto so :P
20:41Chouseror be able to be made to work.
20:41RSchulzI don't think I see the significance of dyamic classloaders.
20:41Chouserfor android?
20:41RSchulzActually, don't they _translate_ JVM to an entirely separate set of opcodes?
20:41RSchulzIn general. What's the issue with dynamic classloading that's tripping up Clojure-generated bytecodes?
20:42ChousukeRSchulz: as far as I know, yes
20:42mattreplit's register-based
20:42Chouserin non-AOT code, each Clojure expression is compiled into Java bytecode and then has to be loaded to run
20:43RSchulzRight.
20:43Chouserthat's a problem for applets because they don't trust your custom dynamic classloader
20:43RSchulzAh.
20:44Chouserit's a problem for android because the runtime platform has no ability to translate Java bytecode to what it needs to run -- that's a development and compile-time function.
20:44RSchulzHow do the other dynamic languages, Groovy, Scala, handle this problem? I run my Grails app under Tomcat without problem.
20:44ChouserAs far as I know, tomcat runs Clojure code fine.
20:44RSchulzBut that's where AOT comes in, right? You get all the bytecodes up front for Android's tools to translate.
20:45RSchulzI think duck1123 would disagree with you...
20:45Chousukethat would disallow redefining stuff at runtime though. :/
20:45Chouseryes, AOT when fully realized should solve both the applet and android problems, and it's getting very close, but it's not quite there yet.
20:46RSchulzRight... So only those programs that, in essence, require the Clojure compiler at run-time (after AOT compilation) would be left out.
20:47ChouserI saw webjure hello world work in tomcat months ago. I'm not sure what's causing problems for duck1123, but I don't think it's anything inherent in Clojure.
20:47ChouserRSchulz: right. like a REPL, for example.
20:47RSchulzI foresee the day that Android's device-resident run-time includes a JVM bytecode -> Android opcode translator.
20:47RSchulzWell, if I can't run a Clojure REPL on an Android phone, it's no-sale for me.
20:48Chouseryou could write a clojure interpreter (in Clojure, if you wanted) and then you'd be all set.
20:48RSchulzOf course, I've yet to buy my first cell phone.
20:48RSchulz... Yeah. I'm a real retro-grouch.
20:49RSchulzI wonder... Does anybody know of Android in a non-cell-phone device?
20:49RSchulzI guess that would be a PDA, basically.
20:49RSchulzI don't suppose there's much of a market for such a thing.
20:55duck1123Chouser: Webjure uses actual java, not pure clojure
21:16jawolfeHi again. I'm wondering how to re-export vars from a namespace. Suppose I have namespaces a, b, and c, and i'd like to export some subset of all of their functions under a single new namespace d. Is this possible, and/or is there a more ideomatic way to produce "interfaces" to large collections of code? Thanks...
21:19hiredmanjawolfe: http://clojure.org/api#toc358 should get you started
21:19duck1123so you want to be able to require d and have select fns from a b and c available?
21:21jawolfeduck1123: yes, exactly
21:22jawolfehiredman: thanks, have already read the docs. all i was able to find were cryptic references to "public vars" without any details of what they are or how to make a var "public"
21:23duck1123jawolfe: in that case, I don't know of anything to really do that
21:24jawolfeduck1123: thanks
21:24duck1123but you could probablt have a macro to take a seq of symbols to require
21:24duck1123def the macro and the var in d, then call it from e
21:25duck1123you might not even need the macro
21:25jawolfehmmm, that could work
21:26jawolfealthough i'd rather not have to do anything extra in e
21:27jawolfei'm not necessarily tied to this type of organization
21:27jawolfebut just trying to start a big project
21:27jawolfeand wondering how best to organize and compartmentalize things
21:30RSchulzI'm not sure it's documented or if I just saw it in reading Clojure code, but (def- ...) and (defn- ...) define "private" (non-exported) Vars.
21:33RSchulzActually, the only private def form in core is (defn- ...)
21:34RSchulzOthers, defmacro-, defonce-, defstruct-, defunbound- and defvar- are defined in clojure.contrib.def
21:35jawolfeThanks, that helps
21:38jawolfeIt still seems useful to me to have a way to declare refer'd symbols as public in a namespace
21:39jawolfei guess i can simulate by defining new vars in the namespace with values copied from other namespaces ...
21:39jawolfeah well, gotta go, thanks for your help.
23:01danlarkinanyone have a remove-whitespace function that won't remove whitespace from inside quoted strings?
23:06zakwilsondanlarkin: I'm not sure I understand what you mean.
23:07danlarkinzakwilson: for unit testing my JSON parser I'm slurping in text files of JSON and encoding them to json and then decoding again and checking against the original
23:07danlarkinbut part of the test is if it handles wacky unconventional whitespace in the original JSON file
23:08danlarkinso when I do (= original-json decoded-json) the original-json has wacky whitespace while the decoded-json doesn't, so they aren't equal
23:09zakwilsonAhh... I think I understand. I don't have a function like that, but I do have something for parsing CSV that you could probably adapt without much effort. Want it?
23:09danlarkinyes if you would be so kind, that would probably help
23:11zakwilsonOne moment - haven't used a pastebin before, and I need to copy a utility function or two out of another file.
23:17lisppaste8zakwilson pasted "function for danlarkin" at http://paste.lisp.org/display/71897
23:19danlarkinzakwilson: thanks! :) One thing I notice is that this function can overflow the stack if it recurses too deeply
23:21zakwilsondanlarkin: How? I was under the impression that recur couldn't overflow the stack.
23:22danlarkinscan-for-delimeter calls itself
23:24hiredmanclojurebot: mk-bean is http://gist.github.com/34229
23:24clojurebotRoger.
23:24zakwilsonSo it does. I thought I had changed it to recur, and I think it could be so changed.
23:25zakwilsonI was using the self-calls to make a stack overflow possible after an early attempt resulted in an infinite loop.
23:25Chouser(apply str (re-seq #"\"(?:[^\\]|\\.)*?\"|\S" text))
23:25Chouserthat's probably buggy. :-)
23:26Chouseryou don't need to handle chunks quoted with 'single quotes' do you?
23:27Chousergotta scoot. later, all.
23:28zakwilsonJust changed it to recur and it works.
23:28danlarkinah yes zakwilson, I'm all too familiar with infinite looping :)
23:30zakwilsonI've gotten in to the habit of using self-calls instead of recur when I'm not sure about the end-test in a function.
23:59danlarkinChouser-away: I think that regex works, thanks