2014-09-01
| 02:28 | sm0ke | so if i am building this nested map {:a {:b {:c 1 :d x}}}, i want if x is nil its not assoc'd to the map |
| 02:28 | sm0ke | is there a nice way to do this |
| 02:31 | TEttinger | ,(let [m {:a {:b {:c 1}}} x nil] (if (nil? x) m (update-in m [:a :b :d] x))) |
| 02:31 | clojurebot | {:a {:b {:c 1}}} |
| 02:31 | TEttinger | ,(let [m {:a {:b {:c 1}}} x 2] (if (nil? x) m (update-in m [:a :b :d] x))) |
| 02:31 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn> |
| 02:31 | TEttinger | ,(let [m {:a {:b {:c 1}}} x 2] (if (nil? x) m (update-in m [:a :b :d] (constantly x)))) |
| 02:31 | clojurebot | {:a {:b {:d 2, :c 1}}} |
| 02:31 | sm0ke | yes thats the obvious way, i was looking something `easy` |
| 02:32 | TEttinger | well I imagine it wouldn't be hard to make that into a more general function. the update-in is the tricky bit |
| 02:33 | TEttinger | closest thing I can think of is when-let |
| 02:33 | TEttinger | (doc when-let) |
| 02:33 | clojurebot | "([bindings & body]); bindings => binding-form test When test is true, evaluates body with binding-form bound to the value of test" |
| 02:33 | sm0ke | yes yes, but i want this to work on arbitary data e.g. |
| 02:33 | sm0ke | {:a {:b {:c [1 2 x]}}} |
| 02:33 | sm0ke | i want to eliminate that x |
| 02:34 | TEttinger | complex nesting is not the kind of thing there's pre-written solutions for |
| 02:34 | TEttinger | update-in is as close as it gets |
| 02:34 | TEttinger | I could be wrong and amalloy swoops in with a half-of-one-liner |
| 02:35 | sm0ke | i think it is impossible |
| 02:35 | TEttinger | well you haven't really described what you want |
| 02:35 | sm0ke | what i want is something like compile time with consitions on runtime |
| 02:35 | sm0ke | condition* |
| 02:36 | TEttinger | do you want to be able to replace any instances of some variable, like 'x , with a value regardless of where it is? |
| 02:37 | sm0ke | i just want an prettier alternative to what you did, (let [m {:a {:b {:c 1}}} x 2] (if (nil? x) m (update-in m [:a :b :d] x))) |
| 02:37 | TEttinger | ,(count "(if (nil? x) m (update-in m [:a :b :d] x))") |
| 02:37 | clojurebot | 42 |
| 02:38 | sm0ke | you are ignoring the let form |
| 02:38 | TEttinger | because that's just your predefined stuff |
| 02:38 | TEttinger | that's stuff you would pass in |
| 02:38 | TEttinger | ,(def m {:a {:b {:c 1}}}) |
| 02:38 | clojurebot | #'sandbox/m |
| 02:39 | sm0ke | what if there was something like {:a {:b {:c 1 **-x :d x}}} |
| 02:39 | TEttinger | ,(def x 2) |
| 02:39 | clojurebot | #'sandbox/x |
| 02:39 | TEttinger | ,(if (nil? x) m (update-in m [:a :b :d] x)) |
| 02:39 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn> |
| 02:39 | sm0ke | **- is magic condition which ignores depending on x |
| 02:39 | sm0ke | :P |
| 02:39 | TEttinger | ,(if (nil? x) m (update-in m [:a :b :d] (constantly x))) |
| 02:39 | clojurebot | {:a {:b {:c 1, :d 2}}} |
| 02:39 | TEttinger | well uh your map has 5 items |
| 02:40 | sm0ke | yes **-x is a reader macro |
| 02:40 | TEttinger | ok, you could probably do that yes. reader macros are kinda discouraged... |
| 02:40 | TEttinger | I'm thinking of reader literals |
| 02:40 | TEttinger | which are not recommended in libraries |
| 02:40 | sm0ke | #only/if |
| 02:41 | sm0ke | i am not sure if even that would work |
| 02:41 | sm0ke | it is impossible to do this {:a {:b {:c 1 #only/if :d x}}} |
| 02:41 | TEttinger | it should be. hang on |
| 02:42 | TEttinger | ,{:a {:b {:c 1 #_ :d #_ x}}} |
| 02:42 | clojurebot | {:a {:b {:c 1}}} |
| 02:42 | TEttinger | so you can already ignore forms, you just want to do it selectively |
| 02:42 | sm0ke | yes my first though was also using (comment) |
| 02:43 | TEttinger | which returns nil, for some reason... |
| 02:43 | sm0ke | ,{:a {:b {:c 1 (if false [:d 2] (comment))}}} |
| 02:43 | clojurebot | #<RuntimeException java.lang.RuntimeException: Map literal must contain an even number of forms> |
| 02:43 | sm0ke | wow stupid |
| 02:44 | TEttinger | it's true though |
| 02:44 | TEttinger | that's a key, [:d 2] |
| 02:44 | sm0ke | but it has to be a compile time thing you see? but (if x..) is a runtime thing |
| 02:45 | sm0ke | cant be done! |
| 02:47 | TEttinger | yeah, I think because you're trying to do it inside the map {} literal |
| 02:47 | sm0ke | yes we would need a special macro for [] {} etc to do this |
| 02:47 | TEttinger | if is a macro, and I admit I'm not an expert on macros |
| 02:48 | sm0ke | ugh, i am going back to if's and let's |
| 02:49 | TEttinger | yes, if is what you should use here |
| 02:49 | TEttinger | all other solutions are much more hackish |
| 02:52 | sm0ke | so all that we need is this (runtime-to-compiletime-if x [:d 2]) this evaluates x during runtime and spats :d 2 (flattening them) for the compiler |
| 02:52 | sm0ke | which makes no sense |
| 02:53 | sm0ke | yay! I just wasted your 15 minutes |
| 03:10 | SagiCZ1 | anyone remembers how do i access this channels logs? |
| 03:11 | beamso | http://logs.lazybot.org/irc.freenode.net/%23clojure/2014-09-01.txt |
| 03:12 | SagiCZ1 | beamso: thank you |
| 03:13 | SagiCZ1 | i need couple more hours back |
| 04:53 | JL235 | Has anyone got any experience with clojure-clr? |
| 04:53 | JL235 | I am thinking of using it |
| 04:53 | JL235 | I have a .net project and thinking of rebuilding it with clojure (as I also want to get into Lisp too) |
| 04:55 | clgv | JL235: what is stopping you from trying it? |
| 05:15 | JL235 | nothing |
| 05:15 | JL235 | but I don't want to invest time moving a project over to something that may have a lot of warts |
| 05:15 | JL235 | not when I could go with something else instead |
| 05:15 | JL235 | so just asking around on people's experiences |
| 05:18 | clgv | JL235: well, before migrating a project you need to learn the language. Hence, I asked what is stopping you from trying out clojure and start learning the basics? |
| 05:24 | JL235 | I am not asking in regards to learning the language |
| 05:25 | clgv | JL235: what are you asking then? the more specific the question the likelier you get a helpful answer |
| 05:26 | JL235 | "Has anyone got any experience with clojure-clr?" |
| 05:30 | maxthoursie | JL235: I've tried to use it, but while core is there, lot's of libraries aren't. I ended up going with jvm clojure instead |
| 05:37 | jyfl987 | hi can anyone give me some example showing parsing weblog file , the filename should be given by cmdline |
| 05:40 | riffraff | hi everyone |
| 05:41 | riffraff | I'm tryint to add test.check tests to my project and I'd like to have them run as normal tests as per clojure.test |
| 05:41 | riffraff | AFAIU I shoiuld use defspec, but I get a Unable to resolve symbol: defspec in this context |
| 05:42 | riffraff | any ideas of what I'm doing wrong? Sorry if' it's a silly question, I'm a newbie :/ |
| 05:44 | JL235 | thanks maxthoursie |
| 05:44 | riffraff | ah I found it in another namespace maybe |
| 06:13 | clgv | riffraff: why not deftest? |
| 06:13 | riffraff | it was my understanding defspec was the preferred way to use test.check with clojure.test |
| 06:13 | clgv | riffraff: ah defspec is part of test.check |
| 06:13 | riffraff | yeah |
| 06:13 | riffraff | the name is somewhat confusing to me as it seems to refer to some BDD framework |
| 06:13 | clgv | from the tests in test. heck it seems to be the way to go |
| 06:13 | riffraff | yes I got it working now |
| 06:13 | riffraff | the trick was that it's defined in clojure.test.check.clojure-test |
| 06:13 | clgv | for future readers, it is in clojure.test.check.clojure-test |
| 06:13 | riffraff | but this is not called out in the readme. As a noob I assumed I was doing something stupid with requires :) |
| 06:13 | clgv | yeah, there could be more documentation. |
| 06:13 | clgv | I am just fiddeling with recursive generators |
| 06:16 | riffraff | err, another silly question: given "lein repl" where my project.clj has org.clojure/test.check in the dependencies, should (require '[clojure.test.check :as tc]) |
| 06:16 | riffraff | work ? |
| 06:20 | clgv | riffraff: yes, it should |
| 06:20 | clgv | riffraff: do you do any profile magic? |
| 06:20 | riffraff | not that I am aware of |
| 06:21 | clgv | did you restart the repl after adding the dependency? |
| 06:23 | riffraff | the one I just opend yes |
| 06:23 | riffraff | not sure if there is some daemin process I need to restart too |
| 06:24 | clgv | riffraff: no. requiring should work then |
| 06:25 | clgv | replace "should" with "must" |
| 06:26 | riffraff | eh :) |
| 06:29 | riffraff | ah I think it _is working, but I was looking at it wrongly |
| 06:30 | riffraff | basically, trying to see if the symbol "tc" was bound to something (by typing "tc" in the repl) |
| 06:30 | riffraff | but it's not, while tc/quick-check instead is |
| 06:30 | riffraff | I think I need to study this namespacing thing a bit more |
| 06:30 | riffraff | thanks anyway |
| 06:51 | clgv | riffraff: ah ok. |
| 06:52 | clgv | ,(require '[clojure.string :as str]) |
| 06:52 | clojurebot | nil |
| 06:52 | clgv | ,(keys (ns-aliases *ns*)) |
| 06:52 | clojurebot | (str) |
| 06:52 | clgv | riffraff: that's a way to check the alias ^^ |
| 06:52 | riffraff | awesome, thanks |
| 06:53 | clgv | ,((ns-aliases *ns*) 'str) |
| 06:53 | clojurebot | #<Namespace clojure.string> |
| 06:53 | clgv | ^^ to see where it maps to |
| 06:56 | martinklepsch | when evaling (println "something") in cider, is there a buffer where I can see the result? |
| 06:56 | martinklepsch | ah, nevermind |
| 06:56 | martinklepsch | the cider-repl buffer :) |
| 07:30 | SagiCZ1 | if i have a non-atom list of atoms can i see their changes? |
| 07:34 | clgv | SagiCZ1: example? |
| 07:35 | SagiCZ1 | (def a (atom 0)), (def b (atom 1)), (def v [a b]), .. now i keep the reference to "v" i can swap! the atoms in it right? |
| 07:37 | noidi | yes, but not atomically :) |
| 07:37 | SagiCZ1 | noidi: elaborate? |
| 07:38 | clgv | SagiCZ1: you cant guarantee any consistence between the two atoms |
| 07:39 | clgv | SagiCZ1: your options are to have the vector within an atom or to use references instead of the atoms |
| 07:39 | noidi | SagiCZ1, say both atoms start at 0 and you want to `inc` them. an observer may observe a world in which one atom has the value 1 and the other 0 |
| 07:39 | clgv | SagiCZ1: btw your usage of def for `a` and `b` is alarming |
| 07:46 | SagiCZ1 | why is alarming? |
| 07:53 | SagiCZ1 | (ns my-ns (:require [ui])) |
| 07:53 | SagiCZ1 | this says it could not locate ui__init.class but i have the ui namespace in the same folder, whats wrong? |
| 07:56 | llasram | SagiCZ1: namespaces are always absolute, never relative |
| 07:57 | SagiCZ1 | thank you, it works now |
| 07:58 | clgv | SagiCZ1: because `def` is only intended for *global* variables |
| 07:59 | SagiCZ1 | clgv: these are supposed to hold game's state and i read that game state should be global and immutable |
| 08:00 | lq | ls |
| 08:00 | lazybot | bin etc home lib lost+found media mnt opt proc root sbin sys usr var |
| 08:01 | llasram | SagiCZ1: Yeah, but you don't need two top-level references to the same object. E.g., just: (def game-state [(atom 0) (atom 0)]) |
| 08:01 | llasram | (or whatever) |
| 08:02 | SagiCZ1 | oh yes ive already changed that.. it was just for the example.. thank you though |
| 08:02 | clgv | SagiCZ1: what llasram said ^^ |
| 08:04 | clgv | SagiCZ1: I think the decision between game state as global variable or game state as function argument is not that clear as you state |
| 08:04 | SagiCZ1 | clgv: its the only that makes sense to me.. i cant wrap my head around passing game state around 20 functions |
| 08:05 | llasram | SagiCZ1: And yet it has a lot of benefits |
| 08:05 | clgv | SagiCZ1: that way you are tempted to have no pure functions at all |
| 08:06 | SagiCZ1 | if i try to use only pure functions i cant progress at all.. do you have any examples of very simple games with pure functions? |
| 08:06 | clgv | SagiCZ1: pure functions are "easy" to test |
| 08:06 | llasram | At my company we started off with several things that it seemed to "make sense" would just be global state, like configuration |
| 08:07 | llasram | And we've realized it was pretty much all a terrible idea, which has made code much harder to test, and are moving to pure-as-possible functions for everything |
| 08:07 | SagiCZ1 | llasram: i understand all the advantages of pure functions.. which does not make me able to write them |
| 08:07 | clgv | SagiCZ1: well, you will have at least one function that holds the atom, e.g. the main game loop |
| 08:07 | llasram | SagiCZ1: Why is it harder? You just have an extra first argument to your functions which is the game state |
| 08:08 | lvh_ | is there a codecs library I'm missing? I need urlsafe base64; the only one I can find is inside buddy |
| 08:08 | lvh_ | and dragging in all of buddy for 10 lines or so seems silly |
| 08:08 | llasram | lvh_: Apache Commons? |
| 08:08 | lvh_ | (as does copying those 10 lines) |
| 08:08 | lvh | llasram: does that have urlsafe base64? I thought it didn't, I'll double check |
| 08:08 | llasram | Oh, maybe not. I just assumed it would |
| 08:08 | clgv | lvh_: isn't there some clojurewerkz lib for URLs that is able to do that? |
| 08:08 | llasram | What makes normal base64 not URL-safe? |
| 08:09 | lvh | llasram: wait, you're right, it does :) |
| 08:09 | llasram | cool |
| 08:09 | lvh | clgv: that'd be great! |
| 08:09 | SagiCZ1 | the thing is.. i am using swing for rendering, i.e. paintComopnent method which has fixed amount of arguments.. how could i pass the state in there? |
| 08:09 | lvh | clgv: *looks* |
| 08:09 | lvh | llasram: some parts of the alphabet |
| 08:09 | lvh | llasram: + and /, specifically |
| 08:09 | llasram | Ah, of course |
| 08:10 | clgv | SagiCZ1: do you use seesaw? |
| 08:10 | SagiCZ1 | clgv: yes |
| 08:11 | lvh | clgv: there's https://github.com/clojurewerkz/route-one, but it doesn't appear to know anything about base64. |
| 08:11 | clgv | SagiCZ1: well, you can easily build closures as paint handlers, that close over the game state atom. on each paint call you deref the atom |
| 08:11 | SagiCZ1 | clgv: either the entities i want to render must be global or the canvas i want to paint on must be global |
| 08:12 | SagiCZ1 | yeah using clojure while not understanding closures sounds like a terrible idea |
| 08:13 | clgv | SagiCZ1: the functions that do the actual painting cant be pure of course, but the game logic that updates the state can be |
| 08:14 | SagiCZ1 | they cant be pure because the fact that they actually "paint on screen" is a side-effect right? |
| 08:15 | clgv | lvh: the contrib lib data.codec has base64 encoding but it's also a bigger dependency... |
| 08:16 | clgv | SagiCZ1: yeah. but functions that determine how something needs to be painted (e.g. color dependend on several state values) can be pure |
| 08:17 | SagiCZ1 | clgv: could u write a pseudocode example of this please? "well, you can easily build closures as paint handlers, that close over the game state atom. on each paint call you deref the atom" |
| 08:20 | clgv | SagiCZ1: here is the example how to add a paint handler https://github.com/daveray/seesaw/blob/master/test/seesaw/test/examples/paintable.clj#L31 |
| 08:22 | SagiCZ1 | i am using that.. but the "draw-a-red-x" is not "closing over" anything is it? |
| 08:23 | clgv | SagiCZ1: in the function creating your gui you could do something like (defn create-gui [game-state-atom, ...] (<CANVAS-COMPONENT> ... :paint (fn [component, graphics] (let [game-state @game-state] ....paint...)))) |
| 08:23 | SagiCZ1 | clgv: now i see it.. perfect! |
| 08:23 | clgv | SagiCZ1: just replace <CANVAS-COMPONENT> with whatever you use as canvas |
| 08:24 | clgv | change "@game-state" to "@game-state-atom" |
| 08:24 | SagiCZ1 | yeah.. no the atom does not have to be global |
| 08:24 | SagiCZ1 | *now |
| 08:29 | lvh | Is there a ring/compjure thing that lets me say "this part of the URL is a base64 thing; please give me the decoded version" |
| 08:36 | SagiCZ1 | clgv: back your example.. is it possible to create the inner function somewhere else for clarity? or it has to be nested to access the atom? |
| 08:38 | SagiCZ1 | clgv: maybe i should have a "factory-function" that can output a function with the closure? |
| 08:41 | jeffterrell | lvh: I found ring.util.codec/base64-{en,de}code here: http://mmcgrana.github.io/ring/ring.util.codec.html |
| 08:41 | jeffterrell | lvh: Does that work for you? |
| 08:41 | lvh | jeffterrell: yeah, me too. Not urlsafe though. |
| 08:41 | lvh | jeffterrell: (also doesn't automagically do the encoding btu I can live with that |
| 08:43 | jeffterrell | Fair enough. |
| 08:44 | lvh | I wish clojure.string.trim let me specify which chars I wanted to trim |
| 08:46 | SagiCZ1 | i would like to call a function n times to generate a list of n items, how do i do that? |
| 08:46 | hyPiRion | (repeatedly n fun) |
| 08:46 | hyPiRion | it's lazy though, so be aware of that |
| 08:46 | hyPiRion | ,(repeatedly 10 rand) |
| 08:46 | clojurebot | (0.5949458375138312 0.08279190123529145 0.14265751227133672 0.07628975550512085 0.7772873079770356 ...) |
| 08:47 | SagiCZ1 | hyPiRion: thats what i want |
| 08:47 | SagiCZ1 | ty |
| 08:48 | SagiCZ1 | ,(repeatedly 4 #(0)) |
| 08:48 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn> |
| 08:48 | SagiCZ1 | why this doesnt work though? |
| 08:49 | SagiCZ1 | ,(repeatedly 4 (fn [] 0)) |
| 08:49 | clojurebot | (0 0 0 0) |
| 08:49 | SagiCZ1 | and now it does?? |
| 08:49 | lazybot | SagiCZ1: Definitely not. |
| 08:50 | SagiCZ1 | ,(repeatedly 4 #((0))) |
| 08:50 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn> |
| 08:50 | hyPiRion | SagiCZ1: What is (0) ? |
| 08:50 | SagiCZ1 | i just want a function that returns 0 |
| 08:50 | SagiCZ1 | this is not correct? #(0) ? |
| 08:50 | clgv | SagiCZ1: (constantly 0) |
| 08:50 | r4vi | (0) is trying to function call a Long |
| 08:50 | hyPiRion | If you want a constant you could use (repeat 4 0), btw |
| 08:51 | clgv | ,(read-string "#(0)") |
| 08:51 | clojurebot | (fn* [] (0)) |
| 08:51 | clgv | SagiCZ1: ^^ that's why |
| 08:51 | riffraff | (repeatedly 4 #( 0 ) ) wouldn't work either though, why? |
| 08:51 | clgv | riffraff: see above |
| 08:51 | SagiCZ1 | it wraps it with another set of braces |
| 08:51 | hyPiRion | ,'#(0) |
| 08:51 | clojurebot | (fn* [] (0)) |
| 08:51 | riffraff | ahihi, got it |
| 08:51 | clgv | hyPiRion: uhh shortcut :D |
| 08:52 | SagiCZ1 | ,(constanly rand) |
| 08:52 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: constanly in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 08:52 | SagiCZ1 | ,(constantly rand) |
| 08:52 | clojurebot | #<core$constantly$fn__4178 clojure.core$constantly$fn__4178@147fc78> |
| 08:52 | SagiCZ1 | ,((constantly rand)) |
| 08:52 | clojurebot | #<core$rand clojure.core$rand@15e8c9d> |
| 08:52 | hyPiRion | that's a function returning the function rand all the time |
| 08:52 | SagiCZ1 | ,((constantly (rand))) |
| 08:52 | clojurebot | 0.3298967693738979 |
| 08:53 | SagiCZ1 | ,(repeatedly 5 #(constantly (rand))) |
| 08:53 | clojurebot | (#<core$constantly$fn__4178 clojure.core$constantly$fn__4178@b873c> #<core$constantly$fn__4178 clojure.core$constantly$fn__4178@dbb0af> #<core$constantly$fn__4178 clojure.core$constantly$fn__4178@12cea05> #<core$constantly$fn__4178 clojure.core$constantly$fn__4178@1b7fb2c> #<core$constantly$fn__4178 clojure.core$constantly$fn__4178@1cb30a4>) |
| 08:53 | SagiCZ1 | nevermind |
| 08:53 | clgv | ,(repeatedly 5 (constantly (rand))) |
| 08:53 | clojurebot | (0.17791487825993624 0.17791487825993624 0.17791487825993624 0.17791487825993624 0.17791487825993624) |
| 08:53 | clgv | SagiCZ1: no idea why you want it that complicated but that works ^^ |
| 08:54 | clgv | ,(repeat 5 (rand)) |
| 08:54 | clojurebot | (0.9761251033774431 0.9761251033774431 0.9761251033774431 0.9761251033774431 0.9761251033774431) |
| 08:54 | clgv | SagiCZ1: same effect ^^ |
| 08:54 | SagiCZ1 | clgv: ^^ just playing around |
| 08:55 | SagiCZ1 | so is there a nicer way to do exactly this? |
| 08:55 | SagiCZ1 | ,(repeatedly 4 (constantly {:a 0 :b (rand)})) |
| 08:55 | clojurebot | ({:a 0, :b 0.49531751143064073} {:a 0, :b 0.49531751143064073} {:a 0, :b 0.49531751143064073} {:a 0, :b 0.49531751143064073}) |
| 08:56 | SagiCZ1 | ,(repeat 2 {:a 0 :b (rand)}) |
| 08:56 | clojurebot | ({:a 0, :b 0.8084007871336014} {:a 0, :b 0.8084007871336014}) |
| 08:56 | SagiCZ1 | got it |
| 09:02 | hyPiRion | you want (rand) to be the same value for each item? Asking, just to ensure you get the right thing out |
| 09:03 | lvh | What's the idiomatic data structure in Clojure for bytestrings? |
| 09:03 | lvh | I've been using bytes[] but that just feels super gross. |
| 09:04 | clgv | hyPiRion: yeah, looks like a code smell. should be something like (let [r (rand)] (repeat 5 {:a 0 :b r})) to make the intention clear |
| 09:05 | SagiCZ1 | hyPiRion: nope that is a mistake |
| 09:05 | SagiCZ1 | hyPiRion: why is not calling random again? |
| 09:05 | justin_smith | lvh: you can use a vector of Byte values, byt bytes[] is an actual array of bytes, and is the right way to represent that |
| 09:06 | lvh | justin_smith: also mutable though right |
| 09:06 | justin_smith | right |
| 09:06 | justin_smith | what do you mean by "bytestring", actually? |
| 09:07 | justin_smith | arrays of bytes are not CharSequences because they are made of 8 bit signed values |
| 09:07 | llasram | SagiCZ1: Because you are calling it yourself vs passing the function `rand` to something |
| 09:07 | llasram | ,(repeatedly 5 rand) |
| 09:07 | clojurebot | (0.013326642964774371 0.40762242985735264 0.7708784528135172 0.9785686587084479 0.7638473865027904) |
| 09:07 | justin_smith | lvh: maybe you want an array of shorts, or even ints, if you want to represent anything beyond 8 bits |
| 09:08 | SagiCZ1 | ,(repeatedly 2 (fn [] {:a (rand) :b (rand)})) |
| 09:08 | clojurebot | ({:a 0.7095231468043378, :b 0.2359827909847596} {:a 0.7883582125143982, :b 0.8835072257869794}) |
| 09:08 | SagiCZ1 | this is what i want |
| 09:08 | SagiCZ1 | i just dont like the fn notation |
| 09:08 | clgv | SagiCZ1: so why dont you use it? that why? :P |
| 09:08 | clgv | *way |
| 09:08 | SagiCZ1 | clgv: fn seems uncool to me |
| 09:08 | SagiCZ1 | especially with no arguments |
| 09:09 | hyPiRion | SagiCZ1: ##(map #(assoc {:a 0} :b %) (repeatedly 2 rand)) |
| 09:09 | lazybot | ⇒ ({:b 0.7055591223129442, :a 0} {:b 0.004841332288907818, :a 0}) |
| 09:09 | llasram | SagiCZ1: No no -- `fn` is the coolest |
| 09:09 | justin_smith | ,(repeatedly #(hash-map :a (rand) :b (rand))) |
| 09:09 | clojurebot | ({:b 0.7774605426166392, :a 0.5457287633034817} {:b 0.9351205665136824, :a 0.10940327234871117} {:b 0.2785826781824663, :a 0.06663172148153373} {:b 0.6237813005636965, :a 0.6235348439569292} {:b 0.2189573584793213, :a 0.11105258859414224} ...) |
| 09:10 | justin_smith | yes, fn is awesome |
| 09:10 | SagiCZ1 | thanks for the ideas |
| 09:10 | llasram | ,(repeatedly 2 #(-> {:a (rand)})) |
| 09:10 | clojurebot | ({:a 0.3764276763964761} {:a 0.28425055137631283}) |
| 09:10 | clgv | SagiCZ1: doh! |
| 09:10 | lvh | justin_smith: I mean bytestrings as in sequences of bytes. Like a C string, or a Python string. |
| 09:10 | lvh | justin_smith: Not like a java String, of course. |
| 09:10 | llasram | lvh: s/Python string/Python 2 string/ |
| 09:10 | justin_smith | lvh: yeah, byte-array is that (and is of course mutible) |
| 09:11 | lvh | llasram: python3 doesn't exist ;) |
| 09:11 | llasram | :-p |
| 09:13 | SagiCZ1 | another question.. if i want to have an inner function close over some local symbol, can i define it somewhere outside? |
| 09:13 | SagiCZ1 | scratch that.. |
| 09:14 | justin_smith | you can pass local values to a function that creates a new function closing over those values |
| 09:14 | SagiCZ1 | yep.. gonna do just that |
| 09:14 | justin_smith | like the classic make-adder |
| 09:30 | SagiCZ1 | can i deref atom by destructuring? (doseq [{a :a b :b} [(atom {:a 0 :b 1}) (atom {:a 2 :b 3})]] (println a b)) |
| 09:31 | clgv | SagiCZ1: no not like that. first deref it to get the value then apply destructuring on the value |
| 09:32 | SagiCZ1 | ok |
| 09:32 | justin_smith | ,(let [{a :a} (atom {:a 42})] a) |
| 09:32 | clojurebot | nil |
| 09:32 | justin_smith | ,(let [{a :a} @(atom {:a 42})] a) |
| 09:32 | clojurebot | 42 |
| 09:32 | SagiCZ1 | yeah that works for let, but not for doseq when u have a coll of atoms |
| 09:32 | justin_smith | you *can* destructure an atom, it just won't return the value you want |
| 09:33 | justin_smith | SagiCZ1: doseq and let use exactly the same destructuring |
| 09:33 | vladh_ | Hey guys — does anyone know how I can keep a script running via lein-exec? I’m trying to run a simple cron-style thing with at-at and don’t want to script to immediately. |
| 09:33 | vladh_ | to die* |
| 09:33 | SagiCZ1 | justin_smith: no they dont? |
| 09:34 | justin_smith | SagiCZ1: doseq needs a sequence, but doseq and let both call clojure.core/destructure to do destructuring |
| 09:34 | SagiCZ1 | doseq does that for each element of the sequence separately though |
| 09:35 | justin_smith | sure - so it destructures each element of the sequence |
| 09:35 | justin_smith | I am just saying the actual destructuring, when it happens, is done by the same function |
| 09:35 | SagiCZ1 | alright.. |
| 09:35 | SagiCZ1 | i see |
| 09:36 | justin_smith | and my ,(let [{a :a} (atom {:a 42})] a) is exactly analogous to your (doseq [{a :a b :b} [(atom {:a 0 :b 1}) (atom {:a 2 :b 3})]] (println a b)) |
| 09:37 | justin_smith | but I switched to let because there is less noise there, and the destructuring happens in the same manner |
| 09:37 | SagiCZ1 | but in let u can solve the problem with prepending @ to the right sight of the binding.. in doseq u cant |
| 09:38 | llasram | wat |
| 09:38 | justin_smith | (doseq [{a :a b :b} (map deref [...])] ...) |
| 09:38 | SagiCZ1 | oh.... wow |
| 09:38 | SagiCZ1 | mind - blown |
| 09:38 | llasram | SagiCZ1: @ is a reader macro for `deref` |
| 09:38 | llasram | ,`@whatever |
| 09:38 | clojurebot | (clojure.core/deref sandbox/whatever) |
| 09:38 | SagiCZ1 | thats news to me |
| 09:39 | clgv | SagiCZ1: well you should probably read the chapter on atoms and refs ^^ |
| 09:39 | SagiCZ1 | clgv: i read it so many times .. i just figured that i should also write some code to help me remember |
| 09:40 | SagiCZ1 | my theoretical knowledge of clojure is higher than the practical experience.. im not saying it's very high anyways |
| 09:40 | clgv | SagiCZ1: use the chapter while writing code ;) |
| 09:40 | SagiCZ1 | alright |
| 09:41 | lvh | Is x.y.z-SNAPSHOT before, or after x.y.z? |
| 09:41 | llasram | lvh: "Before", but snapshots are non-release, so you have no way of knowing what's in one |
| 09:42 | justin_smith | llasram: well you can always look inside :P |
| 09:42 | justin_smith | but yeah, no way to know beforehand what you'll get if you ask for it |
| 09:42 | llasram | justin_smith: Except that the non-pinned SNAPSHOT revision could be updated at any time |
| 09:42 | clgv | lvh: use snapshots only for experimenting with new features that are not in any release, since they might sabotage repeatable builds |
| 09:43 | lvh | I'm trying to publish software thoguh :) |
| 09:43 | justin_smith | llasram: I meant you can check strictly a-posteriori, but really that hardly matters compared to not knowing what you'll get if you ask for it |
| 09:45 | clgv | lvh: well at the end of a dev cycle release a non-snapshot, during the dev cycle you can use snapshot versions |
| 09:46 | lvh | ok :) |
| 09:48 | zeebrah | Y do i need do add the eval here: ((eval (read-string "first")) [1 2 3]) |
| 09:48 | llasram | zeebrah: mu |
| 09:49 | zeebrah | llasram: dont know mmu |
| 09:49 | clgv | zeebrah: because you are doing weird stuff ;) a `resolve` would suffice |
| 09:50 | clgv | ,((resolve (read-string "first")) [1 2 3]) |
| 09:50 | clojurebot | 1 |
| 09:50 | zeebrah | clgv: i'm watching bob martin so yes definitely weird :) |
| 09:50 | clgv | ,((resolve 'first) [1 2 3]) |
| 09:50 | clojurebot | 1 |
| 09:50 | clgv | same ^^ |
| 09:50 | clgv | ,(first [1 2 3]) |
| 09:50 | clojurebot | 1 |
| 09:50 | zeebrah | so resolve is taking a symbol and then finding the function? but why is that necessary |
| 09:51 | llasram | zeebrah: Needing to manually `read` string which contain code is unusual, and probably means there's a more common way to do whatever you're trying to do |
| 09:51 | llasram | zeebrah: Or do you just want to understand why a symbol is not identical to the function a particular namespaces maps that symbol to? |
| 09:51 | zeebrah | llasram: just trying something out because the dude said you can build lisp code and then execute it using eval |
| 09:51 | zeebrah | llasram: i guess :) |
| 09:52 | zeebrah | if the symbol is in function position then why doesn't it just work as I expected? |
| 09:52 | clgv | zeebrah: what are you watching exactly? |
| 09:52 | zeebrah | https://www.youtube.com/watch?v=SYeDxWKftfA |
| 09:52 | justin_smith | zeebrah: the normal way is to just type into the repl, it does the eval and read for you |
| 09:52 | clgv | zeebrah: since the symbol is a symbol and is not a function |
| 09:52 | llasram | zeebrah: So in Clojure (and most Lisps) "reading" and "compiling" are separate steps |
| 09:53 | llasram | Reading turns text into a data-structure |
| 09:53 | llasram | Compilation turns a data-structure into code |
| 09:53 | zeebrah | clgv: right but its not like there are multiple namespaces so there isnt any ambiguity in just using the only one in the namespace? |
| 09:53 | clgv | so Uncle Bob uses Clojure, eh? |
| 09:53 | zeebrah | apparently! |
| 09:54 | clgv | you explicitly constructed a symbol in your example, so no it can not |
| 09:54 | zeebrah | is namespace the right word there? i mean in the sense of lisp 1 and 2 |
| 09:54 | clgv | if you just put a symbol in call position it is resolved to a function on compilation or an error is thrown |
| 09:54 | llasram | zeebrah: In that sense Clojure is a Lisp-1 and has only one "namespace", but it has a concept of namespaces (like CL packages), so the same bare symbol could refer to multiple functions in different namespaces |
| 09:54 | zeebrah | oh i see |
| 09:55 | justin_smith | symbols can have namespaces, but a bare one doesn't - but it gets resolved according to the mappings of the current namespace to a var |
| 09:55 | llasram | ^^ During compilation |
| 09:55 | clgv | justin_smith: but not in his case where he explicitely constructed a "symbol value" |
| 09:55 | llasram | (well, or manual resolution via e.g. `resolve`) |
| 09:56 | justin_smith | ,(map namespace '[foo user/foo sandbox/foo clojure.string/foo]) |
| 09:56 | clojurebot | (nil "user" "sandbox" "clojure.string") |
| 09:56 | justin_smith | clgv: right, not always resolved - but it uses the same rules once you ask for it to be resolved |
| 09:58 | zeebrah | so the reason ((read-string "first") [1 2 3]) didnt return 1 is b/c first doesn't yet belong to a namespace but yet it is still a symbol |
| 09:59 | justin_smith | it's just the symbol, not the var the symbol points at |
| 09:59 | justin_smith | ,((read-string "clojure.core/first") [1 2 3]) ; this is no better |
| 09:59 | clojurebot | nil |
| 10:00 | justin_smith | resolve says "find the var for this symbol" |
| 10:00 | zeebrah | oh |
| 10:00 | hyPiRion | ,('+ 1 2) |
| 10:00 | clojurebot | 2 |
| 10:00 | justin_smith | ,((read-string "clojure.core/first") [1 2 3] 1) ;P |
| 10:00 | clojurebot | 1 |
| 10:01 | justin_smith | that's just a trick |
| 10:01 | zeebrah | so how is this not like a lisp-2 doing (function ..) first? i thought going to a lisp 1 made that unnecessary |
| 10:01 | zeebrah | hmmm interesting |
| 10:01 | hyPiRion | zeebrah: Because a symbol is not a function |
| 10:02 | justin_smith | zeebrah: in normal code, you type the name of the function, and it gets the value pointed at by the var indicated by the symbol |
| 10:02 | zeebrah | understood thanks :) |
| 10:02 | justin_smith | ,(let [plus +] (plus 1 1)) |
| 10:02 | clojurebot | 2 |
| 10:02 | justin_smith | can't do that in a lisp-2 |
| 10:03 | hyPiRion | Right. (let ((plus #'+)) (funcall plus 1 1)) is the closest |
| 10:03 | justin_smith | which reminds me I should make my above statement more precise: it gets the value pointed at by the local binding, or failing that, var resolution |
| 10:04 | zeebrah | does scheme have a version of resolve too? |
| 10:05 | SagiCZ1 | lets say i refer to a different ns "other-ns" using :require in my (ns) .. i am working in the current ns in repl.. what if i want to change a function in the "other-ns" and reflect the change in my working repl? should i call (ns) again to :require it again? it didnt reflect the changes |
| 10:05 | xeqi | does ` have a name? |
| 10:05 | justin_smith | xeqi: syntax-quote |
| 10:06 | xeqi | quasi-quote, symbol-quote .. |
| 10:06 | xeqi | ah |
| 10:06 | xeqi | thanks |
| 10:06 | hyPiRion | I've always referred to it as backquote |
| 10:06 | justin_smith | zeebrah: I think in scheme eval is more likely to be used |
| 10:06 | hyPiRion | but that's cl history I guess |
| 10:06 | justin_smith | here it is called syntax-quote http://clojure.org/reader |
| 10:06 | mi6x3m | clojure |
| 10:06 | mi6x3m | what is a way to extract only a subset of the keys in a map? |
| 10:07 | mi6x3m | like (subset map [:a :b :c]) |
| 10:07 | justin_smith | select-keys |
| 10:07 | mi6x3m | ,(doc select-keys) |
| 10:07 | clojurebot | "([map keyseq]); Returns a map containing only those entries in map whose key is in keys" |
| 10:07 | justin_smith | ,(select-keys {:a 0 :b 1} [:a]) |
| 10:07 | clojurebot | {:a 0} |
| 10:07 | SagiCZ1 | cfleming: hi, are you here by any chance? |
| 10:08 | mi6x3m | (inc justin_smith) |
| 10:08 | lazybot | ⇒ 71 |
| 10:18 | SagiCZ1 | ok let me ask once again.. how do i reload a library in repl? |
| 10:19 | clgv | SagiCZ1: library or namespace of the current project? |
| 10:19 | SagiCZ1 | other namespace |
| 10:19 | clgv | usually you use "send to repl" or something similar which your ide/editor provides |
| 10:20 | SagiCZ1 | ok i just tried that and it owrks |
| 10:20 | SagiCZ1 | works |
| 10:20 | SagiCZ1 | i thought there is some programatic way |
| 10:20 | clgv | SagiCZ1: well yeah, there is but you'll end up with tools.namespace then |
| 10:20 | SagiCZ1 | yeah i dont want that.. |
| 10:21 | clgv | +likely |
| 10:21 | SagiCZ1 | but this works so thats fine |
| 10:22 | justin_smith | SagiCZ1: (require 'some.ns :reload) works in a vanilla repl |
| 10:22 | SagiCZ1 | justin_smith: thank you |
| 10:23 | justin_smith | clgv: the reason to use tools.namespace there is if a definition is removed from the ns, :reload does not undefine it, right? or is there some other nuance? |
| 10:27 | clgv | justin_smith: types and records are problematic. if you redefine a type by reloading its defining namespace other functions from different namespaces that were not reloaded but use that type will break |
| 10:27 | justin_smith | ahh, right |
| 10:28 | lvh | I have a bunch of forms in a threading macro. I want to conditionally add one. Is there a reasonable trick for that? |
| 10:28 | clgv | justin_smith: that's an example from my experience where using require only will break |
| 10:29 | elazar | Trying to go through Clojure koans: https://github.com/functional-koans/clojure-koans. Hitting an issue with cons. http://pastebin.com/raw.php?i=mkPrG1zn Any suggestions? |
| 10:29 | justin_smith | elazar: note how they create the sequence you are consing onto? |
| 10:30 | justin_smith | *they are consing onto |
| 10:30 | elazar | Ah, I think I see. |
| 10:30 | justin_smith | you have to do the same thing with your sequence |
| 10:30 | elazar | Well, I'm a little further now. Thank you, justin_smith. :) |
| 10:30 | justin_smith | ,[(:a :b :c :d :e) '(:a :b :c :d :e)] |
| 10:30 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: Wrong number of args passed to keyword: :a> |
| 10:31 | justin_smith | :a is a keyword, it invokes get on its args if used in a function position |
| 10:32 | elazar | ,(= (quote (:a :b :c :d :e)) (conj (quote (:a :b :c :d)) :e)) |
| 10:32 | clojurebot | false |
| 10:33 | justin_smith | conj is a little funny ##(= (conj [:a :b] :c) (conj '(:a :b) :c)) |
| 10:33 | lazybot | ⇒ false |
| 10:34 | elazar | ,(= (quote (:e :a :b :c :d)) (conj (quote (:a :b :c :d)) :e)) |
| 10:34 | clojurebot | true |
| 10:34 | elazar | ^ Yeah, figured it out. :) |
| 10:34 | elazar | http://clojuredocs.org/clojure_core/clojure.core/conj <-- second example |
| 10:34 | elazar | Sorry, first example, second input. |
| 10:35 | justin_smith | ,(conj #{:a :b :c :d} :e) |
| 10:35 | clojurebot | #{:e :c :b :d :a} |
| 10:48 | maxthoursie | lvh: cond-> ? |
| 11:41 | sm0ke | using java.jdbc is there a way to preserve order of columns? |
| 11:42 | sm0ke | select a,b,c from ... gives {:a 1 :b 2 :c 3} which loses the order |
| 11:42 | bja | sm0ke, I can't imagine relying on ordering there is safe |
| 11:44 | sm0ke | yes, that is why i am asking, jdbc result is ordered |
| 11:44 | bja | https://github.com/clojure/java.jdbc/blob/master/src/main/clojure/clojure/java/jdbc.clj#L800 |
| 11:45 | bja | it looks like query takes :as-arrays? true to make the result set fn into vdc |
| 11:45 | bja | I didn't try it, but it sounds exactly like what you want |
| 11:45 | sm0ke | let me try |
| 11:45 | sm0ke | thanks bja |
| 11:47 | sm0ke | ugh, that is for the outer data structure |
| 11:47 | sm0ke | [{},..] instead of '({},..) |
| 11:48 | bja | oh |
| 11:48 | bja | it looks like the code maps :row-fn across the results |
| 11:49 | sm0ke | row-fn is identity by default so internally it is map as lower denominator |
| 11:49 | sm0ke | sad |
| 11:50 | justin_smith | (map (fn [k] [k (m k)] [:a :b :c]) |
| 11:50 | justin_smith | ) |
| 11:50 | justin_smith | where m is the result, and that last arg has the order you want? |
| 11:51 | sm0ke | well thats not the point |
| 11:51 | justin_smith | what is the point? |
| 11:52 | bja | sm0ke, https://github.com/clojure/java.jdbc/blob/master/src/main/clojure/clojure/java/jdbc.clj#L362 exists to turn the raw ResultSet into a seq of maps |
| 11:53 | sm0ke | ugh read the comment |
| 11:53 | sm0ke | sad |
| 11:54 | luqi | Hello everyone. As a beginner in Clojure, I find it really daunting when things go wrong and the stack trace is just huge. Any suggestions on it? |
| 11:54 | sm0ke | hmm there is a interesting comment which says "but using into {} should preserve order for up to 16 columns" |
| 11:56 | clgv | sm0ke: do you need additional features of the default clojure.java.jdbc functions? if not just write a function that handles the resultset directly |
| 11:56 | bja | sm0ke, maybe you only need 16 columns? :( |
| 11:56 | justin_smith | luqi: there are various tools for colorizing output to help you find the relevant parts |
| 11:56 | sm0ke | no i need more |
| 11:57 | sm0ke | grr.. i will have to go back to basic jdbc |
| 11:57 | justin_smith | luqi: at this point, I have learned how to read the stacktraces, and I look for the frames that are in files I wrote. |
| 11:58 | luqi | yeah, I always look for my files. but they are kinda buried inside massive Java/JVM frames |
| 11:59 | justin_smith | luqi: https://github.com/AvisoNovate/pretty |
| 12:00 | justin_smith | luqi: this ns in particular https://github.com/AvisoNovate/pretty/blob/master/src/io/aviso/exception.clj |
| 12:00 | sm0ke | (inc bja) |
| 12:00 | lazybot | ⇒ 1 |
| 12:00 | sm0ke | (inc bja) |
| 12:00 | lazybot | ⇒ 2 |
| 12:00 | justin_smith | in particular, write-exception |
| 12:00 | sm0ke | seems like i was missing the "?" in :as-arrays? |
| 12:00 | luxbock | luqi: if you are using Emacs, I find the cider-stacktrace mode you get with C-c C-s pretty helpful |
| 12:01 | sm0ke | :as-arrays? indeed is the solution! |
| 12:01 | clojer | Anyone know what this compilation error refers to: "NullPointerException clojure.lang.Numbers.ops (Numbers.java:961)" ? |
| 12:01 | justin_smith | clojer: you tried to do math on nil |
| 12:01 | justin_smith | ,(+ nil 1) |
| 12:01 | clojurebot | #<NullPointerException java.lang.NullPointerException> |
| 12:01 | bja | nice |
| 12:01 | luqi | justin_smith, yeah this looks much nicer! |
| 12:02 | clojer | justin_smith: Great, but why doesn't the error come with a line number? |
| 12:02 | luqi | luxbock: I am using Vim primarily but I'd love to learn Emacs :) |
| 12:02 | justin_smith | luqi: awesome, our own hlship (not online right now) worked on it, and introduced me to it |
| 12:02 | luxbock | I use Emacs with evil, which is pretty close to Vim |
| 12:03 | justin_smith | clojer: Numbers.java - on another stack frame you may find a line number in your own code |
| 12:03 | luqi | Aha, that's actually what I'm thinking about |
| 12:03 | clojer | justin_smith: How do I get that in Emacs/cider? |
| 12:03 | zwer | join #java |
| 12:03 | justin_smith | luxbock: luqi: as far as I am concerned, getting cider to work would be a terrible way to learn emacs |
| 12:04 | justin_smith | clojer: (pst) |
| 12:04 | clgv | ~guards |
| 12:04 | clojurebot | SEIZE HIM! |
| 12:04 | clgv | joining #java tsk tsk tsk |
| 12:05 | justin_smith | luxbock: luqi: I subscribe to that repo's issues feed, I intend to switch to cider when the bug reports slow down (if they ever do) |
| 12:05 | justin_smith | (cider's that is) |
| 12:05 | clojer | justin_smith: Brilliant. You're a life-saver. |
| 12:05 | justin_smith | clojer: np - I think the decision to only show one line of the exception by default is kind of silly |
| 12:06 | justin_smith | clojer: also you can access the last uncaught exception object thrown using *e |
| 12:06 | clojer | (pst) |
| 12:06 | luxbock | I think the cider-stracktrace mode as a more convenient version of pst |
| 12:07 | justin_smith | if you want to assign the exception to some var to do something with later, or write your own code that analyzes the exception, *e is quite handy |
| 12:07 | clojer | justin_smith: Damn. I posted this on the clojure mailing list not realising that was a truncated error message :( |
| 12:08 | justin_smith | I'm sure this isn't the first or last cider bug / cider UI deficiency that has ended up there |
| 12:09 | clojer | justin_smith: Yes and I'm stuck with cider 0.6 as I'm using Emacs Live awaiting the 0.7-compatible update :( |
| 12:09 | nbeloglazov | In order to send pull requrest/patches to libs under clojure namespace (e.g. tools.reader) do I have to sign contributor agreement? |
| 12:09 | justin_smith | ~emacslive |
| 12:09 | clojurebot | No entiendo |
| 12:10 | clojer | justin_smith: My Emacs foo is pretty non-existent :( |
| 12:10 | luxbock | is there something about Emacs Live that preventes you from getting the latest cider-version from elpa/melpa? |
| 12:10 | justin_smith | clojer: emacs live is easy to port to regular emacs, and you can even switch between the two by specifying the config files to run on launch. See also technomancy's https://github.com/technomancy/better-defaults |
| 12:11 | clojer | justin_smith: I often wondered if that could be done but never found the details. |
| 12:11 | justin_smith | luxbock: not really - but the point of emacs live is you don't want to mess with your own configs freeform yet - you want a compatible zero-effort it just works setup out of the box |
| 12:11 | justin_smith | clojer: it's doable, just not compatible with the whole "it just works" thing :) |
| 12:11 | clojer | justin_smith: Problem I had in the past was `git submodule <something or other>` wiping out my customisations |
| 12:12 | luxbock | hmm right, I think I started out with one of the starter kits and then ditched most of it once I got a handle of how things worked |
| 12:12 | justin_smith | clojer: put your .emacs.d under git version control :) |
| 12:12 | clojer | justin_smith: Yes, I like what "just works" with Emacs Live |
| 12:12 | justin_smith | luxbock: clojer: see the readme from technomancy 's better defaults repo I linked above, has a really good sumarry of the situation |
| 12:13 | clojer | justin_smith: Unfortunatley Dr. Sam Aaron is a bit tied up right now to finish testing Cider 0.7 compatibility |
| 12:14 | clojer | justin_smith: There's an update in the dev packs somewhere but I'd rather not mess about |
| 12:14 | justin_smith | fair enough, you could be patient, save yourself some pain, and wait for him to do it, or go through the pain and make it work yourself (or maybe "just barely work, good enough for now") |
| 12:15 | clojer | justin_smith: I'll defer to his greater Emacs skills. Emacs Live is great for my laziness, hubris & impatience :) |
| 12:16 | justin_smith | clojer: in terms of switching configs, the default config is ~/.emacs.d/init.el (or ~/.emacs for legacy, but that is not recommended) - you can launch emacs -q -l alternate-init.el to use a different init file |
| 12:16 | clojer | justin_smith: OK, sounds like it's worth a try. |
| 12:16 | justin_smith | this is useful while experimenting, you can copy init.el and then use -q -l to launch an emacs using the alternate, modified init |
| 12:16 | justin_smith | without breaking your default init file |
| 12:17 | riffraff | mh how does one get a vector of ints with a skewed distribution with test.check? I tried (gen/vector (gen/frequency [[ 50 gen/int 5] [50 gen/int 100]])) but it doesn't seem to work |
| 12:17 | martinklepsch | whats (go *(while true)* ... ) good for? |
| 12:18 | reiddraper | riffraff: you just need [50 gen/int 5] [50 gen/int 100] isn't a valid syntax for gen/frequency. What are you trying to achieve with that/ |
| 12:18 | justin_smith | martinklepsch: I assume that's (go (while true (do-async-things))) |
| 12:18 | martinklepsch | In clojure it seems to be the default in clojurescript it kills my browser |
| 12:19 | reiddraper | riffraff: err, ignore the 'you just need' part of that message |
| 12:19 | justin_smith | martinklepsch: related to the fact that js has no threads maybe? |
| 12:20 | riffraff | reiddraper, I was trying to say "get a frequency of 50% ints in 0..5 and 50% in 0..100" |
| 12:20 | reiddraper | riffraff: use gen/choose to create ranges |
| 12:21 | riffraff | isnot gen/choose 0 y the same as gen/int y ? |
| 12:21 | reiddraper | riffraff: (def f (gen/frequency [[50 (gen/choose 0 5)] [50 (gen/choose 0 100)]])) |
| 12:22 | dnolen_ | martinklepsch: it not the default in Clojure either - that will result in burning CPU cycles doing nothing |
| 12:22 | riffraff | mh, apparently not |
| 12:22 | riffraff | thanks! |
| 12:22 | reiddraper | riffraff: no. And if it were, you'd need parenthesis around (gen/int x) |
| 12:22 | martinklepsch | dnolen_: you're right, I had those examples wrong in my memories. |
| 12:24 | riffraff | I see, I must have tried [5 (gen/int x)], got an error, tried [5 gen/int x], saw it not exploding and moved on |
| 12:25 | martinklepsch | so in (go (while true (do-something (<! c)))) —VS— (go (do-something (<! c))) is the (while true ... useful in what scenario? |
| 12:49 | dnolen_ | martinklepsch: there aren't really cases where (while true ...) is desirable beyond demo examples, you almost always want loop/recur with some exit condition |
| 12:49 | devn | using slime + lein-swank again |
| 12:55 | justin_smith | devn: how is it? |
| 12:55 | devn | simpler |
| 12:57 | justin_smith | is that an endorsement? it sounds like an endorsement |
| 13:24 | riffraff | Okasu, one last thing I don't really understand about test.check and the above mentioned test. I'd expect to run (tc/quick-check 10 my-prop) and have it test ten random sequencies in a few seconds |
| 13:24 | riffraff | (sorry okasu, I meant "ok", darn autocomplete) |
| 13:25 | riffraff | what appears to happen is that the repl runs forever visiting tens of thousands of nodes |
| 13:34 | reiddraper | riffraff: does your test fail? |
| 13:35 | reiddraper | if so, then what you are seeing is something called shrinking. depending on your generators and property, the shrinking process may have to do a large search |
| 13:36 | clgv | reiddraper: is there a possibility to limit the shrinking search or turn it off completely. On occasions this makes sense. |
| 13:38 | reiddraper | clgv: you can wrap your generator (or even your whole property) in gen/no-shrink |
| 13:38 | reiddraper | there isn't a way (yet) to pause/cancel/limit shrinking otherwise |
| 13:41 | grincher | change the value of the string if the value contains a specific substring? Eg. map = {:a "nora", :b "sara}; if VALUE contains "nora" replace with "bob", if VALUE contains "ra" replace with "ma" etc |
| 13:42 | grincher | Sorry, how can I iterate a nested map and change the value of the string if the value contains a specific substring? Eg. map = {:a "nora", :b "sara}; if VALUE contains "nora" replace with "bob", if VALUE contains "ra" replace with "ma" etc |
| 13:42 | clgv | reiddraper: ok thx |
| 13:42 | riffraff | reiddraper, I think that may be it cause if I try to trace the checking of my property I can see it executed a ton of times, but is there a way to ask the quick-check method to fail fast? |
| 13:43 | reiddraper | riffraff: wrap the property in gen/no-shrink to disable shrinking |
| 13:43 | riffraff | ah perfect thanks |
| 13:43 | reiddraper | (tc/quick-check 10 (gen/no-shrink my-prop)) |
| 13:44 | riffraff | I didn't notice this in the docs, seems what I need thank you very much |
| 13:45 | reiddraper | riffraff: not documented at the moment |
| 13:46 | justin_smith | ,(reduce-kv (fn [m k v] (assoc m k (-> v (clojure.string/replace #"^nora$" "bob") (clojure.string/replace #"ra" "ma")))) {} {:a "nora" :b "sara"}) ; grincher |
| 13:46 | clojurebot | {:a "bob", :b "sama"} |
| 13:47 | grincher | thank you justin_smith :) |
| 13:48 | justin_smith | of course in real code you would require clojure.string :as string and string/replace |
| 13:48 | justin_smith | or something like that |
| 13:49 | justin_smith | also if you don't want the substitutions to stack, you would want a cond rather than -> |
| 13:53 | grincher | justin_smith, I am getting some "clojure.lang.LazySeq@d055e162" istead of the "bob" value |
| 13:53 | justin_smith | with what code? care to share on refheap or a gist? |
| 13:59 | gfredericks | ,(clojure.string/replace (str (range 10)) #"clojure\.lang\.LazySeq@[0-9a-f]{8}" "bob") |
| 13:59 | clojurebot | "bob" |
| 13:59 | justin_smith | lol |
| 14:00 | justin_smith | grincher: if you did a lazy op on a string, then you can get a string out the other end with (apply str ...) |
| 14:00 | justin_smith | grincher: in my example there are no lazy ops, which is why I asked to see a paste |
| 14:11 | grincher | justin_smith, https://gist.github.com/gildo/d8f3c6f7614df2368479 |
| 14:15 | justin_smith | OK - I don't see anything there where the "bzip2" value would become a lazy-seq |
| 14:15 | justin_smith | what yaml lib are you using? I will see if I can reproduce. |
| 14:17 | grincher | justin_smith, in line 3 you can find the the parsed yaml |
| 14:17 | grincher | line 3 == x |
| 14:17 | justin_smith | can you share the pr-str version? |
| 14:17 | justin_smith | that verison is not readable |
| 14:18 | justin_smith | ie. the result of (pr x) or (println (pr-str x)) |
| 14:19 | grincher | justin_smith, gist updated |
| 14:19 | grincher | I'am using [circleci/clj-yaml "0.5.2"] |
| 14:22 | martinklepsch | I'm trying to write a transducer that takes a map and runs a few api calls based on the maps input, kind of pipelining the output of the first transducer function to the second and so on. |
| 14:23 | justin_smith | grincher: https://www.refheap.com/89666 I get bob as expected (see the last line) |
| 14:24 | justin_smith | I do see some lazy-seq output there though! I see what you mean. |
| 14:24 | martinklepsch | now I have a function that looks kind of like the following https://gist.github.com/mklappstuhl/67a7cde18575ecf4e39d — point is it takes a callback function to return it's result. how do I properly feed that back into the flow of the transducing function? |
| 14:25 | martinklepsch | do I put it in a channel and take from that channel at the end of that function? |
| 14:26 | martinklepsch | am I maybe on the wrong path using transducers here? |
| 14:27 | Bronsa | ,(clojure.string/replace (range 10) #"" "") |
| 14:27 | clojurebot | "clojure.lang.LazySeq@9ebadac6" |
| 14:27 | Bronsa | justin_smith: ^ |
| 14:27 | justin_smith | grincher: https://www.refheap.com/89666 updated, no longer tries to regex replace non-strings |
| 14:27 | justin_smith | Bronsa: yeah, I just caught that :) |
| 14:28 | justin_smith | I guess I can take the apply str out to, for that matter |
| 14:31 | justin_smith | grincher: of course you may want to go deeper and recursively work on some of the values that are not strings, updating the strings inside, but what's there should be a start |
| 14:33 | grincher | thank you justin_smith |
| 14:35 | justin_smith | np |
| 14:40 | justin_smith | ,(update-in {:a {:b "value"}} [:a :b] str " modified") ; grincher |
| 14:40 | clojurebot | {:a {:b "value modified"}} |
| 14:46 | joobus | can someone give me an example of how to use with-open? I was using slurp to fetch a webpage in the repl, but then if i fetched the same page again the output was all garbled. I think it had something to do with not closing the file descriptor. |
| 14:47 | justin_smith | joobus: slurp closes the file descriptor |
| 14:47 | joobus | hmmm |
| 14:47 | justin_smith | joobus: and generally, things like streams get closed properly if they go out of scope in the jvm. |
| 14:48 | justin_smith | and given that the stream slurp opens never enters your scope... |
| 14:48 | joobus | i guess it was the page i was slurping then |
| 14:48 | tenchi | ?reduce |
| 14:49 | justin_smith | ~reduce |
| 14:49 | clojurebot | reduce accumulates the men from the boys |
| 14:49 | justin_smith | haha |
| 14:49 | tenchi | justin_smith: Haha...no just a chat issue (not clojure). |
| 14:49 | justin_smith | oh, OK |
| 14:50 | llasram | joobus: Are you passing `slurp` the URL for a page, or something you opened yourself via e.g. `clojure.java.io/reader` ? |
| 14:50 | joobus | (slurp "http://zerohedge.com") |
| 14:50 | justin_smith | llasram: oh, good point, I don't even think about that usage |
| 14:50 | llasram | justin_smith: But you were apparently correct anyway :-) |
| 14:50 | joobus | sometimes it comes back with messed up output, like the charset was wrong or something |
| 14:51 | ben_vulpes | I'm using peridot to test some forms with file uploads - does anyone know how to use the peridot (request "/upload" :request-method :post :params {:some "values" :file (file "resources/myfile.txt")) in such a way that it posts all the values in addition to the multipart file? or am i missing something important in how multipart uploads works? |
| 14:51 | justin_smith | joobus: sounds like a problem on their end to me, maybe they are load balancing and some of their servers are sending bad content encoding headers |
| 14:51 | ben_vulpes | hm i guess if i use a map keyword other than "file" all the headers come through |
| 14:52 | joobus | yeah, that sounds reasonably accurate |
| 14:52 | justin_smith | joobus: you could try putting the string into a byte-array, then coercing it back to string with various encoding arguments |
| 14:53 | joobus | tbh, i don't particularly care about that site, i was just testing out slurp |
| 14:53 | justin_smith | &(-> "snowman ☃" .getBytes (String. "UTF-8")) |
| 14:53 | lazybot | ⇒ "snowman ☃" |
| 14:53 | justin_smith | &(-> "snowman ☃" .getBytes (String. "UTF-16")) |
| 14:53 | lazybot | ⇒ "獮潷浡渠�" |
| 15:06 | ricky____ | I'm going through the unless macro example from Clojure in Action and wondering why when unless is a function, the 'then' portion of the 'if' doesn't get evaluated twice when it's true. |
| 15:07 | ricky____ | If it's easier to understand this as code, why does (exhibits-oddity? 7) not show 'Very odd, indeed!' twice? @ http://pastebin.com/JfbjW4QT |
| 15:07 | justin_smith | ricky____: then is fully evaluated before the function even sees it |
| 15:08 | justin_smith | unless only sees the fully evaluated form - the printing happens before unless even runs |
| 15:08 | ricky____ | So what does unless actually see as its second argument? |
| 15:09 | justin_smith | the return value of the form provided as a second arg |
| 15:09 | ricky____ | So since it's println, it gets nil? |
| 15:09 | justin_smith | in exhibits-oddity? the value is nil |
| 15:09 | justin_smith | yes |
| 15:11 | justin_smith | ,(letfn [(unless [test then] (println "in unless") (if (not test) (do then (println "unless done"))))] (unless (even? 1) (println "arg to unless"))) |
| 15:11 | clojurebot | arg to unless\nin unless\nunless done\n |
| 15:11 | justin_smith | that should make it clear |
| 15:15 | bcm | does anyone here use emacs with add-on packages? |
| 15:15 | bcm | www.elgethub.com |
| 15:17 | thesaskwatch | Hi .. is there some simpler / idiomatic mechanism for pub-sub pattern than atom and adding watches to it? |
| 15:18 | justin_smith | thesaskwatch: you can do pub-sub nicely with core.async |
| 15:18 | justin_smith | http://yobriefca.se/blog/2014/06/04/publish-and-subscribe-with-core-dot-asyncs-pub-and-sub/ |
| 15:19 | thesaskwatch | justin_smith: ok, but my use case uses blocking i/o |
| 15:22 | justin_smith | thesaskwatch: what about blocking from outside the go block, and sending to a channel when the io completes? |
| 15:22 | justin_smith | or doing a blocking read from outside a go block, before a blocking write outside a go block, for that matter |
| 15:23 | thesaskwatch | justin_smith: I'm not sure how all those mechanisms are gonna work together. I'm wring an irc client. I'd like to be able to start it and send/receive messages asyncronously (which is a hint for core.async, true). |
| 15:24 | justin_smith | thesaskwatch: all that said, there is pubsub via 0mq http://zguide.zeromq.org/clj:psenvsub |
| 15:24 | thesaskwatch | justin_smith: so I guess I could start a thread within this client and return two channels |
| 15:24 | thesaskwatch | wring -> writing |
| 15:25 | justin_smith | so, if you want to send / receive messages, what about having a go block doing pub sub with an input channel and output channel, then writing to the input and reading the output from your other threads? |
| 15:25 | schmee | thesaskwatch: I'm doing a client server thing as well, I have a thread that just reads things of the socket and push them onto a channel |
| 15:25 | justin_smith | all the IO can be on the outside of the go block |
| 15:25 | schmee | then all the other communication happens over channels |
| 15:26 | justin_smith | schmee: yeah, what thesaskwatch needs sounds like that plus a third thread that writes out to the TCP connection again |
| 15:27 | thesaskwatch | I actually don't mind using a real thread, there will be no many connections |
| 15:27 | milos_cohagen | thesaskwatch: i wrote a wrapper for netty and core async https://github.com/marsmining/nettyca it's an example for simple tcp server |
| 15:27 | thesaskwatch | milos_cohagen: thanks, I'll take a look |
| 15:27 | schmee | justin_smith: yep, that's how I'm doing it now |
| 15:28 | milos_cohagen | thesaskwatch: maybe you could write the client code :) |
| 15:28 | schmee | thesaskwatch: it seems to work pretty well, although I have no experience whatsoever in writing servers |
| 15:28 | thesaskwatch | milos_cohagen: yeah, I have to wrap my head around it first :) |
| 15:29 | thesaskwatch | schmee: could you share the code with me? |
| 15:30 | thesaskwatch | schmee: or is it proprietary? |
| 15:33 | phuu | hey #clojure. core.async question. why does alts! get priority if I <! then alts! in separate go blocks? gist here https://gist.github.com/phuu/32ab6737141d989ea280 |
| 15:34 | phuu | given (def c (chan)) and (def c2 (chan)) |
| 15:34 | dnolen_ | phuu: it doesn't get priority, you should assume the behavior is non-deterministic |
| 15:37 | phuu | dnolen_: ah, ok. i must have just got the same result a few times in a row. |
| 15:38 | phuu | dnolen_: is this true of multiple takes? if i <! 3 times then >!, is the choice also non-deterministic? |
| 15:39 | dnolen_ | phuu: yes |
| 15:39 | phuu | Ahha! |
| 15:39 | phuu | right. well, i got my JS channel implementation wrong then |
| 15:39 | milos_cohagen | phuu: assuming the takes are each in their wn go block |
| 15:40 | milos_cohagen | *own |
| 15:40 | phuu | milos_cohagen: right |
| 15:45 | phuu | ok, thanks both |
| 16:29 | SagiCZ1 | any easy way to destructure map within map? |
| 16:30 | SagiCZ1 | (let [<desctructuring> {:a {:x 0 :y 2} :b 3}] ... get 0 and 2 .. |
| 16:31 | llasram | SagiCZ1: yeah -- destructuring nests |
| 16:31 | xeqi | ,(let [{:a {:keys [x y]}} {:a {:x 0 :y 2} :b 3}] [x y]) |
| 16:31 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: x in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 16:32 | llasram | ,(let [{{:keys [x y]} :a} {:a {:x 0 :y 2} :b 3}] [x y]) |
| 16:32 | clojurebot | [0 2] |
| 16:32 | xeqi | bah |
| 16:32 | Bronsa | heh |
| 16:32 | llasram | zoom |
| 16:33 | SagiCZ1 | ok.. i thought it was possible.. thank you guys |
| 16:33 | Bronsa | TBH I Never use "multiple levels" destructuring, it gets kinda noisy IMHO |
| 16:34 | xeqi | agreed, I usually just make another binding in the let |
| 16:40 | SagiCZ1 | why does this not work? |
| 16:40 | SagiCZ1 | ,(apply String. "hello" ["world" "!"]) |
| 16:40 | clojurebot | #<CompilerException java.lang.ClassNotFoundException: String., compiling:(NO_SOURCE_PATH:0:0)> |
| 16:40 | SagiCZ1 | cant apply on constructors? |
| 16:40 | SagiCZ1 | could the exception get any more stupid? |
| 16:41 | xeqi | "error" |
| 16:42 | SagiCZ1 | yeah.. but seriously class not found? how did it even get to THAT |
| 16:42 | hyPiRion | SagiCZ1: String. is not a class |
| 16:43 | hyPiRion | (String. ..) is syntactic sugar for (new String ..) |
| 16:44 | hyPiRion | ,(macroexpand '(String. "foo")) |
| 16:44 | clojurebot | (new String "foo") |
| 16:44 | hyPiRion | ,(macroexpand '(apply String. "foo" ["bar" "baz"])) |
| 16:44 | clojurebot | (apply String. "foo" ["bar" "baz"]) |
| 16:44 | SagiCZ1 | ,(apply (partial new String) "hello" ["world" "!"]) |
| 16:44 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: new in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 16:45 | hyPiRion | and new is a macro, heh. |
| 16:45 | SagiCZ1 | >:C |
| 16:45 | llasram | SagiCZ1: Unfortunately you can only `apply` functions, and there's nothing built into Clojure for turning constructors into functions |
| 16:45 | SagiCZ1 | ,(macroexpand '(new String "foo)) |
| 16:45 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading string> |
| 16:45 | SagiCZ1 | ,(macroexpand '(new String "foo))) |
| 16:45 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading string> |
| 16:46 | hyPiRion | forgot a " |
| 16:46 | SagiCZ1 | ,(macroexpand '(new String "foo")) |
| 16:46 | clojurebot | (new String "foo") |
| 16:46 | SagiCZ1 | wat |
| 16:46 | SagiCZ1 | is it a special macro then? |
| 16:46 | hyPiRion | yes. it's a core macro. |
| 16:47 | hyPiRion | It's probably better to call it a special form (?) |
| 16:47 | SagiCZ1 | mmkay.. no apply for me then.. |
| 16:47 | SagiCZ1 | well i could wrap the constructor in a function if i wanted |
| 16:54 | ben_vulpes | has anyone ever seen wrap-multipart-params fail to do the expected tempfile behavior? |
| 16:57 | blaenk | I'm wondering if I create an uberjar out of my program, how can I handle (can I?) external configuration files? so preferably I'd like for a configuration file to be along-side the jar file, not within it, so that it can easily be edited |
| 16:59 | ben_vulpes | blaenk: i uberjar my apps and launch them in docker containers with environment variables |
| 16:59 | blaenk | cool |
| 16:59 | ben_vulpes | course, that entails all sorts of other overhead in deploy... |
| 17:00 | xeqi | ben_vulpes: expected tempfile behavior? I've had problems when I attempted to read it twice |
| 17:02 | ben_vulpes | xeqi: i'm failing to even get wrap-multipart-params to write the file to disk instead of reading it in as a...string? |
| 17:03 | mi6x3m | if x is a function returning a function |
| 17:03 | mi6x3m | is there a saner way to call the result than ((x)) ? |
| 17:03 | ben_vulpes | in the "file" paramter in :multipart-params, i'm just getting a string and in the body of the request I'm getting a buffered input stream. |
| 17:03 | ben_vulpes | mi6x3m: what's insane about ((x))? |
| 17:04 | mi6x3m | dunno, looks kinda funny |
| 17:05 | ben_vulpes | dem parens |
| 17:05 | lodin | mi6x3m, I guess you could do (apply (x) [...]), but I would hesitate to call that saner. |
| 17:05 | catern | (trampoline x) |
| 17:05 | catern | (please don't) |
| 17:06 | jjido | catern: hey, I like trampoline ;) |
| 17:06 | catern | jjido: i do too :) |
| 17:06 | jjido | catern: for trampoline work though |
| 17:06 | catern | but i was just joking, please don't use it for this |
| 17:07 | catern | unles you're |
| 17:07 | catern | trampolining an algorithm |
| 17:07 | catern | in which case, do use it |
| 17:08 | lodin | Particularly, don't use it if ((x)) can return a function. |
| 17:10 | lodin | Is there any function f such that (into (empty x) (f x)) is the same as x, other than #(into (empty %) %)? |
| 17:12 | catern | id |
| 17:13 | catern | er, identity |
| 17:13 | lodin | catern, identity fails for lists. |
| 17:14 | catern | `(into (empty '(42)) (identity '(42))) |
| 17:14 | catern | er |
| 17:14 | catern | ,(into (empty '(42)) (identity '(42))) |
| 17:14 | clojurebot | (42) |
| 17:15 | lodin | ,(let [f identity x '(1 2 3)] (into (empty x) (f x))) |
| 17:15 | clojurebot | (3 2 1) |
| 17:15 | catern | oh, right |
| 17:16 | gfredericks | lodin: so your #(into (empty %) %) works because it reverses a list twice? |
| 17:16 | lodin | gfredericks: right. |
| 17:16 | lodin | gfredericks: Not a very nice solution. |
| 17:16 | gfredericks | lodin: why on earth do you need such a thing? |
| 17:17 | lodin | gfredericks: Makes it easier to deal with mixed seqables when the return type is important. |
| 17:18 | llasram | lodin: If the return type is important, your function should return an instance of the correct type |
| 17:19 | llasram | lodin: I can't think of a situation where I've needed a function which took either a list or lazy seq or a vector and was guaranteed to returned an instance of the same type |
| 17:20 | bcm | hi clj-learner |
| 17:20 | amalloy | llasram: well, conj |
| 17:20 | clj-learner | hi |
| 17:20 | llasram | amalloy: pfft, fine :-p |
| 17:20 | llasram | But just `conj` |
| 17:21 | gfredericks | also into |
| 17:21 | lodin | llasram: Right, and into uses conj. |
| 17:21 | gfredericks | and intos uses into and multi-intos uses intos |
| 17:29 | hyPiRion | Where's fmap when we need it |
| 17:29 | lodin | llasram, Consider (defn map-generic [f x] (into (empty x) (map f (into (empty x) (seq x))))) |
| 17:30 | lodin | then (= (map-generic inc [1 2 3]) [2 3 4]) and (= (map-generic inc #{1 2 3}) #{2 3 4}) and (= (map-generic #(update-in % [1] inc) {:a 1 :b 2 :c 3}) {:a 2 :b 3 :c 4}) |
| 17:31 | llasram | lodin: I honestly have difficulty imagining wanting that :-) |
| 17:31 | hyPiRion | lodin: huh, I'm not sure the last example is correct |
| 17:32 | hyPiRion | I think you want (fn [[k v]] [k (inc v)]) instead of that anonymous function |
| 17:33 | gfredericks | ,(defn applicate [& fs] (fn [& vals] (mapv #(%1 %2) fs vals))) |
| 17:33 | clojurebot | #'sandbox/applicate |
| 17:33 | gfredericks | ,((applicate identity inc) [:foo 41]) |
| 17:33 | clojurebot | [[:foo 41]] |
| 17:33 | gfredericks | oh right |
| 17:33 | lodin | ,(defn map-generic [f x] (into (empty x) (map f (into (empty x) (seq x))))) |
| 17:33 | clojurebot | #'sandbox/map-generic |
| 17:33 | hyPiRion | lodin: however, have you looked at fluokitten? it provides an fmap function |
| 17:33 | lodin | (= (map-generic #(update-in % [1] inc) {:a 1 :b 2 :c 3}) {:a 2 :b 3 :c 4}) |
| 17:34 | lodin | ,(= (map-generic #(update-in % [1] inc) {:a 1 :b 2 :c 3}) {:a 2 :b 3 :c 4}) |
| 17:34 | clojurebot | true |
| 17:34 | hyPiRion | lodin: ohh |
| 17:37 | zwer | llasram the idea is that the caller picked an approriate sequence type, and that the function that is processing it generically shouldn't change it |
| 17:39 | llasram | zwer: Sure, I get the idea. I just disagree that it is (very often) useful |
| 17:44 | lodin | llasram: I figured (empty x) and (conj) is for situations when you want to deal more generally with a collection. |
| 17:54 | SagiCZ1 | hi.. how do i get the first element from seq of maps that has 0 as a value of :number? [{:number 6 :a 0} {:number 0 :a 3}] --->{:number 0 :a 3} |
| 17:55 | llasram | SagiCZ1: (first (filter (comp zero? :number) ...)) |
| 17:56 | luqi | SagiCZ1: also you can use some |
| 17:57 | luqi | (some (comp zero? :number)) |
| 17:57 | amalloy | luqi: try that; it won't work |
| 17:58 | SagiCZ1 | yeah comp will be handy |
| 17:58 | gfredericks | clojurebot: amalloy is <reply> try that; it won't work |
| 17:58 | clojurebot | 'Sea, mhuise. |
| 17:59 | luqi | hmm, I see. |
| 18:00 | luqi | my bad. some won't work |
| 18:11 | martinklepsch | (def xform (comp (map fetch-data) (map munge-data))) |
| 18:11 | martinklepsch | is that something transformers are meant for? |
| 18:13 | martinklepsch | I have a fn that I want to map over a seq that has side effects and I'm not sure how to do that or if it's the right thing at all |
| 18:14 | justin_smith | martinklepsch: do you want both the side effects and the results? |
| 18:17 | martinklepsch | justin_smith: yes. I'm trying to implement some sort of pipeline: channel-in > fetch-data > do something with data > return result of last function in pipeline |
| 18:19 | martinklepsch | I was initially thinking about using map< for that but now I'm not even sure if that would have been the right approach |
| 18:25 | justin_smith | reduce is eager, and you can build up your result either element by element or by accumulating a total, whichever is apropriate |
| 18:28 | martinklepsch | justin_smith: so in my case element by element is what I want, right? do you think the scenario I described makes sense for using transducers? |
| 18:29 | justin_smith | it really does (from what I have seen - have not used transducers yet myself, but this looks right for them) |
| 18:46 | martinklepsch | justin_smith: ok, thats reassuring enough to keep digging :) |
| 18:46 | martinklepsch | thanks |
| 18:56 | martinklepsch | justin_smith: pipeline-async looks exactly like what I'm trying to do: https://github.com/clojure/core.async/blob/e7de6747e5d90e08fb9d6d6dbe41c2bdd1ef00a0/src/main/clojure/clojure/core/async.clj#L523 |
| 19:57 | lavokad | why :keys can only be bind to symbols which the same names as the keys? |
| 19:57 | amalloy | lavokad: :keys is shorthand for doing exactly that; if you want to give explicit names, use the longhand map-destructuring form |
| 19:58 | amalloy | ,(let [m {:xpos 1, :ypos 2}, {x :xpos, y :ypos} m] [x y]) |
| 19:58 | clojurebot | [1 2] |
| 21:00 | zanes | Is there a built-in function that takes a seq and returns the same seq with repeating values removed? |
| 21:00 | zanes | I feel like this exists, but I can’t find it. |
| 21:01 | tac_ | like a uniq? |
| 21:02 | zanes | For example, (non-repeating [1 1 1 2 3 3 1]) ; => (1 2 3 1) |
| 21:02 | zanes | It’s pretty simple to write. |
| 21:03 | amalloy | &(doc distinct) |
| 21:03 | lazybot | ⇒ "([coll]); Returns a lazy sequence of the elements of coll with duplicates removed" |
| 21:03 | amalloy | oh, but you want to remove only consecutive duplicates |
| 21:04 | amalloy | &(map first (partition-by identity [1 1 1 2 3 3 1])) |
| 21:04 | lazybot | ⇒ (1 2 3 1) |
| 21:06 | zanes | amalloy: So, I tried that, but I’m in a situation where the second value of the lazy sequence being consumed may take a while. |
| 21:06 | zanes | I’d love for the first value to be realized immediately, rather than only after a change happens. |
| 21:06 | zanes | Does that follow? |
| 21:06 | amalloy | sure. you have to write that yourself, but it's not hard |
| 21:06 | zanes | Okay, great. |
| 21:07 | Ifiht | '(def s "lorem ipsum datum") |
| 21:08 | Ifiht | '(def s "lorem\u000A ipsum\u000A datum\u000A") |
| 21:08 | Ifiht | '(println s) |
| 21:09 | Ifiht | oh darn, no clojurebot. |
| 21:10 | justin_smith | ,"Hello Ifiht" |
| 21:10 | clojurebot | "Hello Ifiht" |
| 21:10 | Ifiht | ,8 |
| 21:10 | clojurebot | 8 |
| 21:10 | Ifiht | ,"Thanks justin" |
| 21:10 | clojurebot | "Thanks justin" |
| 21:11 | Ifiht | ,(def s "lorem\u000A ipsum\u000A datum\u000A") |
| 21:11 | clojurebot | #'sandbox/s |
| 21:11 | Ifiht | ,(println s) |
| 21:11 | clojurebot | lorem\n ipsum\n datum\n\n |
| 21:11 | Ifiht | ,(def s "lorem ipsum\u000A datum\u000A") |
| 21:11 | clojurebot | #'sandbox/s |
| 21:11 | Ifiht | ,(def s "lorem\u000A ipsum\u000A datum\u000A") |
| 21:11 | clojurebot | #'sandbox/s |
| 21:12 | zanes | amalloy: Something like this? https://gist.github.com/zane/33a5b77162441ec3a25e |
| 21:12 | Ifiht | ,(def s (split s #"\u000A")) |
| 21:12 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: split in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 21:12 | Ifiht | ,(def s (clojure.string/split s #"\u000A")) |
| 21:12 | clojurebot | #'sandbox/s |
| 21:12 | Ifiht | ,(def s (sort s)) |
| 21:12 | clojurebot | #'sandbox/s |
| 21:13 | justin_smith | Ifiht: does \u work the same way in regexes? |
| 21:13 | Ifiht | It does in my code, let's see |
| 21:13 | Ifiht | ,(print s) |
| 21:13 | clojurebot | ( datum ipsum lorem) |
| 21:14 | justin_smith | it would sort weird because of the the leading spaces though |
| 21:14 | Ifiht | yes |
| 21:14 | Ifiht | (def s (clojure.string/trim-whitespace s)) |
| 21:14 | Ifiht | ,(def s (clojure.string/trim-whitespace s)) |
| 21:14 | clojurebot | #<CompilerException java.lang.RuntimeException: No such var: clojure.string/trim-whitespace, compiling:(NO_SOURCE_PATH:0:0)> |
| 21:15 | Ifiht | ,(def s (clojure.string/trim s)) |
| 21:15 | clojurebot | #<CompilerException java.lang.ClassCastException: clojure.lang.ArraySeq cannot be cast to java.lang.CharSequence, compiling:(NO_SOURCE_FILE:0:0)> |
| 21:15 | amalloy | zanes: yes, that's a fine implementation. i would make a few changes: (1) "last" is a pretty confusing name; i'd call it "prev". (2) i would start each arity with (lazy-seq ...) instead of putting it in the middle; (3) you should use when-first instead of when-let/first (especially because your implementation is broken for seqs containing nil or false) |
| 21:15 | zanes | Great feedback. Thanks! |
| 21:15 | Ifiht | ,(def s "lorem ipsum datum") |
| 21:15 | clojurebot | #'sandbox/s |
| 21:16 | Ifiht | ,(def s (clojure.string/split s #"\u0020")) |
| 21:16 | clojurebot | #'sandbox/s |
| 21:16 | Ifiht | ,(print s) |
| 21:16 | zanes | Is it always more idiomatic to start each arity with lazy-seq? |
| 21:16 | clojurebot | [lorem ipsum datum] |
| 21:16 | Ifiht | got it |
| 21:16 | amalloy | zanes: there are probably some exceptions, but none spring to mind |
| 21:17 | Ifiht | ,(def s (join (str "(latin)" \u000A) s)) |
| 21:17 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: join in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 21:18 | justin_smith | Ifiht: you can send messages to clojurebot |
| 21:18 | justin_smith | Ifiht: unless there is something you are trying to show all of us |
| 21:18 | justin_smith | or even run your own repl locally |
| 21:18 | Ifiht | yes, I have it working locally, but clojurebot doesn't have my code, one step left? |
| 21:19 | Ifiht | ,(def s (clojure.string/join (str "(latin)" \u000A) s)) |
| 21:19 | clojurebot | #'sandbox/s |
| 21:19 | Ifiht | YES |
| 21:19 | Ifiht | ,(println s) |
| 21:19 | clojurebot | lorem(latin)\nipsum(latin)\ndatum\n |
| 21:19 | Ifiht | THERE!!! ^ |
| 21:19 | Ifiht | can anyone tell me why join skips the last item? |
| 21:20 | justin_smith | it only goes between items |
| 21:21 | amalloy | Ifiht: also instead of writing a million separate lines with def, collapse it all into one form with let |
| 21:22 | Ifiht | would let still work if I want to use the same identifier? |
| 21:23 | justin_smith | you can repeat ids in let |
| 21:23 | llasram | ,(let [s 1, s (inc s)] s) |
| 21:23 | clojurebot | 2 |
| 21:23 | justin_smith | ,(let [s "a" s (str s "b") s (str s "c")] s) |
| 21:23 | clojurebot | "abc" |
| 21:24 | Ifiht | Thanks justin, amalloy. I'll do that. |
| 21:26 | bounb | do you clojure-heads have the feeling you could never go back to your C++/Java days |
| 21:27 | justin_smith | bounb: horses for courses |
| 21:27 | justin_smith | there are certain things I would never do in c++/java, other things I would never do in clojure |
| 21:28 | justin_smith | though personally for lower level stuff I would skip straight from c to java and not touch c++ if it was purely up to me |
| 21:28 | bounb | hm so it's philosophy does not revolutionize they way you approach programming |
| 21:28 | justin_smith | oh it does |
| 21:28 | justin_smith | but there are some things clojure will never be good at |
| 21:28 | justin_smith | but the set of things c will never be good at is larger |
| 21:30 | bounb | "never" meaning "due to some actually existing irreparable theoretical shortcoming"? |
| 21:30 | justin_smith | bounb: for example there are certain tasks in clojure where even (especially) an experienced clojure dev will tell you you are better off writing some java code rather than trying to do that task in pure clojure |
| 21:31 | justin_smith | bounb: heap allocated persistent data structures are bad for realtime, and are not cache-line friendly |
| 21:31 | justin_smith | for example |
| 21:31 | bounb | wow ok |
| 21:31 | bounb | my bubble is slightly deflated |
| 21:32 | justin_smith | also, clojure has to be able to redefine certain things at runtim - which is terrible for your heap usage - it won't really fit in embedded |
| 21:32 | bounb | aha |
| 21:32 | justin_smith | all that said, clojure is awesome - it isn't perfect for all tasks though |
| 21:32 | zanes | amalloy: Out of curiosity, how would you do it without multiple arities? |
| 21:32 | bounb | so you have to make considerations of hardware to find the negatives? |
| 21:33 | bounb | that doesn't bother me. storage/computation is bigger and faster day by day |
| 21:33 | amalloy | zanes: (defn whatever [xs] ((fn [xs prev] (lazy-seq ...)) (rest xs) (first xs))) |
| 21:33 | zanes | Ah, okay. |
| 21:34 | justin_smith | bounb: it's more like knowing what your limitations are - if your requirements include low ram usage, fast startup time, low gc churn, or cache friendliness / low latency, than clojure is likely not a good fit. But much of programming does not have these limitations. |
| 21:34 | amalloy | and that is actually how i would write it: i generally prefer helper lambdas over multiple arities. but i don't think it's important enough to suggest it as a critique |
| 21:34 | zanes | Cool. Thanks! |
| 21:34 | bounb | justin_smith: well said. thanks |
| 21:35 | justin_smith | np |
| 21:35 | bounb | i'm just a smitten newbie |
| 21:35 | bounb | watched several hours of hickey talks in the past couple days |
| 21:36 | justin_smith | cool, he is a good speaker |
| 21:36 | bounb | yeah absolutely |
| 21:36 | bounb | which other speakers in the programming/comp sci world are on his level |
| 21:38 | justin_smith | I saw a Rob Pike speak once, he was pretty good |
| 21:38 | bounb | i see him almost like a prophet, a visionary the way he speaks (ok sounds a bit sycophantic but honestly) |
| 21:38 | bounb | yeah! i like rob pike too |
| 21:38 | bounb | seen a couple great talks from him on go/concurrency |
| 21:40 | bounb | hickey is basically showing me everything i thought i knew about programming is wrong |
| 21:41 | bounb | it can be really simple |
| 21:42 | zanes | amalloy: That’ll drop the first value, no? |
| 21:42 | amalloy | zanes: yes, you need to be more careful than i was; i just wanted to show you the structure of the helper-function skeleton |
| 21:46 | zanes | bounb: Maybe Joe Armstrong? |
| 21:46 | bounb | thanks! |
| 21:53 | bounb | justin_smith: related question then. does your job impose those limitations - if not, do you use clojure at work? |
| 21:53 | justin_smith | bounb: yup, I do backend for web stuff, and use clojure |
| 21:54 | justin_smith | and I love it |
| 21:54 | justin_smith | (inc clojure) |
| 21:54 | lazybot | ⇒ 19 |
| 21:54 | bounb | ah that is good to hear |
| 21:54 | bounb | (inc clojure) |
| 21:54 | lazybot | ⇒ 20 |
| 21:54 | bounb | is this like a karma system |
| 21:54 | justin_smith | $karma clojure |
| 21:54 | lazybot | clojure has karma 20. |
| 21:54 | justin_smith | indeed it is :) |
| 21:55 | justin_smith | it looks like clojure code, but really it is just a command for the bot |
| 22:00 | bounb | (repeatedly (partial inc bounb)) |
| 22:00 | bounb | am i doing it right?! |
| 22:00 | justin_smith | it's just a pseudo-syntax |
| 22:00 | justin_smith | also, the partial wouldn't execute |
| 22:01 | justin_smith | ,(repeatedly (partial + 1)) |
| 22:01 | clojurebot | (1 1 1 1 1 ...) |
| 22:01 | bounb | disappointed :( |
| 22:01 | justin_smith | or wait, yeah it would |
| 22:01 | justin_smith | d'oh |
| 22:01 | bounb | B) |
| 22:01 | bounb | (tbh i tested it first) |
| 22:01 | bounb | (inc bounb) |
| 22:01 | lazybot | You can't adjust your own karma. |
| 22:02 | bounb | foiled! |
| 22:04 | iamdustan | I’m just starting to learn clojure so decided to do some codeeval challenges with it |
| 22:04 | iamdustan | but I am always blowing the memory constraints of codeeval |
| 22:04 | iamdustan | anyone else experience this? |
| 22:05 | justin_smith | if they have ram limits, that's gonna be rough on clojure |
| 22:05 | tac_ | iamdustan: what are codeeval challenges? |
| 22:05 | justin_smith | https://www.codeeval.com/ |
| 22:05 | iamdustan | e.g. simple sorting. my memory usage is 65413120 bytes |
| 22:05 | bounb | the copy on that site is funny |
| 22:06 | tac_ | iamdustan: are you using recursion? |
| 22:06 | bounb | "unlock exclusive hacker deals" |
| 22:06 | justin_smith | iamdustan: yeah, clojure needs to load the whole language into memory at runtime (though arrdem tried to change that - but it looks like that will become a different language) |
| 22:06 | iamdustan | with this code: https://gist.github.com/iamdustan/83d8f3c8759e31eb0f74 |
| 22:07 | iamdustan | bounb: haha yeah let’s pretend it doesn’t say that |
| 22:07 | iamdustan | tac_: I don’t believe I am |
| 22:07 | justin_smith | iamdustan: what's with the redundant vec call on line 7? |
| 22:07 | iamdustan | bounb: the design of that site is just as bad as the copy. |
| 22:07 | iamdustan | justin_smith: oh nice. I didn’t even realize I had done that when I added the map |
| 22:08 | bounb | yeah it's so cheesy |
| 22:08 | bounb | "Incredible profile pages that allow you to show the info you want while protecting your privacy." |
| 22:08 | justin_smith | iamdustan: that will help with ram a little - but the main factor unless your task is huge is going to be the huge resident size of clojure itself |
| 22:08 | bounb | WOW what a great feature so generous |
| 22:09 | bounb | sorry i'm not helping you |
| 22:09 | iamdustan | bounb: you are adding to my nightly entertainment :) |
| 22:10 | bounb | haha good |
| 22:10 | iamdustan | I realized why I have no stackoverflow answers for anything...all the attempted answers I’ve begun to write were troll-ish in nature. |
| 22:10 | bounb | i can't wait to redeem an Exclusive Hacker Deal IRL! |
| 22:11 | iamdustan | justin_smith: thanks a lot. Good to know that even though clojure is “supported” it’s not possible to pass their requirements. |
| 22:11 | iamdustan | bounb: http://cl.ly/image/1c0q0p2n3W0s |
| 22:12 | bounb | LOL |
| 22:12 | justin_smith | iamdustan: you could suggest they look at the baseline size mem usage wise of "lein repl", and only count usage past that, but it seems like that would require reworking their whole deal |
| 22:12 | iamdustan | We recommend everything |
| 22:12 | bounb | they so keen to sell yr info to other companies |
| 22:12 | bounb | "Not recommended" |
| 22:12 | iamdustan | oh yeah. the “actually” private one |
| 22:12 | bounb | because then we can't monetize you |
| 22:13 | iamdustan | justin_smith: good idea. it’d be nice to at least see my own success progress through these. |
| 22:13 | dbasch | iamdustan: https://getsatisfaction.com/codeeval/topics/clojure_time_memory_stats_seem_wrong |
| 22:15 | iamdustan | dbasch: I just started reading that same thread |
| 22:15 | iamdustan | from 2013 so you’d think something would be fixed by now |
| 22:17 | iamdustan | and that thread proves justin_smith correct |
| 22:17 | justin_smith | also, regarding the comment on that page that "clojure needs the whole jvm" - the jvm is lazily loaded to some degree, the real bottleneck is that it needs the whole of clojure compiled and in memory at runtime |
| 22:18 | andrewchambers | dnolen_: I found the thing I was talking about before http://bddbddb.sourceforge.net/ . I don't know if its the sort of thing you are interested, datalog, binary decision diagrams and program anaylsis. |
| 22:18 | dnolen_ | andrewchambers: I'm aware of it :) |
| 22:18 | bounb | pop poll: who here is not a linux user |
| 22:18 | justin_smith | iamdustan: and that's the nature of clojure - they are just measuring things in a way that is not friendly to this language |
| 22:18 | andrewchambers | cool :) |
| 22:18 | catern | bounb: are you a Linux user? |
| 22:18 | bounb | no comment |
| 22:19 | catern | i see |
| 22:19 | catern | you are interested in switching |
| 22:19 | catern | well do so |
| 22:19 | andrewchambers | I liked the part where they said pointer anaylsis was 10 times less code and ran a bit faster in datalog |
| 22:20 | catern | it saves so much effort in the long run |
| 22:20 | zanes | Is there a reason why clojure.core functions like distinct don’t have a 0-arity version that returns a transducer? |
| 22:21 | justin_smith | catern: as a linux user of 15+ years now, I'll have to say it can also be a huge pain in the ass. But if you don't play flashy games or do graphic design work and you like good command line tools, it's great. |
| 22:21 | bounb | catern: nah, i am a fairly long time user. just wanting to confirm my suspicion that this community is pretty much a subset of the community of linux users |
| 22:21 | iamdustan | justin_smith: thanks for the help. |
| 22:21 | justin_smith | iamdustan: np, too bad about how they are scoring our favorite language |
| 22:22 | bounb | justin_smith: well said again about linux |
| 22:22 | catern | bounb: oh okay. well in that case, no, there's probably a lot of OS X users around, judging by today's sad trends |
| 22:22 | bounb | we don't really have any good OSs |
| 22:22 | bounb | they're all a bit naff in various ways |
| 22:23 | justin_smith | just by observation I would say that OS usage in the clojure community is in order: osx, linux, windows |
| 22:23 | bounb | oh i see |
| 22:23 | bounb | yes i forget just how big apple is these days |
| 22:23 | justin_smith | that's really informal :) |
| 22:23 | bounb | justin_smith: don't worry. it was a "pop poll" |
| 22:24 | bounb | im not writing a scientific study |
| 22:24 | justin_smith | and I'd say in terms of convenience of developing clojure, the ranking is linux, osx, windows |
| 22:25 | justin_smith | but that's even more subjective |
| 22:26 | zanes | amalloy: I guess the most succinct implementation is (partial sequence (comp (partition-by identity) (map first))). Heh. |
| 22:27 | zanes | Or maybe that would have the same problem of delaying the first value. Hm. |
| 22:27 | iamdustan | justin_smith: ha. That’s a bit of a stretch for me yet. I still will claim javascript as my fave, but I’m excited about clojurescript and om. |
| 22:28 | blaenk | anyone use cljsbuild? I have it in my :hooks and it keeps saying Compiling ClojureScript whenever I run lein repl lol |
| 22:28 | blaenk | thought it was only supposed to run when other things were run, such as compile and clean |
| 22:28 | amalloy | zanes: probably does, yeah |
| 22:30 | bounb | iamdustan: javascript is your favourite language? |
| 22:31 | iamdustan | bounb: guilty |
| 22:31 | andrewchambers | iamdustan: what languages have you used? |
| 22:31 | iamdustan | bounb: though that is not for breadth of experience |
| 22:31 | bounb | ...explain? |
| 22:31 | iamdustan | oh goodness |
| 22:31 | iamdustan | personal history. |
| 22:31 | andrewchambers | javascript is pretty average overall |
| 22:32 | andrewchambers | not super bad |
| 22:32 | andrewchambers | not great |
| 22:32 | iamdustan | I’ve been a developer for ~3 years (that I’ll count at least) |
| 22:32 | andrewchambers | You code webstuff only though right? |
| 22:32 | iamdustan | and that is all as a front end dev |
| 22:32 | zanes | Man, writing transducers by hand is weird. |
| 22:32 | andrewchambers | I think you just like javascript because you are comfortable iwth it |
| 22:32 | iamdustan | and I went to were I work now to learn back end dev |
| 22:33 | andrewchambers | I think typescript is decent |
| 22:33 | iamdustan | but they realized how good I was at front end and I got pigeon-holed so I just followed the rabbit trail down |
| 22:33 | bounb | anyone here not primarily a "programmer" in their day job? |
| 22:33 | dbasch | bounb: you’re assuming everyone here has a day job |
| 22:33 | andrewchambers | Software engineer might still be a programmer :) |
| 22:33 | iamdustan | I’ve done a bit in python, ruby, read a haskell book, started SICP (since I’m self-taught) which got me into lisps, and then because of Om I shifted to clojure |
| 22:34 | bounb | bounb: if you don't then your answer is implicitly "no" and you don't need mention it |
| 22:34 | iamdustan | I read most of a C++ book last year, but that was still biased towards web development (browser engines) |
| 22:34 | bounb | uh fuck i addressed myself |
| 22:34 | bounb | dbasch: ^ |
| 22:34 | iamdustan | haha |
| 22:34 | bounb | <- moron |
| 22:34 | iamdustan | long-winded way to say, yeah I am a web developer through and through |
| 22:35 | andrewchambers | yeah, javascript is decent compared to those. Haskell is just way out there, and just reading doesn't give you the proper feel for it. |
| 22:35 | andrewchambers | you don't really have any typed languages :P |
| 22:36 | iamdustan | true, true. To that point: I have played with typescript and C# |
| 22:36 | andrewchambers | but thats ok for what you seem to workon |
| 22:36 | iamdustan | well, C++ no? |
| 22:36 | andrewchambers | i dunno |
| 22:36 | andrewchambers | C++ is horrible |
| 22:36 | andrewchambers | But at least with C and C++ you will learn more fundamental computer science stuff |
| 22:36 | andrewchambers | since its much lower level |
| 22:37 | iamdustan | I have a (former) coworker who is big into haskell and I read the “...for great good” book and finished and was like “that was really interesting and I have no idea how I could solve anything with it if my life depended on it” |
| 22:37 | iamdustan | I did write a couple lines of C for a project actually :) |
| 22:37 | iamdustan | well, modified. |
| 22:37 | andrewchambers | yeah, i dunno clojure is pretty high level and cool once you are used to it |
| 22:38 | andrewchambers | clojurescript is alot better than javascript imo, but thats just an opinion |
| 22:38 | andrewchambers | Javascript is quite verbose and the callbacks get very nested |
| 22:38 | dbasch | andrewchambers: it depends on what you mean by “fundamental cs stuff.” You do get closer to hardware, but that’s not necessarily what cs is about |
| 22:38 | andrewchambers | dbasch: yeah, you are right |
| 22:38 | bounb | how can you compare clojurescript and javascript? |
| 22:38 | andrewchambers | closer to computer stuff |
| 22:39 | andrewchambers | not algorithms or anything |
| 22:39 | andrewchambers | but understanding hardware etc |
| 22:39 | iamdustan | it’s like java to javascript. They both have common parts in the name! |
| 22:39 | bounb | hah |
| 22:39 | andrewchambers | I dunno, clojurescript has its own problems |
| 22:39 | andrewchambers | like way harder for abeginner to get started |
| 22:39 | andrewchambers | more setup |
| 22:40 | andrewchambers | they aren't problems with the language, but they are real problems. |
| 22:40 | iamdustan | like everything with java :) |
| 22:40 | andrewchambers | To code in clojurescript you need to understand all the javascript stuff AND all the clojurescript stuff |
| 22:40 | andrewchambers | so its not really beginner friendly |
| 22:40 | bounb | correct me if i'm wrong but i thought clojurescript was just a clojure->javascript compiler |
| 22:40 | andrewchambers | same with clojure<->java |
| 22:40 | iamdustan | I installed maven for a quick freelance project the other day and immediately lost all faith in the java world. |
| 22:41 | andrewchambers | java is horrible |
| 22:41 | andrewchambers | i dunno, The only language that has tools I enjoy is Go at the momeny |
| 22:41 | andrewchambers | little setup, just works |
| 22:41 | bounb | why not clojure |
| 22:41 | andrewchambers | clojure is freaking hard to get started with |
| 22:41 | andrewchambers | stuff is outdated |
| 22:42 | andrewchambers | the lein project.clj stuff took me ages to get started with |
| 22:42 | andrewchambers | because the templates i was copying were out of date |
| 22:42 | bounb | hmmmmmm |
| 22:42 | andrewchambers | then my laptop was really slow |
| 22:42 | andrewchambers | lein version took 6 seconds |
| 22:42 | bounb | so complaints about the language ecosystem |
| 22:42 | andrewchambers | to print |
| 22:42 | andrewchambers | but i understand that |
| 22:43 | andrewchambers | To use clojure, you need to know java and clojure and the tools |
| 22:43 | justin_smith | andrewchambers: I got pretty far with clojure before I learned any java |
| 22:43 | justin_smith | andrewchambers: though I did have to figure out just enough to read some javadoc |
| 22:44 | andrewchambers | Yeah, but if you don't understand java exceptions or you don't understand what a classpath is |
| 22:44 | andrewchambers | you are screwed |
| 22:44 | andrewchambers | someone with experience can easily work it out |
| 22:44 | andrewchambers | but if you are totally new then its harder |
| 22:44 | bounb | andrewchambers: good to hear that point of view. thx |
| 22:44 | andrewchambers | I mean, 4clojure is decent |
| 22:44 | dbasch | andrewchambers: that’s more jvm stuff than java proper |
| 22:44 | andrewchambers | since it lets you play with no setup |
| 22:45 | justin_smith | (inc dbasch) |
| 22:45 | lazybot | ⇒ 9 |
| 22:45 | blaenk | anyone know how to generate a certain length random string? I found crypto-random which lets me specifies the size in bytes the size then increases when its encoded in base64 or whatever |
| 22:45 | justin_smith | yeah, you need to learn the tooling / ecosystem, but not so much the language (until you decide to go deeper) |
| 22:45 | blaenk | I mean, short of truncating the string |
| 22:46 | andrewchambers | The clojure language itself is pretty easy. |
| 22:46 | andrewchambers | My one complaint was the using and ns :refer |
| 22:46 | andrewchambers | so many ways to include stuff |
| 22:46 | justin_smith | blaenk: like cryptographically secure random string? |
| 22:46 | andrewchambers | not really explained well anywhere |
| 22:46 | blaenk | yep |
| 22:46 | blaenk | to use for ring's cookie key |
| 22:46 | dbasch | blaenk: what characters do you want to use / exclude? |
| 22:46 | blaenk | I'd just like something that's printable, i.e. no unprintable characters |
| 22:46 | dbasch | blaenk: use java uuid |
| 22:47 | andrewchambers | all that being said, i think clojure is great once you know how to use it |
| 22:47 | blaenk | uuids can be 16 characters long? I don't know the implications of truncating something |
| 22:47 | brehaut | tautology is tautological |
| 22:48 | iamdustan | what are some use cases that you folks are using clojure for? |
| 22:48 | avi__ | testing java libraries |
| 22:48 | iamdustan | My viewpoint is entirely too focused on the web platform in any fashion |
| 22:49 | justin_smith | iamdustan: backend for http |
| 22:49 | avi__ | I use clojure's repl to test out Jars and explore them before I have to write a lot of java code. |
| 22:49 | iamdustan | avi__: interesting. so you still write java, but clojure is to get familiar with something? |
| 22:49 | bounb | anyone by the name jony hudson itc? |
| 22:50 | iamdustan | justin_smith: with ring and compojure and the like? |
| 22:50 | avi__ | iamdustan: I try to avoid Java, but yes |
| 22:51 | andrewchambers | iamdustan: I have played with writing parts of a compiler in clojure with core.logic |
| 22:51 | avi__ | iamdustan: it allowed me to plumb the guts of DB4o and see the crazy stuff it was doing |
| 22:51 | andrewchambers | didnt actually use it for a few reasons |
| 22:52 | andrewchambers | then I wanted to use clojurescript + core.async + om for a ui for a payment system |
| 22:52 | andrewchambers | but shelved that project for now |
| 22:52 | andrewchambers | I like to try and think of projects that clojure will be good for as a hobby :P |
| 22:52 | justin_smith | iamdustan: ring and our own custom router, edn record mapping layer, and template renderer (the project is open sourced, called caribou) |
| 22:53 | iamdustan | if/when I get to the point of clojurescript + om I will let you know to pick that project back up |
| 22:53 | justin_smith | caribou is a bit too heavy weight / frameworky for clojure (it's an adaptation of some ruby stuff built for an agency to smooth a transition) |
| 22:53 | andrewchambers | clojure also changed the way i write some code at work in normal java |
| 22:53 | andrewchambers | more immutability |
| 22:53 | andrewchambers | more atomic swapping of values |
| 22:55 | bounb | avi__: that's interesting. |
| 22:55 | bounb | thanks |
| 22:56 | andrewchambers | more emphasis on pure functions too |
| 22:58 | avi__ | so much in java needs to be immutable |
| 22:58 | avi__ | thank goodness they made the strings immutable |