2015-12-09
| 00:00 | dongcarl | justin_smith: wow... clojure syntax is tricky... |
| 00:00 | justin_smith | owlbird: eval is like riding a sherman tank down the block to get a soda from the convenience store two buildings away |
| 00:00 | owlbird | The fun will be given to :row-fn while querying data from db. |
| 00:00 | justin_smith | owlbird: maybe you just want identity |
| 00:00 | justin_smith | ,(identity 42) |
| 00:01 | clojurebot | 42 |
| 00:02 | owlbird | no, it's just a sample code, there may be many styles, each one will has its row-fn to format the result-set |
| 00:02 | justin_smith | owlbird: why would you call eval? |
| 00:03 | owlbird | if no style fun was found, just return the original value |
| 00:03 | justin_smith | owlbird: eval is like the worst possible way to return the original value, replace it with identity |
| 00:03 | justin_smith | that's what I was saying |
| 00:03 | justin_smith | also if you give eval a list with symbols you probably wouldn't like the result |
| 00:04 | owlbird | oh... I got you |
| 00:04 | owlbird | many thx |
| 00:06 | justin_smith | owlbird: eval is for compiling code, it just happens to act like identity for inputs that are not lists |
| 00:06 | justin_smith | or symbols |
| 00:21 | dongcarl | justin_smith: question, when it calls one of the defmethods, is the argument the same as the argument for defmulti or is it ch? |
| 00:22 | Trioxin | it's too bad this doesn't seem to be actively developed anymore https://github.com/arcadia-unity/Arcadia |
| 00:27 | justin_smith | dongcarl: it gets the same argument the dispatch function did |
| 00:31 | Trioxin | what would one use in terms of an engine to begin game dev in clojure? |
| 00:33 | dongcarl | justin_smith: can you help me understand what's going on here: https://github.com/shaunlebron/parinfer/blob/master/lib/src/parinfer/reader.cljc#L95 |
| 00:33 | dongcarl | or anyone really |
| 00:33 | dongcarl | here's what a "state" usually looks like https://github.com/shaunlebron/parinfer/blob/master/lib/src/parinfer/indent_mode.cljc#L19 |
| 00:34 | dongcarl | it's calling (select-keys state [:x-pos :ch]), but state doesn't have keys :x-pos or :ch |
| 00:34 | dongcarl | stack does |
| 00:34 | dongcarl | so is it just zeroing out the values in stack using conj? |
| 00:37 | ridcully | Trioxin: libgdx has a wrapper: play-clj |
| 00:39 | ridcully | Trioxin: depending on the kind of game you plan, something like quil could be enough. also consider clojurescript |
| 02:55 | visof | hi guys |
| 02:56 | visof | what is the best effiecient way to read multiple url in parallel?, what i know is make each one in future then use @ for all is this the right solution? |
| 03:16 | Guest53639 | %CLEAR |
| 03:16 | Guest53639 | CLEAR |
| 03:23 | riceandbeans | why does hello world take 13.28 seconds to run? |
| 03:24 | visof | riceandbeans: that's jvm |
| 03:24 | visof | riceandbeans: you run it as jar? |
| 03:25 | visof | riceandbeans: use lein uberjar to get the jar |
| 03:25 | amalloy | it's not the jvm, it's lein |
| 03:26 | visof | amalloy: why lein get all of this time? |
| 03:27 | amalloy | because it loads a bunch of crap, does a bunch of scanning the classpath? i don't know exactly |
| 03:29 | riceandbeans | good god |
| 03:29 | riceandbeans | 22 seconds to build a hello world jar |
| 03:30 | riceandbeans | ok, so java jar hello world takes 5.21 seconds |
| 03:30 | riceandbeans | still less than awesome |
| 03:31 | riceandbeans | yes, I'm totally judging your language based on hello world |
| 03:37 | visof | riceandbeans: https://github.com/technomancy/leiningen/wiki/Faster |
| 04:30 | owlbird | why do the clojure.jdbc functions like db-do-prepared, update!, delete! return a seq, while the original jdbc API return int |
| 04:50 | Gamer-Pro | Hello Guys |
| 04:50 | Gamer-Pro | Download this game from here |
| 04:50 | Gamer-Pro | http://www.indiedb.com/games/spaceshooter-x1/downloads/spaceshooter-x1-update-for-windows |
| 04:50 | Gamer-Pro | This game is the best game of the world |
| 04:55 | BRODUS | anyone know what version of clojure 4clojure uses ? |
| 04:57 | powered | 1.6 I think or lower |
| 04:57 | powered | because some 1.7 functions don't work |
| 05:06 | BRODUS | powered: thanks. I think its at least lower than 1.5 since its not recognizing reduced. |
| 05:36 | jonathanj | if anyone has some time to spare on some code golf, it would be appreciated: https://pb.codehash.net/5276b95b8f404573b3ff1db95717e4ca |
| 06:06 | parsing_clj | Hi there! I want to write a parser and im using insta parse |
| 06:07 | parsing_clj | this is my grammar so far ,modified from the README: http://pastebin.com/3wqcZzLc |
| 06:08 | parsing_clj | I want to parse **THIS IS A HEADLINE**, the same as ** THIS IS A HEADLINE ** |
| 06:08 | parsing_clj | so basically ignore the white spaces, does anyone knoe how to do that? |
| 06:11 | ARM9 | parsing_clj try '**' for head |
| 06:11 | parsing_clj | ARM9: ok |
| 06:15 | ridcully | jonathanj: the merge looks fine to me. i'd extract that interop chain into something nicely named |
| 06:22 | visof | parsing_clj: you use trim first |
| 06:22 | visof | ,(trim "** THIS IS A HEADLINE **") parsing_clj |
| 06:23 | clojurebot | #error {\n :cause "Unable to resolve symbol: trim in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: trim in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: trim in this co... |
| 06:23 | visof | ,(clojure.string/trim "** THIS IS A HEADLINE **") parsing_clj |
| 06:23 | clojurebot | "** THIS IS A HEADLINE **" |
| 06:23 | visof | oh |
| 06:24 | ARM9 | what did you have in mind? |
| 06:24 | visof | parsing_clj: you can use tokens lib stanfordnlp |
| 06:24 | ARM9 | it'd be nice if instaparse had some sort of tokenizer |
| 06:25 | visof | stanford-talk has very good example process-text |
| 06:25 | l1x | hi guys |
| 06:25 | l1x | i am trying to use this java lib in clojure http://basho.github.io/riak-java-client/2.0.1/com/basho/riak/client/api/RiakClient.html#newClient(java.net.InetSocketAddress...) |
| 06:26 | l1x | https://gist.github.com/l1x/98a242724dc5762c0677 |
| 06:26 | owlbird | how to display method name in logs while using tools.logging with log4j |
| 06:26 | l1x | i was wondering why i could not pass in an InetSocketAddress |
| 06:27 | owlbird | I use the %M pattern, but all methods was shown as "invoke" |
| 06:27 | visof | have you (import '[com.basho.riak.client.api RiakClient]) |
| 06:27 | visof | ? |
| 06:27 | l1x | yes |
| 06:28 | l1x | it says no matching method |
| 06:28 | l1x | what does ... mean in java? isnt that a linkedlist? |
| 06:28 | ARM9 | probably varargs |
| 06:29 | visof | l1x: RiakClient.newClient("192.168.1.1","192.168.1.2","192.168.1.3"); but you pass b |
| 06:29 | visof | is it working with this example? |
| 06:29 | l1x | no this is the java way |
| 06:30 | l1x | (RiakClient/newClient 10017 (java.util.LinkedList. '("127.0.0.1" ))) |
| 06:30 | l1x | the clojure version works |
| 06:30 | l1x | i am wondering what is addresses |
| 06:30 | l1x | or how could i figure out its type |
| 06:32 | schmir | l1x: you need to pass something like (into-array java.net.InetSocketAddress [...]) |
| 06:32 | schmir | (as the only argument) |
| 06:33 | l1x | schmir: thanks! |
| 06:35 | l1x | schmir: how would you do that? (into-array (InetSocketAddress. "127.0.0.1" 10017)) Don't know how to create ISeq from |
| 06:36 | l1x | (RiakClient/newClient (into-array [(InetSocketAddress. "127.0.0.1" 10017)])) |
| 06:36 | l1x | like this :) |
| 06:36 | l1x | thanks! |
| 06:37 | schmir | (into-array java.net.InetSocketAddress [(java.net.InetSocketAddress. "foo" 3123)]) |
| 06:44 | jonathanj | so ring.util.io/piped-input-stream uses a nested future to do it's thing |
| 06:44 | jonathanj | Source: https://github.com/ring-clojure/ring/blob/1.4.0/ring-core/src/ring/util/io.clj#L11 |
| 06:45 | jonathanj | the problem with that is that anything that goes wrong in `func` goes completely unnoticed and unhandled |
| 06:47 | jonathanj | would it make sense to do something like: (let [rethrow #(throw %)] (piped-input-stream (fn [output] (try (... some code ...) (catch Exception e (rethrow e))))))? |
| 06:48 | jonathanj | is it possible to attach a listener that is executed when a future is realized? |
| 06:49 | jonathanj | deref-ing a future without knowing if it's going to block or not is not ideal |
| 06:52 | tdammers | if you don't want it to block, then maybe a future isn't the right primitive to use? |
| 06:55 | jonathanj__ | tdammers: what are my other options? |
| 06:57 | tdammers | well, you could roll your own code using atoms and lambdas |
| 06:58 | tdammers | but (realized? f) would probably fit the bill |
| 06:58 | tdammers | i.e., only deref the future if realized? says it's ready |
| 07:41 | jonathanj | tdammers: i guess the question then is what do you do if it's not realized by the time you test it? |
| 07:43 | tdammers | jonathanj: well, what *can* you do? fail hard, or mitigate. It depends on what you want it to do in that case |
| 07:43 | jonathanj | there's a third choice: wait some more |
| 07:43 | tdammers | I'd file that under "mitigate" |
| 07:44 | tdammers | but yeah |
| 07:44 | jonathanj | i see manifold can coerce futures to deferreds, which means i can use (chain) add a callback |
| 07:44 | tdammers | another option would be to restructure your code such that the part that blocks on the future runs in a separate thread |
| 07:44 | jonathanj | it's kind of annoying there isn't anything in the core library that is effectively (wait-for-this-dereffable-then-do derefable f) |
| 07:45 | jonathanj | i suppose it's probably a lot of complexity |
| 07:49 | l1x | how can i translate the chained java methods to Clojure the easiest? new StoreValue.Builder(riakObject) .withLocation(location) |
| 07:49 | l1x | .withOption(Option.W, new Quorum(3)).build(); |
| 07:49 | l1x | (.something (.withOption ....) right? |
| 07:50 | l1x | there is the .. macro |
| 07:54 | jonathanj | i think: (.. (StoreValue.Builder. riakObject) (withLocation location) (withOption Option/W (Quorum. 3) build) |
| 07:54 | l1x | nice! |
| 07:54 | l1x | thanks jonathanj |
| 07:54 | jonathanj | i missed a ) before the last build |
| 07:55 | l1x | isnt StoreValue.Builder supposed to be StoreValue/Builder? |
| 07:55 | jonathanj | i don't know, possibly, it kind of depends on what it is |
| 07:56 | jonathanj | if it's a static, then yes |
| 07:56 | l1x | thank you |
| 07:56 | jonathanj | if it's an inner class then it gets a bit hairier |
| 07:57 | jonathanj | i think you basically turn the . into $ for inner classes |
| 07:57 | jonathanj | http://blog.jayfields.com/2011/01/clojure-using-java-inner-classes.html |
| 07:57 | l1x | huh, never done that |
| 07:58 | l1x | i am trying out |
| 08:00 | jonathanj | from the docs, it looks like it is an inner class |
| 08:00 | jonathanj | so you need to import StoreValue$Builder and address it like that |
| 08:07 | l1x | https://gist.github.com/l1x/f78b129367a1a6ce80b3 |
| 08:07 | l1x | like this? |
| 08:08 | jonathanj | yes |
| 08:09 | l1x | cool now i need to figure out how to chain them |
| 08:10 | l1x | store (.build (.withLocation riak-location (StoreValue/Builder. riak-object))) |
| 08:10 | l1x | something like that |
| 08:10 | jonathanj | the name is StoreValue$Builder |
| 08:10 | l1x | this works -> (StoreValue$Builder. riak-object) |
| 08:11 | jonathanj | you can use .. to pull that structure inside out |
| 08:11 | l1x | yes |
| 08:12 | l1x | (.withLocation (StoreValue$Builder. riak-object) riak-location) |
| 08:12 | l1x | this also works |
| 08:12 | yenda | Does it make sense if I have a clojure app to build a cljs interface for it ? |
| 08:12 | l1x | jonathanj: yeah |
| 08:14 | jonathanj | i'm assuming withLocation mutates the object and returns `this`, in which case (doto) might also be useful |
| 08:15 | gfredericks | doto doesn't need the object to be returned |
| 08:15 | gfredericks | methods that return `this` can be used with -> |
| 08:16 | jonathanj | what i meant was: since the return value is always the same object you can use doto instead of .. to chain the calls |
| 08:16 | l1x | https://basho.github.io/riak-java-client/2.0.0/com/basho/riak/client/api/commands/kv/StoreValue.Option.html |
| 08:16 | jonathanj | which gives you a bit more flexibility because if you have something that is not part of a chained call, you can put it in your (doto) form, whereas with (..) you need to start a new form |
| 08:17 | l1x | i guess i need to import this |
| 08:17 | l1x | with the $ way |
| 08:17 | jonathanj | gfredericks: my experience with Java interop is that -> is not often useful because the order of the arguments wobbles around a lot |
| 08:18 | jonathanj | but i guess those chained calls would work perfectly well |
| 08:22 | ridcully | also doto would not return the build-result, but the builder? |
| 08:24 | jonathanj | yeah, that's true |
| 08:24 | jonathanj | how the heck does (is (thrown? ...)) work? |
| 08:25 | luma | it's magic |
| 08:25 | jonathanj | i went looking for a function `thrown?` and found nothing, then read the docs for clojure.test |
| 08:26 | l1x | jonathanj: thank you very much for your help |
| 08:26 | l1x | it works! :) |
| 08:26 | l1x | https://gist.github.com/l1x/f78b129367a1a6ce80b3 |
| 08:26 | luma | the is-macro checks if the first item of the list is 'thrown?, and acts accordingly if it is |
| 08:26 | l1x | do you think I should rewrite it using the .. ? |
| 08:26 | jonathanj | how do i use thrown? with ex-info? |
| 08:27 | jonathanj | l1x: or -> like gfredericks suggested |
| 08:27 | luma | well, the only thing you can check is if an exception of a specific class is thrown |
| 08:27 | luma | or specific class and message with thrown-with-msg? |
| 08:27 | jonathanj | luma: yeah... (ex-info) kind of hides that from me |
| 08:28 | luma | ex-info creates an exception of class ExceptionInfo, you can check for that |
| 08:28 | jonathanj | can i test the info on an ex-info? |
| 08:28 | luma | no |
| 08:28 | jonathanj | so i guess i write my own (try) |
| 08:29 | luma | or yes, but then you have to manually catch it with (try ... (catch ExceptionInfo ex ...)) |
| 08:30 | jonathanj | i think maybe it's time to use midje |
| 08:31 | l1x | thanks |
| 08:32 | jonathanj | l1x: :) |
| 08:45 | BRODUS | any ideas why this simple try catch block isn't working |
| 08:45 | BRODUS | (try (keys [1 2 3]) (catch Exception e (println "error"))) |
| 08:45 | opqdonut | ,(keys [1 2 3]) |
| 08:45 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to java.util.Map$Entry> |
| 08:45 | BRODUS | right, I expect it to fail |
| 08:46 | opqdonut | I just checked what the exception is |
| 08:46 | opqdonut | an Error wouldn't get caught, but it's an Exception |
| 08:46 | beaky | ,(try (keys [1 2 3]) (catch Exception e (0))) |
| 08:46 | clojurebot | beaky: I don't understand. |
| 08:46 | beaky | :( |
| 08:47 | opqdonut | (0) is wrong anyway |
| 08:47 | beaky | ,(try (keys [1 2 3]) (catch Exception e (nil)))) |
| 08:47 | clojurebot | beaky: Cool story bro. |
| 08:47 | BRODUS | Caused by java.lang.IllegalArgumentException |
| 08:47 | BRODUS | Can't call nil |
| 08:47 | opqdonut | beaky: you have one ) too much |
| 08:48 | opqdonut | BRODUS: very interesting |
| 08:48 | opqdonut | it indeed doesn't work |
| 08:48 | ARM9 | contemplate why (nil) is erronous |
| 08:49 | opqdonut | BRODUS: ah, I know, keys returns a lazy sequence! |
| 08:50 | opqdonut | for some reason (doall (keys [1 2 3])) doesn't help though |
| 08:50 | opqdonut | but e.g. (first (keys [1 2 3])) does work |
| 08:50 | opqdonut | ,(try (first (keys [1 2 3])) (catch Throwable e :error)) |
| 08:50 | clojurebot | opqdonut: I don't understand. |
| 08:50 | BRODUS | i understand lazy sequences mostly, but its not clear why thats the reason its failing |
| 08:50 | opqdonut | clojurebot has probably banned try-catch |
| 08:51 | luma | because it's a lazy sequence, the error isn't thrown inside the try |
| 08:51 | opqdonut | the error is thrown when somebody tries to use the result |
| 08:51 | luma | the lazy sequence is returned out of the try, and the error is thrown when that lazy sequence is later realized |
| 08:51 | opqdonut | ,(do (keys [1 2 3]) 1) |
| 08:51 | clojurebot | 1 |
| 08:51 | opqdonut | see, no error |
| 08:52 | opqdonut | ,(do (first (keys [1 2 3])) 1) |
| 08:52 | clojurebot | #error {\n :cause "java.lang.Long cannot be cast to java.util.Map$Entry"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.Long cannot be cast to java.util.Map$Entry"\n :at [clojure.lang.APersistentMap$KeySeq first "APersistentMap.java" 166]}]\n :trace\n [[clojure.lang.APersistentMap$KeySeq first "APersistentMap.java" 166]\n [clojure.lang.RT first "RT.java" 660]\n [clojure.... |
| 08:52 | opqdonut | ,(do (doall (keys [1 2 3])) 1) -- I have no idea why this doesn't break though |
| 08:52 | clojurebot | 1 |
| 08:54 | MJB47 | doall is only used for side effects |
| 08:54 | MJB47 | it returns nill iirc |
| 08:54 | MJB47 | while first returns the value |
| 08:54 | opqdonut | MJB47: doall should still realise the sequence and give me the error |
| 08:55 | opqdonut | ,(doall (map #(/ % 0) [1 2 3])) -- e.g. |
| 08:55 | clojurebot | #error {\n :cause "Divide by zero"\n :via\n [{:type java.lang.ArithmeticException\n :message "Divide by zero"\n :at [clojure.lang.Numbers divide "Numbers.java" 158]}]\n :trace\n [[clojure.lang.Numbers divide "Numbers.java" 158]\n [clojure.lang.Numbers divide "Numbers.java" 3788]\n [sandbox$eval122$fn__123 invoke "NO_SOURCE_FILE" 0]\n [clojure.core$map$fn__4541 invoke "core.clj" 2625]\n [cl... |
| 08:55 | opqdonut | ,(do (map #(/ % 0) [1 2 3]) 1) -- for comparison |
| 08:55 | clojurebot | 1 |
| 08:56 | luma | opqdonut: it's because of how keys works |
| 08:56 | luma | dorun/doall just continuously calls next on the sequence |
| 08:57 | luma | and KeySeq (which is what implements keys) only actually produces the key when first is called on it |
| 08:57 | opqdonut | but clojure sequences are only lazy in the spine, not the values |
| 08:57 | luma | not when next is called on it |
| 08:57 | opqdonut | oh, KeySeq is special |
| 08:57 | opqdonut | bah |
| 08:57 | luma | https://github.com/clojure/clojure/blob/clojure-1.7.0/src/jvm/clojure/lang/APersistentMap.java#L165-L171 |
| 08:58 | opqdonut | thanks |
| 08:58 | yenda | Is it possible to have a clojurescript frontend for a clojure program ? is there something simpler than using ring to make them talk to each other ? |
| 08:59 | dnolen | yenda: yes. I can't think of anything much simpler than ring etc. |
| 09:01 | BRODUS | thanks for the help everyone |
| 09:04 | jonathanj | luma: how do actually address ExceptionInfo? |
| 09:05 | jonathanj | clojure.lang.ExceptionInfo it seems |
| 09:07 | yenda | dnolen: so ring+compojure is the way to go ? |
| 09:07 | j-pb | yenda: bidi is nicer when you do cljs as well |
| 09:08 | j-pb | it allows you to share routes between cljs and clj and generate urls from those shared datastructures |
| 09:08 | j-pb | it's much more declarative than compojure |
| 09:08 | j-pb | you can also use a websocket, if you want more real live communication between your ab and it's ui |
| 09:09 | j-pb | but then you are more constrained in terms of browser support |
| 09:09 | yenda | j-pb: Browser support is not a problem |
| 09:11 | j-pb | setting up a websocket connection is not that hard to do, and it's somewhat nicer than posts |
| 09:11 | j-pb | I'd pick something like sente for that |
| 09:12 | dnolen | yenda: there is no "way to go" |
| 09:12 | dnolen | but yes that will work |
| 09:13 | powered | you still need ring for Sente |
| 09:14 | j-pb | powered: yeah true, but it's a lot less exposed |
| 09:14 | powered | true |
| 09:14 | yenda | j-pb: I'm not sure I need websockets though |
| 09:15 | yenda | I just need to call functions that alter structures or have side effects and return results |
| 09:15 | powered | if you don't want low latency or server -> client messages then don't use websockets |
| 09:19 | yenda | powered: sente could be nice to watch components state I could add it later |
| 09:19 | yenda | powered: but for now I just want to have a UI to call functions and move stuff in a graph and send it back again to other functions |
| 09:20 | powered | right so you need a simple and quick middleware setup? |
| 09:20 | powered | sente's good for that too |
| 09:23 | yenda | powered: ok, I settled for om frontend-wise so I'm gonna see how it fits with sente |
| 09:24 | jonathanj | if the body of a (future) throws, that exception is wrapped in ExecutionException, is it possible to not do that? |
| 09:28 | j-pb | jonathanj: you could catch the exception within the future |
| 09:42 | QU35t | Fellas |
| 09:42 | opqdonut | jonathanj: or you can just unwrap it when forcing the future |
| 09:48 | jonathanj | j-pb: i actually want the exception though |
| 09:48 | jonathanj | opqdonut: yeah, that's a little bit inconvenient since i'm writing tests for something that returns a future |
| 09:49 | jonathanj | on another note, does anyone use cider and midje together? i can't really seem to get the cider test running stuff working with midje |
| 09:58 | heero_ | Hi, is there a function to reduce over multiple coll ? |
| 09:59 | heero_ | (reduce coll init list1 list2 ...) |
| 10:00 | j-pb | heero_: (reduce fn init (map vector col1 col2 col3 ...)) ? |
| 10:00 | powered | (remove even? {:a 1 :b 2 :c 3}) |
| 10:01 | powered | what is the function I'm looking for instead of remove ? |
| 10:02 | j-pb | powered: clojure had something like that as a contrib library |
| 10:02 | heero_ | j-pb: ok thx |
| 10:04 | MJB47 | wouldnt filter work? |
| 10:05 | MJB47 | ,(filter #(even? (second %)) {:a 1 :b 2 :c 3}) |
| 10:05 | powered | this works: (remove #(even? (second %)) {:a 1 :b 2 :c 3}) |
| 10:05 | clojurebot | ([:b 2]) |
| 10:05 | powered | ah yes |
| 10:06 | j-pb | ,(remove (comp even? val) {:a 1 :b 2 :c 3}) |
| 10:06 | clojurebot | ([:a 1] [:c 3]) |
| 10:09 | j-pb | (apply into ((juxt empty (partial remove (comp even? val))) {:a 1 :b 2 :c 3}) |
| 10:09 | j-pb | ,(apply into ((juxt empty (partial remove (comp even? val))) {:a 1 :b 2 :c 3}) |
| 10:09 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 10:09 | j-pb | ,(apply into ((juxt empty (partial remove (comp even? val))) {:a 1 :b 2 :c 3})) |
| 10:09 | clojurebot | {:a 1, :c 3} |
| 10:09 | j-pb | srcr |
| 10:10 | j-pb | scnr lol |
| 10:21 | kungi | How do I do an   in hiccup? |
| 10:22 | kungi | nevermind I found " " :-) |
| 11:03 | visof | hi guys |
| 11:15 | sdegutis | I don't know why I signed onto IRC and into #clojure. It was just habit I guess. |
| 11:15 | sdegutis | So.. um.... hi? |
| 11:20 | Shambles_ | sdegutis: Hi. |
| 11:20 | sdegutis | Hi. |
| 11:20 | sdegutis | I take it justin_smith is asleep then? |
| 11:28 | Shambles_ | sdegutis: I have no idea. |
| 11:28 | sdegutis | :) |
| 11:38 | WorldsEndless | So, I thought the doseq family of functions ran only as long as the shortest supplied vector, but was proved wrong by(doseq [n (increment 1) v [\a \b \c]] (println n v)) |
| 11:38 | j-pb | doseeq is like for |
| 11:39 | j-pb | so if you have |
| 11:39 | WorldsEndless | So what if I just want to assign a number to each item of another thing (i.e. for file output) |
| 11:39 | j-pb | (map vector col (range)) |
| 11:39 | j-pb | or (map-indexed vector col) |
| 11:39 | j-pb | I prefer the first, but others would probably disagree |
| 11:40 | j-pb | ,(map vector [:a :b :c] (range)) |
| 11:40 | clojurebot | ([:a 0] [:b 1] [:c 2]) |
| 11:40 | j-pb | like this? |
| 11:40 | WorldsEndless | I guess with the latter, I'd then be able to extract the index with something like (doseq [[n v] indexed-vector]) ? |
| 11:40 | j-pb | why do you want to do that? |
| 11:40 | j-pb | yes, but |
| 11:41 | j-pb | you can force lazy evaluation, with dorun and doall :) |
| 11:41 | WorldsEndless | j-pb: Ah, map is the one that truncates on teh shortest, not the comprehensions. Ok |
| 11:41 | j-pb | yeah |
| 11:41 | j-pb | the comprehensions will walk sequences later provided for each element before |
| 11:42 | j-pb | ,(for [x (range 3) y (range 3) z (range 3)] [x y z]) |
| 11:42 | clojurebot | ([0 0 0] [0 0 1] [0 0 2] [0 1 0] [0 1 1] ...) |
| 11:42 | j-pb | ,(for [x (range 2) y (range 2) z (range 2)] [x y z]) |
| 11:42 | clojurebot | ([0 0 0] [0 0 1] [0 1 0] [0 1 1] [1 0 0] ...) |
| 11:44 | WorldsEndless | So with the comprehensions, I should avoid infinite sequences, or just position them later? |
| 11:45 | WorldsEndless | rightwards, that is |
| 11:45 | j-pb | with doseq don't do infinite sequences |
| 11:45 | j-pb | beause it's eager |
| 11:46 | WorldsEndless | I'm guessing that as long as you respect the laziness, (for) should be okay? |
| 11:46 | j-pb | with for, you can happily have infinite sequences, but if you have one nothing before it will advance |
| 11:46 | j-pb | yeah |
| 11:46 | j-pb | ,(for [x (range) y (range 2)] [x y]) |
| 11:46 | clojurebot | ([0 0] [0 1] [1 0] [1 1] [2 0] ...) |
| 11:46 | j-pb | however |
| 11:46 | j-pb | ,(for [x (range 2) y (range)] [x y]) |
| 11:46 | clojurebot | ([0 0] [0 1] [0 2] [0 3] [0 4] ...) |
| 11:47 | WorldsEndless | Cool. I'm still not as fluent as I would like to be in laziness |
| 11:47 | j-pb | you might as well had written |
| 11:47 | j-pb | ,(for [x [0] y (range)] [x y]) |
| 11:47 | clojurebot | ([0 0] [0 1] [0 2] [0 3] [0 4] ...) |
| 11:47 | j-pb | because it will never get passed the first element |
| 12:22 | WorldsEndless | regexp aren't behaving as I expect. Why is #"^" not matching "beginning of line"? |
| 12:23 | ridcully | ,(re-seq #"(?m)^\w" "a b c\nd e f") |
| 12:23 | clojurebot | ("a" "d") |
| 12:24 | WorldsEndless | ooh. ?m is new to me |
| 12:24 | WorldsEndless | is there a doc page for that (googling for regexps is hair-whitening)? |
| 12:25 | luma | WorldsEndless, http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html |
| 12:25 | justin_smith | WorldsEndless: all the (?*) flags are documented in the javadocs |
| 12:25 | justin_smith | or what luma said |
| 12:27 | WorldsEndless | beautiful. That link will come in handy, too. Thanks. |
| 12:42 | WorldsEndless | basic (probably java) question here: I have a dir-path string (not file). If it doesn't exist, I need to create the file. make-parents doesn't seem to do the trick, since it's a dir. What function do I need here? |
| 12:44 | WorldsEndless | Ah. Files.createDirectory |
| 12:45 | WorldsEndless | I learn much more of Java from working in Clojure than I did in years of classes in Java... |
| 13:15 | yenda | haha same for me |
| 13:16 | yenda | and I learned more of Clojure in 3 months than in java in 3 years |
| 13:40 | ecmike | Use Clojure to learn Java, use Java to learn Boilerplate |
| 14:15 | tolstoy | Learn Clojure to have fun at home, and Java to have someone else decide what and when to do a job-jar task based on a 10-year-old outdated architecture. |
| 14:15 | tolstoy | "For 15 years we've known inheritance is a bad way to model your domain." Scribbles: Not a team player. Doesn't get Agile. |
| 14:15 | tolstoy | Doesn't understand "the business". |
| 14:15 | tolstoy | </rant> |
| 14:16 | tolstoy | More positively: I wonder if there's a place for a "lein" like script that uberjars up clojure + that fs library for scripting (if you don't mind slow JVM start up, which I don't). |
| 14:23 | justin_smith | tolstoy: it's not the jvm that is slow to start up, it's clojure |
| 14:24 | tolstoy | I've got a "clj" script that starts up the repl. Plenty fast for me. I'd love something with some extra file-system utils. |
| 14:25 | justin_smith | sure, make a project with the right deps, uberjar, then you can do "java -cp your.jar clojure.main" to get a repl |
| 14:25 | justin_smith | you don't even need any main ns or aot for that to work |
| 14:25 | tolstoy | Right! |
| 14:25 | justin_smith | for bonus points put pomegranate in there too, so that maven deps can be pulled in at runtime |
| 14:26 | justin_smith | (if you really need them) |
| 14:26 | tolstoy | Exactly. You can have the "mh" of build systems. |
| 14:26 | justin_smith | heh |
| 14:26 | alive876 | hi newbie here, i have a project that "lein run" works "lein test" ok , but when i run "lein repl" i get Var null/null is unbound. the project file and main file are http://pastebin.com/2pWGAP0u and http://pastebin.com/Pn721weh thanks much |
| 14:27 | tolstoy | A simple app to build a classpath. Another app to run a repl. Then just compose them. No complicated "boot" thing. ;) |
| 14:28 | tolstoy | Really, all you need is something to resolve deps and the rest: bash (or whatever). |
| 14:28 | tolstoy | Hm. How do you get the org mode manual inside an emacs buffer? I don't know how to work the help system. |
| 14:28 | justin_smith | alive876: I don't know noir but :ns 'jcrit is suspicious - there is no ns called jcrit there |
| 14:29 | justin_smith | tolstoy: M-x info |
| 14:29 | alive876 | ok , ty |
| 14:29 | tolstoy | justin_smith Thanks! |
| 14:29 | justin_smith | tolstoy: after that you can click the hyperlinks or nav via keyboard |
| 14:30 | justin_smith | tolstoy: info is pretty cool - for example incremental search will look into subchapters that aren't visible in the buffer |
| 14:30 | justin_smith | and using org, you can create followable links to places in the info system! |
| 14:30 | justin_smith | (full circle) |
| 14:31 | tolstoy | justin_smith: That's great. I always need to look up in buffer options. |
| 14:31 | alive876 | (ns jcrit.server |
| 14:33 | justin_smith | alive876: right, I was referring to the args to the noir server start. Also, just fyi lib-noir is still maintained, but noir itself is deprecated and they recommend using ring + your routing lib of choice directly |
| 14:34 | alive876 | ok thanks |
| 14:35 | tolstoy | Hm. I always have `:main ^:skip-aot foo.bar`. I wonder if that metadata tag is even needed anymore? |
| 14:35 | alive876 | but for my edification , this does or doesn't create the jcrit ns? |
| 14:35 | alive876 | i mean (ns jcrit.server |
| 14:35 | justin_smith | alive876: no, it creates the jcrit.server ns |
| 14:36 | alive876 | ok,thanks |
| 14:36 | tolstoy | alive876 Try commenting out the (server/load-views ...) form and see if that fixes it. |
| 14:36 | rhg135 | tolstoy: AFAIK not till lein 3 |
| 14:37 | rhg135 | For now aot is the default for main |
| 14:37 | tolstoy | rhg135: Ah. I've been including that so long, the problem it solved for me has receded into the dim mists of time. |
| 14:37 | justin_smith | but if your jar / uberjar isn't meant to be a point click run app, you don't need a :main-ns |
| 14:39 | rhg135 | Yeah, I guess the maintainers assumed lein 3 would come soon |
| 14:40 | rhg135 | The bug report is old |
| 14:41 | alive876 | <justin_smith> that doesn't seem to work. and at the beginning i keep getting this too:Consider using [enlive "1.0.0" :exclusions [org.clojure/clojure]]. |
| 14:46 | justin_smith | alive876: that's a separate issue - you are using an old version of enlive which asks for a different version of clojure than your other libs |
| 14:46 | justin_smith | noir probably asks for some ancient version of clojure like 1.3 or something |
| 14:47 | alive876 | it seems a lot of broken tutorials out there |
| 14:47 | justin_smith | alive876: yeah, clojure moves a little faster than the google magic that would lead you to the up to date stuff |
| 14:49 | justin_smith | but that's just a warning, the real issue is that noir isn't being started up properly. As I mentioned that 'jcrit arg is pointing it to a namespace that doesn't exist, but what does noir actually want that namespace to be, or to have in it? |
| 14:50 | alive876 | yea, i just looked and the tutorial is 4 years old |
| 14:50 | justin_smith | maybe you could find a newer tutorial, maybe one using bidi or compojure instead of noir |
| 14:56 | princeso | is there a function to map data like this {:a 1 :b 2} into some complex object like {:c :a :d {:e :a :f :b} } to result in {:c 1 :d {:e 1 :f 2}} ? |
| 14:57 | ecmike | tolstoy: just saw your rant, spot on |
| 14:57 | clojurebot | Huh? |
| 14:58 | justin_smith | princeso: what is the relationship between the inputs and outputs there? |
| 14:58 | justin_smith | is it just mapping the vals by your {:a 1 :b 2} ? |
| 14:59 | princeso | justin_smith yes |
| 14:59 | justin_smith | ,(require 'clojure.walk) |
| 14:59 | clojurebot | nil |
| 15:00 | justin_smith | ,(clojure.walk/postwalk (fn [o] (if (map? o) (into {} (map (fn [k v] [k ({:a 0 :b 1} v v)]) o)) o)) {:c :a :d {:e :a :f :b} }) |
| 15:00 | clojurebot | #error {\n :cause "Wrong number of args (1) passed to: sandbox/eval49/fn--50/fn--51"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (1) passed to: sandbox/eval49/fn--50/fn--51"\n :at [clojure.lang.AFn throwArity "AFn.java" 429]}]\n :trace\n [[clojure.lang.AFn throwArity "AFn.java" 429]\n [clojure.lang.AFn invoke "AFn.java" 32]\n [clojure.core$map$fn__4541 invok... |
| 15:00 | justin_smith | oops |
| 15:00 | justin_smith | ,(clojure.walk/postwalk (fn [o] (if (map? o) (into {} (map (fn [[k v]] [k ({:a 0 :b 1} v v)]) o)) o)) {:c :a :d {:e :a :f :b} }) |
| 15:00 | clojurebot | {:c 0, :d {:e 0, :f 1}} |
| 15:01 | justin_smith | ,(clojure.walk/postwalk (fn [o] (if (map? o) (into {} (map (fn [[k v]] [k ({:a 1 :b 2} v v)]) o)) o)) {:c :a :d {:e :a :f :b} }) |
| 15:01 | clojurebot | {:c 1, :d {:e 1, :f 2}} |
| 15:01 | princeso | omg you rock justin_smith! thanks |
| 15:01 | justin_smith | princeso: of course you could name things and make it not a one-liner |
| 15:03 | justin_smith | the main tricks there are using postwalk in order to do nested updates, using into {} in order to map over a hash-map and create a new hash-map, and the usage of the hash-map as a lookup function (with the optional not-found value, so that the nested hash-map stil comes through)) |
| 15:03 | justin_smith | and the key/value destructuring from the map entry tuple |
| 15:04 | ecmike | justin_smith: that's really great... do you have any suggestions for learning clojure that well? I find myself doing a lot of thrashing before getting to anything elegant like that |
| 15:04 | justin_smith | ecmike: hanging out here and trying to read / recreate /improve the one-liners helps :) |
| 15:05 | justin_smith | ecmike: also, there is of course http://conj.io as a reference, and seeing other people's answers on 4clojure |
| 15:05 | ecmike | justin_smith: doing that already, wondering if there were any books/sites/etc you recommend |
| 15:05 | ecmike | justin_smith: oh great, I'll check that out |
| 15:05 | princeso | justin_smith: thanks for that. am almost new to clojure, so ill figure out how it all works. |
| 15:05 | ecmike | bookmark*2 |
| 15:06 | justin_smith | princeso: as I recommended to ecmike above, conj.io helps - as does the community knowledge here in the channel if you try to follow the discussion |
| 16:07 | WorldsEndless | I am segmenting a file into many files based on a regexp; it works if I slurp and use string/split, but this will have problems for large files. How can I make this large-file friendly? |
| 16:09 | WorldsEndless | Is the best way to iterate through the lineseq and check for re-match, and then split and send the splits to the appropriate place? |
| 16:15 | jonathanj | i see people talking about using nrepl in production to embed a repl for investigation etc. purposes |
| 16:15 | jonathanj | how do you prevent any random person from connecting to your repl? |
| 16:15 | justin_smith | WorldsEndless: that seems reasonable, yeah, though you could try variations like reading N bytes followed by cleaning up the odds and ends by combining any left over from the previous (if any) before running the regex |
| 16:16 | justin_smith | jonathanj: by default nrepl only allows connections from localhost (which is a good idea), and then you need to use an ssh tunnel to use it from another host |
| 16:16 | jonathanj | ah |
| 16:17 | jonathanj | any reason not to embed an nrepl in a production server? |
| 16:17 | justin_smith | memory overhead I guess - nrepl is pretty easy to launch from an app |
| 16:18 | celwell | jonathanj: that's a terrifying sentence. what's the reason, just curious. |
| 16:18 | justin_smith | celwell: well we already discussed the fact that it won't be available without a secure connection |
| 16:27 | TimMc | celwell: It is both terrifying and incredibly usful. |
| 16:28 | TimMc | jonathanj: We use liverepl instead. The protection is that you have to be the same user who launched the JVM process in order to inject the agent. |
| 16:28 | TimMc | I once tried to add nrepl to an app using drawbridge but I couldn't get password protection working. |
| 16:29 | justin_smith | TimMc: my take was that realistically every OS has local holes, and the realistic barrier to enforce is logged in / not logged in, and once logged in you can't prevent escalations |
| 16:30 | justin_smith | (though I guess they don't always have to be as easy as they are via nrepl) |
| 16:31 | TimMc | Yeah, but there's always a *chance* your kernel is up to date. ;-) |
| 16:31 | TimMc | Heck, if you're inside the datacenter at most shops you're probably as good as in. |
| 16:31 | justin_smith | TimMc: kernel, plus userland - there are local exploits via games, random file conversion utilities, libraries... |
| 16:50 | TimMc | jonathanj: One downside of liverepl is that it doesn't give you all the nice nrepl features, you just get a raw repl with no line-editing. |
| 16:50 | TimMc | liverepl can load additional jars, so that might be a path through if that's a problem for you |
| 17:06 | jonathanj__ | TimMc, justin_smith: Thanks for the discussion, I'll do some reading. |
| 17:13 | glosoli | Hey what's the name of the some tool that could scan through the project and point out the stuff that is being done unconventionally ? |
| 17:13 | celwell | kibit |
| 17:13 | justin_smith | eastwood is good for this too |
| 17:15 | glosoli | thanks |
| 18:22 | irctc | Hi everyone! :) |
| 18:23 | WorldsEndless | Hi, irctc |
| 18:23 | irctc | I need help with a concept in functional programming paradigm. I have a function that connects to an API and returns an xml file. Then I need to parse that file, extract info from the parsed result, do some calculations etc, etc. Now I want to make my code functionally as pure as possible. |
| 18:24 | irctc | As things stand now I have a sequential stack of calls that goes all the way back to the connection that relys on each function passing through a user ID with wich to connect to the api in the connection function. |
| 18:24 | irctc | How do I change this to be more functionally pure? |
| 18:24 | irctc | Hi WorldsEndless. :) |
| 18:25 | irctc | I am thinking that a more functionally pure way would be to just call this connection function once and then save the returned xml in a global (def) and then pass that def arround to other pure functions. |
| 18:26 | irctc | Am I right in approaching this problem that way or is there another way that it should be done? |
| 18:26 | WorldsEndless | Interesting. I recently watched Stuart Sierra's talk on functional design patterns that might be of interest to you: https://www.youtube.com/watch?v=etr08mExAI0 |
| 18:27 | WorldsEndless | irctc: Using React-based web libraries, the global atom idea is pretty standard |
| 18:28 | irctc | What does that mean. Sorry I'm new to functional programming. |
| 18:28 | WorldsEndless | irctc: Although I recently had to redo one of my codebases to pass the value around rather than look it up globally, which brought a lot of benefits |
| 18:28 | tolstoy | irctc I think the idea is to do all your side-effects at the front (or end), so don't bury the web request in the middle of calculations. |
| 18:29 | WorldsEndless | So, Facebook's "React" framework is a popular javascript engine that has proven very powerful in the hands of Clojurians. The clojurescript approaches, like Om or Reagent, rely heavily on that idea of a global Atom |
| 18:29 | tolstoy | irctc: Just make the request, then pass the result to pure transforms, then save (or whatever) the result. |
| 18:29 | WorldsEndless | Agree with tolstoy |
| 18:29 | irctc | tolstoy, my web request goes all the way through my entire algorithm. This makes it very hard to do unit testing as well. |
| 18:30 | WorldsEndless | irctc: Just make the request once, as you were thinking, and pass the needed parts around to what needs them |
| 18:30 | tolstoy | irctc: Actually making the request is buried in there somewhere? |
| 18:30 | justin_smith | if you put it in a def, then you are stuck with only being able to handle one xml file, with pure handlers and no global you can process as many as your computer can handle |
| 18:30 | irctc | So, the request should be made up front and then saved in a def? |
| 18:30 | WorldsEndless | irctc: you may not need to save it in a def at all |
| 18:30 | irctc | Ok, so how do I go about that aproach? |
| 18:31 | justin_smith | irctc: how many different xml files would you ever handle? if it's exactly one for the entire lifetime of the app a def may be OK, if you would ever need a second xml file, definitely don't use a def |
| 18:31 | tolstoy | irctc: Using a "def" is just an implemenation detail. You could: (let [xml (make-request...)] (save-to-db (transform xml))). No global. |
| 18:31 | irctc | >=1 |
| 18:31 | irctc | Nah, I don't use a db here. |
| 18:31 | justin_smith | yeah, if 2 would ever happen, a def would just make things more complicated |
| 18:32 | irctc | I agree justin_smith. You have a point there. |
| 18:32 | tolstoy | irctc: Again, it's just to illustrate that the network retrieval and saving are at the top level, not in the `transform` bit. |
| 18:32 | WorldsEndless | So, guys, I'm a bit tangled up on an idea. Spliting one file to many using readers and writers, I open with "with-open [reader ..]" but am not sure how to alternate writing to a current file with writing to a new file when I match my break-regex. |
| 18:33 | irctc | So when I do (connection userid) where userid is some number like 123, I get my xml file back. How do I then pass it to pure functions without calling (connection userid) function from other functions? |
| 18:33 | justin_smith | The functional concept is that a function given the same args should return the same result. So focus on breaking the task up to stages that are 100% dependent on their arguments. |
| 18:34 | justin_smith | irctc: by calling those functions |
| 18:34 | tolstoy | irctc: (let [xml (connection userid)] (transform xml)) |
| 18:34 | justin_smith | WorldsEndless: with loop or reduce you can have a binding that is passed for each item, and when you see that a new output file is needed you pass that along as the new binding |
| 18:35 | WorldsEndless | Wait... you can do that with reduce? |
| 18:35 | irctc | Ok, the way I have it set up now is I make (top-function-call userid) --calls--> (mid-function-call userid) --calls--> (bottom-function-call userid) --calls--> (connection userid). |
| 18:35 | justin_smith | WorldsEndless: something like (reduce (fn [[out-file acc] el] ... [new-out-file new-acc) lines) |
| 18:35 | tolstoy | WorldsEndless: Hm. You could use a multimethod? read-line, charaterize it, then pass it to a multimethod, even method of which knows which file to append it to? |
| 18:36 | justin_smith | WorldsEndless: the idea being on a given line you know whether to make a new file or not, and that's the file you pass to the processing of the next line |
| 18:36 | tolstoy | irctc: Right. I'd reverse that, if you can. Then pass the XML through your other functions as needed. |
| 18:36 | irctc | tolstoy, you mean I should do a let [xml (connection userid)] at the top-level-function and then just pass the local xml binding to other calls within the top-level-function? |
| 18:37 | tolstoy | irctc: Yes. |
| 18:38 | irctc | tolstoy, I think that makes sense. :) Thank you. |
| 18:38 | tolstoy | irctc: At least one benefit of that is that when you read each function, the only thing that function can see are the params. |
| 18:38 | irctc | Thank you everyone for your help. I'm gona try it this way. |
| 18:38 | WorldsEndless | irctc: good luck |
| 18:39 | irctc | Well the main benefit for me will be that I'll be able to do unit testing. Right now I would have to rely on an external api call and that's a real mess if you have large xml files. |
| 18:39 | irctc | Plus debugging is much easier with pure functions. |
| 18:40 | tolstoy | irctc: Yes! |
| 18:40 | irctc | I think imperative languages have broken me from the start. lol |
| 18:41 | justin_smith | irctc: pure functions are just imperative functions that are only allowed to use data that is in the arg list and can only change things that they return |
| 18:41 | justin_smith | you end up returning collections more often, for this reason |
| 18:48 | irctc | justin_smith: I feel that because of the lessons I learned while using clojure this made me a better imperative programmer. The notion of pure functions is just not enforced that much from the get go in imperative paradigm. I actually wish I was taught a functional language first before imperative languages. |
| 18:49 | justin_smith | irctc: only using arg lists and returning data instead of modifying it are good default behaviors for sure |
| 19:45 | domgetter | So I'm trying to take advantage of the JVM doing optimizations, and I'm using dotimes to see timing from multiple runs of a function. Within a dotimes call, I can see it taking less and less time, but a second call to dotimes starts everything over. Is there a way to keep what "work" the JVM did? https://gist.github.com/domgetter/8c0f66b58cbeca135731 |
| 19:46 | domgetter | As you can see on lines 69, 196, and 1310, the times drop. |
| 19:47 | domgetter | When I call dotimes a second time, is it starting over because I'm in a repl? |
| 19:48 | domgetter | Or (depending on the optimization of course) can I expect an optimization to stick around in production? |
| 20:02 | BRODUS | say i have a complicated expression, and I want to check if the result is either nil? or seq?, how I could I write that while only writing the expression once |
| 20:03 | BRODUS | rather than writing it twice in the or expression |
| 20:04 | lambda-11235 | (let [val ...] (or (nil? val) (seq? val)) |
| 20:42 | codahale | domgetter: If you’re trying to benchmark something, I’d suggest using Criterium. The JVM makes naive benchmarking effectively impossible. |
| 21:36 | jghasjhjkasd | hi can someone tell me why this doesn't work? (map #(1) [1, 2, 3]) |
| 21:36 | jghasjhjkasd | just trying to turn the list in to a list of 1's |
| 21:36 | justin_smith | ,'#(1) |
| 21:36 | clojurebot | (fn* [] (1)) |
| 21:37 | justin_smith | that tries to call 1 as a function |
| 21:37 | jghasjhjkasd | ohh right ok |
| 21:37 | justin_smith | ,(map (constantly 1) [1, 2, 3]) |
| 21:37 | clojurebot | (1 1 1) |
| 21:37 | justin_smith | ,(map (fn [_] 1) [1, 2, 3]) |
| 21:37 | clojurebot | (1 1 1) |
| 21:38 | justin_smith | my two minor peeves about clojure is that identity is longer than (fn [x] x) and constantly is longer than (fn [& _] x) |
| 21:41 | lambda-11235 | justin_smith: Indeed, I find myself defining id and const in the REPL when I need them. |
| 21:42 | lambda-11235 | identity is still two characters shorter than (fn [x] x). |
| 21:44 | justin_smith | lambda-11235: oh right, (fn[x]x) isn't nearly as nice |
| 21:47 | jghasjhjkasd | hey justin_smith |
| 21:48 | justin_smith | yes? |
| 21:48 | jghasjhjkasd | is there any way to do that map thing with the shorthand syntax? |
| 21:48 | jghasjhjkasd | (map (fn [_] 1) [1, 2, 3]) |
| 21:48 | jghasjhjkasd | with # |
| 21:48 | justin_smith | the closest you can get is #(do % 1) |
| 21:48 | justin_smith | because otherwise it will complain about the arg count |
| 21:48 | justin_smith | and #(do % 1) is terrible |
| 21:49 | jghasjhjkasd | i dont get it.. why do you have to use all the arguments? |
| 21:49 | justin_smith | jghasjhjkasd: because if you don't use any args, the compiler generates a function that takes no args |
| 21:49 | justin_smith | and you get an error because you get an arg |
| 21:49 | BRODUS | is there a function that returns the maps a predicate to a collection and returns the first value that satisfies the predicate? |
| 21:49 | jghasjhjkasd | oh ok |
| 21:49 | jghasjhjkasd | thx |
| 21:50 | BRODUS | *is there a function that maps a predicate to a collection and returns the first value that satisfies the predicate? |
| 21:50 | justin_smith | BRODUS: (comp first filter) |
| 21:50 | justin_smith | ,((comp first filter) even? [1 3 6 42]) |
| 21:50 | clojurebot | 6 |
| 21:50 | BRODUS | that makes sense |
| 21:54 | BRODUS | and because filter returns a lazy sequence that means it will not map over the whole collection |
| 21:57 | justin_smith | right |
| 21:58 | justin_smith | but I still find it surprising there isn't a function for "first item matching the predicate" built in |
| 22:14 | amalloy | that obvious missing function is rich's subtle way of encouraging everyone to run their own fork of clojure with noe added function |
| 23:33 | tolstoy | BRODUS "some" kinda does that. (some #(when (pred? %) %) coll). |
| 23:33 | BRODUS | right but that just returns a boolean |
| 23:34 | tolstoy | The way I wrote it there, it returns the value. |
| 23:34 | BRODUS | oh i see |
| 23:34 | tolstoy | ,(some #(when (even %) %) [1 3 5 6 8 1 2 4]) |
| 23:34 | clojurebot | #error {\n :cause "Unable to resolve symbol: even in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: even in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: even in this co... |
| 23:34 | tolstoy | ,(some #(when (even? %) %) [1 3 5 6 8 1 2 4]) |
| 23:34 | clojurebot | 6 |
| 23:37 | BRODUS | good to know, i need to use 'when' more |
| 23:37 | tolstoy | Part of the when, when-not, when-let family. |
| 23:50 | jghasjhjkasd | how do you remember when the list/collection is the first or last parameter of clojure functions? just memorization or is there logic behind it? |
| 23:51 | jghasjhjkasd | like cons is list last, conj is list first, nth is list first, reduce is list last, etc. |
| 23:52 | tolstoy | My guess: if it's operating over a range of values, it's at the end (map, reduce, etc). |
| 23:52 | tolstoy | But if you're just changing one thing about the collection, it's first (conj, assoc). |
| 23:54 | amalloy | jghasjhjkasd: mostly things that operate on sequences take them last, where things that operate on any kind of collection take it first |
| 23:54 | amalloy | also how do you remember your username |
| 23:54 | jghasjhjkasd | i just typed in a bunch of gibberish it's not my username i'm using irc web client |