2016-01-20
| 00:13 | irctc | is clojure is a dialect of lisp, what is english language? |
| 00:20 | montanstercat | php |
| 00:30 | TEttinger | irctc: clojure is to some dialects of Scheme, like Racket for example, as english is to Dutch |
| 00:31 | TEttinger | I have a "thematic gibberish" generator, that makes random text that seems like an existing language or a combination of them. it's written in java but was originally a literal one-liner (400+ character line, but one line) in Clojure |
| 00:31 | TEttinger | the english-like stuff it makes is basically dutch |
| 00:31 | TEttinger | it's hard to tell apart |
| 00:35 | irctc | hmmm |
| 03:14 | cenzhe | hi all |
| 03:15 | cenzhe | Having heard of the 1.8 release went out, I tried it with my project, but sadly sees a minor performance drop, instead of a gain because of the direct linking feature |
| 03:16 | cenzhe | is this just me, or it's common among you folks? |
| 03:45 | puredanger | I can't see how it would make things slower although there are certainly many projects where you would not see much change |
| 03:46 | puredanger | Are you comparing 1.7 to 1.8 or 1.8 with and without direct linking |
| 03:48 | cenzhe | it's between 1.7 and 1.8 |
| 03:55 | cenzhe | By minor, in our case, 1.8 will roughly, but consistently be about 3% slower after initial stabilization |
| 03:56 | cenzhe | I haven't done any further profiling to spot the problem, just wonder if other people seeing the same problem |
| 03:58 | TEttinger | what is direct linking? |
| 04:02 | cenzhe | if a fn is direct linked, it does not need to go through the var lookup phase any more to invoke it |
| 04:06 | TEttinger | huh, that slows things down? could it be another change other than direct linking? |
| 04:16 | jonathanj | can't you disable the direct linking feature to see if that is the cause? (it does seem extremely unlikely that direct linking has a negative performance impact) |
| 04:37 | cenzhe | yah, i'm thinking the same |
| 04:37 | cenzhe | good idea to disable direct linking and try again |
| 04:37 | cenzhe | i'll try and report back |
| 04:39 | cenzhe | wow, I thought direct linking was enabled by default |
| 04:40 | cenzhe | I have to add `-Dclojure.compiler.direct-linking=true` in order to use direct linking? |
| 04:40 | amalloy | cenzhe: 3%? that's surely within experimental error. how did you benchmark |
| 04:43 | cenzhe | the way is rudimentary. Within both versions, I run my task 20 times, exclude the first 5 results, and compare the rest |
| 04:47 | cenzhe | my project has a `parallel?` flag indicating whether to pmap things. With parallel off, the stabilized difference can go as wide as 7%. With parallel on, the gap is around 3%, but consistent |
| 04:48 | cenzhe | btw, though i used the word stabilize, the overall response time is still slowly dropping. I guess it's because JIT comes in. |
| 04:50 | cenzhe | if I plot the response time versus experiment index curve, it's slightly sloped down |
| 04:50 | cenzhe | and by consistent, i mean those two curves given by 1.7 and 1.8, the difference between two curves, is consistently around 3% |
| 04:51 | cenzhe | leaving for a while, BRB |
| 05:04 | irctc | Hi. Is this channel right place to ask stupid newbie questions? |
| 05:06 | neoncontrails | irctc: They've always helped me with mine. I say shoot |
| 05:12 | irctc | neoncontrails: I'm working through modern clojurescript tutorial, and trying to write some macros to automate some things. For instance, validate function (validate.cljsc from the gist below). I wrote some macro (my-validate.cljc for the gist below) but my function does not compile. And i don't understand why. The gist: https://gist.github.com/mbakhterev/86c4ac21ced119a5e90c |
| 05:13 | irctc | neoncontrails: The error is: java.lang.IllegalArgumentException: No matching ctor found for class valip.predicates$gt$fn__2332 |
| 05:14 | irctc | neoncontrails: but everything works fine, when i'm trying in repl (apply validate {} (concat (quantity-check))) |
| 05:15 | TEttinger | it appears to be complaining about (gt 0) |
| 05:15 | irctc | TEttinger: Yep. But what exactly is wrong? |
| 05:18 | TEttinger | irctc: are you passing a string to where it expects a quantity? |
| 05:19 | irctc | TEttinger: No. All the parameters to valip predicates should be strings. So i pass only strings |
| 05:20 | TEttinger | what strings are they? I'm wondering if the issue is with the data |
| 05:21 | irctc | TEttinger: It seems not. Because in the repl expression (apply validate {:quantity "10"} (concat (quantity-checks))) works as expected. |
| 05:22 | TEttinger | hmm |
| 05:23 | irctc | TEttinger: it looks like i missunderstand macros |
| 05:23 | TEttinger | I'm not super great with them |
| 05:23 | clojurebot | excusez-moi |
| 05:30 | neoncontrails | I forget how immutable structures work. In Clojure to update a map without returning it, I'd do this |
| 05:30 | neoncontrails | ,(def record (atom {:success [] :failed []})) |
| 05:30 | clojurebot | #'sandbox/record |
| 05:30 | neoncontrails | ,(swap! record update-in [:success] #(cons 'yay %)) |
| 05:30 | clojurebot | {:success (yay), :failed []} |
| 05:31 | neoncontrails | Is that the best way to handle it in clojure too? |
| 05:32 | neoncontrails | Err... sorry. In *cljs I'd declare as an atom, then do etc. |
| 05:40 | jonathanj | they're basically the same language, except one interops with Java and one with JavaScript, so yes that method is still worth considering |
| 06:34 | shaym | anyone using slamhound ? im getting class not found errors when running it |
| 07:28 | cenzhe | reporting back |
| 07:28 | cenzhe | after setting the flag `-Dclojure.compiler.direct-linking=true` |
| 07:29 | cenzhe | the performance drop no longer appears |
| 07:29 | cenzhe | but the performance gain is also negligible, basically less than 1% |
| 07:31 | cenzhe | that means, in my scenario, some other things in 1.8 can cause a slight performance penalty, but this can be made up with the gain introduced by direct linking |
| 08:25 | Guest96152 | best way to get the value of of a symbol in a tupple? so '(my value is x) where x is a symbol, but I want x's value |
| 08:48 | cenzhe | Guest96152: what is known? the position of 'x, or the name will always be 'x? |
| 08:59 | beaky | hello |
| 09:05 | powered | good day |
| 09:06 | Bronsa` | cenzhe: did you try any of the 1.8 alphas/betas? would be interesting to understand where that slowdown was introduced |
| 09:08 | cenzhe | not yet, only the two major versions |
| 09:09 | cenzhe | I'll try testing some other interim versions when I got some time |
| 09:36 | pseudonymous | I was hoping anyone remembers/knows how to change the ns of one's REPL. I have a lein project and always start in dev/user.clj (which is fine), I just want to hop to another file/ns on occasion |
| 09:39 | cenzhe | (in-ns 'your-namespace) |
| 09:40 | pseudonymous | cenzhe: ah, of course, thank you :) |
| 09:53 | Kamuela | completely forgot how I installed clojure so now I’m not sure of my upgrade path |
| 10:09 | sdegutis | ,(remove #{:bar} #{:foo :bar :quux}) ;; Apparently this works. |
| 10:09 | clojurebot | (:foo :quux) |
| 10:09 | sdegutis | Pretty cool if you ask me. |
| 10:09 | sdegutis | Saying "remove this set from this other set." |
| 10:10 | sdegutis | It's like clojure.set/difference almost, but more intuitive for the simpler case. |
| 10:10 | sdegutis | Good morning. Hi. |
| 10:51 | sdegutis | Is there plan to integrate Clojure 1.8 Socket REPL into Leiningen. |
| 10:54 | wink | as it was released... yesterday? I think not |
| 10:55 | wink | But feel free to open an issue or PR :) |
| 10:56 | sdegutis | Cool. |
| 10:59 | mynick12345 | hi |
| 11:00 | mynick12345 | heard about clojure. the git hub pulse is low. is this becoming deprecated? |
| 11:00 | egli | mynick12345: haha |
| 11:00 | pbx | mynick12345, i hope you are trolling |
| 11:02 | mynick12345 | ok, so is it one of the big tecnologies for the future? really I'm blind |
| 11:06 | wink | aaw |
| 11:07 | wink | https://github.com/clojure/clojure/pulse vs https://github.com/nodejs/node/pulse |
| 11:08 | wink | it's clearly winning. mynick12345 has a point |
| 11:09 | sdegutis | myguidingstar: Yes. Clojure is becoming deprecated. |
| 11:10 | sdegutis | myguidingstar: In favor of Clojure 1.8. |
| 11:10 | sdegutis | myguidingstar: Please upgrade at my earliest convenient. |
| 11:10 | wink | sdegutis: tab complete is a lie |
| 11:11 | sdegutis | Nooooooooooooooo.com !!! |
| 11:11 | sdegutis | Aww mynick12345 left too. |
| 11:16 | sdegutis | Sorry myguidingstar. Wrong nick. Tab-complete lied to me. |
| 11:22 | alex`` | good troll xd |
| 12:32 | justin_smith | cenzhe: I was just reading the scrollback, has anyone mentioned criterium yet? because I think you need to run things more than 100 times for hotspot to really come into play. Criterium helps with this sort of thing, for microbenchmarks at least. |
| 12:58 | lxsameer | hey folks, is there any thing like ruby's sprockets in clojure |
| 12:58 | ToxicFrog | What are ruby sprockets? |
| 12:59 | justin_smith | sprockets is some library for ruby, related to rails somehow iirc |
| 12:59 | justin_smith | https://github.com/rails/sprockets |
| 13:00 | justin_smith | basically we would use lein plugins (things like lein less, or even lein shell) in clojure land for this sort of thing |
| 13:00 | justin_smith | (usually) |
| 13:04 | lxsameer | justin_smith: thanks man, |
| 13:04 | justin_smith | lxsameer: nothing in the clojure world will be quite as "magic" |
| 13:04 | justin_smith | oh, I alsmot forgot, hlshipp has something too... one moment |
| 13:05 | lxsameer | justin_smith: what do you mean by quite as magic? |
| 13:08 | justin_smith | lxsameer: this is hlshipp's version of sprockets for clojure (clever name) https://github.com/hlship/dieter |
| 13:08 | lxsameer | justin_smith: awesome |
| 13:09 | justin_smith | lxsameer: what I mean is that ruby prefers convention over configuration, and has a lot of implicit / assumed behavior in its frameworks (including sprockets), and clojure libs on the other hand prefer causes of behaviors to be local to the thing they respond to and explicit |
| 13:10 | lxsameer | justin_smith: thanks man I completely got it |
| 13:19 | Kamuela | Ah I think I’ve installed lein through homebrew and I don’t think there’s an update for 1.8 yet |
| 13:21 | hiredman_ | every lein project specifies the version of clojure it wants |
| 13:22 | hiredman_ | the version of clojure you use for your projects is has nothing to do with lein |
| 13:23 | hiredman | this is what specify dependencies looks like https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L45-L57 |
| 13:25 | hiredman | for your projects using lein, you have your own dependnencies specified, and clojure and the version of clojure the projects build should use is included in there |
| 13:33 | lokien_ | hello j-pb_ :D |
| 13:37 | Gregory | I have a noob question, and no one seems home at #clojure-begginers, may I ask it here? |
| 13:38 | beaky | hello |
| 13:38 | beaky | yes ask away :D |
| 13:38 | Gregory | thanks |
| 13:38 | Gregory | Why can I do this: (def i #(identity %)) (-> 'wat' i) But not this: (-> 'wat' #(identity %) ) |
| 13:38 | j-pb_ | lokien_: hey :) |
| 13:39 | lokien_ | j-pb_: I was hunting for you for like a week! |
| 13:39 | j-pb_ | lol sorry, I have a super bad cold |
| 13:40 | j-pb_ | lokien_: what can I help you with ? |
| 13:40 | lokien_ | j-pb_: well, do you feel better now? |
| 13:40 | j-pb_ | kinda ^^ |
| 13:41 | Gregory | Oh DERP i just answered my own question---- (-> 'wat' (#(identity %)) ) |
| 13:41 | justin_smith | Gregory: responded on #clojure-beginners because I saw the question there first |
| 13:41 | Gregory | thanks JS |
| 13:41 | justin_smith | ,'#(identity %) |
| 13:42 | clojurebot | (fn* [p1__25#] (identity p1__25#)) |
| 13:42 | justin_smith | ,(macroexpand-1 '(-> "wat" #(identity %))) |
| 13:42 | clojurebot | (fn* "wat" [p1__50#] (identity p1__50#)) |
| 13:42 | beaky | right you need to surround the #() with an extra parens |
| 13:42 | justin_smith | Gregory: in this channel I can show you the result from the bot, instead of just assuming you trust me :) ^ |
| 13:43 | justin_smith | beaky: or just use identity |
| 13:43 | beaky | ye or that |
| 13:43 | j-pb_ | lokien_: so what's been bugging your ^^? |
| 13:43 | beaky | btw im developing a webapp with clojure |
| 13:43 | justin_smith | cool |
| 13:43 | beaky | but for frontend stuff im used to relying on npm and the build tools with it (like babel and stuff) |
| 13:43 | beaky | does clojure have something for that |
| 13:43 | beaky | or should i do it the node way |
| 13:44 | lokien | j-pb_: that's great! I'll pm you, I don't want to pollute the irc :) |
| 13:44 | j-pb_ | sure |
| 13:44 | justin_smith | beaky: npm for the frontend? so it's a js hosted app and not a webapp? |
| 13:45 | justin_smith | or do you mean it's a cljs app, with node on the backend? |
| 13:45 | beaky | its a clojure webapp with some extra frontend stuff |
| 13:45 | beaky | like babel |
| 13:45 | beaky | (clojure for backend app server) |
| 13:46 | beaky | wow i can use clojure for the browser stuff as well? |
| 13:46 | justin_smith | with clojurescript you can yeah, that's why I was confused why you called it clojure but also you are using node- but I guess you are using node for server side processing of js stuff? |
| 13:47 | justin_smith | with clojurescript we have google's closure compiler built in |
| 14:12 | tos9_ | Hi. Can I get the REPL to not exit on sigint? |
| 14:13 | tos9_ | Hrm it looks like the vanilla REPL doesn't actuall exit, so it must be something else that's ruining that |
| 14:18 | tos9_ | Ah, maybe it's lein repl vs lein run -m clojure.main repl.clj? Is it the former that is setting up signal handling etc.? |
| 14:23 | justin_smith | yeah, lein sets up the signal handling |
| 14:23 | tos9_ | it looks like lein trampoline cljsbuild repl-listen also exits |
| 14:23 | justin_smith | funny that lein repl is now "vanilla" while just running clojure.jar is the special case, lol |
| 14:24 | tos9_ | justin_smith: I meant vs clojurescript in that case :P |
| 14:24 | justin_smith | right, any task but repl will lack that signal handling that repl sets up |
| 14:24 | tos9_ | (But also I'm a noob) |
| 14:24 | tos9_ | A ha. OK. So I guess I want to ask how I can make lein repl get me to a clojurescript repl then? |
| 14:24 | justin_smith | tos9_: clojure.jar or the equivalent, running clojure.main, won't install the interrupt handlers |
| 14:24 | tos9_ | I see https://github.com/cemerick/piggieback but I've had a couple of issues with it |
| 14:24 | tos9_ | justin_smith: /nod |
| 14:25 | justin_smith | tos9_: I guess - you could look into using chestnut / weasel |
| 14:25 | tos9_ | ah cool, I found weasel too |
| 14:25 | tos9_ | justin_smith: OK I'll give that a shot, danke. |
| 14:26 | tos9_ | Oh, one other unrelated question -- how can I get core.async to propagate warnings / "exceptions" if that's what they are |
| 14:26 | tos9_ | e.g. (go (<! completely-does-not-exist)) appears to just block indefinitely |
| 14:27 | hiredman | catch them and propagate them |
| 14:28 | hiredman | although that would be a compiler error |
| 14:29 | hiredman | (if a name doesn't exist you should get a compile time error) |
| 14:30 | tos9_ | hiredman: So this I'm guessing is a clojurescript thing |
| 14:31 | tos9_ | When I call (asdf), I get a WARNING and a TypeError printed |
| 14:31 | tos9_ | when I try to have a channel read from asdf, I get silence. |
| 14:31 | tos9_ | But in a non-clojurescript REPL I thiink that appears to not be the case |
| 14:31 | hiredman | that is likely a bug in the cljs core.async stuff then |
| 14:36 | tos9_ | I'm trying to produce a SSCCE but my clojure is terrible :P -- how come when I run lein repl without a project.clj (hoping to just get a repl I can do stuff at) I don't get access to the clojure stdlib |
| 14:36 | hiredman | tos9_: what do you mean by stdlib? |
| 14:37 | tos9_ | hiredman: (require 'clojure.core.async) -> FileNotFoundException Could not locate clojure/core/async__init.class or clojure/core/async.clj on classpath. |
| 14:37 | hiredman | tos9_: sure |
| 14:37 | hiredman | tos9_: core.async is a separate library that you have to say you want |
| 14:38 | hiredman | it is not distributed in the clojure jar |
| 14:38 | tos9_ | Ah. OK -- I guess that's not true in clojurescript land |
| 14:38 | tos9_ | Because my project.clj for that project doesn't declare it in :dependencies? |
| 14:38 | tos9_ | Or maybe it's a sub dep of cljs-http... that seems more likely. |
| 14:40 | tos9_ | hiredman: Can I specify deps on the CLI if I just want a standalone REPL with pulled in deps to play with for a moment |
| 14:40 | hiredman | no idea, I never use lein without a project |
| 14:41 | tos9_ | Do you just never not have a project? Or do you not use lein when you don't have a project? |
| 14:41 | hiredman | I don't use lein when I don't have a project |
| 14:41 | rhg135 | Tos9_ yes with profiles.clj |
| 14:42 | tos9_ | rhg135: This looks persistent too -- right? |
| 14:42 | tos9_ | I guess that will work. |
| 14:43 | rhg135 | Yeah it's persistent |
| 14:44 | msw | how does one type-tag return type of a function which is documented? (defn tagged ^long [^long x] x) is the correct way to say (tagged) returns long according to fikes & clj 1.8. Now try and add docco. (defn tagged ^long "docstring" [^long x] x) doesn't parse. Is there another way rather than brutally manipulating the meta manually after definition to get a docstring in? |
| 14:45 | msw | heh, keep experimenting. It's (defn tagged "docstring" ^return-tag [...] ...). Thanks for listening to the question ;) |
| 14:54 | tos9_ | :/ OK now I found my actual problem -- so in clojure, for things that take additional options in a map or whatever, is it up to the library to raise errors for unknown keys |
| 14:55 | tos9_ | Or can you use like a destructuring to force the map to only contain keys that you explicitly define |
| 14:55 | terom | tos9_: you can use lein-try for trying out libraries without a project |
| 14:55 | tos9_ | terom: awesome, this looks exactly like waht I was asking for |
| 15:15 | hiredman | destructuring is short hand for pulling a value out of a datastructure and binding it to a name |
| 15:16 | hiredman | for example (get {:foo 1} :foo) |
| 15:16 | hiredman | get doesn't constrain the keys the map can have, it doesn't even throw an error if the map doesn't contain the key you are asking for |
| 15:26 | tos9_ | /nod -- OK, so same as Python. |
| 15:27 | tos9_ | So the answer is "yes" roughly? Specifically my actual issue turned out to be I called (foo {:bar 12}) but it was in fact (foo {:baz 12}) |
| 15:27 | tos9_ | and :bar was just silently meaningless. |
| 15:27 | tos9_ | In Python this would basically be like having an API that took **kwargs, but we try to avoid those for this reason. |
| 15:28 | tos9_ | (Even more specifically, I called: https://github.com/r0man/cljs-http 's http/post, and gave it {:json-parameters {}} rather than {:json-params {}}) |
| 15:29 | pvinis | hello. i have a map that has vectors or vectors as values, and i want to do update-in to conj a vector in one of the vector. can i get a [] as a default value for that conj? |
| 15:29 | hiredman | ,(doc fnil) |
| 15:29 | clojurebot | "([f x] [f x y] [f x y z]); Takes a function f, and returns a function that calls f, replacing a nil first argument to f with the supplied value x. Higher arity versions can replace arguments in the second and third positions (y, z). Note that the function f can take any number of arguments, not just the one(s) being nil-patched." |
| 15:31 | pvinis | a fnil.. |
| 15:31 | pvinis | thanks |
| 16:18 | numberte1 | is there a core function for returning true if every predicate in a collection of predicates returns true for a given value |
| 16:19 | numberte1 | i know you can write this pretty easily wrapping 'every?', but it seems common enough to have a builtin for it |
| 16:19 | justin_smith | (apply every-pred preds) returns a function that returns true if every one in the pred is true |
| 16:19 | numberte1 | justin_smith: ahh, thanks |
| 16:20 | justin_smith | ,(def big-even (apply every-pred [even? (partial < 10000)])) |
| 16:20 | clojurebot | #'sandbox/big-even |
| 16:20 | justin_smith | ,(big-even 10002) |
| 16:20 | clojurebot | true |
| 16:20 | justin_smith | ,(big-even 10001) |
| 16:20 | clojurebot | false |
| 16:20 | justin_smith | ,(big-even 10) |
| 16:20 | clojurebot | false |
| 16:20 | justin_smith | of course if you just know the funcitons you don't need the list or to apply |
| 16:21 | numberte1 | yeah, was just thinking about thank |
| 16:21 | numberte1 | s/thank/that |
| 17:08 | lokien_ | ,(doc every-pred) |
| 17:08 | clojurebot | "([p] [p1 p2] [p1 p2 p3] [p1 p2 p3 & ps]); Takes a set of predicates and returns a function f that returns true if all of its composing predicates return a logical true value against all of its arguments, else it returns false. Note that f is short-circuiting in that it will stop execution on the first argument that triggers a logical false result against the original predicates." |
| 17:36 | WorldsEndless | Do I need to encode java objects as atoms when I pass them from function to function, or are they automatically passed by reference not copy? |
| 17:37 | amalloy | on the JVM, object values are always passed as pointers |
| 17:37 | WorldsEndless | ok |
| 17:40 | justin_smith | amalloy: modulo some hotspot magic, if it proves it can pull it off, in 1.8+ iirc |
| 17:41 | justin_smith | but yeah, that shouldn't affect WorldsEndless 's case at all |
| 17:42 | amalloy | it shouldn't affect any cases at all, ever. i could write, "objects are always passed in a way that is indistinguishable to you from being passed as pointers", but doing that for every statement would get tiring |
| 17:42 | justin_smith | true |
| 17:59 | WickedShell | when I defrecord is there a way I can associate the type hints with the fields directly? IE if I (defrecord foo [^long bar]) when I have a lookup of (.bar inst-of-foo) I still have to type hint that use later (obviously my actual use is with java interop/classes where I need the type to avoid reflections) |
| 18:48 | blake__ | Does Clojurescript "need" the ready function the way Javscript does? I ask because I'm applying stuff to various controls and it's working, and I just realized that it's not inside the ready function. Not sure if this is luck or standards. |
| 18:49 | blake__ | Or maybe a little of both.... |
| 18:51 | justin_smith | blake__: depends - how are you managing the dom? if using jquery, you'll likely need to use .ready, if using one of the react libs it's less often you'll need it |
| 18:54 | blake__ | I'm not really. Managing the DOM, I mean. I'm basically just attaching events to controls which are generated server-side. I am using JQuery to do this, however, which is why I thought about the ready event. |
| 19:02 | justin_smith | blake__: right, thus you are using jquery to manipulate the dom, thus you should be using .ready |
| 19:02 | shoky_ | blake__: you don't need to worry about .ready or equivalent if you just include your <script> at the end of <body> tag. that ensures the initial DOM has already been parsed & built. otherwise, you need .ready if your code touches stuff that's supposed to already be in the DOM |
| 19:05 | blake__ | justin_smith, shoky_: Thanks, guys. |
| 19:05 | schmudde` | I also apply the strategy of placing the JS at the end of the body tag because I don't use jQuery. |
| 19:10 | blake__ | One thing at a time for me: I'm switching a Compojure project to use ClojureScript instead of Javascript. |
| 19:33 | SilverParens | Congrats on 1.8! A quick question, why won't (read-string ":key1 :key2") capture both keys? I'm trying to pass zip-xml/xml-> a sequence of keys to traverse the zipper. |
| 19:33 | justin_smith | SilverParens: read-string returns a value |
| 19:33 | justin_smith | that's two values |
| 19:34 | justin_smith | ,(read-string "[:key1 :key2]") ; one workaround |
| 19:34 | clojurebot | [:key1 :key2] |
| 19:34 | SilverParens | For example, (zip-xml/xml-> root-document :head :meta) should traverse two nests... because two keys were sent |
| 19:34 | justin_smith | sure, then you need to use apply I guess |
| 19:35 | justin_smith | (apply zip-xml/xml-> root-document [:head :meta]) |
| 19:35 | SilverParens | justin_smith: Oh, thanks, let me try that. I had the apply before the read-string |
| 19:35 | justin_smith | there is also read, which uses a bufferedreader iirc, and you can make a bufferedreader out of a string |
| 19:36 | justin_smith | but probably easier to put the keys in a vector and use apply, if that's an option |
| 19:36 | SilverParens | justin_smith: Interesting! I'll give it a shot |
| 19:39 | SilverParens | justin_smith: Indeed, it works! Thanks... |
| 19:40 | SilverParens | I though my issue had to do with the clojure.org point about "The read table is currently not accessible to user programs." (http://clojure.org/reference/reader). What could that be referring to? |
| 19:40 | SilverParens | Do they mean the compiled programs that are running on the JVM? |
| 19:41 | amalloy | a program written by you cannot query or mess with the read table |
| 19:41 | justin_smith | SilverParens: in common lisp you can manipulate the read table in order to make custom data reading behaviors |
| 19:41 | justin_smith | this is something we don't do in clojure, on the otherh and |
| 19:43 | justin_smith | data_readers.clj and the *data-readers* var are the closest we get |
| 19:46 | SilverParens | Interesting. So one couldn't modify the meaning of #, for example. |
| 19:51 | justin_smith | right, and you can't add readers that don't start with # |
| 20:00 | blake__ | Is there a clojure function that returns true? |
| 20:01 | blake__ | I mean, I've got #(or true %), because I'm using it in swap! |
| 20:02 | justin_smith | (constantly true) |
| 20:04 | blake__ | Yeah. Hmm. |
| 20:05 | SilverParens | (identity true) |
| 20:05 | SilverParens | (and) |
| 20:07 | sfz- | SilverParens: I don't quite understand why (and) works for that, care to explain? |
| 20:07 | blake__ | sfz- So that "and true" returns true. |
| 20:08 | sfz- | that seems like it would be the equivalent of (and nil) though |
| 20:08 | justin_smith | but it's not a function |
| 20:08 | justin_smith | (constantly true) is a function, always returns true |
| 20:08 | sfz- | ,(and) |
| 20:08 | blake__ | Yes, but doesn't take a parameter. |
| 20:08 | clojurebot | true |
| 20:08 | justin_smith | blake__: false |
| 20:08 | justin_smith | ,((constantly true) 1 2 3 nil false :whatever) |
| 20:09 | clojurebot | true |
| 20:09 | SilverParens | (and) and (and true) both return true because the and function keeps going from left to right until it reaches a false (upon which it returns a false and stops going to the left), if it doesn't reach a falsey value it returns true, so (and) doesn't reach a falsey value because they're aren't any values at al |
| 20:09 | justin_smith | ,((constantly true)) |
| 20:09 | clojurebot | true |
| 20:09 | justin_smith | SilverParens: right but (and) is not a function |
| 20:09 | sfz- | SilverParens: now I understand, thanks |
| 20:10 | sfz- | ,((and) :a) |
| 20:10 | clojurebot | #error {\n :cause "java.lang.Boolean cannot be cast to clojure.lang.IFn"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.Boolean cannot be cast to clojure.lang.IFn"\n :at [sandbox$eval95 invokeStatic "NO_SOURCE_FILE" 0]}]\n :trace\n [[sandbox$eval95 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval95 invoke "NO_SOURCE_FILE" -1]\n [clojure.lang.Compiler eval "Compiler.java"... |
| 20:10 | blake__ | justin_smith: Aha! Thank you I did not see that. |
| 20:10 | sfz- | ,((and (and)) :a) |
| 20:10 | clojurebot | #error {\n :cause "java.lang.Boolean cannot be cast to clojure.lang.IFn"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.Boolean cannot be cast to clojure.lang.IFn"\n :at [sandbox$eval119 invokeStatic "NO_SOURCE_FILE" 0]}]\n :trace\n [[sandbox$eval119 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval119 invoke "NO_SOURCE_FILE" -1]\n [clojure.lang.Compiler eval "Compiler.ja... |
| 20:10 | justin_smith | (constantly true) is a function, and does what was asked |
| 20:10 | sfz- | ,(and (and) :a) |
| 20:10 | clojurebot | :a |
| 20:10 | sfz- | lol |
| 20:10 | sfz- | sorry for spam |
| 20:11 | ianhedoesit | sfz-: it's always good to mess around locally first if possible and if you think there's something interesting feel free to use clojurebot for some show and tell. |
| 20:11 | justin_smith | also, clojurebot replies to dms |
| 20:12 | sfz- | ianhedoesit: I'll be more conscientious in the future. |
| 20:12 | ianhedoesit | it's not that big of a deal, but the error messages can get somewhat disruptive; especially if there's other conversations going on. |
| 20:28 | sfz- | ACK |
| 20:40 | TimMc | justin_smith: It bugs me that (constantly x) and (complement x) can always be golfed down to (fn [& _] x) and (comp not x), respectively |
| 20:41 | justin_smith | there's more to life than golf! |
| 20:41 | justin_smith | but it's true |
| 20:41 | TimMc | I feel like they're basic enough fns that they should have shorter names. |
| 20:41 | justin_smith | com and con |
| 20:41 | TimMc | Same goes for partial, although that one at least can't be golfed further. |
| 20:42 | justin_smith | p |
| 20:42 | TimMc | I was thinking par. |
| 20:42 | TimMc | complement -> !f ? |
| 20:43 | justin_smith | or even just ! |
| 20:43 | TimMc | ;-) |
| 20:43 | TimMc | Eh, this is why lisps have a reputation for over-terseness. |
| 20:48 | amalloy | but not languages that actually use ! to mean not |
| 20:59 | WickedShell | Is there a way to track down why a dependency is pulled in? I'm curious why mainfold (among other libs) is pulled into my uberjar/compilation process |
| 21:01 | justin_smith | WickedShell: lein deps :tree |
| 21:01 | WickedShell | justin_smith, thanks |
| 21:01 | justin_smith | WickedShell: manifold is likely coming from aleph, if you use that |
| 21:01 | WickedShell | not directly anywhere |
| 21:02 | sfz- | ,(do (defn ! [arg] (complement arg)) ((!(constantly false)) :whatever)) |
| 21:02 | clojurebot | true |
| 21:02 | justin_smith | sfz-: alternately (def ! complement) |
| 21:03 | WickedShell | justin_smith, ah it's from byte-streams, again thanks |
| 21:03 | sfz- | justin_smith: thanks, only been clojuring a couple months |
| 21:03 | justin_smith | sfz-: that's why we're all here, to help each other learn |
| 21:04 | sfz- | justin_smith: appreciated, I'm responsible for a riemann box that's processing ~2.5 million metrics every n seconds... so the help is appreciated. |
| 21:04 | justin_smith | cool |
| 21:05 | sfz- | in the process of building a framework around riemann and learning to program clojure idiomatically as I go |
| 21:05 | sfz- | still a long way to feel comfortable |
| 21:06 | justin_smith | sounds like a cool project though |
| 21:48 | WickedShell | I have to admit, I love how fast I can build my project with clojure 1.8, uberjars went from a 2+ minute thing to <15 seconds |
| 21:48 | justin_smith | yeah, startup and build is faster now for sure |
| 21:49 | puredanger | WickedShell: really? that's pretty big |
| 21:50 | puredanger | probably http://dev.clojure.org/jira/browse/CLJ-703 |
| 21:56 | WickedShell | apparently the human time clock is poor, lein uberjar with 1.8.0 24.58 seconds, 1.7.0 166.86 seconds |
| 22:11 | WickedShell | I do have a question though since swapping to clojure 1.8.0 and using direct linking I get an error during uberjar that I wasn't seeing previously while uberjaring. The builds seem to work correctly, and I don't see it when I do a lein clean; lein repl any idea how to track down what causes http://pastebin.com/7r8Un0nD? |
| 22:12 | justin_smith | woah, that looks like a weird heisenbug I've been seeing since my 1.8 update... |
| 22:12 | justin_smith | "clojure.core.async$fn_handler$reify__4798 cannot be cast to java.util.Iterator" |
| 22:13 | justin_smith | not identical of course, but suspicious that both of these only come up since the 1.8 switch |
| 22:13 | justin_smith | I looked at the relevant code, and there's no way the item I am using iterator methods on is created by core.async |
| 22:14 | justin_smith | (unless I'm reading my code wrong, which I can't rule out completely, ever, of course) |
| 22:14 | WickedShell | I don't even think that error is in my code? But I could bre reasing the stack trace wrong... |
| 22:15 | justin_smith | core.async can be confusing that way, but it probably is in your code |
| 22:15 | WickedShell | I mean everything *appears* to be behaving correctly but I get worried when I see a bug in compilation I can't track down |
| 22:15 | WickedShell | any idea how to find where in my code its getting upset? |
| 22:17 | justin_smith | one moment |
| 22:24 | justin_smith | WickedShell: yeah, definitely no recognizable non-clojure code in that stack trace |
| 22:25 | justin_smith | WickedShell: how many places do you call pub? |
| 22:25 | WickedShell | very few iirc should all be in one place |
| 22:25 | justin_smith | cool, because the error definitely happens in the context of a pub call |
| 22:26 | justin_smith | not that I think your code is causing the problem here... |
| 22:27 | John[Lisbeth] | Is clojure a true, compilable lisp? |
| 22:27 | WickedShell | justin_smith, the one and only place pub is called... http://pastebin.com/ZftPzYhG (obviously the outgoingMessages channel gets put on elsewhere) |
| 22:27 | justin_smith | John[Lisbeth]: does generating byte-code count as compiling? |
| 22:28 | justin_smith | fwiw clojure doesn't have an interpreted mode, every function is always generated as byte code before being run |
| 22:28 | justin_smith | but some people are pickier about what "compile" means |
| 22:29 | justin_smith | clojure doesn't generate machine code, it generates byte code for the jvm (or for clr, or javascript) |
| 22:29 | John[Lisbeth] | I mean x86 |
| 22:29 | justin_smith | no, it does not do anything x86 specific |
| 22:30 | John[Lisbeth] | muh 32 bit |
| 22:39 | TEttinger | John[Lisbeth]: I don't think anyone's made a new Lisp that a) has seen wide use and b) isn't JIT-compiled, in the last at least 10 years. I am fairly sure Racket is JIT compiled, no idea about Arc |
| 22:40 | TEttinger | it seems silly to have repl-based languages require a separate lengthy compile step |
| 22:42 | TEttinger | clojure does have a slower step when it compiles to certain things; standalone jars need more work to assemble and can take a little while for large apps |
| 22:42 | TEttinger | normally that step is done for a release but not during development |
| 23:27 | felixn_ | https://gist.github.com/munro/dbda79e245a469e7fe6a <-- hey, still trying to wrap my head around transducers. python generators seem to do the exact same thing, the difference I see is transducers were built around HoF instead of language semantics, does that sound correct? |
| 23:36 | baritonehands | Hello |
| 23:38 | baritonehands | Wondering if there's a preferred way to refactor this code so I don't repeat many of the functions |
| 23:38 | baritonehands | https://github.com/baritonehands/avalon/blob/master/src/clj/avalon/models/groups.clj |
| 23:38 | felixn_ | https://gist.github.com/munro/dbda79e245a469e7fe6a#file-transducer-py-L18 <-- the transducer completion API is the same as a generator, using partition-all as an example. also the init would just be yielding at the top |
| 23:38 | baritonehands | https://github.com/baritonehands/avalon/blob/master/src/clj/avalon/models/games.clj |
| 23:38 | baritonehands | many functions are the same, just swap out variable name |
| 23:39 | baritonehands | or record type |
| 23:41 | felixn_ | baritonehands: macros work well |
| 23:44 | baritonehands | Is that the idiomatic clojure way? |
| 23:51 | baritonehands | felixn_: I was thinking closing around the ref, macros seem like overkill |
| 23:53 | luxbock | baritonehands: why not just keep all the state in one place? |
| 23:53 | luxbock | instead of having it spread accross three namespaces |
| 23:54 | luxbock | I think I would just have those funtions take one extra argument, and then you can use the same function for each case |
| 23:54 | felixn_ | baritonehands: agree with that, plus some of the functions are longer than the original code. (@groups id) vs (get-group id), any impure stuff it's normal to end with ! so (get-group! id) |
| 23:54 | justin_smith | you could have a protocol defining what you can do to a game, then write an implementation that uses a ref |
| 23:55 | baritonehands | luxbock: idk, maybe I can't shake the OOP background, but I thought games ref should go with games functions |
| 23:55 | baritonehands | justin_smith: it's not just for games, my groups and people look very similar |
| 23:56 | justin_smith | baritonehands: functions are not the same as methods, a function should be code that isn't owned by some specific data |
| 23:56 | baritonehands | I want to write the get method once |
| 23:56 | justin_smith | if you want methods, clojure can do OO, do a defrecord and protocols etc. |
| 23:57 | justin_smith | or do functions, and let someone else care about the data in some other context |
| 23:57 | justin_smith | half and half tends to be a mess |
| 23:57 | luxbock | I don't know much about game development, but my impression is that the functional way is generally to keep all state isolated in one place, and try to stick to as many pure functions as possible |
| 23:58 | justin_smith | luxbock: exactly, you have your state objects, then a number of pure functions that define the transitions making up the game |
| 23:58 | baritonehands | also need to keep in mind that this happens to be a ref for now, but in the future will be a SQL call (or some other datastore) |
| 23:58 | justin_smith | baritonehands: all the more reason to leave the functions pure |
| 23:58 | justin_smith | let the state-handling code handle the state |
| 23:59 | justin_smith | or, to use a protocol, and swap out the ref implementation or the sql implementation etc. |
| 23:59 | justin_smith | these both work, things get messy when you arbitrarily mix the two |