#clojure logs

2012-07-29

00:04muhoohuh, suddenly realized i can write SPA's in cljs that compile down to one .js file, and then deploy it on apache or whatever, without clojure (once it's compiled)
00:07howard_any Aussie friends?
00:17RaynesCrikey mate.
00:27muhooflatstick
00:35gerthoward_: kiwi here
00:55howard_my developer manager is a kiwi D:
00:55howard_:D
00:56gertI'm not a real kiwi though. just a dutchman posing as one
00:56howard_hahaha
00:56howard_Guten tag!
00:56gertthat's german!
00:56howard_oops
00:56howard_sorry
00:56howard_haha
00:56gertnot that there's anything wrong with that :)
00:57howard_Dutch is... west germantic
00:57gertso is english
00:58howard_ok
00:58gertjust sayin' :)
00:58howard_"Dutch is grammatically similar to German, such as in syntax and verb morphology"
00:59howard_Clojure is grammatically similar to Common Lisp, such as in syntax and macro
00:59howard_hehe..
01:01nsxthmm... i've a string within a (let), which i want to use to call a function with the same name as the value. the ((resolve (symbol )) etc. trick doesn't seem to work - is this a scope issue that's biting me?
01:02howard_dynamic code execution
01:03howard_have a look at this:
01:03howard_http://stackoverflow.com/questions/11069825/clojure-why-load-string-does-not-work-in-this-case
01:03howard_i had some issue with dynamic code executing some time ago
01:03howard_and there's bit more information in that post
01:06nsxtso how would i access that function, without resorting to eval?
01:07howard_um..
01:07nsxtlet me refheap this to make it easier
01:09howard_do you wanna use read-string?
01:09nsxthttps://www.refheap.com/paste/3869
01:10nsxt(useful.string/dasherize operation) evaluates to 'list-tables'
01:11howard_let me try something
01:11howard_i remember people said clojure cannot dynamically execute code in lexical binding
01:12muhoowow, this noir-cljs browser/repl is fragile as hell
01:12nsxtthanks, howard_. also, i could be approaching this entirely the wrong way (first project)...
01:13muhooneat hack though
01:13howard_, (let [fun #(prn "ha")] ((resolve (symbol "fun"))))
01:13clojurebot#<NullPointerException java.lang.NullPointerException>
01:14howard_i think that is the problem you ran into
01:14howard_clojure apparently does not support dynamically execute code and refer variables in lexical context
01:15howard_, ((resolve (symbol "prn")) "ha")
01:15clojurebot"ha"
01:15howard_see, that one works because prn is root binding, not lexical binding
01:15nsxtright.
01:16howard_actually, i too am developing an application that requires such behaviour
01:16howard_this problem has good workaroundability
01:16nsxtit seemed better to try something like this than to build up a map of strings to functions
01:16howard_the solution I worked out is: make a map of keywords -> functions
01:16nsxthaha
01:16howard_<3
01:16howard_bingo
01:17nsxtyeah, kind of a bummer, but if there's no way around it, then so be it
01:17nsxtthanks for the help
01:17howard_i wish i could find a better solution
01:17howard_dynamically execute code in lexical context will be so helpful
01:18howard_there's another way, though
01:18nsxthm?
01:19howard_not very readable, not elegent
01:19howard_you can put the whole lexical bindings into the evaluated string
01:19howard_:D
01:19nsxtyeah, i thought about that
01:19alandipertthe problem is to eval a function named after a string that's been let?
01:19nsxtbut that reads like garbage
01:19howard_yeah...
01:19nsxtalandipert: correct
01:20alandipert,(let [x "+"] ((symbol x) 1 2))
01:20clojurebot2
01:20howard_symbol + is a root binding and it works
01:20howard_however, if x was a function, it won't work
01:21alandipertoh, i see
01:21alandipertthe function you want to invoke is a local
01:21nsxti guess i could always use a function to extract the dasherized name
01:21nsxtso same thing as pulling it out of the let, except not destroying the readability
01:21alandipertyes, i think there is probably a better alternative - this would be an exceedingly rare thing to want to do
01:22alandipertmacros do have access to the local environment via &env... if you want to keep hacking ;-)
01:22nsxtstill, i'm glad i stumbled across it
01:22alandipertyup that's good stuff
01:25alandipertnsxt: btw, you know you can do: (let [f #(prn "hey")] (f)) ?
01:27nsxtthe problem is that i don't want to define the function within the scope of let
01:32alandipertnsxt: https://www.refheap.com/paste/3871 super hacky and inadvisable, but shows you you can get at locals with a macro
01:33nsxtalandipert: ha, cool
01:45muhoocljs stacktraces are so much more awesome than regular jvm stacktraces: https://www.refheap.com/paste/3872
01:57nsxtthis is driving me nuts, i'm still getting null pointer exceptions
02:18samrathow do I use a scala project(https://github.com/jiminoc/goose) in a clojure project?
02:18samratI found a few tutorials, but they all involved a .jar file
02:18samratand I'm not sure how to make the jar
02:30alandipertsamrat: if you clone and 'mvn install' you should be able to add [com.gravity/goose "2.1.19"] as a lein dep
02:31alandipertotherwise maybe it can be found in a mvn repo somewhere
03:30tos9So, clj will execute a .clj without any namespace declared, but clojure-py does not, and requires an ns. Why is that?
03:32howardclear
04:01emezesketos9: Apparently JVM Clojure just uses the user namespace by default if no ns has been set
04:01emezesketos9: There isn't a language specification per se
04:02emezesketos9: The JVM implementation sort of is the "language specification", if you will
04:02tos9emezeske: Aha cool I was looking for something that clarified whether the spec specified that or not. Good to know.
04:02tos9(That there isn't one :)
04:02emezesketos9: There might be something like that in the docs somewhere, but I am not aware
04:03tos9I think as long as I'm aware of it I can remember to do it always, just hoping that the amount of implementation specific behavior I run into is going to be minimal :)
04:03tos9(or documented :)
04:04muhooemezeske: lein-cljsbuild or noir-cljs, which do you think i should use? :-)
04:04emezeskemuhoo: Well, I'm a bit biased ... :)
04:04muhoohehe
04:05emezeskeI haven't used noir-cljs, so I honestly can't say
04:05emezeskeI use lein-cljsbuild for my personal projects, surprise surprise
04:05muhoofair enough. i spent a few hours trying to get noir-cljs to work, next step is to try yours instead
04:07muhootomorrow though. it's bed thirty now.
04:23michaelr525good morning!
04:34emezeskemuhoo: I hope it works out!
08:35rfgpfeif1erjoin #lwjgl
08:35rfgpfeif1ersorry
08:36rbarraudNeed a leading '/' :)
08:38hyPiRionheh
09:04augustlwant to run "java -jar plovr.jar serve config.js" automatically when I "lein ring server". Is that possible?
10:29justin173what's everyone using to manage state in their cljs apps these days? I'm currently using a horrible combination of waltz, Clojurescript One style event dispatch, and route dispatching, and I really can't decide which one to stick with
10:31pandeirojustin173: i feel ya
10:31pandeiroi was using cljs one's dispatch but i think on my next project i will try waltz
10:33justin173yeah waltz seems cool
10:34pandeirowhat issues (if any) are you having, specifically?
10:35justin173well, should I be using waltz for every little widget thing I have?
10:35pandeiroah yeah, right
10:35justin173like it's probably obvious it doens't need to track state for little collapse/expand text boxes
10:35justin173but what about a widget that say has a main-image window then a list of thumbnails that allows you to cycle through them?
10:36pandeiroi think you could use it for all of it
10:36pandeiroi remember the cljs one dispatch functions for the little text box animation; something so simple had like 12 separate events dispatching
10:37foodooI haven't really workey with Clojurescript before, but maybe this Closure Library is helpful for managing state? http://closure-library.googlecode.com/svn/docs/namespace_goog_storage.html
10:39justin173foodoo: yeah that's part of the thing too, there's like a bunch of clojurescript only solutions, and then that doesn't even get into the google closure ways of doing thing. although to be honest the storage aspect isn't the thing I'm having difficulty with
10:42pandeirojustin173: i think maybe simpler widgets could just be written as one multimethod
10:42pandeiroi mean with different methods dispatched based on state
10:42pandeirobut that's basically waltz
10:42pandeirofrom what i understand
10:43justin173yeah
11:32qerubIs there any way to simplify (doseq [x xs] (f x)) using clojure.core? (map f xs) would do the trick, but I'm not interested in the return value.
11:36pandeiro(defn do-f [xs] (doseq [x xs] (f x))) ?
11:36pandeiroi know it's not clojure.core but it's a one-liner
11:43Bronsa(dorun (map f xs))
11:48qerubpandeiro, Bronsa: Thanks! I'll go with dorun.
12:06qerubHow do I check if a value is an ISeq? (Hint: it's not `seq?`.)
12:07qerubSomething better than (or (seq? x) (vector? x)) would be nice. :)
12:09antares_qerub: it is clojure.core/seq?, if all you care about if a structure implements ISeq
12:09qerub(seq? []) => false
12:09qerubAren't vectors ISeq?
12:10antares_ther are also coll? and sequential?, with coll? being typically what people want
12:10qerubHmm, so vectors aren't ISeq.
12:10Bronsathey are Seqable
12:11qerubOK, this explains everything. Thanks.
12:12wilfredhis there a Clojure equivalent of Python's repr()?
12:13wilfredhi.e. (some-function [1 2 [3 4]]) => "[1 2 [3 4]]"
12:14Bronsastr?
12:14clojurebotbrehaut: I think struct embedding is monkey patching / mixins, and interface embedding is duck typing / typeclasses
12:14Iceland_jack,(str [1 2 [3 4]])
12:14clojurebot"[1 2 [3 4]]"
12:14qerub,(str "foo")
12:14clojurebot"foo"
12:15qerubrepr("foo") => "'foo'"
12:15Bronsa,(str (range 3))
12:15clojurebot"clojure.lang.LazySeq@7480"
12:15Bronsa(pr-str (range 3))
12:15Bronsa,(pr-str (range 3))
12:15clojurebot"(0 1 2)"
12:15Bronsamaybe you want pr-str instead of str
12:15Bronsa,(pr-str "a")
12:15clojurebot"\"a\""
12:16wilfredhah, I should have thought of str
12:16wilfredhI'm trying to get the source of a given function, but it seems clojure.repl/source calls println which is what stopped it worked
12:17wilfredh*stopped it working
12:17Bronsa,(with-out-str (println "derp"))
12:17clojurebot"derp\n"
12:17wilfredhperfect. thanks :)
12:31antares_,(prn [1 2 3])
12:31clojurebot[1 2 3]
12:31antares_,(prn [1 2 { :a 1 }])
12:31clojurebot[1 2 {:a 1}]
12:38dp42Hi everyone, any recommendations on debugging a C2/clojurescript piece of code? The firebug pane is not quite helpful :)
13:15the-kennydp42: Debugging is kinda hard. I'd give the REPL a shot.
13:17harjaQuestion on macros. Is there a way to apply something for each element in body and expand that on runtime? I'd need to transform (1 2 3) to (do (foo-do 1) (foo-do 2) (foo-do 3))
13:19the-kennyYou want unsplice
13:19the-kenny,`(do ~@(1,2,3))
13:19clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>
13:19the-kennyWhoops
13:20the-kenny,`(do ~@(map (fn [a] `(foo ,a)) '(1 2 3)))
13:20clojurebot(do (sandbox/foo sandbox/a) (sandbox/foo sandbox/a) (sandbox/foo sandbox/a))
13:21the-kennygnah. Something like this :)
13:21harjathe-kenny: wow, exactly what I was looking for
13:21harjathanks!
13:24the-kennyLet's make it correct and nice: (let [syms (for [a (range 4)] (list 'foo a)) ] `(do ~@syms))
13:43harjathe-kenny: Is this a good way to do this? https://gist.github.com/3200531 I'm just wondering about the eval-thing on the let form. I'm completely new to clojure and this macro thingy :)
13:44the-kennyharja: You almost never need eval. Let me take a look :)
13:44the-kennywhy do you even eval notes?
13:45harjaI need to get the result from executing the function (chord xx yy)
13:45harjaif I did not put eval, it did not work the way I wanted
13:45harjait just mapped over the list (chord :A4 :major)
13:45the-kennyWhy do you even use a macro there? :)
13:46harjaWell, initially i tried (defn play-chord [ts chord] (at ts (map sampled-piano chord))) but it invoked it immediately
13:47harjaand then I tried (defn play-chord [ts chord] (map #(at ts (sampled-piano %)) chords)) but it did not work either
13:47harjachords => chord
13:47harjait just got played immediately I executed the play-chord -function
13:47harjawith the macro form, it works like it's supposed to
13:48harjathe-kenny: how do I get rid of the eval?
13:50the-kennyI think you want (defn play-chord [ts notes] (doseq [n notes] (at ts (sampled-piano n)))) :)
13:51harjaooh :)
13:51harjaworks!
13:51harjadoseq... okay
13:51hyPiRionHm.
13:51the-kennydoseq is like a "conventional" while-loop, running a piece of code with side effects for each element in 'notes'
13:52harjathe-kenny: yeah, seems logical. Thanks a lot!
13:52the-kennyYour map-version most likely didn't work because lazy evaluation. doseq isn't lazy
13:52harjaBut, getting to the original problem, supposing I want to do something like that with a macro
13:52harjais the eval necessary there? if it is not, how to overcome it?
13:52hyPiRionharja: I don't even think you need a macro here.
13:53harjawell, supposing I want to generate code on the fly
13:53the-kennyhyPiRion: We had that already :) It's just theoretical now
13:53harjathis is just purely hypothetical now
13:53harjayes
13:53hyPiRionAh.
13:53the-kennyharja: You could move the whole map-thingy into the code emitted by the macro itself
13:54the-kennyEw, no. You couldnt :)
13:56hyPiRionOne would usually take use of apply here.
13:58hyPiRionIs overtone.live/at a macro?
13:58harjahyPiRion: yes
14:08davidd`hey guys, I'm confused about some terminology in clojure. what exactly is a form? is it just a list that's going to be executed e.g. (str "1" "2")?
14:09davidd`or is str the form in this case?
14:09jjidodavidd`: I think it is the list
14:09davidd`awesome. thank you jjido.
14:12harjahyPiRion: Do you mean I replace eval with something like (apply (resolve (first notes)) (rest notes))
14:17hyPiRionharja: If overtone.live/at was a function, you could have done (apply at (+ 1000 (now)) (map sampled-piano (chord :A4 :major7)))
14:17hyPiRionThough since you're dealing with side-effects, the-kenny's solution seems more appropriate.
14:18devnisn't there an apply-at?
14:18devnor something?
14:18devnmaybe im just remembering wrong hyPiRion
14:26harjadevn: Yeah! Actually there is :)
14:26harjaThanks for the info.
14:26harjaThe overtone cheat sheet did not mention that
14:28hyPiRiondevn: I've not used overtone, so don't ask me ;)
14:36gfredericks$findfn pos? [-1 1 -3 3] [[1 3] [-1 -3]]
14:36lazybot[]
14:38Bronsa(juxt filter remove)
14:38gfredericksyeah deffing that now
14:38gfredericksgood point that's too short to def
14:38Bronsait traverses the seq twice though
14:38gfredericksyep
14:38gfredericksso does split-with
14:39Bronsaif I am not mistaken there is a function in flatland/useful that does that without traversing it twice
14:39gfredericksI would be shocked if there weren't
14:39gfredericksthis is cljs though so even if I weren't lazy that wouldn't be immediately helpful
14:40Bronsauseful.seq/separate
14:40Bronsaoh, ok
14:44wingyanyone here knows why i would wanna use https instead of http for fetching libs like jQuery et al
14:46hyPiRionwingy: ...security?
14:47wingyhyPiRion: but for a lib file?
14:48wingywhat kind of things am i prohibiting an hacker from doing?
14:48Natchsome browsers will whine if your main pages are over ssl and you fetch stuff unencrypted
14:48Natchmight become a user issue if that's something you need to consider
14:48wingyNatch: whine how? as console.logs or does the user sees those warnings?
14:48Spaceghostc2cbrainproxy: I've decided to start learning clojure. :D
14:49wingySpaceghostc2c: (y)
14:49Spaceghostc2cNow to locate the thread in the mailing list about restricting reader macros.
14:49Natchwingy: you've never visited a site with mixed connections in firefox? I get those dialogues all the time about site trying to fetch stuff. or maybe it's just send.. might be just send
14:50prestowingy, the user does see warnings, yes.
14:50wingyok
14:50wingyi guess https it is then
14:50wingyquite impressive how you have added security by just adding an "s" :)
14:51Natchwell it will probably prevent someone snooping from knowing what you're doing
14:51Natchand inject stuff mand in the middle
14:51Natch:P
14:51Natch*man
14:58hyPiRionwingy: as Natch said, it'll reduce the possibility for man-in-the-middle
14:58wingyhyPiRion: so they cant manipulate the jQuery file im fetching?
14:58gfredericksright
15:02Spaceghostc2cGenerally, I do most things over https. But if whatever I'm transmitting has nothing to do with authentication or anything remotely important, I'll use http.
15:03hyPiRionwingy: Well, it'll be harder, at least.
15:18Spaceghostc2cCan I use lein to keep leiningen up to date?
15:19NatchSpaceghostc2c: "lein upgrade"
15:19cmajor7is there a clojure lib that does registration/activation email thingy?
16:30FrozenlockHow does one load a binary file in clojure? I tried slurp and spit for a simple copy, but the resulting file is not the same as the original :(
16:39antares_Frozenlock: JVM distinguishes between binary streams and character streams. Also, encoding setting matters, especially on OS X. Use http://clojuredocs.org/clojure_core/clojure.java.io and maybe https://github.com/Raynes/fs/
16:41FrozenlockThanks a lot!
16:54justin173stupid question but is there an easy wat to get a current index of an item in the middle of a doseq?
16:57devnjustin173: could you make it indexed first?
16:57devn,(map-indexed vector [1 2 3 4 5])
16:57clojurebot([0 1] [1 2] [2 3] [3 4] [4 5])
16:58justin173yup that's exactly what i'm looking for thanks!
16:58devnyw
16:58justin173i swear I'm never going to fully learn the core api
16:59devnjustin173: it takes some time to internalize it. it's easy to say: oh ill just use an atom! but usually, TAFFT (There's a Function for That)
17:00justin173devn: yeah at least I can sense when there's probably some stupidly simple solution to my issue so I can ask here :)
17:25FrozenlockOk now I'm trying to print the byte-array I have, but instead it only prints "[B@44bcc9bd". Any advices?
17:25FrozenlockI've tried both println and write method for my printstream.
17:33aperiodichuh, that's weird. it seems like its writing out the string representation of the byte array object, rather than its contents
17:34antares_Frozenlock: (String. ^bytes your-byte-array) creates a string from it
17:35antares_aperiodic: byte arrays do not have "string representation" beyond what Frozenlock has demonstrated
17:35antares_character arrays do but not byte arrays
17:35antares_but you can instantiate a string from a byte array
17:35FrozenlockWait, I need to convert my byte-array to string?
17:36antares_if you want to print it as a string
17:36antares_if you want to treat it as a byte array, use what you have
17:36antares_but byte arrays do not have string representation that is human readable
17:36FrozenlockNot really, I want to write it as a binary file :s
17:36aperiodicantares_: maybe "string representation" is the wrong word, but i mean the string that says "there's an array of bytes at memory location 44bcc9bd"
17:37antares_byte buffers kinda do, (java.nio.ByteBufer/wrap …)
17:37aperiodiclike what shows up in stacktraces
17:37antares_aperiodic: [B says "it is an array of bytes"
17:37aperiodicyeah
17:37antares_that's java.nio.ByteBuffer, of course (double f)
17:41brainproxySpaceghostc2c: awesome, glad to hear it :)
17:42brainproxyI've been away from IRC for most of the weekend, leaving again now, but I'll be back on later tonight
17:42brainproxyI definitely recommend the O'Reilly book "Clojure Programming" -- good place to start, especially w/ your strong background in ruby
17:43FrozenlockThat's odd.. I read a .jar file, zip it using the zipping utility, and I get a file twice as large as the original...
17:43FrozenlockDamn you, file manipulation!
17:44aperiodicFrozenlock: (with-open [w (java.io.FileOutputStream. "foo")] (.write w (byte-array [(byte 33) (byte 35)]))) results in a file with just a shebang for me
17:48gunsThe destructuring form [& {:keys [a b] :or {a 1 b 2}] seems clunky. Are there downsides to simplifying that to [& {:keys {a 1 b 2}}]?
17:49aperiodicFrozenlock: if you want to do binary output, i think you want a FileOutputStream rather than a PrintStream; PrintStream seems to be designed to print string representations of data, which is probably why you were getting that "[B@..." nonsense in your output (note there's no print(byte[]) method for PrintStream)
17:49botterCan anyone here recommend good Clojure books, that they have actually used?
17:49botterI have Java experience, but no functional programming experience at all.
17:50Frozenlockaperiodic: That makes sense. I mean, NOW that you have said it :P
17:50botterAnd I'm looking at The Joy Of Clojure, and Clojure Programming by OReilly
17:51johnthejohnAs a programmer new to functional programming, what is the recommended way of learning Clojure?
17:53gunsbotter: Joy of Clojure assumes some familiarity with Lisp
17:53botterguns, do you have any experience with Clojure Programming?
17:53mybuddymichaelI'm reading through Clojure Programming right now. It's better for the newbie than JoC.
17:54gunsbotter: I've heard the book by stu halloway is better if you don't have lisp experience
17:55gunsjohnthejohn: Doing just the first chapter of SICP (in old MIT Scheme) goes a long way
17:55cemerickguns, botter: FWIW, we didn't assume any prior lisp experience.
17:56botterAh! The author himself!
17:56botter:D
17:57cemerick:-)
17:57cemerick*co*author
17:57cemerickbotter: Also FWIW, to get a sense of what the objectives were: http://clojurebook.com
17:58Raynescemerick, guns, botter: FWIW, none of the books assume prior Lisp experience. Where people get this stuff in their heads continues to elude me.
17:58Frozenlockaperiodic: It was indeed the PrintStream which was messing things up, thank you very much ^^
17:58botterRaynes, I assumed they did
17:58RaynesAFAIK, most Clojure programmers didn't come from a Lisp background.
17:58botterBut I'm looking at Amazon's preview of Clojure Programming (the OReilly one) and it looks good
17:59FrozenlockRaynes: I come from an Emacs-lisp background :)
17:59cemerickRaynes: Quite; although I haven't bought the 2nd ed of PC.
17:59FrozenlockBut Im no programmer so...
17:59cemerickso, I try to not say anything about it. :-)
17:59gunsRaynes: maybe you'd agree that JoC is not a very gentle introduction
17:59antares_hey cemerick, hey Raynes
17:59antares_cemerick: are the state of clojure results ready yet?
18:00Raynesguns: It wasn't meant to be, but that certainly has nothing to do with requiring prior Lisp experience.
18:00antares_I am very curious about them :)
18:00cemerickantares_: coming sometime this week.
18:00antares_cool
18:00cemerickI may not actually read all of the comments this time. *Tonnes* of responses.
18:02antares_Raynes: I heard from monger today, it says it badly wants to be reviewed by a rad Clojure hacker. Bonus points if he/she is a southerner.
18:03antares_cemerick: do you know how many people approximately took the survey?
18:04cemerickI do, but don't want to spoil the surprise. :-)
18:04antares_ok, fair enough :)
18:04cemerickMore than 2011, we'll say. ;-)
18:05Raynesantares_: I heard from my knuckles today. It says it really wants to be embedded in someone's face. Bonus points for Swedes.
18:06RaynesIn all seriousness, just haven't had a chance yet. I apologize. :(
18:07antares_it's a good thing I am not a Swede :)
18:21jamiiFirst pass at a datalog compiler: https://gist.github.com/3202150
18:48francis(((:foo 0) ({:bar :baz} 1)))
18:48francis(eval (((:foo 0) ({:bar :baz} 1))))
18:50francissorry, thought that the chatbot would evalute that. Anyway, why does this return a null pointer exception?
18:52francisI realize that its this set doing it, and apparently it's getting evaluated as a funciton. Do sets always do this? do I have to quote everytime I end up with somthing like this? ({:bar :baz} 1)
18:54arohner,({:bar :baz} 1)
18:54clojurebotnil
18:55arohneryour real problem is:
18:55arohner,(nil nil)
18:55clojurebot#<CompilerException java.lang.IllegalArgumentException: Can't call nil, compiling:(NO_SOURCE_PATH:0)>
18:55arohner(nil)
18:55arohner,(nil)
18:55clojurebot#<CompilerException java.lang.IllegalArgumentException: Can't call nil, compiling:(NO_SOURCE_PATH:0)>
18:56francisI
18:57francis'm confused (suprise!) why is that nil?
18:57presto,(#{:meh} : meh)
18:57clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: Invalid token: :>
18:57francisThe set fn (I'm assuming) would return the val at the passed index
18:57presto,(#{:meh} :meh)
18:57clojurebot:meh
18:57francisah
18:57presto,(#{:meh} :bleh)
18:57clojurebotnil
18:58francisthanks
18:58prestoHash set. :=D
18:58francisnifty stuff
18:59presto,([:meh] 0)
18:59clojurebot:meh
18:59presto,([:meh] 1)
18:59clojurebot#<IndexOutOfBoundsException java.lang.IndexOutOfBoundsException>
19:00muhoo,(:meh #{:meh}) ;; also,too
19:00clojurebot:meh
19:01francisSets have no order to them right? Hence the above functionality
19:01prestoYes. I prefer the other order though, are both clojurey?
19:01presto^ to muhoo
19:02prestofrancis, yes, no guaranteed order, as far as I know.
19:02muhoopresto: i use both, depending on the context
19:03prestofrancis, well, there is sorted-set.
19:03presto,(sorted-set :meh :bleh)
19:03clojurebot#{:bleh :meh}
19:03presto,(hash-set :meh :bleh)
19:03clojurebot#{:bleh :meh}
19:05presto,(hash-set :b :c :a)
19:05clojurebot#{:a :c :b}
19:05presto,(sorted-set :b :c :a)
19:05clojurebot#{:a :b :c}
19:05prestoThere we go. o-o
19:25rbarraudHi arbscht
19:34arohnerfrancis: (:foo {:foo 3}) is faster than ({:foo 3} :foo), in some circumstances
19:34arohnerin defrecords primarily
19:34arohnerso the usual advice is use (:foo map) everywhere
19:50francisnoted.
19:52FrozenlockRaynes: your tests in `fs' require midje. Should it be added in the project dependencies?
20:05gertweavejester: your `secure-eql?` function in your (excellent) csrf ring middleware still leaks information about the length of the expected string (with the .length check at the beginning)
20:06gertit's a bit paranoid to worry about that perhaps, but maybe it's good to be paranoid?
20:06devnanyone know of an existing solr-cell clojure lib?
20:06weavejestergert: Does that matter? I mean, people can look at the source code and find that out, and knowing that there are 60 bytes of random data doesn't really help an attacker much.
20:07gerttrue, in this case. I'm thinking about a more general string compare function where the length of a string might not be known outside the app
20:08gertbut good point - in this case it doesn't matter
20:50RaynesFrozenlock: Midje is a dev dependency. It doesn't need to be a project dependency.
20:51FrozenlockRaynes: yeah just realized that... I wasn't in dev :(
20:55FrozenlockDo you want a new pull request or you'll change it?
21:06gfredericks$findfn - [1 2 3] 1
21:06lazybot[]
21:06gfredericks$findfn - 1 2 3 1
21:06lazybot[clojure.core/max-key clojure.core/cond]
21:07gfrederickshuh; somehow have not heard of max-key and min-key before. surely clojure.core is endless.
21:42RaynesFrozenlock: You don't have to do another pull request. Just change this one (any changes made in your branch are reflected by the pull request). In fact, just remove the commit entirely and then do a force push to Github.
21:43RaynesFrozenlock: Or, if all that seems complicated, I can just cherry pick around that commit.
21:43RaynesYeah, I'll just do that.
21:43RaynesFrozenlock: Thanks! :)
21:43FrozenlockThanks to you, I read 4 times what you said and was like "waaaaaa..."
21:43FrozenlockOne day, one day I'll understand git.
21:44FrozenlockBTW you might want to take a look at the make-zip-stream. I use it with Noir to let users download stuff made on-the-fly, with nothing written to disk. Pretty cool :)
21:58jcao219$help
21:58lazybotYou're going to need to tell me what you want help with.
21:58jcao219$help commands
21:58lazybotTopic: "commands" doesn't exist!
21:59gfrederickslazybot: you're going to need to do a better job indicating what you're capable of helping with
21:59xeqi$help list
21:59lazybotxeqi: Lists the available help topics in the DB.
21:59gfredericks$list
22:00lazybotI know about these topics:
22:00gfredericksthose are some nice topics.
22:00xeqilazybot is smart
22:00gfrederickslazybot: I know about all those topics too
22:23estebannquick question. why does this not work? (let [thesym "funngames"] (eval '(println thesym)))
22:24gfrederickseval doesn't use the local scope
22:25estebannthat seems weird to me
22:27gfredericksthe only justification I can think of is that the primary purpose for eval is loading code, and if it used the local scope you'd probably get unintentional shadowing for that use case
22:28gfredericksif you want to add some locals to an expression you can wrap it in a let before evaling
22:28estebannyeah, good point
22:30presto,(let [thesym "funngames"] (eval `(println ~thesym)))
22:30clojurebot#<Exception java.lang.Exception: SANBOX DENIED>
22:30prestoMeh.
22:30prestoAnyway, what about that?
22:31estebannhmmm... possible, but I want the code that's going to be evaled to be easy to write
22:31gfredericksan eval-with-locals macro wouldn't be hard
22:32emezeskePresto, the second one you pasted should work fine
22:32estebannis there a way to access local bindings?
22:33Raynesemezeske: That's pretty unreasonable.
22:33Raynesemezeske: There are situations where it is perfectly acceptable to do so.
22:33gfrederickswell I was thinking explicitly given, but you could do the current local scope as well I think, using the &env variable accessible in a macro
22:33RaynesTo fix a pull request that was issued 30 seconds ago is, in my opinion, acceptable.
22:34emezeskeRaynes: Nah, it is a bad thing to do, all the time. Once it's public,anyone who has grabbed it gets screwed if you rebase or force push
22:34gfredericksemezeske: +1
22:34emezeskeRaynes: Well, if you know for certain nobody has grabbed, sure
22:34emezeskeRaynes: But if you rebase or force a branch that someone else has already pulled, you are giving them grief
22:34Raynesemezeske: The odds that someone had grabbed some random branch of fs and had committed changes based on that tree is pretty ridiculous.
22:35emezeskeRaynes: Doesn't matter if they committed, it is still grief to have a branch you're tracking get rebased
22:35gfredericksRaynes: you only need "having grabbed" not committing changes
22:35RaynesSilliness.
22:36gfredericksyou'll likely not notice and end up merging every time you pull until you finally commit this parallel history
22:36RaynesI wouldn't have recommended he force pushed if it wasn't some random fork that was pushed minutes before on a project that nobody really cares about.
22:37estebanngfredericks: thnks for the suggestions
22:37RaynesBut anyways, if anyone is ever mortally wounded by my actions in the future, please come forward and I will offer reparations in the form of sacrifice.
22:37Frozenlock"... that nobody really cares about" Oh, I see...
22:38RaynesFrozenlock: I was referring to the project, silly, not your contributions.
22:38RaynesFrozenlock: I've been hoping someone would add zip.
22:38emezeskeRaynes: Heh, you can do whatever you want on your project. All I did was state my hatred for rewriting history on public branches. :)
22:38emezeskeTis but my opinion.
22:38gfredericksFrozenlock: clearly despite nobody caring about the project everybody loves your contributions to it
22:38Frozenlocklol
22:38FrozenlockYeah sure :p
22:38gfredericksactually I care about fs and have contributed to it
22:38FrozenlockMy first pull request, so I'm proud.
22:39Raynesemezeske: Fair enough. I don't get it in this context, but meh.
22:39RaynesYou're still one of my favorite people. You had that paredit.vim repo.
22:39RaynesMade me so happy.
22:39emezeskeRaynes: You are one of my favorite people for convincing Tomas to bust out paredit from slimv for real. :)
22:39emezeske<3
22:40Raynes<3
22:41gfrederickswell I tried to contribute; apparently Raynes just did a big rewrite and obsoleted my contribution
22:41RaynesI did? :o
22:41gfredericksyeah but you did it conciously, because you closed the issue with the commit
22:41FrozenlockOh in my case I wouldn't mind about that, as long as there's zip capabilities.
22:41gfrederickswell I mind. I DID IT FOR THE GLORY.
22:42RaynesOh, with-dir.
22:42gfredericksnot only does nobody care about the library, but Raynes has bigger ideas for it than I do.
22:42gfredericksyeah with-cwd is a more internally consistent name
22:43Raynesgfredericks: Ah yes. It was actually because the fix for another issue was to make it all work differently.
22:43gfredericksI told my mother I was going to be in the commit history for fs. I don't know if I have the strength to tell her what really happened.
22:44RaynesI'm so sorry.
22:45Hodapp...
22:50muhooi'm kind of tired of getting clojurescript errors complaining about Could not locate clojure/instant__init.class or clojure/instant.clj on classpath:
22:51casion`I'm an an impasse in understanding
22:52casion`does iterate make a lazy sequence in the same way reduce works imperitively?
22:53muhoo,(doc iterate)
22:53clojurebot"([f x]); Returns a lazy sequence of x, (f x), (f (f x)) etc. f must be free of side-effects"
22:53muhoohmm, says it returns a lazy sequence
22:53muhooand "free of side effects" seems kind of purely functional to me.
22:54technomancyFSVO "must"
22:54uvtccasion`: I don't know what you mean by "way reduce works imperatively". In what way does `reduce` work imperatively?
22:54casion`it evaluates immediately
22:55uvtccasion`: Right. The point of `reduce` is to keep evaluating until it gives you a single result in the end. Which is different from the functions that lazily return a list which you can realize at your liesure. :)
22:56uvtcGah. *leisure.
22:56casion`uvtc: I'm having difficulty grasping lazy sequecnes in general, but I get the concpet
22:56casion`just the application is bewilderring me, so I'm trying to make connections
22:57muhoowhat application?
22:57FrozenlockI always get screwed by lazy sequences. In the REPL they print fine, but in the real world... Oh boy!
22:57RaynesFrozenlock: Pulled your stuff. Excellent work!
22:57casion`muhoo: I'm pretty bad at choosing words heh..
22:57uvtccasion`: There's a neat example of a creating a lazy sequence in the Clojure Prog (O'reilly) book. Oh, let's see ... where is it ...
22:58muhooi wish there were a way to suppress evaluation of lazy seqs in the repl, to get a "real world" sense of where there may be dragons
22:58casion`application in the literal sense, not an 'app'
22:58FrozenlockRaynes: Yay!
22:58casion`noun form of apply
22:59Raynesmuhoo: The dragons are in the house of the undying.
23:00casion`in the volkmann tutorial for instance, this line confuses me '(def f-seq (map f (iterate inc 0)))'
23:00muhooRaynes: i wasn't making a game o thrones joke, but ok
23:00FrozenlockRaynes: How does github work in this case? Should I delete my forked repo?
23:00RaynesFrozenlock: You can. You don't have to.
23:00uvtccasion`: Ah, here we are. Page 94. There's a neat example, where, you create a lazy list by writing a function which wraps `lazy-seq` around `cons` of a value and the result of calling the fn again.
23:01RaynesFrozenlock: Your changes are now in my fork. That's how git works. One copy of a repo doesn't rely on stuff from another copy of that repo.
23:01casion`uvtc: that book arrives on tuesday for me
23:02uvtccasion`: That is, you ask it for the next value, and it produces the next one plus "whatever else comes after that which I haven't yet bothered to compute --- I'll compute it when you need it quit bugging me already">
23:02uvtc:)
23:02casion`I'm mostly relying on the clojure docs and volmann tutorial while browsing other people's code
23:02casion`in the meantime
23:02casion`uvtc: I get that conceptually
23:03casion`but like the line '(def f-seq (map f (iterate inc 0)))' at http://java.ociweb.com/mark/clojure/article.html#Sequences
23:03casion`it's making a lazy sequence of a lazy sequence? or?
23:04Raynesiterate returns a lazy seq and so does map. Nothing happens until you start looking at items in the sequence returned by map. It'll start realizing the sequence from iterate.
23:05casion`what I think is happening is (iterate inc 0) is like a lazy sequence version of (range _), and it's using that as an argument to f, and that's mapped to the lazy sequence f-seq
23:05RaynesI wouldn't overthink it too much.
23:05uvtccasion`: here's the example from the book https://www.refheap.com/paste/3878
23:05casion`is that close to corrrect?
23:05Raynesrange is lazy too.
23:05casion`is it?
23:05Raynesmhm
23:06muhoowell, if it wasn't, then your computer would hang when you do (range)
23:06uvtcThe way it works is, if you just go ahead and call the function in the repl, the repl will try and realize the whole thing. So, that's no good. But,
23:06casion`why iterate there instead?
23:06casion`or would range work the same...
23:06casion`may as well trry
23:06uvtcOh, sorry. I don't mean to cross wires.
23:06casion`uvtc: I'm following you
23:07casion`I can handle 2 conversations ;)
23:07uvtccasion`: Ah. I tend to be one-track minded in that way. :)
23:08uvtccasion`: Anyhow, the way it works is this: if you call that function such that it doesn't need to return all the values at once,
23:09uvtccasion`: it won't. It'll come up with the first rand-int,
23:09uvtccasion`: but then just defer computing the rest until later on.
23:09uvtccasion`: That is, if you only ask for one value from it, it will remain
23:10uvtccasion`: suspended with something like `(cons 42 (random-ints 100))`, and not
23:10casion`so it need not be incremental?
23:10uvtccasion`: make that call to random-ints until you ask for more values.
23:10casion`ok let's see
23:11casion`ahem.. not in the repl I suppose
23:11uvtccasion`: That's the thing; the repl is a people-pleaser. :)
23:11uvtccasion`: It wants to realize lazy lists so it can display them for you.
23:12uvtccasion`: However,
23:12casion`ok, i just dod something wrong
23:12casion`did*
23:12uvtccasion`: Right. Sorry. I was too slow at typing: you shouldn't just call that function,
23:13uvtccasion`: because it will just try to realize the infinite list and take over your repl. Sorry.
23:13casion`too late
23:13uvtccasion`: You can call it like so though, `(take 5 (random-ints 100))`,
23:13casion`and... time to restart emacs
23:13uvtccasion`: and it'll give you just 5 of the infinite list.
23:13casion`brb
23:13uvtccasion`: Oh shoot. Sorry about that.
23:14casionheh
23:14casionwell, obviously I didnt understand that well enough to not do that
23:16uvtccasion: Point is, the function returns a lazy infinite list, and so will generate items as you need them, for example,
23:16casionI think where I'm caught is how the sequence is evaluated
23:16casionor stored
23:16uvtccasion: if you have a function that needs some values from it, `random-ints` will supply as many as it needs:
23:16casionorr both
23:17uvtcEx: `(zipmap [\a \b \c \d] (random-ints 100))`
23:17uvtcThere, zipmap wants to create a map for you made out of zipping those keys and values.
23:17uvtc`random-ints` supplies 4 values, because that's all that zipmap needs.
23:18casionok
23:18uvtcThe way that random int list looks as it's being evaluated looks something like this:
23:18uvtc(50 (the rest))
23:18uvtcOoof. I mean:
23:18uvtc(cons 50 (the-rest))
23:19uvtc(50 (cons 39 (the-rest)))
23:20uvtc(50 39 (cons 42 (the-rest)))
23:20uvtc(50 39 42 (cons 28 (the-rest)))
23:20uvtcAnd it only evaluates that cons when it needs the next one.
23:20casionahh ok
23:21casionI'm still getting used to the idea of immutable.. everything
23:21uvtc(where, `(the-rest)` is that call to `random-ints`. I probably should've written that instead of "the-rest")
23:21casionno, I got what you were saying
23:22uvtccasion: I'm not sure where the sequence "is stored" ... It's floating there in space waiting to be asked for more of its values. :)
23:23uvtcThe values you've asked for are "realized" (computed and made available).
23:23casionI have this need to have at least a basic idea of the implementation
23:23casionor I feel like I don't understand it
23:24uvtc`(source lazy-seq)` ?
23:24casionyeah, i'm going through a few now
23:24casionI just don't know enough clojure yet to grasp some of it
23:24casionthis is all a massive brainfuck to me
23:34uvtccasion: In that example you gave above, `(def f-seq (map f (iterate inc 0)))`; both the `iterate` and the `map` are lazy. `iterate` only generates values it's asked for, and same with `map`. So, if you ask for a value from the list --- say, (nth the-list 5), `nth` asks `map` to start walking through values 'til it gets to the 5th one, and it in turn asks `iterate` for values.
23:34casionso iterate just recurisively cons a result of f?
23:35uvtc(sorry -- replace "the-list" with "f-seq")
23:35uvtc`iterate` just gives you f(x), f(f(x)), f(f(f(x))) , ... as you ask for them.
23:35casiondoesn't it take the nth result from iterate, then map that?
23:36uvtcNo, it has to work up to it. :)
23:36casiondoesnt map need a collection though?
23:36uvtc`iterate` hasn't generated a list yet. It generates it as it's asked for values --- no sooner.
23:36casionso iterate would have to returrn first?
23:37uvtcNo. `map` just needs something that's promised to look and act like a list. :)
23:37casionhmm
23:37uvtcAFAIU, it's a train of lazy functions. You ask `map` for the next one, and it asks `iterate` for the next one.
23:38uvtcBut if you ask here during eastern daylight time working hours, I'm sure the wizards will be able to explain exactly how it works.
23:38casionthat doesn't make sense to me at all... I would think iterate needs to be evaluated first?
23:38casionbut I'm in no position to disagree heh
23:39casionthank you very much though, you've made a lot more clear for me
23:39uvtcy/w. :)
23:43xeqi&(class (iterate inc 0))
23:43lazybot⇒ clojure.lang.Cons
23:53ivan&(take 25 ((fn fibs [] (concat '(1 1) (lazy-seq (map +' (fibs) (drop 1 (fibs))))))))
23:53lazybot⇒ (1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025)
23:56uvtcivan, what is +' ?
23:57ivanit's + with arbitrary precision
23:57ivanthat is, supports adding a small and large number
23:57uvtc,(doc +')
23:57clojurebot"([] [x] [x y] [x y & more]); Returns the sum of nums. (+) returns 0. Supports arbitrary precision. See also: +"
23:57uvtcHm. Didn't know you could use a single-quote mark like that.
23:58uvtcThanks.
23:59uvtcAh. You're mapping +' onto 2 collections: one shifted by 1 from the other...