#clojure log - Sep 13 2014

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

0:00 justin_smith: and of course, that really means the general programming style that works with immutibility

0:00 catern: learning that value has made programming in mutable languages *more* painful!

0:00 justin_smith: why? why not just program immutibly in whatever language?

0:00 in clojure, you can still need to touch mutible state or APIs in the jvm

0:01 though its true you will find less immutible infrasctucture, some stuff isn't so hard to adapt

0:03 ToxicFrog: So I have the following form: (some-> (:name x) (.equalsIgnoreCase (:name y)))

0:03 I want to eliminate reflection, and know that (:name x) and (:name y) have type String.

0:04 Where do I put the ^String annotations?

0:04 ambroseb_: (let [^String a (:name x)] (some-> a ....))

0:04 ToxicFrog: (rather, I know that (:name y) has type String and (:name x) is either a String or nil, but if it's nil the some-> will never get around to making the method call anyways)

0:04 justin_smith: ToxicFrog: this code may be clearer without the some-> form if annotated

0:06 ToxicFrog: ambroseb_: aah. The docs say that type hints can be placed on "expressions" as well as parameters, var-names and let-names, but isn't really clear on how you do that.

0:06 So I was hoping I could attach the ^String to (:name x) directly somehow.

0:06 ambroseb_: ToxicFrog: mm it's an art

0:06 :)

0:06 ToxicFrog: especially when you're passing nil ...

0:07 ToxicFrog: Actually, looking at it, I'm not sure I am passing nil. The some-> may be a holdover from an earlier version.

0:31 michaniskin: is it possible to have nested nrepl clients?

0:31 like if i have a repl session going can i attach to another nrepl server

0:32 justin_smith: michaniskin: yeah, I would be surprised if it did not work, via clojure.tools.nrepl

0:32 michaniskin: i must be doing something wrong, it disconnects me from the current session

0:33 justin_smith: hrm - I would think it would be re-entrant

0:33 ToxicFrog: Dear god the type signature on every?

0:33 justin_smith: haha, I can only imagine

0:33 ToxicFrog: I was expecting something like [(Seqable Any) -> Boolean]

0:33 Instead it's (All [x y] (IFn [(IFn [x -> Any :filters {:then (is y 0), :else tt}]) (Coll x) -> java.lang.Boolean :filters {:then (is (Coll y) 1), :else tt}] [(IFn [x -> Any :filters {:then (is y 0), :else tt}]) (U (IPersistentCollection x) nil) -> java.lang.Boolean :filters {:then (is (U (IPersistentCollection y) nil) 1), :else tt}] [(IFn [x -> Any]) (U (Seqable x) nil) -> java.lang.Boolean]))

0:34 justin_smith: woah

0:34 ToxicFrog: (why am I looking at this? Because core.typed doesn't come with type annotations for clojure.core/not-any?)

0:35 (so I figured I'd check every?, which I thought would have the same type)

0:35 (I'm not so sure anymore)

1:15 justin_smith: so it turns out to be a lot more readable if you run it through pprint and ignore the filters.

1:16 I am a bit confused as to why it has three signatures, though -- one taking (Coll x), one (U (Seqable x) nil), and one (U (IPersistentCollection x) nil)

1:27 Argh. It's complaining that String/contains can't be applied to arguments (U String nil), but String implements CharSequence and the code in fact runs fine

1:27 maybe this will make more sense in the morning

2:39 dorkmafia: http://paste.debian.net/120653/ how come that doesn't work? I also tried {:libpaths [["python/"]["skype4py/Skype4Py/"]] } but {:libpaths ["python/"]} working?

2:40 /ing/d

6:45 dagda1: is there anything similar to respond_to? in clojure that will let me know if a datatype has a method or am I thinking about this all wrong

6:45 justin_smith: dagda1: you can use clojure.reflect/reflect to get all slots and methods on an object

6:46 dagda1: justin_smith: thanks

6:46 justin_smith: or you can use instance? / isa? to see if it implements the protocol or interface defining that method

6:46 that's less expensive, but also less reliable

7:00 papachan: hi

7:01 i would like conj a map {} with doseq because i need to iterate each key value of another map

7:01 i was thinking something like this, but obviously it doesn't work

7:01 https://code.stypi.com/papachan/conj.clj

7:32 milos_cohagen: papachan: if you want to create a new map, from an old map, with some transformations in between, you can use reduce perhaps

7:32 ,(reduce (fn [m [k v]] (assoc m k v)) {} {:a 0 :b 1})

7:32 papachan: milos_cohagen thank you i will try with reduce

7:32 clojurebot: {:a 0, :b 1}

7:33 milos_cohagen: doXXX functions are mostly for performing side effects, like mutating something, printing something, etc

7:34 clojure functions like conj or assoc or "pure", no side-effects

7:35 i mean "are pure" not "or pure"

7:37 papachan: milos_cohagen ok it does the same think when i am using conj

7:41 milos_cohagen: papachan would be happy to take a look if you post a snippet

7:43 papachan: milos_cohagen,

7:44 https://code.stypi.com/papachan/snippet.clj

7:49 milos_cohagen: papachan thanks but from that repl session i'm having a hard time interpreting your goal. what are the requirements of params-parser

7:51 papachan: milos_cohagen i am receiving a params {:model "android" :version "1.2.1"}

7:52 milos_cohagen: ok

7:52 papachan: need to put it in a session cookie structure

7:52 as at final

7:52 and assoc with the actual session cookie

7:54 i was working with do seq but its not the result: it executed each times it detect a keyword

7:55 milos_cohagen: ok so, we want a function f which accepts two maps as arguments a and b. (defn f [a b] ..)

7:55 map "a" keys and vals should be added in someway to map "b"?

7:57 and an updated version of map "b" should be returned?

7:57 papachan: yes i was trying with your reduce code, but still don't understand how i recur each keywords to make a new map structure

7:57 should return the final at my snippet but not repeated

8:01 milos_cohagen: ok so we do (defn f [a b] ...), the ... could be a reduce form, so we say (defn f [a b] (reduce reduce-fn b a))

8:01 papachan: ok

8:03 milos_cohagen: reduce-fn accepts two args, the accumulated vale, which starts with "b", and second arg is the first k,v of "a", and should return the new accumulated value

8:04 sorry hard to explain, i can't just write the answer for you because your examples don't show what "a" and "b" values look like exactly with exact desired output

8:06 papachan: milos_cohagen i am trying to make something work. will try your example

8:17 milos_cohagen: good luck!

8:30 kqr: can I somehow figure out the type of an object I have in my clojure program? it exhibits some interesting properties and I'd like to know what it is

8:30 kungi: I am trying to test my core async code but the test finishes with the report before the assertations in the go-blocks had a chance to run

8:31 Is there an asynchronous testing helper for clojure.test?

8:31 kqr: class maybe what you want

8:31 ,(class "")

8:31 clojurebot: java.lang.String

8:31 kqr: kungi, yes I did, thanks

8:32 it's just a java.io.File

8:32 interesting!

8:54 does anyone know why I get the exception: http://lpaste.net/2155899009351286784 ? even though according to javadocs one of the copy methods take two paths as arguments?

8:55 ...wait

8:55 clojure has a copy function?

8:55 just maybe i should use that instead

9:00 but that fails too

9:00 hm

9:01 kungi: kqr: https://clojure.github.io/clojure/clojure.java.io-api.html

9:01 kqr: who woulda thunk copying files would be so difficult on the jvm :D

9:01 kungi: kqr: there is also a copy function

9:01 kqr: i saw that

9:01 but if I try to (clojure.java.io/copy (File. "t1.txt") (File. "t2.txt")) it complains about one of them not being a var

9:02 if I assign them to variables before doing the call I get an IllegalArgumentException in multimethod "do-copy"

9:02 ToxicFrog: kqr: re Files/copy: is it possible that the reflector is finding the wrong method for it?

9:03 There's a bunch of different versions of copy, including one that takes (Path OutputStream) and one that takes (Path Path); if it's only finding the former, there's your problem

9:03 kqr: http://lpaste.net/4103219378718244864

9:03 full version of the error I get with the clojure-native copy function

9:04 ToxicFrog, yeah, that's what I suspected... but I don't know how I can make it find the other one

9:05 ToxicFrog: kqr: hmm. I tried adding type annotations to mark both src and dest as ^Path but that didn't work :/

9:06 kqr: weird

9:07 ToxicFrog: Oh, I see, reading the docs on java interop it looks like type hints help it on resolving the type of this when making method calls but no mention is given of resolving arguments in overloaded functions

9:07 kqr: well

9:07 (clojure.java.io/copy (clojure.java.io/file "t.txt") (clojure.java.io/file "t2.txt")) works

9:08 even though clojure.java.io/file according to docs passes the argument straight to java.io/File

9:10 ToxicFrog: kqr: ok, but that's expected?

9:10 Look at the docs: "Input may be an InputStream, Reader, File, byte[], or String."

9:10 clojure.java.io/copy supports Files but not Paths

9:11 kqr: ToxicFrog, shit yeah you're right

9:11 ToxicFrog, I thought my variables source and dest were files, but they are paths

9:11 ToxicFrog, thanks

9:12 they were files for the longest time, then I made them into paths before asking here :)

9:15 ToxicFrog: Huh. I must not understand how to set type hints.

9:15 I thought they were stored in the metadata, but:

9:15 user=> (let [^Path p (.toPath (File. "/etc/passwd"))] (meta p))

9:15 nil

9:16 kqr: i thought so too

9:28 ToxicFrog: Huh.

9:28 Ok, so if I use with-meta, everything works fine

9:28 If I use the ^ macro, no metadata is applied

9:28 Oh. Because I'm using it in the wrong position.

9:28 asdfh

9:35 kqr: haha

9:36 ToxicFrog: But it still doesn't work with Path!

9:36 aaaaaaaaagh

9:36 user=> (def x ^int {}) (meta x)

9:36 {:tag #<core$int clojure.core$int@12a133b2>}

9:36 user=> (def src ^Path (.toPath (File. "/tmp/foo"))) (def dst ^Path (.toPath (File. "/tmp/bar"))) (meta dst)

9:36 nil

9:57 kqr: is there a way to store some information about my application in a separate file? i'm trying to create a web app, and both ragtime and korma wants information about the database but in separate formats

9:58 and i'd rather not commit the details of the database to the repo

9:58 rweir_: I've used https://github.com/weavejester/environ pretty happily

9:58 which doesn't help with getting the stuff into your libraries, but it does do the 'what are the values' bit

10:00 kqr: I just now realised that project.clj is a normal clojure file

10:00 that certainly helps

10:01 rweir_: yeah

10:01 think carefully about how much magic you put in there though

10:03 kqr: well ragtime wants a jdbc url, so somehow I need to convert the db details into a url

10:03 is that too much magic?

10:03 rweir_: ah

10:03 I'd probably do that in my real-code instead of project.clj, but I don't have a strong opinion either way :)

10:03 kqr: how'd that work?

10:04 what I'm imagining is a file that simply contains a map with host, db name, username and password

10:04 rweir_: ie do at the point where you first interact with ragtime [I've not used it, so apologies if that's a stupid answer]

10:04 kqr: and then project.clj *and* src/db/schema.clj must use that information

10:04 the first interaction with ragtime is in the project.clj file

10:04 rweir_: oh, interesting

10:04 kqr: or rather, that's where you're supposed to tell it which database to use

10:05 rweir_: ah, I see [looking at the docs]

10:05 kqr: the broader context is that I'm trying to learn the luminus framework

10:05 I find it as confusing as the next guy

10:20 dagda1: is there a way to find the common elements in 2 vectors?

10:21 zot: convert to set and do intersection?

10:47 gfredericks: anybody know what's up with marmalade?

10:51 Raynes: gfredericks: Everything sucks.

10:52 gfredericks: (inc Raynes)

10:52 a few of my packages aren't available after removing marmalade from my list

10:57 lazybot being gone is symbolic of everything being broken this morning

10:58 Bronsa: it's not like lazybot being gone is a first

10:59 Raynes: you know what

11:00 Fuck it

11:00 * Raynes grants everyone ssh access to lazybot's box

11:00 justin_smith: Bronsa: that's the difference between FUBAR and SNAFU

11:00 Raynes: IT'S THE ONLY WAY TO BE SURE

11:00 hyPiRion: Raynes: Have a supervisor on it?

11:00 get mail every time it crashes

11:01 Bronsa: Raynes: <3

11:01 Raynes: hyPiRion: I'd love for it to be as simple as monitoring it, but it's not quite that easy.

11:01 hyPiRion: When lazybot dies his process almost never dies.

11:01 hyPiRion: Raynes: oh, right

11:01 Raynes: He is designed in such a way that if he can't talk to one IRC he doesn't really care that much

11:01 The problem is he can't tell when he can't talk to ANY irc :P

11:02 justin_smith: Raynes: I assume it also has to detect and act on disconnects fro mthe server

11:02 Raynes: It does not.

11:02 hyPiRion: It's the "100% CPU time after server disconnect"-bug?

11:02 Raynes: Uses an ancient unmaintained version of irclj that doesn't handle disconnects at all, really.

11:02 Nah, he just loses connection and can't do anything about it

11:02 So he sends pings every now and then

11:02 hyPiRion: ah, haha

11:02 Raynes: Hoping for an answer

11:02 It's quite sad really

11:02 Let me put the kid out of his misery

11:03 justin_smith: you could make him close the connection and reconnect every half hour

11:03 lol

11:03 Raynes: That's srs engineering right there

11:03 hyPiRion: Well, if anyone has nothing to do in their sparetime, they could patch up poor lazybot

11:03 Raynes: hyPiRion: Step one: use newer half-assed irclj implementation.

11:03 Step two: figure out it needs to be less half assed, make it less half assed

11:03 Step three: #win

11:04 hyPiRion: Raynes: I was talking about step two mostly

11:04 implement proper irclj

11:04 Raynes: The newer irclj is pretty solid

11:04 I don't think it actually lacks much of anything lazybot would need.

11:08 gfredericks: Raynes: so a vigorous manual restart tends to fix transient problems?

11:08 Raynes: gfredericks: It doesn't actually go down that much.

11:08 gfredericks: but when it does that fixes it?

11:08 Raynes: Well yes, because the only 'problem' is usually just that it has lost connection for one reason or another.

11:09 Birds sitting on power lines and shit.

11:09 Normal stuff.

11:09 Irclj needs handling for connection loss and lazybot needs new irclj after that.

11:09 Then he will be legion without my help.

11:09 gfredericks: the hipchat bot I run at work is run in a bash loop that kills/restarts every ten minutes

11:10 Raynes: Sounds like an average Python program.

11:10 justin_smith: gfredericks: that was my "joke" suggestion

11:10 gfredericks: it has the advantage that it's easy to do :P

11:10 Raynes: Hey

11:11 Could be like "Hmmmmmm... Nobody has said anything on any of these 40 channels I'm in in the past half hour..."

11:11 "I... guess I should kill myself now?"

11:11 "(System/exit 0) ; goodbye cruel world"

11:12 justin_smith: Raynes: sounds like my ex having a bpd attack

11:13 Raynes: isn't there an IRC protocol level thing for checking if you are connected?

11:13 Raynes: justin_smith: What's the first thing they do to a robot at the doctor's office?

11:13 THEY CHECK HIS BYTLES.

11:14 justin_smith: Well, ideally your socket realizes nothing's popping out the other end, but you can send PINGs to the server and if you do not get a response in a timely manner you can assume you're lost in interspace.

11:14 justin_smith: Raynes: like every half hour he could run /msg nickserv listchans

11:14 or just that

11:14 Raynes: IRC is super async.

11:15 justin_smith: right, distributed, async

11:15 Raynes: It's real hard to be like "gimme a list of channels" and then say "oh, here's my list of channels"

11:15 You kinda have to send 'gimme a list of channels' off into the void and then receive the response from the void.

11:15 gfredericks: so srsly should I expect marmalade to be down for a long time?

11:15 Raynes: The problem is six other commands could return before that one, despite your ordering :P

11:15 gfredericks: It's marmalade. Expect it to never come back up.

11:15 justin_smith: Raynes: reminds me of my experiments with mud scripting

11:16 basically you need multiple state machines ready to be triggered or finalized, because who knows which part of your logic a given message may be destined for

11:16 gfredericks: I need to give up on emacs package managers and just maintain a personal collection of .el files, don't I?

11:17 justin_smith: gfredericks: technomancy seems fond of el-get

11:17 gfredericks: what's that? another package manager?

11:17 justin_smith: http://www.emacswiki.org/emacs/el-get

11:17 gfredericks: my current problem is that some of my packages are only in this one repo that Raynes said will never come back

11:17 xeqi: gfredericks: I'm going to guess its maintained by one person, so yes

11:18 justin_smith: gfredericks: above link has a "why have both" rationale (up to you whether it's reasonable or not, of course)

11:18 gfredericks: "Think apt-get for emacs"

11:18 Raynes: gfredericks: It is way too early and I'm way too bitter to say one single useful non-silly thing right now.

11:19 gfredericks: Raynes: it's like 10am amirite

11:19 Raynes: I woke up at 7AM

11:19 * gfredericks found out this morning he was wrong about where San Diego is

11:19 Raynes: Didn't even get to go to the toilet before having to solve crisises.

11:19 gfredericks: waking up at 7am is sleeping in for me

11:19 Raynes: Waking up at noon is sleeping in for me.

11:20 gfredericks: I woke up at 8am today and that was *highly* unusual

11:23 who is going to stramg lop

11:24 justin_smith: bizzaro justin am going stramg lop thisy ear

11:24 (not actually going to strange loop)

11:26 gfredericks: does cider have a buffer-local current-ns variable?

11:27 I was looking at my 0.5.0 source and it seemed to mostly just infer based on an initial (ns ...) form, which doesn't help my org-babel uses

11:28 I see nrepl-client.el has (defvar-local nrepl-buffer-ns ...)

11:32 * gfredericks learns more elisp than he was planning to this morning

11:32 justin_smith: gfredericks: edebug is an awesome stepping debugger, that shows you the result of every form as it is evaluated, by the way

11:34 gfredericks: justin_smith: thanks; I'm still n00b enough that extra tools are likely to just layer confusion

11:37 allen: does anyone know of a plugin that allows me to load clojar or external libraries from within a lein repl

11:37 similar to https://github.com/rkneufeld/lein-try

11:38 except have the ability to load different libraries as we go with the flow

11:38 Raynes: https://github.com/cemerick/pomegranate

11:38 xeqi: alembic

11:39 allen: Raynes, beautiful. Thanks

11:39 (inc Raynes)

11:39 lazybot: ⇒ 51

11:39 gfredericks: hi lazybot

11:39 Raynes: Whatever is at the top of the inevitable 1200 libraries on top of pomegranate I guess

11:40 gfredericks: gimme uses fireflox uses alembic uses pomegranate so if you're not using gimme you're basically losing

11:41 Raynes: It looks like alembic doesn't use pomegranate?

11:41 Which is horrifying

11:41 xeqi: it does

11:41 gfredericks: I use pomegranate, with a helper: https://github.com/gfredericks/repl-utils/blob/master/src/com/gfredericks/repl.clj#L12-18

11:41 Raynes: xeqi: Oh, a transitive dep?

11:41 Lovely

11:41 xeqi: I think through lein-as-resource

11:42 hugoduncan: which is woefully out of date

11:43 mantas: $ lein run [11:39:52]

11:43 Exception in thread "main" java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to clojure.lang.Keyword, compiling:(caffeinate/web.clj:1:1)

11:43 line one is simple: (ns caffeinate.web

11:43 any explanation as to why this happens?

11:43 Raynes: Well, I'd close that for starters.

11:43 justin_smith: allen: pallet/alembic is easier to use than pomegranate

11:44 Raynes: Line one is a red herring, mantas. Please show us your whole ns form

11:44 allen: ok cool, i'll check out all three

11:44 xeqi: mantas: through the magic of macros, line 1 is basically everything in the (ns ..) form

11:44 allen: ohh nvm alembic is developed by pallet

11:44 Raynes: Is pomegranate difficult to use? O.o

11:45 xeqi: Raynes: well, you do have to pass the repositories. and if you have mirrors...

11:45 justin_smith: Raynes: alembic uses the project.clj dep syntax, and is automatically recursive

11:45 hugod: alembic keeps pomegranate off your project's classpath

11:45 justin_smith: and you don't need to specify repos at all

11:45 xeqi: hugod: does alembic keep track of what is already been distilled?

11:45 to avoid different distilled calls bring in conflicting deps?

11:46 hugod: xeqi: it checks what is already loaded in the clsspath

11:46 and warns on conflicts

11:46 Raynes: Well, clearly alembic is the best thing since sliced ham.

11:46 justin_smith: xeqi: alembic, in my experience, does not import things if some other version is already imported

11:46 xeqi: right, I thought it had something that way

11:46 justin_smith: Raynes: I found it much easier to use compared to pomegranate

11:46 Raynes: I understand

11:48 zeebrah: i'd like to trace a function for debugging. is it doable?

11:48 justin_smith: zeebrah: tools.trace

11:48 https://github.com/clojure/tools.trace very easy to use

11:49 zeebrah: justin_smith: cheers

11:50 this isn't quite what i had in mind. i was hoping for a CL like trace :(

11:51 justin_smith: zeebrah: tracing the execution of the function?

11:51 zeebrah: yep

11:52 justin_smith: zeebrah: I hear tell cursive clojure (it's an intellij idea plugin) has good step debugging, but have not actually tried it myself

11:53 zeebrah: justin_smith: actually wait, trace-ns is kinda cool and does the job :)

11:54 justin_smith: zeebrah: it doesn't get you the step by step internals though, but I guess it gets you your helper functions

11:55 on a more insane end of things, you can use jdb to trap and step and interact with the stack on the byte code level

11:55 but if trace-ns suffices, cheers :)

11:55 zeebrah: justin_smith: thanks for the help :)

11:56 justin_smith: np

11:57 kungi: I would like to have an atom containing a map of key -> #set pairs. How do I append to such a structure? When the #set belonging to a key is empty it is easy, but how do I append to an existing set in a map with a swap! operation?

11:58 justin_smith: ,(swap! (atom {:numbers #{0}}) update-in [:numbers] conj 1 2 3)

11:58 clojurebot: {:numbers #{0 1 3 2}}

11:58 justin_smith: definitely looks weird, as both swap and update-in take their args just stacked on the end without parens

11:59 kungi: justin_smith: yes it does :-)

11:59 justin_smith: Can I add a non existing key that way?

11:59 gfredericks: it's fun once you get the hang of it though

11:59 yes

11:59 kungi: ,(swap! (atom {:numbers #{0}}) update-in [:blubber] conj 1 2 3)

11:59 clojurebot: {:blubber (3 2 1), :numbers #{0}}

11:59 kungi: Awsome!

11:59 justin_smith: kungi: you need fnil for that if it needs to be a set

11:59 gfredericks: (fnil conj #{}) instead of conj

12:00 justin_smith: ,(swap! (atom {:numbers #{0}}) update-in [:blubber] (fnil conj #{}) 1 2 3)

12:00 clojurebot: {:blubber #{1 3 2}, :numbers #{0}}

12:00 mantas: huh, thanks! yes, the issue was later in the (ns... ) declaration. i didn't know macros had this effect.

12:01 kungi: justin_smith: Thank you

12:01 justin_smith: np

12:02 gfredericks: ,(def my-atom (atom {:foo [1 2 3]}))

12:02 clojurebot: #'sandbox/my-atom

12:02 gfredericks: ,(swap! my-atom update-in [:foo 0] dec)

12:02 clojurebot: {:foo [0 2 3]}

12:03 gfredericks: ,(swap! my-atom update-in [:foo 0] + 42)

12:03 clojurebot: {:foo [42 2 3]}

12:19 allen: date

12:21 iartarisi: Hello, I'm using Korma and trying to restrict the number of fields from a select query. I'd like to get SELECT games.white_id FROM games; but I get all the fields *plus* white_id instead:

12:21 (dry-run (select games (fields :white_id)))

12:21 dry run :: SELECT "games"."stones", "games"."white_id", "games"."black_id", "games"."white_id" FROM "games" :: []

12:21

12:22 I have the latest korma: 0.4.0

13:10 Shoop: Whats the best way to turn ((1 1) (2 2)) into [[1 1] [2 2]]?

13:11 shosti: ,(vec (map vec '((1 1) (2 2))))

13:11 clojurebot: [[1 1] [2 2]]

13:12 justin_smith: ,(mapv vec '((1 1) (2 2)))

13:12 clojurebot: [[1 1] [2 2]]

13:16 Shoop: Thanks :D

13:18 Is vec the same as #(apply vector %)?

13:19 justin_smith: $source vec

13:19 lazybot: vec is http://is.gd/GCHYnT

13:20 Shoop: not literally but conceptually

13:20 justin_smith: interestingly, if you supply an array as the argument, it aliases it, and you break the contract of vectors if you later modify the array

13:23 where vector will not do anything like that

13:27 Jaood: cider needs some keep-alive method

13:42 gfredericks: ,(def argh (into-array [0 1 2 3 4]))

13:42 clojurebot: #'sandbox/argh

13:42 gfredericks: ,(seq argh)

13:42 clojurebot: (0 1 2 3 4)

13:42 gfredericks: ,(def vee (vec argh))

13:42 clojurebot: #'sandbox/vee

13:42 gfredericks: ,vee

13:42 clojurebot: [0 1 2 3 4]

13:42 gfredericks: ,(aset argh 2 :hehe)

13:42 clojurebot: #<ArrayStoreException java.lang.ArrayStoreException: clojure.lang.Keyword>

13:42 gfredericks: ,(aset argh 2 42)

13:42 clojurebot: 42

13:42 gfredericks: ,vee

13:42 clojurebot: [0 1 42 3 4]

13:43 gfredericks: ,(doc vec)

13:43 clojurebot: "([coll]); Creates a new vector containing the contents of coll. Java arrays will be aliased and should not be modified."

13:43 gfredericks: welp can't say it didn't warn you

13:43 does it do that even for large arrays?

13:44 ,(def argh (into-array (range 100000)))

13:44 clojurebot: #'sandbox/argh

13:44 gfredericks: ,(def vee (vec argh))

13:44 clojurebot: #'sandbox/vee

13:44 gfredericks: ,(aset argh 0 42)

13:44 clojurebot: 42

13:44 gfredericks: ,(take 10 vee)

13:44 clojurebot: (0 1 2 3 4 ...)

13:45 justin_smith: fascinating

13:45 gfredericks: it'd have to break it up at some point anyways; might as well be immediately

13:45 justin_smith: so maybe "will be" should say "can be"

13:45 gfredericks: right :)

13:46 we need a variant of the word "modify" for talking about immutable data structures

13:47 how about "schmodify"

13:47 or "schmutate"

13:47 justin_smith: elaborates?

13:47 gfredericks: yeah?

13:47 justin_smith: exponunds upon

13:47 err, expounds upon

13:47 gfredericks: not really a good analogy from normal life

13:51 jjl`: hi all. I'm writing some clojure that will need to be usable from java. what's the simplest way of writing test cases in java within a clojure project?

13:51 gfredericks: jjl`: test cases for automated testing?

13:51 jjl`: yes

13:51 gfredericks: leiningen has an option for specifying the location of java sources

13:52 I guess the rest of the answer depends on how you want to execute/launch the tests

13:52 e.g., do you mind writing tests in clojure that call your java code?

13:52 or do you need a java test framework?

13:53 jjl`: i think okay with the former, provided the java test harness doesn't get shipped in the final jar

13:53 gfredericks: yeah, leiningen lets you distinguish between dev stuff and final-package stuff

13:54 jjl`: okay. do you know which project.clj keys i'll need to read up on?

13:56 gfredericks: check the sample.project.clj file in the leiningen repo; they'll be one called :java-source-path or something similar

13:57 then try writing a test with clojure.test that runs your java code

13:57 jjl`: yeah, i just found that. presumably :exclusions is the other one i need?

13:57 gfredericks: or first you could try `lein run -m MyClass`

13:57 which I think works

13:57 jjl`: if you put it in the :dev profile then you don't need to exclude anything

13:57 :profiles {:dev {:java-source-paths ...}}

13:57 jjl`: oh, handy :)

13:58 thanks :)

13:58 gfredericks: np

14:28 nkozo: I start a "lein repl" and then connect from emacs using cider, now if a Thread prints to *out* (using the timbre logging library) only the "lein repl" prompt shows the output, the cider nrepl session doesn't show it. Why? How you can print to both?

14:44 gfredericks: nkozo: um.

14:44 when you say "a Thread" I assume you mean not the thread you're using directly from cider

14:49 I think I know what all the pieces involved are, I just don't know what the best approach is

15:17 ultranapoletano: ciao

15:17 !list

15:27 jjl`: is there a way of building an abstract class member in clojure? i need it for some java interop and i'd be loathe to write it in java

15:30 gfredericks: what's an abstract class member?

15:31 jjl`: an abstract method

15:31 gfredericks: what would that look like in java?

15:32 jjl`: abstract class Foo { abstract void bar(); }

15:32 gfredericks: I'm curious what sort of java interop that's useful for

15:34 jjl`: Basically I'm building something where arbitrary objects will be passed around because of dynamic typing. All lovely and fine in clojure, but in javaland, you need type safety. I'd like a generic callback mechanism a la Callable, but different

15:35 gfredericks: why not an interface?

15:36 jjl`: because an interface doesn't permit you to enforce a given constructor

15:37 gfredericks: welp I don't know of any way to do abstract stuff in clojure; it doesn't sound like it'd be intolerable to write it in java

15:38 jjl`: no, indeed, it's not that much hassle, it's just i'd prefer to keep as much in clojure as possible

15:45 arohner: is #datomic logged anywhere?

15:46 TEttinger: arohner, it would be kinda ironic if the channel for a database wasn't logged in some database

15:46 arohner: google doesn't seem to know about it

15:47 redblackbit: any idea why (meta ^:foo 'bar) return nil while the documentation states that: Symbols and collections support metadata

15:48 TEttinger: ,(meta ^:foo +)

15:48 clojurebot: nil

15:48 TEttinger: ,(meta +)

15:48 clojurebot: nil

15:48 TEttinger: hm

15:49 ,(meta inc)

15:49 clojurebot: nil

15:49 TEttinger: might need var-quote

15:49 redblackbit: right

15:49 arohner: + resolves to the fn

15:49 ,(meta #'+)

15:49 clojurebot: {:added "1.2", :ns #<Namespace clojure.core>, :name +, :file "clojure/core.clj", :inline-arities #<core$_GT_1_QMARK_ clojure.core$_GT_1_QMARK_@6e4c32>, ...}

15:49 redblackbit: but why doesn’t it work with a symbol?

15:49 TEttinger: ,(meta ^:foo #'bar)

15:49 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve var: bar in this context, compiling:(NO_SOURCE_PATH:0:0)>

15:50 arohner: ,(meta (with-meta 'bar {:foo true}))

15:50 clojurebot: {:foo true}

15:50 gfredericks: redblackbit: it's because of what ' does

15:50 TEttinger: maybe ^:foo isn't evaluated until the form is done?

15:50 gfredericks: ,(meta ^:foo (quote bar))

15:50 clojurebot: nil

15:50 gfredericks: ,(meta (quote ^:foo bar))

15:50 clojurebot: {:foo true}

15:50 gfredericks: redblackbit: your code is equivalent to the first of those two ^

15:51 redblackbit: gfredericks: oic

15:51 gfredericks: also there is:

15:51 redblackbit: gfredericks: makes kinda a pain to attach metadata to symbols though

15:51 gfredericks: ,(with-meta 'bar {:foo true})

15:51 clojurebot: bar

15:51 gfredericks: ,(meta (with-meta 'bar {:foo true}))

15:51 clojurebot: {:foo true}

15:54 redblackbit: gfredericks: anyway, thx!

15:54 gfredericks: np

16:11 danielszmulewicz: Question to the emacs power users: I'm writing a minor mode that makes sense only with clojurescript files, however, there is no clojurescript-mode hook. Any ideas?

16:16 gfredericks: is there a clojurescript-mode?

16:23 danielszmulewicz: gfredericks: People have written their own, but now with cider and the official stack. Anyway, I posted an issue on cider's github.

16:41 noncom: ,(.getConstructor (java.lang.Class/forName "java.util.ArrayList"))

16:41 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: No matching field found: getConstructor for class java.lang.Class>

16:42 noncom: ^^^ why is it searching for the constructor in class Class ? why does not it looking for the constructor in class ArrayList ?

16:46 dbasch: noncom: you’re calling a method that doesn’t exist

16:47 : ,(.getConstructors (java.lang.Class/forName "java.util.ArrayList"))

16:47 &(.getConstructor (java.lang.Class/forName "java.util.ArrayList"))

16:47 lazybot: java.lang.IllegalArgumentException: No matching field found: getConstructor for class java.lang.Class

16:47 dbasch: &(.getConstructors (java.lang.Class/forName "java.util.ArrayList"))

16:47 lazybot: ⇒ #<Constructor[] [Ljava.lang.reflect.Constructor;@b3cde94>

16:48 dbasch: &(first (.getConstructors (java.lang.Class/forName "java.util.ArrayList”)))

16:48 lazybot: java.lang.RuntimeException: EOF while reading string

16:49 dbasch: &(first (.getConstructors (java.lang.Class/forName "java.util.ArrayList")))

16:49 lazybot: ⇒ #<Constructor public java.util.ArrayList(java.util.Collection)>

16:55 noncom: dbasch: thanks!

17:12 raspasov: hi everyone

18:21 onielfa: Hello, I have a stupid problem. When trying to use println like (println "Hello") in the REPL, I got a java.lang.NoSuchMethodError. Am I missing something?

18:22 hyPiRion: onielfa: `lein downgrade 2.4.2`

18:23 we're working on it, there's a bug in latest stable =/

18:23 onielfa: hyPiRion: Thanks a lot! I am going to downgrade :)

18:25 hyPiRion: It works now :) Let's continue learning Clojure, thanks!

18:25 hyPiRion: onielfa: no problem =)

20:48 Bronsa: it's kind of unfortunate that disj only works on sets and not on maps

20:59 gfredericks: Bronsa: so (disj {1 2} [1 3]) would return {1 2}?

21:01 Bronsa: gfredericks: yeah, disj and dissoc have the same function signature

21:02 gfredericks: Bronsa: huwhat? dissoc doesn't take a value

21:02 Bronsa: gfredericks: wat

21:04 what I'd like is for disj to be (defn poly-disj [m & args] (apply (if (map? m) dissoc disj) args))

21:06 gfredericks: Bronsa: so then you lose the conj/disj symmetry

21:06 Bronsa: no? the opposite

21:06 gfredericks: the symmetry being the type

21:06 Bronsa: right now disj only works on sets

21:06 gfredericks: ,(defn poly-disj [m & args] (apply (if

21:06 (map? m) dissoc disj) args))

21:06 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

21:06 raspasov_: yea conj works on everything

21:06 gfredericks: ,(defn poly-disj [m & args] (apply (if (map? m) dissoc disj) args))

21:06 clojurebot: #'sandbox/poly-disj

21:07 gfredericks: ,(-> {} (conj [1 2]) (disj [1 2]))

21:07 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentArrayMap cannot be cast to clojure.lang.IPersistentSet>

21:07 gfredericks: ,(-> {} (conj [1 2]) (poly-disj [1 2]))

21:07 clojurebot: [1 2]

21:08 gfredericks: ,(-> #{} (conj [1 2]) (ploy-disj [1 2]))

21:08 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: ploy-disj in this context, compiling:(NO_SOURCE_PATH:0:0)>

21:08 gfredericks: ,(-> #{} (conj [1 2]) (poly-disj [1 2]))

21:08 clojurebot: [1 2]

21:08 gfredericks: wat

21:08 ,(defn poly-disj [m & args] (apply (if (map? m) dissoc disj) m args))

21:08 clojurebot: #'sandbox/poly-disj

21:08 gfredericks: ,(-> {} (conj [1 2]) (poly-disj [1 2]))

21:08 clojurebot: {1 2}

21:08 gfredericks: ,(-> #{} (conj [1 2]) (poly-disj [1 2]))

21:08 clojurebot: #{}

21:08 gfredericks: Bronsa: ^ that is the mismatch I'm referring to

21:09 (had to fix a boog in your poly-disj)

21:09 Bronsa: yeah sorry for the typo :(

21:10 gfredericks: I honestly don't see how what you're trying to say

21:10 sticking a key/value pair in a disj doesn't make any sense

21:10 gfredericks: wrt sets, conj and disj are opposites

21:10 conj takes a thing to add, disj takes a thing to remove

21:10 wrt maps, conj and poly-disj are not opposites in that sense

21:10 conj takes a PAIR to add, poly-disj takes a KEY to remove

21:12 Bronsa: gfredericks: different operations take different inputs

21:13 by your point dissoc is not the opposite of assoc

21:13 gfredericks: I might be imagining and intended pairing of conj and disj

21:13 an*

21:14 Bronsa: gfredericks: yeah, disj right now has definitely nothing to do with conj, the latter being highly polymorphic while the former being defined only on sets

21:14 gfredericks: the names seem related

21:14 and "defined only on sets" always made sense to me as being the only context where it could be defined

21:14 amalloy: Bronsa: i don't really agree: disj and conj seem to me like they're intended to be inverses

21:15 gfredericks: amalloy! thank goodness you're here!

21:15 amalloy: if disj worked on maps i'd expect it to work like gfredericks's version, not yours

21:15 or, probably, to require an actual MapEntry

21:16 gfredericks: eh, conj takes a vector pair

21:16 amalloy: gfredericks: yeah, but the mapentry didn't exist yet. it's plausible that disj on the map would only remove entries which are in the map

21:17 gfredericks: does java-style never involve creating map entries before adding them to maps?

21:18 amalloy: i can't think of an instance of that, but maybe

21:18 gfredericks: amalloy: in any case do you have a less hand-wavey argument for this than I do, or is it just "they seem like inverses"?

21:18 Bronsa: amalloy: gfredericks it had never crossed my mind that (disj {} [k v]) might make sense, and I still don't think it does but point taken

21:19 I still wish there was a function that behaved like poly-disj, whichever its name

21:19 amalloy: no, i have nothing concrete

21:19 gfredericks: amalloy: at least there's two of us

21:20 amalloy: Bronsa: you can create that function, of course, with protocols. i'm sure you know that; are you hoping for it to be in core instead?

21:20 Bronsa: amalloy: yeah I meant in core

21:23 `remove-keys` maybe

21:24 amalloy: Bronsa: you could even call it `without`, like the java method on maps

21:24 (-> my-set (without x y z))

21:25 er, i guess i meant the method on sets

21:25 Bronsa: yeah without is probably better. remove-keys might suggest an association with select-keys, which only works on maps

22:56 wei: what’s a good way to pass data between two clojure processes? redis/carmine?

23:00 bbloom: wei: dramatically more information needed

23:04 wei: bbloom: good point. i have one process that controls multiple processes. the child processes are interchangeable and can start and stop unpredictably. requirements are that the messages be encrypted and durable across restarts. tangentially related, I recall Rich’s Language of the System talk had some great principles but he didn’t have time to cover how to implement such a system in Clojure

23:05 bbloom: are the processes on one box or distributed across several?

23:14 wei: bbloom: would it significantly change the design?

23:15 bbloom: wei: you can use the file system or you can use the network

23:15 wei: why do you need encryption?

23:15 wei: why do you need durability?

23:15 you asked a reeeaaaallly general (and difficult) question

23:15 wei: thanks for humoring me :)

23:16 bbloom: maybe talk about your high level goal a bit

23:18 wei: haha, this reminds me of a previous conversation where you said, “guaranteed deliverability is a lie”

23:18 bbloom: wei: i would have reminded you of that :-P

23:20 wei: reading up on some design now.. i’ll come back later with more specific questions :)

23:21 vanila: hi

23:21 https://www.youtube.com/watch?v=f84n5oFoZBc

23:21 Hammock Driven Development - Rich Hickey

Logging service provided by n01se.net