#clojure log - Mar 18 2015

The Joy of Clojure
Main Clojure site
Google Group
List of all logged dates

1:45 Seylerius: Working through Project Euler problems, and I'm trying to cap fibonacci values at a specified max. What am I doing wrong here? It's whining about not knowing how to create an ISeq from a long. http://sprunge.us/fBCK

1:47 nuwanda__: Seylerius: you can't (cons long long) doesn't work

1:47 ,(cons 1 2)

1:47 clojurebot: #error{:cause "Don't know how to create ISeq from: java.lang.Long", :via [{:type java.lang.IllegalArgumentException, :message "Don't know how to create ISeq from: java.lang.Long", :at [clojure.lang.RT seqFrom "RT.java" 506]}], :trace [[clojure.lang.RT seqFrom "RT.java" 506] [clojure.lang.RT seq "RT.java" 487] [clojure.lang.RT cons "RT.java" 620] [clojure.core$cons__4053 invoke "core.clj" 29] [sand...

1:48 Seylerius: Ah.

1:55 TEttinger: ,(def fibs (map second (iterate (fn [[a b]] [b (+ a b)]) [0 1])) )

1:55 clojurebot: #'sandbox/fibs

1:55 TEttinger: ,(take 5 (drop 5 fibs))

1:55 clojurebot: (8 13 21 34 55)

1:56 TEttinger: ,(take 5 fibs)

1:56 clojurebot: (1 1 2 3 5)

1:57 koddsson: Is there a function in clojure that will return a function with the original functions argument list reversed?

2:03 ie. (= ((reverse-args (/)) (/ 1 2)) 2)

2:05 amalloy: koddsson: note that you don't mean (/), but just /

2:05 i faguely suspect that you're a haskeller who thinks (/) is an operator section, but it's not

2:05 *vaguely

2:06 koddsson: Yeah no I just made a mistake

2:06 have never done any haskell ;)

2:06 amalloy: koddsson: there's nothing built in, but of course you can write it easily

2:06 (defn flip [f] (fn [& args] (apply f (reverse args))))

2:08 koddsson: Sweet

2:08 Thanks amalloy

2:09 Would this be something I'd use when I want to switch the arguments for a `/` in a `->>` chain or is there a better way?

2:09 (Hope I'm making myself understandable ;)

2:18 amalloy: koddsson: no, probably not. it's kinda unusual to have a ->> chain where you want something to go in at the front; usually it's better to have a -> chain, possibly with a -> inside it

2:19 eg, instead of (->> x (map whatever) ((flip blah) y)), you cna write (-> x (->> (map whatever)) (blah y))

2:19 koddsson: Ah ok

2:19 I'll try something like that

2:19 Thanks for the help amalloy

2:41 bcm: before i write my own... there must be a map-keys function that will work with a deep map

2:41 before i write my own... there must be a map-vals* function that will work with a deep map

2:42 so that (f {:a "a" {:b "b"}} str/capitalize) ;=> {:a "A" {:b "B"}}

2:42 is there a good place to look for stuff like that?

2:43 Kneiva: bcm: walk perhaps?

2:43 bcm: I found one in here: https://github.com/jaycfields/jry

2:43 I suppose I'll use it.

2:43 (update-vals {:b {:c :d :e :f} :h {:c :d :e :f}} dissoc :c) => {:b {:e :f} :h {:e :f}}

2:44 justin_smith: (clojure.walk/postwalk (fn [x] (if (string? x) (.toUppercase x) x)) {:a "A" {:b "B"}})

2:44 ,(clojure.walk/postwalk (fn [x] (if (string? x) (.toUppercase x) x)) {:a "A" {:b "B"}})

2:44 clojurebot: #<RuntimeException java.lang.RuntimeException: Map literal must contain an even number of forms>

2:44 justin_smith: ergh

2:44 ,(clojure.walk/postwalk (fn [x] (if (string? x) (.toUppercase x) x)) {:a "A" :bs {:b "B"}})

2:44 clojurebot: #error{:cause "clojure.walk", :via [{:type java.lang.ClassNotFoundException, :message "clojure.walk", :at [java.net.URLClassLoader$1 run "URLClassLoader.java" 366]}], :trace [[java.net.URLClassLoader$1 run "URLClassLoader.java" 366] [java.net.URLClassLoader$1 run "URLClassLoader.java" 355] [java.security.AccessController doPrivileged "AccessController.java" -2] [java.net.URLClassLoader findClass "...

2:45 justin_smith: ,(require 'clojure.walk)

2:45 clojurebot: nil

2:45 justin_smith: ,(clojure.walk/postwalk (fn [x] (if (string? x) (.toUppercase x) x)) {:a "A" :bs {:b "B"}})

2:45 clojurebot: #error{:cause "No matching field found: toUppercase for class java.lang.String", :via [{:type java.lang.IllegalArgumentException, :message "No matching field found: toUppercase for class java.lang.String", :at [clojure.lang.Reflector getInstanceField "Reflector.java" 271]}], :trace [[clojure.lang.Reflector getInstanceField "Reflector.java" 271] [clojure.lang.Reflector invokeNoArgInstanceMember "Re...

2:45 Empperi: lol, .toUpperCase :)

2:45 bcm: perhaps... walk it is

2:45 justin_smith: ,(clojure.walk/postwalk (fn [x] (if (string? x) (.toUpperCase x) x)) {:a "A" :bs {:b "B"}})

2:45 clojurebot: {:a "A", :bs {:b "B"}}

2:45 justin_smith: FINALLY

2:45 Kneiva: yay \o/

2:45 bcm: thanks justin_smith

2:45 Empperi: although your input data already has uppercase characters lol

2:45 justin_smith: ,(clojure.walk/postwalk (fn [x] (if (string? x) (.toUpperCase x) x)) {:a "a" :bs {:b "bellow"}})

2:46 clojurebot: {:a "A", :bs {:b "BELLOW"}}

2:46 Empperi: well now they are lowercase :)

2:46 well done!

2:46 justin_smith: Empperi: it's St. Patric's day in the US, and I just got back from a show :)

2:46 bcm: going to lift your code via erc

2:46 Empperi: hehe

2:46 bcm: welcome back justin_smith

2:46 Empperi: I'm at work just starting my working day

2:46 bcm: thats 2x you've helped me.

2:46 TEttinger: (inc justin_smith)

2:46 lazybot: ⇒ 214

2:46 justin_smith: bcm: np, glad I could be of assistence

2:46 bcm: it's 5:46pm here Empperi

2:47 justin_smith: just about 0:00 here

2:47 bcm: justin_smith: are you a prof?

2:48 justin_smith: bcm: heh, no

2:48 bcm: Math software sounds extremely fun

2:49 maxima-lly fun ._.;

2:49 justin_smith: haha

2:50 bcm: alright back to work, I'm lifting a competitor's FAQs page. is that sketchy? we're going to re-write it a bit

2:51 justin_smith: so I saw this guy tonight, the first time we really hung out was the first time he ever tried acid, and while I was tripping I decided it would be fun to make him try to use vi

2:51 (he had never seen such a thing)

2:51 bcm: what the fuck hahahaha

2:51 Empperi: lol? acid tripping vi first time usage

2:51 justin_smith: I was like "write some poetry"

2:51 Empperi: this is starting to sound epic

2:51 Seylerius: What does cond do if there are two conditions in a row?

2:51 justin_smith: Seylerius: what makes something a condition?

2:52 Empperi: Seylerius: cond is like if - else if - else if - else -structure

2:52 bcm: Seylerius: cond takes implicit pairs of condition -> action

2:52 justin_smith: Seylerius: as far as cond is concerned, conditions are alternating forms

2:52 Seylerius: Oh, now I get it.

2:52 justin_smith: ,(cond nil (= 1 2) 1 (even? 0))

2:52 clojurebot: true

2:52 * Seylerius is making sense of the clojure implementation of primality test on wikipedia

2:52 justin_smith: aha

2:53 Seylerius: I don't mind cribbing from another source, but I don't let myself submit it until I grok it.

2:53 I do have rules, y'know?

2:53 bcm: cool, thanks Seylerius

2:53 Seylerius: Thank y'all.

2:54 justin_smith: Seylerius: clojure is really great for having so many pure functions - you can usually figure out what things do by trying subforms in the repl

2:54 Seylerius: True dat.

2:54 justin_smith: (impure functions of course make this harder)

2:54 TEttinger: I'm doing some crazy polyglot stuff today. I spent about 6 hours writing reversible atomic updates to all state in a game, in C#, then fell asleep, and since then have written a clojure glPolygonStipple pattern generator and a C skeleton for someone trying to execute a function on timesteps when a timer gets to certain values

2:54 bcm: I listened to a podcast about a guy who's hobby is to change mis-used uses of 'comprised of' on wikipedia. he's changed 45k of them, and there are < 100 left. every sunday night he goes in and fixes all 100.

2:56 TEttinger: bcm, that's uh... quixotic

2:56 justin_smith: haha

2:56 bcm: yeah, he said lots of people called his hobby a flat out waste of time

2:56 but then he had a good point -> hobbies are usually a waste of time

2:57 like watching sports or something

2:58 sounds productive TEttinger

2:59 justin_smith: how did your first-time vi buddy fare with the poetry?

3:00 justin_smith: he found the experience hilarious

3:00 I should ask him how much he remembers of that

3:03 bcm: is there a way for lein to add a dependancy to the repl while its running

3:04 TEttinger: kinda, you can use (what is it again? aether or pomegranate)

3:04 justin_smith: bcm: lein cant't, but you can

3:04 bcm: say its [cheshire "5.4.0"]

3:04 where can i learn more?

3:04 justin_smith: I find pallet/alembic nice because it can load project.clj and use lein syntax

3:05 TEttinger: $google pallet/alembic

3:05 lazybot: [pallet/alembic · GitHub] https://github.com/pallet/alembic

3:05 justin_smith: bcm: add pallet/alembic to your ~/.lein/profiles.clj :user dependencies

3:05 bcm: suhh-weet.

3:05 TEttinger: oooh that is nice

3:05 justin_smith: (require '[alembic.still :as still]) (still/distill '[cheshire "5.4.0"])

3:05 TEttinger: (inc alembic)

3:05 lazybot: ⇒ 2

3:05 justin_smith: that's literall all you need once alembic is loaded

3:06 bcm: :D!

3:06 justin_smith: or you can edit your project.clj then run (alembic/load-project)

3:06 bcm: Ive been a clojure dev for over a year!!

3:07 justin_smith: load-project can be run multiple times - it won't get a different version of a dep, or unload deps, but will find and load new ones

3:07 TEttinger: congrats bcm!

3:08 bcm: Thanks TEttinger.. but i meant it the way of: 'how have i never heard of this!!'

3:09 TEttinger: I hadn't either, but I'm not a full-time clojure guy

3:10 justin_smith: TEttinger: bcm: I try to bring it up whenever it is relevant here

3:10 (this channel is how I heard of it)

3:11 TEttinger: one of my projects has been fun lately, it has involved a C library that I hacked to output JSON files instead of images, then writing a C# library to load the JSON, then a Java lib to load the JSON, then changing a copy of the C lib to output Lua source, then a small Lua lib to load that Lua...

3:11 it's involved more IDEs than normal...

3:13 bcm: now it totally works :D

3:13 TEttinger: not just emacs?

3:14 I guess Java -x-> emacs

3:15 TEttinger: and C# =/= emaca

3:17 bcm: feeling lucky i dont have to leave home

3:44 nicola_: hello, how is everyone doing today?

3:46 justin_smith: nicola_: almost sobered up enough to go to bed

3:46 nicola_: hahaha where are you from?

3:46 justin_smith: west coast US

3:47 nicola_: ah, whats the time there?

3:47 justin_smith: ~00:48

3:47 clojurebot: Cool story bro.

3:47 nicola_: lol good luck!

3:49 its only 09:48 here

3:51 bcm: hi nicola_. 6:50 now

3:51 pm :)

3:52 nicola_: and where is that?

3:58 so, are you guys working on anything interesting?

4:00 daniel`: nicola_: you must be in eastern europe

4:02 nicola_: im in south africa

4:02 Cape Town :)

4:06 daniel`: ah :)

4:06 nicola_: daniel`: where you from?

4:07 daniel`: uk but i live in romania

4:07 nicola_: ah cool

4:07 how long you been programming?

4:07 daniel`: as a job, about 4 years

4:08 nicola_: nice, where you working?

4:08 daniel`: as a hobby for longer

4:08 nicola_: ive only been at it about a year

4:09 daniel`: at a small online advertising startup, i don't use clojure in my job unfortunately

4:09 mostly python

4:10 nicola_: ah well its hard to find a job as a clojure programmer

4:10 daniel`: im trying to bring some clojurescript to the frontend

4:10 its harder, probably not that hard if its the most important thing for you

4:11 nicola_: people tend to be a bit afraid of functional languages

4:12 daniel`: its probably harder to hire, but you probably attract better people on average

4:13 nicola_: thats true. Well im not super familiar with industry standards, im still in uni

4:14 daniel`: good to see that clojure is gaining interest in cape town, i was there with work a little over a year ago

4:15 nicola_: yeah, weve got a small community going here

4:15 its pretty cool

4:15 dysfun: i think ptaoussanis is from cape town as well. i use several of his modules

4:16 nicola_: i actually dont know

4:16 would be cool if he is

4:17 dysfun: ah no, i think it's Jo'burg, but it cuts off

4:17 but he's currently in thailand anyway

4:17 nicola_: ah i see

4:18 well i have to go. :)

4:18 daniel`: cya

4:27 Seylerius: What's the appropriate way to iterate down a seq, then stop and return a value when a function returns true?

4:29 TEttinger: probably reduce and reduced with the value

4:30 ,(let [coll [nil false 0 "" :hooray]] (reduce #(when (= %2 :hooray) (reduced %2)) [] coll))

4:30 clojurebot: :hooray

4:31 TEttinger: ,(let [coll [nil false 0 ""]] (reduce #(when (= %2 :hooray) (reduced %2)) [] coll)) ; if it doesn't have it

4:31 clojurebot: nil

4:31 TEttinger: ,(let [coll [nil false 0 ""]] (reduce #(when (= %2 :hooray) (reduced %2)) nil coll)) ; slight fix

4:31 clojurebot: nil

4:35 borkdude: in liberator, when I want only the content-type text/html for a put! request, but image/jpeg or image/png for get requests, what is the best way to accomplish this?

4:35 ordnungswidrig: borkdude: as the response content-type?

4:35 borkdude: I had a nasty problem with IE9 having its in its accept header image/jpeg as the first thing

4:35 ordnungswidrig yes

4:36 I'm posting to an iframe using iframeio

4:36 but in IE9 I got a popup because it returned the response as image/jpeg

4:37 ordnungswidrig: borkdude: you can use a fn for :available-media-types and depending on value in (get-in ctx [:request :request-method]) return different lists

4:37 borkdude: ah, thanks you!

4:38 ordnungswidrig I didn't realize it could also be a function, but I read it now in the docs :)

4:38 ordnungswidrig: borkdude: liberator.util/by-method is a helper which dispatches on the request-method, e.g. :available-media-types (by-method :get ["image/jpeg" "image/png"] :put ["text/html"])

4:38 borkdude: not tested, though

4:39 borkdude: k

5:03 daniel`: if a third party library uses extend-type, how can i also have the type extended the same in my code?

5:04 rather than reimplement the protocol

5:14 bcm: is there a place where one can watch livestreams of programming?

5:25 ordnungswidrig: bcm: that sounds like a very nice idea. maybe even with live question to the programmer?

5:26 * ordnungswidrig is sure, there's already an eamcs package for that :-P

5:27 bcm: it'd be nice. I'd like to watch

5:28 I did some fun stuff this afternoon that i think maybe someone somewhere would like to watch

5:29 I like watching SC2 because the players are so skilled. I'm not that skilled but i'd sure like to watch someone who is extremely skilled at e.g. emacs do their thing

5:29 even though questions would probably knock them off their train of thought

5:29 wagjo: bcm: there's http://www.twitch.tv/directory/game/Game%20Development

5:29 bcm: aaand http://coderstv.com/

5:30 bcm: I've seen the twitch streams, I'll have to checkout coderstv

5:30 Empperi: oh god, I'm just about to go insane

5:31 lein deploy, how hard it can be?

5:31 pretty darn hard it seems

5:34 daniel`: if a 3rd party lib uses extend-type to implement a protocol, can i use that same implementation in my code rather than reimplement it?

5:35 bcm: what's the O runtime of this function?


5:35 (def a (atom 0))

5:35 (dotimes n (swap! a #(+)))

5:36 nooo :(

5:36 corrected: (dotimes n (swap! a #(+ 1 %)))

5:41 ,(def a (atom 0))

5:41 clojurebot: #'sandbox/a

5:46 zot: dumb question: is there a way to conditionally define a macro/function, ie (defmacro update …), but only for clojure <1.7?

5:48 daniel`: ,(clojure-version)

5:48 clojurebot: "1.7.0-master-SNAPSHOT"

5:49 ro_st1: zot: here prismatic/plumbing only defines `update` if cljs doesn't already define it

5:49 https://github.com/Prismatic/plumbing/blob/ea5bfe00ac4eed1174cc2865ef640b8fb759b4b7/src/plumbing/core.cljx#L41-L50

5:50 zot: ro_st1: perfect, that's exactly what i want to do atm :) thanks!

7:38 clgv: clojure.tools.logging question: I want to log a stacktrace and then exit the program. currently using (binding [log/*force* :direct] (log/errorf ...) (System/exit 1)) does not result in a log entry. Is there some method to flush the logger before calling System/exit?

7:47 egli: bcm: there is http://www.zombieclj.no/ which is highly entertaining

7:47 agarman: clgv: why not use log/fatal ?

7:47 egli: they speak norwegian but you can sort of follow along looking at the source code

7:48 clgv: agarman: huh? a change of loglevel for the message should have which effect?

7:51 hyPiRion: egli: Do you think there is demand enough for subtitles?

8:24 m1dnight_: Guys, for an irc bot I have a thread that runs an infinite loop to read from a socket

8:24 what is a better abstraction to use than a Thread?

8:24 (for easy abort etc)

8:36 pandeiro: anyone know of any gotchas using ring-mock's request w/ wrap-edn-params? when i request over http, the edn params are parsed and end up in :params; when i send the mock request to the app handler (with edn-params), params don't get parsed at all

8:44 answering myself - :content-type "application/edn" needs to be assoc'd on to the mock request directly (i was doing it @ :headers {"Content-Type" "application/edn"})

8:44 egli: hyPiRion: I don't think there is enough demand for subtitles.

8:44 but I don't they are really needed. All they do is write code and comment it. As the code is all written in English it's really easy to follow along

8:45 hyPiRion: egli: ah, alright

8:47 zot: anybody have cljx 0.6 working nicely w/ cider/repl? the readme says that it should "just work", but afaict, 2.5.1 prevents it: https://github.com/lynaghk/cljx/issues/66

8:52 slipset: m1dnight_: a go-loop?

8:52 with a kill-channel and alts?

8:53 zot: (fwiw, it does work w/ 2.5.0 — wanted to see if there was a usable manual sol'n w/ 2.5.1)

8:54 m1dnight_: slipset: valid point, the example shows that it might be what I need

8:54 docs are a little scarse though

8:54 oh nvm, i should read docs for go

8:54 thanks slipset

8:54 (inc slipset)

8:54 lazybot: ⇒ 3

8:54 slipset: :)

9:24 nicferrier: I am having some trouble understanding how to use repeatedly.

9:25 if I do (repeatedly my-function-that-does-something) do I have to doall that to get it to actually do it?

9:25 I was hoping to use it instead of a while loop to loop forever.

9:25 dm3: nicferrier: then doall should work

9:25 but I'd choose while for clarity in this case

9:27 does anyone know how the clojure mailing list is administered? wrote a post couple hours ago which still didn't appear

9:28 gfredericks: nicferrier: I also agree that while is best, but it's worth pointing out that doall would be a memory leak when used like this, so dorun is better

9:28 nicferrier: gfredericks: nice.

9:28 I might actually put it in a core.async loop

9:30 clgv: nicferrier: please don't use `repeatedly` like that

9:30 nicferrier: are you going to arrest me?

9:31 clgv: nicferrier: no, just sending my mobster buddies to your house ;) :D

9:31 nicferrier: hilarious.

9:34 patrkris: hi folks. if I change the implementation of a protocol method implemented on a record, do I have to restart the running REPL for it to come into effect? shouldn't it be enough to eval the defrecord form?

9:35 nicferrier: clgv: it's not a good approach, at least for me. why don't you explain what you think the problem is?

9:35 patrkris: (I've implemented the protocol directly in defprotocol)

9:36 clgv: patrkris: no you will end up with a new class of the defrecord which is not compatible with the existing instances of the previous class

9:36 patrkris: clgv: ah... any way to work around that? will it help to use extend-protocol/extend-type?

9:37 clgv: patrkris: yeah, those are supposed to work

9:37 patrkris: clgv: great, I'll try that. thanks.

9:37 clgv: patrkris: all the other methods except the inline implementation within the defrecord

9:38 nicferrier: using some collection construction function to do side effects is a significant semantic clash

9:38 patrkris: clgv: do people generally prefer implementing protocols that way?

9:39 clgv: patrkris: that probably depends. afaik the inline implementation is more efficient since the usual lookup mechanism for java classes is used instead of the custom clojure protocol lookup

9:39 patrkris: clgv: thought so. thanks again

9:39 clgv: patrkris: but this only matters in a small number of scenarios

9:41 patrkris: clgv: it's the same situation with deftype then?

9:41 clgv: patrkris: yes

9:42 patrkris: defrecord is implemented on top of deftype

9:42 nicferrier: clgv: you may want to downvote this and explain - http://stackoverflow.com/a/17531455/130125

9:43 the reason I used repeatedly was that I could take just a few of it and see that it does it repeatedly.... or I could do all of it.

9:43 so the loop contents doesn't change. just some construct outside of it

9:43 if you use a while you have to have an extra condition which you then have to alter.

9:44 clgv: nicferrier: well, if you are actually interested in the results of invidividual runs that's fine. but your description read differently

9:44 Glenjamin: (doc repeatedly)

9:44 clojurebot: "([f] [n f]); Takes a function of no args, presumably with side effects, and returns an infinite (or length n if supplied) lazy sequence of calls to it"

9:44 Glenjamin: ^ side effects implied

9:45 schmir: patrkris, clgv: I can change the implementation of methods at runtime without problems

9:45 nicferrier: clgv: I'm not interested in anything but the side effect of the repeated function.

9:46 clgv: schmir: the problem of patrkris is that he used inline implementation and had to reevaluate the defrecords and hence define a new class by doing that

9:46 nicferrier: then it is not really appropriate.

9:46 schmir: and he expects the old instances to use the new methods?

9:46 clgv: nicferrier: consider it a hack for that use case

9:46 schmir: that's how I understood it

9:47 patrkris: clgv: understood correctly

9:47 schmir: ok. sorry for the noise

9:47 nicferrier: clgv: ok. I just don't really get it. I'll probably do it differently anyway with a loop recur... but I don't see what's wrong with repeatedly. it even notes it's "for" side effects.

9:48 clgv: schmir, patrkris: from a pure clojure perspective you could think that classes were just modified, but that is not the case

9:48 nicferrier: why construct a sequence when you do not need one.

9:48 +?

9:49 TEttinger: yeah, a typical use for me of repeatedly is ##(repeatedly 20 #(inc (rand-int 20)))

9:49 lazybot: ⇒ (20 20 15 9 2 18 20 6 18 17 6 4 5 6 18 8 8 9 16 12)

9:49 TEttinger: wow, lucky night

9:49 triple crit

9:49 nicferrier: clgv: it's a good point.

9:50 clgv: but one throws it away... and there are advantages as I noted. but ok. if that's your objection I do now at least understand it. :-)

10:36 gonk---: hey, all. im trying to get a good idea in my mind of when to use atoms instead of agents and vice versa. ive looked around a bit, but could not find any examples that clearly state "i used x here because y would have z implications." can anyone shed some light?

10:37 for example, agents happen in another thread by default compared to atoms. what difference would there be from something like (future (change-atom my-atom))

10:41 chouser: gonk---: there are a bunch of differences that may or may not be relevant in any given use case

10:42 timvisher: does anyone know if `cider-nrepl` used as a plugin should decorate `lein ring server-headless` when it has `{:nrepl {:start? true}}` set?

10:44 chouser: for example, in (future (swap! my-changer myatom)), my-changer may be run multiple times, whereas in (send my-changer my-atom), it will be run exactly once.

10:44 timvisher: it looks like it should based on https://github.com/weavejester/lein-ring/blob/master/src/leiningen/ring/server.clj#L46-L48

10:44 chouser: gonk---: This would matter for example if my-changer had side-effects.

10:45 timvisher: unless there's some load order issue

10:46 gonk---: chouser: aha! OK, that's a great example that solves a problem I was having yesterday using atoms then.

10:46 clgv: gonk---: http://clojure-doc.org/articles/language/concurrency_and_parallelism.html

10:48 maio: /truncate-buffer

10:49 gonk---: clgv: ive looked that over, but never realized that agents will occur exactly once, whereas atoms may retry.

10:50 timvisher: looks like it works with `lein repl :headless` though

10:51 chouser: gonk---: Another difference is integration with STM. If you call send from inside a dosync, it will be held until the dosync transaction commits, and then will send exactly once. If you call swap! from inside a dosync, the atom will be mutated each time the transaction retries (hence the ! vs no-!)

10:52 clgv: gonk---: oh you are right. they dont convey the basics of agents well

10:52 chouser: gonk---: If you're interested in advice on when to use or not use various Clojure features, and why, there's a book I could recommend. ;-)

10:53 gonk---: chouser: haha, i thought your name looked familiar!

10:53 clgv: gonk---: the O'Reilly book does a better job, if you happen to have that one lying around

10:55 that other book is a good read as well ;)

10:55 gonk---: clgv: i see most people call JoC a more advanced book, so im not sure if I'm ready, haha.

10:56 clgv: ok. perhaps its time to move off of the online snippets i pick up and move to something more 'established'

10:56 clgv: gonk---: yeah it probably helps to read "Programming Clojure" (2nd edition) or "Clojure Programming" first

10:58 gonk---: clgv: i know they both probably do roughly the same job, and i also know they both score the same under the all-important 'has a bird on the cover' metric, but are there any points that put one over the other?

10:58 clgv: gonk---: writing style, I think

10:58 timvisher: ah. looks like it was a versioning issue. i was on lein-ring 0.8.7

10:59 clgv: choose the one whose writing appeals more to you

11:01 gonk---: clgv: ok. im not sure how much experience you have with them, but i prefer 'good examples' and 'not dry' to most other metrics, so would you say one is better than the other in those regards?

11:02 clgv: by the way, thanks for your patience. :)

11:07 clgv: gonk---: I'd say "Clojure Programming" has a more narrative style while the other has a more technical style. Both have plenty of examples

11:10 gonk---: I think both have sample chapters you can read

11:13 gonk---: clgv: ok. already checking out some samples. thanks.

11:17 irctc: say something

11:19 gonk---: anything

11:22 clgv: ,(println "something")

11:22 clojurebot: something\n

12:08 justin_smith: ,'somethingcompletelydifferent

12:08 clojurebot: somethingcompletelydifferent

12:46 clgv: ,(print "/me greets justin_smith")

12:46 clojurebot: /me greets justin_smith

12:46 LunarLanding: worth a shot

12:49 ordnungswidrig: clgv: /me is implemented as a different IRC command, IMHO

12:50 justin_smith: yeah anything starting with / is a special command interpreted by your client, not the irc server

12:50 clgv: damn ;)

12:50 justin_smith: I forget which client, but ages ago I used one with vi like bindings, that even used : instead of /

12:51 maybe it was an option in tirc?

13:09 mistaBIZ: so with a dirct connection to a running lein repl i have WAARNING: CIDER requires nREPL 0.2.7 to work properly

13:12 timvisher: are ring auto-reload and nrepl known not to play well together?

13:13 i'm seeing a very strange issue where if i have them both set up and i'm doing live dev, eventually tests make there way into the execution path

13:14 justin_smith: mistaBIZ: what version of cider, and what version of cider-nrepl, are you using?

13:17 ane: what's the idiomatic way to test for "not {}"? (not (empty? m)) ?

13:17 justin_smith: ane: seq

13:17 ,(doc empty?)

13:17 clojurebot: "([coll]); Returns true if coll has no items - same as (not (seq coll)). Please use the idiom (seq x) rather than (not (empty? x))"

13:17 eli-se: hi

13:18 ane: oh. sweet.

13:18 justin_smith: ane: if you want it to be a condition and also the binding (eg. if-let) than (not-empty m) is good

13:18 ,(if-let [m (not-empty {:a 0})] (:a m))

13:18 clojurebot: 0

13:19 justin_smith: ,(if-let [m (not-empty {})] (:a m :default))

13:19 clojurebot: nil

13:19 ane: just for a unit test

13:20 (is (seq m)) worked great

13:20 * clgv can't resist the urge to change the above `if_let` to `when-let`

13:22 justin_smith: heh

13:46 dogonthehorizon: Greetings all! I'd like to write a macro that takes a name and a set of fields (with types) and outputs Java source implementing a simple Builder Pattern for me. I'm aware of tools like ANTLR for outputing Java source but it seems rather complex for what I'm after. Am I needlessly complicating things or is therer something simpler that I can do in Clojure?

13:47 amalloy: dogonthehorizon: you don't need a macro to output java source code. it should be (mostly, anyway) functions

13:49 dogonthehorizon: amalloy: Interesting, are you suggesting something like gen-class? I've experimented with gen-class and defrecord but unfortunately I lose type information when I attempt to use these classes from Java...

13:50 amalloy: huh? no, you're just trying to output strings, right? that's what java source code is

13:51 i mean personally i have to say there's probably a better way than outputting java source code, but if that's what you want to do all you need is a function that produces a string

13:53 dogonthehorizon: Ha! My bad; that makes sense. What better way would you suggest, then? I have a working implementation right now that uses gen-class but the lack of type information (e.g. List instead of List<Foo>) makes the Java code rather unwieldy

13:53 Lots of type casting, etc.

13:54 justin_smith: dogonthehorizon: wait, what's the relationship between gen-class and java source?

13:55 dogonthehorizon: justin_smith: I'm attempting to create Java friendly APIs for a small library I've written

13:55 amalloy: dogonthehorizon: when i am trying to produce code that is to be consumed by java programmers, i usually write an interface in java, an implementation of that interface in clojure, and some stub java code that loads the clojure implementation

13:55 justin_smith: ahh, and javac can't help you with the generics since it came from clojure

13:56 amalloy: i would counsel strongly against generating java code if your goal is just to provide a java-friendly API

13:56 justin_smith: (inc amalloy)

13:56 lazybot: ⇒ 237

13:56 justin_smith: yeah, that's the sane way

13:56 write the interface in java, implement in clojure, have the java programmers code to the interface

13:56 dogonthehorizon: amalloy: Similar to how clojure.core does this with IPersistentVector vs PersistentVector?

13:57 amalloy: see, for example, https://github.com/amalloy/thrift-gen, which is a library implemented in clojure, with a few dozen lines of java wrapped around it so that it's easier for java users

13:57 dogonthehorizon: no, those are java classes with java interfaces and implementations in java

13:57 you don't want to do that

13:57 oh

13:57 yes, do that. i misread

13:58 i, in fact, wrote a little tiny builder for the java side of that library

13:58 it's tedious, but it's not long, and it's way easier than generating source code

14:00 dogonthehorizon: amalloy: thrift-gen is exactly the example I was looking for :) Thank you and justin_smith as well for steering me in the right direction!

14:00 amalloy: actually i guess i didn't use any interfaces for this one. interesting

14:13 McCoyPauley: hello

14:13 Balveda: <Balveda> How could I access the data in a cljson decoded object? I get this in result: #js {:serverUsed, :ok 1, :n 0}

14:13 <Balveda> But I can't seem to be able to touch it through vec, map, list, etc

14:16 (aget map "ok") did it

14:21 justin_smith: (inc Balveda)

14:21 lazybot: ⇒ 2

14:21 justin_smith: for sharing the answer

14:22 Balveda: thanks

14:24 Reminds me of that age old situation

14:25 decade old forum threads, asking for an answer, the last message is just a "fixed!" or "sent by pm" and the thread is closed

14:40 benjyz1: hi. I'm looking for some point for running a clojure-ring webapp in production

14:40 *pointers

14:48 justin_smith: benjyz1: do you plan on using a container?

14:49 benjyz1: no. one machine with not much load for the time being

14:49 justin_smith: if not, you can use aleph or http-kit and just make a runnable uberjar

14:49 benjyz1: I'm currently just using ring

14:49 justin_smith: well, whether you use a container and how many machines you use are orthogonal

14:49 benjyz1: thx. why not just Jetty?

14:49 justin_smith: benjyz1: ring is an adaptor over various web servers, I assume you are using the embedded jetty adaptor?

14:50 benjyz1: exaclty, yes

14:50 I want to keep it simple. I need to add an SSL cert

14:50 but don't want to get into NGINX right now

14:51 justin_smith: benjyz1: I'd use an nginx reverse proxy, most of the java http servers are not really hardened

14:51 benjyz1: just the most simple setup and go from there. I'm wondering about securities aspects

14:51 I see. Jetty is not?

14:51 justin_smith: security wise the simplest thing is nginx

14:51 not the way nginx is, no

14:52 benjyz1: I see. wondering for what kind of attacks..

14:54 amalloy: i think benjyz1 is getting the wrong idea: justin_smith isn't saying to not use the embedded jetty adapter

14:55 benjyz1: I guess if fewer people use something, it's less well tested

14:55 amalloy: ie, you run the ring-jetty-adapter inside your clojure app, but he's suggesting you don't use the jetty *container*

14:55 i'd echo the suggestion to use nginx for your ssl proxy, though. it's well-tested and easy to set up

14:56 benjyz1: sounds good. I'll rethink my choice there. thanks

14:56 any idea whom could I contact for detailed knowledge about ring in production?

14:57 I'm wondering whether bigger shops are using it. it's not always obvious

14:57 amalloy: benjyz1: more or less everyone who uses clojure webservers uses ring

14:58 benjyz1: ok, cool. I saw for example prismatic posted a lot of info about what they are doing

15:01 justin_smith: benjyz1: nginx has options like not responding to server scans (requests meant to hit multiple hosts, fishing for results while finding an open exploit), limiting obscure request methods, block referral spam, block hotlinking, etc.

15:01 iulhysuigharw: did usa covertly supply isis with weapons like they did with al-qaeda to justify creating wars?

15:01 did usa excute the creative mess in the middle east like they said they will, does the creative mess include explosions with uncertain responsibles to create wars?

15:01 plz, send my qs to help limiting usa&israel aggression against others.

15:01 .

15:01 did usa covertly supply isis with weapons like they did with al-qaeda to justify creating wars?

15:01 did usa excute the creative mess in the middle east like they said they will, does the creative mess include explosion with uncertain responsibles to create wars?

15:01 plz, send my qs to help limiting usa&israel aggression against others.

15:01 .did usa covertly supply isis with weapons like they did with al-qaeda to justify creating wars?

15:01 did usa excute the creative mess in the middle east like they said they will, does the creative mess include explosion with uncertain responsibles to create wars?

15:01 plz, send my qs to help limiting usa&israel aggression against others.

15:01 .

15:01 did usa covertly supply isis with weapons like they did with al-qaeda to justify creating wars?

15:01 did usa excute the creative mess in the middle east like they said they will, does the creative mess include explosion with uncertain responsibles to create wars?

15:01 plz, send my qs to help limiting usa&israel aggression against others.

15:03 ibash: wut

15:03 benjyz1: just_smith: you mentioned alpeph. I've come across it and it looks interesting.

15:03 that's more alpha though?

15:03 no pun indented

15:03 justin_smith: it's a good server

15:05 benjyz1: cool. I'm using buddy for crypto. it's a new library

15:05 dopamean_: is there a term for a function that does completely different things based on the type of the argument?

15:06 amalloy: confusing

15:06 benjyz1: you might be looking for http://clojure.org/multimethods

15:07 dopamean_: amalloy: very

15:07 this is a question from someone else. i immediately thought of multimethods but he said that there was a more general term for it

15:07 amalloy: he means polymorphic

15:08 AimHere: Multimethods doesn't just dispatch on type, it dispatches on damn near anything you want

15:08 dopamean_: i tried that as well. he said thats not it

15:08 said it was a weird sounding word and thats why he cant remember it. oh well

15:08 apparently jquery's jQuery() function is an example of it

15:19 justin_smith: dopamean_: parametric polymorphism?

15:20 dopamean_: so i guess i asked the question incorrectly. its not the type that determines the behaviour of the function but the actual value of the argument

15:21 so in the case of jquery it could be a selector or it could be html

15:25 amalloy: dopamean_: a functino which returns a different thing based on the value of its argument is just called a function

15:29 justin_smith: (inc functino)

15:29 lazybot: ⇒ 1

15:29 justin_smith: I do that all the time, hah

15:31 amalloy: justin_smith: i transpose letters a lot more than i used to. not sure if it's the keyboard, or if my fingers are getting old

15:32 justin_smith: it's probably contagion from my own terrible typing skills

15:34 benjyz1: thanks justin_smith & amalloy for your input

15:35 amalloy: maybe i should learn to use C-t. at some point i rebound that to transpose-sexp, because i knew that i'd never remember to use it for single character accidents vs just deleting and retyping

15:36 nullptr: amalloy: global abbrevs fix most of these automatically for me... (e.g. "teh" -> "the")

15:36 anti-freeze: Hey everyone. So I'm trying to test my compojure app, and I can't seem to get around the CSRF token when making mock requests, causing any post request to return a 403. Any ideas?

15:37 kungi: anti-freeze: Yes wait a second :-)

15:37 justin_smith: anti-freeze: seems like the two clear options are including the token properly, or turning off the anti-forgery middleware in the test

15:38 anti-freeze: for example, for many endpoint tests, it should suffice to call the unwrapped endpoint directly, unless the functionality you are testing somehow relies on middleware

15:38 anti-freeze: justin_smith: I was considering either setting up a test env with test middleware disabling the anti-forgery middleware, or sending the token in the post data. I don't know how to do either however

15:38 justin_smith: anti-freeze: you don't need a test env, you don't even need the ring server to be running to test an endpoint

15:38 kungi: anti-freeze: I include (csrf-util/anti-forgery-field) in every test

15:38 justin_smith: give the endpoint the request map, test the output map

15:39 no need for the server to be running

15:39 anti-freeze: justin_smith: So I don't use mock/request?

15:39 justin_smith: anti-freeze: I never use mock/request

15:39 kungi: justin_smith: really? never? I think it's quite handy.

15:39 anti-freeze: justin_smith: If I wanted to send the token with mock/request, how would I do that?

15:40 justin_smith: kungi: a request is just a map

15:40 I don't need mocking for that

15:40 anti-freeze: I have no idea, I never use it

15:40 kungi: justin_smith: I am aware of that. but mock/request makes map creation a bit nicer

15:41 amalloy: (inc justin_smith)

15:41 lazybot: ⇒ 215

15:41 anti-freeze: kungi: So, if i was to do something like: (mock/request :post "/login" {:email "a@a.com" :pass "pass"}) where would I include the CSRF?

15:42 kungi: anti-freeze: in the params map

15:42 anti-freeze: have a look into ring.util.anti-forgery

15:42 anti-freeze: kungi: just a plain {... (csrf-util/anti-forgery-field) ?

15:43 kungi: anti-freeze: no.

15:43 anti-freeze: the name of the parameter is __anti-forgery-token

15:43 anti-freeze: kungi: No utility functions for that to make it a little nicer?

15:44 kungi: so it's like {:email ... :pass ... :__anti-forgery-token ring.middleware.anti-forgery/*anti-forgery-token*}

15:45 anti-freeze: Not in this case. But why not write your own utility function.

15:45 anti-freeze: kungi: That's what I was planning to do.

15:46 kungi: I still get 403's

15:47 kungi: anti-freeze: is the code online somewhere?

15:48 anti-freeze: kungi: https://ideone.com/31xqsK

15:51 kungi: anti-freeze: I think I know why this does not work. The middleware expects the token either in a header called x-csrf-token or in a form paremeter called __anti-forgery-token

15:52 anti-freeze: you can use ring.mock.request/header to set it.

15:53 anti-freeze: kungi: Ah, alright. I'll give it a go. Should I leave the __anti-forgery-token in the request map?

15:53 kungi: anti-freeze: no you won't need it there

15:53 anti-freeze: kungi: Alright, thanks a bunch. I'll give it a go and report back

16:00 justin_smith: kungi: anti-freeze: to be more explicit about my not using mock-request, I will spit the pprinted request I want to test to a file, remove irrelevant data, and then use that as my test data (either inserting it as a literal in the test file, or loading it as a resource .edn file)

17:25 raspasov: hi all, any recommendations for a Clojure or Java library for running shell commands on remote machines?

17:30 justin_smith: raspasov: I wouldn't use a library for that, I would use clojure.java.shell/sh - (shell/sh "ssh" "-i" "my.pem" "user@host" "-c" "command to run")

17:31 raspasov: justin_smith: nice, thanks! I'll check that out

17:31 amalloy: justin_smith: minus the -c

17:31 raspasov: I'm looking for the simplest possible thing :)

17:31 justin_smith: amalloy: ahh, I got the args wrong, OK

17:32 raspasov: anyway, I would definitely use a pem file, because that avoids checking remote credentials into your codebase

17:32 raspasov: justin_smith: yea, definitely, makes sense

17:35 Lewix: anyone used robovm before?

17:35 amalloy: ~anyone

17:35 clojurebot: anyone is anybody

17:35 amalloy: i hate this feature

17:36 Lewix: amalloy: feature?

17:37 amalloy: the feature where clojurebot remembers that anyone is anybody and can't be friggin untaught it, so you can't get at the actually-useful factoid also stored under anyone

17:41 justin_smith: ~anybody

17:41 clojurebot: Just a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..."

18:02 dan_b: I know all the arguments that thinking hard about the code is a more effective debugging technique than an interactive debugger

18:03 but I still somwtimes wish I could just stirck a breakpoint in a ring hander and find out what all the values in the request map actually are

18:04 justin_smith: dan_b: here's a favorite trick of mine: (defonce debug (atom [])) then inside some choice bit of code (swap! debug conj m)

18:05 useful variations include addint timestamps, or keyed values with a hashmap instead of a vector

18:05 *adding

18:05 dan_b: also, cursive probably has the best debugging integration right now

18:05 {blake}: dan_b: You mean in the macro? Because, yeah, as justin_smith sez, you can debug in Cursive.

18:05 dan_b: yeah, maybe at some opoint I should look at Things That Are Not Emacs

18:06 justin_smith: dan_b: hell, even SLIME/Swank had better debug support than cider does

18:06 dnolen: dan_b: you can do this so easily in Cursive, it's worth having on your machine even if all you use it for is debugging IMO

18:07 dan_b: I remember slime from CL days. I may even still be listed as a contributor

18:09 riddn.core=> (slurp (BytesInputStream. (.getBytes "hello") 5))

18:09 "hello"

18:09 hmm, that wasn't what I expected to happen

18:09 justin_smith: dan_b: what did you expect that to do?

18:10 dan_b: I expected it to be a byte array

18:10 amalloy: justin_smith: what's better about slime's debugger than cider's?

18:10 dan_b: slurp is for strings

18:10 justin_smith: amalloy: at least there's debug-repl - or is there something like that for cider now?

18:10 amalloy: is there something like that for swank? i don't know about it

18:11 dan_b: yep, you're right, it does say "returns a string"

18:11 I won't probe too hard into what character set/encoding it uses when given a byte strwam then

18:15 justin_smith: ,(slurp (.getBytes "hello☃") :encoding "US-ASCII")

18:15 clojurebot: "hello���"

18:15 justin_smith: ,(slurp (.getBytes "hello☃") :encoding "UTF-8")

18:15 clojurebot: "hello☃"

18:15 justin_smith: dan_b: ^

18:15 UTF-8 is the default, but you can specify any encoding the jvm understands

18:15 dan_b: http://docs.oracle.com/javase/8/docs/technotes/guides/intl/encoding.doc.html

18:16 dan_b: oh, thx

18:16 wasn't expectig you to do the work for me ;-)

18:17 justin_smith: for values of "work" that include "remembering some trivia I learned a while back"

18:28 tolstoy: Is add-watch run in the same "transaction" as the actual update of the value of (say) an atom?

18:30 Seems like from the code (clojure.lang.Atom and clojure.lang.ARef) that the atom is not "swapped" until all watches are complete.

18:31 But there seems to be a delay between when a value is written to a file and when I can read it back out.

18:31 AeroNotix: tolstoy: show example code.

18:31 tolstoy: https://gist.github.com/zentrope/512edc035b894f56878e

18:32 amalloy: tolstoy: no, atoms are not transactional

18:32 tolstoy: I'm not sure if the (occassional) problem is in the way I'm testing it, or the concept itself.

18:33 AeroNotix: ...why do you need a file-backed atom?

18:33 amalloy: i haven't looked at the internals of watchers on atoms, but the only way i can imagine it working is: swap starts, stop completes, atom has new value, watchers are called with old and new value

18:34 tolstoy: AeroNotix: We have a need for some concurrent access to text files.

18:35 AeroNotix: mutex

18:35 tolstoy: amalloy: swap calls compareAndSet which, if it succeeds, calls the watchers.

18:35 amalloy: tolstoy: right

18:36 tolstoy: AeroNotix: There are lots of ways to solve the problem. I'm curious if this is one of them.

18:36 amalloy: i think that's the scenario i described

18:36 tolstoy: Yeah.

18:37 AeroNotix: the simplest thing that works and fills your requirements is a mutax

18:37 mutex

18:41 tolstoy: Maybe my test is bad.

18:43 If I delay checking the content of the file for 1 sec, it has the value I expect.

18:43 Oops. Nope.

18:43 Okay, experiment failed.

18:43 Er, hypothesis.

18:44 amalloy: tolstoy: the most obvious problem to me is that a second swap! can run successfully while the watchers for an earlier swap! are still running

18:45 so you can have two watchers running concurrently, with different old/new values

18:51 tolstoy: Yeah, that makes sense.

19:12 justin_smith: amalloy: looks like the swap! doesn't finalize until the watch returns https://www.refheap.com/98599

19:13 or at least, it acts like it doesn't return until the watch does

19:13 amalloy: justin_smith: i don't understand what that's demonstrating. you know that watchers are run on the same thread that's doing the swapping?

19:14 justin_smith: amalloy: added futures just now if you reload

19:14 https://www.refheap.com/98599

19:16 amalloy: justin_smith: your scheduler is too precise

19:16 try (Thread/sleep (+ 500 (rand-int 500)))

19:16 justin_smith: OK

19:16 amalloy: to see the uncoordination in action

19:17 justin_smith: amalloy: you're right, paste updated

19:17 (inc amalloy)

19:17 lazybot: ⇒ 238

19:17 amalloy: i know, i tried it already just in case

19:17 justin_smith: well we both knew, now everybody can know :)

19:18 amalloy: indeed

19:22 justin_smith: amalloy: on the other hand, an agent would block on the validator, right?

19:22 amalloy: probably. i don't understand validators as well as watchers

19:24 justin_smith: answered my own question and updated https://www.refheap.com/98599 - yeah the watcher stays in sync with an agent

19:24 oh, I meant watcher not validator

19:24 sorry

19:29 tolstoy: Hm.

19:29 justin_smith: updated the paste again, trying a validator this time https://www.refheap.com/98599

19:30 so many retries, but it stays serialized with a validator instead of a watch

19:31 Lewix: How come clojure hasn't been bought by a large corporation yet

19:31 justin_smith: tolstoy: anyway, if you intend to serialize access to the file, an agent is a better pick than an atom

19:31 Lewix: is it for sale?

19:35 tolstoy: justin_smith: Using the validator, rather than the watch on the agent?

19:35 justin_smith: tolstoy: it will work with a watch or a validator on the agent - agents don't optimistically execute or retry the way atoms do

19:35 tolstoy: justin_smith: I was also thinking of just implementing clojure.lang.IAtom. ;)

19:36 Ah.

19:36 justin_smith: if all you need is guaranteed exclusive access, agents make that straightforward enough I'd think - the operation won't go through until previous dispatched ops are done

19:37 but the send / send-off still returns immediately on the caller's end though

19:37 amalloy: justin_smith: honestly if you are just using an agent as a convenient thing to lock/sync on, it's just a mediocre reimplementation of a mutex

19:37 tolstoy: I'm mainly after being able to use swap! and reset!. But can back it with an agent, sure.

19:38 justin_smith: tolstoy: send-off does what swap! does, without the retrying stuff

19:38 amalloy: except it doesn't block callers

19:38 amalloy: if there's some stored state, and you want the asynchronicity (asynchrony?), agents are good

20:55 celwell: Hi, I'm using a library that I pulling in with lein in my project.clj, but I need to make a small change to one of the functions in one of the clj files in that lib. What's the best way to override that function? Or do I need download the whole library and keep my own modified copy?

20:56 tcrayford____: celwell: recommended would be to fork and reupload it to clojars under your own group

20:56 or send a PR if it's a generally useful change

20:57 if you really wanna create a nasty mess by changing one of the functions, look at clojure.core/alter-var-root

20:57 justin_smith: celwell: would a wrapper or utility function suffice, or does the change really need to be internal to that lib?

20:58 celwell: justin_smith: then I think I would have to import a bunch of java files that are already in that library

20:58 justin_smith: celwell: import is just a syntactic convenience

20:59 tcrayford____: doesn't sound too hard ;)

21:00 celwell: if i'm using a clj lib that is importing java files (like aws sdk) does that mean I can access/import those same files anywhere in teh project?

21:00 tcrayford____: yep

21:00 justin_smith: celwell: as long as your deps ensure that they are on the classpath, yes

21:00 celwell: ah, i just rewrite a simialr function then

21:00 amalloy: celwell: but note that nobody's actually importing java files, or accessing java files. it's java *classes* that are being used at runtime

21:01 justin_smith: yeah, better to rule out the easiest/simplest thing first :)

21:01 amalloy: the .java files were compiled long ago into .class files

21:15 aytch: would anyone mind helping me solve this? I'm trying to work through 4clojure.com, and I feel like the test spec is failing.

21:15 (= __ conj '(2 3 4) 1)

21:16 justin_smith: aytch: OK, what did you try?

21:16 amalloy: aytch: as the owner of 4clojure.com i have to say you didn't actually copy the test spec correctly into this chat room

21:16 aytch: if I run (conj '(2 3 4) 1), I get back (1 2 3 4) - as I expect

21:16 oh, hi amalloy! you are correct - I was typing it.

21:16 (= __ (conj '(2 3 4) 1))

21:17 justin_smith: OK, so what did you suppy as an answer?

21:17 aytch: thank you for the awesome site. It's gotten me very interested in learning Clojure.

21:17 (1 2 3 4)

21:17 1 2 3 4

21:17 [1 2 3 4]

21:18 amalloy: aytch: you tried each of those, or you tried one answer which was all three of them?

21:18 justin_smith: the first one is an error, the second one is calling = with 5 args, and the third one would work

21:18 bcham: Can someone help me with Carmine? I'm getting totally fucked here and I just can't figure out why. I'm using docker and I'm linking my redis container to my main app container.

21:18 I can ping the redis server no problem

21:18 but carmine can't connect to it

21:18 TEttinger: (= [(*)(+ (*)(*))(+ (*)(*)(*))(+ (*)(*)(*)(*))] (conj '(2 3 4) 1))

21:18 bcham: even though the host is available within the docker container.

21:18 TEttinger: ,(= [(*)(+ (*)(*))(+ (*)(*)(*))(+ (*)(*)(*)(*))] (conj '(2 3 4) 1))

21:18 clojurebot: true

21:19 amalloy: TEttinger: that's not helpful

21:19 justin_smith: TEttinger: correct, and not at all helpful

21:19 TEttinger: I know

21:19 justin_smith: lol

21:19 aytch: amalloy: I've tried all of them

21:19 amalloy: aytch: like justin_smith said, the last one would work

21:19 try it again

21:19 TEttinger: ,(= [1 2 3 4] (conj '(2 3 4) 1))

21:19 clojurebot: true

21:19 aytch: oh......I see now.

21:19 [1 2 3 4], by itself, solves both.

21:19 TEttinger: ,(= '(1 2 3 4) (conj '(2 3 4) 1))

21:19 clojurebot: true

21:20 aytch: I thought it was two separate tests

21:20 justin_smith: ,(= 1 2 3 4 [1 2 3 4])

21:20 clojurebot: false

21:20 aytch: so I've always had two lines

21:20 TEttinger: if you try to use (1 2 3 4) without the ' , it will try to call 1 as a function

21:20 justin_smith: aytch: yeah, that would mess it up

21:21 amalloy: i guess conj is the first problem with multiple test cases, isn't it

21:21 aytch: I believe so.

21:21 amalloy: maybe i'll add an explanation to that problem, like we did to the math one where people kept "filling in the blank" by restating the whole test case instead of just supplying a value for __

21:21 justin_smith: yeah, I think that is a good idea

21:22 aytch: even just something like "one answer must pass both tests"

21:22 thank you, kind folk!

21:22 amalloy: aytch: http://www.4clojure.com/problem/5

21:23 justin_smith: nice

21:23 aytch: Hooray! Also: that was quick!

21:23 amalloy: aytch: it's nice that we have live-editing of the problem statements built in; it's one of the few things i don't have to restart the server to do

21:26 aytch: I'm a little confused by this, still: https://clojuredocs.org/clojure.core/conj

21:26 (conj [1 2 3] 4)

21:26 TEttinger: conj acts differently for lists and vectors

21:26 aytch: is a vector, which returns [1 2 3 4]

21:27 TEttinger: ,(conj [1 2 3] 4)

21:27 clojurebot: [1 2 3 4]

21:27 justin_smith: and differently still on sets :)

21:27 TEttinger: ,(conj '(1 2 3) 4)

21:27 clojurebot: (4 1 2 3)

21:27 justin_smith: ,(conj #{1 2 3} 4)

21:27 clojurebot: #{1 4 3 2}

21:27 aytch: yeah, but the question shows a list, and the answer is a vector

21:27 TEttinger: (but sets aren't ordered so don't worry)

21:27 justin_smith: ,(conj {:a 1 :b 2} [:c 3])

21:27 clojurebot: {:a 1, :b 2, :c 3}

21:27 TEttinger: aytch, yeah, sequences are checked for equality by their elements

21:27 justin_smith: aytch: oh, that's another thing, clojure does structural equality for some types

21:27 TEttinger: not the actual type of the sequence

21:30 aytch: Okay. I'm still confused, but I shall soldier forward and work out these mysteries in time.

21:31 justin_smith: aytch: structural equality just means that lists and vectors are equal if they have the same elements in the same order, even though the type is different

21:31 they generate different structures when you use conj, but are considered equal

21:31 aytch: ahhh, okay! That's an interesting thing to know.

21:43 justin_smith: amalloy: you may be able to give a good answer to this SO question http://stackoverflow.com/questions/29131907/why-is-a-read-as-a-list-while-a-b-isnt

21:45 amalloy: i mean, i know the technical answer to that question, but i think a better answer is like, "don't care about this; use seq? in place of list?"

21:46 justin_smith: "list? is stupid and useless, use seq?"

21:46 (dec list?)

21:46 lazybot: ⇒ -1

21:47 amalloy: i would upvote that answer

21:49 Guthur`: i would downvote list? because it's semantics are confusing

22:11 justin_smith: amalloy: well, I took my stab at it, but I feel like more info about the "why" he asked, or at least a good justification for not answering that part, would be nice.

22:12 amalloy: justin_smith: i think an important example you're missing is ##(class (seq [1])), to remind people that the explicitly named types aren't the only kinds of seqs you'll find

22:12 lazybot: ⇒ clojure.lang.PersistentVector$ChunkedSeq

22:13 justin_smith: oh, good call! thanks

23:54 devn: ,(range 0 10 9/4)

23:54 clojurebot: (0 9/4 9/2 27/4 9N)

23:54 devn: ,(map long (range 0 10 9/4))

23:54 clojurebot: (0 2 4 6 9)

23:55 justin_smith: ,(range 0.0 (/ 1.0 0.0) Math/PI)

23:55 clojurebot: (0.0 3.141592653589793 6.283185307179586 9.42477796076938 12.566370614359172 ...)

23:56 devn: ,(map long (range 0.0 10.0 9/4))

23:56 clojurebot: (0 2 4 6 9)

23:56 devn: justin_smith: ah yeah, i think that's what i was trying to remember

23:56 justin_smith: which?

23:56 devn: err wait

23:56 no, there's a bug im trying to remember

23:56 justin_smith: what kind?

23:58 devn: ,(partition-all 9/4 (range 10))

23:58 clojurebot: ((0 1 2) (3 4 5) (6 7 8) (9))

23:58 devn: ,(partition-all (long 9/4) (range 10))

23:58 clojurebot: ((0 1) (2 3) (4 5) (6 7) (8 9))

23:59 devn: justin_smith: there it is ^

23:59 if there isn't a patch for it, there will be

Logging service provided by n01se.net