#clojure logs

2011-10-09

00:13khaliGcan't wait for clojurescript support to be added to slime.. this is so cool :)
00:15dnolenkhaliG: totally.
00:18ArafangionAh, other langauges do have atoms, after a fashion.
00:20ArafangionAnd limited forms of agents.
00:20ArafangionAlthough python itself doesn't really have any form of agent.
00:20brehauta lot (most) of the features of clojure are not new; they are carefully chosen and designed to integrate well together
00:22ArafangionIt seems that clojure has managed to avoid the typical flaws new langauges have - they typically try to be too simplistic.
00:22khaliGhaha is that a backhanded compliment?
00:22ibdknoxClojure is pretty simple
00:22dnolenArafangion: ibdknox: on the surface. Implementation is very much "Worse Is *not* Better"
00:23dnolenunder the hood is some complicated stuff.
00:23ibdknoxSure
00:23ibdknoxunder the hood of C# is some crazy stuff too
00:23ArafangionC# is not exactly a simplistic language.
00:23ibdknoxbut I would say Clojure is far simpler than C#
00:24ArafangionAlthough the earlier versions of it probably were, for a java-inspired language.
00:24ibdknoxwhat is your basis of comparison then?
00:24dnolenSimplicity-the design must be simple, both in implementation and interface. It is more important for the interface to be simple than the implementation.
00:24khaliGibdknox, c++ obviously
00:24ibdknoxlol
00:24dnolenhttp://www.jwz.org/doc/worse-is-better.html
00:26ibdknoxI'm in the interface is what matters camp.
00:26dnolenibdknox: yes, Dick Gabriel does not disagree
00:26Arafangionibdknox: Consider Scheme and Go.
00:26Arafangionibdknox: they are both very simple languages, although Go does try to break new ground in at least one area.
00:27ibdknoxArafangion: Go isn't really simpler than python or ruby
00:27dnolenArafangion: Scheme and Go both screw up the simple part.
00:27ArafangionCould you elaborate?
00:27ibdknoxScheme is also not a particularly practical language
00:27dnolenGo channel - puke
00:27dnolenScheme - concrete types which can't be replaced - puke
00:28ArafangionHeh, ok. :) I gotta go, friend arrived. :(
00:28ibdknoxactually no one in here probably disagrees
00:29ibdknoxVery few languages are internally consistent
00:29ibdknoxit's hard to suggest simplicity without that though
00:31ibdknoxdnolen: Is the "worse is better" philosophy widely held?
00:32dnolenibdknox: I would argue yes. But the reason why is complex - it often gets foisted on us - time constraints, programming languages etc
00:36ibdknoxdnolen: hm, I think my argument is that complexity seeps into any non trivial system, and that the general purpose of building the system to begin with is to provide an interface to something that is otherwise difficult. The greatest value is derived from maintaining a simple abstraction to hide the fact that the implementation is likely painful. There are certainly times where you have to swing one way or the other... bu
00:36ibdknoxt in general a thing isn't very useful if it's too complicated to use efficiently
00:37dnolenibdknox: we are in agreement. and that's a fundamental Clojure stance.
00:37dnolen"reasoning under concurrency is totally lame", let's fix that by any means necessary is Clojure's MO.
00:38ibdknoxindeed
00:57todunhi. I'm new to clojure and on here, it was recommended I use clooj and 4clojure.
00:58todunhow do I install clooj? there are download instructions but no install instructions at the github repo.
00:58amalloytodun: the jar should be executable
00:59todunwhere do I get newbie style tutorials that can ease me into learning clojure?
00:59todunamalloy: there is no jar included.
01:00amalloysure there is. look on github, click Downloads in the upper-right
01:00amalloyhttps://github.com/downloads/arthuredelstein/clooj/clooj-0.2.4-standalone.jar looks like the current release
01:01ibdknoxhm
01:01ibdknoxwhat happened to try-clojure?
01:01khaliGtodun, whats your programming background?
01:02amalloyibdknox: interesting. dunno, i'll try restarting it
01:02todunkhaliG: I'm new in general, but I've tried a few languages with different paradigms.
01:02todunkhaliG: familiar with many but very uncomfortable in all languages.
01:06amalloyibdknox: resurrection succeeded
01:06ibdknoxyay!
01:06ibdknoxtodun: http://try-clojure.org/
01:07todunibdknox: thanks will do.
01:07todunibdknox: the more tutorials the merrier :)
01:19Arafangionibdknox: Fair enough - I find that professionally, "worse is clearly better".
01:19Arafangionibdknox: As long as any issues are managed - it's usually much better to get a product out the door than to spend a year longer on it.
01:22Arafangion(And wow, that ds.js is insane)
01:22ibdknoxI have a simple cljs implementation of D3 in Pinot :)
01:22Arafangionibdknox: I can't bear to think about a pinot implementation. :)
01:23ibdknoxhuh?
01:24ArafangionI seemed to think if pinot as an esoteric 'visual' language based on abstract art?
01:25ibdknoxhttp://github.com/ibdknox/pinot
01:26ArafangionIntruging.
01:33kab3wmibdknox: I just started using Noir to build a content management system. Really loving Noir. I'm still new to Clojure ( even Lisp ), but building a web app is helping me figure things out.
01:33ibdknoxkab3wm: awesome :)
01:36ibdknoxkab3wm: have you run into anything you wish was better explained/is confusing?
01:37kab3wmibdknox: well, everything is confusing at the moment.. but I'm getting the hang of it. My issues are more with poorly documented libs. Like congomongo. But I've got basic CRUD stuff working with Noir and a MongoDB at the moment.. so hopefully it's mostly down hill from here.
01:38zakwilsonCongomongo has great documentation as long as you're willing to read the source.
01:38amalloyArafangion: you're thinking of Piet
01:38Arafangionkab3wm: "downhill" is usually a bad thing. ;)
01:38Arafangionamalloy: Indeed, I was.
01:38kab3wmzakwilson: yes, that's been working.
01:39zakwilsonBut yeah, docs would be nice some day.
04:36sritchiehas anyone used the google maps api with clojurescript?
05:12_khaliGwanting to use #(..) syntax but wanting to ignore the parameter/s. is there a way?
05:20amalloyyes, but don't do it
05:21_khaliGamalloy, for swing callbacks - dont often use the event e, for instance
05:21amalloy_khaliG: so just write (fn [_] (...))
05:21_khaliGamalloy, lol i have but its ugly
05:23amalloy*shrug* turn your head and squint if it helps you. it's not ugly,and it's better than #(do %& (...))
07:52tdrgabiregarding the utf8 issue earlier, it appears to be an emacs thing. it was set to a different locale somehow. I run M-x dos-to-utf8 on the whole file and now my characters are nice
07:54ArafangionWhat was the utf8 issue?
08:22daniel___can anyone suggest an equivalent to ord() in python? a function that returns the unicode code point of a char?
08:26daniel___think i found it (codepoints s)
08:26jaleyhey guys - has anyone here had much luck with clojure and android? i'm getting a weird NPE from core.clj (Properties.load() call defining *clojure-version*) before my code is executed afaik. google searching revealed nothing :/
08:35Arafangionjaley: Hmm, I don't know if clojure works on android. You do know that android does NOT run java?
08:36Arafangionjaley: It's using the Dalvik VM.
08:36daniel___java.lang.Exception: Unable to resolve symbol: codepoints in this context (NO_SOURCE_FILE:7) can anyone help me out?
08:37daniel___i thought i required clojure.contrib.string
08:37Arafangiondaniel___: I think java strings are essentially UTF-16 arrays?
08:38daniel___ok Arafangion, just gunna try something
08:38daniel___what does that mean in terms of what i want to do?
08:39jaleyArafangion: yeah - there are a few success stories around. there's even a clojure REPL app on the android market actually :D
08:39daniel___im trying (- "a" "b")
08:39Arafangionjaley: Neat. :)
08:39jaleyArafangion: plus some helloworld examples on various blogs
08:39Arafangionjaley: That's awesome. :)
08:40jaleyArafangion: Android actually uses java developer tools, then google provide a tool to translate the bytecode to their dalvik format, so many jvm languages actually "sort of" work. in a broken and annoying kind of way... :/
08:40ArafangionThis means that it's trivial to use clojure as a single, cross platform language. :)
08:40Arafangionjaley: Yes, specifically, dynamic bytecode generation gets broken. :(
08:41ArafangionWhich breaks Jython, for instance.
08:44jaleyArafangion: yeah... it's far from perfect, but apparently basic things should work
08:44daniel___i have a repl open... (ns whatever (:require clojure.contrib.string))
08:45_khaliGi'm looking forward to writing my android app with clojurescript
08:45daniel___(codepoints "a") gives me the error
09:01bsod1paredit's C-) is great but I want to disable auto-close parens, how can I do that?
09:03daniel___i just needed (clojure.contrib.string/codepoints "a")
09:03daniel___thanks for your help guys!
09:06gfredericksdaniel___: oh hah. I should have noticed that.
09:07daniel___nps :)
09:07daniel___now i need a function that splits a string into a list of individual characters
09:08st3fansplit?
09:08daniel___yeah st3fan, i think so
09:08daniel___what regex will give me each char?
09:08st3fan,(seq "foo")
09:08clojurebot(\f \o \o)
09:08st3fanthere you go
09:09daniel___what library is that in?
09:09daniel___and what are the \?
09:09st3fancore
09:09st3fan\f is the single character f
09:09daniel___ok, let me experiment
09:09daniel___thanks a lot
09:09st3fanlike 'f' on other languages
09:12st3fan,(str (join (seq "I love cheese"))(
09:12clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading>
09:12st3fan,(str (join (seq "I love cheese")))
09:12clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: join in this context, compiling:(NO_SOURCE_PATH:0)>
09:13st3fan,(str (reverse (seq "I love cheese")))
09:13clojurebot"(\\e \\s \\e \\e \\h ...)"
09:13st3fanhm
09:13st3fan,(str (str-join (seq "I love cheese")))
09:13clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: str-join in this context, compiling:(NO_SOURCE_PATH:0)>
09:14gfredericks,(apply str (reverse "I love cheese"))
09:14clojurebot"eseehc evol I"
09:16Bronsa,(reverse "string")
09:16clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.IllegalStateException: replace already refers to: #'clojure.string/replace in namespace: sandbox>
09:16Bronsai think i broke clojurebot :E
09:16gfredericks&(reverse "string")
09:16lazybot⇒ (\g \n \i \r \t \s)
09:17gfredericksis lazybot to the rescue???
09:17lazybotgfredericks: Oh, absolutely.
09:17Bronsai ,(use 'clojure.string)
09:17Bronsaand reverse && replace got broken
09:17gfredericksBronsa: somebody will reboot it eventually
09:17Bronsai'm sorry ( ,_,)
09:17Bronsadidn't mean to broke it
09:17Bronsa*break
09:17gfredericksno problem. lazybot still works.
09:20st3fan&(str (map #(str %) (seq "Hello")))
09:20lazybot⇒ "clojure.lang.LazySeq@5db0151"
09:20st3fanhow does str return a lazy seq?
09:26Bronsast3fan: you're trying to str a sequence
09:26Bronsayou should apply str to a sequence
09:31gfredericksst3fan: you also might like pr-str
09:32gfredericks&(pr-str (map str (seq "Hello")))
09:32lazybot⇒ "(\"H\" \"e\" \"l\" \"l\" \"o\")"
09:43mindbender1
09:43gfredericksmindbender1:
09:44mindbender1gfredericks: hi
09:46gfredericks:)
09:47mindbender1I'm in the process of learning clojure and have read programming clojure and the joy of clojure and my head is spinning...:)
09:49gfredericksmindbender1: what sorts of languages are you coming from?
09:50mindbender1not a particularly good programmer prior to clojure but I am familiar with java.. so I wanted a language I could grow with
09:51mindbender1I intend to work in the erp field with the clojure language
09:52gfredericksthat sounds fun
09:52mindbender1any pointers or red signs?
09:53ArafangionWith the ERP field, or clojure?
09:54mindbender1with clojure in the erp field, especially as I intend extend already popular erp packages with clojure?
09:55mindbender1or rather customize them
09:55carkin the same vm as your erp packages ?
09:56mindbender1yes in the same vm
09:56carkso you run the package, and it calls into clojure ?
09:57carki mean, do you intend to have clojure around it, or the other way around ?
09:57mindbender1yes or I was thinking clojure.jar would be somewhere on the lib path of the app
09:57carkas far as i know you might be loosing the benefit of a repl
09:57mindbender1then customizationss will be in a different jar. no touching of classes in the app
09:58carklosing*
09:58mindbender1actually the app I had in mind is adempiere
09:59carki find it's easier to call java (or even patch stuff) from clojure than the other way around
09:59mindbender1yes i intend to call java from clojure
09:59mindbender1that is call the classes in the app from my clojure dev environment
10:00ArafangionYou can't easily call into clojure from java?
10:00carki fyou can use your erp packages as libraries to your clojure app, then you're golden
10:00carkArafangion: yes you can
10:00carkArafangion: only it's annoying when you're used to the ease of developement starting from clojure
10:00mindbender1ok you suggest using the erp packages as lib in my app?
10:01carki don't know if it is possible in your case, but if it was me, i would try very hard before going the other way around
10:02carkone of the strong points of clojure is interactive developement
10:02mindbender1already the app itself allows customizations to be put in a customizations.jar so I was hoping I could write that customization.jar in clojure
10:03carkby calling into clojure, you'd need to use the old code->compile->run cycle at least until you have your interface ironed out
10:03carkwhich is very possible, but annoying
10:05Arafangioncark: Well, if it were me, I'd define the interface in Java... And implement it in Clojure.
10:05ArafangionWhich reminds me.
10:05carkArafangion: yes, true
10:06ArafangionDoes Clojure have a dependency injection framework? (Spring seems to be common...)
10:06carkclojure is a functional language
10:06carkit does not need a dependency injection framework
10:06mindbender1joy of clojure talks about clojure not needing DI
10:07cark,(sort-by identity > [4 3 8 1 2])
10:08clojurebot(8 4 3 2 1)
10:08ArafangionI'm not so sure about that.
10:08carkse how i injected the > function in the sort-by function
10:08carksee*
10:08Arafangioncark: Yes, so the language itself provides it there. For this langauge, at least. That's awesome.
10:09Arafangioncark: Arguably, in the case of python, it does so likewise if you think of the language providing a service locator.
10:09TweyDI frameworks are just a workaround for Java treating functions as second-class citizens…
10:09ArafangionTwey: That's unrelated.
10:09TweyOh?
10:09carki think it's related
10:09ArafangionDI frameworks are a workaround for the proliferation of dependencies caused by writing generic code in OO environments.
10:09carktho i'm no DI guru
10:10ArafangionThey allow you to replace any dependency with another dependency.
10:10ArafangionFor example.
10:10TweyBut you can do that with first-class functions.
10:11ArafangionImplementing a function that operates on a stream is better than implementing a function that operates on a file name.
10:11ArafangionBecause the latter function does not allow you to replace how the file is opened or iterated over.
10:11TweyRight
10:11mindbender1Arafangion: ? please expantiate
10:11carklook at my example again, sort-by is the generic version of sort
10:11ArafangionThat is dependency injection on a trivial level.
10:11TweyI am aware of the concept of DI
10:12TweyAnd I assert that first-class functions provide all the necessary features to do that, without a third-party framework
10:12ArafangionNow, here's where DI gets annoying.
10:12mindbender1Arafangion: references please
10:12TweyOkay
10:12ArafangionWHen you have, eg, a function that does, well, suppose it's a web spider.
10:13ArafangionOne of the functions it uses is get-http-protocol-handler
10:13ArafangionIn a typical, non-oo language, you would have something like: perform_spider(list_of_root_references0
10:14ArafangionBut... If you're using DI as a design technique, you would have:
10:14Arafangionperform_spider(list_of_root_references, http_protocol_handler, generic_sort, ...)
10:14carkwell in clojure you would have something like this :
10:15ArafangionIn OO langauges, you typically end up having a heirachy of dependencies.
10:15mindbender1and with java 6 CDI was built in
10:15cark(defn perform-spider [& {keys [protocol-handler sort-fn ... ]}] ....)
10:15Arafangioncark: Aha, and now we get to the meat of it.
10:15carkthen you can make your factory function, which woudl be the configuration for your application
10:16Arafangioncark: You can do the same in say, Java, as well, but one neat thing a "dependency injection framework", is that it will do that wiring up for you.
10:16carkit won't
10:16Arafangioncark: It will.
10:17carkyou still need to write the xml configuration
10:17Arafangioncark: Ah, that reminds me why I didn't like Spring. :(
10:17carki'd rather write clojure than xml =P
10:17Arafangioncark: Apparently, however, you don't have to. I actually come to DI from C#.
10:17mindbender1what I read of DI was a matter of handling things like initialization and transaction management services
10:18Arafangioncark: And I don't write any XML for my dependency injection, at all.
10:18TweyIt needs to know which dependencies to use, somehow
10:18ArafangionIn C#, I use reflection for that.
10:18carkArafangion: at some point you still need to tell your framework which interface you want to use
10:18TweyThe Spring gets the information from the XML configuration
10:18TweyThe Clojure takes that map argument
10:18carki mean which implementation
10:18Arafangioncark: I use conventions.
10:18TweyI'm guessing the C# uses annotations or something
10:19Arafangioncark: Eg, if I ask for IFoo, then unless I specify otherwise, I tend to mean "Use Foo".
10:19carkwell then you have a single implementation and you don't need DI
10:19ArafangionIn my unit tests, if I ask for IFoo, then unless I specify otherwise, I tend to mean "Use a mock<IFoo>".
10:19Twey… yeah
10:19Arafangioncark: If I didn't haev unit tests, perhaps.
10:20Arafangioncark: But in any case, I do have project-specific conventions and only a small number of exceptions.
10:20Arafangion(exceptions... excemptions... I think I mean the latter)
10:20carkas i said, i'm no DI guru, but i really don't see how you can use a generic functionality without specifying the implementation you will be using
10:21carkmaybe i've been away from c# and java for too long =)
10:22carkmy take on it is this : in java/c# you're mostly working with objects, they need to be configured at creation time
10:23Arafangioncark: The implementation in my primary project is specified as: "Use the implementation of the same name minus the leading 'I'".
10:23carkin clojure you're mostly working with function
10:23Arafangioncark: As I said, I use reflection.
10:23carkso you configure the function at call time
10:23carkArafangion: ah i get it now
10:24Arafangioncark: However, in my unit tests, I do not want to be testing teh dependencies, I want to test the "unit" in isolation.]
10:24Arafangioncark: And that, is actually teh main reason I use DI.
10:24ghiuhi, can anyone explain to me why (map #(+%1 1) '(1 2 3 4)) works while (map #((let [one 1] (+%1 one ))) '(1 2 3 4)) gives an error?
10:24Arafangioncark: So as a result, for the unit test project, I say: "The implementation I want is a dynamically generated mock of type IFoo".
10:24cark,(map #(let [one 1] (+%1 one )) '(1 2
10:24cark 3 4))
10:24clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading>
10:24cark,(map #(let [one 1] (+%1 one )) '(1 2 3 4))
10:24clojurebot(2 3 4 5)
10:24Arafangioncark: So I make a real instance of the unit I want to test... With all of it's dependencies automatically mocked out.
10:25carkArafangion: i see, and that's nice
10:25Arafangioncark: Extreme DI is pointless in a functional language, I'll agree with that... However...
10:25ghiu, (map #((let [one 1] (+%1 one ))) '(1 2 3 4))
10:25clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>
10:25Bronsaghiu you have an extra pair of parenthesis
10:25Arafangioncark: Surely you will have some kind of 'module' that you can define as a "unit", and surely you'll want to test each unit individually?
10:26ghiuBronsa: oh, the one before let?
10:26Bronsayes
10:26Bronsaalso the one matching that
10:26ghiubecause it is already the body of the function
10:26ghiui see
10:26carkArafangion: i must confess i mostly don't do unit testing, i'm all good with behaviour testing
10:26ghiuthanks
10:26Bronsanp
10:27Arafangioncark: By behaviour testing, do you mean system testing?
10:27carkArafangion: higher level testing i guess
10:27Arafangioncark: Yeah... Those are important too, but they have this one massive flaw.
10:27carki do small time testing at the repl =)
10:27Arafangioncark: They tend to be slow... And if a test fails, you don't actually know what went wrong. You know only that a test failed.
10:28Arafangioncark: And I've seen such testing take hours.
10:28carkArafangion: i know i can get away with it because i'm not working in a team
10:28Arafangionsmall-time testing has another massive flaw in that they're not repeatable, and therefore, not useful as a tool when you're doing refactoring.
10:29Arafangioncark: I don't think a team has anything to do with it... But it would depend on your requirements.
10:29carki think unit testing is usefull, and i use it a lot then, when you're working on data structures or algorithms
10:29ArafangionI wouldn't bother to do more than manual testing for simple scripts and quick projects, for example.
10:30Arafangioncark: Case in point: I was able to see exactly what was broken when I *completely changed my VM*.
10:30Arafangioncark: From Python(C) to IronPython. (.NET)
10:30carkArafangion: wew that must have been painfull
10:31Arafangioncark: It was surprisingly pleasant, but mostly because I stopped short of completing the port. ;)
10:31carkhehe ok
10:31Arafangioncark: The main thing that stopped me was no expat support. :(
10:32ArafangionAnd #python is currently hostile with using expat.
10:32carkanyways, to come back to DI, i find that i don't need so much of that in real life projects
10:32carkand genericity is usually pretty localized
10:32ArafangionI mostly use it in "real life projects".
10:33ArafangionThen again, most of my projects tend to have a LOT of business logic.;
10:33carkwell mine too
10:33ArafangionAnd they change a lot. :(
10:33carkbut it's still localized
10:34ArafangionAnd to be honest...
10:34ArafangionI don't think I get any productivity improvement for using a DI framework.
10:34ArafangionI still use DI, but I don't think using a "DI Framework" gives actual productivity improvement.
10:34carkclojure should provide you with this improvement i think =)
10:34ArafangionIt saves perhaps 2 minutes of refactoring each time I change a dependency, and that'd be updating my unit tests.
10:35Arafangioncark: Alas, I won't likely be ablet o use Clojure at work.
10:35ArafangionI'd like to, it would solve a number of painful issues I have.
10:36ArafangionFor instance, between the various JS VM's, .NET, Mono, and Java, I'd be able to have common code everywhere.
10:36ArafangionAnd by extension, they'd share a lot of tests and business logic.
10:37carkhow come you have to work on all these VMs ?
10:37ArafangionI don't, but on windows, I use .NET
10:37ArafangionAnd on the mac, I don't.
10:38carki see
10:38ArafangionI use ObjC on the mac.
10:42ArafangionI'm off to bed!
10:43carkgood night !
10:47eliOcshello everyone!
10:57kephalein lein does trampoline use jvm-opts? i'm getting a suspicious outofmemoryerror with a huge max on my heap space when using lein trampoline run
11:04eanxgeeknew to clojure and trying to compile what I suspect is a simple selenium program, http://pastebin.com/cuxdUWPa, getting error Exception in thread "main" java.lang.Exception: Unsupported binding form: (new DefaultSelenium (:host (quote localhost)) (:port (quote 4444)) (:command (quote *firefox)) (:url (quote http://wwww.google.com)))
11:04eanxgeekany thoughts on what I have done wrong?
11:07cark(DefaultSelenium. "localhost" 4444 "Firefox" "www.google.com")
11:07carkor something like i
11:07carktit
11:07carkit
11:07cark!
11:08carkwhat's with all the quoting you're doing
11:08carkand (:keyword blah) doesn't mean what you think it means
11:10eanxgeekcark: I was wondering if I was messing something up there with the :keyword blah
11:11carkkeywords are function that look themselves in the map argument
11:11carkso
11:11eanxgeekcark: when I simplify further, like your above example, I get DefaultSelenium. should be a vector
11:12cark,(:blah {:a 1 :blah 2})
11:12clojurebot2
11:12carkpaste again =)
11:13eanxgeekhttp://pastebin.com/zi4Pzyhk
11:14Bronsaeanxgeek the code should look like (defn fn-name [args] (let [var (Class. args)] (.doStuff var)))
11:14eanxgeekI may have over simplified your intention
11:14carkeanxgeek: just like bronsa said
11:16eanxgeekcark: Bronsa: I think i have that http://pastebin.com/RvBXfYai
11:16eanxgeeknow getting java.lang.IllegalArgumentException: Parameter declaration let should be a vector (NO_SOURCE_FILE:1)
11:18carkhttp://pastebin.com/kjcM0Cra
11:18mindbender1please how can I include username and paswword in a URI so that I can access it later with..
11:19mindbender1(let [url (URI. (System/getenv "DATABASE_URL"))
11:19mindbender1 (if-let [user-info (.getUserInfo url)]
11:19mindbender1 {:user (first (str/split user-info #":"))
11:21eanxgeekcark: Bronsa: just as a fyi, I'm actually trying to simplify a snippet of code that someone else had written where they use (let [client (new DefaultSelenium (:host opts) (:port opts)...
11:22carkeanxgeek: he's looking up the parameters in the opt map
11:22eanxgeekcark: right I figured that out hence why my :host 'localhost doesn't work
11:23eanxgeekso I have now removed that stuff, trying (let [client (new DefaultSelenium ('localhost) ... but that doesn't work
11:23eanxgeekstill getting show be a vector
11:23carkdid you look at my paste ?
11:24cark('localhost) just doesn't make sense
11:25eanxgeekwell not sure if this code will work but it compiled
11:25eanxgeekhttp://pastebin.com/tbrK1Yhr
11:25eanxgeeknext step is to test in a repl
11:25carkman
11:25carkit won't work at all
11:25eanxgeekheh
11:26eanxgeeki'm such a noob
11:26eanxgeekcan't i go back to python
11:26carkparenthesis are for function application
11:26cark(localhost) is like localhost() in javascript
11:26eanxgeekah ok
11:27eanxgeeknow that makes sense
11:27carkquoting is something entirely different
11:27cark'blah
11:27carkthat means, the symbol blah
11:27daniel___anyone using vimclojure with nailgun? do you just put vimclojure/server in your project.clj? what else did you do to get ng working?
11:27cark(blah arg1 arg2) means the function blah called with args arg1 and arg2
11:28duck1123eanxgeek: also, have you looked at clj-webdriver? Might be a bit easier to do whatever you're doing
11:29eanxgeekduck1123: I have not, as far as I can tell the group I'll be working with is using clojure and selenium-java-x.jar
11:29carkyou might want starting with basic understanding of clojure
11:30eanxgeekyeah I can already tell some of my reading didn't stick :-(
11:30duck1123Fair enough, just thought I'd let you know it's out there
11:30eanxgeekdamn battery... looks like I'm outta here one way or the other
11:30eanxgeekthanks for the pointers I'll keep banging away at this.
11:32carkthere's an awefull lot of banging to do =)
11:34duck1123are there any libraries or what-not that will allow me to trace when my namespaces are used/required/loaded? I have an issue where one of my nses is using a ns I never declared.
11:36duck1123Well, I just found the problem, but my question still stands
11:36raekduck1123: if you're using gen-class there might be old versions of your namespaces in compiled form in the classes/ directory
11:37duck1123raek: No, my issue is this is one of the few places where I've used load-file. I use this namespace in that loaded file. That was causing my problem
11:38duck1123I need to find a better way to load this code, but I still face times where I'd like to trace the namespace load order
11:52duck1123is there any way to use xml zip filters to find an element based on the actual element (as opposed to how it looks in the source)
11:53duck1123it looks like the zip filters give me the prefix and the name for the tag, not taking xml namespaces into account
11:56daniel___vimclojure/server seems to have broken dependencies...anyone using vimclojure can tell me how they set up their ng server?
12:12ghiuhi, i'm trying to pack a .jar file with some functions i've made. when importing it i get a Could not locate deviant_scraper/core__init.class or deviant_scraper/core.clj on classpath
12:12ghiuany help?
12:16duck1123ghiu: are you trying to do this manually, or are you using a build tool of some sort?
12:33daniel___,(seq "dsfsdfsdfsd")
12:33clojurebot(\d \s \f \s \d ...)
12:37daniel___if i have two lists like (\d \f \s \h \q), how can i iterate through both lists doing operations involving each pair?
12:38daniel___by pair, im thinking if it were an array, the values with the same index
12:39daniel___in fact, it could be (1 2 3) and (4 5 6) and I want to do something like 4-1 + 5-2 + 6-3
12:39duck1123,(map (fn [x y] {x y}) [1 2 3] [4 5 6])
12:39clojurebot({1 4} {2 5} {3 6})
12:40duck1123,(apply + (map (fn [x y] (- y x)) [1 2 3] [4 5 6]))
12:40clojurebot9
12:42daniel___thanks duck1123, let me take some time to get my head around what you just did
12:42duck1123If you call map with multiple collections, it'll call that function with one from each collection
12:43daniel___i see, thats neat
12:43daniel___and apply + is basically a summation
12:44duck1123(apply + '(3 3 3)) is the same as (+ 3 3 3)
12:44daniel___yep, got it
12:45daniel___cheers
12:46duck1123you could also use reduce instead of apply. which would be like (+ (+ 3 3) 3) I can never remember which is better in +'s case
12:52daniel___,(seq "dsfsdf")
12:52clojurebot(\d \s \f \s \d ...)
12:52daniel___this creates a collection of characters
12:53daniel___im having trouble because i need them to be strings of length 1
12:53raekthe vararg version of + is implemented with reduce
12:53duck1123,(map str "dsfsdf")
12:53clojurebot("d" "s" "f" "s" "d" ...)
12:53raekdaniel___: (map str "dsfdsf")
12:54daniel___ahh ta
12:54duck1123raek: so does that mean that given the choice, I should reduce there?
12:55raekfor str and concat it's better to use apply than reduce
12:55raekit depends on the function, I guess...
12:56raek(reduce str will create a lot of intermediate immutable strings but apply str will use a string builder)
12:58duck1123Does anyone have any suggestions for processing xml in a ns-aware fashion?
12:59duck1123I'm checking out pjt's saxon wrapper, but it returns a single item if the query has only one result
13:06devnduck1123: there's another parser thingamajig somewhere
13:07devni think I saw it in reference to a SOAP-specific library
13:07devnsorry i dont have a name for you, but that's something to google around for
13:07daniel___can someone using a vim repl share how they set it up? im using vimclojure but cant get nailgun to work
13:08ghiuis ring robust enough to be used as production server or it is dev-only and requires a deployment under tomcat?
13:10carkring is not an http server ... i'm guessing you're talking about jetty ?
13:11duck1123ghiu: There are several sites that I can think of that are using ring in relatively heavy production
13:11carki do use ring in production too
13:11duck1123and I believe more people use jetty than tomcat
13:11carkwith jetty
13:11ghiudo you need any reverse proxy in front of it?
13:11ghiulike
13:11duck1123ring is more or less container agnostic
13:11carkabd it's good enough for hundreds of pages per second
13:11dbushenkocark: where do you use ring in production?
13:11ghiuyou use it under nginx or something?
13:12carkjetty + ring, directly
13:12carkusing it for a telecomunication application, providing information to customers of small telcos
13:12duck1123I use nginx in front of aleph. I had some odd issues with caching with apache
13:13dbushenkocark: can you share a link? I'm collecting success stories
13:13carknope it's all behind login/password
13:13carkthe application is sold by the company i made it for
13:14dbushenkosad...
13:14carksorry =(
13:15dbushenkothis is your startup?
13:15winkcark: how did you daemonize it?
13:15carknope i'm a freelance programmer
13:15carkit's not running as a daemon
13:15ghiuthe main main of ring repository (https://github.com/weavejester/lein-ring) only shows how to use it for a dev server
13:15carkrunning under solaris
13:16ghiuhow to use it in production?
13:16carki provide a jar file, and directory structure, i develop under windows, they make it run
13:16carki really don't know much about the unix side
13:17carkthey have a startup scirpt, it's only running the executable jar
13:17carkwe had only one solid down time at a customer's site
13:17carkbecause there was a limit to the number of thread jetty was creating
13:18carkbut after a few hours researching the cause, it was easily fixed
13:18carkreally no trouble at all besides this one time
13:23amalloyghiu: www.4clojure.com uses ring/jetty/nginx. not a huge load, of course, but it's "production"
13:23carknginx is for the static stuff ?
13:23carkor is everything behind a proxy ?
13:30thoefertry to start a clojurescript app, but I get a javascript error "No protocol method EventType.event-types defined for type null: null" - anyone encountered a similiar error? That´s the small script: https://gist.github.com/1273934
13:30thoeferall samples work for me...
13:31justicefriesso am I to understand correctly that templating with most clojure frameworks are done in clojure?
13:31justicefriesinstead of writing any html/haml/whatever
13:33duck1123Some people use templates, but a lot of people just use hiccup to generate html
13:35dbushenkojusticefries, no, that's not so simple
13:35dbushenkomoment, let me show you a prooflink
13:36dbushenkoread this one
13:36dbushenkohttp://www.reddit.com/r/programming/comments/al98b/clojure_and_compojure_to_the_rescue_again/
13:36dbushenkobreafly: you get an html-page without templating tags, then transform it to hiccup-formatted clojure code using clj-tagsoup and then generate html using hiccup
13:38winkamalloy: is there any detailed description/howto for that setup? I haven't really found anything decent to copy yet :P
13:38amalloyhaha don't copy us. ours is terrible
13:38winkI'm doing lein run in a screen. can it be worse? :)
13:39amalloycark: that's what you get for not highlighting me :P. everything is behind a proxy for port-forwarding - that server hosts a half-dozen websites
13:39carkhehe ok
13:39carkmy bad !
13:41amalloywink: about equally bad, i guess. our deploy process is lein deps && kill oldproc && nohup java -cp (...) clojure.main -e (...)
13:42ghiui have exported (leiningen localrepo) a java .jar to my local repository. i've added it to the solution and with leiningen i have it now in my lib/ when i try to include id, i have a java.lang.ClassNotFoundException exception. any idea?
13:44gfredericksamalloy: isn't it weird how programmers have been deploying things for decades now and we still think it's hard to do anything that survives a reboot?
13:46gfredericksThat might just be my least favorite part about linux.
13:53thoefermy bad, clojurescript works :)
13:54ghiuhmmm, can i import an entire namespace from java or just objects?
13:55ghiui mean classes?
13:56daniel__2,(map str "dsad")
13:56clojurebot("d" "s" "a" "d")
13:56gfredericksghiu: just classes. You can use gen-class to create a class in your ns that calls functions in the ns.
13:56gfredericksdepending on what you're doing that may or may not be the simplest approach.
13:59ghiuok, but does it resolves all the dependancies? i mean, if i include class A that has some methods that return class B or require as argument class C, can i use them?
13:59daniel__2(apply + (map contstr/codepoints (map str "dasdsa")))
14:00daniel__2i get a cant cast lazyseq into number with this
14:00sid3khi all. I solved first 40 problems at 4clojure and now need a free online guide to continue. None of the clojure books has a kindle version. is there any guide considered as the best one by the community?
14:00bsod1is there a lazy sort function in clojure?
14:02gfredericksdaniel__2: that makes sense. What are you trying to do? Add the codepoints in the original string?
14:02gfredericksghiu: it will take care of all the dependencies that you declare in your (ns) declarations...not quite sure what else you might mean.
14:02amalloybsod1: none built in. you can write one pretty quickly though, and JoC does just that
14:02daniel__2gfredericks: sum all the integers
14:03daniel__2i think i need ([1] [2] [3]) instead of ((1) (2) (3))
14:03gfredericksdaniel__2: why not (contstr/codepoints "dasdsa") instead of the maps?
14:03bsod1amalloy: who is JoC?
14:03amalloyjoy of clojure
14:03bsod1ah, ok, thanks
14:04daniel__2gfredericks: not sure what that gives me but let me try
14:04daniel__2you're right, thats what i want
14:04daniel__2cheers
14:04gfredericks:)
14:04daniel__2i thought it not be split at the end of it
14:04amalloybut a general-purpose lazy sort isn't as useful as something more specific for your problem. like, if you know in advance you need the two largest elements you can do better than lazy-sorting the whole thing
14:04daniel__2it might not be*
14:06daniel__2but so i learn something, in the case i had a lazyseq and wanted to convert them to numbers?
14:07gfredericksdaniel__2: if you want to sum up a lazy seq you can use (apply + ...) just like in your example
14:07gfredericks&(apply + (range 2 10))
14:07lazybot⇒ 44
14:08gfredericksdaniel__2: if you mean the case where you have a sequence of sequences like [(3) (4) (8)], you would want to call (map first ...) on it first, to pull them out
14:08daniel__2,(apply + ((1) (2) (3)))
14:08clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>
14:09gfredericks,(apply + (map first [[1] [2] [3]]))
14:09clojurebot6
14:09daniel__2ok, thanks
14:09gfredericks,(map first [[1] [2] [3]])
14:09clojurebot(1 2 3)
14:09gfredericksyep
14:09gfredericksdaniel__2: note that if you want to make a list literal (with parentheses), you have to quote it so clojure won't try to evaluate it: ##(map first '((1) (2) (3)))
14:09lazybot⇒ (1 2 3)
14:11daniel__2yup, i knew that
14:19amalloynote also that if you want to make a list literal you're usually wrong :P. not always, of course, but it's a good rule to start with
14:19bsod1I'm sorting a seq with 1000 elements for some tests and learning, after second time I sort the same seq, sorting time decreased to 1/4 of first time, is it because of JVM's optimizations?
14:20amalloysorting a sorted sequence is pretty fast
14:20amalloyrun down the line, find out it's already sorted, do no swaps
14:20bsod1amalloy: no it's not sorted, I'm not changing the seq, I'm sorting same unsorted seq every time
14:21bsod1amalloy: my sort function is side-effect free, there no changing
14:21bsod1there is no changing*
14:21bsod1amalloy: here's my sort function http://paste.pocoo.org/show/489995/
14:22daniel__2can anyone suggest how to change a random character in a string?
14:23amalloyoh, you wrote the lazysort. i thought you were using java's sort. still, i can draw no benchmarking conclusions from the sort code without knowing how you are benchmarking
14:23amalloydaniel__2: ##(str \F)
14:23lazybot⇒ "F"
14:23bsod1amalloy: (time (qsort (take 1000 (repeatedly #(rand-int 1000))) <))
14:23amalloyso it's not the same seq at all
14:24daniel__2say i have ("f" "d" "h" "w"), how would i choose a character at random?
14:24bsod1amalloy: actually I'm saving this seq to a var but I changed it to paste it here
14:24daniel__2and modify it
14:24gfredericksdaniel__2: rand-nth?
14:24bsod1(def t (take 100...))
14:24gfredericksdaniel__2: never mind
14:24bsod1(time (qsort t <))
14:24gfredericksdaniel__2: for random updates you'll want a vector instead of a list
14:25amalloybsod1: well, (a) the first sort is also creating the sequence, and (b) since your sort is lazy, that (time (qsort)) will do basically zero work
14:25daniel__2hmm ok, lets say i have a function (defn mutatestring [string] ...)
14:25daniel__2i want to return the string with one char modified
14:26daniel__2so ill have a string which i want to convert to a vector of chars?
14:26bsod1amalloy: I'm sorting on REPL so qsort is printing the result, so it's sorting all the seq
14:26amalloybsod1: but time is returning before the printing happens, so that's immaterial
14:27bsod1amalloy: ok, I'll add (print) over qsort and try again
14:29gfredericksdaniel__2: I guess if it's a string in and out then the vector would be too much. I'd just take a substring from both sidse and combine them back together using str
14:29gfredericks(let [i (choose-index)] (str (subs s 0 (dec i)) (rand-char) (subs s (inc i))))
14:30gfredericksdaniel__2: ^ that might do it
14:30amalloydaniel__2: but if you're doing a lot of this stuff, using a vector as an intermediate representation and converting to a string only when necessary will make your life easier
14:31daniel__2it will, let me try and understand both ways
14:31daniel__2how would i convert a string to a vector?
14:31amalloy&(vec "test")
14:31lazybot⇒ [\t \e \s \t]
14:32daniel__2,(rand-nth (vec "test"))
14:32clojurebot\t
14:33gfredericksdaniel__2: rand-nth was probably a bad suggestion, since that doesn't help you know where to update
14:38daniel__2im just playing, how would i modify a character by a small amount? i can get the unicode code point and increment it but im not sure what the opposite of codepoints is to convert it back toa char
14:38gfredericks,(char 77)
14:38clojurebot\M
14:39daniel__2aaah ok
14:39mindbender2anyone familiar with heroku? I'm having troubles getting an app to run with foreman
14:39daniel__2this repl in irc is revolutionary
14:40amalloyhaha daniel__2 it is a pretty old revolution
14:41winkamalloy: thanks. yeah, only a bit better :P
14:44amalloy&(-> "A" first int inc char str) ;; clojure's compellingly-simple ascii arithmetic...
14:44lazybot⇒ "B"
14:46daniel__2amalloy: nice
14:46clojurebotamalloy: therfor I return [previous] if rest is empty
14:47daniel__2whats ->
14:47duck1123shut up, clojurebot
14:47amalloy&(use 'clojure.walk)
14:47lazybot⇒ nil
14:47amalloy&(macroexpand-all '(-> "A" first int inc char str))
14:47lazybot⇒ (str (char (inc (int (first "A")))))
14:48duck1123-> puts second ->> puts last
14:48duck1123they're both great for simplifying code
14:49daniel__2doesnt look much simpler to me :S
14:49daniel__2whats does first do in this example?
14:50gfredericksturns "A" into a char
14:50gfredericks,(first "A")
14:50clojurebot\A
14:50daniel__2,(char "A")
14:50clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number>
14:50daniel__2hmmm ok
14:50gfredericksdaniel__2: it works because (first) will start by converting the argument to a seq
14:50gfredericksc.f., ##(first "foobar")
14:50lazybot⇒ \f
14:51amalloydaniel__2: -> simplifies by turning the code inside-out. you can read from left to right and see the steps in order instead of in reverse order
14:51duck1123Take "A", grab the first char, turn it into an int, increment it, thurn it back into a char, thurn that into a string
14:51amalloybut it's not super-helpful in this case; -> and ->> are more useful for functions that take more than one arg
14:52daniel__2ok, i see
14:52Vinzentit helps to preserve natural order of reading here
14:52amalloyeg, ##(->> [0 1] (iterate (fn [[a b]] [b (+ a b)])) (map first) (filter even?) (take 40) (reduce +)) ;; add up the first 40 even fibonacci numbers
14:52lazybot⇒ 1655824071758491008590040
14:52amalloywow, that high?
14:53daniel__2,(int (char "#"))
14:53clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number>
14:53duck1123they add up, *drumroll*
14:53daniel__2,(int (char "A"))
14:53clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number>
14:53daniel__2sorry, oops
14:53amalloyduck1123: i think you want
14:53amalloy~rimshot
14:53clojurebotBadum, *ching*
14:54daniel__2,(int (first "#"))
14:54clojurebot35
14:54daniel__2hmmm, why am i using codepoints when it seems to be as simple as int
14:54daniel__2,(int (first "$"))
14:54clojurebot36
14:55gfredericksdaniel__2: because everybody spends their first year of clojure figuring out how their code doesn't need to be nearly as complicated as their first attempt?
14:55daniel__2:)
14:55gfredericksat least I did. And then another year or two after thaht.
14:57daniel__2how long has clojure been around?
14:58duck11233.5 years?
14:59daniel__2thats about the right sort of time to start learning :D
14:59duck1123Sept 22 2007
15:04daniel__2gfredericks: can you explain (let [i (choose-index)] (str (subs s 0 (dec i)) (rand-char) (subs s (inc i)))) ?
15:05daniel__2i substitute s for the string
15:06daniel__2and the rand-char?
15:06daniel__2i dont want it completely random, i want it just offset
15:06daniel__2i cant tell whether you made up these functions or not
15:06daniel__2choose-index?
15:07amalloyhe made up choose-index
15:07amalloyoh, and rand-char
15:10daniel__2ok, ill have a go at implementing them
15:15daniel__2why is it (.length "abc") and not (length "abc") ? does the . mean something?
15:16Vinzentdaniel__2, it's a method call
15:16raekdaniel__2: yes, it's the syntax you use to make a method call on a java object
15:16Vinzent(.method obj) in clojure is equivalent to obj.method in java
15:16raekso .length is not actually a clojure function at all
15:16Vinzentclojure one is count
15:17daniel__2aah right
15:17daniel__2thanks
15:18Vinzentdoes ^:keyword syntax always creating array-maps? I mean, is ^:foo ^:bar always equivalent to ^{:foo true :bar true}?
15:19raekI presume it uses the same way to choose the array map / hash map implementation as usual map literals
15:22Vinzentso the limit is 8, if my memory serves me?
15:22raek,(class '{1 1, 2 2, 3 3, 4 4, 5 5, 6 6, 7 7})
15:23clojurebotclojure.lang.PersistentArrayMap
15:23raek,(class '{1 1, 2 2, 3 3, 4 4, 5 5, 6 6, 7 7, 8 8})
15:23clojurebotclojure.lang.PersistentArrayMap
15:23raek,(class '{1 1, 2 2, 3 3, 4 4, 5 5, 6 6, 7 7, 8 8, 9 9})
15:23clojurebotclojure.lang.PersistentHashMap
15:23raeklooks so
15:28tdrgabiArafangion: a long time ago, you asked "what utf8 issue".
15:29tdrgabiwhile using noir and hiccup, something like: [:h1 "På"] looked like P�
15:29tdrgabibut it was because of my emacs and nothing wrong in clojure/noir
15:29dnolencore.match has reached the point where last 10% is 90% of the work :P
15:29dnolen0.2.0-alpha5 being released, probably the last one before cutting beta.
15:29daniel__2gfredericks: (let [i (choose-index)] (str (subs s 0 (dec i)) (rand-char) (subs s (inc i))))
15:30daniel__2im having trouble with the end cases
15:30daniel__2choose-index: (rand-int (dec (count s)))
15:30daniel__2that means (dec i) could be -1
15:31daniel__2and (inc i) could give an index too high
15:33gfredericks,(subs "foobar" 0 -1)
15:33clojurebot#<StringIndexOutOfBoundsException java.lang.StringIndexOutOfBoundsException: String index out of range: -1>
15:33gfredericksdaniel__2: I guess the dec should probably not be used.
15:33gfredericks,(subs "foobar" 0 0)
15:33clojurebot""
15:34gfredericks,(subs "foobar" 6)
15:34clojurebot""
15:34gfredericksI think the inc is correct though
15:35gfredericksdaniel__2: I don't think choose-index should have the dec either
15:35daniel__2,(subs "foobar" 0 0) doesnt help either though
15:35clojurebot""
15:35daniel__2,(count "ABC")
15:35clojurebot3
15:35daniel__2,(nth "ABC" 3)
15:35clojurebot#<StringIndexOutOfBoundsException java.lang.StringIndexOutOfBoundsException: String index out of range: 3>
15:35daniel__2thats why i have the dec
15:35gfredericksdaniel__2: (rand-int 3) never returns 3
15:36gfredericksjust [0 1 2]
15:36daniel__2oh
15:36daniel__2:D
15:36gfrederickswhat's wrong with (subs "foobar" 0 0)? If you're replacing the first character then you want the "before" part to be empty, right?
15:36daniel__2gfredericks: duh :S
15:37daniel__2thanks
15:37gfredericksyep
15:39daniel__2its still not quite right, at least im not getting exceptions
15:40gfredericksno exceptions == no bugs :)
15:41daniel__2nvm, found my mistake
15:41duck1123just like no failing tests means it's perfect
15:41gfredericksduck1123: that's what we tell our clients
15:41daniel__2i had (subs s 0 (inc i)) instead of (subs s (inc i))
15:41gfredericksthat'll do it
15:42daniel__2perrrfect :D
15:45daniel__2lisps are tricky but definitely fun
15:51Vinzent,(class (meta ^:1 ^:2 ^:3 ^:4 ^:5 ^:6 ^:7 ^:8 ^:9 :foo))
15:51clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: Metadata can only be applied to IMetas>
15:51Vinzent,(class (meta ^:1 ^:2 ^:3 ^:4 ^:5 ^:6 ^:7 ^:8 ^:9 'foo))
15:51clojurebotnil
15:53thorwildnolen: clojure.core.match, pretty please ;)
15:53dnolenthorwil: http://dev.clojure.org/jira/browse/MATCH-28 done
15:53dnolenwell not "done" but ok, I'll do that
15:54thorwildnolen: does throwing if no match found vary, i.e. does it transport more information than a nil?
15:54thorwilcool
15:56raek,(class (meta ' ^:1 ^:2 ^:3 ^:4 ^:5 ^:6 ^:7 ^:8 ^:9 foo))
15:56clojurebotclojure.lang.PersistentHashMap
15:56raekVinzent: ^
15:56dnolenthorwil: throwing would make it easier to determine what failed, but this should probably be a variant of match, like matchr (match-raise ?)
15:56dnolenmatch by default shouldn't throw I don't think.
15:57raek^{:foo "bar"} (quote baz) and (quote ^{:foo "bar"} baz) are not the same
15:57thorwilin my admittedly very limited experience, i stumbled over exceptions where i would have been happy with a nil a few times
15:57dnolenthorwil: yeah, it's not friendly at all, http://dev.clojure.org/jira/browse/MATCH-29
16:02Vinzentraek, ah, should remember it. But I don't understand why: 'baz returns a symbol, ^ adds meta to the next symbol...
16:03ghiuhow can i cast a symbol to a string? like :a => "a" ?
16:04brehaut,(name :a)
16:04clojurebot"a"
16:04brehautand :a is a keyword, not a symbol
16:04raekVinzent: ^ add metadata to the data structure to the right, which is the list (quote baz)
16:05dnolenI'm still amazed that core.match just works w/ ClojureScript
16:05ghiuthanks to both :)
16:06raek^{:foo "bar"} (+ 1 2) adds metadata to the _code_ of (+ 1 2), not to the runtime result
16:06raek(for that, the 'with-meta' function is used)
16:06Vinzentraek, hm, right, ^ is in the reader time and (quote baz) is in runtime
16:07raekexactly
16:07Vinzent,(class (meta ' ^:1 ^:2 ^:3 ^:4 ^:5 ^:6 ^:7 ^:8 foo))
16:07clojurebotclojure.lang.PersistentArrayMap
16:07Vinzentok, thank you raek
16:20daniel__2what do you do if you want more than one line in an if's else statement
16:20ghiuhow to check if a value is a number? something like string?
16:20Vinzentdaniel__2, use (do ...)
16:20gfredericksdaniel__2: you can use (do ...) whenever you need several statements in place of one
16:21Vinzentghiu, number?
16:21gfredericks,(doc number?)
16:21clojurebot"([x]); Returns true if x is a Number"
16:21daniel__2this is getting bloody confusing
16:21daniel__2i've got loop, when, if all jumbled up
16:21ghiuVinzent: thank. it is not documented here http://clojure.org/cheatsheet
16:22gfredericksdaniel__2: that does sound confusing
16:22gfrederickswhen and if are much more similar to eachother than to loop
16:22Vinzentdaniel__2, usually you don't need this, because usually there is no side effects...
16:23daniel__2i dont think i am thinking of the easiest way
16:23daniel__2i have a function that takes 3 arguments [generation source target]
16:23daniel__2i want to start at 0 and loop until i reach generation
16:23gfredericks(doseq [i (range generation)] ...)
16:24Vinzentghiu, hm, indeed, that should be there is the "test" section...
16:24gfredericksdoseq is for side effects though. Does your function need side-effects?
16:24daniel__2if i havent reached generation, i want to modify source until it passes a test and then pass that new source back into the function
16:25daniel__2i dont know what you mean by side-effects
16:25daniel__2i think i need to break the problem into smaller pieces
16:25Vinzentdaniel__2, function have side effects when it modifying some state outside of it
16:25gfredericksdaniel__2: a "pure function" is one that has no side effects, which means that all it does is take an input and return something completely determined by the input
16:25daniel__2no, it should be pure
16:26daniel__2isnt that the idea of functional programming? arent all functions ideally pure?
16:26gfredericksin functional programming languages it's usually good practice to code in pure functions when it's not too difficult
16:26gfredericksdaniel__2: yes
16:26Vinzentwell, maybe not all, but most of them
16:27gfredericksdaniel__2: your description of "start at zero and loop until ..." is an imperative-sounding description; it's not entirely clear what the functional equivalent would be
16:27gfredericksperhaps map, perhaps reduce...
16:27daniel__2(defn evolve [generation source target]) ... i want it to pass back a modified source to itself generation times
16:27brehautVinzent, daniel__2: a function that does not change external state but depends on some changing external state is also impure, e.g. if you get the system time or ask for a random number
16:28gfredericksdaniel__2: you might want iterate
16:28daniel__2yes, i think i do
16:29gfredericksthen you would call (nth iterated-seq generations) on the result
16:29amalloy(nth (iterate #(compute-next-generation % target) source) generations) sounds about right to me
16:29amalloythough i'm just guessing on what "target" is for
16:30gfredericksyep that sorta thing
16:30daniel__2im trying to evolve a random string into hello world
16:30amalloythen yep, my guess is about right
16:30daniel__2target is "hello world" so i use it to test the fitness of source
16:30amalloydaniel__2: i think you should actually use a fitness function, not a target
16:31daniel__2i have a fitness function (defn fitness [source target])
16:31daniel__2compares source and target and returns an int
16:31amalloyokay. i'd suggest passing that in to compute-next, rather than the target itself
16:31daniel__2but then how will i be able to test the fitness on the next iteration?
16:32daniel__2ill have lost my target
16:32amalloybut i actually meant something slightly higher level: (defn fitness-fn [target] (fn [source] (...do work...))
16:32amalloythen you can create (fitness-fn "hello world") once, and use the function it returns to compare against any number of sources
16:33daniel__2i see
16:33gfredericksdaniel__2: ^ fun with higher-order functions :)
16:33daniel__2but then i have "hello world" in my code, and ideally its an argument i pass to main
16:34gfredericksthen (fitness-fn arg-from-main) instead
16:35daniel__2its not pure if it relies on an arg from main though is it?
16:35daniel__2thats why i have to pass it in each time
16:36daniel__2maybe i just misunderstand the concept of higher order function
16:36gfredericksdaniel__2: higher order function means a function where some of the args or the return value is also a function
16:37gfredericksin this case fitness-fn, as amalloy described, is a higher order function because it returns a function
16:37daniel__2right
16:37gfredericksit returns a fitness function with a particular target
16:37gfredericksyou would then take the returned function and use it with iterate
16:38daniel__2i think i get it
16:38gfredericksI think amalloy suggested it because then the algorithm that does the mutation and such doesn't need to know the details of how the fitness function is computed -- it just takes the fitness function as an argument
16:38gfredericks(instead of the target)
16:38daniel__2yes, clever
16:41daniel__2i dont understand the (nth (iterate line...know any simple examples illustrating this?
16:42gfredericksiterate repeatedly applies a function; so ##(take 8 (iterate #(* 3 %) 5))
16:42lazybot⇒ (5 15 45 135 405 1215 3645 10935)
16:43gfredericksnth just gives you the element at a particular index of the resulting infinite seq
16:43gfredericksso it's equivalent to applying a function n times
16:43daniel__2right, like a loop
16:44daniel__2or dont know if you know ruby ... n.times ..
16:44gfredericksI do know ruby. It's like that, but for pure functions
16:45gfredericksnot that you _have_ to use pure functions with iterate, but that's the general flavor in contrast to ruby
16:46gfrederickse.g., in ruby n.times does not have the aspect of passing the return value of the function back into it as the argument. It just performs some actions for side effects n times
16:46amalloydaniel__2: https://gist.github.com/1274144 is a draft of how this algorithm could look if you were evolving integers instead of strings
16:47amalloyand of course to evolve strings instead, you change fitness-fn, and pass different args to start
16:48daniel__2you just knocked that up now?
16:48amalloyyeah
16:49amalloyyou seemed like you could use something more concrete :P
16:49daniel__2you are passing sources - more than one source?
16:49amalloydaniel__2: working with a pool of candidates every generation
16:50amalloythe easiest choice was to have evolve always keep the survivor pool the same size as the candidate pool, but you could do it differently; i'm no evolutionary-algorithm expert
16:50daniel__2ok, thats jumping ahead of what im doing :) im only mutating one source at the moment
16:51daniel__2ill take some time to study this and see what i come up with
16:51daniel__2cheers
16:51amalloyenjoy
16:51amalloyi'm off to lunch, so ask someone else for help
16:52brehautgfredericks: re side-effects in iterate, the docs explicitly state that the function must be free of side effects; that means that iterate has the potential to do reordering of operations in future versions which would produce weird results with side effects.
16:54gfredericksbrehaut: what operations could be reorderd?
16:55amalloyyeah, that's fairly implausible
16:56brehautimplausible or not, I'm not sure its wise to encourage people to write code outside of the guarantees of the core functions
16:57amalloybrehaut: for some things, like reduce, i agree. but the docs for iterate are just lamely reminding you that pure functions are good; there's no way they could reorder or depend on purity in any way
16:57gfredericksit's bizarre that the docs for iterate say such a thing while other functions like split-with do not. And split-with will certainly call your predicate twice as often as necessary
16:59gfredericks,(split-with #(< (rand) 0.8) (range 10))
16:59clojurebot#<ExecutionException java.util.concurrent.ExecutionException: clojure.lang.ArityException: Wrong number of args (1) passed to: sandbox$eval27$fn>
16:59gfredericksgerg
16:59gfredericks,(split-with (fn [_] (< (rand) 0.8)) (range 10))
16:59clojurebot[() (2 3 4 5 6 ...)]
17:00gfredericks^ that's when I'd like to know that pure functions are required
17:02daniel__2hmm is -fn deliberate on the function name
17:02gfredericksnot sure what you mean
17:02daniel__2seems like its defined fitness-fn and called with fitness
17:02gfredericksoh in amalloy's code?
17:02daniel__2in amalloy_'s example
17:03gfredericksdaniel__2: I don't think he made a mistake.
17:03gfrederickshe let's the result of fitness-fn to the name 'fitness'
17:03gfredericksand also uses it as the name of the argument to evolve
17:03daniel__2yeah, just seen
17:04daniel__2i cant see why he needed to do the let though
17:05daniel__2instead of fitness-fn goal
17:05gfredericksyou mean instead of placing the call to fitness-fn within the anonymous function?
17:06daniel__2yeah
17:08gfredericksit would have worked the other way, but this way fitness-fn only gets called once, instead of every time the anonymous function is called
17:13daniel__2so the iterate function...it will iterate with the return value in place of %
17:13daniel__2so whatever it returns goes back in again
17:13daniel__2the (take (count ... line
17:16daniel__2how can i implement the equivalent of ruby until
17:17daniel__2until fitness > old-fitness do mutate(source)
17:17daniel__2so keep trying mutations until you get a better fitness
17:27amalloy&(doc take-while)
17:27lazybot⇒ "([pred coll]); Returns a lazy sequence of successive items from coll while (pred item) returns true. pred must be free of side-effects."
17:27amalloyor drop-while, either way
17:29daniel__2im making my evolve recursive, is that a bad idea?
17:30daniel__2actually, i dont know how that will work with the iterate
17:30gfredericksdaniel__2: with iterate, instead of using recursion directly, you just return whatever ought to be passed in to the function the next time
17:31daniel__2(take-while condition function) ?
17:31daniel__2will repeat function until condition is true
17:31daniel__2and then return the result of the passing function
17:31gfredericksnot a function, a seq
17:32gfredericksso you could use take-while with iterate
17:32gfredericks,(first (drop-while #(< % 1000) (iterate #(* 2 %) 3)))
17:32clojurebot1536
17:33gfredericks,(take-while #(< % 1000) (iterate #(* 2 %) 3))
17:33clojurebot(3 6 12 24 48 ...)
17:34daniel__2right, hmmm
17:34daniel__2this is a good brani workout
17:34daniel__2brain*
17:35gfredericksonce you get used to it, looking at imperative ruby code will make you ill
17:35gfredericksI guess that may or may not be a good thing
17:35daniel__2thats doing something slightly different
17:35daniel__2i still want to iterate over n generations
17:36daniel__2but for each generation, i want to only take the fitter child
17:36gfredericksso you have a collection of children and you want to pick the one with the highest fitness?
17:36daniel__2not really
17:37daniel__2i dont have a collection of children yet, i just want to iterate my mutate function until the fitness of the child is greater than it was before
17:37daniel__2i have (mutate source)
17:38gfredericksah, so (drop-while #(<= (fitness %) fitness-from-before) (iterate mutate this-guy))
17:38daniel__2i dont want to accept the result is (< (fitness (mutate source)) (fitness source))
17:38daniel__2if*
17:38gfredericksmaybe remove makes more sense
17:38gfredericks(first (remove #(<= (fitness %) fitness-from-before) (iterate mutate this-guy)))
17:41daniel__2need paren highlighting in irc :p
17:43gfredericksdrop-while would still work there, I just like remove better for silly personal reasons
17:43daniel__2just compiling for the moment of truth
17:44daniel__2need to get a repl in vim
17:44daniel__2this takes too long
17:44gfredericksdaniel__2: what's your workflow?
17:45daniel__2at the moment, make changes to the code, compile, execute
17:45daniel__2trying small experiments in a repl
17:46daniel__2would be good not to have to exit vim to compile
17:46gfredericksare you using leiningen?
17:47daniel__2ja
17:47gfredericksI normally have two windows, one for the repl and one for vim. I can reload the code with (require 'some.ns :reload)
17:47amalloydaniel__2: why exit vim? just C-z to suspend it
17:47daniel__2amalloy: thats a possibility, i just never thought of it
17:48gfredericksdaniel__2: no reason it should take you more than a couple seconds to try out the code you wrote
17:48daniel__2im getting an invalid number of arguments passed to iterate anyway :(
17:48ghiuhow can i take a map as input and return the same map with keywords converted to strings? example: {:a 1, :b "23", :c '(1 2 3 {:d [:e :f]})} => {"a" 1, "b" "23", "c" '(1 2 3 {:d [:e :f]})}
17:49gfredericksghiu: (zipmap (map name (keys m)) (vals m))
17:49bdb_stringify-keys
17:49bdb_&(doc stringify-keys)
17:49lazybot⇒ "([m]); Recursively transforms all map keys from keywords to strings."
17:50gfredericksbdb_: that would fail his example of being not-recursive
17:50bdb_as lazybot just informed me :-)
17:50gfredericksgood ole lazybot
17:50amalloy(inc lazybot)
17:50lazybot⟹ 0
17:50gfredericks:)
17:51ghiuwow, thanks :D
17:51gfredericksyezzir
17:52bdb_forgive me if this has been discussed to death (feel free to point me towards a blog post or something) but what are people using for durability in clojure servers/services?
17:53daniel__2i'd paste some code, but i havent got my vim working since i reinstalled my OS
17:53daniel__2"+y doesnt work
17:54daniel__2might be something to do with vimclojure, not sure
17:55daniel__2https://gist.github.com/1274252
17:55nappingletters still work as names?
17:56gfredericksdaniel__2: iterate takes two args, so something is wrong on line 22
17:56gfredericksyou probably meant (iterate mutate source)?
17:57amalloythe function passed to remove also should take an argument
17:57ghiuhmmm
17:57daniel__2there are two args... the anon function and source
17:57ghiushouldn't this work? (walk #(%1) #(%1) {:a 1, :b "23", :c '(1 2 3 {:d [:e :f]})} )
17:57amalloyghiu: no
17:57daniel__2ah wait, line 22
17:57ghiustringify-keys is perfect but i need to stringify any occurrence of any key
17:57amalloy#(%1) is basically never what you want
17:57gfredericksghiu: what do you want #(%1) to do?
17:58nappingIt seems a bit odd that a {} pattern treats a vector as indexed by integers, while wrapping it like [& {}] uses apply hash-map and treats it as an association list
17:58gfredericks,(#(%1) #(println "HELLO!"))
17:58clojurebotHELLO!
17:58amalloygfredericks: i want it to die in a fire
17:58nappingIs there any better explanation of that than what I can already see by macroexpanding let?
17:59daniel__2amalloy: what was wrong with the function passed to remove?
17:59gfredericksdaniel__2: you're not using the argument anywhere
17:59amalloydaniel__2: it doesn't take any arguments. there's no %
17:59daniel__2ah
17:59ghiuamalloy: i want to check every form and if it's a keyword, turn it into a string instead
17:59amalloyremove calls its function once on each element
18:00icefoxs
18:00amalloyghiu: just use clojure.walk/postwalk if you want a simple walk; don't rewrite it in terms of walk
18:00daniel__2instead of (mutate source) it should be %?
18:00daniel__2so (fitness %)
18:00amalloyyeah
18:01daniel__2kk
18:01daniel__2lets see
18:01amalloyand as gfredericks says you need to unwrap the args to iterate: (iterate mutate source)
18:02daniel__2yeah, done that
18:02daniel__2sweet, i get some kind of output
18:02daniel__2need more generations :)
18:02gfredericksno exceptions == no bugs
18:02ghiuamalloy: (walk #((if (keyword? %1) (name %1) (%1))) #(%1) {:a 1, :b "23", :c '(1 2 3 {:d [:e :f]})} ) ?
18:03gfredericksoh boy
18:03amalloythat has like a hundred parens too many
18:03daniel__2will be interesting to see how long it takes for 5000 generations
18:03daniel__250 took longer than i expected
18:03amalloysee also ##(doc identity), ghiu
18:03lazybot⇒ "([x]); Returns its argument."
18:03gfredericksghiu: ask us again after you have removed exactly one hundred parens from that expression
18:05daniel__2i think i want the opposite of remove
18:05daniel__2or the opposite condition :/
18:05gfredericksdaniel__2: that's filter
18:05daniel__2gets as far from hello world as its possible to get
18:06amalloy&(doc filter)
18:06lazybot⇒ "([pred coll]); Returns a lazy sequence of the items in coll for which (pred item) returns true. pred must be free of side-effects."
18:06amalloyhaha awesome, daniel__2
18:06daniel__2ok, thanks
18:06amalloylet us know what string is farthest away from hello world
18:06daniel__2țȑȖǩȊȫȂșǯȽȹȓ
18:06gfredericksdaniel__2: although it sounds like your fitness function might be backwards
18:06amalloyit can be the toy program people write when they stop using a language
18:06daniel__2lol
18:06gfredericksamalloy: :-D
18:07gfredericksthat looks like a program hiredman would write
18:07daniel__2gfredericks: i've tested my fitness function, works fine
18:07daniel__2this is looking better now
18:09daniel__2still doesnt seem right, after 50000 generations i have dlk33ndoemgl
18:10daniel__2aah, i get why
18:12daniel__2when i have [& args] what are the args bound to for use inside the function?
18:13daniel__2arg1 arg2?
18:13gfredericksthe arguments are a list called args
18:13gfredericks,((fn [& args] (pr-str ["My args are" args])) 7 8 :famished)
18:13clojurebot"[\"My args are\" (7 8 :famished)]"
18:15gfredericksdaniel__2: this is your main function?
18:15daniel__2yeah
18:15gfredericksyou could do normal arguments like (fn [foo bar]...), but then your program would probably crash if you didn't get exactly 2 command line args
18:15daniel__2i want to make the start args abstract so i can change them on each run
18:15amalloydaniel__2: you can probably save a lot of wasted compilation time by dropping the gen-class
18:16amalloyand then using clojure.main, which is a precompiled class in clojure.jar, as your entry point
18:18daniel__2ok
18:18amalloybetter, of course, is to use a persistent jvm like the repl or swank/slime, so that you don't need a -main at all, but that's probably more work
18:19amalloyand i only suggest changing because you were annoyed about compilation time - this is generally not a priority
18:19daniel__2yes, ill try and get slime working when i get more time
18:19daniel__2its 1:17am and i just want this to work so i can go to bed :/
18:20brehautdaniel__2: with the emacs starter kit, slime is much easier to get going than it used to be
18:20gfredericksdaniel__2: well then your problem is you live in a time zone where it's late.
18:21daniel__2yep
18:21brehautdaniel__2: bookmark https://github.com/technomancy/emacs-starter-kit/
18:21daniel__2brehaut: dont want to learn emacs, would rather stick with vim
18:23gfredericksdaniel__2: I use vim and it's only mildly painful. If I don't think about it then I don't know what I'm missing.
18:23daniel__2sure
18:25daniel__2touch README
18:25daniel__2oops
18:25amalloyhah, i smell a project about to get pushed to github
18:25daniel__2lol
18:26gfrederickseh? what does touch README do (apart from the obvious)?
18:26technomancyactually slime and the starter kit are more or less orthogonal
18:26amalloygfredericks: it's a step github recommends in their "how to create a repo on github"
18:26technomancyunless you mean the overall getting started experience is easier
18:26gfredericksah ha
18:27brehauttechnomancy: yeah the over all experience
18:27amalloythey don't like repos without a README, though it doesn't seem like an empty one is any better
18:27daniel__2right after i install ssh itll be on there :D
18:27amalloydaniel__2: windows?
18:27daniel__2no, arch linux
18:28daniel__2i reinstalled my ubuntu and arch a couple of days ago
18:28daniel__2things are still not all setup
18:28amalloyfascinating. i didn't think there were unix distros with ssh not installed
18:28gfredericksyeah that sounds pretty unhelpful
18:28amalloygood point, technomancy
18:28gfrederickstechnomancy: README.xml? :)
18:29amalloyany day now github will add support for README.clj, just you wait. then we'll have won
18:29gfrederickssomebody start encouraging that in the java community and see if it catches on
18:29gfredericksamalloy: we'll have won the opportunity to escape every damn double-quote we use? :)
18:29clojurebotamalloy is <amalloy> just use juxt, it'll be great
18:30daniel__2amalloy: arch pretty much makes you choose everything
18:30gfredericks(inc clojurebot)
18:30lazybot⟹ 2
18:30daniel__2which for me was good, i learnt a lot
18:30amalloyhahaha best ever. thanks clojurebot, that was perfect timing
18:30ghiuamalloy: got it, thanks (postwalk (fn [x] (if (keyword? x) (name x) x)) m))
18:30daniel__2anyway, i have to go to bed https://github.com/danielstockton/evolve/blob/master/src/evolve/core.clj
18:30daniel__2thanks for all your help, i will resume tomorrow evening
18:31gfredericksgoodnight
18:38bdb_README.clj is only a pull request away: https://github.com/github/markup
18:38bdb_"The code we use to render README.your_favorite_markup"
19:44icefoxIs there a list of janitor type tasks for clojurescript anywhere?
19:52amalloyicefox: you asked this yesterday, right? maybe i'm the only dumb one in the channel, but i can only guess at what "janitor type tasks" means
19:54ibdknoxamalloy: dude you're so dumb.
19:54ibdknoxwait
19:54ibdknoxso am I
19:54ibdknox:(
19:54icefoxamalloy: simple things like, function foo isn't documented, or function foo is deprecated and any code that uses it should be upgraded. The Linux project started the idea of janitors as a way to help get new developers into the Linux project. In trade for doing janitor type tasks the devs promise to review and help them get familiar with the code base
19:54amalloyibdknox: in fairness, i couldn't answer his question even if i did know, because i don't know much about cljs
19:54amalloybut perhaps some prodding will inspire the rest of the channel
19:55icefoxreally I want to learn ClojureScript and one way that seems to work for me is to help contribute so I wanted to know if there are any boring not too difficult tasks that needed done
19:55ibdknoxicefox: I'm not sure anyone is keeping a list updated for such things
19:56ibdknoxicefox: the best thing you could do right now, is just use it
19:56ibdknox-,
19:56icefoxyah, been poking around with it making some apps
19:56jlihm. if I want to add a thing to the end of a sequence, is it better to do (conj (vec coll) x) or (concat coll [x])?
19:57jlior am I doing something wrong?
19:57jli(yes, I know it's slow)
19:57amalloyjli: they are both right and both wrong, depending on what you're doing
19:59ibdknoxjli: why do you have a seq if you need to add something to the end of it?
19:59amalloythough, really, (conj (vec coll) x) is a bit nuts - if you're going to be adding onto the end you should make it a vec to begin with, in which case (conj coll x) is fine
20:01jliI start with (range), then I map over it, and then I want to add something to the end
20:02amalloyif you're only doing that once, concat is much better
20:02jliI tried doing "(vec (range ..))" but after the map, conj adds to the beginning
20:03amalloyindeed, because map turns it back into a lazy sequence
20:03ibdknoxconcat will keep it lazy
20:07jliright. okay. concat, rock. thx.
20:35kab3wmibdknox: Noir question for you.. is there any way to conditionally insert a partial if a flash message exists? The problem I'm running into is if I check if flash-get exists, it pops it and I can't access it after that.
20:43ibdknoxkab3wm: you can just us an if-let :)
20:43ibdknoxkab3wm: (if-let [someval (flash-get)] (partial-with-val someval))
20:44kab3wmibdknox: cool, I'll give that a shot. thank you.
23:13metajackWhy does (String/valueOf nil) throw an exception, but (#(String/valueOf %) nil) return "null" (Clojure 1.3)?
23:22zodiakmetajack, I would ~guess~ that clojure deals with looking at what the String java lib expects (a string) and if it's nil, then all that the function can return is nil, whereas, the java function has no idea about how to handle nil's in strings
23:22zodiakthat would be my guess after learning clojure for a month ;)
23:32brehautmetajack: thats really quite surprising
23:33symboleMaybe (String/valueOf nil) is not calling valueOf(Object obj).
23:33metajackbrehaut: it throws null pointer exception. from what i can tell all the other versions of valueOf take primitives
23:34brehautmy java is not super sharp, but i didn't think the primitive types were nullable?
23:34brehauthi talios
23:34talioshola
23:35symbolebrehaut: They're not. Maybe they're being set to null internally, and that's why it fails? I'm not really sure.
23:37symbole#() is a Clojure function which takes Object(s) as an argument, so I think nil might be converted to an Object before it makes its way to valueOf.
23:37brehautsymbole: its implicitly an Object if nil anyway
23:38metajackwell in the real code i found this in, ti's a named function defined with defn, but i reproduced it with #()
23:39brehautmetajack: #() is expanded by the reader to a (fn […) form
23:39brehauter fn*
23:39metajackSo I don't think that particular form matters for this issue.
23:41brehautmetajack: indeed; it seems only that its crossing a method boundary that matters
23:42amalloy,(String/valueOf nil)
23:42clojurebot#<NullPointerException java.lang.NullPointerException>
23:42amalloy,(#(String/valueOf %) nil)
23:42clojurebot"null"
23:42amalloy$javadoc String valueOf
23:42lazybothttp://download.oracle.com/javase/6/docs/api/java/lang/String.html#valueOf(java.lang.Object)
23:44amalloyso valueOf(Object) is willing to convert null to "null". the others aren't, of course, because they take primitives
23:45metajackSo direct invocation basically picks one of the primitive versions incorrectly?
23:46amalloymetajack: probably. i'm not intimately familiar with clojure's typehinting algorithms, but i believe the compiler knows that a nil literal is of class null
23:47amalloywhereas in the other case it only knows it will be given an Object. perhaps it chooses to compile that into a no-reflection dispatch to String/valueOf(Object)
23:49amalloy,(String/valueOf ^Object nil)
23:49clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: Metadata can only be applied to IMetas>
23:49amalloy,(#(String/valueOf ^Integer %) nil)
23:49clojurebot"null"
23:49amalloy,(#(String/valueOf ^int %) nil)
23:49clojurebot#<CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: int, compiling:(NO_SOURCE_PATH:0)>
23:49amalloyhmph
23:50brehaut,(let [a nil] (String/valueOf a))
23:50clojurebot#<NullPointerException java.lang.NullPointerException>
23:50brehaut,(let [a nil] (String/valueOf ^Object a))
23:50clojurebot"null"
23:50amalloysure, that much is given
23:51symbolemetajack: I think it's worth posting this quesiton to the mailing list. I'm curious what this is all about.
23:51amalloyi'm surprised to see that neither of metajack's original versions causes the compiler to emit reflective code
23:51brehautlikewise
23:52brehautwhat is particularly odd is, it should give a more useful error if its selecting a method incorrectly based on type
23:52brehaut, (let [a nil] (String/valueOf ^int a))
23:52clojurebot#<CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: int, compiling:(NO_SOURCE_PATH:0)>
23:52amalloybrehaut: no, i don't think it should. the exception should be coming when the compiler tries to unbox the Long it's working with
23:53amalloyand discovers that the Long is nil
23:54brehautbut its not choosing to unbox right? theres no reflection warnings
23:56amalloybrehaut: it's not dealing with a primitive long, it's compiled against a Long, i think (this is assuming, arbitrarily, that it's chosen the long overload)
23:56amalloyso the un-reflective code says "unbox this Long to a long, then call String/valueOf"
23:57brehautI'm not sure i understand why it would choose to compile against the long overload
23:57brehaut(and incidentally, the same error occurs in 1.2)
23:59amalloybrehaut: i don't think it *should* compile against the long overload, but i can imagine it happening, and it would explain the issue