#clojure log - Aug 22 2015

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

1:22 mcktrtl: how do I share preconditions from two different functions?

1:25 domokato_: is there a function that given a collection returns a new empty collection of the same type?

1:30 nevermind

1:41 amalloy: mcktrtl: how would you usually share code in general, between two different functions?

1:41 mcktrtl: put the shared code in a third function

1:42 amalloy: so, why can't you do that here?

1:43 write a function that your precondition calls

1:43 mcktrtl: i'm not sure, i think i'm confused with how the {:pre [] :post []} maps work

2:56 dagda1_: I have this binary tree https://gist.github.com/dagda1/499772c530244dcd935f that I'm using to solve this problem https://www.hackerrank.com/challenges/swap-nodes

2:56 I need to add the ability to swap nodes does anyone have any high level advice on how I might achieve this?

4:06 hiredman: /win 17

4:06 jeaye: invalid window number: 17

5:33 thealpine: Hello!

7:09 expez: Bronsa: Do you have some ballpark idea (this year?) when you'll bring t.a.js up to date? We want to use it to add cljs support to clj-refactor.

7:33 pepijndevos: If I want to split a multimethod and its implementation, which files should include which?

7:34 The implementation needs the definition, but the user also needs to load the implementations.

7:34 justin_smith: pepijndevos: a multimethod definition should be in a file with as few deps as possible

7:35 that ns should be required by both the code using the methods, and the code implementing them

7:35 the latter two namespaces should have nothing to do with one another, other than both referring to the multimethod def

7:37 (and the fact that your app code would require both of course)

7:44 pepijndevos: ok, thanks

7:44 clojurebot: Cool story bro.

7:45 justin_smith: pepijndevos: and of course it is totally legit to put the multimethod definition and impl in completely different libraries

7:45 (if the design calls for it of course)

7:46 pepijndevos: justin_smith but if I put the def in one, the impl in another, {requiring the def), and the usage in yet another (requiring the def), nothing requires the impl, so I think the usage should require that too?

7:47 justin_smith: pepijndevos: oh, yeah, of course

7:47 the whole structure is like a diamond - app at top, def at bottom, impl on one side

7:47 triangle, something

7:47 pepijndevos: right

7:47 justin_smith: I think you get the idea

7:48 but the more fleshed out version is like a diamond

7:48 def at bottom

7:48 some lib that uses an impl on one side

7:48 some concrete impl on the other side

7:48 no connection between those two

7:48 pepijndevos: Mine is probably more like a hairball. haha

7:48 justin_smith: app at the top bringing the two together

7:50 pepijndevos: concrete example - ring itself doesn't have any need to know http-kit's impl or composure. http-kit and composure are also fully independent, though each builds on a different side of ring. finally your app requires compojure and http-kit and ring and brings it all together

7:50 pepijndevos: that's protocols not multimethods, but it's the same design shape

7:50 pepijndevos: right

8:20 lokien_: Hey, why can't I just (map (+) [1 2 3]) and have to use reduce instead? Is map different from haskell one?

8:24 wink: lokien_: sounds like an arity problem to me

8:24 justin_smith: lokien_: (+) does not return a function

8:24 ,(+)

8:24 clojurebot: 0

8:24 justin_smith: ,(map + [1 2 3])

8:24 clojurebot: (1 2 3)

8:25 lokien_: wink: I see there are unnecessary parens here, but map version returns [1 2 3] instead of 6

8:25 Yes, this

8:25 justin_smith: lokien_: map is not different from haskell's map, but () is different from haskell's ()

8:25 wink: lokien_: my bad for phrasing it. but you could map a "+ 1" function, so to say.

8:25 justin_smith: lokien_: not unnecessary, but probably unwanted (and definitely error causing)

8:25 wink: what justin_smith said :)

8:26 lokien_: Wait a minute, I'll try it

8:27 wink: I still think map'ing a + doesnt# make sense. or I am too much into clojure and not other functional languages

8:27 lokien_: ,(map #(+ % 1) [1 2 3])

8:27 clojurebot: (2 3 4)

8:27 lokien_: So I guess I have to do it that way

8:28 justin_smith: wink: it's weird, but it's possible

8:28 ,(map + [1 2 3] [4 5 6]) ; wink

8:28 clojurebot: (5 7 9)

8:28 wink: lokien_: well, did you actually want to calculate 1 + 2 + 3 ?

8:28 justin_smith: not what I meant.

8:28 lokien_: wink: kinda

8:28 wink: yeah, I'd file that into reduce and it surprises me to do that via map at all. in any language

8:29 but I could be very wrong :)

8:29 lokien_: It's just that prefix notation of lisps

8:29 Gets me confused every time

8:29 justin_smith: lokien_: also haskell doesn't do multiple arities, and we do it extensively

8:29 ,(> 3 2 1 -21)

8:29 clojurebot: true

8:30 lokien_: justin_smith: that's why I'm cheating on her with clojure

8:30 justin_smith: haha

8:31 lokien_: justin_smith: I can't do anything if any other language has small breasts or something, here I can just create a macro for it

8:31 justin_smith: lokien_: clojure is the fun, easygoing, though maybe at times unreliable one

8:32 haskell is marriage material, but sometimes a pain in the ass

8:32 lokien_: justin_smith: unreliable, you mean?

8:32 justin_smith: lokien_: no type checking

8:32 lokien_: functions that just pass your junk data to some other function, with no attempt to check for validity

8:33 lokien_: justin_smith: can I check this somehow?

8:33 justin_smith: stack traces that go 30 frames deep because finally someone found nil that was introduced at the top

8:33 lokien_: you can, but clojure's internals don't usually

8:33 lokien_: it's a joke, I love clojure, but it definitely doesn't do much to anticipate errors or validate data

8:34 lokien_: justin_smith: static languages are a pain in the ass when you want to add new stuff to them, or modify them

8:34 justin_smith: lokien_: right, this is the tradeoff I was trying to joke about

8:35 lokien_: Like random function in haskell would produce IO.Integer or some other stuff and I have to exploit it every time I want to use it

8:35 justin_smith: lokien_: clojure lets you get away with a lot more - but sometimes you pay the price that it will let you do something very stupid

8:35 lokien_: God damn it, it's just an integer

8:35 justin_smith: right

8:35 haha

8:35 lokien_: Thanks for help, have an awesome day

8:35 justin_smith: you too

9:13 bodie_: I'm trying to figure out the syntax for this. I have a fn f of two items and a vector of vectors of two items v. how do I map f over v such that f will be called with the contents of each vector, resulting in a vector of the results?

9:16 `map` isn't what I need, since it applies to the first element of each vector, then the second element, etc. what I want is basically the opposite of that.

9:17 I guess I'm asking a dumb question or something, but I can't seem to figure out how to hunt down the answer to this.

9:18 justin_smith: ,(map #(apply + %) [[1 2] [3 4]]) ; bodie_ - something like this?

9:18 clojurebot: (3 7)

9:18 bodie_: yes

9:18 thanks justin_smith :)

9:18 justin_smith: ,(map + (map list [[1 2] [3 4]])) ; alternately

9:18 clojurebot: #<ClassCastException java.lang.ClassCastException: Cannot cast clojure.lang.PersistentList to java.lang.Number>

9:18 justin_smith: err

9:19 bodie_: hmm, weird. I was using map with apply, but I wasn't getting what I expected

9:19 justin_smith: ,(apply map + (map list [[1 2] [3 4]])) ; alternately

9:19 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.Number>

9:19 justin_smith: something like thus

9:20 haha, the original is the right way, anyway, the other way is silly even if I get it right

9:24 Wild_Cat: what kind of text generation/formatting do you guys use? I'm playing around with Clojure code that generated C++ and doing everything with (str ...) calls sort of feels inelegant.

9:25 justin_smith: Wild_Cat: there's format of course, and clojure.pprint/cl-format

9:32 Wild_Cat: justin_smith: oh, that one looks powerful

9:36 justin_smith: Wild_Cat: yeah, cl-format can do amazing things

9:36 Wild_Cat: now to handle indentation... :p

9:39 ...or maybe I should just defer code formatting until a later phase. I'll sleep on it.

9:39 justin_smith: there's always the "shell call to emacs" method

9:40 or one of the single-purpose C auto-formatters

9:40 I assume they have ones that can do C++

9:41 Wild_Cat: could be. C++ is a pain in the ass to autoformat, what with both the preprocessor and the templates being Turing-complete

9:41 but since I'm just emitting a subset of C++ (one that unfortunately uses templates, though) maybe I could get away with it.

9:41 justin_smith: C++ templates are the weirdest macro system ever I swear

9:42 Wild_Cat: the entire language is terribly inelegant, really. The solution to *everything* is text substitution.

9:46 justin_smith: Wild_Cat: I imagine as a lisper using macro systems and higher order programming in other languages, I know what it must be like to be an Italian visiting the American midwest and someone taking you to like little ceasars for pizza.

9:47 "I mean I guess I understand on an abstract level that these things are in the same category, but this version makes me very sad"

9:51 Wild_Cat: justin_smith: in all fairness I'm a Clojure noob.

9:51 my weapon of choice has been Python for quite a long time

9:52 but Clojure's focus on immutability, smart datastructures and powerful parallelism/concurrency facilities are convincing me to switch

10:19 hyPiRion: is there any edn test suite anywhere?

11:33 lvh: oh hello willb

11:33 Oh, Wild_Cat is gone already.

12:24 Bronsa: expez: I'm sorry, I can't promise anything. cljs had big changes in the last year so getting t.a.js up to date with that won't be a small task and I don't know when I'll have the time to do that

13:33 sobel: does anyone know of nginx-clojure in production somewhere? http://nginx-clojure.github.io/index.html

15:47 expez: how can I catch and adorn an exceptioninfo with more data?

15:49 What I'm doing now is catching it, grabbing ex-data, then calling ex-info passing .getMessage and associng new stuff onto data

15:49 this seems like more work than what's intended

15:53 justin_smith: ,(try (throw (ex-info "OK" {})) (catch clojure.lang.ExceptionInfo e (throw (ex-info (.getMessage e) (assoc (.getData e) :also "WAT")))))

15:53 clojurebot: justin_smith: excusez-moi

15:53 justin_smith: :P

15:54 expez: you could also make a new ex-info and throw the new one you caught into the ex-data

15:54 and let the top level decide whether to pull out the insides

15:55 expez: it seems like a "add to ex-info and re-throw" would be an easy function to write though

15:55 expez: justin_smith: yeah I ended up doing exactly what you proposed

16:12 dagda1_: I've got this code https://gist.github.com/dagda1/499772c530244dcd935f that creates a tree, I need the nodes of a tree in order to solve this puzzle https://www.hackerrank.com/challenges/swap-nodes

16:12 I'm not entirely sure how I go about swapping the nodes at a given depth

16:17 RasHasGul: can redefine a function in Clojure without restarting the application?

16:17 +you

16:17 justin_smith: RasHasGul: yes

16:18 RasHasGul: justin_smith: I don't know clojure, but do you know where can I read about this?

16:19 justin_smith: RasHasGul: you redefine a function the same way you define it

16:19 so, usually using defn (or indirectly by requiring some file that calls defn)

16:19 RasHasGul: justin_smith: and how will the application will use this modified definition without restarting it?

16:20 justin_smith: RasHasGul: because the functions are not usually inlined

16:20 the next time you call the function, the newer definition is found

16:22 RasHasGul: are you a java programmer?

16:22 RasHasGul: justin_smith: so in the clojure repl I just change the body of a function and the application will start using the new definition?

16:22 justin_smith: no

16:22 justin_smith: but I'm familiar with it

16:23 justin_smith: RasHasGul: right, you can call defn again, and the new definition will be used

16:23 RasHasGul: the reason I ask is that unlike java where you compile some class, and that class is loaded and you call a method on that class...

16:23 in clojure we have a special class - clojure.lang.Var, and most clojure code will try to find the Var instance that holds the thing you want

16:24 when you use def or defn, you are changing the contents of (and potentially creating anew) some var

16:26 RasHasGul: ok cool, so this is done live, clojure compiles the modified defn to bytecode on fly and injects it on to the app right?

16:29 justin_smith: RasHasGul: exactly

16:29 RasHasGul: in fact doing this at runtime in an app, defining things at load, and defining things in a repl all work exactly the same way

16:29 which is very helpful for interactive development

16:32 RasHasGul: yeah very nice, is real live in the literal sense, you don't have to throw away your data or restart your app when modifying a procedure

16:32 justin_smith: exactly

16:32 RasHasGul: sometimes we need to use tricks when it comes to scope closure

16:32 RasHasGul: Racket is not like this :/

16:32 justin_smith: where a function isn't using a var by name, but it is instead defined based on some anonymous argument

16:33 RasHasGul: emacs is though :)

16:33 justin_smith: clojure isn't quite as free and easy with redefinitions as emacs

16:33 but comes close

16:34 RasHasGul: justin_smith: ah, so its not all smooth sailing, what tricks you talk about?

16:35 justin_smith: RasHasGul: for example when starting the ring web server, you are expected to pass a function as the argument

16:35 just because the function is redefined, doesn't mean ring is using the new version, so you can hack it by passing in the var holding the function instead

16:36 when you call a var as if it were a function, it automatically looks up its contents and tries calling it

16:36 ,(= #'+ +)

16:36 clojurebot: false

16:36 justin_smith: ,(type #'+)

16:36 clojurebot: clojure.lang.Var

16:36 justin_smith: ,(#'+ 2 3)

16:36 clojurebot: 5

16:37 RasHasGul: justin_smith: so you mean that instead of passing an anonymous function to ring web server you pass it a named function instead? to be able to redefine it

16:38 justin_smith: RasHasGul: not quite - one moment, I wrote a stack overflow answer that shows how this works

16:40 RasHasGul: this SO answer shows how it works http://stackoverflow.com/questions/28904260/dynamic-handler-update-in-clojure-ring-compojure-repl/28905078#28905078

16:48 tl;dr it's not just that the arg needs to be named - when capturing something to call later, you need to capture the var and not the function the var points to in order to see updates

16:51 RasHasGul: justin_smith: I see, so is just that existing code won't use the modified defnitions until you do the trick you showed in SO

16:55 rhg135: when you pass the plain function, it's just it's current definition. if you pass a var it's a refernce to it essentially

16:56 an endowed one, but 'tis mutable

17:00 RasHasGul: oh I get it, didn't understand the #'foo part in the SO example

17:01 justin_smith: ,'#'foo

17:01 clojurebot: (var foo)

17:01 justin_smith: it's just a reader macro

17:38 google isn't helping me much - I wonder if anyone is making anything like mirage that clojure could use - maybe porting the jvm to a rump kernel

17:39 I ask because it would be awesome to run clojure this way http://www.skjegstad.com/blog/2015/08/17/jitsu-v02/

17:52 rhg135: openjdk zero shouldn't be too hard to build for rump

17:53 justin_smith: rhg135: instant spin-up on-demand clojure apps would be awesome

17:53 rhg135: they would be

17:56 justin_smith: rhg135: ooooh looks like OSv might be close to this http://events.linuxfoundation.org/sites/events/files/slides/OSv_ACEU14.pdf

17:59 rhg135: some processors can run java bytecode, I would have expected that to be chaper

17:59 * rhg135 shrugs

18:04 futuro: I'm looking for a semi-robust way to deal with xml schemas -- specifically it is Wikimedia dumps -- and I'm curious how people handle data type translation from xml files

18:05 That is, if there's a schema defining the types inside an xml file, do folks normally enter/define this by hand in their code, or is there a clean way to read xsd files to generate this for you?

18:05 I'm currently searching the web, but I thought I'd ask here as well

18:05 mcktrtl: might anyone be able to suggest a project where metadata is used in an interesting way?

18:11 futuro: mcktrtl: what do you mean by "interesting"?

18:13 mcktrtl: anything past private/public, docstrings, and how the project "dire" works... im just curious to look at any other applications

19:47 amalloy: most interesting usages of metadata are "clever", not good

19:48 mcktrtl: interesting things in general usually are :)

20:40 rhg135: "interesting" hardly ever means good

20:41 not in code at least :(

21:22 RasAsGhul: justin_smith: ping

21:22 android1: hi

22:38 WickedShell: I'm having trouble importing java classes (specifically anything from the java.awt.geom package other things from java.awt work but (:import java.awt.geom.Rectangle2D.Float) fails to find the class every time. Any way to figure out why this is happening? (Before I restarted the REPL with the changes saved to disk (:import 'java.awt.geom.Rectangle2D.Float) worked without a problem in the REPL

22:39 justin_smith: ,(:import 'it.doesnt.Matter.what.you.put.here.but.it.doesnt.do.what.you.Think)

22:39 clojurebot: nil

22:40 WickedShell: ahhh well that explains that bit :P

22:40 justin_smith: outside the ns special form you want import not :import

22:40 WickedShell: yeah was thinking that as I typed it in here actually

22:40 justin_smith: ,(import java.util.HashMap)

22:40 clojurebot: java.util.HashMap

22:41 justin_smith: also you don't want the '

22:41 WickedShell: I thought the ' was needed in the REPL?

22:41 justin_smith: namespaces need it because they are not bound to anything when you call require

22:41 when you call import, the name of the class resolves to tell it what class to import

22:42 import is not a pre-requisite to using a class - they are automatically resolved and loaded - it's a convenience though

22:43 WickedShell: If I don't import first (in the past) things fail to compile with lein (at least that was the error I recall getting and importing solved it)

22:43 justin_smith: WickedShell: if you don't use import, you need to fully type out the package every time

22:43 that's the only difference

22:44 WickedShell: oh.. yeah that makes sense lol

22:44 justin_smith: the real magic happens in setting up your classpath, which lein does

22:44 then symbols are looked up in the classpath

22:46 WickedShell: Is there a way to see in the REPL if it can resolve an object? I can't figure out why I can't find java.awt.geom.RoundRectangle2D.Float when I have a straight java program that is finding it without any problem

22:47 justin_smith: WickedShell: you can just type in the class name

22:47 ,java.util.HashMap

22:47 clojurebot: java.util.HashMap

22:47 justin_smith: ,java.util.ThisDoesNotExist

22:47 clojurebot: #error {\n :cause "java.util.ThisDoesNotExist"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.ClassNotFoundException: java.util.ThisDoesNotExist, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.ClassNotFoundException\n :message "java.util.ThisDoesNotExist"\n :at [java.net.URLClassLoader$1 run "U...

22:47 WickedShell: ,java.awt.geom.RoundRectangle2D.Float

22:47 clojurebot: #error {\n :cause "java.awt.geom.RoundRectangle2D.Float"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.ClassNotFoundException: java.awt.geom.RoundRectangle2D.Float, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.ClassNotFoundException\n :message "java.awt.geom.RoundRectangle2D.Float"\n :at [ja...

22:48 WickedShell: ,java.awt.geom.RoundRectangle2D

22:48 clojurebot: java.awt.geom.RoundRectangle2D

22:48 WickedShell: ooohhh I think I tripped over the java side of it...

22:48 justin_smith: ,java.awt.geom.RoundRectangle2D$Float ; maybe it is an inner class

22:48 clojurebot: java.awt.geom.RoundRectangle2D$Float

22:48 justin_smith: it is!

22:48 there's your answer

22:50 WickedShell: justin_smith, yup tripped over that... Thanks for your help!

Logging service provided by n01se.net