#clojure log - Jan 04 2016

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

4:58 jonathanj: can i `map` a transducer?

4:59 i have a transducer for filtering out foos (filter foo?), but now i have a nested structure, a list of lists, i'd like to filter out foos from each inner list

4:59 without permanently flattening the structure

5:09 hyPiRion: jonathanj: (map #(filter foo? %))?

5:10 jonathanj: yeah, i guess so but that means i have to have a transducer for foo and just a plain predicate, i was hoping to just compose a bunch of transducers

5:10 i *think* `eduction` does what i want, but the documentation is so thin i can't really be sure

5:12 hyPiRion: you can probably do it if you generate the nested structure with transducers

5:12 jonathanj: ,(sequence (map (partial eduction (filter odd?))) [[0 1] [2 3 4] [5 6 7]])

5:12 clojurebot: ((1) (3) (5 7))

5:13 hyPiRion: that's effectively the same as this:

5:13 (sequence (map #(filter odd? %)) [[0 1] [2 3 4] [5 6 7]])

5:13 jonathanj: for that simple example, what about if i want to layer more transducers?

5:14 i guess it should be the same regardless

5:14 the thing is that in my code i have a transducer instead of (filter odd? xs)

5:14 so it's more like (partial eduction foos)

5:15 hyPiRion: Oh, then eduction is probably fine

5:15 jonathanj: so i can reuse my transducer elsewhere

5:20 mmm

5:23 mmm, except in reality my collection is a list of maps with a key i wish to filter

5:25 specifically, it's a list of maps containing information about pages in a PDF and the key i want to filter is the X-Objects contained by that page, it's not super obvious how i manipulate the data for that key in every map and retain the original structure

5:32 hyPiRion: Could you give an example on how it's laid out?

5:34 jonathanj: [{:page <Page object from Java library> :x-objects [{:x-object <X-Object from Java library> :length 42 ...} ...]} ...]

5:34 what i'm trying to do is keep only certain types of x-objects (i want to remove objects that are not images)

5:35 i'm trying a different approach now though, i'm providing a way for the function that generates the structure to include only the relevant information

5:35 instead of trying to strip it out later

5:35 but i would still be interested to see the solution

5:36 i think what i want is something that behaves like a lens but it's really not clear to me how i make that happen with transducers

5:36 i.e. writing code to "reach in" and transform something while retaining the original structure of all the parent layers seems like a faraway dream to me

5:37 i think i remember reading about some library designed to make this a lot easier but i forget its name

5:37 hyPiRion: (map (fn [x] (update x :x-objects #(filter my-filter %))) my-data) ?

5:38 or (update-in x [:x-objects] ...) if you're using an old Clojure version

5:39 jonathanj: i think specter is what i was thinking of

5:41 hyPiRion: i was trying to make use of transducers to avoid creating intermediate structures of data i have no use for

5:41 (mostly as an exercise in transducers)

5:42 hyPiRion: Ah

5:42 jonathanj: i think at this point i have a transducer hammer and everything looks like a transducer nail though

5:43 so thanks for knocking some sense into me

5:44 hyPiRion: Well, it's possible I guess, but I don't think it would not be pretty. And I'd assume it's not a performance issue, it's surprisingly rare that actually is an issue.

5:44 I did some work on recursive transducers (http://hypirion.com/musings/recursive-transducers) and let me say it can get messy quickly

5:44 jonathanj: is there a way to find the index of something in a vector given a pred?

5:44 hyPiRion: yes, it does seem to get messy very quickly

5:46 hyPiRion: (defn indices [pred coll] (keep-indexed #(if (pred %2) %1) coll))

5:48 TEttinger: (reduce #(if (pred %2) (reduced (inc %1)) (inc %1)) 0 coll)

5:48 jonathanj: what is a sorted map?

5:49 is it sorted upon every assoc/update?

5:49 TEttinger: ,(let [pred #{4} coll (range)](reduce #(if (pred %2) (reduced %1) (inc %1)) 0 coll))

5:49 clojurebot: 4

5:50 TEttinger: ,(let [pred #{4} coll (range 0 10 2)](reduce #(if (pred %2) (reduced %1) (inc %1)) 0 coll))

5:50 clojurebot: 2

5:50 jonathanj: `reduced` is kind of an amazing thing

5:50 TEttinger: yep

5:50 hyPiRion's is shorter though, probably clearer

5:51 mine gets the first, his gets all

5:51 different uses

5:51 jonathanj: are there restrictions on what one can use as a key in a map in clojure?

5:51 can i use a java object as a key?

5:52 powered: reduced is the break of other languages

5:52 but only for reduce

5:52 jonathanj: kind of

5:52 you can't break a reduce in Python, for example

5:54 thinking about it, i almost never use break in Python since i tend to use the higher level constructs

5:55 except that in Clojure you can :while (for) but in Python you can't break a listcomp

5:56 rivarun: nothing you can't write in a listcomp if you really want to, but no sugar for it

5:58 jonathanj: sure, but suddenly what is a concise form has to turn into a wordy function (that you never really wanted in the first place) just so you can exit early

5:59 it just suddenly struck me as mildly amusing, i'd never really thought about it before

7:53 princeso: what is the magic behind this '{& fn catch try finally try} in the macro doc. Im just WOT¿? https://github.com/clojure/clojure/blob/61bc3523eebaade6a1d856f74330169eb26211ea/src/clj/clojure/repl.clj#L120

7:54 ({& fn catch try finally try} name)

7:57 Bronsa: princeso: it's making (doc catch) (doc finally) use the same docstring as try

7:57 and (doc &) use the docstring for fn

8:01 princeso: Bronsa thx. where to find more docs about? i dont get it. Is it some shortcut?

8:02 MJB47: its just a hash-map

8:02 which act as functions

8:02 Bronsa: ,('{& fn} '&)

8:02 clojurebot: fn

8:05 princeso: MJB47 Bronsa, ah yes, thx. Im sorry im learning at brute force XD

9:37 jsabeaudry: What happens if I call mult on the same channel twice?

9:47 engblom: If I want to merge two vectors so [1 2 3 4] and [a b c d] becomes [[a 1] [b 2] [c 3] [d 4]], what options do I have beside (for..)? Is there a ready function/macro for that?

9:47 opqdonut: ,(map vector [1 2 3 4] [:a :b :c :d])

9:47 clojurebot: ([1 :a] [2 :b] [3 :c] [4 :d])

9:48 visof: hi guys

9:48 engblom: opqdonut: Thanks! That surely makes the code shorter than my (for...) alternative

9:51 visof: i'm in situation which i have large csv file with first field sorted number, and i want to query the file by the first field, my approach is to split the files to smaller files and check if the provided number in which file then query the smaller file, is there a better approach than this to solve this problem?, note: i don't want to use in-memory design for the full file, i want memory efficient solution

9:51 can anybody suggest anything?

9:51 mavbozo: happy new year!

9:52 visof: mavbozo: today is 1/04

9:52 domgetter: visof: the best solution is probably to shove it in a relational database, but you want to avoid that, no?

9:54 engblom: visof: I do a lot of similar things in my work.... but there I really think bash scripts are the best tools.

9:55 * mavbozo logging in to irc for the first time in 2016

10:03 visof: engblom: i want to make this funcionality inside my code

10:03 domgetter: yeah i want to avoid it

10:30 jsabeaudry: Sanity check: wrapping a reset! in a dosync is pointless, right?

10:31 ridcully_: reset! is for atoms, dosync is for refs

10:33 jsabeaudry: ridcully_, thanks, I'm cleaning some old code and this made no sense to me

10:37 nathanic: et

11:15 matthavener: visof: run through the file once and create a lookup table of 'first field' to 'file offset and length', and then mmap the file

12:20 kungi: Is there a maximum function size in clojure?

12:20 When I try to evaluate a function I get the funky error: Unknown constant tag 80 in class file

12:20 Bronsa`: there's a hard limit on how much bytecode can be emitted, imposed by the jvm

12:21 kungi: can you nopaste that function?

12:21 kungi: Bronsa`: yes

12:22 http://p.nnev.de/8084

12:22 Bronsa`: you're probably exceding the max size for the jvm constant pool

12:22 don't embed huge strings in code

12:23 kungi: Bronsa`: Ok.

12:23 Bronsa`: save them in a file and read that file

12:24 kungi: Bronsa`: To my defense I have to say: It's not my code :-). Some guy tries to evaluate how far he can adapt my code through my "templates".

12:49 engblom: When looking at this file: http://pastebin.com/J9eCWA3y , what do you think is the best way to check that the first line ends with "YES"? And what would be the best way to get the number from t=number at the end of the second line?

12:50 Would you use (subs ...)?

12:51 If I would use subs, I would need to catch StringIndexOutOfBoundsException... Because the line length might vary.

12:52 Bronsa`: engblom: a regex?

12:55 engblom: Bronsa`: How would you use regex to get out only 20750 from "4c 01 55 00 7f ff 0c 10 be t=20750"? The value might vary.

12:57 Bronsa`: engblom: wouldn't #".*t=(.*)" do?

12:59 devth: ,(re-find #"\d+$" "4c 01 55 00 7f ff 0c 10 be t=20750")

12:59 clojurebot: "20750"

12:59 devth: if the value is always numeric

12:59 int to be specific

13:01 engblom: Thanks!

13:08 justin_smith: jonathanj: regarding what you can use as keys - you *can* use anything as a key in a hash-map, but using a mutable object as a key, then mutating it, will have fun consequences that your code probably isn't ready for

13:09 devth: so...i never got in the habit of using transducers. read all about them a few years ago. are they making anyone else's life better?

13:09 *1.5 yrs or whatever it was

13:10 same with reducers

13:13 justin_smith: devth: they are a performance tweak that helps a bit, and for those people creating things like core.async that have new data sources they are an awesome feature

13:13 devth: makes sense. more appropriate for certain lib authors..

13:14 one thing that almost made me reach for reducers the other day was wanting to perform a map and a filter at the same time.

13:14 which you are essentially doing if you compose reducers, right?

13:15 justin_smith: devth: reducers and transducers are not the same thing

13:15 you compose transducers

13:16 devth: yes i know they are not the same thing :P

13:16 justin_smith: OK, reducers are not a thing you can compose

13:16 devth: ok, got mixed up while reading http://ianrumford.github.io/blog/2013/08/25/some-trivial-examples-of-using-clojure-reducers/ i guess

13:44 engblom: I tried to take use of the -> macro, but failed. Could someone please tell me what I am doing wrong in http://pastebin.com/Xy8KC5AB

13:47 With that code I am trying to list all files having a filename beginning with "28"

13:47 It is doing what it should do until line 8 where it fails

13:47 ridcully_: map and filter want the seq last

13:48 engblom: When I had them nested, without -> it worked

13:48 featheredtoast: probably better to use the ->> macro

13:48 if you're going that route

13:49 justin_smith: (-> "/some/path" File. .listFiles seq (->> (map #(.getName %)) (filter #(= "28" (subs % 0 2)))))

13:49 or just use ->> all throughout I guess

13:49 also, that last check might be better as #(.startsWith % "28")

13:53 engblom: Actually, all the files I want are looking like this: 28-something. For example 28-04146d8243ff. I would want the 04146d8243ff part of all those files.

13:53 justin_smith: engblom: right, I was saying use that as the filter

13:53 instead of subs etc.

13:54 ,(filter #(.startsWith % "28") ["28hi" "no" "a" "28done"])

13:54 clojurebot: ("28hi" "28done")

13:54 engblom: Thanks

13:54 justin_smith: engblom: also, with your existing filter lambda, you would get an error with a one character file name

13:55 (not that this is likely, but just so you know)

13:57 engblom: Ok, now it is outputting a list looking like this: ("28-04146d54e7ff" "28-04146d8243ff")

13:57 How would you remove the "28-" part from each, knowing that in worst case the list is empty?

13:58 justin_smith: ,(clojure.string/replace "28-foo" "28-" "")

13:58 clojurebot: "foo"

13:59 justin_smith: or, if it is guaratneed that all start with 28- #(subs % 3)

13:59 engblom: justin_smith: So another map?

13:59 justin_smith: engblom: right

13:59 ridcully_: if you filter for 28- you can savely remove it. if you have concerns about a `28-` file leaving you with an empty name, you can either use a regexp to filter or just use that file

13:59 justin_smith: ,(subs "28-foo" 3)

13:59 clojurebot: "foo"

13:59 engblom: justin_smith: It is pretty much sure all begins with 28 as we already filtered out only those

13:59 justin_smith: right, right

14:01 engblom: Thanks!

14:02 justin_smith: you could replace the two maps with one keep (keep #(when (.startsWith % "28-") (subs % 3)))

14:03 the when returns nil for non-matches, and those are removed by keep

14:26 engblom: I have a list (key1 key2 key3) and a function f. Now I would want to create a map {key1 (f key1) key2 (f key2) key3 (f key3)}. The value is always what you get when you run f on the key. Is there a ready function for that, or do I need to create one myself?

14:27 justin_smith: (zipmap key-list (map f key-list))

14:27 or (into {} (map (juxt identity f) key-list))

14:28 or (into {} (map (juxt identity f)) key-list)

14:28 I like the last one best

14:32 engblom: Thanks!

14:43 Now I have a pretty useful GPIO library for Raspberry Pi: https://github.com/engblom/gpio

14:43 justin_smith: cool

14:43 engblom: glad you didn't give up when that other one didn't work out

14:44 engblom: I know I am not experienced with Clojure, so if anyone got interrest to improve on it, feel free to do so. I might learn something from that too :)

14:55 kungi: engblom: how does defn ^:private differ from defn-?

14:59 souterrain: engblom: I'm learning clojure, and now I'll have to dust off the RPi as well. Thanks. :)

15:06 noncom|2: did anyone had a chance to install a fresh emacs with prelude recently?

15:19 engblom: kungi: It is the same as far as I understand.

15:20 souterrain: Yes, please do that! I am happy for as much testing as possible of this library.

15:21 souterrain: I think this library should make GPIO programming very simple. It will work as normal unprivileged user.

15:22 souterrain: I have tested it with the Jessie version of Raspbian, which added the gpio user group.

15:23 noncom|2: recently i installed a freshnew emacs and with prelude and it hangs on loading

15:23 it eats 1 core of CPU and all RAM it can get, doing nothing on the stage where prelude should draw its packages

15:23 ...

15:23 what do i do?

15:24 justin_smith: noncom|2: have you tried the -debug-init flag?

15:24 noncom|2: another option is to start "emacs -q" (load no user init), then run each line of your .emacs one at a time in the ielm console

15:25 then you can see which one hangs (and see verbose output as each step runs)

15:26 noncom|2: or, instead of ielm, you can just open your .emacs and use C-M-x to run each line of your .emacs one at a time

15:26 noncom|2: justin_smith: just tried the -debug-init flag.. does not change anything.. emacs starts in its bare configuration, tries contacting melpa on behalf of prelude and hangs..

15:27 i don't actually ahve any customization in init.el at all, it all comes from prelude

15:27 its a fresh one

15:27 would that mean that prelude installation is broken now?

15:27 i can try to run it an instruction-by-instruction..

15:27 justin_smith: noncom|2: until melpa is available, sounds like it...

15:27 noncom|2: yeah, my suggestion would end up leading ot debugging what broke about prelude

15:28 but it sounds like you already know connecting ot melpa is the part that is broken

15:28 sdegutis: Are all Clojure libraries, and Clojure itself, and third party libraries, known to work well with Java JDK 8?

15:28 noncom|2: justin_smith: well, at least, its the last text that remains in the status line when it hangs

15:28 kwladyka: cfleming i heard you can say something about add rum macros like rum/defc rum/defcs and < to curisve in intellij? I want make show parameters, jump to source, refactoring etc. work for https://github.com/tonsky/rum

15:28 engblom: sdegutis: I have not had any problem at least, but that does not neccessary mean much as I have only used a fraction.

15:29 justin_smith: sdegutis: I would hesitate to make any assertion about "all third party libraries". There are definitely at least some third party libs that will break with jdk 8, I'm sure of it. How many? hopefully very few.

15:29 sdegutis: I've had no problems using jdk8 for a large project with many deps

15:30 sdegutis: justin_smith: so then do most people use JDK 1.7 rather?

15:30 justin_smith: sdegutis: why would jdk8 be more likely to break something than 7 would? clojure says it will work with 6+

15:30 in my experience it works great with 6,7, or 8

15:31 sdegutis: Cool.

15:31 justin_smith: I'm just saying, third party libs break in weird ways, and there are a lot of them. But the good ones work with 8, in my experience so far.

15:31 engblom: The library I just wrote will not work with jdk1.6...

15:31 sdegutis: I upgraded to JDK 1.8 a few weeks ago and my server stopped sending emails (it seemed that it no longer could send them) via AWS JDK SES.

15:31 engblom: 1.7 added the WatchService

15:32 justin_smith: sdegutis: is aws using 1.8?

15:32 sdegutis: the one gotcha I can think of is if you were using javac locally with 1.8 and targetting the wrong version

15:33 sdegutis: hmm

15:33 justin_smith: or a random 1.8 bug that you found, I guess?

15:33 sdegutis: maybe

15:34 looking into it today (first day back at work)

15:38 noncom|2: there is (defvar prelude-dir (file-name-directory load-file-name) "comment") at the very beginning, C-x C-e it gives "Wrong type argument: stringp, nil" and everywhere further, prelude-dir == nil. is this okay or does it look like a problem?

15:39 this being nil ruins all other dir inits furhter down..

15:39 but idk if it's the same with the real work, as with C-x C-e

15:40 justin_smith: that expression should return the directory the file is in, but if loading line by line it might not

15:40 you might need to do an explicit set with M-x :

15:40 you can also use M-x : (or an IELM repl buffer) to check the value of prelude-dir, make sure it is set, etc.

15:44 noncom|2: justin_smith: umm it's still always nil.. even if i do : http://joxi.ru/1A5b5BZFKzkEVr and C-x C-e it separately

15:44 there, at the next line where it should be used, it is nil..

15:45 eh.. i guess finding what's the problem with emacs will be a real quest

15:45 justin_smith: noncom|2: defvar is like defonce

15:45 noncom|2: ah

15:45 justin_smith: you need to use setq instead to explicitly set the var

15:45 (only while debugging, of course)

15:45 welcome to the magical world of elisp!

15:45 noncom|2: oh, that really worked!

15:45 ehehe))

15:48 justin_smith: yes, found the line, err: http://joxi.ru/KAgKZaYugNe3kA

15:48 justin_smith: noncom|2: and that is just like clojure require, it looks for the prelude-packages.el file, and the error will be somewhere in there

15:49 noncom|2: yeah

16:08 spieden: anyone using devcards with reagent? can't find versions of both that work together

16:08 jonathanj: justin_smith: cool, i have no intention of mutating it

16:11 noncom|2: justin_smith: heh: http://joxi.ru/BA0d9E6uBvwXnA

16:13 i don't know what could be wrong with it

16:14 simply the package download hangs

16:14 but not just hangs - it wastes a lot of cpu and memory..

16:14 and it never happened before. afaik there were no changes to emacs and prelude since it worked the last time

16:14 :/

16:14 justin_smith: noncom|2: is that host available?

16:16 noncom|2: justin_smith: this one: https://melpa.org/packages/ yes, looks like it is online

16:17 anyway, what a terrible error must be to cause this type of hang..

16:20 damn this is a blocker... i'll have to reside to some sublime text..

17:18 pilne: hrm.. is the reason it is so easy to call frege functions from clojure because frege compiles first to java source and then lets javac compile it down to java bytecode?

17:19 hiredman: clojure interop with other jvm langauges is via the jvm

17:19 the jvm provides types and an object model

17:41 pilne: yeah, but when i mentioned calling scala from clojure, i was told it can be difficult due to the way scala handles things, frege seems to compile down to "plain" java, which is what i assume makes it easy to call it?

17:45 TEttinger: pilne: from what I understand, frege does seem to compile down to some approximation of ordinary java.

17:45 hiredman: my understanding is frege's runtime is more, maybe 'reified' is the right word, so the semantics sort of match the generated code, where scala's compiler is more sophisticated

17:45 TEttinger: this is hello world http://lpaste.net/148367

17:45 (compiled to java)

17:46 there's no defined frege fns there, so I'm not sure how they are callable (I could ask my friend who made it to compile a defn example)

17:46 hiredman: a more sophisticaed compiler, through transforms and optimizations what have you, can result in code that has the semantics of the input language, but looks way different

17:48 pilne: interesting

17:50 this is the kinda shit that really interests me and gets my brain churning... i need a way to hack on things productively on my phone so i can burn downtime at work productively to gain more time hacking code >.< lol

20:01 souterrain: engblom: which JRE are you using on RPi? Just curious whether there are performance issues, or if there is a better one to choose on a small system like that.

20:19 justin_smith: souterrain: I've had good luck with the vm that comes with raspian (sun jdk 8)

20:38 TEttinger: I'm curious if Avian can run Clojure now with something less than the heavyweight OpenJDK class library

20:50 justin_smith: TEttinger: even if it was possible, it would also require people not use non-avian stuff via interop, right?

20:50 TEttinger: mmm

20:54 souterrain: justin_smith: ok, thanks. I'll stick with what raspian comes with then.

21:29 mikerod: are Java type hints safe to leave in cljs code?

21:29 meaning does the compiler allow it

21:29 or do you need to reader-conditional it out etc

21:30 for some reason I haven't been able to find a definite answer to this - I'm just not sure what is the "best practice" there

21:39 banjiewen: I'm running in to a strange issue with static methods in a gen-class and return type casts: https://gist.github.com/banjiewen/cc0a03e16e5880ed60bd

21:39 In short, "ClassCastException rat.fish.RatFish cannot be cast to rat.fish.RatFish" doesn't make much sense to me.

21:39 Guessing I'm lacking some sort of interop understanding

21:41 Any suggestions would be greatly appreciated.

21:41 * banjiewen goes back to googling

21:45 mikerod: @banjiewen I think I don't see enough info here to try to diagnose the issue

21:46 or I don't understand all the tricky details about gen-class

21:46 it sort of sounds to me like you have multiple instances of the same class from conflicting class loaders

21:46 banjiewen: mikerod: RatFish is a pretty straightforward `defrecord` in ns rat.fish

21:47 mikerod: perhaps you have an AOT-compile-loaded RatFish in the AppClassLoader and then you have a 2nd version of this RatFish from a Clojure DynamicClassLoader due to the :require

21:47 I can't immediately think of any related Jiras or anything to this and I cannot see how you could be doing something wrong here really

21:50 banjiewen: Thanks for taking a look, anyway.

21:51 justin_smith: banjiewen: this happens because of reloaded code

21:51 banjiewen: There's no way to stick a static method on a defrecord'd class, is there?

21:51 justin_smith: banjiewen: the old object is not an instance of the new definition

21:51 banjiewen: yes, there is

21:51 oh wait, not statics

21:51 n/m

21:52 banjiewen: justin_smith: I'll try with a clean environment to see

21:52 justin_smith: banjiewen: you might need to run lein clean before starting a new repl

21:52 banjiewen: kk

22:03 mikerod: banjiewen: I'd like to see the series of steps you take

22:03 to build the project and then run your repl

22:04 it does seem like you're managing to get Clojure's DynamicClassLoader to load up a RatFish class instance after your AOT-compiled code has already loaded a RatFish class instance with another loader - probably your system dependent "AppClassLoader"

22:04 or "jvm dependent" I guess

22:05 banjiewen: mikerod: Looks like justin_smith was right about the environment - too much cruft lying around. `lein clean` followed by some fixup on my project.clj cleared up the issue.

22:05 Thanks both.

22:05 mikerod: haha good

22:05 that makes it simple then

22:06 justin_smith: alias wat lein clean

22:06 heh

22:06 mikerod: AOT-compiled code is often a quick way to get in scenarios where you see MyClass cannot be cast to MyClass

23:05 jeaye: How could I make this work: (update-in {:foo {:bar [1 2 3 4 5 6]}} [:foo :bar] remove even?)

23:05 justin_smith: ,(update-in {:foo {:bar [1 2 3 4 5 6]}} [:foo :bar] (partial remove even?))

23:05 clojurebot: {:foo {:bar (1 3 5)}}

23:06 jeaye: ,(update-in {:foo {:bar [1 2 3 4 5 6]}} [:foo :bar] #(remove even? %))

23:06 clojurebot: {:foo {:bar (1 3 5)}}

23:06 jeaye: justin_smith: Ah, beat me to it.

23:06 Thanks.

23:07 justin_smith: np - you almost had the answer already, clearly

23:07 jeaye: also, if you have flip (update-in m (flip remove) even?)

23:07 jeaye: ,(doc flip)

23:07 clojurebot: I don't understand.

23:07 justin_smith: err, forgot the kvec but I think you get the idea

23:08 jeaye: Where does flip live?

23:08 justin_smith: jeaye: flip is a function available in a few util libs that returns a new function taking the same number of args, in the opposite order

23:08 jeaye: Ah. I don't have it.

23:08 justin_smith: I think there is a version of flip in flatland/useful and also in prismatic/plumbing

23:08 also it is an easy function to write

23:09 ,(defn flip [f] (fn [& args] (apply f (reverse args))))

23:09 clojurebot: #'sandbox/flip

23:09 jeaye: No problem. I'll leave it as-is for now.

23:09 justin_smith: ,(update-in {:foo {:bar [1 2 3 4 5 6]}} [:foo :bar] (flip remove) even?)

23:09 clojurebot: {:foo {:bar (1 3 5)}}

Logging service provided by n01se.net