2011-07-09
| 00:09 | bhenry | who is in charge of the planet clojure reader feed? |
| 00:14 | hugod | amalloy_: adding a :dev-resources-path to project.clj for the tools.jar file seems to work (as described in the readme under sun/orcale jdk) |
| 01:49 | amalloy | dnolen: i see that you're helping spread the gospel of performant clojure again :) |
| 02:31 | zodiak | hey everyone, so, quiet in here.. but.. I have to ask; what's the web frameworks for clojure ? is there a sort of rails/django/play type of mvc framework ? |
| 02:31 | talios | webnoir looks to be the new hotness |
| 02:32 | zodiak | talios: danke.. off to google I go :) |
| 02:32 | talios | zodiak: http://www.webnoir.org |
| 02:32 | zodiak | oh. even better. dankeschoen |
| 02:32 | talios | builds ontop of compojure, which itself is a webframework, webnoir is more higher level |
| 02:33 | amalloy | zodiak: noir is the new hotness, but it's pretty amazing how easy it is to work with the lower-level tools like ring, compojure, and hiccup |
| 02:33 | zodiak | perhaps a bad question but, I am coming from a smalltalk/ruby/scheme/perl background.. does clojure more closely follow scheme with minimal syntax or common lisp with 4000+ methods ? :) |
| 02:34 | talios | amalloy: heh, noir is just ring/compojure/hiccup by the looks of it |
| 02:34 | zodiak | amalloy: looking at it now.. webnoir I mean.. seems to be fairly grokable :) |
| 02:34 | amalloy | zodiak: some of both |
| 02:34 | zodiak | amalloy: more names to google. thank you (honestly :) |
| 02:35 | zodiak | amalloy: as long as it's not as "bad" as CL .. that's a good thing :D |
| 02:35 | amalloy | clojure's "syntax" is pretty minimal, but it has more built-ins than scheme (not really the same thing as syntax) |
| 02:35 | talios | zodiak: noir etc. arn't fullstack tho, so theres no ActiveRecord like thing built in. |
| 02:35 | amalloy | talios: no? i thought that's what noir was supposed to do. i haven't looked into it |
| 02:35 | zodiak | talios aah. I was going to ask at some point about "orm" (I know you can't really have the O part but, you get the point) |
| 02:36 | zodiak | I take it the channel is "newb friendly" ? |
| 02:36 | talios | amalloy: not that I've seen. but if you adding clojureql shouldn't be hard |
| 02:37 | amalloy | zodiak: we only murder one in ten new users. you seem to have survived so far, so you're probably safe |
| 02:37 | zodiak | good show ;) |
| 02:37 | talios | zodiak: http://www.clojureql.org - it's not an ORM, but a nice liibrary/framework for querying/working with dbs |
| 02:38 | zodiak | talios: reading the examples. the syntax looks horribly clean :) awesome. |
| 02:38 | talios | amalloy: yes but me maim three out of five people who ask annoying questions :) |
| 02:40 | zodiak | last annoying newb question (promise) is clojure's performance "good" (I know, that's a very subjective question but, it's faster than python/ruby I assume since it's a jvm language) |
| 02:46 | Scriptor | does doing new File() in Java do any actual IO, or does only happen when you call some method on it? |
| 02:47 | Scriptor | couldn't find anything about joining paths in clojure, so just looking at the java way of doing it |
| 02:47 | amalloy | Scriptor: no io |
| 02:48 | Scriptor | yay |
| 02:49 | talios | zodiak: Id say faster but that kinda depends on what you're doing isn't it :) |
| 02:49 | zodiak | talios: oh. totally. I know it's subjective, as long as it's not the slowest kid in the class, it's all good I guess :D |
| 02:51 | talios | if there's methods you really need to optimize you can give type hinting to your methods which make things more porformant, I think thats improved a lot already in 1.3 as well |
| 02:55 | seancorfield_ | sorry for the constant part/join - the network here is *^%^$ |
| 03:09 | amalloy | zodiak: clojure in general is pretty fast. things which can be quite slow if you do them the "easy way" are interop (calling non-clojure java code) and arithmetic. |
| 03:10 | amalloy | but if you find out that's your bottleneck (and you care), you can add annotations to the source to make that faster without having to restructure anything. bug dnolen about it, he loves to show off how fast clojure can be |
| 03:15 | hiredman | I'm going crazy looking for a screenshot I took of a tweet were a guy said something like "people like hiredman are not helping clojure catch on" (since someone was asking about newbie friendliness) and which all my logging, etc, I can't find the stupid thing |
| 03:18 | amalloy | people like hiredman are not helping clojure catch on |
| 03:18 | amalloy | maybe use that as a substitute? |
| 03:19 | hiredman | http://www.thelastcitadel.com/_media/clojure.png?cache=cache <-- I did find some early work on a clojurebot logo |
| 03:21 | hiredman | I know for a fact I had this thing, where did it go, it's not like I ever delete anything |
| 03:28 | amalloy | hiredman: hah, that's hilarious |
| 03:33 | amalloy | ibdknox: you around? |
| 03:33 | ibdknox | amalloy: sup? |
| 03:34 | amalloy | i'm finding it pretty hard to modify the starter bot, because everything depends on this global *game-state*. specifically, i'd like to update the state every time i move an ant, so that they don't think a space is empty anymore if another ant is on his way there |
| 03:35 | amalloy | i guess i can create a local copy of it, then create a new (binding) preparatory to every call into the starter kit |
| 03:36 | ibdknox | I did it by adding in an ant tracker |
| 03:36 | ibdknox | because beyond just knowing if a space is taken I wanted to be able to uniquely ID an ant so I can give it a role |
| 03:36 | ibdknox | that's not included in the starter thing because they explicitly state they don't want it to be lol |
| 03:36 | amalloy | sure |
| 03:37 | amalloy | but do you have an objection to having most of the starter-kit functions accept an (optional?) explicit state argument, rather than depend on a global? |
| 03:37 | amalloy | incidentally, you don't need to uniquely ID ants in order to give them roles |
| 03:38 | ibdknox | no? |
| 03:38 | ibdknox | how's that? |
| 03:38 | amalloy | you can have a map of {location => role} pairs, which you match against the ants when you read them, and update when you move them |
| 03:39 | amalloy | i imagine your tracker works similarly, except you store {location=>id} |
| 03:39 | amalloy | and have an additional {id=>role} map |
| 03:39 | ibdknox | yep |
| 03:39 | amalloy | that might be better, so that you can have a role like "hang out with ant 43", but it seems more complicated |
| 03:40 | ibdknox | it's stupid simple, but that also means it's stupid ;) |
| 03:41 | ibdknox | btw |
| 03:41 | ibdknox | the only reason I did it the way I did was because they wanted the packs to be similar |
| 03:41 | ibdknox | I originally wrote it such that the bot was passed a map of the state |
| 03:41 | ibdknox | and you just worked with that directly |
| 03:41 | ibdknox | I think that might be the better solution overall |
| 03:42 | ibdknox | the bot being the function you pass to start-game |
| 03:42 | amalloy | right |
| 03:42 | ibdknox | thoughts? |
| 03:42 | ibdknox | I can make that change on the grounds that it's more idiomatic |
| 03:43 | amalloy | well, i'd write it the way you first did |
| 03:43 | amalloy | but it boils down to adding a (state) argument to pretty much every function in ants.clj |
| 03:43 | ibdknox | it would actually get rid of most of the functions entirely |
| 03:43 | amalloy | so perhaps in the interests of more-easily modeling state it's better to bind it |
| 03:44 | amalloy | ibdknox: well, maybe. i think a lot of them are good to have around as sort of an API to the map, so you don't have to know what it contains if you don't want |
| 03:44 | ibdknox | fair enough |
| 03:45 | ibdknox | water makes it slightly more complicated too |
| 03:45 | ibdknox | since it's not given every time |
| 03:45 | ibdknox | though, not any real complexity there |
| 03:46 | ibdknox | completely unrelated, my 7 line bot is doing stupidly well |
| 03:46 | ibdknox | lol |
| 03:46 | amalloy | ibdknox: i improved the performance by switching (first) to (rand-nth) :P |
| 03:46 | ibdknox | haha |
| 03:46 | ibdknox | here's what the one I submitted is doing |
| 03:47 | amalloy | ibdknox: but the server still doesn't run clojure bots correctly, does it? i'm curious how you submitted it in that case |
| 03:47 | ibdknox | https://gist.github.com/1073423 |
| 03:47 | ibdknox | I put it all in a single file |
| 03:47 | amalloy | idea stealer! |
| 03:47 | ibdknox | it was annoying |
| 03:47 | ibdknox | but it works :-p |
| 03:47 | ibdknox | haha |
| 03:48 | ibdknox | implemented it first ;) |
| 03:49 | ibdknox | amalloy: oh, something I found out and need to change in the starter thing: you can move on top of food. |
| 03:49 | ibdknox | err |
| 03:49 | ibdknox | can't* |
| 03:50 | amalloy | i don't see that mattering. does food spawn right next to you, and then only hatch after you've moved? |
| 03:54 | ibdknox | well if you're next to it and you're trying to move to it, it will count as an invalid move |
| 03:54 | ibdknox | enough of those and you end up disqualified |
| 03:54 | amalloy | ibdknox: but you shouldn't be next to it, is my point, since it should hatch when you get there |
| 03:54 | amalloy | unless it behaves as i suggedted above |
| 03:54 | ibdknox | it hatches the next turn |
| 03:56 | hiredman | it would be interesting to do it cps style for co-operative multitasking |
| 03:58 | amalloy | oh, yikes. the the :ants key is a seq of locations |
| 03:59 | amalloy | that makes it pretty tough to change the state to no longer include an ant |
| 04:03 | ibdknox | hm, it's a seq? I must've screwed something up.. it should be a set |
| 04:04 | amalloy | ibdknox: oh, sorry then |
| 04:04 | amalloy | i didn't read closely; i'm sure you're right |
| 04:07 | amalloy | ibdknox: if you're interested i wrote up https://gist.github.com/ea397d8052c71fefbb4b as an example of keeping two ants from moving into the same square at once |
| 04:09 | ibdknox | amalloy: cool! I just made a change to make passable? take other ants into account, since everywhere I kept having to do (unoccupied? (passable? loc)) |
| 04:10 | amalloy | (def okay-move? (comp unoccupied? passable?)) :P |
| 04:10 | ibdknox | haha |
| 04:11 | amalloy | ibdknox: do you know how to get debug information about a crash? every five or ten games my bot gets marked as "crashed" at some point |
| 04:13 | ibdknox | this works for me: |
| 04:13 | ibdknox | (defn run [] |
| 04:13 | ibdknox | (try |
| 04:13 | ibdknox | (start-game my-bot) |
| 04:13 | ibdknox | (catch Exception e |
| 04:13 | ibdknox | (.printStackTrace e)))) |
| 04:13 | ibdknox | it seems if you explicitly print the trace it ends up in the output |
| 04:14 | amalloy | ibdknox: in what output? |
| 04:14 | ibdknox | when you run ./test_bot or ./play_one_game it lists all the turn info |
| 04:14 | ibdknox | it shows up there |
| 04:14 | ibdknox | as it runs |
| 04:14 | amalloy | oh. i guess their engine is swallowing stderr |
| 04:15 | amalloy | but not stdout. weird choice, imo, but what do i know |
| 04:15 | ibdknox | something to do with the way the sandbox works? |
| 04:15 | ibdknox | I have no idea |
| 04:16 | ibdknox | you might have to run it with the same flags as test_bot has too... I can't remember |
| 04:17 | ibdknox | the whole thing could use some help to be honest lol |
| 04:17 | amalloy | --strict --capture_errors |
| 04:17 | ibdknox | yeah |
| 04:17 | ibdknox | strict will list out invalid moves and such |
| 06:37 | trochala | Hello, I am reading the Joy of Clojure book, and it suggests installing cljr from github.com/fogus/cljr. |
| 06:38 | trochala | This repo doesn't exist but seems to have moved to https://github.com/liebke/cljr. |
| 06:39 | trochala | I can see that the last commit is one year ago. I wanted to ask if the project is outdated and if I should use some other repl package |
| 06:40 | schasi | trochala: I am also new, but I think installing it from lein is a good idea |
| 06:40 | schasi | Even though I'd like to know what the proes here have to say about it :D |
| 07:02 | rbuchmann | Hey, quick question: What git mode, if any, do you prefer for emacs and why? |
| 07:07 | rbuchmann | I had a look at magit, but I'm not sure I like it |
| 07:54 | lnostdal-laptop | emacs and swank-clojure-1.6+ users; does evaluating (future 42) work in your repls? |
| 07:55 | bsteuber | you mean leiningen-1.6+ |
| 07:55 | lnostdal-laptop | ah, yeah |
| 07:55 | lnostdal-laptop | i mix the numbers |
| 07:55 | bsteuber | me too :) |
| 07:56 | lnostdal-laptop | to be exact, i'm using swank-clojure-1.4.0-SNAPSHOT (from git) .. and leiningen-1.6.1 from git |
| 07:56 | lnostdal-laptop | ..and futures doesn't work.. |
| 07:57 | lnostdal-laptop | "Task java.util.concurrent.FutureTask@3a70dd47 rejected from java.util.concurrent.ThreadPoolExecutor@5e3c782[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 2" |
| 07:58 | bsteuber | same for me still |
| 07:58 | bsteuber | strange technomancy couldn't reproduce it |
| 07:58 | lnostdal-laptop | ok, yeah, i even updated clojure-mode to make sure |
| 07:58 | lnostdal-laptop | ..though i guess that should be unrelated |
| 07:58 | lnostdal-laptop | ..what version of emacs, bsteuber ? |
| 07:58 | bsteuber | 24 |
| 07:59 | bsteuber | but that should really not matter |
| 07:59 | lnostdal-laptop | 24.0.51.1 .. same .. but, yeah, indeed |
| 07:59 | lnostdal-laptop | i'm using jvm7 tho |
| 07:59 | bsteuber | hmm |
| 08:00 | lnostdal-laptop | (System/getProperty "java.version") => "1.7.0" |
| 08:00 | bsteuber | yeah it's really a mystery to me |
| 08:00 | lnostdal-laptop | maybe he's forgotten to push some patches .. that does happen :} |
| 08:01 | bsteuber | just sticking to lein 1.5.2 and getting things done for now |
| 08:02 | lnostdal-laptop | so ...anyone else seeing the same thing besides bsteuber and me? |
| 08:05 | lnostdal-laptop | and another question; what coding style does people use for global variables now in 1.3.x seeing as globals aren't dynamic by default anymore? |
| 10:04 | b6n | Can someone tell me how I can transform a data structure like [[:foo 1] [:bar 2]] into {:foo 1 :bar 2} ? |
| 10:05 | dnolen_ | ,(into {} [[:foo 1] [:bar 2]]) |
| 10:05 | clojurebot | {:foo 1, :bar 2} |
| 10:05 | dnolen_ | b6n: ^ |
| 10:06 | b6n | oh it's so easy?! thanks a lot |
| 10:14 | vdrab | Hi all. what is the idiomatic way to do buffered reads from standard input in clojure? |
| 10:15 | vdrab | duck-streams? clojure.java.io? |
| 10:16 | vdrab | java BufferedReader? java InputStream? |
| 10:23 | fliebel | vdrab: i'd say (clojure.java.io/reader *in*) should do. |
| 10:24 | fliebel | &(class *in*) |
| 10:24 | sexpbot | ⟹ clojure.lang.LineNumberingPushbackReader |
| 10:24 | vdrab | fliebel: thanks! |
| 10:25 | fliebel | vdrab: Maybe skip the reader part, and just wrap *in* in a buffered reader from java.io |
| 10:25 | vdrab | is this also considered the most performant way to read streams? (elegance and all aside) |
| 10:27 | fliebel | I wouldn't know. Maybe you can get stdin from javaland without the pushback stuff. |
| 10:27 | fliebel | &System.in |
| 10:27 | sexpbot | java.lang.ClassNotFoundException: System.in |
| 10:28 | vdrab | &System/in |
| 10:28 | sexpbot | ⟹ #<BufferedInputStream java.io.BufferedInputStream@1f5a6f9> |
| 10:28 | fliebel | well, there you go :) |
| 10:28 | vdrab | thanks |
| 10:29 | vdrab | and wrap this in a line-seq? |
| 10:32 | vdrab | "(println (line-seq (clojure.java.io/reader *in*)))" gives me around 11mb/sec throughput on my little macbook |
| 10:36 | vdrab | can you think of any obvious ways to improve upon this? |
| 10:38 | Scorchin | so has anyone got any guesses on what the july 20th announcement is? |
| 10:41 | Scriptor | nope, I'm still too bummed about not being in the city then |
| 10:42 | dnolen_ | Scorchin: I'm betting compiler related. |
| 10:42 | Scorchin | dnolen_: anything specific? |
| 10:43 | Scorchin | clojure in clojure would be nice |
| 10:44 | Scorchin | can then make a clojure in JS runner |
| 10:47 | dnolen_ | Scorchin: I'm thinking it'll be something along those lines. When I gave my preso on Logic programming at the NYC Clojure Meetup a while back, he mentioned he had new ideas for the compiler. Also to allow libraries to provide typechecking the compiler really needs to provide some kind of hook which doesn't exist right now. |
| 10:48 | Scriptor | hmm, I didn't overhear anything special from him at the last meetup, so that may be it |
| 13:40 | chouser | dnolen_: I didn't think you'd have to guess |
| 13:41 | dnolen_ | chouser: heh, I don't have any inside knowledge :) |
| 13:54 | ataggart | dnolen_: What were the companion books to The Reasoned Schemer you mentioned? I'm not able to google it up. |
| 13:55 | ataggart | dnolen: same question ^ |
| 14:39 | dnolen_ | ataggart: Bratko's Prolog book, Sterling & Shapiro Prolog book, Byrd's thesis http://pqdtopen.proquest.com/#abstract?dispub=3380156 |
| 14:40 | ataggart | thx |
| 15:47 | arohner | I have an arrow that looks like (-> foo (bar) (.trim)) |
| 15:47 | arohner | where .trim is being called on a string. How do I add a type hint there to avoid reflection? |
| 15:53 | arohner | I guess I can do the fn trick |
| 15:53 | dnolen_ | ,(do (set! *warn-on-reflection* true) (-> "foo" identity (.trim))) |
| 15:53 | clojurebot | java.lang.IllegalStateException: Can't change/establish root binding of: *warn-on-reflection* with set |
| 15:54 | dnolen_ | (-> "foo" ^String (identity) (.trim)) |
| 15:54 | dnolen_ | ^ works |
| 15:54 | arohner | aha! |
| 15:54 | arohner | dnolen: thanks |
| 15:57 | dRbiG | can anyone give me some 'classic' situation/problem when macros come really really handy? |
| 15:58 | AWizzArd | dRbiG: when developing a DSL |
| 15:59 | arohner | dRbiG: with-open |
| 15:59 | arohner | ,(doc with-open) |
| 15:59 | clojurebot | "([bindings & body]); bindings => [name init ...] Evaluates body in a try expression with names bound to the values of the inits, and a finally clause that calls (.close name) on each name in reverse order." |
| 15:59 | AWizzArd | For nearly every lib you will probably want to have one macro that offers a little DSL. |
| 15:59 | dnolen_ | dRbiG: day to day boilerplate is a big use case. |
| 16:02 | Chousuke | macros are a potential solution whenever you feel like you're writing repetitive code |
| 16:02 | dRbiG | right.\ |
| 16:02 | dRbiG | the with-open example would be a block in ruby |
| 16:03 | chouser | though closures do a pretty impressive job there too |
| 16:03 | Chousuke | Yes, the first approach should of course be a design that doesn't force you to write repetitive stuff, but whenever that's not possible (or feasible) macros help |
| 16:04 | paraseba | dRbiG: ruby block would be similar to passing a clojure function to with-open. Macros give you the extra syntactic sugar, so you don't need to wrap everything in (fn ...) |
| 16:04 | dRbiG | so lets consider: i want o bind a set of x-foo variables to results of (.foo bar) - i guess i can do it nicely with a macro? |
| 16:04 | Chousuke | sure |
| 16:04 | bsod1 | clojure repl funcitons like dir, doc, javadoc, pprint etc. are not included in `lein swank`, right? with `lein repl` I can use it but in SLIMV repl, I can't.. |
| 16:05 | arohner | bsod1: they're there, but you might have to 'use' them first to get them into your user namespace |
| 16:05 | bsod1 | arohner: thanks, that's what I was wondering.. |
| 16:05 | arohner | (use '[clojure.pprint :only (pprint)]) |
| 16:06 | arohner | etc |
| 16:06 | arohner | look in clojure.repl, and clojure-contrib.repl-utils |
| 16:16 | dnolen_ | bsod1: it also useful when you're building a fairly involved embedded paradigm, the results from macro transformation in core.logic are pretty intense. |
| 16:16 | dnolen_ | oops, dRbiG ^ |
| 16:20 | dnolen_ | dRbiG: https://gist.github.com/1073927 |
| 16:22 | dRbiG | defne - ? some pattern maching defn? |
| 16:22 | dnolen_ | dRbiG: it's basically Prolog. |
| 16:23 | dnolen_ | but yes, that pattern matching via unification. |
| 16:24 | dRbiG | interesting. pattern matching and currying is always useful |
| 16:25 | dnolen_ | dRbiG: these macros are all about controlling names, binding, scope, etc. stuff that's hard to w/o macros. |
| 16:33 | amalloy | dRbiG: as a matter of interest, you might like to see how it's possible to implement (let ...) as a macro layered over (fn ...) |
| 16:36 | dRbiG | i think i've seen that somewhere already |
| 16:38 | amalloy | well, https://gist.github.com/1073943 if you want |
| 16:42 | arohner | is http://dev.clojure.org/jira/browse/CONTRIB the right place for an issue in clojure/java.jdbc? |
| 16:44 | amalloy | arohner: i don't think so. lemme check |
| 16:45 | amalloy | arohner: http://dev.clojure.org/jira/browse/JDBC |
| 16:45 | arohner | similarly, I don't see a "new" style project for c.c.zip-filter and c.c.zip-filter.xml. Are they supposed to have one? |
| 16:46 | dRbiG | right, now i have a really stupid question: how do i get length of *command-line-args*? :S |
| 16:46 | amalloy | &(doc count) |
| 16:46 | sexpbot | ⟹ "([coll]); Returns the number of items in the collection. (count nil) returns 0. Also works on strings, arrays, and Java Collections and Maps" |
| 16:47 | dRbiG | thanks. i find the lack of common agreement on verbs a major inconvenience ;) |
| 16:47 | dRbiG | hmm, actually now i realise it's verbs vs. nouns |
| 16:49 | amalloy | dRbiG: indeed. java has .length and .size - verbs with noun-names :P |
| 16:49 | arohner | dRbiG: ideally, in a lisp (or any FP language), all function calls are verbs |
| 16:50 | dRbiG | my 'code'base is mostly ruby now, so length is indeed my first idea |
| 16:51 | arohner | chouser: what's the plan with zip-filter.xml and "new" contrib projects? I have a bug in zip-filter.xml; there needs to be a small tweak in tag= to make it work with your new data.xml |
| 16:52 | arohner | chouser: in tag=, need to swap ((zip/node %) :tag) for (:tag (zip/node %)) |
| 16:52 | dRbiG | though it makes sense not to think about length/size as a noun-property of things that can be infinite |
| 16:53 | arohner | dRbiG: right, sometimes it's not a property, which is why it's a verb |
| 16:53 | wilfredh | so, I read that Clojure's let behaves like Scheme's let*, so is there a Clojure equivalent of Scheme's let? Would it be useful? |
| 16:54 | arohner | dRbiG: I also like count because length implies a 1D view of things that isn't entirely appropriate for e.g. sets |
| 16:54 | dRbiG | arohner: good point there |
| 16:55 | zakwilson | I have never wanted let from CL/Scheme in Clojure, and usually prefer let* in those languages. |
| 16:59 | amalloy | wilfredh: the equivalent is easy with destructuring, but there's not much need for it, and you don't get the (mild) performance benefits |
| 17:00 | amalloy | &(let [a 1, b (inc a)] (let [[a b] [b (inc a)] [a b])) |
| 17:00 | sexpbot | java.lang.IllegalArgumentException: let requires an even number of forms in binding vector |
| 17:00 | amalloy | &(let [a 1, b (inc a)] (let [[a b] [b (inc a)]] [a b])) |
| 17:00 | sexpbot | ⟹ [2 2] |
| 17:00 | amalloy | the first let creates some bindings, and the second uses destructuring to assign in parallel |
| 17:01 | keithwyss | Hey everybody. I just noticed the other day that on the clojure.org/api pages for the xml and lazy-xml libraries there are a few pubic functions that aren't listed until you view the source. The emit methods are public, but not listed. Also lazy-xml/attributes. |
| 17:01 | keithwyss | Is this something that should be changed, or is using those functions discouraged for some reason? |
| 17:06 | sean_corfield | mornin' :) |
| 17:07 | sean_corfield | i'm looking at some clojure code (that i didn't write) and it has (swap! some-atom (fn [_] val)) - isn't that equivalent to (reset! some-atom val) ? |
| 17:07 | sean_corfield | would there be any reason to use swap! here rather than reset! ? |
| 17:07 | amalloy | sean_corfield: maybe it's an effort to make the reader cry |
| 17:09 | dRbiG | and another question, i've got a function that takes two arguments - can i expand a thing like *command-line-args* so i won't have to do (first ...) (second ...) on it? |
| 17:09 | paraseba | sean_corfield: I've seen the same thing several times, and always ask me why. I don't have an answer yet |
| 17:10 | arohner | dRbiG: you could let destructure it |
| 17:10 | dRbiG | i want the shortest way to do it |
| 17:10 | paraseba | sean_corfield: or the other form: (swap! x (constantly ....)) |
| 17:11 | dnolen_ | ,(let [*args *[1 2 3] [a1 a2 a3] *args*] [a1 a2 a3]) |
| 17:11 | clojurebot | java.lang.IllegalArgumentException: let requires an even number of forms in binding vector |
| 17:11 | arohner | dRbiG: (defn foo [[first_arg second_arg] :as cmd-line-args] ...) |
| 17:11 | dnolen_ | ,(let [*args* [1 2 3] [a1 a2 a3] *args*] [a1 a2 a3]) |
| 17:11 | clojurebot | [1 2 3] |
| 17:12 | dRbiG | right, so :as seems to be the magic here |
| 17:12 | arohner | dRbiG: http://clojure.org/special_forms |
| 17:12 | arohner | look at let |
| 17:13 | dRbiG | i admit i haven't read all the docs so sorry in advance for questions that are already answered there - i'll try to look first though :) |
| 17:14 | paraseba | sean_corfield: I think I read somewhere, probably in JoC that you should try to use swap!, without major explanations. And, for instance, fogus unk library uses the (swap! x (constantly form |
| 17:14 | arohner | reset! is the right thing to use in that case. it's explicitly what it's designed for |
| 17:15 | amalloy | yes, you should use swap! because your functions shouldn't be (constantly ...). if they are, you should use reset!, not least because it makes you question your approach |
| 17:16 | paraseba | amalloy: I see... |
| 17:18 | amalloy | if you change a mutable value in a way that ignores its current value, you're not managing state very well. there are exceptions to that rule, which is why we have reset! |
| 17:20 | paraseba | yes, initialization for instance, when you already know for sure the current value |
| 18:08 | chouser | arohner: that change makes sense to me |
| 18:08 | chouser | But I don't know anything about plans. I've been told not to commit to old contrib anymore, but I haven't heard anything about zip-filter being included in the new contrib. |
| 18:09 | arohner | hrm. It should remain "alive" |
| 18:09 | arohner | I |
| 18:09 | arohner | I'm currently mapping over all of wikipedia's XML dump with it |
| 18:10 | chouser | It seems to me someone who has the authority to create new-contrib projects should say which will be included (eventually, even) and which will not. Those that will not should be "released" from the |
| 18:10 | chouser | from the Clojure project so authors can take ownership of them themselves. |
| 18:11 | amalloy | hey chouser, since we're on the topic, did you get my github message about prxml? |
| 18:11 | arohner | right |
| 18:11 | chouser | I think that technically the copyright would allow authors to do that now, but it seems a bit rude. |
| 18:11 | ibdknox | What exactly is the motivation for removing the contrib libraries? |
| 18:11 | chouser | amalloy: I did. Did you see my response? |
| 18:11 | amalloy | apparently not |
| 18:11 | amalloy | my inbox is regrettably still empty |
| 18:13 | amalloy | ibdknox: they're too monolithic. to get one function for parsing xml, you need to depend on a jar with a bazillion unrelated .clj files |
| 18:13 | amalloy | (that is, the motivation is that there is "a contrib library", not "contrib libraries") |
| 18:13 | ibdknox | ah |
| 18:13 | ibdknox | makes sense |
| 18:14 | ibdknox | amalloy: unrelated, they seem to have finally merged my changes into the aichallenge, I think we can have more than one file now ;) |
| 18:14 | amalloy | oh cool |
| 18:15 | amalloy | huh. i seem to have chosen *not* to follow/fork either your repo or theirs, ibdknox. strange decision |
| 18:15 | ibdknox | lol |
| 18:18 | dRbiG | another question probably answered somewhere in the manual: how do i define a global value? i don't like the idea of passing stuff all the way down |
| 18:18 | amalloy | ibdknox: http://aichallengebeta.hypertriangle.com/starter_packages.php doesn't list it yet, so i gather there's some lag between the git repo and actual reality |
| 18:18 | ibdknox | amalloy: I'll keep an eye on it and let you know when it works :) |
| 18:19 | ibdknox | dRbiG: just define it at the top of your file? (def my-const 302) |
| 18:19 | amalloy | dRbiG: (a) use def or defn; (b) you'd be amazed how much you can do with just lets and lambdas (that is, anything). see www.4clojure.com as an example of a problem-solving site that doesn't allow any defs |
| 18:20 | sean_corfield | amalloy paraseba thanx for the input on swap! / reset! |
| 18:25 | dRbiG | def doesn't do it ("java.lang.Exception: Unable to resolve symbol:") - btw i actually want a constant, not a variable :) |
| 18:26 | dnolen_ | dRbiG: 1.3.0-beta1 supports (def ^:const foo bar) |
| 18:26 | ibdknox | dRbiG: what was your line? |
| 18:28 | amalloy | dRbiG: everything's (basically) a constant already, with the immutable data structures |
| 18:28 | dRbiG | ibdknox: you mean the exception line? |
| 18:28 | dnolen_ | oops I mean (def ^:constant foo bar) |
| 18:28 | ibdknox | dRbiG: your def line that you said doesn't work? |
| 18:29 | dRbiG | (def root ".") for example |
| 18:29 | dRbiG | i guess |
| 18:29 | amalloy | dRbiG: well that will work for sure |
| 18:30 | dRbiG | the problem is in the other part |
| 18:30 | ibdknox | ? |
| 18:30 | dRbiG | i'm trying to use it in def - proxy - let |
| 18:30 | amalloy | ibdknox: the value he's assigning to the def'd var is an invalid expr |
| 18:31 | ibdknox | ah, I see |
| 18:34 | paraseba | sean_corfield: do you have any thoughts on how we should test c.j.jdbc? would you use mocking or a real (maybe embedded) database? |
| 18:38 | dRbiG | right, all is needed is a forward declaration :) |
| 18:39 | mdeboard` | I'm teaching myself Clojure, have a strong Python background but very little formal CS education, so this question might be stupid. When using the word "lazy" in Clojure, e.g. "...`for` returns a lazy `seq` whereas `doseq` is for generating side effects..." (Joy of Clojure) is this the same concept as generator functions/expressions in Python? Or even (forgive me, I know this is far afield) Django QuerySets? |
| 18:39 | dRbiG | i'd say it |
| 18:39 | dRbiG | is |
| 18:40 | mdeboard` | I feel like it is at first blush but I don't want to have a misconception already |
| 18:41 | pdk | you could look at it that way |
| 18:41 | mdeboard` | Ah, "Most of the sequence library functions are lazy, i.e. functions that return seqs do so incrementally, as they are consumed, and thus consume any seq arguments incrementally as well." http://clojure.org/sequences |
| 18:42 | pdk | (for [i (range 5)] (- 1)) would give you a lazy sequence that contains (0 -1 -2 -3 -4) |
| 18:42 | mdeboard` | That's about the same as Python generators (I understand there are other differences) |
| 18:42 | dnolen_ | mdeboard`: generators in Python are not very functional if I'm not mistaken tho right? they are stateful no? |
| 18:42 | pdk | doseq always returns nil so it's intended just for producing side effects like printing and i/o on each step of the loop |
| 18:42 | amalloy | pdk: if you use (- i) instead of (- 1), anyway :P |
| 18:42 | pdk | well |
| 18:43 | pdk | that's true |
| 18:43 | pdk | criminy! |
| 18:43 | pdk | so say if i wanted to print out each value in a sequence on a line |
| 18:43 | pdk | (doseq [i mysequence] (print i)) |
| 18:44 | mdeboard` | dnolen_: Yes to the fact they're stateful |
| 18:44 | dnolen_ | mdeboard`: that makes a fairly big difference. |
| 18:44 | mdeboard` | but they ar ea part of Python's functional paradigm |
| 18:45 | pdk | you could picture something like a function closed over a ref as an analogy for python generators |
| 18:45 | mdeboard` | dnolen_: I see what you mean. I'm not used to thinking about state (at least in some explicit way) |
| 18:47 | amalloy | the same underlying mechanism fuels clojure's lazy-seqs and python's generators, but clojure exposes it with a much more functional api |
| 18:49 | dnolen_ | amalloy: is that true? yield is more like continuations I thought. |
| 18:50 | ibdknox | Iterators in C# and VB work similarly, though they also keep state |
| 18:52 | mdeboard` | One other thing I'm getting hung up on while reading Joy of Clojure (and other docs) is the notion of "side effects." What I *think* that means is that a function does one thing -- yields a value -- but does not in the course of its operation do anything else. Can someone give me a practical/real world & as simple an example as possible? I've seen references that IO ops are an example of a side effect, but afraid I a |
| 18:52 | mdeboard` | m not making a connection. |
| 18:52 | amalloy | dnolen_: there's not really a big difference. you can implement "yield" as "return a value/thunk pair", with the python runtime building the thunk for you. that's pretty much the same as how lazy-seq works, no? |
| 18:54 | ibdknox | mdeboard`: pure functions take a value in and return a value out, nothing else happens. The notion of side effects is when a function changes something outside of itself. |
| 18:55 | dnolen_ | mdeboard`: Are you asking how it's possible to do something useful w/o side-effects? :) |
| 18:55 | mdeboard` | dnolen_: No, not at all. |
| 18:55 | dnolen_ | ,(print "foo") |
| 18:55 | clojurebot | foo |
| 18:55 | mdeboard` | dnolen_: I'm asking for a practical example of side effects because I am having trouble coming up with a context |
| 18:55 | dnolen_ | mdeboard`: print doesn't return a useful value, it's IO |
| 18:56 | mdeboard` | ibdknox: Yeah, I get the general idea I guess, looking for a practical example. |
| 18:56 | mdeboard` | dnolen_: Hm, so, ... hang on. |
| 18:57 | mdeboard` | dnolen_: e.g. http://p.mattdeboard.net/clos.html, line 4, the println? I put it in there just to see what was going on in internals. Is that an exampel of a side effect? |
| 18:58 | dnolen_ | mdeboard`: yup. |
| 18:59 | ibdknox | mdeboard`: here's a practical example: I have a function to create users for my website. My first implementation simply takes in a name and password and returns back a map with an ID added and the password hashed. This implementation is currently free of side effects. I provide input and it gives me an output. |
| 18:59 | mdeboard` | Maybe it's tough for me to contextualize because it's strongly discouraged to have side effects in Python functions. Or, at least, I always try to avoid it since it makes code gross, unwieldy and hard to read/maintain. |
| 19:00 | ibdknox | mdeboard`: that's not very useful though, because I haven't stored it somewhere. In my real implementation I add a line to my function that then stores that map in a database. |
| 19:00 | mdeboard` | Ahhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh! |
| 19:00 | mdeboard` | ibdknox: Now I see |
| 19:00 | ibdknox | mdeboard`: now I have a side effect. If I were to create the same user 20 times, I would have the same user in my DB 20 times. Whereas with the pure function I could do it a million times and it wouldn't matter. :) |
| 19:00 | dnolen_ | mdeboard`: changing the contents of shared dictionary inside of a function - mutation - is also a side-effect. |
| 19:01 | mdeboard` | Interesting. |
| 19:01 | dnolen_ | mdeboard`: your ability to reason about your program just went out the window. |
| 19:03 | dnolen_ | add some concurrency and you have a real mess. |
| 19:03 | mdeboard` | dnolen_: I don't understand that either, though I think that's just because I'm "too close" to Python. It's like being an abused wife. Too close to the situation to recognize how effed up it is. |
| 19:04 | dnolen_ | mdeboard`: the reason people hate mutable globals is because they decrease your ability to reason about your program. Who knows who changed what where? |
| 19:04 | ibdknox | to be fair, side effects aren't bad, per se |
| 19:04 | ibdknox | just they have to be monitored intelligently |
| 19:04 | ibdknox | and used carefully |
| 19:04 | dnolen_ | mdeboard`: but even local state changes are hard to keep in your head. |
| 19:05 | mdeboard` | dnolen_: re; local state changes, agree completely. Though I am having trouble reasoning through clojure recursion and looping. |
| 19:05 | dnolen_ | mdeboard`: so Clojure datastructures are immutable, you can't never change anything without it flowing in a functional manner through your code. That is not w/o resorting to the various tools for managing state change. |
| 19:05 | dnolen_ | mdeboard`: recursion is hard. |
| 19:06 | dnolen_ | mdeboard`: but once you get it, it's pretty sweet. |
| 19:09 | mdeboard` | I mean I kind of get it, I know it's "process the first item from an iterable, then with the result of that process, process (first (rest iterable))" until, say (= (count iterable) 0), but actually putting those steps into practice hurts my brain. I'm trying to rewrite in Clojure this "make change" app I originally wrote in Python for school, and it's eating holes in my brain. |
| 19:10 | mdeboard` | ANyway, I'm done pissing and moaning, I'm enjoying Clojure. Thanks for all the thoughtful answers. |
| 19:10 | amalloy | mdeboard`: chapter 3.2 of On Lisp has a discussion of this that i think is neat |
| 19:10 | amalloy | pdf freely available at http://lib.store.yahoo.net/lib/paulgraham/onlisp.pdf |
| 19:13 | amalloy | the whole book really is fantastic; when you have some time, have a read. the last five chapters or so are still well beyond me |
| 19:15 | ibdknox | amalloy: hah! That's awesome, I didn't know it was freely available.. it's damn near impossible to find the book |
| 19:16 | dnolen_ | hmm is there any such thing as mutually recursive generators in Python? |
| 19:16 | mdeboard` | amalloy: Thanks. I'm working my way through Joy of Clojure right now |
| 19:16 | amalloy | ibdknox: http://www.paulgraham.com/lisp.html and http://www.paulgraham.com/books.html |
| 19:16 | amalloy | mdeboard`: another excellent book |
| 19:17 | mdeboard` | dnolen_: If there is, using them would be extremely inefficient from what I understand. |
| 19:17 | amalloy | dnolen_: wouldn't any generator with two different yield statements be mutally-recursive? |
| 19:18 | amalloy | ie, you could write it in clojure as two lazy-seqs that refer to each other |
| 19:19 | ibdknox | amalloy: does python allow multiple yeilds? I know C# does |
| 19:19 | amalloy | ibdknox: i know jack-all about python |
| 19:20 | mdeboard` | ibdknox, amalloy: Yes, with branching logic |
| 19:20 | mdeboard` | but not try/except |
| 19:21 | amalloy | mdeboard`: well. i'm imagining something more like |
| 19:21 | amalloy | yield 1; yield 2; # pretending that semicolons are valid separators |
| 19:21 | mdeboard` | Oh, no |
| 19:22 | amalloy | mdeboard`: http://linuxgazette.net/100/pramode.html ? |
| 19:22 | ibdknox | yeah, C# allows that |
| 19:22 | dnolen_ | amalloy: yeah this is what I'm talking about generator has to happen inside the same fn |
| 19:22 | mdeboard` | amalloy: mind: blown |
| 19:23 | mdeboard` | I thought yield froze the function and returned to parent context, like "return" |
| 19:23 | amalloy | mdeboard`: once you have the facilities for a yield to exist anywhere in a function, adding support for more than one doesn't seem like much work |
| 19:24 | dnolen_ | mdeboard`: amalloy: I just tried to write a mutually recursive generator in Python, didn't work for me. But perhaps there is way, I don't see any literature anywhere on it. |
| 19:24 | mdeboard` | amalloy: I'm not well-versed enough in the "how does that work" area to come to that conclusion :\ |
| 19:25 | dnolen_ | mdeboard`: in case, IHMO lazy-sequences are strictly more powerful general than generators in Python :) |
| 19:26 | dnolen_ | mdeboard`: lazy-seqs, recur, and trampoline in tangent recover the loss of TCO in Clojure, not as elegant as TCO to be sure, but at least you can implement the literature in Clojure. |
| 19:31 | mdeboard` | This isn't mutual recursion, right? Putting on my dunce cap here. |
| 19:31 | mdeboard` | http://p.mattdeboard.net/foo.py.html |
| 19:32 | dnolen_ | mdeboard`: not really, bar doesn't call itself. |
| 19:32 | mdeboard` | I'm terrible at recursion. |
| 19:33 | amalloy | dnolen, mdeboard`: https://gist.github.com/1074054 |
| 19:33 | dnolen_ | mdeboard`: but that may be a good clue as to how it can be done. |
| 19:33 | amalloy | demonstration that having multiple yields is equivalent to mutual recursion |
| 19:34 | mdeboard` | amalloy: https://gist.github.com/1074055 |
| 19:34 | dnolen_ | amalloy: hardly, first and second could be higher order, impossible in Python. |
| 19:35 | amalloy | dnolen_: i don't understand |
| 19:35 | dnolen_ | first could take a "second", second could take a "first" |
| 19:36 | dnolen_ | lazy-seqs are not some weird special case the way generators are. |
| 19:36 | amalloy | so? python has lambdas and closures |
| 19:37 | mdeboard` | "weird special cases"? |
| 19:37 | amalloy | i mean, generators are built into the language, yes, in a way i wish they weren't |
| 19:37 | dnolen_ | amalloy: which can not be transfer yield to each other. |
| 19:37 | amalloy | you're talking about continuations now? |
| 19:38 | dnolen_ | amalloy: no I'm talking about the fact that lazy-seq support a kind of open mutual recursion, yield does not. |
| 19:41 | mdeboard` | wait uh |
| 19:45 | mdeboard` | dnolen_away: What do you mean doesn't support mutual recursion? |
| 19:46 | mdeboard` | stand by, paste inc |
| 19:58 | amalloy | mdeboard`: trying to win an award for longest standby? |
| 19:58 | mdeboard` | dnolen_away, amalloy: Mutual recursion? http://p.mattdeboard.net/foo.py.html |
| 19:58 | mdeboard` | lol |
| 19:58 | mdeboard` | nice timing! |
| 19:59 | mdeboard` | er, ignore baz() |
| 19:59 | mdeboard` | oop |
| 19:59 | mdeboard` | http://p.mattdeboard.net/foo.py.html |
| 19:59 | mdeboard` | left out the whole "recur" part |
| 20:00 | amalloy | ugh, languages with statement/expression dichotomy make me sad |
| 20:01 | amalloy | if foo yield bar; else yield baz; |
| 20:01 | amalloy | vs (yield (if foo bar baz)) |
| 20:02 | mdeboard` | Yeah I prefer Python's branch logic syntax less than switch/case syntax. |
| 20:02 | mdeboard` | amalloy: But point being, isn't that mutual recursion between even & odd? |
| 20:03 | amalloy | i think so, but i never needed convincing |
| 20:03 | amalloy | i mean, clearly it's mutual recursion |
| 20:03 | mdeboard` | I NEED TO BE RIGHT ON THIS MAN |
| 20:03 | mdeboard` | But seriously, I know, but the guy who did conveniently disappeared. |
| 20:03 | amalloy | but is it mutually-recursive higher-order generators? that's for dnolen to decide, since nobody else is sure what he means |
| 20:10 | mdeboard` | If he meant that mutually recursive generators are first-class citizen, then yeah they are (obv). Anyway just a mental exercise on my part |
| 22:04 | bdesham | any idea why I get "java.lang.Exception: No dispatch macro for: )" on the last line of <https://gist.github.com/1074160>? |
| 22:06 | scottj | replace the # with % |
| 22:06 | scottj | the last # |
| 22:07 | bdesham | oh gosh |
| 22:07 | scottj | # is a special character that does something different (dispatches) based on it's next character. like be a set #{} or an anon func #() |
| 22:07 | bdesham | that was simple ;-) |
| 22:08 | scottj | so anytime you get that message the offending char will follow a # |
| 22:08 | bdesham | good to know. thanks! |
| 22:11 | ihodes | what kind of tutorials/essays/whatever are needed in the beginner/whatever clojure community right about now? i still need to write my "ins and outs of clojure, pt II"... but aside from that...? |
| 22:12 | bdesham | ihodes: I haven't checked recently, but one thing I found overly difficult when getting started was just how to set up source files |
| 22:13 | bdesham | like, if someone gives you a function to try out... where do you put it? if you put it into a .clj file, how do you run it? how do you get a repl to access those functions? ...stuff like that |
| 22:15 | ihodes | bdesham: hmmm, good idea. getting started is getting easier, but conceptually no one has really explained it (or have they? where at?) |
| 22:16 | mdeboard` | I just started Clojure yesterday |
| 22:16 | mdeboard` | and want to enthusiastically second bdesham's suggestion |
| 22:17 | bdesham | ;-) |
| 22:17 | mdeboard` | what's lein? Is it required? I'm using it because I guess that's the only way to get history via up/down arrow keys |
| 22:17 | bdesham | mdeboard`: if you have any specific questions, fire away... |
| 22:17 | mdeboard` | and tab completion, I think? |
| 22:17 | bdesham | oh |
| 22:17 | mdeboard` | lein repl > vanilla repl |
| 22:17 | mdeboard` | afaict |
| 22:17 | bdesham | you can use other things for that, like jline, but leiningen is probably the easiest way |
| 22:17 | bdesham | right |
| 22:18 | mdeboard` | How are Clojure projects organized? Hell, even something explicitly saying, "The file extension for Clojure files is .clj" would be awesome |
| 22:18 | mdeboard` | It's a 3-second Google request but still. |
| 22:18 | mdeboard` | How do I load a .clj file into repl contxt? |
| 22:19 | bdesham | leiningen is primarily a build system, in that it'll handle the messy work of initializing a repl (as you've seen), fetching your project's dependencies, testing, and eventually putting everything into a single .jar file |
| 22:19 | bdesham | (err... not sure if you were actually asking, or just suggesting things to ihodes ;-)) |
| 22:19 | mdeboard` | I'm asking :P |
| 22:19 | mdeboard` | and suggesting |
| 22:20 | mdeboard` | I'm p smart and self-educating but still, I know in a month I'm going to look back on my clojure directry structure and facepalm |
| 22:20 | bdesham | right |
| 22:20 | bdesham | personally I wish I'd known about leiningen earlier |
| 22:21 | mdeboard` | I only knew about it because i use emacs and swank's maintainer wrote leiningen |
| 22:21 | bdesham | I started with "Programming Clojure", which is really great, but kind of glosses over these mundane beginning details as far as I can recall |
| 22:21 | mdeboard` | so there was some cross-pollination |
| 22:21 | mdeboard` | Yeah, tutorials tend to skip over things |
| 22:21 | mdeboard` | really low-level considerations |
| 22:22 | bdesham | I'd like to write a tutorial like that, but I'm not sure I have a good enough understanding of how the internals work |
| 22:23 | ihodes | mdeboard`: great! tell me more, if you can think of it ;) and ask questions, if you've got any |
| 22:23 | ihodes | mdeboard`: i'd look on the github page for leiningen re: getting started. technomancy has some nice info there as well |
| 22:24 | mdeboard` | Yeah I did, followed all that. I'm good on the REPL end (though I could use some auto-indentation and colorization :) ) |
| 22:24 | ihodes | mdeboard`: including an example project. and getting going with clojure deps etc |
| 22:24 | ihodes | mdeboard`: yeah that would be so nice...maybe I'll get around to it one day ;) |
| 22:24 | bdesham | what's the best way to call (time ...) without displaying the output of the call? |
| 22:25 | bdesham | at the repl |
| 22:25 | bdesham | I guess I could just look at the definition of time and have it return nil |
| 22:25 | mdeboard` | Here's a question. What does this syntax mean: |
| 22:26 | mdeboard` | (defn foo [[op & args]] |
| 22:26 | ihodes | bdesham: it returns the value of the expression you're timing, and prints the time out |
| 22:26 | mdeboard` | the double-brackets |
| 22:26 | ihodes | bdesham: so no worries there, i don't think |
| 22:26 | ihodes | mdeboard`: double brackets == destructuring |
| 22:26 | mdeboard` | ?? |
| 22:27 | mdeboard` | destructuring is...a concept I Just need to read about? |
| 22:27 | bdesham | mdeboard`: yep ;-) |
| 22:27 | ihodes | mdeboard`: e.g. (let [[x y] [1 :a]] {x y}) => {1 :a} |
| 22:27 | mdeboard` | Alright. I'm reading through Joy of Clojure |
| 22:27 | ihodes | mdeboard`: make sense? |
| 22:27 | bdesham | it's important, and a useful thing to learn |
| 22:27 | bdesham | ihodes: right, I just want (time) to not return that value |
| 22:27 | ihodes | mdeboard`: i think it's in the JoC--been a while since i've read it through. it's definitely a useful think to learn. you can destructure maps, too. which is great. |
| 22:27 | bdesham | I'm testing an algorithm by making it do a lot of computations, but I don't actually want to see the output |
| 22:28 | bdesham | I looked at the source for "time" and just replaced the last form with nil, that works fine |
| 22:28 | ihodes | bdesham: what's your use scenario? what are you trying to avoid? you could e.g. just do (do (time (first [1])) nil) |
| 22:28 | ihodes | bdesham: or that! |
| 22:29 | mdeboard` | oh, destructuring is like uh |
| 22:29 | bdesham | ihodes: oh, good idea with the (first ...) |
| 22:29 | mdeboard` | is not unfamiliar |
| 22:29 | mdeboard` | from py |
| 22:29 | ihodes | bdesham: the first is just the example algorithm i'm timing ;) |
| 22:29 | bdesham | I'm doing something like (take 1000000 <my function>) and all the values overwhelm my terminal |
| 22:29 | ihodes | bdesham: so (do (time ALGORITHM HERE) nil) as do just returns the last form |
| 22:30 | ihodes | i'd use `do` i think |
| 22:30 | ihodes | mdeboard`: good -- do you understand sort've my example above? don't know if it was clear enough |
| 22:30 | mdeboard` | Yeah |
| 22:30 | ihodes | sort of* |
| 22:30 | mdeboard` | That's what I used to grok the concept |
| 22:30 | bdesham | d'oh... I was thinking first would evaluate the expression and not return the whole thing, but that wouldn't work for lazy sequences ;) |
| 22:31 | ihodes | mdeboard`: good. you can do similar things with maps, though it's a little tricker. google "destructuring maps clojure" to get some good info, i'd say. or read JoC ;) |
| 22:31 | mdeboard` | that's like uh |
| 22:32 | mdeboard` | (lambda x,y: {x:y})(1, 'a') |
| 22:34 | ihodes | mdeboard`: in a way, i suppose. though that's just a function application there, but the effect is similar. you'll get the hang of it the more you see and use it--feel free to ask any Qs here too |
| 22:45 | mdeboard` | wow joy of clojure fisting my third eye |
| 22:46 | ihodes | mdeboard`: haha how so? |
| 22:46 | mdeboard` | explanation of what state is, difference between mutable & immutable state, and the advantages of immutable state gave me that, "Ohholyshit!" moment of comprehension |
| 22:47 | mdeboard` | mostly about the nature of OOP |
| 22:47 | ihodes | mdeboard`: there you go :) it's such a great read. what langs are you coming from? |
| 22:47 | mdeboard` | Python mostly, but some js as well. |
| 22:48 | mdeboard` | Toyed with lots of others but nothing I'd ever claim any kind of knowledge about |
| 22:49 | ihodes | very nice. i like python. welcome to Clojure though! i'm off--being kicked out of my coffee shop. happy coding |
| 22:49 | mdeboard` | tt |
| 23:00 | Yamazaki-kun | 340-2899999999999999999999999999999999999999999999999999999999999999999999999 opppppaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |
| 23:00 | mdeboard` | arigato gozaimas |
| 23:01 | Yamazaki-kun | sorry; my cat apparently really need to say that. |
| 23:02 | mdeboard` | Yamazaki-kun: thought you were having issue with floating point |
| 23:02 | mdeboard` | 340.289999999999999999999999999999999999999999999999 |
| 23:09 | jimi_hendrix | hello, what is the prefered editor for writing clojure? |
| 23:10 | mdeboard` | jimi_hendrix: What editor are you used to? |
| 23:10 | mdeboard` | or, what editor do you normally use? |
| 23:11 | jimi_hendrix | mdeboard`, depends. typically i use vim, but i also use eclipse for jvm stuff. i know that emacs is the popular editor in the lisp community |
| 23:11 | hiredman | emacs is very popular for clojure as well |
| 23:11 | mdeboard` | Yeah I use emacs for everything, personally |
| 23:12 | mdeboard` | python, js/node, clojure |
| 23:12 | tufflax | vim is ok for clojure |
| 23:13 | mdeboard` | jimi_hendrix: emacs is popular for lisps because it's written in a lisp, so is well-suited to handling lisp syntax out of the box. |
| 23:13 | jimi_hendrix | right |
| 23:13 | jimi_hendrix | it also has slime/swank |
| 23:13 | tufflax | jimi_hendrix you may wanna look at this or something http://www.deepbluelambda.org/programming/clojure/programming-clojure-with-vim |
| 23:14 | tufflax | i use vimclojure myself and im pretty happy with it |
| 23:14 | mdeboard` | jimi_hendrix: Eh slime/swank are a bridge too far for me right now. I'm sure it's handy but I just use vanilla clojure-mode and lein repl. I'm sure vim is fine too |
| 23:14 | mdeboard` | as long as it has auto-indent & parens matching I can't imagine it mattering too much in the beginning |
| 23:16 | mdeboard` | i spent a couple hours mucking about with slime/swank yesterday, finally just threw up my hands and am using vanilla clojure-mode. Don't really miss anything. |
| 23:16 | Scriptor | as a vim user, I like having a separate window for slime right below the main editor in emacs |
| 23:16 | Scriptor | one of the reasons why I started learning it |
| 23:17 | mdeboard` | sigh I should probably get slime up-and-running |
| 23:17 | tufflax | Scriptor hm what do you mean exactly... main editor? |
| 23:17 | Scriptor | tufflax: the window that contains whichever file I'm working on |
| 23:18 | Scriptor | just in case anyone is confused, I'm talking about emacs windows...or whatever they called |
| 23:18 | jimi_hendrix | Scriptor, i have messed around with slime and that is a very nice feature |
| 23:18 | mdeboard` | buffers |
| 23:18 | tufflax | ok... but what is emacs? but you are a vim user? |
| 23:18 | mdeboard` | http://common-lisp.net/project/slime/images/more-slime.png |
| 23:18 | tufflax | thats* |
| 23:19 | mdeboard` | tufflax: I think he just means, like, "I am not an emacs zealot and use mostly vim, but I like having slime emacs separate buffers etc etc" |
| 23:19 | Scriptor | tufflax: mpost of the time I use vim, but I've been tinkering with clojure using emacs (don't use vim with clojure otherwise) |
| 23:20 | tufflax | I've not used emacs a lot but one can get a decent repl and all that in vim too |
| 23:20 | Scriptor | yea, but it was just simpler to set up slime/swank with emacs :) |
| 23:20 | Scriptor | although I do have vimclojure |
| 23:20 | jimi_hendrix | tufflax, i am reading the link you gave me right now. i do very much prefer vim to emacs 99% of the time |
| 23:21 | hiredman | when I wrote clojure in vim I prefered to just have a seperate repl running over using vimclojure, but I never use vim anymore |
| 23:24 | tufflax | Although I'm new to both vim and emacs, I imagined the basic editing being much nicer in vim, so I went with that |
| 23:24 | hiredman | meh |
| 23:24 | Scriptor | the super-simplified way of putting it is that vim is the better text editor, emacs the better dev environment |
| 23:25 | hiredman | I used vim for years, had to switch to emacs for work, so much better |
| 23:25 | tufflax | oh yeah? but doesn't your wrists hurt? :p |
| 23:26 | hiredman | I think the joke is the pinky starts to hurt |
| 23:27 | tufflax | but seriously, why is it so much better? |
| 23:27 | hiredman | I have capslock mapped to control, and have for many months now but still haven't gotten into the habbit of using it instead of control |
| 23:27 | hiredman | tufflax: have you ever written vimscript? |
| 23:27 | tufflax | just a little |
| 23:27 | hiredman | elisp is horrible but it beats the pants off of vimscript |
| 23:27 | tufflax | hehe' |
| 23:28 | mdeboard` | tufflax: It's so much better iff. you want a fully customizable dev environment |
| 23:28 | tufflax | :) |
| 23:28 | hiredman | emacs has org-mode which is amazing, all you can write all kinds of crazy extensions |
| 23:28 | hiredman | and |
| 23:28 | mdeboard` | and no insert-mode |
| 23:29 | hiredman | fullscreen gui emacs on my mac is just so damn pretty |
| 23:29 | tufflax | i made a totally new keyboard layout where i bound my caps lock to alt-gr, and have every symbol on the keyboard on alt-gr + letters, its really good with vim |
| 23:29 | hiredman | (emacs 24 + the cocoa fullscreen patch) |
| 23:30 | mdeboard` | scpaste :) |
| 23:32 | hiredman | to be fare vimscript is #11 on the github rankings which is kind of crazy |
| 23:32 | hiredman | elisp is #13 |
| 23:32 | hiredman | fair |
| 23:32 | hiredman | I can't believe anyone would put themselves through writing that much vimscript |
| 23:34 | jimi_hendrix | vimscript is crazy though |
| 23:34 | scottj | also perhaps more elisp projects are included in emacs itself or emacswiki than vimscript projects in vim and whatever |
| 23:34 | mdeboard` | Plus, I mean, irc in my editor? Yes pls |
| 23:34 | jimi_hendrix | mdeboard`, i tried that. it wasnt that great |
| 23:34 | mdeboard` | doin it wrong |
| 23:34 | mdeboard` | :P |
| 23:35 | Scriptor | mdeboard`: emacs is my favorite windows irc client |
| 23:35 | jimi_hendrix | idk, i need my xchat |
| 23:35 | jimi_hendrix | even though i hate it |
| 23:35 | mdeboard` | ... |
| 23:35 | jimi_hendrix | its like an abusive relationship |
| 23:36 | mdeboard` | people need all these features for IRC, I don't get it |
| 23:36 | Scriptor | I love seeing 4 irc channels at the same time |
| 23:36 | mdeboard` | tab completion of names, event notifications, auto ID to services is all I really need |
| 23:36 | Scriptor | with xchat I'd have to keep tabbing around |
| 23:36 | jimi_hendrix | mdeboard`, i barely use any |
| 23:36 | hiredman | I get notifications from irssi |
| 23:37 | jimi_hendrix | Scriptor, thats true, but many other clients support windows/panels |
| 23:37 | hiredman | I have a program that reads the irssi log and sends it to SQS and then I pull it down from SQS and growl it |
| 23:37 | hiredman | costs about $1.20 a month |
| 23:37 | mdeboard` | rcirc is a great IRC/IM client. Plus fully scriptable :) |
| 23:38 | scottj | hiredman: why now pull it from whatever host you're running irssi on? |
| 23:38 | Scriptor | "and doesn't light up like a christmas tree" |
| 23:38 | Scriptor | heh |
| 23:38 | hiredman | scottj: I could, but SQS is webscale :) |
| 23:39 | hiredman | actually my first version used hornetq running on the host irssi is running on |
| 23:39 | scottj | hiredman: hehe :) I do a similar thing with one line of bash |
| 23:39 | clojurebot | hiredmans euler.clj is so embarassing |
| 23:39 | hiredman | clojurebot: thanks |
| 23:39 | clojurebot | thanks for your suggestion, but as usual it is irrelevant |
| 23:39 | Scriptor | harsh |
| 23:40 | tufflax | haha |
| 23:51 | mdeboard` | mmkay just got slime/swank installed for emacs. Wow. Enormous, enormous boost. |