#clojure logs

2011-06-09

00:05jtszzzzzdnolen, Here is what I am going for https://gist.github.com/1016032
00:20dnolenjtszzzzz: does Submission have a fixed number of fields?
00:20Scriptor_Hi everyone
00:21jtszzzzzdnolen, I don't intend to use Submission anymore. Sorry for confusion. I just intend to return a map keyed by the provided key on the FieldSpec
00:22dnolenjtszzzzz: I think your gist is too much context, a smaller complete example of what you want to do would helpful.
00:22dnolenjtszzzzz: but so far I'm suspecting you don't need a macro.
00:29jtszzzzzdnolen, I just added a Generalized.clj to that gist. This should really boil it down to the guts of the problem
00:32justinkoI just created a new project via lein and added a function. How can I call that function in "lein repl"?
00:33dnolenjtszzzzz: so the issue is you need to create those keys based on the # of lists?
00:33jtszzzzzyes, and i need the let bindings based on the number of lsits
00:33jtszzzzzand the args into the map based on the number of lists
00:38jtszzzzzjustinko .. you need to load your namespace .. do something like (require 'myproject.core)
00:40jtszzzzzthen you can navigate to your namespace like this (ns myproject.core)
00:41justinkojtszzzzz: that worked, thanks
00:41jtszzzzznp
00:41dnolenjtszzzzz: https://gist.github.com/1016073
00:43justinkojtszzzzz: just found out I can add ":main my-poject.core" to project.clj to automatically hop into that namespace
00:44justinkojtszzzzz: now is there a "reload" type function that reloads the clj source code?
00:44justinkofor the repl
00:46technomancyjustinko: (require 'foo.bar :reload)
00:46jtszzzzzdnolen, reading this now!
00:48justinkotechnomancy: thanks!
00:52technomancynp
00:53jtszzzzzdnolen, thanks a lot. That is really nice. I think this will work good for what I am doing!
00:54dnolenjtszzzzz: https://gist.github.com/1016088 another version that avoid metadata cleverness.
00:57dnolenjtszzzzz: update the last one for readability (IMO)
00:57dnolens/update/updated
00:57sexpbot<dnolen> jtszzzzz: updated the last one for readability (IMO)
00:58jtszzzzzi like it!
01:10justinkoomg you can define a :test metadata for inline tests? That is awesome.
01:10justinkodo any of you guys actually use it?
01:10justinkoor do you stick with the /test directory?
01:20dnolenjustinko: I think usage was common in the early days when no tooling, now most people use maven or lein with /test dir.
01:20dnolencake too
03:29Dranikhello all!
03:29DranikI have a question
03:29DranikI have the following variable: (def my (ref {:a 1, :b 2}))
03:30DranikAnd I wanna a reference from inside the hash-map to my
03:30justinkonathanmarz: I just read your interview on geektalk
03:30Dranik(dosync (alter my assoc :c my)))
03:31Dranikbut this leads to stack overflow
03:31Dranikis there a way to make a cyclic reference {:c my} inside 'my' ?
03:33nathanmarzjustinko: cool
03:33hoeckDranik: no, not with immutable maps
03:33Dranikhoeck: I need a mutable map
03:33Dranikthat's why I use ref
03:34hoeckDranik: right, but the map is still immutable
03:34Dranikhoeck: is there at least any way to do that? even not idiomatic?
03:34hoeckthe :c key would have to be a ref too
03:34Dranikno, I've tried this also
03:35Dranikprobably I should have used a common Java map...
03:37hoeckDranik: having a ref in the map works, but can be kind of clumsy
03:38hoeckDranik: when you use plain java maps, you loose the threadsafety and other guarantees of clojure maps
03:38Fossiprobably you need to tell us more about your real problem
03:39Fossithen maybe somebody gcan tell you what would be idiomatic ;)
03:39Fossiwhat you are currently trying to do sounds like a huge mess to me tbh :>
03:41hoeckFossi: circular datastructures are not that uncommon
03:41Fossiyes
03:41hoeckFossi: well, maybe in the land of functional languages
03:41Fossibut this instance sounds messy
03:42Fossiesp with mutability and all
03:42DranikFossi: I'm impoementing a scheme interpreter in clojure using chapter 4 of SICP
03:42DranikI need this cyclic reference when I create a procedure
03:43DranikI define a binding for the body of the procedure and add the current environment to it
03:43Dranikhoeck: when I do (dosync (alter my assoc :c (ref my)))), it also throws the same exception
03:44hoeckDranik: the printer throws that exception, because it fails to print your cyclic structure
03:45Dranikhoeck: looks like you're right!
03:45DranikI'll try this...
03:45hoeckDranik: I also have to correct myself, your first approach was correct, you don't have to use a nested ref
03:47hoeck,(let [my (ref {:a nil})] (dosync (alter my assoc :a my)) (-> @my :a deref :a deref :a deref type))
03:47clojurebotclojure.lang.PersistentArrayMap
03:48Dranikis there a way to disable the printer?
03:49hoeckimplementing an interpreter using a circular datastructure does not feel 'right' in clojure
03:50hoeckDranik: (set! *print-level* 10) on the repl
03:50Draniktrying this...
03:50hoecklimits printing of nested datastructures to n levels
03:54Dranikhoeck: you know what? just disabling the printer solved all the issues! :-)
03:54Dranikthanks a lot!
03:55hoeckDranik: you're welcome
05:34gilechamHmmm, anyone able to shed some light on why:
05:34gilecham(let (vector a 1) a)
05:34gilechamfails stating that "let requires a vector"
05:35mrBliss`gilecham: the syntax for let is: (let [a 1] a)
05:49gilechammrBliss`: yes but (vector a 1) should return [a 1] ...
05:51Chousukegilecham: when evaluated
05:51Chousukegilecham: (vector a 1) is a list of two symbols and a number
05:51Chousukeevaluating it results in a vector of whatever a is and a number
05:52Chousukes/a is/a evaluates to/
05:52sexpbot<Chousuke> evaluating it results in a vector of whatever a evaluates to and a number
05:53gilechamChousuke: so the problem is that, because let is a macro, the call to vector is not evaluated before evaluationg the call to vector?
05:53Chousukegilecham: to put it another way, all code you write must be "literal". If a syntax requires a vector, then you must give it a literal vector.
05:54Chousukegilecham: But when you *generate* code you can of course generate the vector dynamically.
05:54mrBliss`gilecham: right (let is actually a special form)
05:55Chousukehm
05:56gilechamDrat. I'm trying to write something which will allow me to automatically replace all arguments of a function with new ones generated by a function call on the original. I was hoping to just wrap a let... round the body of my function
05:56ChousukeYou can do something like this though: &&(let [a 2] `(let ~(vector ['a a]) (do whatever)))
05:57Chousukehm
05:57mrBliss`,`(let ~(vector 'a 1) ~'a))
05:57Chousukehow does that inline evaluation wrok?
05:57clojurebot(clojure.core/let [a 1] a)
05:57mrBliss`Chousuke: ##
05:57Chousukeoh right
05:57Chousukedamn
05:58Chousukegilecham: note that that ` form only generates the code. to get it to do something, it must be the result of a macro (so that it will be evaluated at runtime) or you must eval it manually
05:58mrBliss`gilecham: can you give a small example because I don't really understand
05:58Chousukegilecham: you can probably do that with a macro.
05:58Chousukeor you could use the templating facility in core
05:59gilechamChousuke, mrBliss`: Thanks! I thought there was macro magic in here somewhere
05:59Chousukegilecham: this might help http://richhickey.github.com/clojure/clojure.template-api.html
06:02gilechammrBliss`: Intent was to be able to write:
06:02gilecham(defn foo [a]
06:02gilecham (let [a (transform a)]
06:02gilecham (original-body a)))
06:04gilechamOff to read up on templates and return with more questions, thanks again
06:06teromWhy not just use a higher order function?
08:02void_hi there, what is this syntactic sugar please? ->
08:03fliebelvoid_: A thrush, almost at least.
08:03manutterThreading
08:03manutterLet me misuse it, as an illustration...
08:03fliebel&(1 (+ 1) (* 2))
08:03sexpbotjava.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn
08:03fliebel&(-> 1 (+ 1) (* 2))
08:03sexpbot⟹ 4
08:03manutter,(-> 1 (inc) (println) (inc) (println))
08:03clojurebotjava.lang.NullPointerException
08:04manutterdarn, too much abuse
08:04manutterso much for clarifying the issue
08:04fliebel&(macroexpand-1 '(-> 1 (+ 1) (* 2)))
08:04sexpbot⟹ (clojure.core/-> (clojure.core/-> 1 (+ 1)) (* 2))
08:04fliebel&(require 'clojure.walk)
08:04sexpbot⟹ nil
08:04void_&(doc ->)
08:04sexpbot⟹ "Macro ([x] [x form] [x form & more]); Threads the expr through the forms. Inserts x as the second item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the second item in second form, etc."
08:05fliebel&(clojure.walk/macroexpand-all '(-> 1 (+ 1) (* 2)))
08:05sexpbot⟹ (* (+ 1 1) 2)
08:05manutter,(-> (identity 1) (+ 1) (* 2))
08:05clojurebot4
08:06manutterThe basic idea is that it lets you take (foo (bar (baz x))) and turn it into (-> x (baz) (bar) (foo)), which can be more readable in certain circumstances
08:07manutter,(-> (identity 1) (inc) (println) (inc) (println) (inc))
08:07clojurebotjava.lang.NullPointerException
08:07void_oh I see
08:07manutterstill cant' get that one to work
08:07manuttero well
08:07void_yup, this is what google gave me, nice article: http://debasishg.blogspot.com/2010/04/thrush-in-clojure.html
08:07fliebelmanutter: println return nil
08:07void_&(doc identity)
08:07sexpbot⟹ "([x]); Returns its argument."
08:08manutterdoh, of course
08:08fliebelmanutter: You can also skip the identity and enter 1 directly.
08:08manutter,(-> 1 (inc) (inc) (* 2))
08:08clojurebot6
08:08void_&(-> (1) (inc) (inc))
08:08sexpbotjava.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn
08:08manutteryeah, I was chasing a red herring there :)
08:09void_&(-> 1 (inc) (inc))
08:09sexpbot⟹ 3
08:09fliebel$(->> (range 10) (map #(* 2 %)) (reduce +))
08:09fliebel&(->> (range 10) (map #(* 2 %)) (reduce +))
08:09sexpbot⟹ 90
08:09void_what does it mean if you use ->> instead of -> ?
08:10manutter-> comes in handy for things like setting up swing components, where you create something and then do x to it, then do y to it, then do z to it
08:10fliebelvoid_: it inserts the argument at the end instead.
08:10manutterThe difference between -> and ->> is where the "running" total goes
08:10raekvoid_: (-> x (f a b c)) means (f x a b c), but (->> x (f a b c)) means (f a b c x)
08:10manutterlet me try again
08:10fliebelmanutter: Actually, for swing, most actions don't return anything, so you'd use doto.
08:11void_this is cool
08:11manutterok, I'm going to just shut up and drink my coffee, it's too early for me still!
08:11manutter:)
08:12manutterI don't use -> and ->> much yet, that's probably why I don't understand it as well as I think I do.
08:14void_it's amazing how whole source of compojure takes 4 files https://github.com/weavejester/compojure/tree/master/src/compojure
08:14raekit helps removing nesting: (into {} (map #(Integer/parseInt %) (remove empty? (line-seq rdr)))) -> (->> rdr (line-seq) (remove empty?) (map #(Integer/parseInt %)) (into {}))
08:15raekthen you can put each step at its own line, and the code becomes beautiful again...
08:15manutterthere, that's a much better example
08:17manutterYeah, I really like compojure, though the real power behind it is in Ring
08:18void_guys, do you think it's a good idea to learn Clojure by building a web application?
08:18manutterI'd say so
08:18manutterespecially if your goal is to learn how to write good web apps in clojure
08:19void_I still feel very lost in clojure code
08:19kephale1in the void so to speak
08:19raekone thing that can be fun to do is to build your own chat application and protocol
08:20void_oh yeah definitely
08:20raeksomething very simple
08:20void_use some sproutcore+websocket for clients
08:20void_or backbone.js or whatever
08:20raekthen you have a little bit of state management too
08:20void_yeah I think that will be the next
08:20void_I did something like that in node.js
08:21raekI was thinking about basic I/O with ordinary sockets, but by all means use whatever knowledge you have to make it fun :-)
08:21void_but node.js seems so simple compared to clojure
08:21void_raek: yesterday I made hangman game for telnet
08:21manuttervoid_: have you done the 4clojure.org exercises?
08:21void_no sir
08:22manutterThey're a good remedy for the "I feel lost in clojure" syndrome
08:22void_now that looks very nice
08:22void_I started koans
08:22manutteryeah, same idea
08:22void_it's amaing how many learnin resources are out there
08:23manutterindeed
08:29void_by the way "joy of clojure", anybody read it?
08:29manutterIt's on my bookshelf, I'm partway thru it
08:30manutterIt's not intended as an intro text, I like Clojure In Action for that
08:30void_yeah, same feelings here - not an intro text
08:31manutterthough I just got the "Rough Cuts" version of Clojure Programming, and it's looking pretty good too
08:31void_rough cuts, like a beta version?
08:31manutterYeah sort of
08:32manutterIt's what O'Reilly calls their pre-release program
08:32kephale1is Raynes' book finished yet?
08:32manutternot sure
08:40void_hm, so I created a project with lein. And I would like to run REPL on tom of my existing code, is there any easy way to do it?
08:40void_oh
08:40void_lein repl
08:41manutterand if you're using emacs, you can use lein swank and then use M-x slime-connect to run a repl right in emacs
08:41void_yeah I'm not
08:41void_:)
08:41void_textmate
08:41manutterAh
08:41manutterI've never used that one
08:41manutterwhat OS is that/
08:41manutter?
08:41void_Mac
08:42manutterAh, ok
08:42manutterI should play with that some time
08:45kephale1there was also a recently revitalized lisp GUI for OS X that now uses Clojure and can play fairly nicely with lein… unfortunately the name of it has completely slipped my mind
08:46manutterdoh!
08:46kephale1there is*
08:47manutterHmm, first google result is Emacs...
08:47manutterLemonodor?
08:47manutterMCLIDE?
08:48void_kephale1: I would like to try that
08:48kephale1MCLIDE!
08:49kephale1right because it was developed for MCL
08:49void_oh ok
08:49manutterMight have to give that a whirl
08:49manutterFirst I'm going to stop by and submit the web site to web-sites-that-suck.com tho :P
08:50void_If I wanted to play with my code without reloading jvm each time (I use lein run), what is the best way?
08:50void_except emacs
08:50void_because I'm not in the mood for learning new editor
08:50void_manutter: that link is dead :P
08:50manuttereh, I probably spelled it wrong
08:50kephale1manutter: lol
08:50manutterbut still
08:50void_http://www.webpagesthatsuck.com/
08:51manutterThat were it! :)
08:53mrBliss`void_: are you using https://github.com/swannodette/textmate-clojure ?
08:53void_mrBliss`: yes
08:53void_but that still doesn't give me repl
08:54void_I mean I can execute one line
08:54void_which is the same ...
08:54manutteromg even the MCLIDE *icon* is that horrible plaid
08:54mrBliss`Command-Shift-L loads a file
08:55kephale1manutter: at the least I think the project is pretty recently revived… lets hope they're putting all their efforts into the backend ; )
08:55kephale1i concur, emacs FTW
08:55kephale1especially when it comes to lisps
08:56manutter+1 on both counts
09:02VinzentIs there function combinators somewhere in core or contrib? like (map (fn/and string? empty?) ["" [] ()] => (true false false)
09:03void_anybody uses mongo with clojure?
09:03manutterVinzent: there's comp and partial, though from your example I'm not sure that's what you're looking for
09:05Vinzentmanutter, (fn/and string? empty?) should return the predicate that returns true for things that are strings and empty
09:05kephale1Vinzent: i think you'd have an issue with the and since its a macro
09:05kephale1but 1 sec i may have an idea
09:05Vinzentsame as #(and (string? %) (empty? %)), but shorten
09:06raekVinzent: I think fogus suggested such functions on the clojure dev mailing list a while ago
09:06hoeckVinzent: I'm looking for that too :)
09:06mrBliss`found it: http://dev.clojure.org/jira/browse/CLJ-729
09:08raekand the discussion: http://groups.google.com/group/clojure-dev/browse_thread/thread/899349c6a9b526e0/10233af5f5f13831
09:08kephale1Vinzent: I think you'd have to write a function like the one fogus is suggesting
09:08kephale1but you might be able to use juxt in it
09:09Vinzentfound the lib: https://github.com/zahardzhan/fn
09:10Vinzentkephale1, right, juxt suites me in my case
09:11Vinzentbut it's more verbose
09:12kephale1yeah, but you can use it to write your function which might be something like a comp of a partial and of a juxt
09:12kephale1err that last and is the macro, not the conjunction
09:12kephale1trying to get it to work now
09:22kephale1though i'm avoiding using that fn library...
09:22kephale1,(every? #(apply (fn [x y] (and x y)) ((juxt string? empty?) %)) (list "" ""))
09:22clojurebottrue
09:22kephale1,(every? #(apply (fn [x y] (and x y)) ((juxt string? empty?) %)) (list "" '(a b)))
09:22clojurebotfalse
09:23kephale1kinda ugly, but you could wrap something like that into a funcion
09:23kephale1function*
09:23kephale1hooray for a reason to use juxt : P
09:26kephale1again there is weirdness in this because i'm not using fn/and but:
09:26kephale1(def predicator (fn [& predicates] #(apply (fn [x y] (and x y)) ((apply juxt predicates) %))))
09:28kephale1someone might have a better idea than the nested application there though
09:30mrBliss`(defn every-pred [& preds] (fn [& args] (every? #(apply % args) preds)))
09:31kephale1thats the one fogus presented right?
09:32kephale1hrm, yeah mine is far from solving the 0 arg issue
09:32raek,(every? odd? [])
09:32clojurebottrue
09:35kephale1,(and)
09:35clojurebottrue
09:35__name__Interestin
09:35__name__*Interesting even
10:25DranikIs there a way to add a library to leiningen project's classpath and not import it into the local maven repository?
10:25clgvDranik: yes, just copy it to your lib directory
10:26clgvDranik: and use :disable-implicit-clean true in your project.clj
10:26Dranikwhen does leiningen clean the lib directory?
10:27raekDranik: when you run lein deps, I think
10:27Dranikah, yeah...
10:27Dranikthanks
10:27raekDranik: are you sure the lib is not in Clojars or Maven Central?
10:28raekif you make this project publically available, it's much simpler for others if there is an artifact for the dependency
10:28Dranikits j2ee5-api.jar...
10:29fliebelhttp://blogs.oracle.com/henrik/entry/moving_to_openjdk_as_the
10:30kephale1Dranik: or you can just run your own repository with something like archiva
10:30raekDranik: http://jarvana.com/jarvana/search?search_type=project&amp;project=javaee-api
10:31Dranikraek: what's that?
10:31raekjarvana?
10:32Dranikaha
10:33raekjarvana is a search engine for maven artifacts
10:33Dranikwow! thanks!
10:33raek...the place to look at for non-clojure libraries
10:34clgvraek: great. didnt know that before
10:43dnolenfliebel: https://gist.github.com/1016858
10:43dnolentabling fixed
10:43fliebeldnolen: yea, got a notice from jira, great!
10:44dnolenfliebel: caveat at the moment is you can't table defns only def + fn because of lexical scoping issue.
10:44dnolenbbl
10:44fliebeldnolen: Does htis also mean run is no longer lazy?
10:49devnmust...find...book: http://www.amazon.com/Art-Prolog-Second-Programming-Techniques/dp/0262193388/ref=reg_hu-rd_add_1_dp
10:49devn(for less than 105.00, preferably)
10:52jolyAm I correct that trampolined functions can't return a vector or map since they implement IFn?
10:53joly,(trampoline (fn [a] [1 a 3]) 2)
10:53clojurebot[1 2 3]
10:53joly... I guess not
10:54jolyah, parentheses error locally
10:54mrBliss`,(map fn? [(fn []) [] {} #{}])
10:54clojurebot(true false false false)
10:56jolythanks, I was doing a 4clojure trampoline problem and was using (instance? clojure.lang.IFn r). Totally missed fn?.
10:59zenolidevn: AbeBooks has a bunch of copies listed ...2nd ed for ~$40, 1st ed for ~$10.
11:10anonymouse89is there a way to exclude a function/macro from being "used" by another ns without explicitly excluding?
11:10anonymouse89or to rephrase, something like defn- for defmacro?
11:11fliebelanonymouse89: If you can add metadata to a macro, you can say ^:private I guess.
11:12raekanonymouse89: (defn- foo ...) is the same as (defn ^{:private true} foo ...) and you can use the latter way for macros
11:12fliebelraek: Sure? ##(doc defmacro)
11:12sexpbot⟹ "Macro ([name doc-string? attr-map? [params*] body] [name doc-string? attr-map? ([params*] body) + attr-map?]); Like defn, but the resulting function name is declared as a macro and will be used as a macro by the compiler when it is called."
11:13anonymouse89fliebel, raek: yes, this works. Thanks!
11:15raekI think that basically (defmacro foo [x y] ...) is equvalent to (defn ^{:macro true} foo [x y &env &form] ...)
11:16raekhrm, yes. using an attribute map looks prettier: (defmacro foo {:private true} ...)
11:16anonymouse89raek: for whatever reason (defn- mymacro ^{:macro true} ... ) gives me a StackOverflow when I call it
11:20mrBliss`,(macroexpand '(defmacro m [args] 1))
11:20clojurebotDENIED
11:20mrBliss`(do (clojure.core/defn m [args] 1) (. (var m) (setMacro)) (var m))
11:20mrBliss`so it's not ^{:macro true}, but (.setMacro ..)
11:21devnzenoli: thanks!
11:43dnolenfliebel: so I think I have an approach that can work for Rel, will be more involved to implement but will address the generality that I want.
11:43fliebeldnolen: Coll, I'm all ears :)
11:44dnolenfliebel: write a macro that generates the Rel type for all IFn methods, 1-21 args.
11:45dnolenRel will take 23 params, name meta and 21 fns, possibly initial nil, these are unsynchronized mutable, setters will generate for all o these.
11:45dnolenClojure will all automatically pack all args past 20 into the rest parameter.
11:45dnolenthe 21st arg I mean.
11:48dnolenwill need to think about dealing with indexing, but I think this approach can work. I'm interested in a syntax for indexing any arg, as well compound indexes.
11:50fliebeldnolen: Okay, so we're now writing a NoSQL db for relations? :)
11:50dnolenfliebel: no, some Prologs support this from what I understand.
11:51dnolenfliebel: but yeah, large knowledge bases could be queried efficiently.
11:51fliebelSo Prolog contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of MongoDB.
11:51dnolenfliebel: other way around.
11:52fliebelSo MongoDB contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Prolog.
11:54fliebeldnolen: But, sure sounds cool and all. Only... 20 args! I assume Clojure does this for efficiency?
11:55clgvfliebel: "Nobody will need more than 20 args!"
11:55dnolenfliebel: no Clojure supports arbitrary number of args, so will Rel. it just that anything more than 20 gets packed into a rest arg, so you need to unpack them yourself.
11:56dnolenso only fast path for 1-20.
11:56fliebelclgv: Nobody will need more then 5 args 90% of the time, so 20 + varargs seems a weak optimization with a bad sideeffect.
11:56dnolenfns that take > 10 args are gross.
11:57fliebeldnolen: On the other hand, think about functions like defn and vector...
11:57clgvmy juxt-map cannot handle varargs yet, since it was too much work and I was content with 8 pairs = 16 args...
11:58dnolenfliebel: ?
11:58fliebeldnolen: (vector 1 2 3 4) goes over 20 args real quick.
11:58clgvfliebel: how often do you specify it manually like this? ;)
11:58fliebelclgv: Juxt-map?
11:59dnolenfliebel: vector does take arbitrary args, it takes 5 at most.
11:59fliebelclgv: Not at all, but I do define functions with more than 20 statements.... maybe.... sometimes
11:59dnolens/doesn/doesn't
11:59dnolens/does/doesn't
11:59sexpbot<dnolen> s/doesn'tn/doesn'tn't
11:59clgvfliebel: like juxt but instead of buildin a seq/vec it does build a map with specified keys
11:59dnolenergs
12:17VinzentIn midje, how can I say that fn returns approximately some number?
12:18manutterRound off the result and say it equals exactly some number
12:19manutterHmm, I'm trying to think of a way to make that more specific...
12:20manutterOk, let me rephrase that:
12:20mprenticehow can i get the direct children of a type in a hierarchy created with make-hierarchy?
12:20manutterThe value x is approximately equal to y if the absolute value of (x - y) is less than some "close enough" factor
12:22manutterso write your midje test to calculate the absolute value of target number minus actual number, and assert that it is < e (where "e" is the margin of error)
12:23VinzentYes, I can do it, but the right way is to use roughly:
12:23Vinzent(fact (/ 666666.666 13) => (roughly 51282))
12:24manutterroughly?
12:24manutterOh, is that a midje function?
12:24VinzentYep
12:25Vinzentor, if I want to specify "close enough" number: (fact (/ 666 13.0) => (roughly 51 0.5))
12:25manutterwell there you go, now I learned something
12:26VinzentMidje is really awesome, isn't it? :)
12:26manuttermprentice: I don't know how to get the direct descendants of a type in a hierarchy, but if I had to try, I'd get (descendants h type) and then compare them to each other with isa? to discard the ones that are not direct descendants
12:26manutterYeah, I love midje
12:29mprenticemanutter: hmm, i guess i'm trying to use hierarchy in a way it's not designed for. i want to pre-walk the hierarchy
12:31dnolenmprentice: yeah there's parents, but no children.
12:32manuttermprentice: can you build your tree structure first, and then use that to build your hierarchy?
12:33manutterThat way they'd be parallel structures, but you could walk the one, and use the other for isa? testing and so on.
12:33mprenticei don't need the hierarchy, i was just hoping to use it as an easy way to build a tree
12:34mprenticebut i don't think i gained anything by doing that
12:35manutteryeah hierarchies are more a tool for describing relationships I think
13:33void_hi. I asked this before but: Is there any way to start REPL from inside my program. Something like read-line -> evaluate it in an infinite loop.
13:33void_I was just wondering if there is anything that does this.
13:36manutterhmm, there's a clojure.repl namespace
13:37void_nah there's only things like dir, source, apropos
13:37manutterAh, no I found it
13:37technomancyclojure.main/repl
13:37void_oh that
13:37manutteromg technomancy out-typed me again
13:37void_dvorak
13:37void_right technomancy? ;)
13:37manutterlol
13:37technomancyabsolutely
13:38technomancyalso terseness
13:39void_I love how anybody can add examples to http://clojuredocs.org/clojure_core/clojure.main/repl
13:39void_or clojuredocs.org
13:42void_awesome!
13:43void_this (clojure.main/repl)
13:57timvisherhey all
13:57timvisheranyone know where I can read some good docs on compojure sessions?
13:58manuttercompojure sessions or ring sessions?
13:58timvisheri suppose that compojure would just be using ring sessions
13:58timvisheri'm not sure
13:58timvisheris there such a thing as compojure sessions?
13:59timvisherbetter yet, all I'm trying to do is stuff a string into a session
13:59timvisheri found some references to session-assoc
13:59timvisherbut i can't find that in the source anywhere
14:01manutterall I can find is this: http://clojuredocs.org/ring/ring.middleware.session/wrap-session
14:01dnolentimvisher: compojure is really just a routing DSL these days, all session stuff comes from Ring
14:02manutterlooks like the wrap-session handler just adds a hash map to the :session key on the request object, and you store stuff by putting it in a hash-map your attach to the :session key on the response object
14:02manutter(but don't quote me)
14:05timvisherso my site is defined using the handler/site function
14:05timvisherwhich auto-wraps sessions around all the routes
14:05timvisherI'm trying to figure out how to alter the session now
14:05timvisherthat's where I'm falling down
14:06manutterso if I'm understanding the docs correctly, you should be getting a request map that contains a :session key
14:06Vinzenttimvisher, just get :session key from request map and assoc what you need
14:07manutterThe :session key on the request is your session data coming in, and then to modify it, create a new map (just use ordinary assoc on the map you get from session) and attach it to a :session key in your response
14:08timvishergotcha
14:08timvisheri think i was expecting things to be more complex. :)
14:08timvishershame on me
14:08manutterwell, I'm passing on what I think I've heard, so grain of salt, etc
14:08manutterbut I think that's all there is to it
14:09manutterIf you use Sandbar there's some more complex session handling available
14:09manutterbut Ring is pretty vanilla
14:09timvishergotcha
14:09Vinzentiirc you should write your middleware to save session, if your handler doen't modify it
14:10manutterI think that the standard wrap-session middleware updates the session data
14:10manutterThe docs say that if you add a :session key to the response, "the session is updated with the new value"
14:11manutterIf I'm understanding that correctly, that should preserve any session values that you did not change
14:13Vinzentmanutter, may be, I just remember I've read somewhere about it
14:14manutterYeah, I played with it a while ago, I'm trying to remember what I discovered at the time
14:14manutterbut I think I'm somewhere in the ballpark anyway
14:14timvisheris the referrer sent when a form posts to a url?
14:15amalloytimvisher: should be, but you also shouldn't really rely on it
14:15timvisherhere's the big picture of what i'm trying to do.
14:16timvisherI've got a long page with a bunch of small elements, I'd like to
14:16timvishersend a post to a route, and then focus the result of the function
14:16timvishercalled there when I return to the previous page
14:16timvisheri'd like to return to whatever url they were on previously, as well.
14:16timvisheralthough at the moment i just redirect to root
14:17amalloytimvisher: a popular way to do the latter is to post to /myform?backto=somepage
14:18timvisheramalloy: brilliant. :) don't know why i didn't think of storing the window.location in the form
14:18timvisherok, so that solves that problem
14:19timvisherthen, i can store the title in the session on the way back and focus it there
14:19timvisherawesome
14:53lawfulfalafelhow do you find out the size of a list?
14:53amalloycount
14:54amalloy&(map count ["string" '(some list) [1 2 3 4]])
14:54sexpbot⟹ (6 2 4)
14:54amalloylawfulfalafel: ^
14:59lawfulfalafelthanks you amalloy
15:05pdkdoes anyone know if clojure bit-shift-right is equivalent to java >> or >>>
15:05pdkiirc >>> sets the high order bits to 0
15:05TimMc,(bit-shift-right -1)
15:05clojurebotjava.lang.IllegalArgumentException: Wrong number of args (1) passed to: core$bit-shift-right
15:05TimMc,(bit-shift-right -1 5)
15:05clojurebot-1
15:07TimMcLooks like sign-extend to me.
15:09pdk,(type (bit-shift right 255 1))
15:09clojurebotjava.lang.Exception: Unable to resolve symbol: bit-shift in this context
15:09pdk,(type (bit-shift-right 255 1))
15:09clojurebotjava.lang.Integer
15:10zakwilsonAm I understanding correctly that I can't do variable capture in a Clojure macro?
15:11pdkyou should be able to
15:12pdkit has a reader macro for gensym after all
15:12dnolenzakwilson: you can, ~'foo
15:12dnolen,`(foo)
15:12clojurebot(sandbox/foo)
15:12dnolen,`(~'foo)
15:12clojurebot(foo)
15:13zakwilsondnolen: thanks
15:14zakwilsonpdk: not using gensyms where they would ordinarly be called for usually throws an exception.
15:14pdk,~'foo
15:14clojurebotjava.lang.IllegalStateException: Var clojure.core/unquote is unbound.
15:15pdkwait durr
15:28pdkis there a changelog for 1.2.1
15:34miwillhite@technomancy, one time I was in here asking how to get environment variables…when you told me you prefixed the function call with a comma (it was something like ",(System/getenv)")…was that a typo, or does the comma mean something when used that way?
15:35Chousukemiwillhite: on this channel , invokes clojurebot
15:35raekmiwillhite: comma is whitespace in clojure. it is also the prefix clojurebot listens to for code evaluation
15:35miwillhiteah okay, thanks :P
15:36miwillhite,(+ 1 1)
15:36clojurebot2
15:36miwillhitesweet
15:36ampleyfly,_
15:36clojurebotjava.lang.Exception: Unable to resolve symbol: _ in this context
15:36TimMc,,,,,,
15:36clojurebotEOF while reading
15:39amalloyis there a good/standard way to implement IFn by hand rather than with (fn …)? I've written (reify IFn (invoke [this] …)), and that works for 0 args. if i call it with any args, it throws an AbstractMethodError. in some ways that's fine since i don't want to allow any args, but it would be nice if it threw an arity exception instead
15:39amalloyi can proxy AFn, but it's my understanding that you should stay away from proxy if you can help it
15:40amalloyto avoid an XY issue: i'm doing this because i want to implement IDeref as well as IFn
15:43hiredmanA nasty way to do it would be to use a Var
15:44hiredmanactually, well, the fullfils what you said in the most pointless way
15:46amalloywell. the more i poke at it the less certain i am that implementing IFn is really a good idea anyway
15:49lawfulfalafelcan someone help me with this code? http://pastebin.com/AytnsLps
15:49dnolenamalloy: I would write a helper macro to throw ArityException on the other arities. I'm planning on implementing IFn and I see there's a lot of boilerplate that could be abstracted away.
15:49lawfulfalafelI don't really get how I am supposed to keep the numbers I am generating
15:49bhenrylawfulfalafel: you're not thinking functionally
15:50hiredmanyeah, a deftype+helper macro for replacing AFn is just waiting to be written
15:50lawfulfalafelbhenry: so where is the error in my thinking?
15:51raeklawfulfalafel: use let instead of def inside functions
15:51raekdef is not for local variables
15:51bhenry,(doc let)
15:51clojurebot"([bindings & body]); Evaluates the exprs in a lexical context in which the symbols in the binding-forms are bound to their respective init-exprs or parts therein."
15:52raeklawfulfalafel: have you learned about loop and recur?
15:54raeklawfulfalafel: also, in a functional solution, you will typically not have any calls to 'do', 'doseq' or any other construct that is made for side-effects
15:55raeklawfulfalafel: example of a loop in Clojure to sum all numbers between 0 and x: (loop [acc 0, i x] (if (zero? i) acc (recur (+ acc i) (dec i))))
16:05amalloylawfulfalafel: also line 15 you need whitespace after the +
16:14naeuis there a simple way of listing a given object's fields/methods?
16:14raeknaeu: show
16:15naeuraek: thanks
16:15naeunow i need to figure out how to unfreeze emacs
16:15naeui tried this in a slime repl: (println (vec (.getMethods (class f))))
16:15naeuand it totally froze up
16:15raekclojure.contrib.repl-utils/show
16:16naeukilling emacs seems cruel
16:16raeknaeu: I think you can press C-c C-c in the repl
16:16naeuraek: yeah, i've tried that
16:17raekso it froze emacs itself, and not the swank server?
16:18naeuraek: yup
16:18naeuraek: i even killed the swank server and emacs is still frozen
17:08raekhas anyone successfully managed to use autodoc lately?
17:09raekif I use the standalone jar with java -jar, it chokes on my usage of clojure.java.io (seems like autodoc evals the code in clojure 1.1)
17:10raekif I add it as a dev-dependency, it fails because clojure-contrib 1.1.0-master-SNAPSHOT does not exist anymore
17:11void_so I was thinking .. Android is running on JVM. Clojure produces JVM bytecode. Can you create Android apps with Clojure?
17:11void_I mean, yes you can (I googled that), but does anybody do it?
17:12raekvoid_: it is possible, but quite slow currently. I hear they are working on it: http://dev.clojure.org/display/design/Android+Support
17:15offby1void_: actually, Android doesn't run on the JVM. Google wrote their own, incompatible VM called "Dalvik".
17:15offby1In theory, however, it is probably possible to add a Dalvik backend to the Clojure compiler
17:15void_oh yeah I now recall that they have their own
17:16void_so Google have their own Java compiler too?
17:20void_ohhh ->/->> is cool
17:20void_ (->>
17:20void_ (mongo/fetch :expenses)
17:20void_ (map (fn [e] (:title e)))
17:20void_ )
17:20void_this is such beautiful code
17:21raekvoid_: if you tend to use 'map' with anonynous functions a lot, consider using 'for' instead
17:21Chousukevoid_: why not just (map :title)?
17:21raek(for [e (mongo/fetch :expenses)] (:title e))
17:21void_thanks guys thanks ;)
17:22raekeh, what Chousuke said ;-)
17:22void_Chousuke: didn't know you can do that
17:22Chousukeit's one of the little awesome features that Clojure has :P
17:22raekbut seriously. the autodoc deps seems to have been broken for half a year now.
17:23raekis the conclusion that nobody document their code?
17:23raekor have everyone switched to Marginalia?
17:23raek(Marginalia is very neat, but not what I want in this case)
17:25ohpauleezraek: I use Raynes' autodoc AND marginalia in my stuff
17:25ohpauleezand generate both
17:25Raynesohpauleez: I'm fine with just using marginalia, fyi.
17:26raekah, now Raynes' version works for me. wonder what I were doing wrong.
17:26solussd,(->> 3 (* 3) (/ 4) (* 5)) ;it can make ugly code too!
17:27clojurebot20/9
17:27RaynesI have a version of autodoc?
17:27RaynesCool.
17:27raekRaynes: thanks for fixing it
17:27raek[org.clojars.rayne/autodoc "0.8.0-SNAPSHOT"]
17:27RaynesYou're welcome. I'd tell you how I did it if I could remember actually doing it.
17:27RaynesI seem to recall doing something minor to it for my cake autodoc plugin.
17:41void_hmm why doesn't "\n" make a newline?
17:42void_\newline neither
17:42void_oh I got it
17:42void_I wouldn't pass it to println
18:00lawfulfalafeljust out of curiosity, why does the empty list evaluate to true?
18:01lawfulfalafelIt seems like it would be useful for recursive functions that are being passed a list
18:01lawfulfalafelor maybe that's just my n00b opinion
18:01dnolenlawfulfalafel: you have (seq foo) for that. only nil and false are false-y thank heavens.
18:02raeklawfulfalafel: the rules for truthiness is that nil and false are falsey, everything else is truthy
18:02raekthat something empty can be non-nil allows for more laziness
18:03raekotherwise a lazy-seq producing function would have to force the first element to check whether it should return nil or not
18:51zakwilsonIs there a built-in inverse of coll? (like CL's atom)
18:52hiredmancoll? doesn't just test for collections, it tests for IPersistentCollection
18:53Raynes(comp not coll?)
18:53hiredmanso java collections will all return false
18:53hiredmanetc
18:54amalloyzakwilson: no, mainly because clojure has a fuzzier dividing line. it's not "lists vs everything else"
18:56zakwilsonI'd be safe ignoring Java collections in this case, but is there a generic test for single values versus collections that works on everything?
18:57hiredmanit really depends on what you are doing with it, there is no generic always safe test
18:58hiredmanif you are writing a macro and dealing with clojure forms coll? and (comp not coll?) are good enough
19:01zakwilsonThat's exactly what I'm doing.
19:01hiredmanI figured as much
19:02hiredmanI imagine it being part of some elaborate system of macros
19:02hiredmanand then I sigh and try to think of something else
19:03choffsteinHey all -- I have a question. I have a situation where I am building html content using hiccup with different functions. In on area, I have something like "[:li {:id "myTab"} (fn-to-render-content arg1 arg2)]". My issue is that I need fn-to-render-content to return two vectors, not a vector of two vectors. I was thinking about constructing some sort of macro to "unwrap" a vector and return the individual elements ... like "(u
19:03choffstein[1 2 3 [4 5]]))" becomes "1 2 3 [4 5]"
19:03choffsteinIs that possible?
19:04hiredmansounds horrid, but zakwilson is a macro writer, so he can help you
19:05zakwilsonNo elaborate system of macros, but the macro does call a multimethod to mangle its arguments.
19:07zakwilsonchoffstein: you could (apply u [1 2 3 [4 5]])
19:07zakwilsonWell, not u(nwrap), but whatever function it is you want to call on 1 2 3 [4 5]
19:09choffsteinzakwilson: I don't want to apply a function though
19:10choffsteinsomething more like "[a b c (unwrap [d e f])]" would return "[a b c d e f]"
19:10hiredmannot possible
19:10amalloychoffstein: that's not possible
19:11choffsteinboo
19:11amalloyand for good reason
19:11choffsteinalright. can't know unless you ask, right? :)
19:11zakwilson,(flatten [1 2 3 [4 5]])
19:11clojurebot(1 2 3 4 5)
19:11zakwilsonthat's about as close as it gets
19:12choffsteinYeah ... but not quite what I am looking for unfortunately. It is alright.
19:12choffsteinI'll figure it out
19:12amalloywait, choffstein, you want to use this for hiccup?
19:12zakwilsonIt can be done in Common Lisp, but Clojure doesn't have multiple return values.
19:12choffsteinyes
19:12amalloyjust return (list [ret1…] [ret2…])
19:13amalloyhiccup renders seqs by expanding them into the parent element, roughly
19:13choffsteinamalloy: hiccup seems to be running into issue having a parent element with no tag
19:13amalloychoffstein: with a *list* parent element? vectors are not lists
19:13choffsteindoh.
19:14amalloychoffstein: try (html [:ul '([:li 1] [:li 2])])
19:14amalloyi think that ought to return a :ul with two children
19:15choffsteinlist worked ... vector didn't. doh.
19:15choffsteinfeeling stupid.
19:15choffsteinthanks :)
19:15amalloychoffstein: that's because vectors are for introducing html elements, and you don't want to introduce an html element ;)
19:15choffsteinthat makes a completely reasonable amount of sense :)
19:40gigamonkeySo everybody seen Fogus's interview with Hickey? http://www.codequarterly.com/2011/rich-hickey/
19:41brehautgigamonkey: and the companion interview with abelson? ;)
19:42hiredmanI sure hope everyone has seen it, it's been online for *hours*
19:44gigamonkeybrehaut: yeah, you can read than one too. ;-)
19:44gigamonkeyhiredman: come on, we're on Internet time here.
19:44hiredmansorry
19:45hiredmanit's been online for *beats*
19:45gigamonkeyheh.
19:46brehauthah
19:46devngigamonkey: i have now
19:48offby1what devn said :)
19:53offby1"optional type hints", eh? Cool
20:17offby1"Hammock-Driven Development". I'd sign up for that.
20:19MoominpapaI imagine I'll get a "doc" answer for this one, but is there a function in the standard library equivalent to (fn [coll­ f] (redu­ce #(ass­oc %1 %2 (f %2)) {} coll)­)?
20:21brehaut(into {} (map (juxt identity f) coll))
20:22hiredmanwrong
20:22brehautfigures
20:22hiredmanMoominpapa: not really
20:22hiredman,(let [a {:a 1}] (zipmap (keys a) (map inc (vals a))))
20:22clojurebot{:a 2}
20:23MoominpapaI guess group-by does the opposite...
20:23hiredmanbrehaut: pardon me, I think I misread that
20:24brehauthiredman: no problem
20:27MoominpapaThanks.
20:32technomancyclojurebot: uh oh
20:32clojurebotExcuse me?
20:33MoominpapaIt uses leiningen... :)
20:52__name__Nice nick, btw :)
20:53offby1there's an offbyone out there, too; we run into each other occasionally and duel
20:54__name__Heh
21:36mattb[]howdy
21:37mattb[]brand new to clojure, lisp, and functional programming in general (raised on C)
21:37mattb[]I was looking at different fibonacci implementations and found one using data recursion rather than function recursion:
21:38mattb[](def fib-seq (lazy-cat [0 1] (map + (rest fib-seq) fib-seq)))
21:38mattb[]two questions about this:
21:38amalloymattb[]: yeah, brehaut likes that one
21:39mattb[]1. does evaluating (rest fib-seq) and fib-seq in the map reevaluate the sequence for *each*, or once the lazy sequence is evaluated does it cache the values?
21:39amalloylazy seqs are cached
21:39mattb[]2. how does the functional community look at problems like this; prefer data recursion, or prefer function recursion?
21:39mattb[]alright cool, I figured
21:39amalloymattb[]: the definition there is one that's popular in haskell
21:39mattb[]something about data recursion seems ridiculously elegant to me
21:39brehautdata recursion like that is good in haskell, less good in clojure
21:40mattb[]ah
21:40brehautbecause its hard to define that in a non-global way
21:40brehauts/hard/awkard/
21:40sexpbot<brehaut> because its awkard to define that in a non-global way
21:40mattb[]gotcha
21:40dnolenbrehaut: I disagree.
21:40dnolenmattb[]: that style is natural in Clojure as it has neither TCO nor Haskell laziness.
21:40amalloyin clojure i like ##(take 15 (map first (iterate (fn [[a b]] [b (+ a b)]) [0 1])))
21:40sexpbot⟹ (0 1 1 2 3 5 8 13 21 34 55 89 144 233 377)
21:42mattb[]I've come to appreciate s-expressions pretty quickly, but I still have a crazy hard time wrapping my head around code
21:42amalloy$google clojure rosetta-code fibonacci
21:42sexpbotFirst out of 61 results is: Fibonacci sequence - Rosetta Code
21:42sexpbothttp://rosettacode.org/wiki/Fibonacci_sequence
21:42brehautdnolen: im weak on binding-fu and vars, but i dont know how to create a definition of fib like the recurvsive one mattb[] showed that doesnt have a global var (and the head-retention that goes along with it)
21:42amalloymattb[]: an explanation of my code is there
21:43mattb[]awesome thanks amalloy
21:43brehautdnolen: what have i got wrong ?
21:43dnolenbrehaut: you can name anon fns.
21:43brehautdnolen: im not sure if we are talking about the same thing?
21:43brehautoh
21:44brehautactually we are and i misread the definition
21:44dnolenmattb[]: lazy-seqs are particularly powerful as they can be mutually recursive.
21:45mattb[]so this wikipedia article claims the haskell-inspired fib to be "more elegant"; what makes you prefer the iterate version amalloy?
21:45amalloymattb[]: well, if someone on rosettacode says it's more elegant, it must be true...
21:46mattb[]oh lol this isn't wikipedia.. duh
21:47amalloymattb[]: the way the haskell version is implemented on rosetta code involves holding the head of the lazy sequence, so would eventually run out of memory
21:47mattb[]"map first ;; throw away the "metadata" (see below) to view just the fib numbers" it doesn't explain this; what's the deal with metadata?
21:47mattb[]ahh ok
21:47mattb[]that's what was meant by head retention
21:47amalloydnolen is probably right in that it could be implemented better
21:48amalloymattb[]: when i wrote that, i meant something like "turn each [prev, next] pair into just one integer"
21:48amalloyfeel free to edit in a way as to make that clearer
21:48mattb[]ah k
21:50mattb[]this does seem a lot more sane than the "more elegant" version
21:51amalloyit's an acquired taste, i'm sure
21:53mattb[]thanks for the help guys
21:55mattb[]by the way, in the doc for iterate: "f must be free of side-effects" how is this explicitly enforced? are builtins flagged for whether or not they allow side effects?
21:55brehautmattb[]: its not
21:55danlarkinit should read "f _should_ be free of side-effects"
21:56mattb[]k
21:57brehautmattb[]: an effects tracking system is requires a lot of complexity (see also: haskell) akin to (or part of) a type system
21:57mattb[]aye
21:58mattb[]am I right in seeing haskell as more of a research language than for practical use?
21:58brehautmattb[]: http://www.codequarterly.com/2011/rich-hickey/ search for "I think Haskell is a fantastic" and read the next 3 paragraphs
21:58dnolenmattb[]: not true these days, people using haskell for pratical things.
21:58brehautmattb[]: not really.
21:58brehautmattb[]: its practical once you master it, its just not easy to master
21:59mattb[]ah
21:59dnolenmattb[]: also possible to get verification for Clojure via Datalog/Prolog, I'm working on that.
21:59mattb[]nice link brehaut
22:03mattb[]something I was having a hard time finding is in situ algorithms in functional languages; the quicksort example I saw for clojure specifically mentioned that "this isn't really quicksort since it's not in situ"
22:03mattb[]what would something like that look like?
22:04brehautit would look like the imperative example that had been mangled a little, and it would operate on a transient
22:04brehautin the future it might operate inside a pod, and in haskell it would exist inside an effectful type context.
22:04mattb[]is this a case where such an algorithm would just be a poor choice for a functional implementation?
22:05brehautit depends?
22:06mattb[]I mean, do you reap the memory benefits of an in situ algorithm if it's not in situ?
22:06dnolenmattb[]: remember Clojure's not didactic about purity, you can implement quicksort on a mutable array if you like.
22:06mattb[]aye, I'm thinking more from a general functional context though
22:06dnolenfunctional languages like OCaml and Standard ML have similar escape hatches.
22:06mattb[]still trying to wrap my head around how you guys get anything done without state :p
22:06brehautmattb[]: we use state when we need to
22:07brehautclojure excels at handling state
22:07mattb[]I see
22:07dnolenmattb[]: Clojure probably has more state management facilities than pretty much any language out there except Haskell.
22:07brehautas dnolen said, theres mutable arrays, we have access to javas mutable collections, transient versions of clojures collections, and a grab bag of great reference types
22:10brehautmattb[]: imperitive state is also trivially modelable as a bunch of functions that take a 'world' and return a new 'world, and through the power of higher order functions, you can abstract that away
22:12brehautyou might have encountered these in C# or F# as Linq or Workflows if you've lived in dotnet land
22:13mattb[]yep, coming from C# actually
22:13brehautC# is actually a pretty decent halfway point to functional languages
22:13brehautits just the average stdlib that lets it down
22:13brehaut(ie, all the old stuff)
22:14mattb[]the biggest hurdle so far is remembering what data structures look like in clojure; I keep trying to pass an integer from a vector to map lol
22:14mattb[]the whole lisp thing is eating my brain
22:14brehauti dont follow
22:15mattb[]just misinterpreting what I'm actually passing around
22:16mattb[]is that "ants" demo from rich hickey still a good example to learn from? I know a few minor things changed syntax-wise
22:16mattb[](e.g. vec in lieu of apply vector)
22:17brehauttheres also a few fairly significant library additions that make the ode a bunch cleaner
22:17brehautand defstruct has been deprecated
22:17mattb[]aha
22:17mattb[]that's good to know
22:17brehautit uses (dorun (for …)) or something (could be doall, or have a map or something) where doseq would be better
22:18brehautand it uses send-off in place of (for example) future from memory
22:19mattb[]dorun retains the head like doall?
22:19brehautnah one of them doesnt
22:20mattb[]k
22:20brehautbut doseq should generally be your first choice for side-effects on sequences
22:20brehautnot least of all because it has full comprehension notation supported
22:21brehautdoall retains the head btw, dorun discards
22:21mattb[]yeah
22:22mattb[]found a couple list messages about them
22:23mattb[]by the way, can fn [_] be anonymized? I found I couldn't get it to infer an argument in an anonymous function without using it
22:23mattb[](by anonymous I mean #, maybe that's just sugar?)
22:23brehautby fn [_] you mean a functio nthat ignores its argument?
22:24mattb[]yea
22:24brehautyou cant use the #() reader form to abbreviate it no
22:24mattb[]k
22:24brehautbut constantly might be what you are after
22:24brehaut&(map (constantly :a) (range 10))
22:24sexpbot⟹ (:a :a :a :a :a :a :a :a :a :a)
22:25amalloy&(map #(do % :a) (range 10))
22:25sexpbot⟹ (:a :a :a :a :a :a :a :a :a :a)
22:25brehautamalloy: yuk :P
22:25mattb[]haha
22:25amalloynot recommended, but fulfills the stated requirements
22:26mattb[]what does evaluating the arguments even do?
22:26amalloy?
22:27mattb[]if you did that to a list with a function in it, would it call the function?
22:27mattb[](the do %)
22:27amalloyno
22:27amalloyit's a no-op, although it might not get entirely compiled away
22:27mattb[]k
22:28mattb[]when was defstruct deprecated? it's not documented as such in the api ref
22:28brehautit was deprecated when defrecord was introduced
22:30brehauthttp://clojure.org/data_structures#Data%20Structures-StructMaps
22:30brehautthe word 'depreciated' isnt used
22:30mattb[]indeed
22:30mattb[]I disregarded that note before
22:30brehaut"Note: Most uses of StructMaps would now be better served by http://clojure.org/datatypes.&quot;
22:30mattb[]so defstruct was a hashmap and defrecord is an actual java class with final fields?
22:31brehautdefrecord is still a map
22:31brehautbut yes, its backed by a custom class
22:32brehautconsider them an intermediate feature of the language though, you dont need them
22:33mattb[]so in hickey's example, (defstruct cell :food :pher) would be better served by defrecord or a different structure entirely?
22:34brehaut'better' how?
22:34brehautfor performance, yeah a record
22:34brehautbut a map would suffice
22:34mattb[]in terms of deprecation/more "functional"
22:34mattb[]k
22:34brehautneither is 'more functional'
22:35brehautstructs were just maps with certain keys given a performance optimisation
22:35mattb[]aye
22:36brehautthe clojure idiom is to write your code in terms of the abstraction, in this case maps (with keyword keys)
22:36brehautand maps are the general case of that
22:37brehautwith structs and records as implementation details
22:37mattb[]gotcha
22:37brehautthats good, cause i made a meal of the typing ;)
23:08dnolenman I love macros
23:10brehautdnolen: any particular reason today?
23:11dnolenbrehaut: implementing IFn deftype in pure Clojure, lots of crazy boilerplate eliminated.
23:11brehautoh true cool
23:12brehautifn has a million arg variations right?
23:12dnolenyeah
23:47amalloypsh. i'm sure careful consideration went into each line of AFn.java
23:48brehautim sure it was either a hand manging emacs chord or an arcane jumble of vim
23:50dnolenAFn.java would drive anyone screaming to macros.
23:51amalloydnolen: so you might think, but look at MouseAdapter in awt
23:52mattb[]hahaha
23:52mattb[]just looked up afn.java
23:53mattb[]I'd like to believe someone did this by hand