2011-10-09
| 00:13 | khaliG | can't wait for clojurescript support to be added to slime.. this is so cool :) |
| 00:15 | dnolen | khaliG: totally. |
| 00:18 | Arafangion | Ah, other langauges do have atoms, after a fashion. |
| 00:20 | Arafangion | And limited forms of agents. |
| 00:20 | Arafangion | Although python itself doesn't really have any form of agent. |
| 00:20 | brehaut | a lot (most) of the features of clojure are not new; they are carefully chosen and designed to integrate well together |
| 00:22 | Arafangion | It seems that clojure has managed to avoid the typical flaws new langauges have - they typically try to be too simplistic. |
| 00:22 | khaliG | haha is that a backhanded compliment? |
| 00:22 | ibdknox | Clojure is pretty simple |
| 00:22 | dnolen | Arafangion: ibdknox: on the surface. Implementation is very much "Worse Is *not* Better" |
| 00:23 | dnolen | under the hood is some complicated stuff. |
| 00:23 | ibdknox | Sure |
| 00:23 | ibdknox | under the hood of C# is some crazy stuff too |
| 00:23 | Arafangion | C# is not exactly a simplistic language. |
| 00:23 | ibdknox | but I would say Clojure is far simpler than C# |
| 00:24 | Arafangion | Although the earlier versions of it probably were, for a java-inspired language. |
| 00:24 | ibdknox | what is your basis of comparison then? |
| 00:24 | dnolen | Simplicity-the design must be simple, both in implementation and interface. It is more important for the interface to be simple than the implementation. |
| 00:24 | khaliG | ibdknox, c++ obviously |
| 00:24 | ibdknox | lol |
| 00:24 | dnolen | http://www.jwz.org/doc/worse-is-better.html |
| 00:26 | ibdknox | I'm in the interface is what matters camp. |
| 00:26 | dnolen | ibdknox: yes, Dick Gabriel does not disagree |
| 00:26 | Arafangion | ibdknox: Consider Scheme and Go. |
| 00:26 | Arafangion | ibdknox: they are both very simple languages, although Go does try to break new ground in at least one area. |
| 00:27 | ibdknox | Arafangion: Go isn't really simpler than python or ruby |
| 00:27 | dnolen | Arafangion: Scheme and Go both screw up the simple part. |
| 00:27 | Arafangion | Could you elaborate? |
| 00:27 | ibdknox | Scheme is also not a particularly practical language |
| 00:27 | dnolen | Go channel - puke |
| 00:27 | dnolen | Scheme - concrete types which can't be replaced - puke |
| 00:28 | Arafangion | Heh, ok. :) I gotta go, friend arrived. :( |
| 00:28 | ibdknox | actually no one in here probably disagrees |
| 00:29 | ibdknox | Very few languages are internally consistent |
| 00:29 | ibdknox | it's hard to suggest simplicity without that though |
| 00:31 | ibdknox | dnolen: Is the "worse is better" philosophy widely held? |
| 00:32 | dnolen | ibdknox: I would argue yes. But the reason why is complex - it often gets foisted on us - time constraints, programming languages etc |
| 00:36 | ibdknox | dnolen: 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:36 | ibdknox | t in general a thing isn't very useful if it's too complicated to use efficiently |
| 00:37 | dnolen | ibdknox: we are in agreement. and that's a fundamental Clojure stance. |
| 00:37 | dnolen | "reasoning under concurrency is totally lame", let's fix that by any means necessary is Clojure's MO. |
| 00:38 | ibdknox | indeed |
| 00:57 | todun | hi. I'm new to clojure and on here, it was recommended I use clooj and 4clojure. |
| 00:58 | todun | how do I install clooj? there are download instructions but no install instructions at the github repo. |
| 00:58 | amalloy | todun: the jar should be executable |
| 00:59 | todun | where do I get newbie style tutorials that can ease me into learning clojure? |
| 00:59 | todun | amalloy: there is no jar included. |
| 01:00 | amalloy | sure there is. look on github, click Downloads in the upper-right |
| 01:00 | amalloy | https://github.com/downloads/arthuredelstein/clooj/clooj-0.2.4-standalone.jar looks like the current release |
| 01:01 | ibdknox | hm |
| 01:01 | ibdknox | what happened to try-clojure? |
| 01:01 | khaliG | todun, whats your programming background? |
| 01:02 | amalloy | ibdknox: interesting. dunno, i'll try restarting it |
| 01:02 | todun | khaliG: I'm new in general, but I've tried a few languages with different paradigms. |
| 01:02 | todun | khaliG: familiar with many but very uncomfortable in all languages. |
| 01:06 | amalloy | ibdknox: resurrection succeeded |
| 01:06 | ibdknox | yay! |
| 01:06 | ibdknox | todun: http://try-clojure.org/ |
| 01:07 | todun | ibdknox: thanks will do. |
| 01:07 | todun | ibdknox: the more tutorials the merrier :) |
| 01:19 | Arafangion | ibdknox: Fair enough - I find that professionally, "worse is clearly better". |
| 01:19 | Arafangion | ibdknox: 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:22 | Arafangion | (And wow, that ds.js is insane) |
| 01:22 | ibdknox | I have a simple cljs implementation of D3 in Pinot :) |
| 01:22 | Arafangion | ibdknox: I can't bear to think about a pinot implementation. :) |
| 01:23 | ibdknox | huh? |
| 01:24 | Arafangion | I seemed to think if pinot as an esoteric 'visual' language based on abstract art? |
| 01:25 | ibdknox | http://github.com/ibdknox/pinot |
| 01:26 | Arafangion | Intruging. |
| 01:33 | kab3wm | ibdknox: 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:33 | ibdknox | kab3wm: awesome :) |
| 01:36 | ibdknox | kab3wm: have you run into anything you wish was better explained/is confusing? |
| 01:37 | kab3wm | ibdknox: 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:38 | zakwilson | Congomongo has great documentation as long as you're willing to read the source. |
| 01:38 | amalloy | Arafangion: you're thinking of Piet |
| 01:38 | Arafangion | kab3wm: "downhill" is usually a bad thing. ;) |
| 01:38 | Arafangion | amalloy: Indeed, I was. |
| 01:38 | kab3wm | zakwilson: yes, that's been working. |
| 01:39 | zakwilson | But yeah, docs would be nice some day. |
| 04:36 | sritchie | has anyone used the google maps api with clojurescript? |
| 05:12 | _khaliG | wanting to use #(..) syntax but wanting to ignore the parameter/s. is there a way? |
| 05:20 | amalloy | yes, but don't do it |
| 05:21 | _khaliG | amalloy, for swing callbacks - dont often use the event e, for instance |
| 05:21 | amalloy | _khaliG: so just write (fn [_] (...)) |
| 05:21 | _khaliG | amalloy, lol i have but its ugly |
| 05:23 | amalloy | *shrug* turn your head and squint if it helps you. it's not ugly,and it's better than #(do %& (...)) |
| 07:52 | tdrgabi | regarding 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:54 | Arafangion | What was the utf8 issue? |
| 08:22 | daniel___ | can anyone suggest an equivalent to ord() in python? a function that returns the unicode code point of a char? |
| 08:26 | daniel___ | think i found it (codepoints s) |
| 08:26 | jaley | hey 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:35 | Arafangion | jaley: Hmm, I don't know if clojure works on android. You do know that android does NOT run java? |
| 08:36 | Arafangion | jaley: It's using the Dalvik VM. |
| 08:36 | daniel___ | java.lang.Exception: Unable to resolve symbol: codepoints in this context (NO_SOURCE_FILE:7) can anyone help me out? |
| 08:37 | daniel___ | i thought i required clojure.contrib.string |
| 08:37 | Arafangion | daniel___: I think java strings are essentially UTF-16 arrays? |
| 08:38 | daniel___ | ok Arafangion, just gunna try something |
| 08:38 | daniel___ | what does that mean in terms of what i want to do? |
| 08:39 | jaley | Arafangion: yeah - there are a few success stories around. there's even a clojure REPL app on the android market actually :D |
| 08:39 | daniel___ | im trying (- "a" "b") |
| 08:39 | Arafangion | jaley: Neat. :) |
| 08:39 | jaley | Arafangion: plus some helloworld examples on various blogs |
| 08:39 | Arafangion | jaley: That's awesome. :) |
| 08:40 | jaley | Arafangion: 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:40 | Arafangion | This means that it's trivial to use clojure as a single, cross platform language. :) |
| 08:40 | Arafangion | jaley: Yes, specifically, dynamic bytecode generation gets broken. :( |
| 08:41 | Arafangion | Which breaks Jython, for instance. |
| 08:44 | jaley | Arafangion: yeah... it's far from perfect, but apparently basic things should work |
| 08:44 | daniel___ | i have a repl open... (ns whatever (:require clojure.contrib.string)) |
| 08:45 | _khaliG | i'm looking forward to writing my android app with clojurescript |
| 08:45 | daniel___ | (codepoints "a") gives me the error |
| 09:01 | bsod1 | paredit's C-) is great but I want to disable auto-close parens, how can I do that? |
| 09:03 | daniel___ | i just needed (clojure.contrib.string/codepoints "a") |
| 09:03 | daniel___ | thanks for your help guys! |
| 09:06 | gfredericks | daniel___: oh hah. I should have noticed that. |
| 09:07 | daniel___ | nps :) |
| 09:07 | daniel___ | now i need a function that splits a string into a list of individual characters |
| 09:08 | st3fan | split? |
| 09:08 | daniel___ | yeah st3fan, i think so |
| 09:08 | daniel___ | what regex will give me each char? |
| 09:08 | st3fan | ,(seq "foo") |
| 09:08 | clojurebot | (\f \o \o) |
| 09:08 | st3fan | there you go |
| 09:09 | daniel___ | what library is that in? |
| 09:09 | daniel___ | and what are the \? |
| 09:09 | st3fan | core |
| 09:09 | st3fan | \f is the single character f |
| 09:09 | daniel___ | ok, let me experiment |
| 09:09 | daniel___ | thanks a lot |
| 09:09 | st3fan | like 'f' on other languages |
| 09:12 | st3fan | ,(str (join (seq "I love cheese"))( |
| 09:12 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading> |
| 09:12 | st3fan | ,(str (join (seq "I love cheese"))) |
| 09:12 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: join in this context, compiling:(NO_SOURCE_PATH:0)> |
| 09:13 | st3fan | ,(str (reverse (seq "I love cheese"))) |
| 09:13 | clojurebot | "(\\e \\s \\e \\e \\h ...)" |
| 09:13 | st3fan | hm |
| 09:13 | st3fan | ,(str (str-join (seq "I love cheese"))) |
| 09:13 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: str-join in this context, compiling:(NO_SOURCE_PATH:0)> |
| 09:14 | gfredericks | ,(apply str (reverse "I love cheese")) |
| 09:14 | clojurebot | "eseehc evol I" |
| 09:16 | Bronsa | ,(reverse "string") |
| 09:16 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.IllegalStateException: replace already refers to: #'clojure.string/replace in namespace: sandbox> |
| 09:16 | Bronsa | i think i broke clojurebot :E |
| 09:16 | gfredericks | &(reverse "string") |
| 09:16 | lazybot | ⇒ (\g \n \i \r \t \s) |
| 09:17 | gfredericks | is lazybot to the rescue??? |
| 09:17 | lazybot | gfredericks: Oh, absolutely. |
| 09:17 | Bronsa | i ,(use 'clojure.string) |
| 09:17 | Bronsa | and reverse && replace got broken |
| 09:17 | gfredericks | Bronsa: somebody will reboot it eventually |
| 09:17 | Bronsa | i'm sorry ( ,_,) |
| 09:17 | Bronsa | didn't mean to broke it |
| 09:17 | Bronsa | *break |
| 09:17 | gfredericks | no problem. lazybot still works. |
| 09:20 | st3fan | &(str (map #(str %) (seq "Hello"))) |
| 09:20 | lazybot | ⇒ "clojure.lang.LazySeq@5db0151" |
| 09:20 | st3fan | how does str return a lazy seq? |
| 09:26 | Bronsa | st3fan: you're trying to str a sequence |
| 09:26 | Bronsa | you should apply str to a sequence |
| 09:31 | gfredericks | st3fan: you also might like pr-str |
| 09:32 | gfredericks | &(pr-str (map str (seq "Hello"))) |
| 09:32 | lazybot | ⇒ "(\"H\" \"e\" \"l\" \"l\" \"o\")" |
| 09:43 | mindbender1 | |
| 09:43 | gfredericks | mindbender1: |
| 09:44 | mindbender1 | gfredericks: hi |
| 09:46 | gfredericks | :) |
| 09:47 | mindbender1 | I'm in the process of learning clojure and have read programming clojure and the joy of clojure and my head is spinning...:) |
| 09:49 | gfredericks | mindbender1: what sorts of languages are you coming from? |
| 09:50 | mindbender1 | not a particularly good programmer prior to clojure but I am familiar with java.. so I wanted a language I could grow with |
| 09:51 | mindbender1 | I intend to work in the erp field with the clojure language |
| 09:52 | gfredericks | that sounds fun |
| 09:52 | mindbender1 | any pointers or red signs? |
| 09:53 | Arafangion | With the ERP field, or clojure? |
| 09:54 | mindbender1 | with clojure in the erp field, especially as I intend extend already popular erp packages with clojure? |
| 09:55 | mindbender1 | or rather customize them |
| 09:55 | cark | in the same vm as your erp packages ? |
| 09:56 | mindbender1 | yes in the same vm |
| 09:56 | cark | so you run the package, and it calls into clojure ? |
| 09:57 | cark | i mean, do you intend to have clojure around it, or the other way around ? |
| 09:57 | mindbender1 | yes or I was thinking clojure.jar would be somewhere on the lib path of the app |
| 09:57 | cark | as far as i know you might be loosing the benefit of a repl |
| 09:57 | mindbender1 | then customizationss will be in a different jar. no touching of classes in the app |
| 09:58 | cark | losing* |
| 09:58 | mindbender1 | actually the app I had in mind is adempiere |
| 09:59 | cark | i find it's easier to call java (or even patch stuff) from clojure than the other way around |
| 09:59 | mindbender1 | yes i intend to call java from clojure |
| 09:59 | mindbender1 | that is call the classes in the app from my clojure dev environment |
| 10:00 | Arafangion | You can't easily call into clojure from java? |
| 10:00 | cark | i fyou can use your erp packages as libraries to your clojure app, then you're golden |
| 10:00 | cark | Arafangion: yes you can |
| 10:00 | cark | Arafangion: only it's annoying when you're used to the ease of developement starting from clojure |
| 10:00 | mindbender1 | ok you suggest using the erp packages as lib in my app? |
| 10:01 | cark | i 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:02 | cark | one of the strong points of clojure is interactive developement |
| 10:02 | mindbender1 | already 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:03 | cark | by calling into clojure, you'd need to use the old code->compile->run cycle at least until you have your interface ironed out |
| 10:03 | cark | which is very possible, but annoying |
| 10:05 | Arafangion | cark: Well, if it were me, I'd define the interface in Java... And implement it in Clojure. |
| 10:05 | Arafangion | Which reminds me. |
| 10:05 | cark | Arafangion: yes, true |
| 10:06 | Arafangion | Does Clojure have a dependency injection framework? (Spring seems to be common...) |
| 10:06 | cark | clojure is a functional language |
| 10:06 | cark | it does not need a dependency injection framework |
| 10:06 | mindbender1 | joy of clojure talks about clojure not needing DI |
| 10:07 | cark | ,(sort-by identity > [4 3 8 1 2]) |
| 10:08 | clojurebot | (8 4 3 2 1) |
| 10:08 | Arafangion | I'm not so sure about that. |
| 10:08 | cark | se how i injected the > function in the sort-by function |
| 10:08 | cark | see* |
| 10:08 | Arafangion | cark: Yes, so the language itself provides it there. For this langauge, at least. That's awesome. |
| 10:09 | Arafangion | cark: Arguably, in the case of python, it does so likewise if you think of the language providing a service locator. |
| 10:09 | Twey | DI frameworks are just a workaround for Java treating functions as second-class citizens… |
| 10:09 | Arafangion | Twey: That's unrelated. |
| 10:09 | Twey | Oh? |
| 10:09 | cark | i think it's related |
| 10:09 | Arafangion | DI frameworks are a workaround for the proliferation of dependencies caused by writing generic code in OO environments. |
| 10:09 | cark | tho i'm no DI guru |
| 10:10 | Arafangion | They allow you to replace any dependency with another dependency. |
| 10:10 | Arafangion | For example. |
| 10:10 | Twey | But you can do that with first-class functions. |
| 10:11 | Arafangion | Implementing a function that operates on a stream is better than implementing a function that operates on a file name. |
| 10:11 | Arafangion | Because the latter function does not allow you to replace how the file is opened or iterated over. |
| 10:11 | Twey | Right |
| 10:11 | mindbender1 | Arafangion: ? please expantiate |
| 10:11 | cark | look at my example again, sort-by is the generic version of sort |
| 10:11 | Arafangion | That is dependency injection on a trivial level. |
| 10:11 | Twey | I am aware of the concept of DI |
| 10:12 | Twey | And I assert that first-class functions provide all the necessary features to do that, without a third-party framework |
| 10:12 | Arafangion | Now, here's where DI gets annoying. |
| 10:12 | mindbender1 | Arafangion: references please |
| 10:12 | Twey | Okay |
| 10:12 | Arafangion | WHen you have, eg, a function that does, well, suppose it's a web spider. |
| 10:13 | Arafangion | One of the functions it uses is get-http-protocol-handler |
| 10:13 | Arafangion | In a typical, non-oo language, you would have something like: perform_spider(list_of_root_references0 |
| 10:14 | Arafangion | But... If you're using DI as a design technique, you would have: |
| 10:14 | Arafangion | perform_spider(list_of_root_references, http_protocol_handler, generic_sort, ...) |
| 10:14 | cark | well in clojure you would have something like this : |
| 10:15 | Arafangion | In OO langauges, you typically end up having a heirachy of dependencies. |
| 10:15 | mindbender1 | and with java 6 CDI was built in |
| 10:15 | cark | (defn perform-spider [& {keys [protocol-handler sort-fn ... ]}] ....) |
| 10:15 | Arafangion | cark: Aha, and now we get to the meat of it. |
| 10:15 | cark | then you can make your factory function, which woudl be the configuration for your application |
| 10:16 | Arafangion | cark: 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:16 | cark | it won't |
| 10:16 | Arafangion | cark: It will. |
| 10:17 | cark | you still need to write the xml configuration |
| 10:17 | Arafangion | cark: Ah, that reminds me why I didn't like Spring. :( |
| 10:17 | cark | i'd rather write clojure than xml =P |
| 10:17 | Arafangion | cark: Apparently, however, you don't have to. I actually come to DI from C#. |
| 10:17 | mindbender1 | what I read of DI was a matter of handling things like initialization and transaction management services |
| 10:18 | Arafangion | cark: And I don't write any XML for my dependency injection, at all. |
| 10:18 | Twey | It needs to know which dependencies to use, somehow |
| 10:18 | Arafangion | In C#, I use reflection for that. |
| 10:18 | cark | Arafangion: at some point you still need to tell your framework which interface you want to use |
| 10:18 | Twey | The Spring gets the information from the XML configuration |
| 10:18 | Twey | The Clojure takes that map argument |
| 10:18 | cark | i mean which implementation |
| 10:18 | Arafangion | cark: I use conventions. |
| 10:18 | Twey | I'm guessing the C# uses annotations or something |
| 10:19 | Arafangion | cark: Eg, if I ask for IFoo, then unless I specify otherwise, I tend to mean "Use Foo". |
| 10:19 | cark | well then you have a single implementation and you don't need DI |
| 10:19 | Arafangion | In my unit tests, if I ask for IFoo, then unless I specify otherwise, I tend to mean "Use a mock<IFoo>". |
| 10:19 | Twey | … yeah |
| 10:19 | Arafangion | cark: If I didn't haev unit tests, perhaps. |
| 10:20 | Arafangion | cark: But in any case, I do have project-specific conventions and only a small number of exceptions. |
| 10:20 | Arafangion | (exceptions... excemptions... I think I mean the latter) |
| 10:20 | cark | as 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:21 | cark | maybe i've been away from c# and java for too long =) |
| 10:22 | cark | my take on it is this : in java/c# you're mostly working with objects, they need to be configured at creation time |
| 10:23 | Arafangion | cark: The implementation in my primary project is specified as: "Use the implementation of the same name minus the leading 'I'". |
| 10:23 | cark | in clojure you're mostly working with function |
| 10:23 | Arafangion | cark: As I said, I use reflection. |
| 10:23 | cark | so you configure the function at call time |
| 10:23 | cark | Arafangion: ah i get it now |
| 10:24 | Arafangion | cark: However, in my unit tests, I do not want to be testing teh dependencies, I want to test the "unit" in isolation.] |
| 10:24 | Arafangion | cark: And that, is actually teh main reason I use DI. |
| 10:24 | ghiu | hi, 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:24 | Arafangion | cark: So as a result, for the unit test project, I say: "The implementation I want is a dynamically generated mock of type IFoo". |
| 10:24 | cark | ,(map #(let [one 1] (+%1 one )) '(1 2 |
| 10:24 | cark | 3 4)) |
| 10:24 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading> |
| 10:24 | cark | ,(map #(let [one 1] (+%1 one )) '(1 2 3 4)) |
| 10:24 | clojurebot | (2 3 4 5) |
| 10:24 | Arafangion | cark: So I make a real instance of the unit I want to test... With all of it's dependencies automatically mocked out. |
| 10:25 | cark | Arafangion: i see, and that's nice |
| 10:25 | Arafangion | cark: Extreme DI is pointless in a functional language, I'll agree with that... However... |
| 10:25 | ghiu | , (map #((let [one 1] (+%1 one ))) '(1 2 3 4)) |
| 10:25 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn> |
| 10:25 | Bronsa | ghiu you have an extra pair of parenthesis |
| 10:25 | Arafangion | cark: 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:26 | ghiu | Bronsa: oh, the one before let? |
| 10:26 | Bronsa | yes |
| 10:26 | Bronsa | also the one matching that |
| 10:26 | ghiu | because it is already the body of the function |
| 10:26 | ghiu | i see |
| 10:26 | cark | Arafangion: i must confess i mostly don't do unit testing, i'm all good with behaviour testing |
| 10:26 | ghiu | thanks |
| 10:26 | Bronsa | np |
| 10:27 | Arafangion | cark: By behaviour testing, do you mean system testing? |
| 10:27 | cark | Arafangion: higher level testing i guess |
| 10:27 | Arafangion | cark: Yeah... Those are important too, but they have this one massive flaw. |
| 10:27 | cark | i do small time testing at the repl =) |
| 10:27 | Arafangion | cark: 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:28 | Arafangion | cark: And I've seen such testing take hours. |
| 10:28 | cark | Arafangion: i know i can get away with it because i'm not working in a team |
| 10:28 | Arafangion | small-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:29 | Arafangion | cark: I don't think a team has anything to do with it... But it would depend on your requirements. |
| 10:29 | cark | i think unit testing is usefull, and i use it a lot then, when you're working on data structures or algorithms |
| 10:29 | Arafangion | I wouldn't bother to do more than manual testing for simple scripts and quick projects, for example. |
| 10:30 | Arafangion | cark: Case in point: I was able to see exactly what was broken when I *completely changed my VM*. |
| 10:30 | Arafangion | cark: From Python(C) to IronPython. (.NET) |
| 10:30 | cark | Arafangion: wew that must have been painfull |
| 10:31 | Arafangion | cark: It was surprisingly pleasant, but mostly because I stopped short of completing the port. ;) |
| 10:31 | cark | hehe ok |
| 10:31 | Arafangion | cark: The main thing that stopped me was no expat support. :( |
| 10:32 | Arafangion | And #python is currently hostile with using expat. |
| 10:32 | cark | anyways, to come back to DI, i find that i don't need so much of that in real life projects |
| 10:32 | cark | and genericity is usually pretty localized |
| 10:32 | Arafangion | I mostly use it in "real life projects". |
| 10:33 | Arafangion | Then again, most of my projects tend to have a LOT of business logic.; |
| 10:33 | cark | well mine too |
| 10:33 | Arafangion | And they change a lot. :( |
| 10:33 | cark | but it's still localized |
| 10:34 | Arafangion | And to be honest... |
| 10:34 | Arafangion | I don't think I get any productivity improvement for using a DI framework. |
| 10:34 | Arafangion | I still use DI, but I don't think using a "DI Framework" gives actual productivity improvement. |
| 10:34 | cark | clojure should provide you with this improvement i think =) |
| 10:34 | Arafangion | It saves perhaps 2 minutes of refactoring each time I change a dependency, and that'd be updating my unit tests. |
| 10:35 | Arafangion | cark: Alas, I won't likely be ablet o use Clojure at work. |
| 10:35 | Arafangion | I'd like to, it would solve a number of painful issues I have. |
| 10:36 | Arafangion | For instance, between the various JS VM's, .NET, Mono, and Java, I'd be able to have common code everywhere. |
| 10:36 | Arafangion | And by extension, they'd share a lot of tests and business logic. |
| 10:37 | cark | how come you have to work on all these VMs ? |
| 10:37 | Arafangion | I don't, but on windows, I use .NET |
| 10:37 | Arafangion | And on the mac, I don't. |
| 10:38 | cark | i see |
| 10:38 | Arafangion | I use ObjC on the mac. |
| 10:42 | Arafangion | I'm off to bed! |
| 10:43 | cark | good night ! |
| 10:47 | eliOcs | hello everyone! |
| 10:57 | kephale | in 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:04 | eanxgeek | new 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:04 | eanxgeek | any thoughts on what I have done wrong? |
| 11:07 | cark | (DefaultSelenium. "localhost" 4444 "Firefox" "www.google.com") |
| 11:07 | cark | or something like i |
| 11:07 | cark | tit |
| 11:07 | cark | it |
| 11:07 | cark | ! |
| 11:08 | cark | what's with all the quoting you're doing |
| 11:08 | cark | and (:keyword blah) doesn't mean what you think it means |
| 11:10 | eanxgeek | cark: I was wondering if I was messing something up there with the :keyword blah |
| 11:11 | cark | keywords are function that look themselves in the map argument |
| 11:11 | cark | so |
| 11:11 | eanxgeek | cark: when I simplify further, like your above example, I get DefaultSelenium. should be a vector |
| 11:12 | cark | ,(:blah {:a 1 :blah 2}) |
| 11:12 | clojurebot | 2 |
| 11:12 | cark | paste again =) |
| 11:13 | eanxgeek | http://pastebin.com/zi4Pzyhk |
| 11:14 | Bronsa | eanxgeek the code should look like (defn fn-name [args] (let [var (Class. args)] (.doStuff var))) |
| 11:14 | eanxgeek | I may have over simplified your intention |
| 11:14 | cark | eanxgeek: just like bronsa said |
| 11:16 | eanxgeek | cark: Bronsa: I think i have that http://pastebin.com/RvBXfYai |
| 11:16 | eanxgeek | now getting java.lang.IllegalArgumentException: Parameter declaration let should be a vector (NO_SOURCE_FILE:1) |
| 11:18 | cark | http://pastebin.com/kjcM0Cra |
| 11:18 | mindbender1 | please how can I include username and paswword in a URI so that I can access it later with.. |
| 11:19 | mindbender1 | (let [url (URI. (System/getenv "DATABASE_URL")) |
| 11:19 | mindbender1 | (if-let [user-info (.getUserInfo url)] |
| 11:19 | mindbender1 | {:user (first (str/split user-info #":")) |
| 11:21 | eanxgeek | cark: 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:22 | cark | eanxgeek: he's looking up the parameters in the opt map |
| 11:22 | eanxgeek | cark: right I figured that out hence why my :host 'localhost doesn't work |
| 11:23 | eanxgeek | so I have now removed that stuff, trying (let [client (new DefaultSelenium ('localhost) ... but that doesn't work |
| 11:23 | eanxgeek | still getting show be a vector |
| 11:23 | cark | did you look at my paste ? |
| 11:24 | cark | ('localhost) just doesn't make sense |
| 11:25 | eanxgeek | well not sure if this code will work but it compiled |
| 11:25 | eanxgeek | http://pastebin.com/tbrK1Yhr |
| 11:25 | eanxgeek | next step is to test in a repl |
| 11:25 | cark | man |
| 11:25 | cark | it won't work at all |
| 11:25 | eanxgeek | heh |
| 11:26 | eanxgeek | i'm such a noob |
| 11:26 | eanxgeek | can't i go back to python |
| 11:26 | cark | parenthesis are for function application |
| 11:26 | cark | (localhost) is like localhost() in javascript |
| 11:26 | eanxgeek | ah ok |
| 11:27 | eanxgeek | now that makes sense |
| 11:27 | cark | quoting is something entirely different |
| 11:27 | cark | 'blah |
| 11:27 | cark | that means, the symbol blah |
| 11:27 | daniel___ | 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:27 | cark | (blah arg1 arg2) means the function blah called with args arg1 and arg2 |
| 11:28 | duck1123 | eanxgeek: also, have you looked at clj-webdriver? Might be a bit easier to do whatever you're doing |
| 11:29 | eanxgeek | duck1123: 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:29 | cark | you might want starting with basic understanding of clojure |
| 11:30 | eanxgeek | yeah I can already tell some of my reading didn't stick :-( |
| 11:30 | duck1123 | Fair enough, just thought I'd let you know it's out there |
| 11:30 | eanxgeek | damn battery... looks like I'm outta here one way or the other |
| 11:30 | eanxgeek | thanks for the pointers I'll keep banging away at this. |
| 11:32 | cark | there's an awefull lot of banging to do =) |
| 11:34 | duck1123 | are 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:36 | duck1123 | Well, I just found the problem, but my question still stands |
| 11:36 | raek | duck1123: if you're using gen-class there might be old versions of your namespaces in compiled form in the classes/ directory |
| 11:37 | duck1123 | raek: 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:38 | duck1123 | I 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:52 | duck1123 | is 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:53 | duck1123 | it looks like the zip filters give me the prefix and the name for the tag, not taking xml namespaces into account |
| 11:56 | daniel___ | vimclojure/server seems to have broken dependencies...anyone using vimclojure can tell me how they set up their ng server? |
| 12:12 | ghiu | hi, 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:12 | ghiu | any help? |
| 12:16 | duck1123 | ghiu: are you trying to do this manually, or are you using a build tool of some sort? |
| 12:33 | daniel___ | ,(seq "dsfsdfsdfsd") |
| 12:33 | clojurebot | (\d \s \f \s \d ...) |
| 12:37 | daniel___ | if i have two lists like (\d \f \s \h \q), how can i iterate through both lists doing operations involving each pair? |
| 12:38 | daniel___ | by pair, im thinking if it were an array, the values with the same index |
| 12:39 | daniel___ | 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:39 | duck1123 | ,(map (fn [x y] {x y}) [1 2 3] [4 5 6]) |
| 12:39 | clojurebot | ({1 4} {2 5} {3 6}) |
| 12:40 | duck1123 | ,(apply + (map (fn [x y] (- y x)) [1 2 3] [4 5 6])) |
| 12:40 | clojurebot | 9 |
| 12:42 | daniel___ | thanks duck1123, let me take some time to get my head around what you just did |
| 12:42 | duck1123 | If you call map with multiple collections, it'll call that function with one from each collection |
| 12:43 | daniel___ | i see, thats neat |
| 12:43 | daniel___ | and apply + is basically a summation |
| 12:44 | duck1123 | (apply + '(3 3 3)) is the same as (+ 3 3 3) |
| 12:44 | daniel___ | yep, got it |
| 12:45 | daniel___ | cheers |
| 12:46 | duck1123 | you 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:52 | daniel___ | ,(seq "dsfsdf") |
| 12:52 | clojurebot | (\d \s \f \s \d ...) |
| 12:52 | daniel___ | this creates a collection of characters |
| 12:53 | daniel___ | im having trouble because i need them to be strings of length 1 |
| 12:53 | raek | the vararg version of + is implemented with reduce |
| 12:53 | duck1123 | ,(map str "dsfsdf") |
| 12:53 | clojurebot | ("d" "s" "f" "s" "d" ...) |
| 12:53 | raek | daniel___: (map str "dsfdsf") |
| 12:54 | daniel___ | ahh ta |
| 12:54 | duck1123 | raek: so does that mean that given the choice, I should reduce there? |
| 12:55 | raek | for str and concat it's better to use apply than reduce |
| 12:55 | raek | it depends on the function, I guess... |
| 12:56 | raek | (reduce str will create a lot of intermediate immutable strings but apply str will use a string builder) |
| 12:58 | duck1123 | Does anyone have any suggestions for processing xml in a ns-aware fashion? |
| 12:59 | duck1123 | I'm checking out pjt's saxon wrapper, but it returns a single item if the query has only one result |
| 13:06 | devn | duck1123: there's another parser thingamajig somewhere |
| 13:07 | devn | i think I saw it in reference to a SOAP-specific library |
| 13:07 | devn | sorry i dont have a name for you, but that's something to google around for |
| 13:07 | daniel___ | can someone using a vim repl share how they set it up? im using vimclojure but cant get nailgun to work |
| 13:08 | ghiu | is ring robust enough to be used as production server or it is dev-only and requires a deployment under tomcat? |
| 13:10 | cark | ring is not an http server ... i'm guessing you're talking about jetty ? |
| 13:11 | duck1123 | ghiu: There are several sites that I can think of that are using ring in relatively heavy production |
| 13:11 | cark | i do use ring in production too |
| 13:11 | duck1123 | and I believe more people use jetty than tomcat |
| 13:11 | cark | with jetty |
| 13:11 | ghiu | do you need any reverse proxy in front of it? |
| 13:11 | ghiu | like |
| 13:11 | duck1123 | ring is more or less container agnostic |
| 13:11 | cark | abd it's good enough for hundreds of pages per second |
| 13:11 | dbushenko | cark: where do you use ring in production? |
| 13:11 | ghiu | you use it under nginx or something? |
| 13:12 | cark | jetty + ring, directly |
| 13:12 | cark | using it for a telecomunication application, providing information to customers of small telcos |
| 13:12 | duck1123 | I use nginx in front of aleph. I had some odd issues with caching with apache |
| 13:13 | dbushenko | cark: can you share a link? I'm collecting success stories |
| 13:13 | cark | nope it's all behind login/password |
| 13:13 | cark | the application is sold by the company i made it for |
| 13:14 | dbushenko | sad... |
| 13:14 | cark | sorry =( |
| 13:15 | dbushenko | this is your startup? |
| 13:15 | wink | cark: how did you daemonize it? |
| 13:15 | cark | nope i'm a freelance programmer |
| 13:15 | cark | it's not running as a daemon |
| 13:15 | ghiu | the main main of ring repository (https://github.com/weavejester/lein-ring) only shows how to use it for a dev server |
| 13:15 | cark | running under solaris |
| 13:16 | ghiu | how to use it in production? |
| 13:16 | cark | i provide a jar file, and directory structure, i develop under windows, they make it run |
| 13:16 | cark | i really don't know much about the unix side |
| 13:17 | cark | they have a startup scirpt, it's only running the executable jar |
| 13:17 | cark | we had only one solid down time at a customer's site |
| 13:17 | cark | because there was a limit to the number of thread jetty was creating |
| 13:18 | cark | but after a few hours researching the cause, it was easily fixed |
| 13:18 | cark | really no trouble at all besides this one time |
| 13:23 | amalloy | ghiu: www.4clojure.com uses ring/jetty/nginx. not a huge load, of course, but it's "production" |
| 13:23 | cark | nginx is for the static stuff ? |
| 13:23 | cark | or is everything behind a proxy ? |
| 13:30 | thoefer | try 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:30 | thoefer | all samples work for me... |
| 13:31 | justicefries | so am I to understand correctly that templating with most clojure frameworks are done in clojure? |
| 13:31 | justicefries | instead of writing any html/haml/whatever |
| 13:33 | duck1123 | Some people use templates, but a lot of people just use hiccup to generate html |
| 13:35 | dbushenko | justicefries, no, that's not so simple |
| 13:35 | dbushenko | moment, let me show you a prooflink |
| 13:36 | dbushenko | read this one |
| 13:36 | dbushenko | http://www.reddit.com/r/programming/comments/al98b/clojure_and_compojure_to_the_rescue_again/ |
| 13:36 | dbushenko | breafly: 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:38 | wink | amalloy: is there any detailed description/howto for that setup? I haven't really found anything decent to copy yet :P |
| 13:38 | amalloy | haha don't copy us. ours is terrible |
| 13:38 | wink | I'm doing lein run in a screen. can it be worse? :) |
| 13:39 | amalloy | cark: 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:39 | cark | hehe ok |
| 13:39 | cark | my bad ! |
| 13:41 | amalloy | wink: about equally bad, i guess. our deploy process is lein deps && kill oldproc && nohup java -cp (...) clojure.main -e (...) |
| 13:42 | ghiu | i 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:44 | gfredericks | amalloy: 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:46 | gfredericks | That might just be my least favorite part about linux. |
| 13:53 | thoefer | my bad, clojurescript works :) |
| 13:54 | ghiu | hmmm, can i import an entire namespace from java or just objects? |
| 13:55 | ghiu | i mean classes? |
| 13:56 | daniel__2 | ,(map str "dsad") |
| 13:56 | clojurebot | ("d" "s" "a" "d") |
| 13:56 | gfredericks | ghiu: just classes. You can use gen-class to create a class in your ns that calls functions in the ns. |
| 13:56 | gfredericks | depending on what you're doing that may or may not be the simplest approach. |
| 13:59 | ghiu | ok, 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:59 | daniel__2 | (apply + (map contstr/codepoints (map str "dasdsa"))) |
| 14:00 | daniel__2 | i get a cant cast lazyseq into number with this |
| 14:00 | sid3k | hi 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:00 | bsod1 | is there a lazy sort function in clojure? |
| 14:02 | gfredericks | daniel__2: that makes sense. What are you trying to do? Add the codepoints in the original string? |
| 14:02 | gfredericks | ghiu: it will take care of all the dependencies that you declare in your (ns) declarations...not quite sure what else you might mean. |
| 14:02 | amalloy | bsod1: none built in. you can write one pretty quickly though, and JoC does just that |
| 14:02 | daniel__2 | gfredericks: sum all the integers |
| 14:03 | daniel__2 | i think i need ([1] [2] [3]) instead of ((1) (2) (3)) |
| 14:03 | gfredericks | daniel__2: why not (contstr/codepoints "dasdsa") instead of the maps? |
| 14:03 | bsod1 | amalloy: who is JoC? |
| 14:03 | amalloy | joy of clojure |
| 14:03 | bsod1 | ah, ok, thanks |
| 14:04 | daniel__2 | gfredericks: not sure what that gives me but let me try |
| 14:04 | daniel__2 | you're right, thats what i want |
| 14:04 | daniel__2 | cheers |
| 14:04 | gfredericks | :) |
| 14:04 | daniel__2 | i thought it not be split at the end of it |
| 14:04 | amalloy | but 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:04 | daniel__2 | it might not be* |
| 14:06 | daniel__2 | but so i learn something, in the case i had a lazyseq and wanted to convert them to numbers? |
| 14:07 | gfredericks | daniel__2: if you want to sum up a lazy seq you can use (apply + ...) just like in your example |
| 14:07 | gfredericks | &(apply + (range 2 10)) |
| 14:07 | lazybot | ⇒ 44 |
| 14:08 | gfredericks | daniel__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:08 | daniel__2 | ,(apply + ((1) (2) (3))) |
| 14:08 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn> |
| 14:09 | gfredericks | ,(apply + (map first [[1] [2] [3]])) |
| 14:09 | clojurebot | 6 |
| 14:09 | daniel__2 | ok, thanks |
| 14:09 | gfredericks | ,(map first [[1] [2] [3]]) |
| 14:09 | clojurebot | (1 2 3) |
| 14:09 | gfredericks | yep |
| 14:09 | gfredericks | daniel__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:09 | lazybot | ⇒ (1 2 3) |
| 14:11 | daniel__2 | yup, i knew that |
| 14:19 | amalloy | note 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:19 | bsod1 | I'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:20 | amalloy | sorting a sorted sequence is pretty fast |
| 14:20 | amalloy | run down the line, find out it's already sorted, do no swaps |
| 14:20 | bsod1 | amalloy: no it's not sorted, I'm not changing the seq, I'm sorting same unsorted seq every time |
| 14:21 | bsod1 | amalloy: my sort function is side-effect free, there no changing |
| 14:21 | bsod1 | there is no changing* |
| 14:21 | bsod1 | amalloy: here's my sort function http://paste.pocoo.org/show/489995/ |
| 14:22 | daniel__2 | can anyone suggest how to change a random character in a string? |
| 14:23 | amalloy | oh, 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:23 | amalloy | daniel__2: ##(str \F) |
| 14:23 | lazybot | ⇒ "F" |
| 14:23 | bsod1 | amalloy: (time (qsort (take 1000 (repeatedly #(rand-int 1000))) <)) |
| 14:23 | amalloy | so it's not the same seq at all |
| 14:24 | daniel__2 | say i have ("f" "d" "h" "w"), how would i choose a character at random? |
| 14:24 | bsod1 | amalloy: actually I'm saving this seq to a var but I changed it to paste it here |
| 14:24 | daniel__2 | and modify it |
| 14:24 | gfredericks | daniel__2: rand-nth? |
| 14:24 | bsod1 | (def t (take 100...)) |
| 14:24 | gfredericks | daniel__2: never mind |
| 14:24 | bsod1 | (time (qsort t <)) |
| 14:24 | gfredericks | daniel__2: for random updates you'll want a vector instead of a list |
| 14:25 | amalloy | bsod1: 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:25 | daniel__2 | hmm ok, lets say i have a function (defn mutatestring [string] ...) |
| 14:25 | daniel__2 | i want to return the string with one char modified |
| 14:26 | daniel__2 | so ill have a string which i want to convert to a vector of chars? |
| 14:26 | bsod1 | amalloy: I'm sorting on REPL so qsort is printing the result, so it's sorting all the seq |
| 14:26 | amalloy | bsod1: but time is returning before the printing happens, so that's immaterial |
| 14:27 | bsod1 | amalloy: ok, I'll add (print) over qsort and try again |
| 14:29 | gfredericks | daniel__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:29 | gfredericks | (let [i (choose-index)] (str (subs s 0 (dec i)) (rand-char) (subs s (inc i)))) |
| 14:30 | gfredericks | daniel__2: ^ that might do it |
| 14:30 | amalloy | daniel__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:31 | daniel__2 | it will, let me try and understand both ways |
| 14:31 | daniel__2 | how would i convert a string to a vector? |
| 14:31 | amalloy | &(vec "test") |
| 14:31 | lazybot | ⇒ [\t \e \s \t] |
| 14:32 | daniel__2 | ,(rand-nth (vec "test")) |
| 14:32 | clojurebot | \t |
| 14:33 | gfredericks | daniel__2: rand-nth was probably a bad suggestion, since that doesn't help you know where to update |
| 14:38 | daniel__2 | im 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:38 | gfredericks | ,(char 77) |
| 14:38 | clojurebot | \M |
| 14:39 | daniel__2 | aaah ok |
| 14:39 | mindbender2 | anyone familiar with heroku? I'm having troubles getting an app to run with foreman |
| 14:39 | daniel__2 | this repl in irc is revolutionary |
| 14:40 | amalloy | haha daniel__2 it is a pretty old revolution |
| 14:41 | wink | amalloy: thanks. yeah, only a bit better :P |
| 14:44 | amalloy | &(-> "A" first int inc char str) ;; clojure's compellingly-simple ascii arithmetic... |
| 14:44 | lazybot | ⇒ "B" |
| 14:46 | daniel__2 | amalloy: nice |
| 14:46 | clojurebot | amalloy: therfor I return [previous] if rest is empty |
| 14:47 | daniel__2 | whats -> |
| 14:47 | duck1123 | shut up, clojurebot |
| 14:47 | amalloy | &(use 'clojure.walk) |
| 14:47 | lazybot | ⇒ nil |
| 14:47 | amalloy | &(macroexpand-all '(-> "A" first int inc char str)) |
| 14:47 | lazybot | ⇒ (str (char (inc (int (first "A"))))) |
| 14:48 | duck1123 | -> puts second ->> puts last |
| 14:48 | duck1123 | they're both great for simplifying code |
| 14:49 | daniel__2 | doesnt look much simpler to me :S |
| 14:49 | daniel__2 | whats does first do in this example? |
| 14:50 | gfredericks | turns "A" into a char |
| 14:50 | gfredericks | ,(first "A") |
| 14:50 | clojurebot | \A |
| 14:50 | daniel__2 | ,(char "A") |
| 14:50 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number> |
| 14:50 | daniel__2 | hmmm ok |
| 14:50 | gfredericks | daniel__2: it works because (first) will start by converting the argument to a seq |
| 14:50 | gfredericks | c.f., ##(first "foobar") |
| 14:50 | lazybot | ⇒ \f |
| 14:51 | amalloy | daniel__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:51 | duck1123 | Take "A", grab the first char, turn it into an int, increment it, thurn it back into a char, thurn that into a string |
| 14:51 | amalloy | but it's not super-helpful in this case; -> and ->> are more useful for functions that take more than one arg |
| 14:52 | daniel__2 | ok, i see |
| 14:52 | Vinzent | it helps to preserve natural order of reading here |
| 14:52 | amalloy | eg, ##(->> [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:52 | lazybot | ⇒ 1655824071758491008590040 |
| 14:52 | amalloy | wow, that high? |
| 14:53 | daniel__2 | ,(int (char "#")) |
| 14:53 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number> |
| 14:53 | duck1123 | they add up, *drumroll* |
| 14:53 | daniel__2 | ,(int (char "A")) |
| 14:53 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number> |
| 14:53 | daniel__2 | sorry, oops |
| 14:53 | amalloy | duck1123: i think you want |
| 14:53 | amalloy | ~rimshot |
| 14:53 | clojurebot | Badum, *ching* |
| 14:54 | daniel__2 | ,(int (first "#")) |
| 14:54 | clojurebot | 35 |
| 14:54 | daniel__2 | hmmm, why am i using codepoints when it seems to be as simple as int |
| 14:54 | daniel__2 | ,(int (first "$")) |
| 14:54 | clojurebot | 36 |
| 14:55 | gfredericks | daniel__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:55 | daniel__2 | :) |
| 14:55 | gfredericks | at least I did. And then another year or two after thaht. |
| 14:57 | daniel__2 | how long has clojure been around? |
| 14:58 | duck1123 | 3.5 years? |
| 14:59 | daniel__2 | thats about the right sort of time to start learning :D |
| 14:59 | duck1123 | Sept 22 2007 |
| 15:04 | daniel__2 | gfredericks: can you explain (let [i (choose-index)] (str (subs s 0 (dec i)) (rand-char) (subs s (inc i)))) ? |
| 15:05 | daniel__2 | i substitute s for the string |
| 15:06 | daniel__2 | and the rand-char? |
| 15:06 | daniel__2 | i dont want it completely random, i want it just offset |
| 15:06 | daniel__2 | i cant tell whether you made up these functions or not |
| 15:06 | daniel__2 | choose-index? |
| 15:07 | amalloy | he made up choose-index |
| 15:07 | amalloy | oh, and rand-char |
| 15:10 | daniel__2 | ok, ill have a go at implementing them |
| 15:15 | daniel__2 | why is it (.length "abc") and not (length "abc") ? does the . mean something? |
| 15:16 | Vinzent | daniel__2, it's a method call |
| 15:16 | raek | daniel__2: yes, it's the syntax you use to make a method call on a java object |
| 15:16 | Vinzent | (.method obj) in clojure is equivalent to obj.method in java |
| 15:16 | raek | so .length is not actually a clojure function at all |
| 15:16 | Vinzent | clojure one is count |
| 15:17 | daniel__2 | aah right |
| 15:17 | daniel__2 | thanks |
| 15:18 | Vinzent | does ^:keyword syntax always creating array-maps? I mean, is ^:foo ^:bar always equivalent to ^{:foo true :bar true}? |
| 15:19 | raek | I presume it uses the same way to choose the array map / hash map implementation as usual map literals |
| 15:22 | Vinzent | so the limit is 8, if my memory serves me? |
| 15:22 | raek | ,(class '{1 1, 2 2, 3 3, 4 4, 5 5, 6 6, 7 7}) |
| 15:23 | clojurebot | clojure.lang.PersistentArrayMap |
| 15:23 | raek | ,(class '{1 1, 2 2, 3 3, 4 4, 5 5, 6 6, 7 7, 8 8}) |
| 15:23 | clojurebot | clojure.lang.PersistentArrayMap |
| 15:23 | raek | ,(class '{1 1, 2 2, 3 3, 4 4, 5 5, 6 6, 7 7, 8 8, 9 9}) |
| 15:23 | clojurebot | clojure.lang.PersistentHashMap |
| 15:23 | raek | looks so |
| 15:28 | tdrgabi | Arafangion: a long time ago, you asked "what utf8 issue". |
| 15:29 | tdrgabi | while using noir and hiccup, something like: [:h1 "På"] looked like P� |
| 15:29 | tdrgabi | but it was because of my emacs and nothing wrong in clojure/noir |
| 15:29 | dnolen | core.match has reached the point where last 10% is 90% of the work :P |
| 15:29 | dnolen | 0.2.0-alpha5 being released, probably the last one before cutting beta. |
| 15:29 | daniel__2 | gfredericks: (let [i (choose-index)] (str (subs s 0 (dec i)) (rand-char) (subs s (inc i)))) |
| 15:30 | daniel__2 | im having trouble with the end cases |
| 15:30 | daniel__2 | choose-index: (rand-int (dec (count s))) |
| 15:30 | daniel__2 | that means (dec i) could be -1 |
| 15:31 | daniel__2 | and (inc i) could give an index too high |
| 15:33 | gfredericks | ,(subs "foobar" 0 -1) |
| 15:33 | clojurebot | #<StringIndexOutOfBoundsException java.lang.StringIndexOutOfBoundsException: String index out of range: -1> |
| 15:33 | gfredericks | daniel__2: I guess the dec should probably not be used. |
| 15:33 | gfredericks | ,(subs "foobar" 0 0) |
| 15:33 | clojurebot | "" |
| 15:34 | gfredericks | ,(subs "foobar" 6) |
| 15:34 | clojurebot | "" |
| 15:34 | gfredericks | I think the inc is correct though |
| 15:35 | gfredericks | daniel__2: I don't think choose-index should have the dec either |
| 15:35 | daniel__2 | ,(subs "foobar" 0 0) doesnt help either though |
| 15:35 | clojurebot | "" |
| 15:35 | daniel__2 | ,(count "ABC") |
| 15:35 | clojurebot | 3 |
| 15:35 | daniel__2 | ,(nth "ABC" 3) |
| 15:35 | clojurebot | #<StringIndexOutOfBoundsException java.lang.StringIndexOutOfBoundsException: String index out of range: 3> |
| 15:35 | daniel__2 | thats why i have the dec |
| 15:35 | gfredericks | daniel__2: (rand-int 3) never returns 3 |
| 15:36 | gfredericks | just [0 1 2] |
| 15:36 | daniel__2 | oh |
| 15:36 | daniel__2 | :D |
| 15:36 | gfredericks | what'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:36 | daniel__2 | gfredericks: duh :S |
| 15:37 | daniel__2 | thanks |
| 15:37 | gfredericks | yep |
| 15:39 | daniel__2 | its still not quite right, at least im not getting exceptions |
| 15:40 | gfredericks | no exceptions == no bugs :) |
| 15:41 | daniel__2 | nvm, found my mistake |
| 15:41 | duck1123 | just like no failing tests means it's perfect |
| 15:41 | gfredericks | duck1123: that's what we tell our clients |
| 15:41 | daniel__2 | i had (subs s 0 (inc i)) instead of (subs s (inc i)) |
| 15:41 | gfredericks | that'll do it |
| 15:42 | daniel__2 | perrrfect :D |
| 15:45 | daniel__2 | lisps are tricky but definitely fun |
| 15:51 | Vinzent | ,(class (meta ^:1 ^:2 ^:3 ^:4 ^:5 ^:6 ^:7 ^:8 ^:9 :foo)) |
| 15:51 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: Metadata can only be applied to IMetas> |
| 15:51 | Vinzent | ,(class (meta ^:1 ^:2 ^:3 ^:4 ^:5 ^:6 ^:7 ^:8 ^:9 'foo)) |
| 15:51 | clojurebot | nil |
| 15:53 | thorwil | dnolen: clojure.core.match, pretty please ;) |
| 15:53 | dnolen | thorwil: http://dev.clojure.org/jira/browse/MATCH-28 done |
| 15:53 | dnolen | well not "done" but ok, I'll do that |
| 15:54 | thorwil | dnolen: does throwing if no match found vary, i.e. does it transport more information than a nil? |
| 15:54 | thorwil | cool |
| 15:56 | raek | ,(class (meta ' ^:1 ^:2 ^:3 ^:4 ^:5 ^:6 ^:7 ^:8 ^:9 foo)) |
| 15:56 | clojurebot | clojure.lang.PersistentHashMap |
| 15:56 | raek | Vinzent: ^ |
| 15:56 | dnolen | thorwil: throwing would make it easier to determine what failed, but this should probably be a variant of match, like matchr (match-raise ?) |
| 15:56 | dnolen | match by default shouldn't throw I don't think. |
| 15:57 | raek | ^{:foo "bar"} (quote baz) and (quote ^{:foo "bar"} baz) are not the same |
| 15:57 | thorwil | in my admittedly very limited experience, i stumbled over exceptions where i would have been happy with a nil a few times |
| 15:57 | dnolen | thorwil: yeah, it's not friendly at all, http://dev.clojure.org/jira/browse/MATCH-29 |
| 16:02 | Vinzent | raek, ah, should remember it. But I don't understand why: 'baz returns a symbol, ^ adds meta to the next symbol... |
| 16:03 | ghiu | how can i cast a symbol to a string? like :a => "a" ? |
| 16:04 | brehaut | ,(name :a) |
| 16:04 | clojurebot | "a" |
| 16:04 | brehaut | and :a is a keyword, not a symbol |
| 16:04 | raek | Vinzent: ^ add metadata to the data structure to the right, which is the list (quote baz) |
| 16:05 | dnolen | I'm still amazed that core.match just works w/ ClojureScript |
| 16:05 | ghiu | thanks to both :) |
| 16:06 | raek | ^{:foo "bar"} (+ 1 2) adds metadata to the _code_ of (+ 1 2), not to the runtime result |
| 16:06 | raek | (for that, the 'with-meta' function is used) |
| 16:06 | Vinzent | raek, hm, right, ^ is in the reader time and (quote baz) is in runtime |
| 16:07 | raek | exactly |
| 16:07 | Vinzent | ,(class (meta ' ^:1 ^:2 ^:3 ^:4 ^:5 ^:6 ^:7 ^:8 foo)) |
| 16:07 | clojurebot | clojure.lang.PersistentArrayMap |
| 16:07 | Vinzent | ok, thank you raek |
| 16:20 | daniel__2 | what do you do if you want more than one line in an if's else statement |
| 16:20 | ghiu | how to check if a value is a number? something like string? |
| 16:20 | Vinzent | daniel__2, use (do ...) |
| 16:20 | gfredericks | daniel__2: you can use (do ...) whenever you need several statements in place of one |
| 16:21 | Vinzent | ghiu, number? |
| 16:21 | gfredericks | ,(doc number?) |
| 16:21 | clojurebot | "([x]); Returns true if x is a Number" |
| 16:21 | daniel__2 | this is getting bloody confusing |
| 16:21 | daniel__2 | i've got loop, when, if all jumbled up |
| 16:21 | ghiu | Vinzent: thank. it is not documented here http://clojure.org/cheatsheet |
| 16:22 | gfredericks | daniel__2: that does sound confusing |
| 16:22 | gfredericks | when and if are much more similar to eachother than to loop |
| 16:22 | Vinzent | daniel__2, usually you don't need this, because usually there is no side effects... |
| 16:23 | daniel__2 | i dont think i am thinking of the easiest way |
| 16:23 | daniel__2 | i have a function that takes 3 arguments [generation source target] |
| 16:23 | daniel__2 | i want to start at 0 and loop until i reach generation |
| 16:23 | gfredericks | (doseq [i (range generation)] ...) |
| 16:24 | Vinzent | ghiu, hm, indeed, that should be there is the "test" section... |
| 16:24 | gfredericks | doseq is for side effects though. Does your function need side-effects? |
| 16:24 | daniel__2 | if 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:25 | daniel__2 | i dont know what you mean by side-effects |
| 16:25 | daniel__2 | i think i need to break the problem into smaller pieces |
| 16:25 | Vinzent | daniel__2, function have side effects when it modifying some state outside of it |
| 16:25 | gfredericks | daniel__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:25 | daniel__2 | no, it should be pure |
| 16:26 | daniel__2 | isnt that the idea of functional programming? arent all functions ideally pure? |
| 16:26 | gfredericks | in functional programming languages it's usually good practice to code in pure functions when it's not too difficult |
| 16:26 | gfredericks | daniel__2: yes |
| 16:26 | Vinzent | well, maybe not all, but most of them |
| 16:27 | gfredericks | daniel__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:27 | gfredericks | perhaps map, perhaps reduce... |
| 16:27 | daniel__2 | (defn evolve [generation source target]) ... i want it to pass back a modified source to itself generation times |
| 16:27 | brehaut | Vinzent, 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:28 | gfredericks | daniel__2: you might want iterate |
| 16:28 | daniel__2 | yes, i think i do |
| 16:29 | gfredericks | then you would call (nth iterated-seq generations) on the result |
| 16:29 | amalloy | (nth (iterate #(compute-next-generation % target) source) generations) sounds about right to me |
| 16:29 | amalloy | though i'm just guessing on what "target" is for |
| 16:30 | gfredericks | yep that sorta thing |
| 16:30 | daniel__2 | im trying to evolve a random string into hello world |
| 16:30 | amalloy | then yep, my guess is about right |
| 16:30 | daniel__2 | target is "hello world" so i use it to test the fitness of source |
| 16:30 | amalloy | daniel__2: i think you should actually use a fitness function, not a target |
| 16:31 | daniel__2 | i have a fitness function (defn fitness [source target]) |
| 16:31 | daniel__2 | compares source and target and returns an int |
| 16:31 | amalloy | okay. i'd suggest passing that in to compute-next, rather than the target itself |
| 16:31 | daniel__2 | but then how will i be able to test the fitness on the next iteration? |
| 16:32 | daniel__2 | ill have lost my target |
| 16:32 | amalloy | but i actually meant something slightly higher level: (defn fitness-fn [target] (fn [source] (...do work...)) |
| 16:32 | amalloy | then you can create (fitness-fn "hello world") once, and use the function it returns to compare against any number of sources |
| 16:33 | daniel__2 | i see |
| 16:33 | gfredericks | daniel__2: ^ fun with higher-order functions :) |
| 16:33 | daniel__2 | but then i have "hello world" in my code, and ideally its an argument i pass to main |
| 16:34 | gfredericks | then (fitness-fn arg-from-main) instead |
| 16:35 | daniel__2 | its not pure if it relies on an arg from main though is it? |
| 16:35 | daniel__2 | thats why i have to pass it in each time |
| 16:36 | daniel__2 | maybe i just misunderstand the concept of higher order function |
| 16:36 | gfredericks | daniel__2: higher order function means a function where some of the args or the return value is also a function |
| 16:37 | gfredericks | in this case fitness-fn, as amalloy described, is a higher order function because it returns a function |
| 16:37 | daniel__2 | right |
| 16:37 | gfredericks | it returns a fitness function with a particular target |
| 16:37 | gfredericks | you would then take the returned function and use it with iterate |
| 16:38 | daniel__2 | i think i get it |
| 16:38 | gfredericks | I 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:38 | gfredericks | (instead of the target) |
| 16:38 | daniel__2 | yes, clever |
| 16:41 | daniel__2 | i dont understand the (nth (iterate line...know any simple examples illustrating this? |
| 16:42 | gfredericks | iterate repeatedly applies a function; so ##(take 8 (iterate #(* 3 %) 5)) |
| 16:42 | lazybot | ⇒ (5 15 45 135 405 1215 3645 10935) |
| 16:43 | gfredericks | nth just gives you the element at a particular index of the resulting infinite seq |
| 16:43 | gfredericks | so it's equivalent to applying a function n times |
| 16:43 | daniel__2 | right, like a loop |
| 16:44 | daniel__2 | or dont know if you know ruby ... n.times .. |
| 16:44 | gfredericks | I do know ruby. It's like that, but for pure functions |
| 16:45 | gfredericks | not that you _have_ to use pure functions with iterate, but that's the general flavor in contrast to ruby |
| 16:46 | gfredericks | e.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:46 | amalloy | daniel__2: https://gist.github.com/1274144 is a draft of how this algorithm could look if you were evolving integers instead of strings |
| 16:47 | amalloy | and of course to evolve strings instead, you change fitness-fn, and pass different args to start |
| 16:48 | daniel__2 | you just knocked that up now? |
| 16:48 | amalloy | yeah |
| 16:49 | amalloy | you seemed like you could use something more concrete :P |
| 16:49 | daniel__2 | you are passing sources - more than one source? |
| 16:49 | amalloy | daniel__2: working with a pool of candidates every generation |
| 16:50 | amalloy | the 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:50 | daniel__2 | ok, thats jumping ahead of what im doing :) im only mutating one source at the moment |
| 16:51 | daniel__2 | ill take some time to study this and see what i come up with |
| 16:51 | daniel__2 | cheers |
| 16:51 | amalloy | enjoy |
| 16:51 | amalloy | i'm off to lunch, so ask someone else for help |
| 16:52 | brehaut | gfredericks: 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:54 | gfredericks | brehaut: what operations could be reorderd? |
| 16:55 | amalloy | yeah, that's fairly implausible |
| 16:56 | brehaut | implausible or not, I'm not sure its wise to encourage people to write code outside of the guarantees of the core functions |
| 16:57 | amalloy | brehaut: 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:57 | gfredericks | it'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:59 | gfredericks | ,(split-with #(< (rand) 0.8) (range 10)) |
| 16:59 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: clojure.lang.ArityException: Wrong number of args (1) passed to: sandbox$eval27$fn> |
| 16:59 | gfredericks | gerg |
| 16:59 | gfredericks | ,(split-with (fn [_] (< (rand) 0.8)) (range 10)) |
| 16:59 | clojurebot | [() (2 3 4 5 6 ...)] |
| 17:00 | gfredericks | ^ that's when I'd like to know that pure functions are required |
| 17:02 | daniel__2 | hmm is -fn deliberate on the function name |
| 17:02 | gfredericks | not sure what you mean |
| 17:02 | daniel__2 | seems like its defined fitness-fn and called with fitness |
| 17:02 | gfredericks | oh in amalloy's code? |
| 17:02 | daniel__2 | in amalloy_'s example |
| 17:03 | gfredericks | daniel__2: I don't think he made a mistake. |
| 17:03 | gfredericks | he let's the result of fitness-fn to the name 'fitness' |
| 17:03 | gfredericks | and also uses it as the name of the argument to evolve |
| 17:03 | daniel__2 | yeah, just seen |
| 17:04 | daniel__2 | i cant see why he needed to do the let though |
| 17:05 | daniel__2 | instead of fitness-fn goal |
| 17:05 | gfredericks | you mean instead of placing the call to fitness-fn within the anonymous function? |
| 17:06 | daniel__2 | yeah |
| 17:08 | gfredericks | it 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:13 | daniel__2 | so the iterate function...it will iterate with the return value in place of % |
| 17:13 | daniel__2 | so whatever it returns goes back in again |
| 17:13 | daniel__2 | the (take (count ... line |
| 17:16 | daniel__2 | how can i implement the equivalent of ruby until |
| 17:17 | daniel__2 | until fitness > old-fitness do mutate(source) |
| 17:17 | daniel__2 | so keep trying mutations until you get a better fitness |
| 17:27 | amalloy | &(doc take-while) |
| 17:27 | lazybot | ⇒ "([pred coll]); Returns a lazy sequence of successive items from coll while (pred item) returns true. pred must be free of side-effects." |
| 17:27 | amalloy | or drop-while, either way |
| 17:29 | daniel__2 | im making my evolve recursive, is that a bad idea? |
| 17:30 | daniel__2 | actually, i dont know how that will work with the iterate |
| 17:30 | gfredericks | daniel__2: with iterate, instead of using recursion directly, you just return whatever ought to be passed in to the function the next time |
| 17:31 | daniel__2 | (take-while condition function) ? |
| 17:31 | daniel__2 | will repeat function until condition is true |
| 17:31 | daniel__2 | and then return the result of the passing function |
| 17:31 | gfredericks | not a function, a seq |
| 17:32 | gfredericks | so you could use take-while with iterate |
| 17:32 | gfredericks | ,(first (drop-while #(< % 1000) (iterate #(* 2 %) 3))) |
| 17:32 | clojurebot | 1536 |
| 17:33 | gfredericks | ,(take-while #(< % 1000) (iterate #(* 2 %) 3)) |
| 17:33 | clojurebot | (3 6 12 24 48 ...) |
| 17:34 | daniel__2 | right, hmmm |
| 17:34 | daniel__2 | this is a good brani workout |
| 17:34 | daniel__2 | brain* |
| 17:35 | gfredericks | once you get used to it, looking at imperative ruby code will make you ill |
| 17:35 | gfredericks | I guess that may or may not be a good thing |
| 17:35 | daniel__2 | thats doing something slightly different |
| 17:35 | daniel__2 | i still want to iterate over n generations |
| 17:36 | daniel__2 | but for each generation, i want to only take the fitter child |
| 17:36 | gfredericks | so you have a collection of children and you want to pick the one with the highest fitness? |
| 17:36 | daniel__2 | not really |
| 17:37 | daniel__2 | i 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:37 | daniel__2 | i have (mutate source) |
| 17:38 | gfredericks | ah, so (drop-while #(<= (fitness %) fitness-from-before) (iterate mutate this-guy)) |
| 17:38 | daniel__2 | i dont want to accept the result is (< (fitness (mutate source)) (fitness source)) |
| 17:38 | daniel__2 | if* |
| 17:38 | gfredericks | maybe remove makes more sense |
| 17:38 | gfredericks | (first (remove #(<= (fitness %) fitness-from-before) (iterate mutate this-guy))) |
| 17:41 | daniel__2 | need paren highlighting in irc :p |
| 17:43 | gfredericks | drop-while would still work there, I just like remove better for silly personal reasons |
| 17:43 | daniel__2 | just compiling for the moment of truth |
| 17:44 | daniel__2 | need to get a repl in vim |
| 17:44 | daniel__2 | this takes too long |
| 17:44 | gfredericks | daniel__2: what's your workflow? |
| 17:45 | daniel__2 | at the moment, make changes to the code, compile, execute |
| 17:45 | daniel__2 | trying small experiments in a repl |
| 17:46 | daniel__2 | would be good not to have to exit vim to compile |
| 17:46 | gfredericks | are you using leiningen? |
| 17:47 | daniel__2 | ja |
| 17:47 | gfredericks | I normally have two windows, one for the repl and one for vim. I can reload the code with (require 'some.ns :reload) |
| 17:47 | amalloy | daniel__2: why exit vim? just C-z to suspend it |
| 17:47 | daniel__2 | amalloy: thats a possibility, i just never thought of it |
| 17:48 | gfredericks | daniel__2: no reason it should take you more than a couple seconds to try out the code you wrote |
| 17:48 | daniel__2 | im getting an invalid number of arguments passed to iterate anyway :( |
| 17:48 | ghiu | how 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:49 | gfredericks | ghiu: (zipmap (map name (keys m)) (vals m)) |
| 17:49 | bdb_ | stringify-keys |
| 17:49 | bdb_ | &(doc stringify-keys) |
| 17:49 | lazybot | ⇒ "([m]); Recursively transforms all map keys from keywords to strings." |
| 17:50 | gfredericks | bdb_: that would fail his example of being not-recursive |
| 17:50 | bdb_ | as lazybot just informed me :-) |
| 17:50 | gfredericks | good ole lazybot |
| 17:50 | amalloy | (inc lazybot) |
| 17:50 | lazybot | ⟹ 0 |
| 17:50 | gfredericks | :) |
| 17:51 | ghiu | wow, thanks :D |
| 17:51 | gfredericks | yezzir |
| 17:52 | bdb_ | 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:53 | daniel__2 | i'd paste some code, but i havent got my vim working since i reinstalled my OS |
| 17:53 | daniel__2 | "+y doesnt work |
| 17:54 | daniel__2 | might be something to do with vimclojure, not sure |
| 17:55 | daniel__2 | https://gist.github.com/1274252 |
| 17:55 | napping | letters still work as names? |
| 17:56 | gfredericks | daniel__2: iterate takes two args, so something is wrong on line 22 |
| 17:56 | gfredericks | you probably meant (iterate mutate source)? |
| 17:57 | amalloy | the function passed to remove also should take an argument |
| 17:57 | ghiu | hmmm |
| 17:57 | daniel__2 | there are two args... the anon function and source |
| 17:57 | ghiu | shouldn't this work? (walk #(%1) #(%1) {:a 1, :b "23", :c '(1 2 3 {:d [:e :f]})} ) |
| 17:57 | amalloy | ghiu: no |
| 17:57 | daniel__2 | ah wait, line 22 |
| 17:57 | ghiu | stringify-keys is perfect but i need to stringify any occurrence of any key |
| 17:57 | amalloy | #(%1) is basically never what you want |
| 17:57 | gfredericks | ghiu: what do you want #(%1) to do? |
| 17:58 | napping | It 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:58 | gfredericks | ,(#(%1) #(println "HELLO!")) |
| 17:58 | clojurebot | HELLO! |
| 17:58 | amalloy | gfredericks: i want it to die in a fire |
| 17:58 | napping | Is there any better explanation of that than what I can already see by macroexpanding let? |
| 17:59 | daniel__2 | amalloy: what was wrong with the function passed to remove? |
| 17:59 | gfredericks | daniel__2: you're not using the argument anywhere |
| 17:59 | amalloy | daniel__2: it doesn't take any arguments. there's no % |
| 17:59 | daniel__2 | ah |
| 17:59 | ghiu | amalloy: i want to check every form and if it's a keyword, turn it into a string instead |
| 17:59 | amalloy | remove calls its function once on each element |
| 18:00 | icefox | s |
| 18:00 | amalloy | ghiu: just use clojure.walk/postwalk if you want a simple walk; don't rewrite it in terms of walk |
| 18:00 | daniel__2 | instead of (mutate source) it should be %? |
| 18:00 | daniel__2 | so (fitness %) |
| 18:00 | amalloy | yeah |
| 18:01 | daniel__2 | kk |
| 18:01 | daniel__2 | lets see |
| 18:01 | amalloy | and as gfredericks says you need to unwrap the args to iterate: (iterate mutate source) |
| 18:02 | daniel__2 | yeah, done that |
| 18:02 | daniel__2 | sweet, i get some kind of output |
| 18:02 | daniel__2 | need more generations :) |
| 18:02 | gfredericks | no exceptions == no bugs |
| 18:02 | ghiu | amalloy: (walk #((if (keyword? %1) (name %1) (%1))) #(%1) {:a 1, :b "23", :c '(1 2 3 {:d [:e :f]})} ) ? |
| 18:03 | gfredericks | oh boy |
| 18:03 | amalloy | that has like a hundred parens too many |
| 18:03 | daniel__2 | will be interesting to see how long it takes for 5000 generations |
| 18:03 | daniel__2 | 50 took longer than i expected |
| 18:03 | amalloy | see also ##(doc identity), ghiu |
| 18:03 | lazybot | ⇒ "([x]); Returns its argument." |
| 18:03 | gfredericks | ghiu: ask us again after you have removed exactly one hundred parens from that expression |
| 18:05 | daniel__2 | i think i want the opposite of remove |
| 18:05 | daniel__2 | or the opposite condition :/ |
| 18:05 | gfredericks | daniel__2: that's filter |
| 18:05 | daniel__2 | gets as far from hello world as its possible to get |
| 18:06 | amalloy | &(doc filter) |
| 18:06 | lazybot | ⇒ "([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:06 | amalloy | haha awesome, daniel__2 |
| 18:06 | daniel__2 | ok, thanks |
| 18:06 | amalloy | let us know what string is farthest away from hello world |
| 18:06 | daniel__2 | țȑȖǩȊȫȂșǯȽȹȓ |
| 18:06 | gfredericks | daniel__2: although it sounds like your fitness function might be backwards |
| 18:06 | amalloy | it can be the toy program people write when they stop using a language |
| 18:06 | daniel__2 | lol |
| 18:06 | gfredericks | amalloy: :-D |
| 18:07 | gfredericks | that looks like a program hiredman would write |
| 18:07 | daniel__2 | gfredericks: i've tested my fitness function, works fine |
| 18:07 | daniel__2 | this is looking better now |
| 18:09 | daniel__2 | still doesnt seem right, after 50000 generations i have dlk33ndoemgl |
| 18:10 | daniel__2 | aah, i get why |
| 18:12 | daniel__2 | when i have [& args] what are the args bound to for use inside the function? |
| 18:13 | daniel__2 | arg1 arg2? |
| 18:13 | gfredericks | the arguments are a list called args |
| 18:13 | gfredericks | ,((fn [& args] (pr-str ["My args are" args])) 7 8 :famished) |
| 18:13 | clojurebot | "[\"My args are\" (7 8 :famished)]" |
| 18:15 | gfredericks | daniel__2: this is your main function? |
| 18:15 | daniel__2 | yeah |
| 18:15 | gfredericks | you 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:15 | daniel__2 | i want to make the start args abstract so i can change them on each run |
| 18:15 | amalloy | daniel__2: you can probably save a lot of wasted compilation time by dropping the gen-class |
| 18:16 | amalloy | and then using clojure.main, which is a precompiled class in clojure.jar, as your entry point |
| 18:18 | daniel__2 | ok |
| 18:18 | amalloy | better, 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:19 | amalloy | and i only suggest changing because you were annoyed about compilation time - this is generally not a priority |
| 18:19 | daniel__2 | yes, ill try and get slime working when i get more time |
| 18:19 | daniel__2 | its 1:17am and i just want this to work so i can go to bed :/ |
| 18:20 | brehaut | daniel__2: with the emacs starter kit, slime is much easier to get going than it used to be |
| 18:20 | gfredericks | daniel__2: well then your problem is you live in a time zone where it's late. |
| 18:21 | daniel__2 | yep |
| 18:21 | brehaut | daniel__2: bookmark https://github.com/technomancy/emacs-starter-kit/ |
| 18:21 | daniel__2 | brehaut: dont want to learn emacs, would rather stick with vim |
| 18:23 | gfredericks | daniel__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:23 | daniel__2 | sure |
| 18:25 | daniel__2 | touch README |
| 18:25 | daniel__2 | oops |
| 18:25 | amalloy | hah, i smell a project about to get pushed to github |
| 18:25 | daniel__2 | lol |
| 18:26 | gfredericks | eh? what does touch README do (apart from the obvious)? |
| 18:26 | technomancy | actually slime and the starter kit are more or less orthogonal |
| 18:26 | amalloy | gfredericks: it's a step github recommends in their "how to create a repo on github" |
| 18:26 | technomancy | unless you mean the overall getting started experience is easier |
| 18:26 | gfredericks | ah ha |
| 18:27 | brehaut | technomancy: yeah the over all experience |
| 18:27 | amalloy | they don't like repos without a README, though it doesn't seem like an empty one is any better |
| 18:27 | daniel__2 | right after i install ssh itll be on there :D |
| 18:27 | amalloy | daniel__2: windows? |
| 18:27 | daniel__2 | no, arch linux |
| 18:28 | daniel__2 | i reinstalled my ubuntu and arch a couple of days ago |
| 18:28 | daniel__2 | things are still not all setup |
| 18:28 | amalloy | fascinating. i didn't think there were unix distros with ssh not installed |
| 18:28 | gfredericks | yeah that sounds pretty unhelpful |
| 18:28 | amalloy | good point, technomancy |
| 18:28 | gfredericks | technomancy: README.xml? :) |
| 18:29 | amalloy | any day now github will add support for README.clj, just you wait. then we'll have won |
| 18:29 | gfredericks | somebody start encouraging that in the java community and see if it catches on |
| 18:29 | gfredericks | amalloy: we'll have won the opportunity to escape every damn double-quote we use? :) |
| 18:29 | clojurebot | amalloy is <amalloy> just use juxt, it'll be great |
| 18:30 | daniel__2 | amalloy: arch pretty much makes you choose everything |
| 18:30 | gfredericks | (inc clojurebot) |
| 18:30 | lazybot | ⟹ 2 |
| 18:30 | daniel__2 | which for me was good, i learnt a lot |
| 18:30 | amalloy | hahaha best ever. thanks clojurebot, that was perfect timing |
| 18:30 | ghiu | amalloy: got it, thanks (postwalk (fn [x] (if (keyword? x) (name x) x)) m)) |
| 18:30 | daniel__2 | anyway, i have to go to bed https://github.com/danielstockton/evolve/blob/master/src/evolve/core.clj |
| 18:30 | daniel__2 | thanks for all your help, i will resume tomorrow evening |
| 18:31 | gfredericks | goodnight |
| 18:38 | bdb_ | README.clj is only a pull request away: https://github.com/github/markup |
| 18:38 | bdb_ | "The code we use to render README.your_favorite_markup" |
| 19:44 | icefox | Is there a list of janitor type tasks for clojurescript anywhere? |
| 19:52 | amalloy | icefox: 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:54 | ibdknox | amalloy: dude you're so dumb. |
| 19:54 | ibdknox | wait |
| 19:54 | ibdknox | so am I |
| 19:54 | ibdknox | :( |
| 19:54 | icefox | amalloy: 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:54 | amalloy | ibdknox: in fairness, i couldn't answer his question even if i did know, because i don't know much about cljs |
| 19:54 | amalloy | but perhaps some prodding will inspire the rest of the channel |
| 19:55 | icefox | really 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:55 | ibdknox | icefox: I'm not sure anyone is keeping a list updated for such things |
| 19:56 | ibdknox | icefox: the best thing you could do right now, is just use it |
| 19:56 | ibdknox | -, |
| 19:56 | icefox | yah, been poking around with it making some apps |
| 19:56 | jli | hm. 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:57 | jli | or am I doing something wrong? |
| 19:57 | jli | (yes, I know it's slow) |
| 19:57 | amalloy | jli: they are both right and both wrong, depending on what you're doing |
| 19:59 | ibdknox | jli: why do you have a seq if you need to add something to the end of it? |
| 19:59 | amalloy | though, 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:01 | jli | I start with (range), then I map over it, and then I want to add something to the end |
| 20:02 | amalloy | if you're only doing that once, concat is much better |
| 20:02 | jli | I tried doing "(vec (range ..))" but after the map, conj adds to the beginning |
| 20:03 | amalloy | indeed, because map turns it back into a lazy sequence |
| 20:03 | ibdknox | concat will keep it lazy |
| 20:07 | jli | right. okay. concat, rock. thx. |
| 20:35 | kab3wm | ibdknox: 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:43 | ibdknox | kab3wm: you can just us an if-let :) |
| 20:43 | ibdknox | kab3wm: (if-let [someval (flash-get)] (partial-with-val someval)) |
| 20:44 | kab3wm | ibdknox: cool, I'll give that a shot. thank you. |
| 23:13 | metajack | Why does (String/valueOf nil) throw an exception, but (#(String/valueOf %) nil) return "null" (Clojure 1.3)? |
| 23:22 | zodiak | metajack, 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:22 | zodiak | that would be my guess after learning clojure for a month ;) |
| 23:32 | brehaut | metajack: thats really quite surprising |
| 23:33 | symbole | Maybe (String/valueOf nil) is not calling valueOf(Object obj). |
| 23:33 | metajack | brehaut: it throws null pointer exception. from what i can tell all the other versions of valueOf take primitives |
| 23:34 | brehaut | my java is not super sharp, but i didn't think the primitive types were nullable? |
| 23:34 | brehaut | hi talios |
| 23:34 | talios | hola |
| 23:35 | symbole | brehaut: They're not. Maybe they're being set to null internally, and that's why it fails? I'm not really sure. |
| 23:37 | symbole | #() 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:37 | brehaut | symbole: its implicitly an Object if nil anyway |
| 23:38 | metajack | well in the real code i found this in, ti's a named function defined with defn, but i reproduced it with #() |
| 23:39 | brehaut | metajack: #() is expanded by the reader to a (fn […) form |
| 23:39 | brehaut | er fn* |
| 23:39 | metajack | So I don't think that particular form matters for this issue. |
| 23:41 | brehaut | metajack: indeed; it seems only that its crossing a method boundary that matters |
| 23:42 | amalloy | ,(String/valueOf nil) |
| 23:42 | clojurebot | #<NullPointerException java.lang.NullPointerException> |
| 23:42 | amalloy | ,(#(String/valueOf %) nil) |
| 23:42 | clojurebot | "null" |
| 23:42 | amalloy | $javadoc String valueOf |
| 23:42 | lazybot | http://download.oracle.com/javase/6/docs/api/java/lang/String.html#valueOf(java.lang.Object) |
| 23:44 | amalloy | so valueOf(Object) is willing to convert null to "null". the others aren't, of course, because they take primitives |
| 23:45 | metajack | So direct invocation basically picks one of the primitive versions incorrectly? |
| 23:46 | amalloy | metajack: 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:47 | amalloy | whereas 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:49 | amalloy | ,(String/valueOf ^Object nil) |
| 23:49 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: Metadata can only be applied to IMetas> |
| 23:49 | amalloy | ,(#(String/valueOf ^Integer %) nil) |
| 23:49 | clojurebot | "null" |
| 23:49 | amalloy | ,(#(String/valueOf ^int %) nil) |
| 23:49 | clojurebot | #<CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: int, compiling:(NO_SOURCE_PATH:0)> |
| 23:49 | amalloy | hmph |
| 23:50 | brehaut | ,(let [a nil] (String/valueOf a)) |
| 23:50 | clojurebot | #<NullPointerException java.lang.NullPointerException> |
| 23:50 | brehaut | ,(let [a nil] (String/valueOf ^Object a)) |
| 23:50 | clojurebot | "null" |
| 23:50 | amalloy | sure, that much is given |
| 23:51 | symbole | metajack: I think it's worth posting this quesiton to the mailing list. I'm curious what this is all about. |
| 23:51 | amalloy | i'm surprised to see that neither of metajack's original versions causes the compiler to emit reflective code |
| 23:51 | brehaut | likewise |
| 23:52 | brehaut | what is particularly odd is, it should give a more useful error if its selecting a method incorrectly based on type |
| 23:52 | brehaut | , (let [a nil] (String/valueOf ^int a)) |
| 23:52 | clojurebot | #<CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: int, compiling:(NO_SOURCE_PATH:0)> |
| 23:52 | amalloy | brehaut: 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:53 | amalloy | and discovers that the Long is nil |
| 23:54 | brehaut | but its not choosing to unbox right? theres no reflection warnings |
| 23:56 | amalloy | brehaut: 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:56 | amalloy | so the un-reflective code says "unbox this Long to a long, then call String/valueOf" |
| 23:57 | brehaut | I'm not sure i understand why it would choose to compile against the long overload |
| 23:57 | brehaut | (and incidentally, the same error occurs in 1.2) |
| 23:59 | amalloy | brehaut: i don't think it *should* compile against the long overload, but i can imagine it happening, and it would explain the issue |