#clojure logs

2014-04-30

00:51TerranceWarriorAre there objects in Clojure? If not, What replaces it?
00:51beamsoyou still have java objects. you can use clojure records as well.
00:51TimMcTerranceWarrior: Clojure is on the JVM, so you have basically everything you have in Java.
00:51TimMcTerranceWarrior: What functionality do you want?
00:52TimMcIf you want composite data, Clojure has maps.
00:52TimMcIf you want to collect similar pieces of code, you probably want namespaces.
01:05arrdemif you want to have maps with similar pieces of code, prepare to do evil things!
02:57mpenetambrosebs: hi! is it possible to annotate a defmethod? the warnings seems to indicate it should be possible but I dont see how in the docs
02:58ambrosebsmpenet: have you tried `ann`?
02:59mpenetI didn't, but how do you indicate "annotate this method for this dispatch value" (I annotated the defmulti already)
02:59ambrosebsit's inferred based on the dispatch function
03:00ambrosebswhat's your dispatch fn?
03:00mpenethttps://github.com/mpenet/alia/blob/feature/core.typed/src/qbits/alia/cluster_options.clj
03:00mpenethttps://github.com/mpenet/alia/blob/feature/core.typed/src/qbits/alia/cluster_options.clj#L44
03:02ambrosebsmpenet: It doesn't look like the dispatch value implies certain types in defmethods?
03:02ambrosebsyou just do different things based on the keyword?
03:02ambrosebsoh the second arg changes?
03:03ambrosebs*third
03:03mpenetyes, I'd like to typecheck second ard
03:03mpenetarg*
03:03mpenetI mean third yes :)
03:04ambrosebsmpenet: you probably need to enumerate all the cases in the annotation to the defmulti
03:04ambrosebsthat might work
03:06ambrosebsthe simplest thing would be to add a cast in each method
03:06mpenetok
03:06ambrosebs{:pre [(instance? RetryPolicy policy)]}
03:06mpenetah right, should have thought of this
03:07ambrosebsI'm not very vocal about casts right now since support is poor :)
03:07ambrosebswill change soon
03:07mpenetthanks!
03:08ambrosebsoh and a :no-check'd defmulti implies the defmethods are no-checked
03:09mpenetYep I know, I am starting like this and will gradually get rid of these
03:09ambrosebscool
03:09mpenetI want to annotate all the public parts already
04:12l3dxI'm trying to find an open source java project that is well suited as a java->clojure porting exercise for beginners. Was thinking of the spring petclinic sample. Anyone thoughts, or other suggestions?
04:21amalloyl3dx: why would you port a program from java to clojure? if it's already there in java, just use it
04:21l3dxas an exercise
04:23l3dxthe motivation is to learn by doing it, and also being able to compare the resulting FP solution to the OOP solution
04:25noidiI doubt that porting would lead you to an idiomatic Clojure solution
04:26noidiof course you can create an application that's functionally identical, but I wouldn't try to translate the Java source into Clojure
04:27l3dxI see your point
04:28l3dxso "porting" was kind of misleading
04:32winkbit sick of blog engines :P
04:32winkl3dx: I'd search for something with text output as you probably wouldn't be able to reuse the real testsuite of a project anyway
04:33winkthen again it depends on how closely you want to mock it.
04:35amalloyl3dx: one approach i've seen people take is to have a sort of toy application that you re-implement in every new language
04:36amalloythen you're not always struggling for new ideas, or writing hideous ports because you want to mirror functionality from the wrong language
04:36amalloyeg, a scheme interpreter, or a webserver that implements the equivalent of /usr/bin/wc for POSTed inputs
04:41l3dxyes, I like that idea
04:43l3dxI don't have any that fit, but maybe some of my collegues have. we're a group at work trying to get better at FP. the comparison is mostly to convince managers to adopt :P
05:56ProTipHello.
05:56ProTipIs there a way to macroexand a call to a method using a threading macro?
05:56ProTip*function
05:57ProTipif I use defmacro to create the macro for some reason I can't use macroexpand-all to see how it turns out.
06:05maxthoursieProTip: (macroexpand-all '(-> 1 (* 2) (+ 3)))
06:07maxthoursie,(* (+ (*) (*)) (+ (*) (*)))
06:07clojurebot4
06:07maxthoursieneat :)
06:24ProTip@maxthoursie Thanks, but what if I had the macro bound to a variable and wanted to expand that?
06:28oskarthIf I find myself assoc and dissocing the same map, what should I be doing? Is there some nice destructuring way to do it at the same time? Rather than let [action (:action p) item (dissoc p :action)...]...)
06:30clgvoskarth: no not really. but you can use threading macros, e.g. (-> my-map (assoc :a 42) (dissoc :c))
06:30oskarthclgv: true, but I need access to both separately
06:31clgvoskarth: oh you mean extracting an item and removing it
06:31oskarthI was thinking something like [[:action] & rest] or so
06:31clgvoskarth: there is keyword-based destructuring but there is no "& rest" equivalent
06:32oskarthI want to use both action and item separately in other let clauses
06:32oskarthI see
06:32clgv,(let [{:keys [a] :as m} {:a 42, :b 11}] [a (dissoc m :b)])
06:32clojurebot[42 {:a 42}]
06:32clgvoops
06:32oskarthit's almost a partition by keys
06:32clgv,(let [{:keys [a] :as m} {:a 42, :b 11}] [a (dissoc m :a)])
06:32clojurebot[42 {:b 11}]
06:34clgv,(defn pop-key [m k] (let [v (get m k)] [v (dissoc m k)]))
06:34clojurebot#'sandbox/pop-key
06:35clgv,(let [[a rest-map] (pop-key {:a 42, :b 11} :a)] (println a rest-map))
06:35clojurebot42 {:b 11}\n
06:35clgvoskarth: you could also write a custom-macro for that if it is really worth it
06:35oskarthnot really, just wondered if there was a neat trick for doing it in one line, similar to destructuring for vectors
06:36oskarththanks though
06:36oskarthmaybe it can be done with spit/group/partition-by but couldn't figure out how
06:40clgvdo you want to do that repeatedly for all keys? otherwise I dont see why you would want to use group-by/partition-by?
06:43oskarthnope, just to split it like a set based on keys, but it isn't a real problem, more curiosity
06:49pyrtsaoskarth: You could use the result of (juxt k #(dissoc % k)) for that but it's a bit contrived.
06:51oskarthpyrtsa: hm, that's true. But yeah, doesn't do much for readability in this case
07:05mpenetambrosebs: another question: When I try to check-ns with this definition for set-hayt-query-fn! I get an exception that I am not sure I understand fully: https://gist.github.com/mpenet/a7b7726a28017bf2c6ec#file-gistfile1-clj-L66-L77 -> ExceptionInfo Cannot set! non-assignable target clojure.core/ex-info (core.clj:4403)
07:06mpenetusing the commented version without set! checks.
07:12mpenetseems quite odd, no-check seems to have no impact here btw
07:25mpenetit seems to come from https://github.com/clojure/tools.analyzer.jvm/blob/master/src/main/clojure/clojure/tools/analyzer/passes/jvm/validate.clj#L60
07:25mpenetah I got it... nevermind.
07:27grimmulfrWith the risk of getting flamed for this, how in the world can I use more than one :use or :require? What's the correct syntax? I have a project that has (:require [jayq.core as jq]) but I need to add crate on there also.
07:27agarmanyou can use multiple or just put multiple symbols in one
07:27mpenet(:require [jayq.core as jq]
07:27mpenet [something.else :as foo])
07:28agarmanexactly
07:28grimmulfrCheers. I tried something similar and still got the error, must've done something wrong
07:28mpenetyour example is broken
07:28mpenetas -> :as
07:28grimmulfrI used :as, just typed wrong in here
07:29l3dxread the docs :) http://clojuredocs.org/clojure_core/clojure.core/use
07:29agarmanI recommend a quick read of http://blog.8thlight.com/colin-jones/2010/12/05/clojure-libs-and-namespaces-require-use-import-and-ns.html
07:29grimmulfrThank you
07:29agarmanColin Jones explains the usage clearly and updated it recently to reflect changes to require
07:32locksit's one of the more confusing parts of clojure I've come across so far
07:33agarmanit definitely needed a clear explanation
07:36martinklepschagree very much. the basic rule of thumb is "use :require almost always", right?
07:37agarmanI only use require now
07:37martinklepschremember that I came back to that 8th light article every couple of days when I started clojur'ing
07:37agarmanand require :refer instead of use
07:37agarmanexcept with java
07:37agarmanthen you have to use import
07:37martinklepschagarman, yeah thats my understanding as well
07:37martinklepschagarman, didn't get to that so far (luckily?)
07:39agarmanI'm always stuck doing interop for something or another...there's a lot of java, scala & groovy libraries that provide great functionality that I don't want to rewrite :-)
07:39xsynwhere did all the pedestal docs go?
08:02gtrakis there a way to set the bytecode version for AOT?
08:02gtrakIE, I'm running java7/8, user might be using 6.
08:04agarmanin your project.clj
08:04gtrakagarman: details?
08:04agarman:javac-options ["-target" "1.6"]
08:04gtrakah, but that's for java itself, what about clojure AOT?
08:04gtrakI'm considering just making a java stub, though.
08:05agarmanI'd be disappointed if it doesn't use the lcd setting for AOT
08:05gtrak(clojure doesn't use javac for classgen)
08:05gtrakI've definitely run into problems before, at least with lein 2.0.0
08:10gtrakI can just skip it and use clojure.main I suppose
08:11clgvgtrak: clojure aot is java 6 compatible since that's the minimum requirement since clojure 1.6
08:11gtrakyou'd think :-)
08:12clgvyou got a counterexample?
08:12gtraksure, I could :aot :all something up and find the bytecode version with javap, one sec.
08:15gtrakhuh, ok, maybe not.
08:15gtrakthat's weird. must be something project-specific.
08:15clgvgtrak: I just AOT compiled a complete project myself and checked serveral class which reported version 49 corresponding to java 5 although using clojure 1.6
08:16gtrakclgv: yea, I'm just sure I've been bitten by this before, but that's a much more complex project.
08:16clgvgtrak: AOT with different clojure versions will bite you
08:16gtrakI've been bitten that way, too.
08:17clgvgtrak: I ran into that several times when migrating from 1.2.1 to 1.3 ;)
08:17clgvstale class files and such hoorray ;)
08:17mdrogalisJust hopped into the channel, but yes. Take Storm for example. AOT is killing that project off slowly.
08:17mdrogalisIt's AOT'ed for 1.4
08:18clgvmdrogalis: does the library need to be AOTed?
08:18mdrogalisclgv: IMO no. But it is right now.
08:19clgvmdrogalis: it's open source right?
08:19mdrogalisclgv: Indeed. Apache.
08:20clgvmdrogalis: humm well, upload a non-AOT lib to clojars for yourself ^^
08:20clgvyou can always AOT all of the application as uberjar in the end...
08:20mdrogalisclgv: It's a rather hairy project, taking out the AOT bits isn't trivial.
08:21clgvmdrogalis: oh I understood you wrong then. so refactoring is needed to get rid of the aot...
08:22mdrogalisclgv: Yeah, sorry for the misunderstanding. It interops heavily with Java.
08:22agarmanmore of storm is written in java than clojure now-a-days
08:23mdrogalisAnd the Clojure bits are mostly wild macros.
08:23gtrakand I was using backtype as a shining example of clojure acquisition just a couple weeks ago :-)
08:24clgvspouts and bolts :P
08:24mdrogalisThose abstractions make me angry lol
08:24agarmanI'm in process of setting up hadoop + spark stuff here... I liked storm when I used it a couple years ago, but seems to be momentumless now
08:24clgvthat example looks spanish to me ;)
08:24mdrogalisIt's just soo.. Unnecessary.
08:24clgvspanish with a lispy flavour
08:25mdrogalisagarman: A friend is putting a ton of good words about Spark in my ear. What do you think?
08:25clgvah damn, in english it is "looks greek to me", right?
08:25mdrogalisThe rain in Spain falls mainly on the plain :)
08:26agarmanI liked spark. It was an improvement over cascading. Spark stream is what I'm likely building an upcoming app around
08:26rkneufeld_xsyn: they're all in the main repo: https://github.com/pedestal/pedestal/tree/master/guides
08:27mdrogalisUnderstood.
08:36mdrogalisagarman: PM
09:11jcromartieI keep going back and forth between pulling apart the Ring request and passing the relevant pieces to a well-defined function, and just cramming everything in the request map and writing all of my functions in terms of that instead.
09:11jcromartieparticularly when it comes to view rendering
09:12jcromartieso many things in the view have to be done relative to bits of the request… :|
09:13klzzvni'm trying to import a Java class and create an instance of it - all at runtime... this is what i got so far
09:13klzzvnhttps://gist.github.com/klzzvn/3d24229a68f22cc8a86e
09:13klzzvnwhat's the problem at the end? why can't it (new) the class?
09:14clgvklzzvn: wrong usage. (new MyClass ...) or (MyClass. ...)
09:15clgvklzzvn: though you should use (import 'javafx.scene.shape.Circle) and then (Circle. ...)
09:16klzzvnclgv: that's the point, I can't use regular import because i have to import the class at runtime
09:16clgvklzzvn: ah now I understand that you want to use the class object from the function. that wont work, you need a class at compile time for "new"
09:16klzzvnand i don't know the name of the class, so i cant do (new MyClass)
09:16klzzvnclgv: any other way to create an instance? besidesusing newInstance
09:17clgvklzzvn: java reflection
09:17jcromartieklzzvn: how about a macro
09:17clgvklzzvn: you could use "eval" though
09:18clgvklzzvn: (eval `(new ~(symbol "javafx.scene.shape.Circle") ~arg1 ...))
09:18klzzvnclgv: waaaaaaaait, let me try that...
09:19clgvafter you made sure the class is loaded, though
09:19klzzvni think it work!!! :)
09:19klzzvnbut how? what the difference between evaling and just (new) in the code?
09:19clgvbe careful with "eval" in general.
09:19klzzvni'm still very new to clojure...
09:20clgvyou generate code at runtime and eval compiles and runs it.
09:20klzzvnclgv: isnt' that the same way the REPL works? and if i try to (new) in the REPL it still fails...
09:20clgva rough picture is described as: you trigger a compilation at runtime
09:20klzzvnI thought REPL is some kind of eval...
09:21clgvyeah it is. but the problem is you want your code to run without a REPL as well ;)
09:21klzzvnas far as I get it, the REPL reads the text, makes clojure data structures out of it, and evals it...
09:21clgvcorrect.
09:21klzzvnwell, yeah :) but the example fails in the REPL too
09:22klzzvnjust putting (new (sneaky-import ".....")) in the REPL fails
09:22clgv,(import 'java.util.Date)
09:22clojurebotjava.util.Date
09:22klzzvnand putting your (eval .....) works
09:22clgv,(new Date)
09:22clojurebot#inst "2014-04-30T13:18:00.660-00:00"
09:22Anderkentis there any way of making this not so ugly: &(apply str (interpose \- (map (partial apply str) (partition 2 "123456789012"))))
09:23Anderkentugh, I never remember what the command is to eval in mid of text
09:23Anderkent,(apply str (interpose \- (map (partial apply str) (partition 2 "123456789012"))))
09:23clojurebot"12-34-56-78-90-12"
09:23clgvAnderkent: probably threading macros
09:23Anderkentyeah but order of things, I guess as->
09:24clgvyou only got sequence operations as far as I can see
09:24Anderkenthm, you're right, not sure why I was thinking the order switched
09:24clgv,(->> "123456789012" (partition 2) (map (partial apply str)) (interpose \-) (apply str))
09:24clojurebot"12-34-56-78-90-12"
09:25clgv(require '[clojure.string :as str])
09:25clgv,(require '[clojure.string :as str])
09:25clojurebotnil
09:25clgv,(->> "123456789012" (partition 2) (map (partial apply str)) (str/join \-))
09:25clojurebot"12-34-56-78-90-12"
09:25muhukklzzvn: new is a special form. I guess that's why it needs to be `read` (and evaled).
09:25Anderkentclgv: cool, thanks
09:26clgvmuhuk: klzzvn: yes it is a special form that needs a symbol that resolves to a class at its compile time
09:27clgvjoin should be in core maybe as clojure.core/str-join ;)
09:27klzzvnclgv: muhuk: thanks guys, it works now...
09:27klzzvnit's super ugly i must say :)
09:27klzzvnbut it fixes my problem with JavaFX and importing some JavaFX classes with static initializers
09:28jcromartieI'm not seeing a clear consensus on either <namespace>_test.clj or test/<namespace>.clj
09:28jcromartieany opinions here?
09:28jcromartiepro/con?
09:28clgvklzzvn: yeah I heard that javafx has some design issues there
09:29klzzvnclgv: yup, I don't speak Java at all, so I can't say what they are doing and is it in bad taste... but it's not possible to just (import) some JFX classes without some tricks...
09:29clgvjcromartie: leiningen suggest a default in its standard "new" template
09:29klzzvnclgv: they do have Builder classes that can bypass some of the problem.. but it's still not very pretty...
09:29jcromartieI personally prefer the <ns>_test.clj approach but I see major projects have moved away from that
09:30clgvjcromartie: tests in "test/" folder but not part of the namespace and postfix "_test"
09:30clgvjcromartie: which and what do they use?
09:32jcromartieclgv: well yeah all tests go in the test/ folder, but it is just another source folder. I mean as far as actual namespaces go
09:32jcromartiehttps://github.com/ring-clojure/ring/tree/master/ring-core/test/ring/middleware/session/test
09:33jcromartieso basically, foo.bar.baz is tested by foo.bar.test.baz
09:33clgvjcromartie: woah thats odd. I dont like that convention
09:33jcromartieI'm not crazy about it
09:33jcromartiewe've got an even weirder setup
09:33jcromartiecurrently
09:33clgvbetter prefix namespaces with "test."
09:33jcromartieyou mean suffix?
09:33jcromartieor test.foo.bar.baz
09:33clgvyes like that
09:34clgvthought it looks odd on the filesystem with "test/test/..."
09:34jcromartieso you vote for that, over the Leiningen suggested convention
09:35clgvwell I use it in two projects like that since I didnt like the postfix variant
09:36jcromartiewhat we've got now is a mess :) https://gist.github.com/jcromartie/b36e07ad1ceb7de25e2a
09:37jcromartiea mix of all sorts and who knows what
09:37Rosnecis there a layout in swing/seesaw which would allow me to have a grid with fixed size items, but a variable number of rows/columns?
09:37jcromartiefoo.test.unit.bar.bat, foo.functional.baz, foo.zort-test
09:37Rosnecso if I resize the window, it will change the number of columns to fit
09:38jcromartiegotta rein it in
09:47clgvuuuh
09:48Anderkentjcromartie: also foo.test-zort
09:49Anderkentoh wait you were talking about a specific project not generally
09:51eraserhdIn core.logic, is there a way to make a relation by a method other than compositioin of other relations?
09:51eraserhdFor example, I'd like to write 'symbolo', but I don't think there's a way to do it in terms of project and gensym.
09:57jcromartiehahah clgv I realize I copied the sed line
09:57jcromartie:P
09:59clgv:P
10:05jcromartieI'd love to be able to do a survey of Clojure source structure
10:05jcromartietime to go to the Github API!
10:07jdkealyanyone well acquainted with "friend" ? I have been testing an authenticated area, but when i refresh my changes, i get signed out. Anyone know how to stay signed in using friend ?
10:23jcromartiejdkealy: I would guess you are blowing away your session store
10:23jdkealy@jcromartie I am passing the :auto-reload? true option to ring in my project.clj
10:26jcromartieyou can specify a session store for your Ring handler
10:27jcromartiefor instance, I do it like this: (defonce session-store (ring.middleware.session.memory/memory-store)) (def handler (handler/site routes {:session {:store sessions-store}}))
10:27jcromartie*like* that… not exactly that
10:27jcromartiebut when the namespace with my handler gets reloaded, it doesn't lose the session store
10:28jcromartieby default if you don't explicitly specify a session store, Ring will use a brand new one
10:28jcromartieso reloading the ns that constructs your handler will wipe out your session
10:29fizrukis there a contains? analogue to check if get-in will work?
10:30jdkealynice. thanks! is there a contains? i am not sure what that means
10:31fizruk,(contains? {:x {:y 1}} :x)
10:31clojurebottrue
10:31jcromartiewhy not just get-in?
10:31jcromartieI know it's not exactly equivalent
10:32jcromartieunless you're using vectors...
10:32fizrukjcromartie: and that’s why I want that
10:32welder(if-let [val (get-in m [k1 k2])]
10:32jcromartiethen it wouldn't work at all
10:32jcromartie:P
10:32jcromartiegot it
10:32jcromartieso k2 is an index in a vector?
10:33jcromartiewait that would still work
10:33fizruk,(get-in {:x {:y 1}} [:x :y])
10:33clojurebot1
10:33jcromartiebut you care about the difference between existence in the coll and a nil value
10:33fizrukyes
10:33jcromartieOk
10:34fizruk(if-let [val (get-in {:x {:y nil}} [:x :y])] true false)
10:34fizruk,(if-let [val (get-in {:x {:y nil}} [:x :y])] true false)
10:34clojurebotfalse
10:35fizrukI want that to be true ^
10:35welder,(contains? {:x nil} :x)
10:35clojurebottrue
10:35welder:(
10:36fizrukok, maybe there’s a solution on a different level
10:36jcromartieyou just need to write a function
10:36fizrukwhat I want next is an update-in which updates *only* if there is a value
10:36clojurebotYou don't have to tell me twice.
10:36cbpyou mean a key?
10:37fizruka value at given key, yes
10:37cbpnil is the absence of a value
10:37fizruk,(update-in {} [:x :y] #(or % 1))
10:37clojurebot{:x {:y 1}}
10:38fizruk,(update-in {:x {:y nil}} [:x :y] #(or % 1))
10:38clojurebot{:x {:y 1}}
10:38jdkealythanks @jcromartie that works perfectly!
10:38fizrukI want first to return {} and second to work like that
10:39cbpThat's honestly going against the language. You'll have to write your own versions and check explicitly for nil
10:40cbpor use contains?
10:40fizrukcbp: nil always made a perfect value for me
10:40gfredericksdid leiningen support ~/.profiles.clj as an alternative to ~/.lein/profiles.clj?
10:41fizrukcbp: ok, I’ll change semantics to not use nil as value then
10:41cbpfizruk: sure but it's also the value returned when something is empty
10:42fizrukkorma uses nil when you want to check if something in DB is nil or not
10:42jcromartiefizruk: https://www.refheap.com/83816
10:42cbper when something is not there
10:42jcromartiethis is not impossible
10:42cbpembrace the nil punning :-P
10:43fizrukso I have some search-params structure which is basically a map
10:43fizrukand it might contain nil when I want something to be absent
10:44fizrukot it might not contain key at all when I don’t want that field to be a part of search request
10:44cbpYou can just use jcromartie's version and update when it's true
10:44fizrukand I find it confusing that I have to define my own contains-in?
10:45fizruki mean, is it that core has not much support of general functions like that? or is it me trying to do something “against the language”?
10:45cbpclojure disagrees and wants you to treat nil as being absent
10:47fizrukok
10:47jcromartiecbp: then why does contains? exist?
10:48jcromartie,(contains? {:x nil} :x)
10:48clojurebottrue
10:52cbpjcromartie: I'm not sure. To check if nil is inside a set?
10:52jcromartieI use it to check HTTP parameters
10:57clgv,(contains? #{1 2 nil 4} nil)
10:57clojurebottrue
10:58clgv,(contains? {1 2 nil 4} nil)
10:58clojurebottrue
11:02eraserhdI vaguely recall there was another pattern matching library that people used instead of core.match. What was it?
11:03gfredericksdoes anybody know of a leiningen plugin that sets the project version based on an env variable (when present)?
11:03gfredericksI'm about to write one otherwise
11:05eraserhdgfredericks: why?
11:06gfredericksuseful for certain ways of using CI
11:09eraserhdgfredericks: ah
11:16dmi3ygst
11:17dmi3yplease ignore that
11:18ssideris_eraserhd: matchure
11:18dobladezI really like Emacs clojure-test-mode's ability to run clojure.test (C-c ,). However, it looks like running a single test (C-c M-,) doesn't run the fixtures... Am I missing something?
11:22jcromartieI need to use clojure-test-mode more
11:26devurandomHow do I turn the result of (map ... (range ...)) into a static non-lazy list?
11:27bbloom(doc mapv) ; devurandom
11:27clojurebot"([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & ...]); Returns a vector consisting of the result of applying f to the set of first items of each coll, followed by applying f to the set of second items in each coll, until any one of the colls is exhausted. Any remaining items in other colls are ignored. Function f should accept number-of-colls arguments."
11:28bbloomsee also: vec and doall
11:28devurandomI tried doall, but that did not seem to work.
11:28devurandomI.e. the type stayed the same.
11:28bbloomdevurandom: doall won't change the type
11:29bbloomdevurandom: it will only force the inherit memoization of the lazy seq
11:29bbloominternally, a "is realized?" flag will flip
11:29gtraktechnomancy: success! 0.7.0 is going to be more of a real release https://github.com/clojure-emacs/cider/issues/546
11:30devurandomSo mapv is equivalent to (vec (map))?
11:31gtrakdevurandom: but faster
11:31bbloomgtrak: faster?
11:31gtrakslightly
11:31gtrakyea, there's no laziness stack-frames :-)
11:32devurandomYay, now it works! Thanks a lot!!
11:32gtrakah, wait a minute. I'm wrong.
11:32gtrakit still uses map under the covers.
11:32gtrakexcept for the 2-arity.
11:32bbloomgtrak: i'm looking now, that's only for parallel maps
11:32gtrakthere, ego phew
11:32bbloomgtrak: either way, impl detail
11:33gtrakone man's impl-detail is another man's impl.
11:37eflynnhow do you get the documentation of a funciton
11:38cbp,(clojure.repl/doc juxt)
11:38clojurebot"([f] [f g] [f g h] [f g h & fs]); Takes a set of functions and returns a fn that is the juxtaposition of those fns. The returned fn takes a variable number of args, and returns a vector containing the result of applying each fn to the args (left-to-right). ((juxt a b c) x) => [(a x) (b x) (c x)]"
11:40fizruk,(some #{false} [false])
11:40clojurebotnil
11:40fizrukwhy, clojurebot?
11:41cbpyep you have to special case that
11:41gfredericks,(some #(= false %) [false])
11:41clojurebottrue
11:42technomancygtrak: nice!
11:42fizrukgfredericks: i though #{false} should be equivallent to #(= false %) there
11:42fizrukthought*
11:42gfredericksno, sets return the value when present
11:42gfredericks,(#{false} false)
11:42clojurebotfalse
11:43malyn,(some false? [false])
11:43clojurebottrue
11:43gfredericksso you're hitting one of clojure's nil/false edge cases
11:43gfredericksthis is one of the reasons the (some #{x} coll) idiom makes me grumpy
11:43fizrukoh, ok
11:43fizrukthanks!
11:43gfredericksnp
11:44arrdemsee you guys on the other side of finals...
11:47gfredericksarrdem: wait what there's finals? when? this must be one of those crazy nightmares...
11:51technomancygfredericks: just finalés
12:05coventrybbloom: I enjoyed your eff talk.
12:05bbloomcoventry: thanks!
12:05bbloomglad you liked it
12:10gfredericksI'm imagining this talk is similar to "WAT" and features bbloom making fun of some language and saying "eff..." after each point.
12:10cbpeffing clojure!
12:10bbloomcoventry: i didn't make fun of monads too much, did i? ;-)
12:13farhavenbbloom: is there a source for me to make a cultural backup of that talk?
12:13bbloomfarhaven: http://www.mixcloud.com/paperswelove/
12:14mikerodgfredericks: the (some #{x} coll) idiom is just weird to explain to people new to the language
12:14mikerodI mean, a side note
12:14coventryNot enough. :-)
12:14mikerodas a side note*
12:16mikerodI guess it is cool though
12:16mikerodcoventry: what is the "eff talk"
12:17bbloommikerod: i'll tweet about it now so as to keep my self promotion to the professional self promotion platform
12:18mikerodbbloom: that sounds appropriate
12:18bbloommikerod: done.
12:20mikerodbbloom: thanks, I'll be checking it out. so your self promotion has at least drawn in 1 more person to the video. win
12:20bbloom(inc self-promotion)
12:20lazybot⇒ 1
12:21coventrymikerod: http://www.mixcloud.com/paperswelove/bbloom_3_17_2014_programming_with_alegebraic_effectshandlers/
12:26gfredericksmikerod: yeah; it'd work fine of course if sets were predicates, which is most of my set-as-IFn usage
12:29gfredericksI followed through on my earlier threat: https://github.com/fredericksgary/lein-env-version
12:29coventrybbloom: It seems like there's some overlap between eff and extensible effects. Can the examples in the eff paper be translated directly to eclj?
12:30CookedGr1phontechnomancy: I'm submitting a pull request to cider for C-u M-x cider-jack-in to take a profile argument, am I right in thinking that "with-profile default" is the same as not specifying a with-profile parameter?
12:30bbloomcoventry: the extensible effects in haskell as per oleg are directly related to the research & researchers who built Eff, both of which have heavily influenced my desire for the functionality i'm working on for eclj... at this time, eclj's handlers are broken b/c i'm still working on what the design should look like in a lisp/clojure
12:31bbloomcoventry: but a goal is for all those eff examples to work trivially in eclj
12:31technomancyCookedGr1phon: that's correct; should be the same
12:32bbloomcoventry: but at this time, the goal of clojure compatability is at odds with some other (less publicized) goals of mine, so i'm not sure how hard i'm going to push on eclj itself
12:32CookedGr1phontechnomancy: great, that means we can have the prompt default to "default" and no further checking/explanation is necessary. Thanks!
12:32technomancynp
12:33gtrakCookedGr1phon: fwiw, I agree with making the launch parameters more generic than a specific with-profile thing.
12:33gtraktechnomancy mentioned a local-dir specific vars file that would be convenient per-project.
12:33coventrybbloom: It would be great if there was an eclj version of the state examples, because I am having trouble following them.
12:34bbloomcoventry: why not try the eff interpreter?
12:34bbloomcoventry: it's pretty easy to build/run
12:34bbloomonly trick is that in ML-likes you need to write ;; after what you want tevaluated in the repl
12:34bbloom:-)
12:34gtrakCookedGr1phon: http://www.gnu.org/software/emacs/manual/html_node/elisp/Directory-Local-Variables.html
12:34technomancygtrak: maybe you could prompt for the whole command but have it pre-populated with a lein with-profile invocation?
12:35bbloomcoventry: i also did some experiments w/ using core.async's internals to do something eff-like here: https://github.com/brandonbloom/cleff
12:35gtraktechnomancy: I don't see a problem for an alias for the specific profile functionality, I just want what's underneath to be general.
12:35bbloomcoventry: but it's shallow like generators in python or C# or whatever
12:35bbloomcoventry: ie lexical finite state machines instead of arbitrary dynamic extents
12:36gtraktechnomancy: so we don't have interacting bits munging strings unpredictably.
12:36gtraki guess that's what you do in elisp, though ;-)
12:36technomancygtrak: it should just be a straight-up command though
12:36bbloomcoventry: i've also experimented with "first class handlers" in clojure w/ just regular exceptions (not delimited continuations). goal was to to explore syntax. see here: https://github.com/brandonbloom/handlers
12:36technomancythe string should be opaque
12:37CookedGr1phongtrak: technomancy: FYI, here's the pull request as it stands https://github.com/clojure-emacs/cider/pull/544
12:38CookedGr1phonI agree that it's a bit naff and inflexible having the string hidden away and manipulating it like this
12:38gfrederickstechnomancy: any ideas on how to do an acceptance test of a plugin w/o installing the plugin to the local mvn repo?
12:38gfredericks(i.e., the test should run a task on a test project that uses the plugin)
12:38CookedGr1phondepends whether you want to enforce that whatever lein command you run will actually run a repl I suppose...
12:39technomancygfredericks: you can use .lein-classpath in the test project to point to src/ of the plugin
12:39technomancykind of a poor man's plugin checkout-deps
12:39gtrakCookedGr1phon: yea, I was thinking about that. I occasionally want a 'lein do clean, compile, repl' cycle.
12:39gfrederickstechnomancy: and it won't complain that the plugin isn't in ~/.m2?
12:39gtrakCookedGr1phon: and those might have different profiles applied at each point.
12:39gtrakdepending on what I need, it's a complex project.
12:39CookedGr1phonthen again, it would be good if I could for example have it run a lein droid on-device repl, which would be too much for the current setup
12:40technomancygfredericks: it's like checkout deps, declare a released version of the plugin but use .lein-classpath to overlay the latest
12:40gfredericksoh I guess using a released version isn't terrible
12:40gfrederickstechnomancy: hokay cool enough thx
12:41CookedGr1phonfeel free to chip in on the pull request if you think it would be better all round to just prompt with the default lein string and give the user the option to edit it arbitrarily
12:42gtrakCookedGr1phon: I think it's best to just let the user fully-customize the string, a prompt is fine, it just needs to be obvious that the last step ought to be whatever makes a repl.
12:42CookedGr1phonit would certainly be more flexible, and still solves my main issue which is linking the leiningen process to the emacs window so I don't get loose ends everywhere
12:42gtrakand if it doesn't do it already, we want the default to be sensible, and amenable to something like the local-dirs vars.
12:42gtrakI'd use that.
12:44coventrybbloom: Yeah, eclj would have been good because it's built on a more familiar foundation, but eff would be the next natural choice.
12:46bbloomcoventry: unfortunately clojure's best available syntax(es) for effect handler matching aren't great...
12:47bbloomthe try/catch syntax is awful, multimethods only do static value dispatch or, like protocols, only type hierarchy dispatch
12:47bbloomreally want something closer to pattern matching, like in eff
12:50gfredericksoh snap clojars has a latest-version img for github READMEs
12:50gfredericksyaaaay
12:52iwohey, does anyone know if it's possible provide a callback (or similar) that can be called on eviction when using core.cache or core.memoize?
12:53justin_smithiwo: implement the cache protocol, write a clearing function that does the thing, or allows a configurable callback that does the thing
12:54justin_smithiwo: this could be done by wrapping some other functions already used to implement the cache protocol
12:55TimMcI now have a working website using Enlive for HTML generation. Here's an example of using it non-trivially: https://github.com/timmc/pellucida/blob/master/src/org/timmc/pellucida/single.clj#L123
12:56TimMcYou can see how the main transformation block is able to delegate to other fns to transform smaller portions of the page.
12:56iwojustin_smith: thanks! basically i'm caching something that needs to be explicitly 'closed' when it's evicted
12:58TimMcNow I finally have a thing to show people when I say Enlive is nice. -.-
13:00coventrybbloom: Oh, interesting. I thought the main difficulty was going to be that there are so many ways to cause side effects in clojure, independently of whatever framework you set up to track them.
13:01bbloomcoventry: if you own the interpreter, that's the easy part! https://github.com/brandonbloom/eclj/blob/master/src/eclj/env.clj
13:01bbloomthat file contains all the effects in clojure's semantics
13:01grimmulfrIs there a dommy way of changing certain style elements? I create an element and set a style, and I want to change one thing when clicking a button. Everything's done but I can't seem to find a way of altering the style (apart from overwriting it with changed values)
13:02bbloomcoventry: sadly, clojure.core has lots of semantic effects that are subsumed by calls to RT and other jvm interop
13:02grimmulfrI can do it with jayq, but though I keep it all dommy for DOM alteration
13:03coventrybbloom: But I suppose the idea is to give more control over whichever effects you choose to express in the handler notation, not to track them all.
13:03justin_smithiwo: there may in fact be an implementation of the cache protocol in core.cached that allows that kind of specialization; I don't know of one though
13:03bbloomcoventry: yeah, so having a general purpose "interop" effect is convenient as hell, but it means that the cat is out of the bag instantly
13:04bbloomcoventry: it's similar to mutable by default: once you do that, people are going to go wild with it
13:21AlwaysBCodingdoes anyone know how to colorize the output from `lein test` ... so that failing tests are red etc...
13:23technomancyAlwaysBCoding: lein difftest does that
13:23technomancyplus some other stuff
13:25cbpAnyone get this error using cider on emacs? Happens whenever I open parens and type a dot like so: (.) It freezes my emacs for a while. https://www.refheap.com/83843
13:25AlwaysBCodingtechnomancy: thanks, that looks pretty good. any idea how to customize it?
13:25technomancyAlwaysBCoding: not really, sorry
13:28blake__OK, I'm trying to "get" a few things about these three lines of code: https://www.refheap.com/83840
13:28cbpMaybe this new version of cider fixes that...
13:29blake__There's a defrecord, which I get. Then there's a function that, it appears, creates an instance of that record.
13:29justin_smithblake__: any questions? for (defrecord Foo ...) clojure generates ->Foo and map->Foo
13:29justin_smithautomatically
13:30jcromartieblake__: the ->RecordName function is called the "positional constructor" function
13:30blake__I did not know that. I only know -> as the threading macro, but that couldn't be the case here since it's part of the name.
13:31jcromartieand it takes the record fields in the order specified in the defrecord's field vector
13:31justin_smithblake__: -> is just a pair of symbols that can be part of any name
13:31jcromartiethere is also the map->RecordName variety that takes a map of fields
13:31justin_smith,(let [->->-> 1] (inc ->->->))
13:31jcromartiethose functions are generated by defrecord
13:31clojurebot2
13:31blake__justin_smith: Right, but since I didn't see "->AdditionalDependence" defined anywhere, I was confuseth.
13:32blake__So what would be the purpose of the function? A shorthand?
13:32justin_smithdocs for 1.3, still apply http://clojuredocs.org/clojure_core/clojure.core/defrecord
13:33justin_smithblake__: it is defined as a convenience
13:34justin_smithfunny, those docs use ->Foo but don't really describe it anywhere
13:34blake__I don't even see the "->Foo".
13:35justin_smithwell it is ->Someone
13:35blake__I went to that page to test out the code which is how I figured out what it did. (Though it's not identical, since one produces the second parameter as a vector and the other as a list.)
13:35blake__justin_smith: Aha. There it is.
13:36blake__So "->whatever" for serial parameters and "map->whatever" for key/value init?
13:37justin_smithblake__: well not just key/value, but coercion from a map with appropriate keys
13:37justin_smithbut yeah
13:37blake__Groovy, tx.
13:40coventryHow can I convert a clojure list of instances of JavaClass to [LJavaclass; ?
13:41bbloom,(into-array Class [Integer String])
13:41clojurebot#<Class[] [Ljava.lang.Class;@60b493>
13:42bbloomcoventry: ^^ that what you want?
13:46jcromartieany reason why I shouldn't assoc some of my model data with the Ring request on the way through the routes?
13:46jcromartielike, if it's a /projects/:key/* route, stick the indicated project under :route-project in the request
13:47jcromartieit could be a delay or something to avoid unnecessary lookups
13:47justin_smithjcromartie: seems like a cromulent middleware to me, as long as you have considered the security implications
13:47jcromartieyeah
13:48jcromartieblegh… it's hard to strike the right balance when drawing the line between dealing with the request and dealing with your business model directly
13:48justin_smithconsider also a cache, since I assume multiple requests would want to lookup the same item
13:48jcromartiewell the model is in memory in this case
13:48jcromartieso there's no real problem there
13:48justin_smithoh, ok
13:49jcromartiebut where do you stop passing a Ring request and start dealing with business domain stuff
13:49jcromartieit's not clea
13:49jcromartieclear
13:54justin_smithjcromartie: perhaps separate the routing (where it is a request) from handling (where it is business logic manipulation) - each middleware should belong on one side or the other of that division
13:55justin_smiths/business logic manipulation/manipulation of datastructures in order to implement business logic/
13:56coventrybbloom: Yes, thanks.
14:43HolyJakHello people! How do you solve the lack of static types in Clojure and the resulting inability to see what is the data that actually flows through a program at each step and errors such as expecting a map instead of vector, which are not discovered until [late in] runtime? I try now to use small functions with destructuring to document better the expected shape of data and pre- + post-conditions to fail fast if I make a mistake either in code
14:44rasmustoHolyJak: check out schema https://github.com/prismatic/schema
14:44ToxicFrogHolyJak: for small programs, I don't bother, I just test. For large programs, I use core.typed.
14:44rasmustoHolyJak: schema for runtime, core.typed for compile time
14:47amalloyjust don't write bugs. easy
14:48l1xmorning
14:49l1xi am wondering what is the right approach to have a transient variable that i keep adding stuff in a function and print out it's current state, println does not work on transient collections
14:49amalloyl1x: that's almost certainly not what transients are for
14:50bblooml1x: just use an atom, swap!, and conj
14:50bbloom,(def log [])
14:50amalloytransients should be treated like persistent collections which *may*, for performance, choose to mutate themselves
14:50clojurebot#'sandbox/log
14:50bbloom,(swap! log conj 1)
14:50clojurebot#<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to clojure.lang.Atom>
14:50bbloom,(def log (atom [])) ; whoop0s
14:50clojurebot#'sandbox/log
14:50bbloom,(swap! log conj 2)
14:50clojurebot[2]
14:50bbloom,(swap! log conj 3)
14:50clojurebot[2 3]
14:50bbloom,(swap! log conj 4)
14:50clojurebot[2 3 4]
14:50bbloomlog
14:50bbloom,log
14:50clojurebot#<Atom@e58b15: [2 3 4]>
14:50l1xahhh!
14:51l1xthis is what i am looking for
14:51l1xbbloom: thanks a million
14:51justin_smithif you define log outside the function, you can access it from your repl between function calls
14:51l1xyes, this is exactly what i need, you guys rock
14:52dbaschl1x: the more important question is, do you really need mutability?
14:52justin_smithl1x: a common pattern for me is to insert some data that a function is barfing over into an atom, then going in the repl and experimenting with said data and function
14:53justin_smithdbasch: at dev time? sure!
14:53dbaschjustin_smith: yes, I mean for prod
14:53justin_smithdbasch: yeah I don't let atoms called "debug" into my commits, not to mention prod :)
14:53dbaschjustin_smith: it’s not clear from l1x’s question what the actual problem is
14:54amalloyyeah, actually just half an hour ago i did the same thing: i was confused about what values x ever took on during the course of a doseq, so i (let [values (atom #{})] (doseq ... (swap! values conj x)) (prn @values))
14:54l1xdbasch: yes i do need that, but the atom approach solves that problem
14:54l1xi have an app that has to carry a minimal state
14:54justin_smithdbasch: I assumed he was wanting to get a better look at some intermediate values within a function for debugging purposes - though that may be wrong
14:54amalloy(spoiler alert: it turned out i was editing different code than i was running)
14:54l1xand it would be hard to solve without an atom or a transient vector, but as far as i can see the correct/idiomatic clojure way is using atom and swap!
14:55dbaschl1x: yeah, transient vectors are not for state, they are for building something faster
14:55dbaschtransients in general
14:55l1xdbasch: yes i just realized
14:55rasmustoamalloy: that's the worst, I did that with the linux kernel for about 3 weeks :( early_printk never showed up
14:55amalloy3 weeks!!!
14:55justin_smithl1x: transients are for performance, and should be used to replace a series of conj or assoc calls, not for arbitrary mutation
14:56rasmustoamalloy: I was in school, so it was ok
14:56l1xthanks
14:56justin_smithl1x: or what dbasch said
14:56rasmustoamalloy: hell, it'd probably still be OK
15:02mskoudLets say i want to write to a logfile different places in my application, what is the ideomatic way to do it? I'm not interested in a log library, but how to structure the code and where to place global vars...
15:03gfredericksmskoud: global vars for what?
15:03amalloydo you actually want to write to a log file from different places in your application, or are you hoping that answers to this question will lead to enlightenment in some other area?
15:04justin_smithmskoud: idiomatically, the only global var would be the function that logs
15:04justin_smithimho
15:04mskoudi'm not sure, but i guess i will need a file handle somewhere to the open file.
15:05puredangerone common pattern is to have an agent and to "send" it messages for it to write to the log
15:05justin_smithmskoud: yeah, the logging function should keep track of that though, and be able to reopen the file if it gets moved / compressed, etc.
15:05puredangerbut if you want that, it's probably better to use a logging lib like timbre which has all that set up already
15:06mskoudyes, i'm aware of the libs, but i'm trying to get to terms with how to complete "normal" tasks in Clojure :-)
15:06dbaschmsassak: the only good reason to not use a logging library would be if you hate the existing ones and your project is to write your own
15:07technomancyhating java logging is not an unreasonable position
15:07puredangermskoud: I would normally do this by using a library so I could get back to writing my application :)
15:07dbaschsorry, that was for mskoud
15:07puredangertechnomancy: that's actually a requirement
15:07justin_smithand there are indeed reasons to hate existing loggers - or at least want to improve them (and this has to do with the usage of globals funny enough)
15:07dbaschtechnomancy: agreed
15:07puredangerwe can all agree to hate Java logging
15:07technomancypuredanger: haha
15:08justin_smithlowfi: run your app inside nohup, redirecting to a named output, and use println :P
15:08mskoudi agree to use a library, bad example, i just was not completely sure how to acomplish a task like writing to a open file different place in an app.
15:09justin_smiththe above suggestion of an agent is a good one
15:09cbpUse an agent to queue
15:09bbloompuredanger: what's not to love about totally ungreppable gigabytes of xml?
15:09justin_smithor a core.async go block that logs things that come into a channel
15:09bbloompuredanger: especially when it's malformed
15:09puredangerbbloom: totally ungreppable gigabytes of malformed xml
15:10storme,(take 60 (range 0 1000 3))
15:10clojurebot(0 3 6 9 12 ...)
15:10cbpAre there any binary logging libraries around?
15:11cbpmaybe even with protobufs
15:11technomancycbp: I wish I could laugh, but check out systeemd
15:11puredangerjustin_smith: if your question is about how to deal with managing an open resource, then I would recommend passing it around as part of the state of your application
15:11technomancy*systemd
15:12technomancybinary logging is a real thing that otherwise-sane people are promoting
15:12puredangercbp: log libs like log4j have custom appenders, I presume some may exist that write binary but you could write your own
15:12puredangerlog4j has an email appender, so you could email it to yourself
15:13puredangeryou know, if you're insane
15:13bbloomtechnomancy: i mean, utf8 is binary data right? binary data is only a bad idea b/c we haven't given it a predictable universal schema :-P
15:13bbloomtechnomancy: solution: java serialization.
15:13puredangerlol
15:14llasramThanks, bbloom
15:14nullptrbbloom: on that topic, database tables are pretty much binary logs too :)
15:14cbp:-P
15:14puredangerBrian Goetz once told me that 20% of his time at Oracle was spent regretting Java serialization
15:15bbloompuredanger: 20% of my time programming was spent regretting other people's decisions regarding serialization
15:16bbloombut seriously, i can't fault anyone who shipped something and later apologizes
15:16bbloomshipping is a feature & apologizing makes it almost OK
15:17nullptrall code is bad, for most bad code there's a good explanation...
15:21technomancypuredanger: huh, I didn't realize Oracle had a 20% policy like google
15:21puredangerha!
15:21puredanger1 day per week can only be spent on regret
15:22bbloomlike they say, it's 120% time. the extra 20% is for self-loathing
15:26eraserhd"Blistering barnacles! Something's not shipshape: Invalid PGP key." ?
15:26eraserhdWhat kind of requirements are there on the PGP key?
15:27eraserhd(for clojars)
15:33storme,(,(some even? '(1 2 3 4))
15:33storme)
15:33clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
15:33storme.(some even? '(1 2 3 4))
15:34storme,(some even? '(1 2 3 4))
15:34clojurebottrue
15:44dbascheraserhd: I use my ssh key
15:46grimmulfrAnother silly question from me: Any way of getting crossdomain json with cljs-ajax?
15:46grimmulfrI haven;t dealt with this much as I always make requests on the same server, but I want to try out some public json sources and nothing works for me, I keep getting Access-Control-Allow-Origin'
15:48Frozenlo`grimmulfr: Are you the one controlling the server of the json sources?
15:48nullptrx-domain json as in ... jsonp?
15:49grimmulfrWell, no, that's the problem
15:49grimmulfrHmm, I just started using cljs-ajax
15:49grimmulfrCan I use it for jsonp requests?
15:49grimmulfrI kinda suck at this, never had to deal with this sort of problems :(
15:49HolyJakrasmusto, ToxicFrog: Thanks. I know of core.typed and schema but do not thing everybody uses them - yet I encounter these problems always. I do write tests - perhaps just not good enough.
15:51Frozenlockgrimmulfr: It does suck. I bumped my head multiple times on the same-origin policy thingy. It's on the public Internet, but you can't grab it....
15:52nullptrgrimmulfr: that lib looks to be a different case -- basically abstracting goog.net.XhrIo*
15:52nullptri would suggest using (or wrapping) goog.net.Jsonp
15:52grimmulfrhm, jq/ajax works wonderfully it seems
15:52grimmulfrI managed to get a response
15:52grimmulfrFrozenlock: I know, right?
15:53grimmulfrWe always host out code on the same server so this is rarely a problem
15:53nullptrgrimmulfr: that seems curious -- x-domain protection is not lib specific :)
15:53grimmulfrAnd we do most of the access from within flash, and have crossdomail all nicely setup
15:53grimmulfrwell, nullptr, I just did (let [jsonstring (jq/ajax "http://api.automeme.net/text.json&quot;)] and then printed that out
15:53FrozenlockI'm with nullptr here, how could a different lib help you?
15:53grimmulfrand it printed the entire object, which does include the response
15:54grimmulfrone works, the other doesn't. Pretty sure it's my error of course
15:54grimmulfrI could pastie what I was trying, maybe I'm missing something
15:55grimmulfrwhat was the paste site again? (I'm used to pastie)
15:55Frozenlockrefheap
15:55FrozenlockShame on you for not setting emacs to paste automatically on refheap!
15:55Frozenlock:-p
15:55grimmulfrI should do that
15:57grimmulfr[ajax.core :as ajax], and then https://www.refheap.com/83861
15:58Frozenlockgrimmulfr: your doing a POST?
15:58Frozenlock*you're
15:59grimmulfrI just used some example
15:59grimmulfrNow that I think about it, I shouldn't
15:59lucswgrimmulfr: the reponse have Access-Control-Allow-Origin:*
16:00lucswgrimmulfr: so it seems that browser allows to execute cross domain req.
16:01grimmulfrI should kill myself right about now
16:01grimmulfrGet works, obviously. It;s always that one little thing, ain't it
16:01lucswhttps://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
16:01TravisDIs there any support in clojure for starting new threads without resorting to Java? Also, can someone explain why this does not print hi 10 times? (repeatedly 10 #(.start (new Thread (fn [] (println "hi")))))
16:02Frozenlockgrimmulfr: 'that one little thing' is what prevents me from achieving great things.
16:02FrozenlockIt's always there, lurking in the shadows
16:03lucswTravisD: it does print hi in my repl..
16:03TravisDhm
16:03jcromartieTravisD: future
16:03jcromartiealso "repeatedly" is lazy
16:03TravisDOh, and it does for me too.
16:04lucsw:)
16:04TravisDsome other code of mine that is suspiciously similar does not :(
16:04TravisDjcromartie: I'll check out future
16:05jcromartieTravisD: since (repeatedly n f) creates a lazy seq, it won't be realized until it's consumed
16:05jcromartieso for example
16:05jcromartie,(def x (repeatedly 100000 #(println "spam")))
16:05clojurebot#'sandbox/x
16:05jcromartienothing :)
16:05TravisDAhh
16:05TravisDthat makes sense
16:05grimmulfrDamn, only that jsn works, any other, still same error, even with get
16:06jcromartiebut if I said, instead:
16:06jcromartie,(take 10 (repeatedly 100000 #(println "hello")))
16:06clojurebot(hello\nhello\nnil hello\nnil hello\nnil hello\nnil hello\nnil hello\n...)
16:06jcromartieit is a real mess though… because we're mixing output with a seq :(
16:06TravisDjcromartie: Could also use dorun, I guess
16:07jcromartiedon't print from lazy seqs except for logging/tracing
16:07jcromartieyeas
16:07jcromartieif you just want to do something n times, use dotimes
16:07jcromartie,(dotimes [_ 10] (println "hi"))
16:07clojurebothi\nhi\nhi\nhi\nhi\nhi\nhi\nhi\nhi\nhi\n
16:07TravisDI am writing some code that lets different threads get their own random number generators. I just wanted to make sure they were getting different seeds)
16:10TravisDfantastic, it appears to work :) And future is much nicer than the (.start (new Thread fn)) business
16:11grimmulfrSo if the json is accesible within my browser, but not from this code, it's the code, right?
16:11jcromartiefns are also runnable
16:11jcromartiewell you knew that
16:12puredangerif you're using JDK 8, ForkJoinPool has a commonPool now too that you can submit tasks to
16:12nullptrgrimmulfr: no, depends on the x-domain policy
16:12nullptrsee link above from lucsw
16:12puredangerTravisD: that ForkJoinPool comment was for yoiu
16:13TravisDpuredanger: Ah, cool. Don't think I'm using JDK 8 :(
16:13grimmulfrYeah, none of the other urls work. Just that one (same for jq/ajax)
16:13grimmulfrI need to find another way
16:14nullptr$ lynx -mime_header http://api.automeme.net/text.json | grep Origin
16:14nullptrAccess-Control-Allow-Origin: *
16:14grimmulfrYeah, that one works with my code too.
16:15grimmulfrNothe of other that I try though, they only work in the browser
16:15grimmulfrhttp://xkcd.com/info.0.json
16:15grimmulfrThis is the one I;m after
16:16nullptrit lacks the header, so you're stuck unless there's a jsonp version
16:16nullptrotherwise you'll have to proxy
16:16grimmulfrMeh, too much hastle for just testing out json stuff
16:16grimmulfrSo it wasn't the code
16:28amalloyTravisD: you could also use https://github.com/flatland/useful/blob/develop/src/flatland/useful/utils.clj#L201, if you just want a different Random for each thread
16:28Glenjaminhi guys, could i ask an opinion: when using an arrow, do you quote forms that have no arguments? eg (->> table (rseq) (vals) (apply concat))
16:28amalloy(def random (thread-local (Random.))), (let [my-thread-random @random] ...)
16:29amalloyGlenjamin: i always do, but many people don't
16:29dbaschGlenjamin: I don’t
16:29llasramGlenjamin: I do if any of the threaded forms take arguments, and don't if none do
16:29bbloomi don't either
16:29TravisDamalloy: I'm doing something like this: https://www.refheap.com/9db1992783a03d6afa2033d1c
16:29Glenjamini've got them lined up vertically, the un-paren-ed ones look a bit rubbish
16:29Glenjaminbut (:keyword) also looks silly
16:31amalloyGlenjamin: you're probably using ->> too aggressively anyway: i think (apply concat (vals (rseq table))) is substantially more readable, or perhaps (->> (vals (rseq table)) (apply concat))
16:32amalloyor, if you want to be a bit sneaky, (mapcat val (rseq table))
16:32Glenjaminamalloy: i shortened it a bit, the full one is https://www.refheap.com/83863
16:32Glenjaminhah, i started with (vals) (mapcat identity) before i found (apply concat), (mapcat val) is quite nice
16:35amalloythe length isn't really important - i encourage using ->> not to reduce nesting, but to increase readability by emphasizing what's most important. so i'd probably write (take 15 (for [[k vs] (rseq table), v vs] (lookup-user model v)]))
16:35amalloyer, modulo that dangling ]
16:36TravisDamalloy: Does what I posted look reasonable?
16:36amalloyor if you hate using 'for, maybe (take 15 (->> (rseq (mapcat val table)) (map (partial lookup-user model))))
16:37Glenjamininteresting, i like that way of thinking about it
16:37amalloyand of course i got the nesting wrong in that one. (take 15 (->> (mapcat val (rseq table)) (map (partial lookup-user model))))
16:38amalloyTravisD: i dunno, seems fine but i lack the context to make much of a judgment
16:39TravisDAh, I was just wondering if the code you posted would be substantially cleaner
16:39TravisDamalloy: I just want differently seeded random number generators for each thread so that I can parallelize some random experiments without worrying about locking the rng or anything
16:41amalloyGlenjamin: http://stackoverflow.com/questions/12715577/when-should-i-use-the-clojure-arrow-macro/12716708#12716708 is another thing i wrote on that topic
16:41amalloyTravisD: if you don't care about reifying the seed or the rng as values you can manipulate directly (you just care that they exist and are different per thread), i think a thread-local is simpler
16:42TravisDamalloy: the only thing I want to make sure is that I can control what seeds get used by the different threads
16:42TravisDso if I spawn N threads, those N threads will always use the same N seeds, possibly reordered
16:46amalloymine would have some race conditions, like if f finished very quickly, the same thread might be reused from the future pool, and then it would continue using the same rng rather than requesting a new one
16:46amalloyif you want each *call to f* to have a different rng, vs each *thread* to have a different rng, you want a different solution
16:47TravisDhmm, I'm not sure which of those two options I want. I guess it depends on how I set up the experiments. if f does one complete run of everything, then I probably want each call to f to use a specific rng
16:47amalloysince there's not necessarily a guarantee that there's a one-to-one correspondence there, even though it looks like it
16:47TravisDthe main thing I want is to maintain repeatability
16:48TravisDin a single thread I can just initialize the RNG with some seed and I'll always get the same results. I was thinking I would have the same thing if I guarantee that each of N threads gets some predicable seed
16:48TravisDand then I can split my experiment's trials among those threads
16:51TravisDI'll go with this for now, and if I need to change it later I will :)
16:52amalloyif each task T[i] uses the rng in some way, then to maintain repeatability you have to also distribute them to the worker queues (which can have a thread each, or not) in the same way every time
16:53amalloysince giving worker-1 T[0] and then T[1], and worker-2 T[2], will get different results than giving worker-1 T[0] and T[2], with worker-2 getting T[1]
16:55TravisDamalloy: Yeah, I was thinking that. So I was planning to control the task scheduling myself
16:55TravisDah, I see. But the seeds might not pan out equally all the time
16:56TravisDI'll need to think about it some more
16:58TravisDit seems surprisingly complicated
17:38kwertiiIs there a way to parameterize Midje facts? For example, if I have two different implementations of a protocol, they should both pass the same tests with regards to the protocol itself. Can I somehow pass each implementation in as a parameter to a fact?
17:51turbopapehi Guys, Is core.async considered stable enough so I can use it in production ?
17:51cbpyes
17:52turbopapeOk thanks cbp. Large traffic ok ?
17:53bbloomturbopape: if you have to ask, you probably don't have large traffic
17:53cbpI wouldn't be able to answer anyway. I only use it on cljs
17:54turbopapeno bbloom, but I just wanted to have an Idea about the maturity of the lib.
17:55bbloomturbopape: it's quite stable
17:55amalloybbloom: related: http://stackoverflow.com/questions/17142960/lamina-vs-storm
17:55turbopapeok, thanks bblom !
17:56amalloyspecifically the "30GB/day is Big Data" segment
17:56bbloomamalloy: i saw a guy give a talk about "big data"
17:56bbloomhe showed the worst chart i've ever seen
17:56bbloomit was a bar chart w/ two bars, one really tall and one not as tall
17:56bbloomthe Y axis was not labeled
17:56bbloomthe X axis was labeled "data sets"
17:57bbloomi asked him what the Y axis was, he said that he wasn't sure how big the "small" dataset was, but the "large" data set was "huuuge"
17:57bbloomi said "how huge?"
17:57bbloomanswer: "4 gigabytes"
17:57amalloythis was in like the 1980s, i guess?
17:57FrozenlockWasn't there something like that about mongodb? Like, 'it's for bigdata', where bigdata is 100gb
17:58jcromartiethat's awesome
17:58bbloomthey had a 6 machine cluster to deal w/ their 4 gigabytes. when i pointed out that it fits in memory on my laptop, he got mad at me....
17:58jcromartie:)
17:58bbloomthis was about a year ago
17:58bbloomlol
17:58jcromartiebut what if you had *five* GB
17:58jcromartiehow about now smart guy?
17:58Berend__lol
17:58Frozenlockgasp!
18:01dbaschbbloom: https://twitter.com/dbasch/status/269868078152691714 :)
18:03bbloomdbasch: true story.
18:07akurilinQuick question: how do I make sure none of my test source is ever run when either spinning up a dev ring app or using an uberjar? I'm suspecting I'm referencing a test namespace somewhere and it's using a fixture that cleans-up the db
18:07akurilin:(
18:07akurilinDon't want to commit this to production, this would be bad.
18:08technomancyakurilin: use `lein with-profile production repl` or whatever
18:08technomancyakurilin: also use profile isolation if you do AOT; see the last question in the lein faq
18:10akurilintechnomancy: what determines whether test/ folder is taken in consideration?
18:10technomancyakurilin: that's added by the :base profile
18:10technomancythe production profile doesn't include it
18:10technomancyalso the uberjar task strips out the base profile
18:10technomancybut you can leak from AOT if you don't use profile isolation
18:11akurilintechnomancy: is it possible to find out what the characteristics are of each of the profiles that lein comes with? Looking through docs.
18:12technomancysure; show-profiles does that
18:14akurilintechnomancy: oh cool
18:14akurilinhm I might have an old lein, mine doesn't have production in it
18:15technomancyakurilin: production is just shorthand for the empty profile
18:16l1xdbasch: :D
18:16l1xthat tweet
18:18akurilintechnomancy: cool, thakn you
18:18justin_smithakurilin: side effects at the top level are bad, even in a test ns
18:19justin_smithakurilin: or do you mean someone is calling test/run-tests?
18:20technomancyeh, lots of good reasons to make sure tests don't get included
18:20technomancyyou can have defmethods that screw everything up
18:20technomancyor shadow a src/ namespace or config file with something that only makes sense during tests
18:21justin_smithyeah, just addressing the specific symptom which I would think would not be an issue unless the test code actually got explicitly run
18:41akurilinjustin_smith: yeah I actually realized I recently started running tests with envdir and the env vars folder kept pointing the tests at the dev db
18:41akurilinso it was nuking that one instead of the test db
18:41akurilinbut that's a good point, the fixtures shouldn't go off by themselves without someone calling run tests
18:42akurilinbtw the other day I discovered that rails tests are all run in one transaction, so they rollback the transaction at the end of eacdh integration test
18:42akurilinmuch better than truncating the whole thing like I do :D
18:43akurilinexcept I have no idea how to force test sql, korma conn pool and clojure.jdbc to all share the same connection
18:43justin_smithakurilin: look at how c3p0 is used
18:44justin_smithyou can specify a "connection provider" that can specify a shared connection instance
18:45akurilinhm interesting, I'll have to investigate
18:54mercwithamouthcan someone tell me what's going on with this 'assoc!' error message? https://gist.github.com/anonymous/8dd29ad26facdb30d55a
18:55justin_smithtwo namespaces you refer both define assoc!
18:55amalloymercwithamouth: just desserts for referring to :all
18:55justin_smithremember that clojure.core is implicitly referred
18:55amalloyclutch probably defines assoc!
18:56justin_smithmercwithamouth: instead of trying to guess which definition you want to use, it is complaining that you are trying to refer to it from two different places at once
18:57amalloywell, justin_smith, it *does* guess - this is a warning message, not an error
18:57justin_smithoh, I misread the exception thing
18:57amalloyhm, maybe i'm wrong. that's how it used to behave, but that sure does look like a stacktrace
18:58justin_smithwell, regardless, it definitely did something other than guess, even if it guessed too (pedantry rescued)
18:58cbpIllegal state exceptions usually occur in repl sessions i think
18:59mercwithamouthamalloy: hmmm so simply get rid of the :refer all
18:59mercwithamouthwhen is that actually necessary....ahh i see. clutch has it's own 'assoc!' function thats conflicting?
18:59cbpwhen you try to replace a referred var from one namespace with another
18:59justin_smithmercwithamouth: require with an :as argument is much cleaner, and avoids these issues (among others)
19:00mercwithamouthjustin_smith: gotcha, that WOULD be cleaner
19:00justin_smiththen, when you want to edit your code, or derive something from it, it is clear where the functions you use were coming from
19:04dbaschmercwithamouth: or if you want to refer, refer to only what you need
19:04dbaschotherwise refer all is a longer way of saying use :)
19:05mercwithamouthdbasch: yeah, i'm sure as i become more familiar with the libraries i'm using i'll trim things down
19:05cbpIf a new jar with the same version number got uploaded, I have to delete it first from my .m2 right?
19:05mercwithamouthlol, gotcha
19:05dbaschrefer is something to use judiciously anyway
19:05dbaschwhen in doubt, require as
19:07amalloycbp: that's step 1, yeah. step 0 is murdering the person who overwrote a release version
19:07cbpamalloy: it's a SNAPSHOT so I guess it's ok
19:07amalloycbp: in that case you don't have to delete anything
19:08amalloysnapshots are supposed to get updated, and they do
19:08cbpOh
19:08technomancylein -U deps to force it
19:08technomancyotherwise it's there for 24h
19:08cbpthanks
19:09amalloylein -U do clean, clean, clean, clean, deps # just in case
19:09technomancy>_<
19:10justin_smithlein do out, out, damn spot
19:10cbpi copy pasted that
19:10hyPiRionamalloy: You should use lein twice for that. Too bad it was reverted
19:11amalloylein repeat, i think it was
19:11hyPiRionoh, maybe. At least it was repetition
19:11justin_smithlein reich clean https://www.youtube.com/watch?v=xU23LqQ6LY4
19:12amalloyhyPiRion: https://github.com/technomancy/leiningen/pull/688
19:12hyPiRionamalloy: ah, there we go
19:13amalloyah, i crack me up. "For when `lein clean && lein deps` just isn't enough. USAGE: `lein repeat 5 do deps, clean, compile, uberjar`"
19:13cbphah
19:15cbpdoes lein -U deps update plugins too?
19:15technomancycbp: I think so
19:16TravisDCan anyone explain to me why (do (def ^:dynamic *x* 0) (def ^:dynamic *xp1* 1) (binding [*x* 10, *xp1* (inc *x*)] *xp1*)) returns 1 instead of 11?
19:17cbp(doc binding)
19:17clojurebot"([bindings & body]); binding => var-symbol init-expr Creates new bindings for the (already-existing) vars, with the supplied initial values, executes the exprs in an implicit do, then re-establishes the bindings that existed before. The new bindings are made in parallel (unlike let); all init-exprs are evaluated before the vars are bound to their new values."
19:17justin_smithTravisD: maybe binding has parallel rather than serial semantics?
19:17cbpkeyword parallel
19:18TravisDah, cool
19:18justin_smithoh yeah, there we go
19:18TravisDI guess I should have checked
19:18TravisDIs there a reason for it to be like that?
19:19justin_smithyou could use nested binding forms if you wanted a specific order I guess
19:20justin_smithI don't think large binding forms are expected the way large let forms are
19:21TravisDyeah, I was just curious because I found it surprising that it behaves that way. Seems like it should only be different from let if there is a reason
19:22BronsaTravisD: I guess it's more efficient to push all the thread bindings at once
19:22TravisDah
19:24justin_smithmy hunch is that sequential let is a concession to imperative programming, and you don't need to make that kind of concession in a form like binding
19:25TravisDI feel like a sequence of definitions isn't really imperative
19:26justin_smithTravisD: you can't have chaining of state without strict sequence
19:26justin_smithand let is often used in idiomatic clojure code to chain state
19:27TravisDjustin_smith: I mean I don't see how it's avoidable. Some definitions depend on other definitions. The sequence was already there
19:27dbaschjustin_smith: for that matter, s-expressions shouldn’t be evaluated sequentially either. It’s not really about state, it’s more about execution of code
19:28justin_smithdbasch: but the ordering is important because of state (even if the state is not declared explicitly in the code)
19:28justin_smithI'm not saying "don't do sequential imperative logic", I am just saying it is there
19:28dbaschjustin_smith: same as when you define functions mathematically, based on previously defined functions
19:28dbaschjustin_smith: it’s not really state, it’s just dependent definitions
19:29dbaschjustin_smith: in that you cannot go back and change a definition in a theorem, for example
19:29justin_smithdbasch: but you can sequentially alter bindings in a let
19:29justin_smiths/alter/shadow
19:30dbaschthe point being that a program is not a disconnected sequence of expressions that assumes any execution order is possible
19:30dbaschbinding is the exception here
19:32justin_smith,{:a (println :a) :b (println :b) :c (println :c) :d (println :d) :e (println :e) :f (println :f) :g (println :g) :h (println :h) :i (println :i)}
19:32clojurebot:e\n:g\n:c\n:h\n:b\n:d\n:f\n:i\n:a\n{:e nil, :g nil, :c nil, :h nil, :b nil, ...}
19:33bbloomthe evaluation semantics for maps & sets are particularly interesting b/c of the phase separation of the reader
19:33justin_smithI think that was a non-sequitor
19:34justin_smithor maybe not (hit enter too soon)
19:36l1xwhat is the opposite operation to conj! ?
19:36justin_smith,(doc dissoc!)
19:36clojurebot"([map key] [map key & ks]); Returns a transient map that doesn't contain a mapping for key(s)."
19:36bblooml1x: for what data structure?
19:36l1xvector
19:36justin_smithor maybe ...
19:36justin_smith(doc pop!)
19:36clojurebot"([coll]); Removes the last item from a transient vector. If the collection is empty, throws an exception. Returns coll"
19:37bblooml1x: justin_smith is right, it's pop! ... however ...
19:37bblooml1x: don't start with transients!
19:37l1x:)
19:37l1xthis is not for trasients
19:37justin_smiththen why would you use conj!
19:38bbloomdon't start with any side effecting thing if you can help it
19:38bbloomif you have a ! operation, you should also have a no-! operation that you're optimizing
19:38justin_smithI like how emphatic I sound when talking about functions on transients
19:38l1xi mean yes, no !
19:38justin_smithpop
19:38justin_smith,((juxt pop identity) (conj [0] 1))
19:38clojurebot[[0] [0 1]]
19:39l1xwell i guess i need to ask a different question
19:39justin_smith,((juxt pop identity peek) (conj [0] 1))
19:39clojurebot[[0] [0 1] 1]
19:39l1xso i am trying to implement a simple function that counts how many times it has seen a certain string
19:39justin_smithstatefully I assume?
19:40l1xyes, state has to be carried
19:40bbloomBronsa: ignoring perf, there's good semantic reason bindings occur in parallel
19:40l1xso first i though i just use a simple [] but I guess it is not the best option
19:41justin_smithl1x: well, if you really want a stateful thing, I guess have an atom mapping string to count
19:41l1xsecond thought is [{:string count} {:another_string count}]
19:41l1xthere are multiple strings
19:41l1xyes atom is for sure
19:41bbloom(doc swap!)
19:41clojurebot"([atom f] [atom f x] [atom f x y] [atom f x y & ...]); Atomically swaps the value of atom to be: (apply f current-value-of-atom args). Note that f may be called multiple times, and thus should be free of side effects. Returns the value that was swapped in."
19:42l1xthat part you already pointed out earlier
19:42l1xi am more interested in the optimal data structure
19:42l1xi guess i am going to experiment with [{} {} ]
19:42bbloomwhat's wrong with a map?
19:42bbloom,(update-in {} ["some string"] (fnil inc 0))
19:43clojurebot{"some string" 1}
19:43bbloom,(update-in {"some string" 5} ["some string"] (fnil inc 0))
19:43clojurebot{"some string" 6}
19:43bbloom,(def a (atom {}))
19:43clojurebot#'sandbox/a
19:43justin_smith,(let [state (atom {}) counter (fn [s] (swap! state update-in [s] (fnil inc 0)))] (mapv counter ["hi" "hi" "bye"]) @state)
19:43clojurebot{"bye" 1, "hi" 2}
19:43bbloom,(swap! a update-in ["str 1"] (fnil inc 0))
19:43clojurebot{"str 1" 1}
19:43bbloom,(swap! a update-in ["str 1"] (fnil inc 0))
19:43clojurebot{"str 1" 2}
19:43bbloom,(swap! a update-in ["str 1"] (fnil inc 0))
19:43clojurebot{"str 1" 3}
19:43bbloom,(swap! a update-in ["str 2"] (fnil inc 0))
19:43clojurebot{"str 2" 1, "str 1" 3}
19:46l1xbbloom: thanks this is even better
19:49mercwithamouthhmm not really a clojure question necessarily...but lets say i ask for a username and a password to entered in twice...how would i go about sending that request via curl?
19:50Frozenlockmercwithamouth: what do you mean entered twice? In the same form?
19:50mercwithamouthi'm coming from a 'newb' rails background so now i'm trying to get a good grasp on dealing with http and routing in general
19:51mercwithamouthFrozenlock: well a confirmation 're-enter your password'
19:51justin_smithmercwithamouth: curl -d user=whatever -d pass=secret -d pass=secret
19:51justin_smiththough realistically you would have two fields with different names, and you provide those field names via curl
19:51mercwithamouthjustin_smith: ahh, thatnks!
19:51mercwithamouthyeah well pass and pass1
19:51l1xbbloom: update-in is really useful i did not know about it
19:52mercwithamouthwhich well...i think i'll change that to salted_pass right now
19:52justin_smiththough post does allow the same key to be supplied more than once iirc
19:52bblooml1x: update-in is one of the best things ever.
19:52l1xyeah it seems so :)
19:52justin_smithupdate-in, get-in, assoc-in
19:52l1xo hai nested data structures
19:52bblooml1x: chains real nice too
19:52l1xget-in i am using everywhere, it is just crazy useful to get to a certain nested level in a structure
19:53justin_smith,(assoc-in {:a [1 2 3]} [:a 1] 1.5)
19:53clojurebot{:a [1 1.5 3]}
19:53l1xnice
19:54l1x,(def a (atom {}))
19:54clojurebot#'sandbox/a
19:54l1x,(swap! a update-in ["str 1"] (fnil inc 0))
19:54clojurebot{"str 1" 1}
19:54l1x,(swap! a update-in ["str 1"] (fnil inc 0))
19:54clojurebot{"str 1" 2}
19:54l1x,(swap! a update-in ["str 1"] (fnil dec 0))
19:54clojurebot{"str 1" 1}
20:03mercwithamouthnot to be too annoying or spoon fed but why do i get not response from localhost:8080/register as my code is? https://gist.github.com/anonymous/2bbbeb0d6e5c14faa404
20:04justin_smithan empty response?
20:04justin_smithis the request you are sending POST?
20:04nullptrmercwithamouth: your get is empty (GET "/register" [])
20:05mercwithamouthahh hmm could i do (Get "/register" [(str "hello")]) just to test it?
20:05mercwithamouthGET*
20:05l1x,(swap! a update-in ["str 1"] (fnil dec 0))
20:05clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: a in this context, compiling:(NO_SOURCE_PATH:0:0)>
20:05l1xhoops
20:05justin_smithseems that would do it, though str is redundant there
20:05l1x:)
20:06justin_smith(GET "/register" "hello") - ring will handle that just fine
20:06mercwithamouthyeah...
20:06justin_smith(you also don't need the array)
20:06justin_smith*vector
20:07mercwithamouthunsupported binding "hello"
20:07nullptrjustin_smith: *compojure :)
20:07nullptrmercwithamouth: put [] in front
20:07justin_smithoh, fine, compojure doesn't like it then
20:07justin_smithnullptr: ring would handle it fine
20:07justin_smith(I don't actually use compojure)
20:08mercwithamouthnice!
20:08mercwithamouththanks...there we go. now i can play...
20:08nullptryeah it's good to do enough with just ring that you convince yourself you need compojure
20:08nullptrboth great libraries
20:09justin_smithnullptr: we actually replaced compojure because it sucks at data driven route generation and reverse routing
20:09mercwithamouthyeah, i'm just taking my time and going through clojure and web chapter, web dev with clojure and wikipedia now to get a good handle on things i was guarded from in the past
20:09dbaschmercwithamouth: nonsequitur, but you should enforce a longer minimum password length :)
20:10nullptrjustin_smith: yeah, i stumbled upon bidi recently which has a generation story -- did you do something custom?
20:10mercwithamouthdbasch: 8 fair enough?
20:10justin_smithnullptr: for the caribou project we have our own lib, caribou/polaris
20:10dbaschmercwithamouth: I use 12
20:11mercwithamouthjeethus...
20:11dbaschmercwithamouth: btw, why do you have pass and pass1?
20:12justin_smithdbasch: "your passwords did not match, please try again"
20:12dbaschjustin_smith: that’s something you probably want to handle in the front-end, you don’t need a round-trip to the server for that
20:12justin_smithfair enough
20:13mercwithamouthdbasch: i'm debating on making the user enter the password in twice during registration
20:13dbaschmercwithamouth: you should, but that’s the browser’s business
20:13amalloymercwithamouth: i recently discovered that one of my 8-character passwords can be looked up on the web, just by typing its md5 into google. 8 characters is not really enough to be secure
20:13Frozenlockmercwithamouth: Do you have email password?
20:13Frozenlock*reset
20:14mercwithamouthFrozenlock: nah i don't have anything as of yet...
20:14mercwithamouthamalloy: hmm...good to know....12 it is then
20:14FrozenlockThen yes, you should absolutely ask the user to input the psw twice.
20:15l1xbbloom: how would you remove a key from the map with swap! ? can i use dissoc-in or you have a better idea?
20:15bblooml1x: just update-in with dissoc
20:15mercwithamouthmy first app is going to be a note taking app similar to a blog....i have a few ideas i'd like to add on to a traditional blog then after that i'll move on to something serious
20:15bbloomor just swap with dissoc directly
20:15bbloom,(swap! (atom {:x 1}) dissoc :x)
20:15clojurebot{}
20:16l1xawesome!
20:16mercwithamouthlong term it's a blog engine that allows annotations, versioning and private posts for me only. you'll be able to upload markdown files to create your posts(not a static blog generator)
20:16l1xclojure and #clojure makes my life easier :)
20:17mercwithamouth#clojure is pretty good...i can even ask my silly questions here and not get flamed
20:32l1xhahah
20:33l1xwell, i dont think that the clojure community is particularly flammable :)
20:33bbloomit's true. we're all robots made out of inert metals
20:33justin_smithcombustion is a mutation, we don't go for that around here
20:34AWizzArdcore.async experts here? I saw the first code example here: http://stuartsierra.com/2013/12/08/parallel-processing-with-core-async
20:34AWizzArdThe `parallel` FN, and wonder why it was written that way.
20:35AWizzArdInstead of the let, doall and repeatedly there could have been a simple (dotimes [i n] (go-loop …)).
20:35AWizzArdAnd that last go block, which returns a channel also seems not to do much.
20:35mercwithamouthha
20:36justin_smithAWizzArd: with dotimes, where would the channel that returns the result be?
20:36mercwithamouthhopefully i'll have my hands on Om next month...that looks really interesting. i'll tinker with react with js for a few days first i suppose
20:37AWizzArdjustin_smith: the parallel FN takes an explicit `output` chan as argument.
20:38AWizzArdIt writes all its results there.
20:38justin_smithAWizzArd: oh, sorry, I'm just looking at this for the first time
20:38AWizzArdnp
20:38bbloomAWizzArd: no idea why he didn't just use dotimes, but the purpose of the final go block is to give you an "all done" message
20:39bbloomAWizzArd: w/o closing the explicit output channel, since you may have other people who are writing to that
20:39AWizzArdbbloom: how would the all done message look?
20:40AWizzArdbbloom: a simple return of nil?
20:40bbloomAWizzArd: something like (do (<! (parallel 5 f input output)) (close! output))
20:41bbloomAWizzArd: the returned channel will simply close after the doseq and closed channels yield nils from attempted reads
20:42bbloomAWizzArd: so the caller can block on the return expression, which will close when the doseq finishes internally
20:42AWizzArdHmm, in my experiments the return channel always replies with nil.
20:43AWizzArdah no, wait
20:45AWizzArdbbloom: okay, the returned channel always blocks, until I close the input chan.
20:45bbloomAWizzArd: try a simpler example
20:45AWizzArddid
20:45bbloom(<!! (go 1))
20:45AWizzArdAnd the idea is: the caller of parallel, who will receive this return channel, has no info of the status of the input chan?
20:45bbloomuse the !! versions when testing in your repl
20:45bbloomat the top level anyway
20:45AWizzArdyes, I used the !!
20:46AWizzArdRight now I was just thinking: when I put the input chan as arg, then why can’t I know that it was closed? So why would I need the return chan as info to know that the input chan was closed.
20:47bbloomAWizzArd: it seems to attempt to exhaust input channels
20:47AWizzArdI understand now that it works as you suggested. Now I just look for a scenario where I would like to know that the input channel was closed.
20:49bbloomAWizzArd: this parallel function knows when an input channel is closed b/c it returns nil... and then each go loop in here will run until it can send that value...
20:49bbloomthe output channel may be backed up
20:49bbloomso input may close long before the go-loops terminate after succeeding to write to output
20:49bbloomthe final go block exists to wait until all inputs have been fully exhausted and successfully copied to the output channel
20:50AWizzArdHmm yes.
20:50AWizzArdI just tested it.
20:50AWizzArdI started 5 jobs, but didn’t read any result. Now I checked if the return chan is closed, and it wasn't.
20:51AWizzArdThen I closed the input chan, but reading from the return chan still blocked. First I had to read all 5 outputs from the out chan, and immediately afterwards the return chan got closed.
20:51AWizzArdOkay fine, then this is all clear now.
20:51bbloomtry creating a buffered output channel
20:51bbloomjust to see how that behaves
20:52AWizzArdAnd this also explains why he used repeatedly vs. dotimes
20:52bbloomit does?
20:52bbloomoh, b/c he needed the output channels, oh yeah
20:52AWizzArdyes
20:52bbloomthat makes sense, but i'd have done it differently :-P
20:53AWizzArdbbloom: yes, with a buffered out chan the return chan immediately closes (of course), when the input chan gets closed.
20:54AWizzArdbbloom: do you have a spontaneous idea how you would have written that parallel FN?
20:56AWizzArdbbloom: only this doall seems to not be required
20:56AWizzArdas the following doseq completly eats the repeatedly
20:56bbloomAWizzArd: the doall is definitely required
20:56bbloomAWizzArd: nope!
20:56AWizzArdIt funnily seems to work.
20:56bbloomthe doseq will block on the first input to be exhausted
20:56AWizzArdI just tried it without the doall and right now it looks as if it behaves the same way.
20:57bbloomit's going to force an ordering, breaking the parallel feature of the parallelism :-P
20:57amalloyugh, why does ring accept InputStream but not Reader? it's supposed to be sending characters
20:58justin_smithamalloy: well ring can send arbitrary data - or am I misunderstanding you?
20:58amalloyAWizzArd: if you remove the doall, then you'll only spin up tasks the moment you start trying to read from them
20:58bbloomAWizzArd: h/o my dopey core.async env isn't sane, can't test :-P
20:59AWizzArdamalloy: excellent, I think now we fully covered that code
20:59justin_smithwtf chrome tells me I am sending content type text/plain curl -D tells me it is application/rss+xml ...
20:59AWizzArdThanks bbloom and amalloy.
21:00amalloyjustin_smith: your server could be making a decision based on the request headers
21:00amalloydid you send the exact same request that chrome did?
21:00justin_smithOK how do I tell ring "no really this is rss not plain text"
21:00justin_smithamalloy: no, I did not
21:01AWizzArdbbloom: although working with go in Clojure should not run in parallel anyway, no?
21:01bbloomAWizzArd: go will use a threadpool on the jvm, you'll get actual parallelism
21:01AWizzArdah okay, good
21:01amalloyif you want to act exactly like chrome: open chrome's network tab, issue the request again, and right-click "copy as curl"
21:02justin_smithamalloy: OK - but my core priority is telling browsers the content is rss - any idea about how that would work?
21:03amalloybut anyway, justin_smith, you just set the content-type header. if you're setting it server-side and that's not appearing on the client end, then check whether you have some middleware that's clobbering it
21:04justin_smithamalloy: I spent a couple days doing that :) curl sees the right header, with chrome it is clobbered somehow, you are probably right about something in chrome's request overriding but I just find that baffling
21:05justin_smithamalloy: not only that but I scoured the repos of my web libs looking for errant code that may have gotten pulled in in the handler logic...
21:05justin_smith(which is why frameworks suck)
21:06amalloyi mean, i would guess it's the Accept header
21:07amalloythere are definitely middlewares that decide what to return based on the content types the client would prefer
21:08amalloyand chrome could well say it prefers text/plain to application/rss+xml
21:08amalloyit's easy enough to check that by looking at the headers chrome is sending, rather than diving through miles of frameworks
21:08justin_smithAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
21:08justin_smithyeah
21:08justin_smithamalloy: I guess I know that now, thanks
21:11justin_smithif I had my wits about me I would have tried a different user agent sooner, firefox happily shows the feed items and offers the option to subscribe as expected
21:12amalloyi was about to ask, does chrome even support rss?
21:12amalloyit doesn't have anything built-in afaik
21:13justin_smithI would have thought it would at least offered me the "what do you want to do with this, it is rss" prompt, but I guess that wasn't a realistic expectation
21:13amalloyhere's 4clojure's rss feed: http://www.4clojure.com/problems/rss - we don't even bother setting the content-type, so it defaults to text/html, and rss-aware user agents don't care
21:15dbaschchrome used to prompt you to subscribe using Google Reader
21:15dbaschwhich is no more, as you probably know
21:15justin_smithamalloy: I am pretty sure you don't care about validation, but in case you do http://validator.w3.org/feed/check.cgi?url=http%3A%2F%2Fwww.4clojure.com%2Fproblems%2Frss
21:16amalloyhaha
21:17amalloybroken since june of 2012, justin_smith. descrption indeed
21:17AWizzArdI must click on that link…
21:18amalloyRaynes: bro, two years ago you spelled "description" wrong: https://github.com/4clojure/4clojure/commit/5e6af1b83b4a236e11a09d591cab5870b4987e82#diff-b68cf9b369d8cc1aa59eef3daa7f491bR23
21:19RaynesWhoa, I worked on 4clojure two years ago?
21:19RaynesAm I really destined to feel old at 21? :|
21:19RaynesBecause I'm getting there.
21:20amalloyyour first 4clojure commits were over three years ago, old man: https://github.com/4clojure/4clojure/commits?author=Raynes
21:20Raynese
21:20RaynesWow, is that how little I've done for 4clojure?
21:20RaynesWhy do people give me credit for it :|
21:22justin_smithRaynes: get this cane, it is an umbrella and a sword too (I bought it at a thrift store by mistake, thinking I was just getting an umbrella) http://www.swordsforsale.us/SingleSwordsForSale.asp?ID=22975&amp;Cat=Sword%20Canes
21:22Raynes"but shit, it was 99 cents!"
21:22RaynesSorry man, I can't get through a 'thrift store' mention without a macklemore reference.
21:22RaynesIt's like a disease.
21:22dbaschRaynes: I wrote my first game in 1983. It was a Pacman clone. In Basic.
21:22justin_smithindeed, they didn't know what they had
21:23Raynesdbasch: I didn't say my feeling old was justified :P
21:23dbaschRaynes: good. I don’t feel old :P
21:24Raynesdbasch: Apparently I wrote my first game in 2009 and it wasn't really much of a game as much as it was a collection of gtk buttons and text fields.
21:25dbaschRaynes: my Pacman wasn’t much fun either. I couldn’t make the ghosts go around the maze so they went through walls.
21:25dbaschRaynes: I thought “whatever, they are ghosts"
21:25justin_smithdbasch: more realistic, reflecting the supernatural abilities of actual ghosts
21:25justin_smithit's not a bug, it's verisimilitude
21:26justin_smithon reflection, what you said
21:26dbaschjustin_smith: they just made a bee line for Pacman, only slowly enough that you could escape
21:26justin_smithnice
21:27dbaschthe *last* game I wrote was probably 10 years ago
21:27dbaschunless you count this as a game: https://gist.github.com/dbasch/6923514
21:27justin_smithI should make an extensible clojure based nethack
21:28TEttingerjustin_smith: haha already beat you to it, kinda
21:28justin_smithreally? do tell
21:29TEttinger(in that it uses tiles from a graphical nethack)
21:29TEttingerhttps://github.com/tommyettinger/Ravager completely undocumented! has some neat features like ambush point detection!
21:30justin_smithnice
21:30amalloy$google caves of clojure
21:30lazybot[The Caves of Clojure: Part 1 / Steve Losh] http://stevelosh.com/blog/2012/07/caves-of-clojure-01/
21:30TEttingercurrent version looks like https://dl.dropboxusercontent.com/u/11914692/Ravager-thin-walls.PNG -- I stopped because I couldn't figure out how I should do a GUI
21:31amalloythat was a really nice series of blog posts about writing nethack in clojure, by...i think he's sjl here in #clojure
21:31justin_smithvery cool
21:32justin_smithI wonder what the state of the art is for algorithmically generating sokoban puzzles
22:00TEttingersjl: I might try to follow through Caves of Clojure using SquidLib for output instead of Lanterna. should be interesting.
23:11livingstonI had some code that was reading the class path and looking up resources on it that matched a pattern -- now my classpath seems empty. One thing I've changed was adding a nrepl dependency (was using swank before) will that much with the loader/classpath?
23:11livingstonmuch with -> muck with
23:14livingstongah I just realized I had a cider dependency in there too - cutting that out now.
23:17livingstonnope that's gone and changed nothing. I do have nrepl still.
23:23justin_smithhow are you starting clojure, and how are you looking at the classpath?
23:24livingstonI'm starting it with maven clojure:nrepl
23:24livingstonI was using this (clojure.java.classpath/classpath)
23:25livingstonall I see now is this (#<File /var/folders/bk/w587c61d02s2hkn5zqs4zlnm0000gs/T/clojuremavenplugin2851089989068089718jar>)
23:25livingstonwhich I guess points some fingers at clojure maven plugin
23:29livingstonthat plug in is set up like this (I think I moved up to the most recent one, otherwise haven't changed) https://gist.github.com/drlivingston/cdf20840b4c26910182c#file-clojure-maven-pom-part-pom
23:34livingstonargh! I reverted to clojure maven plugin 1.3.9 and now low and behold there are all my class path contents.
23:36livingstonI guess I'll file an issue for this.
23:41justin_smithlivingston: leiningen tends to work very nicely, in my experience
23:41justin_smithdo you have a specific reason to use maven instead?
23:42livingstonI have to integrate with a lot of existing java.
23:43livingstonmaven has a lot of really useful tools that are being replicated in lein, maybe most of them are there now since last time I messed around with it. but I don't quite understand the xml fear
23:43beamsoi'm unsure if it's xml fear or people's memories of maven
23:44justin_smithyou can still use maven tools in a lein project, after using lein pom to make a pom.xml
23:45justin_smithbut if maven works that's cool, just making sure you know most of us use lein and it pretty much just works
23:45livingstonyeah that just seems like an extra step. also yet another thing to rock the boat with the in-house java people
23:45justin_smiththat's a good point, yeah
23:45justin_smithanother alternative is using lein jar to compile the clojure into an artifact, and continuing to use maven on the java side
23:46justin_smithif you can strictly segregate the two at least
23:46livingstonsome things aren't that clean