#clojure log - May 02 2016

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

2:16 dysfun: justin_smith, asdf12z_: the binding for compojure can be a vector, symbol or map

2:17 it treats them all differently with magic macro shit

2:19 amalloy: well, it treats the map and symbol the same

2:19 ie, it just applies clojure's normal destructuring rules to both

2:19 vectors are the special case; it destructures the :params key instead of the whole map

2:22 dysfun: yeah, that

3:41 jonathanj: are there any tools that output coverage data that i could use with codecov.io?

3:44 cloverage is... weird:

3:44 Caused by: java.lang.IllegalArgumentException: Can't call nil, form: (nil (nil #{map__14313}) (nil nil nil (nil #{map__14313})) #{map__14313})

3:45 compiling:(aleph/http/client_middleware.clj:176:5)

3:47 TEttinger: that's a lot of nil there

3:47 jonathanj: haha, yeah

3:47 clojurebot: Cool story bro.

3:48 TEttinger: I don't think I even know what code coverage is

3:48 is it a test thing?

3:48 jonathanj: it's basically how many lines of your source your tests exercise

3:48 100% coverage means every line (and possibly every branch condition) is exercised by your test suite

3:49 anyway, cloverage doesn't seem to work at all for me, it bails out with this bizarre error

3:49 i was kind of hoping someone else had encountered this

3:50 https://github.com/lshift/cloverage/issues/85

4:00 is it possible to use a lein plugin from a local repo?

4:17 fikgol: TEttinger you are right. thanks

4:18 TEttinger: you are right. thanks

4:21 TEttinger: ah glad i could help

4:28 tolstoy: jonathanj: One way to do it is add leiningen/whatever to your source, then make sure it's on the classpath in .lein-classpath.

4:28 ~/.lein-classpath (I think the name is).

4:28 clojurebot: excusez-moi

4:28 tolstoy: Then you can develop plugins within your existing project.

4:37 Oops, I mean <project>/.lein-classpath.

6:25 bikeshedr: asdf12z_: haha, I was just wondering this last week while going through the luminus-book

6:59 panor: does anyone know whether (set-agent-send-executor!) also increases the pool when futures are used?

7:33 Keksike: what are clojure function parameters in curly braces called and how do they work, for example (defn myFunction [{id :id}] ...

7:34 M-martinklepsch: Keksike (IRC): it's called destructuring http://blog.jayfields.com/2010/07/clojure-destructuring.html

7:34 Keksike: M-martinklepsch: thanks

7:35 M-martinklepsch: Keksike (IRC): essentially they allow you to bind certain keys in maps without an extra let

7:35 Keksike: ah ok

7:36 M-martinklepsch: is there a way to define two sets of params for a function, one which has a map-parameter and takes the value from it that way, and one which just has the id as a normal parameter for example?

7:36 I don't remember what thats called when defining many sets of params for a function

7:36 bsamorim: guys, how do I use a custom-made Java class to a clojure code?

7:36 via lein

7:37 luma: that's called multiple arity, but you need to have a different amount of parameters for each

7:37 M-martinklepsch: Keksike (IRC): variadic is the term used to describe functions taking a varying number of arguments (varying arities)

7:37 luma: you can't define two different implementations for the same amount of parameters

7:37 panor: does anyone know whether (set-agent-send-executor!) also increases the pool when futures are used?

7:37 Keksike: ty again M-martinklepsch

7:38 M-martinklepsch: Keksike (IRC): luma__ (IRC) right but he could do `(defn x ([map] ...) ([id data

7:38 ]))`

7:38 Keksike: ok

7:38 M-martinklepsch: that might be a bit confusing to others but in theory it's possible

7:39 Keksike (IRC): if you're looking for pattern matching there are a few libraries out there as well

8:46 panor: does anyone know whether (set-agent-send-executor!) also increases the pool when futures are used?

9:19 bsamorim: guys, how can I import a custom-made java class?

9:19 in clojure

9:19 all the way from the class's .class file

9:25 ridcully: just make sure it is in the right place of the directory structure (what it claims to be in the package) in your classpath and you should be good to go?

9:28 bsamorim: ridcully: but what would be the "right place"? i mean, suppose that i created my project with lein and put my java Foo class in src/java/Foo.class

9:29 ridcully: how should I import it?

9:31 ridcully: if it's in not package, then it's just Foo. also i am not sure, if src/java/*.class get picked up at all?

9:32 does it actually turn up in your target-dir?

9:40 bsamorim: ridcully: how do I check that?

9:44 ridcully: bsamorim: on unix i'd use `find target|grep ...` - ymmv. but my advice here is just "java knowledge applied". i never had the need to deal with single pre compiled java.class files in lein yet

9:44 bsamorim: ridcully: hmmm....is it possible to create a java class via clojure?

9:45 ridcully: it would be a ridiculously simple class, just a List with some extensions

9:45 ridcully: i'd use it mainly for java's mutability

9:49 TimMc: bsamorim: You can use bytecode generation. :-)

9:50 bsamorim: TimMc: hmmm...interesting...how would I go about doing that ?

9:50 TimMc: is there a tutorial somewhere?

9:50 TimMc: Oh, I was kidding, you'd really want gen-class.

9:50 ridcully: bsamorim: https://github.com/technomancy/leiningen/blob/4a683b85eda2e0662120a12a1f0680e6ebc0c28c/doc/MIXED_PROJECTS.md

9:50 TimMc: I mean, "want" is a strong word, but for your purposes gen-class is probably the least worst.

9:52 bsamorim: ridcully: many thanks!!!!!

9:52 i'm checking it out

10:22 justin_smith: TimMc: why not deftype with some mutable fields?

10:23 sdegutis: Good morning one and all.

10:26 dysfun: you're perky this morning

10:29 sdegutis: dysfun: Until this day, I never knew perky meant "cheerful and lively."

10:29 I thought it was more like upbeat or something.

10:29 * dysfun doesn't see there's much difference

10:29 TimMc: justin_smith: Depends on what they need.

10:30 panor: does anyone know whether (set-agent-send-executor!) also increases the pool when futures are used?

10:31 justin_smith: panor: the pool futures use is auto-expanding, and is used by send-off

10:31 send uses a smaller pool

10:31 (that does not auto-expand)

10:32 panor: HMm not sure, i read in the docs: Clojure futures are evaluated in a fixed size thread pool that is also used by agents (updated via clojure.core/send).

10:33 justin_smith: panor: not fixed size, that is false

10:33 agents have two pools, you can read the code to verify that

10:35 panor: right here, it creates two pools, one fixed, the other cached (expandable), agents use both (send vs. send-off), futures use the expandable one https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Agent.java#L49

10:35 panor: you might want to correct the person who told you futures were using a fixed pool

10:36 (this has been an issue in my own codebase in the past, someone was spawning futures like penny candy and crashed the vm by all the memory used in creating the new thread stacks)

10:36 panor2: sorry dc'd :(

10:37 the pooledExecutor is fixed?

10:37 justin_smith: panor2: yes, you can look up Executors.newFixedThreadPool - you saw the source link?

10:37 panor2: ye i got that

10:38 so how does it expand?

10:38 a fixed one has at most n threads right?

10:38 justin_smith: the newCachedThreadPool creates that

10:38 it is not fixed

10:38 read down a couple of lines :)

10:39 as I mentioned before, two pools

10:40 panor2: here's the doc for newCachedThreadPool https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html#newCachedThreadPool(java.util.concurrent.ThreadFactory)

10:41 panor2: ah yes i see

10:41 i thought there was two times fixed, oops :D

10:41 justin_smith: panor2: this is why the docs mention you should use send-off (edpandable pool) for indefinite operations, and send (fixed pool) for quicker ones

10:41 panor2: but i'm talking about futures atm :) so if i do (future ...) which pool will it use

10:41 the docs say the fixed one

10:41 justin_smith: panor2: the expandable one

10:42 panor2: hmm ok then :)

10:42 jonathanj: if you want to limit parallelism in an easier way, consider using claypoole

10:43 it has a (future) implementation that lets you provide a threadpool

10:44 justin_smith: panor2: relevant line of the future code (future uses future-call) https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L6687

10:44 panor2: hmm indeed, it seems you are correct :D

10:45 justin_smith: that uses soloExecutor, which if you cross reference to the other link, is the one that expands

10:45 after an app crashing and burning because you have wrong assumptions about these things a couple of times, one has incentive to really know what's going on :)

10:46 panor2: true, thanks for the effort :)

10:47 justin_smith: also, once you figure out which stuff is in java and which in clj, the clojure codebase is pretty straightforward to navigate to find answers

10:50 dysfun: OT - what's your take on Haskell From First Principles? As a perpetual Haskell n00b it looks good but I'd be interested in a more informed perspective.

10:51 sdegutis: Yes, Clojure is simple.

10:51 And easy.

10:52 dysfun: justin_smith: haven't read it. is that the bitemyapp one?

10:52 justin_smith: yeah, well him and a co-author (education expert)

10:56 dysfun: oh

10:57 mpenet: soloExec is an (unbounded) cached threadpool if I recall

10:57 justin_smith: it's kind of cool - Julie learned Haskell as part of the process of them writing the book, which informed the content...

10:57 mpenet: yup, that's what the source / javadoc I linked to above says as well

10:57 mpenet: rule of thumb is to avoid using any of the clojure.core stuff relying on threads unless it's for small stuff

10:57 dysfun: i can't comment on her and i'm going to refrain from commenting on him

10:57 justin_smith: dysfun: fair enough

10:58 mpenet: sadly some part of core.async suffer the same pb

10:59 *parts

11:01 ex: `thread` and I think the all callbacks for put/take (and all the functions that uses these), so a lot of stuff :(

11:01 beaky: helllo

11:01 how do you select the best steaks

11:01 oops wrong channel

11:03 TimMc: sort, then take n

11:05 justin_smith: TimMc: surely fmap with the juiciness monad - oops, wrong channel

11:06 dysfun: well if you're in a shop where you could walk out with bad steak, you're in the wrong shop

11:06 TimMc: Are you sure we should be sending steaks over channels in the first place?

11:06 justin_smith: TimMc: yeah, the buffers could lead to freshness issues

11:07 sdegutis: ,(count [""""""""""""""""""""""""])

11:07 clojurebot: 12

11:25 justin_smith: is there a standard idiom for repl foolishness that I don't want to impose on collaborators, but I do want loaded into user? maybe a small project that injects bindings into the user ns?

11:28 TimMc: justin_smith: .lein/profiles.clj, yeah?

11:29 justin_smith: TimMc: but I want functions for user

11:29 I guess I'll put those in a plugin

11:30 or maybe just (when (.exists (io/file "~/user.clj")) (load-file "~/user.clj")) or some such directly in profiles.clj

11:30 TimMc: If it's just local stuff, you can write code as nonrepeatable as you like. :-P

11:31 justin_smith: haha, right, I just wondered if there was something pre-rolled, seems like it would be a common enough thing

11:31 TimMc: The :repl map in projects has some useful stuff, as long as the project itself doesn't define anything.

11:31 https://github.com/technomancy/leiningen/blob/stable/sample.project.clj#L346

11:32 justin_smith: TimMc: right, of course, and I can put that in profiles.clj, thanks!

11:33 ridcully: there is also -i with a regular repl

11:33 Glenjamin: justin_smith: i've added "dev/" to src paths in a :dev profile, then added "dev/user.clj" to gitignore before

11:33 justin_smith: Glenjamin: yeah, I wanted global for all projects though

11:34 Glenjamin: I have vinysa set up to inject a bunch of stuff into a namespace called "." - that sort of thing?

11:34 justin_smith: Glenjamin: yeah, that's another approach - but I'm gonna see how far I can get with ~/user.clj and then consider vinyasa

11:35 Glenjamin: this is my user profiles.clj: https://www.refheap.com/118554

11:46 justin_smith: Glenjamin: cool, that's helpful - now to stop shaving yaks and get some work done

11:47 binjured: is there any way to alias an import of a Google Closure class in CLJS? I need to import two classes with the same name from different namespaces.

11:48 justin_smith: binjured: you can use require to get google closure libs in cljs, right?

11:49 and you can use :rename with require

11:49 binjured: justin_smith: yeah, but i can't figure out how to construct via that. compiler always complains "foo.bar.Baz isn't a constructor"

12:30 panor: how do you get the internal state of an agent?

12:32 dysfun: you mean the current value?

12:32 @

12:33 panor: ah yeah im stupid lol

13:18 WorldsEndless: Selmer allows passing of variables into the rendered page (ie for Javascript use). But I'm using Hiccup; anyone know of a similar faculty without encoding them in the DOM?

13:20 ridcully: you mean like [:script {:type "text/javasript"} (str "var something='" (quoteproperly something) "'"] ?

13:25 _maddy: cool I just discovered something called defrecord, and it looks better suited for storing data than a hashmap... have to figure out how it works next

13:29 WorldsEndless: ridcully: Yeah, I suppose so. Looks lke it needs to be hand-made?

13:30 mloveless: and of course there's always defleopard

13:31 ridcully: WorldsEndless: i don't know if there is shortcut. i just wanted to understand the question

13:31 leopard?

13:31 mloveless: the band.. sorry, bad joke

13:32 WorldsEndless: ridcully: Looks like there is a javascript-tag option, still requiring actual writing of javascript though

13:32 ridcully: thats def leppard ;)

13:34 mloveless: whoops!

13:42 TimMc: WorldsEndless, ridcully: It's surprisingly difficult to do that safely.

13:43 My strong recommendation is to emit <input type="hidden" name="foo" value="json-goes-here"> because otherwise you can run into the most *exciting* security issues.

13:44 Long story short, there's no general way to encode data safely in a <script> block because it's CDATA.

13:53 jonathanj: couldn't you emit something like <script id="app-config" type="application/json">...json data...</script> and parse it as JSON? as long as you're not eval()ing the contents, you should be fine?

13:55 you'd obviously need some JS code to run after that script tag: window.MyApplication.config = JSON.parse(document.getElementById('app-config')); // or such

13:55 seems a bit easier to manage (and a lot harder to mess up) than interpolating values into strings intended to be valid javascript code

13:56 ben_vulpes: anyone have experiences positive or negative to share with the clojure scheduling libraries, or the unadorned java versions thereof?

13:57 jonathanj: ben_vulpes: never used it before but i read about it in a post when the author announced his time library: http://docs.caudate.me/hara/hara-io-scheduler.html

13:58 ben_vulpes: testability is very important to me

13:58 jonathanj: hara.io.scheduler separates the what and the when, which i would imagine makes it a lot easier to test

14:01 ben_vulpes: man this hara dude has gone a wee bit nuts

14:01 i am an impress

14:01 TimMc: jonathanj: No, that's insecure for the exact same reason a text/javascript block would be.

14:01 I'm going to make a blog post about this sooner or later.

14:01 jonathanj: although in my experience testing time-based things, you want some way to step the clock whenever you want and as much as you want

14:02 i don't see anything like this for hara

14:02 TimMc: how so?

14:02 TimMc: jonathanj: I don't have the time to get into it right now, but <script> is CDATA, so </script> ends a script block, always.

14:02 and if that ends up in your data, you're hosed.

14:03 jonathanj: it does?

14:03 even if you wrap it in <![CDATA[...]]>?

14:04 how would "</script>" end up there anyway?

14:05 presumably when hiccup (or whatever) serializes your markup it escapes all the bad things, so you never end up with a literal <, >, &, etc.

14:05 TimMc: jonathanj: Give it a try.

14:05 and remember that an attacker can supply ]]></script> if they want to.

14:07 For the moment, just trust me when I say that the only viable options are: 1) Backslash-escaping forward slashes in the JSON; 2) Base-64-encoding the JSON (which is actually difficult due to character encoding issues); and 3) putting the JSON in an element attribute.

14:07 The blog post will have more detail + a demo, I just need to reformat it.

14:08 jonathanj: hang on, an attacker where?

14:09 if someone happens to inject some JS into your config database on the server, that still won't matter because it'll all be quoted instead of literal when it's rendered

14:09 if there is some guy injecting code into the client's browser on their local machine you're basically screwed anyway

14:15 TimMc: Security needs to be general.

14:36 _maddy: is mapv more efficient than map, if I need to go through all the items in any case?

14:37 amalloy: jonathanj: the default behavior of hiccup (or whatever) is not to escape everything. you have to specifically say what needs to be escaped

14:39 will_sm: _maddy, map is lazy, so a new collection isn't created so the values are calculated as needed

14:39 _maddy, a case where this may be detrimental is when you need the entire seq multiple times

14:40 amalloy: why would that be a problem?

14:40 will_sm: In the REPL, I did `(def a (map println (range 10)))`, which should be 10 nils

14:41 outputing `a` calls the printlns each time

14:41 AimHere: Did you really want a list of ten nils?

14:41 will_sm: AimHere, didn't matter

14:41 AimHere: Otherwise, wouldn't doseq be the more idiomatic

14:42 amalloy: will_sm: no it doesn't

14:42 AimHere: Oh right, sorry, you're explaining stuff

14:42 will_sm: amolloy, nvm lol

14:44 _maddy: will_sm: like for example map-reduce, it will go over the whole seq anyway

14:46 will_sm: amalloy, does getting the first element calculate the whole thing? `(first (map println (range 10)))` printed out all of them in the REPL, but is this always the case?

14:47 amgarchIn9: I think 32 element chunks are hardwired. Try (range 33).

14:48 will_sm: amgarchIn9, yup

14:48 AimHere: Doesn't (range 33) have 33 elements?

14:49 amgarchIn9: yes, that's two chunks.

14:49 will_sm: AimHere, yeah, it printed 0-31 inclusive when I took the first

14:53 amalloy: _maddy: the main disadvantage of using mapv instead of map is that you get the entire collection in memory at once, whereas with (reduce f x (map f xs)) you can produce it only as needed, and throw away old items

14:54 i don't know whether mapv or map is faster there, if the size of the collection is not an issue, but either way it is probably fairly close and not worth worrying about, so i'd use the safer map

14:54 i wonder if mapv would exist, actually, if transducers had been invented first

14:55 probably not

15:12 justin_smith: amalloy: agreed

15:13 _maddy: are you consuming the results, or doing some side effect as you go?

15:21 _maddy: justin_smith: consuming

15:23 justin_smith: aha, yeah. If it was just side effects you could use run!, but consuming you could check out using the map transducer if appropriate, or just use map as amalloy mentions

15:29 _maddy: ok, thanks

16:14 binjured: with CLJS/JS interop, am i missing something or is it normal to have to wrap just about everything in clj->js?

16:15 Glenjamin: binjured: you'd generally want to constrain interop to a small area, but then yes - you can't use lists/vectors/maps on JS funcs without converting

16:16 binjured: Glenjamin: seems like i can't even pass Closure class instances to other constructors without it.

16:16 Glenjamin: ah, i don't know much about that - I rarely use classes in JS-land

16:18 chemouna: I wanted to share this list for people who are learning clojure https://github.com/chemouna/ClojureResources (i've collected while learning clojure myself)

16:21 if i'm missing some excellent other resources i would love to find them , please point them out

17:48 jrc: ..

17:48 ..

17:49 .............................................................................................

17:49 .0.

17:51 sorry

17:51 amalloy: say hello to your cat for us

17:52 justin_smith: 😼

17:53 jrc: I will haha

18:06 irctc: Hi there. I am wondering if anyone can tell me what has happened to conj.io?

18:07 Is it down temporarily, or has it been perma-deprecated?

18:07 justin_smith: irctc: I was wondering too, maybe arrdem can enlighten us

18:51 ZimaBlue: why is areduce a macro?

19:19 jrc: I installed vim-fireplace seems to be working, :%Eval etc works, but commands like cqq cqc do nothing, I wasn't instructed to add anything to .vimrc to make these work, has anyone had luck with this vim plugin?

19:23 ben_vulpes: what's literal syntax for a partial'd function?

19:23 i'd like to test that a function returns a particular function

19:23 ,(defn bens-funk [] :hi)

19:23 clojurebot: #'sandbox/bens-funk

19:24 ben_vulpes: ,(println (partial bens-funk))

19:24 clojurebot: #object[sandbox$bens_funk 0xb8f8de4 sandbox$bens_funk@b8f8de4]\n

19:24 ben_vulpes: ,(println (partial sandbox/bens-funk))

19:24 clojurebot: #object[sandbox$bens_funk 0xb8f8de4 sandbox$bens_funk@b8f8de4]\n

19:24 ben_vulpes: alternatively, what'd be the idiomatic approach to test that a particular function got returned from another function?

19:25 amalloy: ben_vulpes: don't test functions for equality

19:25 ben_vulpes: boo

19:25 amalloy: the only thing you can do is test their behavior by calling them with interesting arguments

19:25 ben_vulpes: cool nbd

19:53 EgyptPharaoh: Hi guys, im new to clojure

20:23 sdegutis: Aha! I hvzae data challeng.e Finally!

20:24 So you have data like this.. µany maps, list of them (or seq), and it has: each have a key :age, and you want to find the number of quantity of each.

20:26 (f [{:age 1} {:age 1} {:age 1} {:age 2} {:age 2} {:age 3}]) => 3

20:27 It's kind of like, the opposite of distinct.

20:27 the intermediate of that (f ...) is {1 3, 2 2, 3 1} because that's the frequencies

20:28 Ag! Frequencies!

20:28 Map it to :age ahd then (frequndcies) it

20:28 ,(->> [{:age 1} {:age 1} {:age 1} {:age 2} {:age 2} {:age 3}] (map :age) (frequencies) (vals) (map dec) (reduce + 0))

20:29 [SOLVED]

20:29 clojurebot: 3

20:29 sdegutis: This was good challeng.e

20:30 justin_smith: ,transduce (map :age) (fn ([s] (count s)) ([s i] (conj s i))) #{} [{:age 1} {:age 1} {:age 1} {:age 2} {:age 2} {:age 3}]) ; sdegutis

20:30 clojurebot: #object[clojure.core$transduce 0x3c23ebbb "clojure.core$transduce@3c23ebbb"]

20:31 justin_smith: ergh

20:31 ,(transduce (map :age) (fn ([s] (count s)) ([s i] (conj s i))) #{} [{:age 1} {:age 1} {:age 1} {:age 2} {:age 2} {:age 3}]) ; sdegutis

20:31 clojurebot: 3


20:31 I will never understand transduers jsut.

20:31 justin_smith: .

20:31 Hmm let me prettyify that CLojure code. rst.

20:32 justin_smith: the key to understanding transduce is to use it to answer toy problems like this one, of course

20:32 sdegutis: Hmm.

20:32 Your solution confuses the **** out of me.

20:32 I don't undrstand what the (fnn) is doing or why there' a se.t

20:32 justin_smith: ,(transduce (map :age) (completing conj count) #{} [{:age 1} {:age 1} {:age 1} {:age 2} {:age 2} {:age 3}]) ; improveder

20:32 clojurebot: 3

20:33 justin_smith: (completing conj count) is cool

20:33 sdegutis: improveder?

20:33 justin_smith: sdegutis: it was improved, now it's even improveder

20:33 sdegutis: earlier today i adjusted my work email signature in an email to an old colleague i used to work with to isnead of "Technical Support" to say "Code Typer In-er"

20:33 er, *Codes

20:33 justin_smith: sdegutis: set because I'm just counting how many ages (perhaps that answers the wrong question but is coincidentally right?)

20:34 sdegutis: Ahh yes it's coindidental.

20:34 justin_smith: oops!

20:34 sdegutis: It's number of "repeats".

20:34 So, age 1 is in there 3 times, so that's 2 repeats.

20:34 justin_smith: ahh

20:34 sdegutis: Sge 2 is in there twice, so 1 repeat.

20:34 3 once, 0 repeats.

20:34 2 + 1 + 0 = 3

20:35 Also what the heck is completing? Is CLojure just untyped Haskell now?

20:36 TEttinger: ,(doc completing)

20:36 clojurebot: "([f] [f cf]); Takes a reducing function f of 2 args and returns a fn suitable for transduce by adding an arity-1 signature that calls cf (default - identity) on the result argument."

20:36 TEttinger: oh nice

20:36 justin_smith: ,(transduce (map :age) (completing #(update % %2 (fnil inc -1)) (comp (partial apply +) vals)) {} [{:age 1} {:age 1} {:age 1} {:age 2} {:age 2} {:age 3}])

20:36 clojurebot: 3

20:36 sdegutis: Yeah I sitll don't understand completing after reading htat.

20:36 justin_smith: fnil inc -1? Haha why not dec?

20:36 hmm

20:36 justin_smith: sdegutis: you know that pattern of (f (reduce g coll))

20:36 sdegutis: My brain is mal functionling tonight.

20:37 justin_smith: No,

20:37 justin_smith: you say earlier "perpetual Hasskell newb" to refer to yosuelf as, yet here we see that you think in arity and function calls!

20:37 justin_smith: sdegutis: you never do (f (reduce g coll))? that is for when you want to accumulate one kind of data, and then process it before returning it

20:37 sdegutis: I seem to think in context-dependent transformations

20:37 justin_smith: sdegutis: haskell does not have arity

20:38 sdegutis: justin_smith: not that I can recall

20:38 justin_smith: well, mostly not

20:38 sdegutis: justin_smith: (it pretends to"

20:38 justin_smith: heh

20:38 sdegutis: Hmm. Only 17 matchs for "reduce" in our code.

20:38 Most of them are (reduce + 0) in an ->>

20:38 (at the end)

20:38 justin_smith: because you don't like (apply +) ?

20:39 sdegutis: Correct. I hate apply.

20:39 Most of my apply is apply str or apply max 0

20:39 amalloy: "haskell does not have arity". a strange way to put it, but i guess not crazy

20:40 justin_smith: amalloy: maybe I meant "arity is not relevant to haskell in quite the way we are talking about here"

20:40 sdegutis: amalloy: justin_smith: you could almost say it has terminal and non-terminal transformations

20:40 justin_smith: because of course it does have arity

20:40 sdegutis: it almost has like, a function can take 0 args, like foo = "bar", now foo refers to "bar", or it takes 1 arg and returns a value, or it takes 1 arg and returns a function

20:41 so weird

20:41 hey wait a minute

20:41 amalloy: i mean, the way transducers use arity is pretty gross imo. it's a way to smuggle two totally distinct functions together as one "function" with two arities

20:41 sdegutis: you tricked me into thinking about haskell

20:41 jeaye: amalloy: Yup

20:42 justin_smith: well, the single arg function should take the same kind of thing as the first arg of the two arg function

20:42 so there's at least some relationship there

20:43 sdegutis: Crap. Out data ia ugly

20:43 crap

20:43 justin_smith: I will study your final exapl thanks

20:44 This i s oncufsong!

20:46 justin_smith: you will become world famous if you write a tutorial on transducers

20:47 Nobody understands them at all and there are no tutorials on them using simple data like this example.

20:47 holy crap that was remarkably typo roof

20:47 justin_smith: sdegutis: hmm

20:47 sdegutis: justin_smith: and It's very difficult to dissest your code

20:48 justin_smith: dissect?

20:51 Lewix: (cond-> {:first first :last last}

20:52 what does cond-> do

20:52 amalloy: have you tried (doc cond->)

20:54 justin_smith: sdegutis: for starters, #(update % %2 (fnil inc -1)) is your frequencies but 0 indexed instead of 1 indexed to avoid the map dec

20:54 sdegutis: justin_smith: correct, dissoect

20:54 justin_smith: so it's an /alternative/ to map dec, rather than "avoiding" it

20:55 justin_smith: i feel like map dec would make more sense in the context semantically, and should work fine with transducers

20:55 justin_smith: sdegutis: what I mean, is it does the same amount of work that frequencies does, and avoids the extra work of map dec

20:55 sdegutis: hello eah another typo-less sentence!

20:55 justin_smith: but at the risk of more confusion for the sake of efficiency?

20:55 justin_smith: but sure, it could be a pointless optimization

20:56 sdegutis: why does everyone find fnil so weird? I think it's awesome and should be used a lot.

20:56 sdegutis: justin_smith: i like fnil sure, but update % %2 confuses my face off

20:56 extra level of indirection that makes my understanding more didfficult

20:56 justin_smith: OK

21:00 sdegutis: Hmm. This is hard problem.

21:01 Our database appears unhelpfully structured.

21:02 ,::find

21:02 Haha.

21:02 clojurebot: :sandbox/find

23:48 sdegutis: Wow.

23:48 I just realized, you can reduce with max instead of apply!

23:48 ,(->> [1 3 2] (reduce max))

23:48 heck yeah!

23:48 clojurebot: 3

Logging service provided by n01se.net