2015-08-22
| 01:22 | mcktrtl | how do I share preconditions from two different functions? |
| 01:25 | domokato_ | is there a function that given a collection returns a new empty collection of the same type? |
| 01:30 | domokato_ | nevermind |
| 01:41 | amalloy | mcktrtl: how would you usually share code in general, between two different functions? |
| 01:41 | mcktrtl | put the shared code in a third function |
| 01:42 | amalloy | so, why can't you do that here? |
| 01:43 | amalloy | write a function that your precondition calls |
| 01:43 | mcktrtl | i'm not sure, i think i'm confused with how the {:pre [] :post []} maps work |
| 02: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 |
| 02:56 | dagda1_ | I need to add the ability to swap nodes does anyone have any high level advice on how I might achieve this? |
| 04:06 | hiredman | /win 17 |
| 04:06 | jeaye | invalid window number: 17 |
| 05:33 | thealpine | Hello! |
| 07: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. |
| 07:33 | pepijndevos | If I want to split a multimethod and its implementation, which files should include which? |
| 07:34 | pepijndevos | The implementation needs the definition, but the user also needs to load the implementations. |
| 07:34 | justin_smith | pepijndevos: a multimethod definition should be in a file with as few deps as possible |
| 07:35 | justin_smith | that ns should be required by both the code using the methods, and the code implementing them |
| 07:35 | justin_smith | the latter two namespaces should have nothing to do with one another, other than both referring to the multimethod def |
| 07:37 | justin_smith | (and the fact that your app code would require both of course) |
| 07:44 | pepijndevos | ok, thanks |
| 07:44 | clojurebot | Cool story bro. |
| 07:45 | justin_smith | pepijndevos: and of course it is totally legit to put the multimethod definition and impl in completely different libraries |
| 07:45 | justin_smith | (if the design calls for it of course) |
| 07: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? |
| 07:47 | justin_smith | pepijndevos: oh, yeah, of course |
| 07:47 | justin_smith | the whole structure is like a diamond - app at top, def at bottom, impl on one side |
| 07:47 | justin_smith | triangle, something |
| 07:47 | pepijndevos | right |
| 07:47 | justin_smith | I think you get the idea |
| 07:48 | justin_smith | but the more fleshed out version is like a diamond |
| 07:48 | justin_smith | def at bottom |
| 07:48 | justin_smith | some lib that uses an impl on one side |
| 07:48 | justin_smith | some concrete impl on the other side |
| 07:48 | justin_smith | no connection between those two |
| 07:48 | pepijndevos | Mine is probably more like a hairball. haha |
| 07:48 | justin_smith | app at the top bringing the two together |
| 07:50 | justin_smith | 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 |
| 07:50 | justin_smith | pepijndevos: that's protocols not multimethods, but it's the same design shape |
| 07:50 | pepijndevos | right |
| 08:20 | lokien_ | Hey, why can't I just (map (+) [1 2 3]) and have to use reduce instead? Is map different from haskell one? |
| 08:24 | wink | lokien_: sounds like an arity problem to me |
| 08:24 | justin_smith | lokien_: (+) does not return a function |
| 08:24 | justin_smith | ,(+) |
| 08:24 | clojurebot | 0 |
| 08:24 | justin_smith | ,(map + [1 2 3]) |
| 08:24 | clojurebot | (1 2 3) |
| 08:25 | lokien_ | wink: I see there are unnecessary parens here, but map version returns [1 2 3] instead of 6 |
| 08:25 | lokien_ | Yes, this |
| 08:25 | justin_smith | lokien_: map is not different from haskell's map, but () is different from haskell's () |
| 08:25 | wink | lokien_: my bad for phrasing it. but you could map a "+ 1" function, so to say. |
| 08:25 | justin_smith | lokien_: not unnecessary, but probably unwanted (and definitely error causing) |
| 08:25 | wink | what justin_smith said :) |
| 08:26 | lokien_ | Wait a minute, I'll try it |
| 08:27 | wink | I still think map'ing a + doesnt# make sense. or I am too much into clojure and not other functional languages |
| 08:27 | lokien_ | ,(map #(+ % 1) [1 2 3]) |
| 08:27 | clojurebot | (2 3 4) |
| 08:27 | lokien_ | So I guess I have to do it that way |
| 08:28 | justin_smith | wink: it's weird, but it's possible |
| 08:28 | justin_smith | ,(map + [1 2 3] [4 5 6]) ; wink |
| 08:28 | clojurebot | (5 7 9) |
| 08:28 | wink | lokien_: well, did you actually want to calculate 1 + 2 + 3 ? |
| 08:28 | wink | justin_smith: not what I meant. |
| 08:28 | lokien_ | wink: kinda |
| 08:28 | wink | yeah, I'd file that into reduce and it surprises me to do that via map at all. in any language |
| 08:29 | wink | but I could be very wrong :) |
| 08:29 | lokien_ | It's just that prefix notation of lisps |
| 08:29 | lokien_ | Gets me confused every time |
| 08:29 | justin_smith | lokien_: also haskell doesn't do multiple arities, and we do it extensively |
| 08:29 | justin_smith | ,(> 3 2 1 -21) |
| 08:29 | clojurebot | true |
| 08:30 | lokien_ | justin_smith: that's why I'm cheating on her with clojure |
| 08:30 | justin_smith | haha |
| 08: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 |
| 08:31 | justin_smith | lokien_: clojure is the fun, easygoing, though maybe at times unreliable one |
| 08:32 | justin_smith | haskell is marriage material, but sometimes a pain in the ass |
| 08:32 | lokien_ | justin_smith: unreliable, you mean? |
| 08:32 | justin_smith | lokien_: no type checking |
| 08:32 | justin_smith | lokien_: functions that just pass your junk data to some other function, with no attempt to check for validity |
| 08:33 | lokien_ | justin_smith: can I check this somehow? |
| 08:33 | justin_smith | stack traces that go 30 frames deep because finally someone found nil that was introduced at the top |
| 08:33 | justin_smith | lokien_: you can, but clojure's internals don't usually |
| 08:33 | justin_smith | lokien_: it's a joke, I love clojure, but it definitely doesn't do much to anticipate errors or validate data |
| 08:34 | lokien_ | justin_smith: static languages are a pain in the ass when you want to add new stuff to them, or modify them |
| 08:34 | justin_smith | lokien_: right, this is the tradeoff I was trying to joke about |
| 08: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 |
| 08: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 |
| 08:35 | lokien_ | God damn it, it's just an integer |
| 08:35 | justin_smith | right |
| 08:35 | justin_smith | haha |
| 08:35 | lokien_ | Thanks for help, have an awesome day |
| 08:35 | justin_smith | you too |
| 09: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? |
| 09:16 | bodie_ | `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. |
| 09:17 | bodie_ | 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. |
| 09:18 | justin_smith | ,(map #(apply + %) [[1 2] [3 4]]) ; bodie_ - something like this? |
| 09:18 | clojurebot | (3 7) |
| 09:18 | bodie_ | yes |
| 09:18 | bodie_ | thanks justin_smith :) |
| 09:18 | justin_smith | ,(map + (map list [[1 2] [3 4]])) ; alternately |
| 09:18 | clojurebot | #<ClassCastException java.lang.ClassCastException: Cannot cast clojure.lang.PersistentList to java.lang.Number> |
| 09:18 | justin_smith | err |
| 09:19 | bodie_ | hmm, weird. I was using map with apply, but I wasn't getting what I expected |
| 09:19 | justin_smith | ,(apply map + (map list [[1 2] [3 4]])) ; alternately |
| 09:19 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.Number> |
| 09:19 | justin_smith | something like thus |
| 09:20 | justin_smith | haha, the original is the right way, anyway, the other way is silly even if I get it right |
| 09: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. |
| 09:25 | justin_smith | Wild_Cat: there's format of course, and clojure.pprint/cl-format |
| 09:32 | Wild_Cat | justin_smith: oh, that one looks powerful |
| 09:36 | justin_smith | Wild_Cat: yeah, cl-format can do amazing things |
| 09:36 | Wild_Cat | now to handle indentation... :p |
| 09:39 | Wild_Cat | ...or maybe I should just defer code formatting until a later phase. I'll sleep on it. |
| 09:39 | justin_smith | there's always the "shell call to emacs" method |
| 09:40 | justin_smith | or one of the single-purpose C auto-formatters |
| 09:40 | justin_smith | I assume they have ones that can do C++ |
| 09: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 |
| 09:41 | Wild_Cat | but since I'm just emitting a subset of C++ (one that unfortunately uses templates, though) maybe I could get away with it. |
| 09:41 | justin_smith | C++ templates are the weirdest macro system ever I swear |
| 09:42 | Wild_Cat | the entire language is terribly inelegant, really. The solution to *everything* is text substitution. |
| 09: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. |
| 09:47 | justin_smith | "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" |
| 09:51 | Wild_Cat | justin_smith: in all fairness I'm a Clojure noob. |
| 09:51 | Wild_Cat | my weapon of choice has been Python for quite a long time |
| 09:52 | Wild_Cat | 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 | lvh | 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 | expez | 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 | expez | 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 | justin_smith | expez: you could also make a new ex-info and throw the new one you caught into the ex-data |
| 15:54 | justin_smith | and let the top level decide whether to pull out the insides |
| 15:55 | justin_smith | 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 | dagda1_ | 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 | RasHasGul | +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 | justin_smith | 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 | justin_smith | the next time you call the function, the newer definition is found |
| 16:22 | justin_smith | 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 | RasHasGul | justin_smith: no |
| 16:22 | RasHasGul | 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 | justin_smith | 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 | justin_smith | 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 | justin_smith | 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 | justin_smith | 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 | justin_smith | 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 | justin_smith | 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 | justin_smith | 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 | justin_smith | 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 | justin_smith | when you call a var as if it were a function, it automatically looks up its contents and tries calling it |
| 16:36 | justin_smith | ,(= #'+ +) |
| 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 | justin_smith | 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 | justin_smith | 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 | rhg135 | 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 | justin_smith | 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 | justin_smith | 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 |
| 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 | futuro | 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 | futuro | 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 | rhg135 | 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 | justin_smith | when you call import, the name of the class resolves to tell it what class to import |
| 22:42 | justin_smith | 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 | justin_smith | 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 | justin_smith | 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 | justin_smith | ,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 | justin_smith | there's your answer |
| 22:50 | WickedShell | justin_smith, yup tripped over that... Thanks for your help! |