2014-07-02
| 00:18 | nex | Im trying to infer the type of a form using clojure.tools.analyzer.jvm, with (ana.jvm/analyze '(str 1 2)) i can get the :tag which tells its a string. with '(+ 1) or '(map identity []) I just get java.lang.Object, I think because those fns can return different types, depending on the args. Is there a way to accomplish what I want? so far i thought to keep sets of fns which return certain "types" such as :number or :vector and compare the first element of the f |
| 00:18 | nex | orm to those sets |
| 00:20 | ambrosebs | nex: tools.analyzer only collects enough information to inform the emitter of reflection stuff. |
| 00:21 | ambrosebs | nex: your idea of annotating a set of known return types is a good one. |
| 00:23 | nex | ambrosebs: i wouldnt mind the effort, but it would be a lot better to be able to do this on arbitrary fns. |
| 00:24 | ambrosebs | nex: you'd need to write a type inferencer then, probably based on success typing like dialyzer |
| 00:25 | ambrosebs | so, not trivial |
| 00:25 | ambrosebs | you could kinda use core.typed, but gradual typing is much more annoying to do arbitrary analysis with. |
| 00:25 | ambrosebs | success typing is forgiving. |
| 00:28 | ambrosebs | also it depends what you're actually using this for? |
| 00:28 | nex | ambrosebs: i heard from a friend that in haskell you could use this kind of procedure to help with debugging, cause you can infer the outputs class and compare with the possible input types of fathers forms |
| 00:29 | ambrosebs | sure, but we don't know how to do type checking on arbitrary clojure code yet. |
| 00:29 | ambrosebs | core.typed is the best bet so far. |
| 00:29 | ambrosebs | that's best described as a subset of clojure |
| 00:30 | fitzoh | Anyone thoughts on how to write this function? Trying to do some atom manipulation (f :key2 :val {:root [{:a 1}{:a 2}] } -> {:root [{:a 1 :key2 :val}{:a 2 :key2 :val}]} |
| 00:31 | nex | ambrosebs: im working on fractal.ai, think of it as googles text input but you write a clojure expression, additionaly im trying to do something like fractal.ai/some-fn where the webui could generate form fields according to the types of the input, for example if the fn recieved a date object, the ui would generate a date form field |
| 00:33 | nex | ambrosebs: could you point me out in a direction, with typed clojure? cause ive looked into it but not deeply at all. i will also work a little on the naive approach of tagging fns manually, but id like to start brewing something more profound |
| 00:34 | icma | anyone know why I can't require clojure.contrib.trace? https://gist.github.com/anonymous/38f34eddc3fc0430aa59 |
| 00:35 | puredanger | clojure.contrib.trace is part of the old "monolithic contrib" used prior to Clojure 1.3 |
| 00:36 | puredanger | http://dev.clojure.org/display/community/Where+Did+Clojure.Contrib+Go |
| 00:36 | puredanger | the trace stuff is now in https://github.com/clojure/tools.trace/ which is a library you will need to include in your project |
| 00:37 | icma | puredanger: excellent. thanks. |
| 00:38 | ambrosebs | nex: you can pass forms to check-form-info to type check them http://clojure.github.io/core.typed/#clojure.core.typed/check-form-info |
| 00:39 | rufoa | fitzoh: (defn f [k v m] (update-in m [:root] (fn [ms] (map #(assoc % k v) ms)))) |
| 00:39 | ambrosebs | icma: where did you hear about contrib.trace btw? |
| 00:40 | fitzoh | rufoa: awesome, ty |
| 00:40 | rufoa | np |
| 00:41 | icma | ambrosebs: not sure anymore. lost the page. I was just searching for "clojure deftrace" and "deftrace". |
| 00:42 | ambrosebs | icma: ok |
| 00:44 | mange | zanes: I'm looking at that backoff stuff again, because I wanted to write a version using ribol, and I'm not sure yours works how I would expect it to. It seems to be truncating the sequence on an exception, rather than delaying and retrying? |
| 01:14 | amalloy | very impressive, bbloom |
| 01:26 | yedi | what are some things you must know if you;re going to interview for clojure position |
| 01:34 | TEttinger | yedi: what does this type hint mean: ^"[[Z" |
| 01:34 | yedi | O_O |
| 01:34 | TEttinger | hehe |
| 01:35 | TEttinger | it's a 2d boolean array |
| 01:35 | puredanger | array of array of boolean |
| 01:35 | TEttinger | you won't need to know that unless you work at prismatic... |
| 01:35 | puredanger | [ = array, Z = boolean |
| 01:37 | TEttinger | yedi, how would you "partly flatten" a nested vector; where flatten removes all nesting, here you want to remove the outermost layer of nesting and only flatten that. |
| 01:39 | TEttinger | (___ __ _ [[1 2][3 4][[5][6]]]) |
| 01:39 | TEttinger | fill in some blanks |
| 01:40 | TEttinger | it should return [1 2 3 4 [5] [6]] |
| 01:42 | razum2um | when i start a new clj new should i prefer dashed-name or underscore_name ? |
| 01:42 | razum2um | i mean lib name |
| 01:43 | razum2um | ah, I see only dashes here http://crossclj.info/ |
| 01:45 | yedi | TEttinger: I feel like I can do it iteratively but filling in those blanks is a different story |
| 01:45 | yedi | oh wait |
| 01:45 | yedi | reduce into [] |
| 01:45 | TEttinger | yep! |
| 01:45 | TEttinger | nice |
| 01:45 | TEttinger | that's a good trick |
| 01:46 | amalloy | well, apply concat is more typical than reduce into [] there |
| 01:46 | TEttinger | well true |
| 01:46 | amalloy | depends what data type you want back |
| 01:46 | TEttinger | I mostly used it for maps |
| 01:46 | TEttinger | so I never really got used to apply concat |
| 01:47 | ivan | https://www.refheap.com/9d8f8ea4d4d4f8bdbed6c817c/raw nrepl woes |
| 01:48 | TEttinger | ivan, it is failing to eval /1, then it evals 2 on the next line |
| 01:48 | ivan | (I'm fixing a few things in REPL-y's standalone REPL and looking a lot at what nREPL and clojure.main do) |
| 01:48 | TEttinger | so it isn't returning 24, it's 2 then 4 and the real value is 4 |
| 01:49 | ivan | yeah, I know that much :) |
| 01:49 | TEttinger | maybe just stick a newline after that stuff |
| 02:18 | akurilin | Random question: in ring apps, do you guys generally tend to wrap your korma calls and perhaps store them all in a model namespace, say if you want to call them from a handler/controller? Or do you just directly invoke korma from the controller? |
| 02:52 | ttasterisco | akurilin: I structure my projects roughly following Amit's DDD http://www.infoq.com/presentations/DDD-Clojure |
| 03:00 | akurilin | ttasterisco: I'll check that video out, seems relevant :) |
| 03:03 | clgv | ttasterisco: is that only a "conceptual" talk. the slides seemed very spartanic when browsing through |
| 03:03 | clgv | ? |
| 03:06 | ttasterisco | clgv: it's mostly conceptual but he goes into the practicalities close to the end |
| 03:07 | ttasterisco | I felt that his presentation at the SF Clojure meetup last year was more direct |
| 03:12 | magopian | ,(Character/isWhitespace "a") |
| 03:12 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: No matching method found: isWhitespace> |
| 03:12 | amalloy | magopian: \a |
| 03:12 | magopian | ? |
| 03:13 | ttasterisco | character |
| 03:13 | ttasterisco | not string |
| 03:13 | magopian | ohhh |
| 03:13 | magopian | it's my python background ;) (no difference between a char and a one-char string ;) |
| 03:13 | magopian | thanks |
| 03:16 | magopian | ,(every? :nothing nil) |
| 03:16 | clojurebot | true |
| 03:16 | magopian | ,(every? :nothing "") |
| 03:16 | clojurebot | true |
| 03:17 | magopian | (getting through the "programming clojure" book, and I first thought the very first example comparing java to clojure was unfair because the java version was also working for null/empty string) |
| 03:17 | magopian | (but seems that "every?" returns true for those cases, so it works the same... weird though, that every? returns true for nil/empty) |
| 03:17 | magopian | ,(some? :nothing "") |
| 03:17 | clojurebot | #<ArityException clojure.lang.ArityException: Wrong number of args (2) passed to: core/some?> |
| 03:18 | magopian | ,(some? :nothing nil) |
| 03:18 | clojurebot | #<ArityException clojure.lang.ArityException: Wrong number of args (2) passed to: core/some?> |
| 03:18 | magopian | ,(not-any? :nothing nil) |
| 03:18 | clojurebot | true |
| 03:19 | amalloy | magopian: every object in the empty collection is equal to five, and equal to six, and... |
| 03:19 | amalloy | feel free to find a counterexample |
| 03:21 | clgv | mange: yeah thats the mathematical definition of the all quantifier |
| 03:22 | clgv | magopian: ^^ |
| 03:22 | magopian | yup ;) |
| 03:22 | clgv | the exist quantifier alas `some` returns nil meaning false ;) |
| 03:23 | clgv | for empty collections |
| 03:27 | magopian | clgv: that's what i'm looking at atm ;) |
| 03:36 | magopian | are the books on it-ebooks really free... or pirated? |
| 03:37 | magopian | because i can see a lot of cloure books on there, downloadable for free |
| 03:37 | magopian | clojure* |
| 03:41 | ambrosebs | magopian: what's on there? |
| 03:43 | magopian | ambrosebs: http://it-ebooks.info/tag/clojure/ |
| 03:43 | ambrosebs | I don't particularly want to click |
| 03:45 | magopian | ambrosebs: i'm sorry, i don't understand your question |
| 03:45 | magopian | there's a list of most (all?) of the clojure books I heard of |
| 03:45 | magopian | freely downloadable |
| 03:45 | magopian | but... dunno, the site doesn't look legit, so i'm wondering if those are "stolen" |
| 03:46 | magopian | i've seen at least some of those ebooks sold in various places, so having them freely downloadable here feels strange |
| 03:48 | ambrosebs | right, must be pirated. |
| 03:50 | magopian | ambrosebs: ah, thanks |
| 03:51 | magopian | i'll buy/download the ebooks from the publisher's sites |
| 03:52 | magopian | ambrosebs: which book would you recommend ? |
| 03:53 | ambrosebs | magopian: I like Clojure Programming or Joy of Clojure |
| 03:54 | magopian | thanks again |
| 03:57 | clgv | magopian: yeah those are not legally available without payment |
| 03:58 | clgv | magopian: the decision between "Clojure Programming" and "Programming Clojure (2nd edition)" depends on what style of book you like |
| 04:01 | magopian | clgv: ah... can you tell me a bit more? |
| 04:04 | clgv | magopian: hard to describe but I try like that: In my opinion "Clojure Programming" is more narrative whereas "Programming Clojure" is more technical. a student (computer science) of mine preferred "Programming Clojure" since it got him started faster with less ceremony |
| 04:05 | magopian | i see |
| 04:05 | clgv | so in fact reading both probably has a complementary effect. I'd read the available sample chapters to decide which style I like most |
| 04:39 | magopian | clgv: that's what i'm doing right now ;) |
| 04:58 | magopian | clgv: i went with programming clojure, bought on pragprog, thanks for the advices! |
| 04:59 | clgv | magopian: glad to help :) |
| 05:53 | sveri | Hi, did anyone here do authentication with websockets or sente and http-kit? Are there any best practices or examples available? |
| 05:55 | ergh | does clojure have a neat way to say "give me a vector of this value n times"? |
| 05:58 | ergh | oh, "(take 10 (repeat 1)" works. i knew there was something :p |
| 05:58 | Bronsa | .(repeat 10 1) |
| 05:59 | Bronsa | ,(repeat 10 1) |
| 05:59 | clojurebot | (1 1 1 1 1 ...) |
| 06:01 | ergh | Bronsa: oh that's better, thanks |
| 07:25 | rurumate | is there an easy way to call a private method of a java object? |
| 07:25 | stain_ | I believe you may have to introspect and make the method public |
| 07:26 | rurumate | there used to be method-call in contrib.reflect or something but I can't find it in clojure.refect |
| 07:29 | clgv | hmm the seesaw :popup property seems broken. at least the examples from the code base wont work ... :( |
| 07:39 | clgv | damn, the copied example works. but not the analogue one in the codebase... |
| 07:49 | perplexa | hai |
| 07:53 | perplexa | what's considered the best practice to handle configurations in clojure? |
| 07:55 | cmdrdats1 | perplexa: 'best practise' is pretty subjective - but I would recommend http://12factor.net/config - regardless of language |
| 07:56 | perplexa | yeah but that's really meta :P |
| 07:56 | cmdrdats1 | not really - just use environment variables |
| 07:56 | perplexa | i won't. |
| 07:56 | perplexa | nobody wants a complete config in environment vars |
| 07:57 | cmdrdats1 | ok - hence subjective :) |
| 07:57 | perplexa | that works when you want to override single parameters |
| 07:57 | perplexa | but having like 50 params completely in the environment violates the whole point of having a config |
| 07:58 | perplexa | i'm just not sure whether i should go for yaml or propertiy files |
| 07:58 | cmdrdats1 | environments can be entirely localised to process though? |
| 07:58 | perplexa | and how to properly access the params from within clojure |
| 07:58 | Janiczek | perplexa: EDN instead of yaml maybe? |
| 08:00 | perplexa | that looks good :) |
| 08:01 | razum2um1 | perplexa: look at https://github.com/weavejester/environ it uses EDN-like .lein-env file as config |
| 08:01 | razum2um1 | but also accepts ENV |
| 08:05 | sveri | Hi, did anyone here do authentication with websockets or sente and http-kit? Are there any best practices or examples available? |
| 08:06 | perplexa | razum2um1: thx |
| 08:51 | perplexa | hm. i have my config stored in my main namespace with (def config nil), and in my main method i run (intern *ns* 'config (props/load-props property-file)), this seems to work fine on the repl but when i run the jar, it's always nil when the config var is accessed from within other functions. |
| 08:52 | perplexa | any ideas why that is, or how i would properly do what i'm trying to do? |
| 08:58 | justin_smith | perplexa: how are you accessing the property-file? as a resource or as a file? |
| 08:58 | justin_smith | in a jar, you should probably use clojure.java.io/resource |
| 08:59 | jcromartie | perplexa: why don't you use alter-var-root ? |
| 08:59 | justin_smith | or, at least, (def config) rather than (def config nil) |
| 09:00 | perplexa | java.io.reader ;p |
| 09:00 | justin_smith | perplexa: a reader of what though? |
| 09:00 | perplexa | jcromartie: cos i have no idea what you are telling me :D |
| 09:00 | justin_smith | a resource or a file or a URI? |
| 09:00 | perplexa | need to check |
| 09:00 | jcromartie | perplexa: BTW *ns* is bound to the namespace of the caller |
| 09:00 | jcromartie | ,(do (ns foo) (defn bar [] (println *ns*))) |
| 09:00 | clojurebot | #'foo/bar |
| 09:01 | perplexa | justin_smith: a file. that stuff works. it's just about accessing the result form everywhere without requiring the filename in all of these places |
| 09:01 | jcromartie | ,(ns user) |
| 09:01 | clojurebot | nil |
| 09:01 | jcromartie | ,(foo/bar) |
| 09:01 | clojurebot | #<Namespace sandbox>\n |
| 09:01 | perplexa | jcromartie: yeah i expected that. so when i run the jar, it might just intern the var in the wrong place |
| 09:01 | justin_smith | perplexa: oh, so you are running the uberjar in a place where that file is guaranteed to exist? |
| 09:01 | perplexa | justin_smith: yep |
| 09:01 | perplexa | reading works, just overwriting my config def doesn't |
| 09:02 | justin_smith | OK, yeah, then it is likely some AOT binding of the var value |
| 09:02 | jcromartie | perplexa: instead, do this: (alter-var-root #'my.main.ns/config (constantly (load-config …))) |
| 09:02 | justin_smith | yeah, this is what alter-var-root is for |
| 09:02 | perplexa | jcromartie: thanks! |
| 09:02 | perplexa | (inc jcromartie) |
| 09:02 | lazybot | ⇒ 7 |
| 09:02 | jcromartie | I'm currently grappling with config woes |
| 09:03 | jcromartie | we used to load it all from a file |
| 09:03 | jcromartie | but then devops said we couldn't upload config files willy-nilly |
| 09:03 | jcromartie | so now we read it all in from env vars |
| 09:03 | perplexa | eeww :x |
| 09:03 | jcromartie | well it makes sense |
| 09:04 | perplexa | one more thing |
| 09:04 | justin_smith | jcromartie: I find having some abstraction for binding config that both files or other config loading methods use in common is helpful |
| 09:04 | perplexa | why (constantly)? |
| 09:04 | justin_smith | this also makes testing easier |
| 09:04 | jcromartie | yeah |
| 09:04 | justin_smith | perplexa: because alter-var-root acts on the previous value |
| 09:04 | jcromartie | we're using environ |
| 09:04 | perplexa | justin_smith: wat |
| 09:04 | jcromartie | and I have a config namespace and a defconfig macro that enables a config check |
| 09:04 | jcromartie | so in the config namespace we use (defconfig api-url :parser parse-url) etc. |
| 09:05 | justin_smith | ,(do (def x "hello") (alter-var-root x #(str % " world!")) x) |
| 09:05 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.Var> |
| 09:05 | jcromartie | and then we can run (check-config) to assert that there are no missing config values |
| 09:05 | justin_smith | err |
| 09:05 | justin_smith | ,(do (def x "hello") (alter-var-root #'x #(str % " world!")) x) |
| 09:05 | clojurebot | "hello world!" |
| 09:05 | justin_smith | perplexa: that^ |
| 09:06 | jcromartie | and (defconfig foo) looks for config named "foo" in several places, either a :foo key in a config map or a FOO environment variable, as per environ |
| 09:07 | perplexa | justin_smith: i still don't get it :) |
| 09:07 | perplexa | ,(do (def x "hello") (alter-var-root #'x "replaced ;p") x) |
| 09:07 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn> |
| 09:07 | jcromartie | perplexa: alter-var-root takes a var (which are containers for values created by def/defn etc.) and a function which takes the var's current value and returns the new value that it should take |
| 09:08 | perplexa | ah |
| 09:08 | jcromartie | ,(def x) |
| 09:08 | clojurebot | #'sandbox/x |
| 09:08 | perplexa | the function part was the missing puzzle piece :) |
| 09:08 | jcromartie | ,x |
| 09:08 | clojurebot | "hello" |
| 09:08 | perplexa | thx |
| 09:08 | jcromartie | k |
| 09:08 | jcromartie | ,#'x |
| 09:08 | clojurebot | #'sandbox/x |
| 09:08 | jcromartie | ,(var x) |
| 09:09 | clojurebot | #'sandbox/x |
| 09:09 | jcromartie | ,(deref (var x)) |
| 09:09 | clojurebot | "hello" |
| 09:09 | jcromartie | ,(deref (var sandbox/x)) |
| 09:09 | clojurebot | "hello" |
| 09:09 | clgv | ,(-> "x" symbol resolve deref) |
| 09:09 | clojurebot | "hello" |
| 09:12 | perplexa | jcromartie: we're just migrating our aggregations from old perl+sql shizzle to cascalog ;x |
| 09:12 | jcromartie | awesome |
| 09:13 | perplexa | and i'm trying to build a rather flexible bootstrapping framework around that, so have it integrate easily with our other etl processes ;x |
| 09:14 | jcromartie | If I may suggest having: config values actually defined as vars in a namespace is really useful |
| 09:14 | jcromartie | err, that |
| 09:14 | jcromartie | that colon was supposed to go after "suggest" |
| 09:15 | perplexa | i seem to miss the point |
| 09:15 | jcromartie | but anyway, it's better to get a load-time "unable to resolve symbol" error than to have a mysterious nil at runtime |
| 09:21 | Glenjawork | i tend to have an (env!) function, which throws when the key doesn't exist |
| 09:22 | Glenjawork | and tells me what environment variable it wanted |
| 09:36 | perplexa | i hate it when code runs in the repl but not as jar :| |
| 10:05 | clgv | perplexa: that's a clear sign that you did something wrong ;) |
| 10:05 | perplexa | Exception in thread "main" java.lang.RuntimeException: Invalid token: /user/camus/output |
| 10:05 | perplexa | :| |
| 10:05 | perplexa | yeah clgv :P |
| 10:06 | clgv | well probably not a string? |
| 10:06 | perplexa | well |
| 10:06 | perplexa | (defn mk-src [in-path schema-path fields] |
| 10:06 | perplexa | (println "fufufu" (str (:aggregations.input.base (cached-props))))) |
| 10:06 | perplexa | should be a str ;p |
| 10:06 | perplexa | and works fine in repl |
| 10:07 | clgv | no the error messages sounds as if you inserted the path literally and not as a string |
| 10:07 | perplexa | the path is (:aggregations.input.base (cached-props)) |
| 10:07 | perplexa | and it's a symbol |
| 10:07 | perplexa | but (str ...) works locally at least ;/ |
| 10:11 | augustl | perplexa: (cached-props) - that's not an argument to that function? :) |
| 10:12 | augustl | perplexa: do you get the error on the call to str, or the call to println, or something else? |
| 10:13 | augustl | seems like that error would probably come from whatever (cached-props) is doing, can't imagine a (:my-key thing) causes an error with /user/camus/output in it :) |
| 10:13 | augustl | g2g |
| 10:14 | clgv | as I said I get the error when I just enter that path into the REPL => RuntimeException Invalid token: /user/camus/output |
| 10:14 | perplexa | augustl: yeah it's the argument |
| 10:14 | clgv | so that path is actually read somewhere by clojures read where it probably should be specified as string |
| 10:14 | clgv | perplexa: ^^ |
| 10:15 | clgv | ,/user/camus/output |
| 10:15 | clojurebot | #<RuntimeException java.lang.RuntimeException: Invalid token: /user/camus/output> |
| 10:15 | clgv | ,"/user/camus/output" |
| 10:15 | clojurebot | "/user/camus/output" |
| 10:15 | clgv | ^^ |
| 10:15 | perplexa | i know. |
| 10:16 | clgv | well then fix it by making it a string or deleting the occurence ;) |
| 10:17 | perplexa | it's not that easy |
| 10:17 | perplexa | i'm always converting it to a string |
| 10:17 | perplexa | when passing it to other calls |
| 10:17 | perplexa | i just don't get why it works in repl but not when i run the jar |
| 10:18 | clgv | ,(type (read-string "/user/camus/output")) |
| 10:18 | clojurebot | #<RuntimeException java.lang.RuntimeException: Invalid token: /user/camus/output> |
| 10:19 | clgv | ,(type (read-string "/user")) |
| 10:19 | clojurebot | #<RuntimeException java.lang.RuntimeException: Invalid token: /user> |
| 10:19 | clgv | ,(type (read-string "user")) |
| 10:19 | clojurebot | clojure.lang.Symbol |
| 10:20 | clgv | ah right it is not even a legal symbol, so in this phase the reader fails |
| 10:20 | perplexa | wtf |
| 10:20 | perplexa | yeah locally i use a different config.. which does start with hdfs:// |
| 10:21 | clgv | you should put up a minimal gist to show what you are doing. although I think you just need to specify any paths as strings and thats it |
| 10:21 | perplexa | ,(type (read-string "hdfs:///user/camus/output")) |
| 10:21 | clojurebot | clojure.lang.Symbol |
| 10:21 | perplexa | :| |
| 10:21 | clgv | there is no meaningful reason why that should be specified as symbol |
| 10:23 | perplexa | clgv: hm yeah. i'm a complete newb and i just use the function from the reply there: http://stackoverflow.com/questions/7777882/loading-configuration-file-in-clojure-as-data-structure |
| 10:25 | puredanger | cglv: looks like a symbol to the reader :) |
| 10:25 | ndp | perplexa: Could it be that you're missing quotes in the string itself? ex: (read-string "\"foo\"") |
| 10:25 | ndp | ,(type (read-string "\"foo\"")) |
| 10:25 | clojurebot | java.lang.String |
| 10:25 | clgv | puredanger: what do you mean? (I was just investigating whether the read fails on trying to read it as symbol) |
| 10:26 | perplexa | ndp: see the link that i just pasted :) |
| 10:26 | perplexa | i should probably just switch to edn and have proper values |
| 10:26 | clgv | perplexa: if that really happens on Properties/load you should see it in the stacktrace |
| 10:27 | perplexa | clgv: yes it does |
| 10:27 | perplexa | at properties$load_props.invoke(properties.clj:8) |
| 10:27 | clgv | perplexa: ah no I spotted the read-string in the code |
| 10:27 | clgv | just surround the path in the conifg with "" |
| 10:27 | clgv | as I told you all the time :P |
| 10:28 | perplexa | yeah but it shouldn't be like that :| |
| 10:28 | ndp | I notice that in the config file from that link you read a property which is a list of strings but no properties which are just strings |
| 10:28 | ndp | So, let's try this: |
| 10:28 | perplexa | like, that's not really how a property file should work :) |
| 10:28 | clgv | perplexa: well then don't use read-string there |
| 10:28 | ndp | ,(type (read-string "[\"foo\", \"bar\"]")) |
| 10:28 | clojurebot | clojure.lang.PersistentVector |
| 10:29 | clgv | perplexa: perplexa: do you really want to specify clojure data structures in the property file? |
| 10:29 | perplexa | clgv: nope, but scalars, like doubles, strings, ints. that would be good. |
| 10:29 | clgv | perplexa: that would not be really how a property file should work as well ;) |
| 10:29 | perplexa | i'm just gonna drop the entire approach and use edn as suggested earlier, now that i know there's a definitive problem with the current solution |
| 10:30 | clgv | perplexa: then just skip the read-string for non-numeric read texts |
| 10:30 | gfredericks | is there a library somewhere for combining several defn'd functions into a single -main that dispatches on the first arg? |
| 10:30 | clgv | perplexa: you will need to wrap the path in "" in edn as well :P |
| 10:30 | gfredericks | I've got an ad hoc one in my latest project and might make it a lib if it makes sense |
| 10:31 | ndp | You're going to have to quote the path whether you use EDN or not |
| 10:31 | clgv | gfredericks: a comp-main macro? |
| 10:31 | perplexa | clgv: yeah but it's a different format in general :) a property file shouldn't break when you put paths without quotes in them. |
| 10:31 | perplexa | i'm fine with quotes in edn ;p |
| 10:32 | ndp | The property file didn't break, your postprocessing did =) |
| 10:32 | clgv | perplexa: well you are not reading it as property file because of your read-string usage, that the reason |
| 10:32 | ndp | The other option is to wrap your read-string in a try-catch and ignore the exception |
| 10:32 | perplexa | clgv: yep |
| 10:33 | perplexa | or just drop read-string completely and replace it with something that returns proper types based on regexes :) |
| 10:33 | gfredericks | clgv: doesn't have to be a macro it could be var-based |
| 10:33 | gfredericks | clgv: my current version just looks in the current namespace for vars with :command metadata |
| 10:33 | clgv | gfredericks: oh are you building a complete -main with tools.cli that way? |
| 10:34 | gfredericks | umms |
| 10:34 | gfredericks | hadn't decided the scope yet |
| 10:34 | gfredericks | handling the subsequent args is complicated :( |
| 10:34 | clgv | that would indeed be an awesome shortcut for default use cases ;) |
| 10:35 | clgv | gfredericks: if not position you mean? |
| 10:35 | clgv | *positional |
| 10:35 | gfredericks | yeah |
| 10:35 | gfredericks | it could have a hook for providing a function from [String] -> [Object] |
| 10:35 | gfredericks | which would let you do arbitrary things |
| 10:35 | gfredericks | like hook in tools.cli |
| 10:35 | clgv | just make them named as tools.cli offers you |
| 10:36 | gfredericks | but the main point is to let you have different tasks spread around different defns |
| 10:37 | gfredericks | the current approach is you put ^:command on the defn and the main bit finds it that way |
| 10:37 | clgv | lein run -- awesome-calc 42 23 => calling (awesome-calc 42 239 ? |
| 10:37 | gfredericks | (awesome-calc "42" "239") |
| 10:37 | clgv | ah right ;) could be with conversion if you parse the arg meta |
| 10:38 | gfredericks | yeah don't know how far to take it |
| 10:41 | yeoj___ | if i return a jdbc result set with (query "select ..") ... how can i call the java method .ResultSetMetadata() on it? I'm confused on java interop (and if i even need to use it...) |
| 10:44 | clgv | gfredericks: well I'd add conversion and stop then. that way you dont need to bother with a command line interface at all to get a runnable (uber-)jar |
| 10:44 | clgv | gfredericks: that would be the main selling point, right? |
| 10:45 | gfredericks | what does a generic conversion interface look like? |
| 10:45 | gfredericks | the metedata has a symbol to lookup that resolves to a function to do the conversion? |
| 10:46 | gfredericks | clgv: I normally end up creating a dispatch map for my main, so that's what's getting replaced mostly |
| 10:47 | clgv | gfredericks: keyword for default builtin-case cases (:string, :long, :double ...) function for custom conversion |
| 10:48 | clgv | ifn? vs fn? |
| 10:48 | clgv | or keyword? vs fn? ;) |
| 10:50 | gfredericks | there should be a term for when there's an edge case overlap between two sets of a sort that isn't likely to be a problem but still drives people like me crazy |
| 10:50 | gfredericks | like when the keyword is also an IFn in this case |
| 10:51 | Glenjamin | is this the whole "should strings be iterable" thing? |
| 10:51 | clgv | yeah the distinction whether you want to support IFn or Fn is sometimes not trivial |
| 10:53 | clgv | yeoj___: afair clojure.jdbc/query returns a clojure sequence, hence you cant call a resultset method on it |
| 10:53 | clgv | yeoj___: at least not on the returned result. maybe you can use one of the hooks to extract the desired data |
| 10:54 | gfredericks | I wonder if it'd be weird if java.jdbc put the result set in the metadata of the return value |
| 10:54 | yeoj___ | clgv: ok... i'm looking through the jdbc.clj code now to see if i can figure anything out... it's not clear exactly how query coerces a resultset into ... |
| 10:54 | clgv | gfredericks: I think there are hooks to access it |
| 10:54 | Glenjamin | you can drop down a level in the api and get the resultset |
| 10:54 | Glenjamin | one sec |
| 10:55 | Glenjamin | http://clojure.github.io/java.jdbc/#clojure.java.jdbc/db-query-with-resultset |
| 10:55 | Glenjamin | query just uses db-query-with-resultset and runs the resultset through result-set-seq |
| 10:56 | yeoj___ | Glenjamin: ah, cool thanks. |
| 11:01 | agarman | is there a way to examine the :pre & :post conditions on a fn? |
| 11:02 | agarman | something like get-validator for Var |
| 11:03 | ambrosebs | agarman: no |
| 11:06 | agarman | I couldn't find a way, but wanted to ask just in case there's something I missed |
| 11:07 | ambrosebs | agarman: there's nothing magic about :pre, it's just code. See clojure.core/fn |
| 11:14 | dave-7 | Hi again, I'm having some trouble setting up secretary's routing using the goog.History object (http://squirrel.pl/blog/2014/03/14/clojurescript-routing-and-templating-with-secretary-and-enfocus/). It's probably some part of the closure library that I'm not understanding, but it seems like the dom is being overwritten whenever I eval the (doto ...) section (from the routing example in the link). |
| 11:19 | agarman | (inc ambrosebs) |
| 11:19 | lazybot | ⇒ 9 |
| 11:21 | agarman | ambrosebs: didn't think of it as magic, but had looked in clojure.lang for where it was executed, skipping past (source fn) |
| 11:22 | ambrosebs | I just think validators are slightly more magic than pre :) |
| 11:43 | razum2um1 | is there any way to use "-quote in a docstring? |
| 11:48 | clgv | ,(println "\"\"") |
| 11:48 | clojurebot | ""\n |
| 11:48 | clgv | ,"\"\"" |
| 11:48 | clojurebot | "\"\"" |
| 11:48 | rurumate | ,(fn ^{:doc "\"-quote" } foo []) |
| 11:48 | clojurebot | #<sandbox$eval71$foo__72 sandbox$eval71$foo__72@1a0fea4> |
| 11:49 | clgv | ,(defn f "\"bla\"" [x] (* x x)) |
| 11:49 | clojurebot | #'sandbox/f |
| 11:49 | clgv | ,(doc f) |
| 11:49 | clojurebot | "([x]); \"bla\"" |
| 11:50 | clgv | works on my repl |
| 11:59 | skinkitten | (1) |
| 12:00 | razum2um1 | yep, escaping works, but wouldn't it be cool to have triple-quotes like python? |
| 12:02 | philandstuff | or reader macros :trollface: |
| 12:05 | clgv | of #ifdefs ? |
| 12:05 | gfredericks | I was able to use reflection to add heredocs to the clojure reader in like 20 minutes |
| 12:05 | gfredericks | can't seem to find the code for it though |
| 12:05 | gfredericks | it's probably lost in refheap |
| 12:06 | clgv | gfredericks: refheap needs a random "did you know this gist?" functionality |
| 12:06 | clgv | then you could find it again by chance :P |
| 12:07 | clgv | or I guess registering an account there would work as well ;) |
| 12:14 | dbasch | gfredericks: do you remember more or less when that was? |
| 12:15 | dbasch | site:refheap.com helps me find my stuff sometimes |
| 12:17 | gfredericks | yes. |
| 12:18 | gfredericks | Between 2014-02-25 and 2014-03-10 |
| 12:18 | gfredericks | but I'm not 100% positive it's on refheap |
| 12:24 | ticking | sorenmacbeth: Nice work with flambo! :) |
| 12:38 | expez | https://www.refheap.com/87779 is there some clever construct I can use to get rid of all the nested ifs when dealing with the multiple arity constructors of bar? |
| 12:38 | rurumate | A go block will always wrap the return value in a channel. Will that channel remain open? |
| 12:44 | dbasch | expez: what does bar do and why can't it take nil arguments for x, y and z? |
| 12:45 | Glenjamin | expez: http://clojuredocs.org/clojure_core/clojure.core/defn#example_137 |
| 12:48 | expez | dbasch: I didn't write bar, but it's a wrapper around a java constructor which comes in three flavors and doesn't accept null anywhere |
| 12:52 | dbasch | expez: why are you making foo a three-arity function instead of an argument list of variable lengths, or different arities? |
| 12:52 | expez | because it's being called with results from the db where x y and z can all by nil :( |
| 12:52 | expez | I hate null values so much |
| 12:54 | dbasch | expez: so just OR your argument list with the default values and call bar with that |
| 12:55 | expez | Not sure why I didn't think of that, so obvious now. Thanks! |
| 12:55 | dbasch | e.g. |
| 12:55 | dbasch | ,(map #(or %1 %2) [nil nil 5] [1 2 3]) |
| 12:55 | clojurebot | (1 2 5) |
| 12:55 | dbasch | np |
| 12:59 | TimMc | Assuming none can be false |
| 13:01 | puredanger | fnil? |
| 13:04 | TimMc | ,((fnil (fn [a b c] [a b c]) 1 2 3) nil nil 5) |
| 13:04 | clojurebot | [1 2 5] |
| 13:10 | tuft | good morning clojuresphere |
| 13:13 | tspot | After 3 months of learning Clojure I'm ready to throw in the towel. Ch 9 of "Joy of Clojure" on namespaces and multimethods just seems incomprehensible :(. |
| 13:13 | cbp | tspot: you can try asking for help |
| 13:13 | tspot | I'm also finding too many things have multiple meanings eg. keywords as functions |
| 13:15 | TimMc | tspot: To be fair, I tend to avoid multimethods. |
| 13:15 | tspot | I was inspired by Rich Hickey's decomplecting but Cloure seems more complex than any language I've learned before. |
| 13:15 | TimMc | Try Scala. :-P |
| 13:16 | gfredericks | namespaces and multimethods is a weird pairing for a book chapter o_O |
| 13:17 | justin_smith | yeah, that is really odd |
| 13:18 | ambrosebs | keywords being functions isn't complex, in that sense. Possibly confusing and unintuitive. |
| 13:18 | justin_smith | tspot: keywords as functions is a syntax shortcut, you can just use get |
| 13:18 | aperiodic | tspot: "seems"? have you used it to implement anything outside of Joy of Clojure exercises? or are you trying to get through the whole book before starting anything? |
| 13:18 | mikerod | tspot: Be careful to interpret simple as easy and complex as difficult |
| 13:19 | tspot | There's so much qualifying and obscurity in Clojure such as :: prefixes and ' quoting that code doens't "speak" the way it does in other languages |
| 13:19 | justin_smith | tspot: well that's not complex, it's just different. mutability, on the other hand, is massively complex. |
| 13:19 | mikerod | tspot: And are you already familiar with functional-orientation in programming? |
| 13:20 | tbaldridge | tspot: you're really mentioning a lot of stuff that beginners don't need to use. I suggest learning from another text, and then picking up JoC after you understand the language a bit more |
| 13:20 | ndp | tspot: It really depends on which languages you're coming from. What's your background? |
| 13:20 | tspot | ndp: Ruby |
| 13:20 | tspot | ndp: Perl before that |
| 13:20 | tbaldridge | tspot: so talk to me about blocks vs lambdas vs procedures :-P |
| 13:21 | ndp | tspot: Ok, both of those are Algol-family languages; it'll take a little while before you fully internalize the characteristics of Lisps. |
| 13:21 | mikerod | Clojure takes huge steps to promote simplicity. This may involve moving away from what is easy / familiar. |
| 13:21 | tspot | tbaldridge: .each is as straightforward as it gets |
| 13:21 | tbaldridge | tspot: but in reality, Ruby is a OOP language, so it makes sense for everything to be an object. Clojure is a functional programming language, so it makes sense that most things would be functions |
| 13:22 | tbaldridge | ,({:a 42} 42) |
| 13:22 | clojurebot | nil |
| 13:22 | tbaldridge | bleh |
| 13:22 | tbaldridge | ,({:a 42} :a) |
| 13:22 | clojurebot | 42 |
| 13:22 | ndp | tspot: I had a somewhat extended settling in time whne I first picked up Lisp after only having done C-like languages. |
| 13:22 | tbaldridge | ,(:a {:a 42}) |
| 13:22 | clojurebot | 42 |
| 13:22 | tspot | mikerod: I actually like the Lisp roots. It's just the contextual switching that throws me. |
| 13:23 | tbaldridge | tspot: and that just takes time (I came from C#/Python). You just have to start small and after awhile it'll come. |
| 13:23 | tspot | tbaldridge: I like the functional/immutable alternative to OO but Clojure has a LOT of syntax. Too much. |
| 13:24 | tbaldridge | tspot: but starting small is a good place to start, read a few chapters from a getting started in Clojure book (not JoC) and then go and write some stuff. |
| 13:24 | tbaldridge | tspot: define syntax? |
| 13:24 | mikerod | tspot: I'm not seeing this "too much" syntax argument I guess |
| 13:24 | dbasch | tspot: it may seem that way because you're not used to it and it's all new, but it's really not that much compared to other languages |
| 13:24 | Glenjamin | JoC is possibly not a great intro do clojure book - i think it says that in chapter 2 actually |
| 13:24 | dbasch | tspot: have you tried the 4clojure exercises? |
| 13:24 | Glenjamin | or maybe it says not a great intro to programming, i forget |
| 13:25 | mikerod | I'd argue that Clojure, along with pretty much all popular Lisps, have the least "amount of syntax" when compared to other mainstream langs |
| 13:25 | dbasch | tspot: JoC can be overwhelming if you don't have some lisp and/or java background |
| 13:25 | mikerod | Clojure did add a bit more than traditional in other Lisps. This was done for the sake of simplicity in removing the overloading of the () construct. |
| 13:25 | tspot | Glenjamin: Yes, I'm also reading "Clojure in Action" for first steps. Much clearer but I'm only at the early chapters. |
| 13:26 | tbaldridge | (inc mikerod) |
| 13:26 | lazybot | ⇒ 1 |
| 13:26 | Glenjamin | aphyr's blog series i think is excellent |
| 13:26 | mikerod | Rich Hickey has a good discussion of why he added a few more data literals. |
| 13:26 | tbaldridge | (let ((a 42) (b 433)) (+ a b)) is just gross |
| 13:26 | Glenjamin | but once you're beyond the basics, i think building something useful teaches you loads |
| 13:26 | mikerod | I can't recall the exact talk. |
| 13:27 | Glenjamin | the first thing i built was something i could have built in not-clojure, and if i built it now it'd be completely differently structured - but i really got the hang of the language while doing it |
| 13:28 | mdrogalis | mikerod: http://www.infoq.com/presentations/Simple-Made-Easy 25:13 |
| 13:28 | atyz | Hey all... I've run into a weird problem with our production boxes. After a few hours of running the processor load will reach 100% and will trigger auto scaling. I have reason to believe that this is not because of load. Does anyone have any clues as to how I can figure out what this is? |
| 13:28 | tbaldridge | atyz: perhaps log the GC some and see if there is a connection? |
| 13:29 | tspot | It's not the data structure syntax that bothers me. More the @~ and :: stuff. Clojure seems cluttered with what I would call qualifiers and quoting seems to spill out well beyonds its use in macros. I have a hard time understanding its use in (ns ..... (:require and all its permutations |
| 13:29 | Glenjamin | ns is a mess |
| 13:29 | atyz | tbaldridge: thats a good idea, although I thoguht that would affect the memory more |
| 13:30 | Glenjamin | especially if you get the literals slightly wrong, the error messages are next-to useless |
| 13:30 | TimMc | atyz: Can you induce a thread dump? |
| 13:30 | TimMc | Maybe you'll find something that is spawning threads. |
| 13:31 | atyz | TimMc: this is along the lines I was thinking. I am using futures to do some asynchronous processing. I'm under the impression that they will kill themselves on the completion of the job. Is this a correct assumption? |
| 13:32 | TimMc | They should, yeah. But I think those are on a pool of limited size. |
| 13:32 | mikerod | mdrogalis: Thanks :) |
| 13:32 | atyz | They are, 2 per core I believe |
| 13:33 | atyz | Do you think it could be that there are too many being spawned for the processor to keep up? |
| 13:33 | aperiodic | tspot: @~ is only needed in macros, which you almost never need to write. :: is not that common either: it's mainly used when you want to be sure to avoid conflicts in a map. quoting is only necessary in actual code when you want to use symbols without evaluating them which is extremely rare. at the repl, you do have to quote to use bare (require ...), but not when making a namespace with (ns ... (:require ...)). |
| 13:34 | aperiodic | tspot: i think you are trying to understand every possible language feature before actually writing something, which will make any language seem crazily complex and daunting to learn |
| 13:34 | TimMc | atyz: Dunno. But try running jstack PID if it's available. |
| 13:34 | TimMc | atyz: What happens to the CPU if you take a machine out of the scaling group? (Can you do that?) |
| 13:34 | mikerod | Quoting is more of a Lisp thing than a Clojure-specific. I don't see why it would "leak out far beyond macros" |
| 13:35 | mikerod | The syntax-quote ` ~@ stuff is just shorthand for quoting things. |
| 13:35 | mikerod | And all this just relates back to having homoiconicity. |
| 13:35 | mikerod | I think aperiodic is right that this shouldn't be the focus when getting started learning and using the language. |
| 13:36 | mikerod | The ns macro is a bit whacky though, I'd agree. Just don't typo there. :) |
| 13:37 | ambrosebs | clojure is not a good language to make mistakes in. |
| 13:37 | TimMc | ,`[0 ~@(range 1 5) 0] ;; aperiodic, it's useful outside of macros as well |
| 13:37 | clojurebot | [0 1 2 3 4 ...] |
| 13:38 | aperiodic | oh, cool |
| 13:39 | atyz | TimMc sorry for the delay. I think If I take it out of the scaling group (and lb) it will continue to spin at 100% |
| 13:39 | mikerod | TimMc: do you find yourself often doing things like that? |
| 13:39 | atyz | But thats just a guess |
| 13:39 | atyz | I'll try to do so now |
| 13:40 | mikerod | I don't think I have many cases where that'd be something I wrote. Perhaps you have good use-cases though. |
| 13:41 | mikerod | It is certainly convenient if you needed to unroll a bunch of stuff into a literal form :P |
| 13:42 | TimMc | atyz: Err yes, the LB. :-) |
| 13:42 | TimMc | mikerod: It's rare, but when I do use it, it's super convenient. :-) |
| 13:47 | mr-foobar | in clojure does a symbol follow a protocol or an api ? |
| 13:47 | atyz | TimMc: I just pulled it out of the load balancer, so I guess we will see what happens in a few minutes |
| 13:48 | dbasch | mr-foobar: not sure what you're asking, can you rephrase your question? |
| 13:49 | dbasch | mr-foobar: a symbol is just an instance of clojure.lang.Symbol |
| 13:50 | mr-foobar | dbasch: clojure.lang.Symbol is what I was looking for. |
| 13:52 | mr-foobar | dbasch: symbols can be used like enums right ? ( i am in the js land. need something like symbols / js ) |
| 13:53 | nkoza | mr-foobar: the common idiom is to use keywords for that |
| 13:53 | nkoza | mr-foobar: as in :red :blue :green |
| 13:54 | mr-foobar | nkoza: oh, I am aware of that. I am using js :( I want to port that idiom to js basically. |
| 13:58 | atyz | TimMc: Interesting... Its still at 100 % after being out of the LB for 10 minutes |
| 13:58 | TimMc | So, it's definitely stuck on something. Do you have jstack on that machine? Should come with the JDK. |
| 13:59 | atyz | TimMc: I do indeed. sudo jstack 1277 |
| 13:59 | atyz | 1277: Unable to open socket file: target process not responding or HotSpot VM not loaded |
| 13:59 | atyz | The -F option can be used when the target process is not responding |
| 14:00 | atyz | Yep, it seems there is a deadlcok |
| 14:00 | TimMc | Apparently the -l option will print locks. |
| 14:01 | atyz | https://www.refheap.com/87785 |
| 14:01 | atyz | There is no locks I don't think |
| 14:01 | atyz | But a bunch of the processes are locked |
| 14:02 | TimMc | "No deadlocks found" |
| 14:03 | atyz | Yep - this is really curious - I can't help but think this is because of my use of futures |
| 14:03 | TimMc | I'm not sure if those blocked threads are normal, though -- maybe they're a threadpool waiting for requests. |
| 14:03 | TimMc | Check the thread dump for a server that is behaving nicely. |
| 14:04 | atyz | Well TimMc the issue is that *all* of the servers get into this state |
| 14:04 | atyz | Eventually |
| 14:04 | atyz | I'm having to kill the oldest one |
| 14:05 | atyz | Periodically |
| 14:05 | TimMc | Can you take one out of LB that is not yet at 100%, check the threads, and compare it? |
| 14:06 | atyz | I could do that |
| 14:08 | TimMc | I'm not entirely sure how to interpret these entrails, but there might be something obvious. |
| 14:08 | hiredman | http://wiki.eclipse.org/Jetty/Howto/High_Load#Thread_Pool |
| 14:21 | atyz | TimMc: https://www.refheap.com/87787 <-- the new one... Its the same |
| 14:31 | hotcore | ,({:a 42} :a) |
| 14:31 | clojurebot | 42 |
| 14:32 | cbp | TIL multimethods don't realize sequences when you're dispatching on (map type x) |
| 14:35 | atyz | hiredman: that could be something! Thank you. Now to find where to configure this |
| 14:35 | atyz | Although that wouldn't explain why the cpu usage i still at 100% now |
| 14:38 | hiredman | atyz: who knows what the queue depth is, could take forever to chew through |
| 14:40 | atyz | hiredman: would this just be api requests that havent been processed? or threads pushing out data that haven't been sent yet? |
| 14:42 | hiredman | either |
| 14:43 | hiredman | the picture may be more complicated if you are using the async reply features of pedastal |
| 14:44 | hiredman | and imposing limits on jetty's request queue won't "fix" whatever the problem is, it will just cause hard failures fast instead of soft slow failures |
| 14:45 | atyz | hiredman: that is something, atleast |
| 14:45 | hiredman | yep |
| 14:49 | amalloy | cbp: that doesn't sound right. the first thing isa? does is check whether (= parent child) |
| 14:49 | hiredman | I wonder if it could be a gc pause causing a back up in jetty's queue, if the hard failures start happening, you can run the jvms with -verbose:gc and try to correlate that output with the hard failures |
| 14:49 | amalloy | so it should realize the sequence of (map type x) |
| 14:50 | atyz | hiredman: you seem quite confident that this has something to do with jetty? |
| 14:50 | amalloy | if you mean that the elements of x are themselves sequences, and it doesn't realize *those* sequences, then well, of course not |
| 14:51 | hiredman | atyz: I think the symptoms you are describing match what is in the wiki there pretty well, but I don't know what the underlying cause is |
| 14:52 | hiredman | atyz: something must be "sticking" it jetty's queue for some reason, which is causing the back up of requests in the queue |
| 14:52 | yeoj___ | i'm trying to reference java's .getMetaData but it's not seeming to be working... i wanted to pass that in as the function (third arg) to db-query-with-results .... is it possible it needs a type metadata somewhere to get interopp to work? |
| 14:52 | cbp | amalloy: https://www.refheap.com/87790 |
| 14:53 | cbp | er |
| 14:53 | cbp | i messed up there |
| 14:54 | hiredman | atyz: it could be some other place you are doing unbounded queueing, futures run on an unbounded threadpool |
| 14:55 | hiredman | jetty must expose its queue depth somewhere (as a mxbean or something) if you can find that and read it on one of these highload servers it would give you an idea |
| 14:56 | cbp | amalloy: https://www.refheap.com/87791 |
| 14:56 | cbp | :-P |
| 14:57 | cbp | (mapv type x) does make that work though |
| 14:57 | atyz | hiredman: howw ould you create a future on an unbounded threadpool, I thought inheritly they were restricted? |
| 14:57 | cbp | also note that (foo [1 2]) doesnt work |
| 14:58 | hiredman | atyz: futures are not |
| 14:58 | arrdem | cbp: mapv :P |
| 14:58 | hiredman | clojure has two built in thread pools, futures use the unbounded one |
| 14:59 | arrdem | cbp: note that this explodes for more than the two-ary case, hence this https://github.com/clojure/algo.generic/blob/master/src/main/clojure/clojure/algo/generic.clj |
| 14:59 | amalloy | cbp: that's nothing to do with realizing sequences |
| 15:00 | amalloy | the lazy seq is in fact realized there |
| 15:00 | amalloy | you could see that by using, for example, (map #(doto (type %) prn) x) |
| 15:01 | amalloy | rather, isa?'s behavior to "look inside vectors to see if their elements are isa?" only applies when both objects are specifically vectors |
| 15:01 | atyz | hiredman: thats very interesting, I'm even more confident that that is my problem now |
| 15:02 | amalloy | (and of course (map type x) is not a vector) |
| 15:03 | hiredman | atyz: are you familiar with the executors framework? switching from clojure's built in future to something more custom using your own threadpool is not too bad |
| 15:05 | atyz | hiredman: I am not at all. futures were just a really simple way to do some fire-and forget asynchronous work done |
| 15:06 | atyz | I could probably also use core.async too |
| 15:06 | hiredman | atyz: I would be very careful with core.async |
| 15:07 | atyz | You think I would end up with the same problem if I don't configure the channel properly? |
| 15:07 | hiredman | forkjoin threadpools are not supposed to have io schedule on them |
| 15:07 | hiredman | (any blocking operation really) |
| 15:08 | hiredman | atyz: my guess is you are doing something blocking at some point, in which case you'll want your own threadpool even if you use core.async |
| 15:08 | atyz | hiredman: they are. they are usually api calls |
| 15:09 | atyz | to other services |
| 15:09 | atyz | But in a lot of the cases it should have its own threadpool. https://github.com/dakrone/clj-http |
| 15:10 | hiredman | core.async can make those async calls look synchronous, but it doesn't obviate the need for a an io threadpool |
| 15:10 | hiredman | atyz: but clj-http is still blocking |
| 15:10 | atyz | It is, I realise that |
| 15:10 | atyz | I think that that is the issue |
| 15:11 | hiredman | so you are spinning out these futures to do this blocking operation without any back pressure |
| 15:11 | hiredman | infact executors might not work very well, they don't have a good way to do back pressure |
| 15:12 | atyz | Well those clj-http calls aren't done through futures |
| 15:12 | atyz | clj-http allows you to create your own threadpool |
| 15:12 | atyz | to work from |
| 15:12 | tbaldridge | as an aside, http-kit has a really nice async http client |
| 15:12 | dakrone | hiredman: they do, you can spin up an executor with a fixed-size queue |
| 15:12 | dakrone | and then adding to the queue will block until work completes |
| 15:12 | atyz | https://www.refheap.com/87792 |
| 15:13 | hiredman | dakrone: sure, but the Executors factory class won't make one of those for you |
| 15:13 | dakrone | hiredman: yes, quite true |
| 15:13 | hiredman | atyz: yeah, that doesn't really matter though, it may be running on connection manager threadpool, but on the calling thread it is still a blocking operation |
| 15:14 | atyz | OH that makes sense |
| 15:24 | cbp | amalloy: Oh so it will work as long as it's = and doesn't have to check for isa? |
| 15:24 | cbp | as in (defmethod foo [Long Long] ..) would work there |
| 15:28 | atyz | hiredman: I don't suppose you have configured jetty embedded jetty before? Does this mean I won't be able to use the version that comes with pedestal anymore? |
| 15:28 | ohpauleez | My ears are ringing :) |
| 15:30 | ohpauleez | atyz: Are you using Pedestal 0.3.0? |
| 15:30 | atyz | ohpauleez: not yet |
| 15:31 | atyz | [io.pedestal/pedestal.service "0.2.2"] |
| 15:31 | ohpauleez | Ahh, that uses the latest Connection bits in the latest Jetty release |
| 15:31 | ohpauleez | but requires you are on JDK 1.7 or higher |
| 15:31 | atyz | ohpauleez: I"m afraid to upgrade - I've had to make some changes to how pedestal boots |
| 15:31 | ohpauleez | If you're making clj-http calls within your service, it's advised you wrap them in Hystrix |
| 15:32 | ohpauleez | The startup and integration is greatly simplied in 0.3.0. There are a bunch of performance improvements, extra security features you can toggle on if you want, and the ability to use ServletFilters right in your Pedestal App (at the container level) |
| 15:32 | ohpauleez | or reach deep into the container to toggle whatever you need |
| 15:33 | atyz | Well lets see what happens if I upgrade it qucikly |
| 15:33 | atyz | Maybe it will work |
| 15:35 | atyz | ohpauleez: well surprisingly it worked! |
| 15:36 | ohpauleez | You may have to adjust some of your startup code, and adjust your namespaces |
| 15:36 | ohpauleez | ie: there's no more *.service.* |
| 15:36 | atyz | Oh... Then some stuff is probably broken |
| 15:38 | atyz | Anyway, to the issue at hand.. woudl you maybe point me in the direction of where I could possibly configure jetty? |
| 15:40 | ohpauleez | How do you want to configure it? During startup, you can pass a function that is given the container (and returns it), and you can do whatever you want |
| 15:41 | ohpauleez | in 0.3.0, you can reach even deeper, into the Container's context setup |
| 15:41 | ohpauleez | which is difficult to do unless the hooks are exposed or you jump through a lot of hoops |
| 15:42 | ohpauleez | If what you want is to specify your own interceptor chain, you do that on the :interceptors key on the service map |
| 15:42 | ohpauleez | instead of accepting the default stack, you just assembly your own |
| 15:42 | atyz | ohpauleez: yes, but that didn't allow me to specify the order in which they were loaded |
| 15:43 | ohpauleez | yes |
| 15:43 | ohpauleez | if you specify them in the original service map, the default ones aren't added |
| 15:43 | ohpauleez | and the processing is always sequential to how they're specified |
| 15:44 | ohpauleez | If you add :interceptors in your own function, that function *has-to* run before any startup or processing function on the Pedestal side |
| 15:44 | ohpauleez | if Pedestal sees :interceptors on the service-map, it takes them and runs with them |
| 15:45 | ohpauleez | You can also take the default stack (if you want it) and attach root interceptors at the root URL in your routes (if they're all HTTP/route specific) |
| 15:47 | sveri | Hi, I am trying to reload my enlive templates namespace based on a watcher on the resources path. However, I cannot get it working, as soon as I use: (use 'namespace :reload) my watcher function is not called anymore. Any ideas how to make it work? http://pastebin.com/X15vx6f5 |
| 15:47 | cbp | methinks isa? should be better documented |
| 15:52 | tbaldridge | ,(doc isa?) |
| 15:52 | clojurebot | "([child parent] [h child parent]); Returns true if (= child parent), or child is directly or indirectly derived from parent, either via a Java type inheritance relationship or a relationship established via derive. h must be a hierarchy obtained from make-hierarchy, if not supplied defaults to the global hierarchy" |
| 15:54 | cbp | there's nothing there about (isa? [Long Long] [Number Number]) working or (isa? (list Long Long) [Number Number]) not working |
| 15:56 | TimMc | cbp: What? That's absurd. D-: |
| 16:04 | dbasch | ,(isa? '(Long Long) '(Number Number)) |
| 16:04 | clojurebot | false |
| 16:04 | dbasch | ,(isa? [Long Long] [Number Number]) |
| 16:04 | clojurebot | true |
| 16:04 | tbaldridge | ,(source isa?) |
| 16:05 | clojurebot | Source not found\n |
| 16:05 | Glenjamin | does anyone know why PersistentQueue doesn't have a function to create one in core? |
| 16:06 | Glenjamin | ,(-> (clojure.lang.PersistentQueue/EMPTY) (conj 1 2 3) pop) |
| 16:06 | clojurebot | #<PersistentQueue clojure.lang.PersistentQueue@402> |
| 16:06 | Glenjamin | or a printer implementation apparently |
| 16:06 | Glenjamin | ,(-> (clojure.lang.PersistentQueue/EMPTY) (conj 1 2 3) pop vec) |
| 16:06 | clojurebot | [2 3] |
| 16:07 | amalloy | Glenjamin: there's no good reason |
| 16:07 | dbasch | ,(isa? {Long Long} {Long Number}) |
| 16:07 | clojurebot | false |
| 16:07 | dbasch | actually that one makes sense |
| 16:07 | bhauman | Glenjamin: I have often missed that function, medley has it though |
| 16:07 | Glenjamin | i only noticed because mori exposes it as a primary datatype http://swannodette.github.io/mori/#queue |
| 16:07 | tbaldridge | dbasch: ick, yeah, isa? has a special case for vectors |
| 16:08 | tbaldridge | why? I haven't a clue |
| 16:08 | Glenjamin | although i want a structure which does random access, efficient append and effcient dropping of "old" entries in a windowing-fashion |
| 16:08 | Glenjamin | which i don't think exists |
| 16:08 | eevar | a circle buffer? |
| 16:09 | amalloy | $google amalloy ring-buffer |
| 16:09 | lazybot | [amalloy/ring-buffer · GitHub] https://github.com/amalloy/ring-buffer |
| 16:09 | amalloy | Glenjamin: doesn't actually expose random-access, but there's no reason it couldn't |
| 16:11 | Glenjamin | Oh, in pure js |
| 16:12 | Glenjamin | Oh I see, it's vector-backed |
| 16:12 | puredanger | Glenjamin: re Queue stuff, vote: http://dev.clojure.org/jira/browse/CLJ-1078 |
| 16:13 | Glenjamin | Ta |
| 16:14 | Glenjamin | amalloy: I might see if I can port this to JS backed on a mori vector if that's ok with you? |
| 16:15 | amalloy | sure. i don't own the idea of ring buffers; there's probably not even anything novel in my implementation |
| 16:16 | Glenjamin | I'll have to read up on some thing it seems :) |
| 16:18 | TimMc | dbasch: ##(isa? '[Long Long] '[Number Number]) |
| 16:18 | lazybot | ⇒ false |
| 16:18 | TimMc | so your list example wouldn't have worked anyhow |
| 16:18 | TimMc | ,(isa? (list Number Number) [Number Number]) |
| 16:18 | clojurebot | true |
| 16:19 | dbasch | ,(isa? (list Long Long) (list Number Number)) |
| 16:19 | clojurebot | false |
| 16:47 | borkdude | I have defined a macro in a namespace recipes.macros named with-data-loaded. I call it from clojurescript, but the clojurescript compiler says: WARNING: No such namespace: recipes.macros at line 115 src/recipes/app.cljs |
| 16:49 | bob2 | https://github.com/clojure/clojurescript/wiki/Differences-from-Clojure#lisp i guess |
| 16:50 | borkdude | bob2 I've done that: https://www.refheap.com/87798 |
| 16:50 | bob2 | i feel like you missed the "The :as prefix selector is required in :require-macros." bit |
| 16:51 | borkdude | hmz |
| 16:51 | borkdude | then why isn't it required in [cljs.core.async.macros :refer [go go-loop]] |
| 16:52 | borkdude | but I will try |
| 16:52 | bob2 | no idea |
| 16:52 | borkdude | nope, still the same |
| 16:53 | borkdude | it's like it doesn't pick up the clj file |
| 16:57 | borkdude | Clojurescript up and running says: "This assumes that a Clojure source file is available on the classpath at my_project/ |
| 16:57 | borkdude | foo.clj containing defmacro foo.". How can I assure that this is the case with lein cljsbuild auto? |
| 16:58 | PigDude | what does this mean? clojure.lang.ArityException: Wrong number of args (4) passed to: PersistentArrayMap> |
| 16:58 | PigDude | i get this error with no line number or anything |
| 16:59 | amalloy | PigDude: you passed four arguments to a map. probably you didn't mean to call the map at all, but had too many parens or were missing a do |
| 16:59 | hiredman | PigDude: the stack trace will have line numbers in it |
| 17:01 | PigDude | hiredman: when? |
| 17:01 | PigDude | hiredman: there is no stack trace |
| 17:01 | hiredman | PigDude: there is always a stracktrace, your tooling may not be displaying it |
| 17:02 | hiredman | the exception will be in *e |
| 17:02 | hiredman | you can use clojure.stacktrace/print-stack-trace to print it, or call the method I never case correctly on it |
| 17:03 | tbaldrid_ | hiredman: except when it says "No trace found" still no clue what that means |
| 17:03 | PigDude | hiredman: my tooling consists of a terminal, bash, and leiningen |
| 17:03 | PigDude | where is *e? |
| 17:03 | PigDude | hiredman: ^ |
| 17:03 | hiredman | tbaldrid_: the jit can some sometimes elide traces, there is some jvm option to turn it off |
| 17:04 | hiredman | PigDude: type *e in the repl |
| 17:04 | Shayanjm | So I'm trying to use lein ring to handle a hot-reloaded ring server for me while I build on it. Here's the code: https://gist.github.com/shayanjm/65942169797fd2f84a54 |
| 17:04 | PigDude | hiredman: what repl |
| 17:04 | PigDude | hiredman: i'm running `lein test` |
| 17:04 | Shayanjm | everything starts fine, and I can access the server |
| 17:04 | hiredman | :( |
| 17:04 | Shayanjm | but I can't access the nrepl |
| 17:04 | Shayanjm | if I try to connect, it just hangs |
| 17:04 | hiredman | PigDude: I find it very hard to believe that lein test isn't printing a stacktrace |
| 17:05 | PigDude | hiredman: do you want a screenshot? |
| 17:05 | Shayanjm | I tried passing join? false through the :adapter settings in the project.clj but it doesn't seem to be working |
| 17:05 | hiredman | PigDude: sure |
| 17:05 | dbasch | hiredman: that particular exception in cider doesn't print a trace either |
| 17:05 | dbasch | , ({} 1 2 3 4) |
| 17:05 | clojurebot | #<ArityException clojure.lang.ArityException: Wrong number of args (4) passed to: PersistentArrayMap> |
| 17:05 | dbasch | ,(print *e) |
| 17:05 | clojurebot | #<Unbound Unbound: #'clojure.core/*e> |
| 17:05 | hiredman | dbasch: that is because cider has a stupid option that defaults to not displaying the stacktrace |
| 17:06 | amalloy | tbaldridge: "trace missing" kinda stuff comes when the jit has converted the relevant method into machine code that's optimized enough that it's no longer capable of keeping track of the bytecode that generated it, or something like that |
| 17:06 | hiredman | dbasch: don't assume clojurebot's evaluation environment is like the repls |
| 17:06 | dbasch | hiredman: but even *e has no stacktrace |
| 17:06 | PigDude | so do you want to see the screenshot still hiredman |
| 17:06 | PigDude | dbasch seems to be right |
| 17:06 | hiredman | PigDude: show me lein test not printing a stacktrace |
| 17:06 | dbasch | there are a bunch of cases like that in core.clj, I remember one like that recently |
| 17:07 | dbasch | where it essentially eats the stacktrace |
| 17:07 | hiredman | PigDude: he is not |
| 17:08 | PigDude | hiredman: here's a paste, i hope you trust me not to have doctored it https://www.refheap.com/b7f57290f403ef0dda758f63e |
| 17:08 | hiredman | PigDude: right, so you are catching the exception somewhere and printing it out |
| 17:08 | hiredman | (try … (catch Exception e (prn e))) |
| 17:08 | hiredman | actually |
| 17:08 | hiredman | that is core.async |
| 17:09 | amalloy | yeah, notice that didn't even count as a failure in the tests. someone caught it and printed it |
| 17:09 | hiredman | there is a stupid line that got committed in core.async that prints out unhandled exceptions like that |
| 17:09 | PigDude | hiredman: the only exception handling in my program is in clojurescript code |
| 17:09 | PigDude | hiredman: seriously? |
| 17:09 | hiredman | PigDude: right, but you have a go routine somewhere that is throwing that exception |
| 17:09 | benkay | so i've got a weird thing going on - for some hard-to-pin-down subset of pages on which i'm using enlive, it's setting a <style type="text/css> tag to the header, and setting other attrs on my images like "width=0,height=0". has anyone else run into this? |
| 17:09 | hiredman | PigDude: yep |
| 17:09 | cbp | hiredman: :| |
| 17:10 | hiredman | it may have been fixed in a later release, dunno |
| 17:10 | PigDude | so when programming with core.async, you don't get stacktraces?? |
| 17:10 | lazybot | PigDude: Uh, no. Why would you even ask? |
| 17:10 | hiredman | PigDude: if you catch the exception yourself you will |
| 17:10 | cbp | core dont need no silly stacktraces |
| 17:11 | amalloy | hiredman: https://github.com/clojure/core.async/blob/76b25bf91c670b0c3542ed9cb687ff29fb2183a7/src/main/clojure/clojure/core/async/impl/exec/threadpool.clj#L24-L33 ? |
| 17:11 | dbasch | hiredman: you're wrong, there are cases in core where you don't get stacktraces |
| 17:11 | stuartsierra | PigDude: You get a stacktrace, but it can be difficult to predict where and when the stacktrace will appear. |
| 17:11 | hiredman | https://github.com/clojure/core.async/blob/master/src/main/clojure/clojure/core/async/impl/exec/threadpool.clj#L33 |
| 17:11 | PigDude | discussion changed, is clojure a ghetto? :) |
| 17:11 | hiredman | stuartsierra: you don't, the executor prints out the exception, no trace |
| 17:12 | hiredman | amalloy: yeah |
| 17:12 | hiredman | dbasch: no, you just don't know where to look |
| 17:12 | amalloy | dbasch: i don't think that's true |
| 17:12 | stuartsierra | Wait, when did that happen? |
| 17:12 | dbasch | amalloy hiredman I remember an example that we found here a few weeks ago |
| 17:12 | dbasch | trying to find it in the logs |
| 17:12 | PigDude | thanks for helping me figure this out dbasch and hiredman |
| 17:12 | amalloy | stuartsierra: https://github.com/clojure/core.async/commit/9fcae99576c0735a804bbd4cbec81307e2d34d90 |
| 17:13 | amalloy | specifically https://github.com/clojure/core.async/commit/9fcae99576c0735a804bbd4cbec81307e2d34d90#diff-2193dd8597437d6454bb74edd2f15e00L26 |
| 17:13 | hiredman | core.async, land of random stuff |
| 17:13 | dbasch | it was an exception that did not even show a line number |
| 17:13 | PigDude | stuartsierra: so in my case i did not get a stacktrace because it was a special case in core, nothing to do with async |
| 17:13 | hiredman | dbasch: not having a line number and not have a stacktrace are different |
| 17:14 | dbasch | hiredman: it had neither |
| 17:14 | hiredman | dbasch: nope |
| 17:14 | amalloy | i think you can get exceptions with no stack trace at all if the jit has done something particularly aggressive |
| 17:14 | amalloy | "trace missing" |
| 17:14 | hiredman | amalloy: and -XX:-OmitStackTraceInFastThrow will fix that |
| 17:15 | hiredman | (in theory) |
| 17:15 | dbasch | amalloy: technically it had a stacktrace, but it was shallow because it was a freshly thrown exception that caught another one |
| 17:15 | hiredman | well, there you go, it had a stacktrace |
| 17:15 | dbasch | it was a really silly line, but I can't find it |
| 17:16 | amalloy | i just remembered an issue in the cljs compiler where it was catching an OOME and trying to alloc up a new exception to wrap around it |
| 17:16 | amalloy | i wonder if that's fixed |
| 17:18 | yedi | is there a function that unqualifies a keyword |
| 17:19 | amalloy | i regard keywords as unqualified if they haven't got at least a bachelor's degree |
| 17:20 | Frozenlock | Is there a way to give a name to the :sender/:from in postal? |
| 17:20 | cbp | yedi: name |
| 17:20 | cbp | o you scared him away |
| 17:20 | Frozenlock | I'd like the recipient to see "Frozenlock" instead of "frozenlock@gmail.com" :-/ |
| 17:21 | wheeee | :injections in project.clj |
| 17:21 | wheeee | Err whoops. |
| 17:22 | cbp | $mail yedi (name :a/b) |
| 17:22 | lazybot | Message saved. |
| 17:24 | Frozenlock | Ah got it... :from "Frozenlock <frozenlock@gmail.com>" |
| 17:26 | dbasch | Frozenlock: :from can be "Mr. Frozenlock <frozenlock@gmail.com>" |
| 17:26 | dbasch | you beat me to it |
| 17:26 | Frozenlock | By a single minute ;-p |
| 17:27 | dbasch | Frozenlock: I had to go look into an app of mine that does that :P |
| 17:28 | Frozenlock | Is this a javax/mail thing, or it's a universal email thing that I should have known? |
| 17:32 | Klaufir | I am trying to follow the STM tutorial at http://sw1nn.com/blog/2012/04/16/clojure-stm-ref-consistency/ , however I get a nullptr exception for reasons unknown to me, details: http://lpaste.net/106817 |
| 17:32 | Klaufir | I need some help determining the reason for that nullptr exception |
| 17:33 | amalloy | Frozenlock: it's an email thing |
| 17:34 | hiredman | Klaufir: that tutorial is bogus, their code was never run and would never have worked |
| 17:34 | Frozenlock | amalloy: Awww, shame on me then. |
| 17:34 | hiredman | Klaufir: they are using #() incurrectly |
| 17:34 | hiredman | Klaufir: it would always generate an npe |
| 17:34 | stuartsierra | amalloy, hiredman, PigDude, dbasch: I'm going to fix this. |
| 17:35 | hiredman | incorrectly |
| 17:35 | hiredman | Klaufir: because of the way #() turns in to a function, that code is trying to call the result of (println "READ start") on the resut of (dosync ...) |
| 17:36 | hiredman | and of course the result of a call to println is nil |
| 17:36 | hiredman | switch to (fn [] ...) or #(do ...) |
| 17:36 | Klaufir | hiredman: ah, thank you. |
| 17:36 | Klaufir | hiredman: can you recommend a better text for learning stm? |
| 17:37 | hiredman | Klaufir: don't bother, you'll never use it |
| 17:37 | dbasch | Frozenlock: http://tools.ietf.org/html/rfc2822#appendix-A.1 |
| 17:39 | wheeee | Can someone tell me what :injections does within a lein project.cljs? |
| 17:39 | wheeee | project.clj |
| 17:39 | nhll | . |
| 17:40 | amalloy | a rule of thumb: if the tutorial you're reading has paragraphs of text crossed out and concludes with "we found a potential problem with the clojure runtime", the author is probably clueless |
| 17:40 | cbp | Klaufir: clojure programming has nice diagrams on the retry mechanisms of the different clojure refs |
| 17:40 | Klaufir | cbp: thanks |
| 17:42 | hiredman | hah they must have been running their code in some environment that sent the npe stacktraces somewhere else, so they never saw them |
| 17:43 | hiredman | clojurebot: bloggers |are| the worst |
| 17:43 | clojurebot | In Ordnung |
| 17:44 | amalloy | hiredman: my guess was that it was originally written with (future #((...))), which squelches the exceptions |
| 17:45 | amalloy | and then they switched to Thread/start to avoid having to explain futures or something |
| 17:45 | hiredman | amalloy: well, no future wouldn't call the function |
| 17:45 | amalloy | oh, right |
| 17:47 | PigDude | is it cleaner to use separate async channels than to share one and tag messages? |
| 17:47 | PigDude | matching tagged messages isn't easy like in erlang |
| 17:47 | hiredman | PigDude: maybe use the pub/sub stuff |
| 17:48 | hiredman | https://github.com/clojure/core.async/blob/master/src/main/clojure/clojure/core/async.clj#L823 |
| 17:50 | PigDude | i wish async walkthrough.clj covered that usage, do you know of one? |
| 17:50 | hiredman | noppe |
| 17:50 | PigDude | (example of using async pub/sub) |
| 17:50 | PigDude | ok :) |
| 17:50 | PigDude | it looks like what i want though, thanks |
| 17:53 | stuartsierra | http://dev.clojure.org/jira/browse/ASYNC-76 |
| 17:58 | Shayanjm | Does anyone know why `lein ring server` would start & execute correctly, but the nrepl hangs? |
| 17:58 | Shayanjm | https://gist.github.com/shayanjm/65942169797fd2f84a54 |
| 18:01 | benkay | did the optional query clauses ever make it into datomic? https://groups.google.com/d/msg/datomic/p3FLisquFH8/J1kXJ_9pQngJ |
| 18:03 | BobSchack | benkay: yep see http://docs.datomic.com/query.html#expression-clauses |
| 18:03 | benkay | thanks BobSchack |
| 18:03 | BobSchack | NP |
| 18:03 | alloyed | @Shayanjm lein-ring outputs a log when the nrepl comes up, does your app otherwise work without ever saying "nrepl has started on XXXX" or whatever? |
| 18:04 | Shayanjm | alloyed: Everything works fine, and it says nrepl has started on XXXX as well as the ring server has started on XXXXX |
| 18:04 | Shayanjm | everything "works" I just can't connect to the repl :\ |
| 18:04 | Shayanjm | it doesn't even error upon connection either - it just keeps trying to connect indefinitely |
| 18:04 | Shayanjm | (or it hangs, I can't really tell which is happening) |
| 18:06 | alloyed | hmm, what nrepl client are you using? just `lein repl :connect"? |
| 18:06 | serjeem | Is there an equivalent to (declare …) for classes/records? |
| 18:07 | technomancy | serjeem: no, you can't seamlessly replace a class or record afaik |
| 18:08 | technomancy | which is basically the whole point of vars |
| 18:08 | serjeem | technomancy: heartbreaking :(. Is there some kind of hack I could use to forward-reference a class before I define it? |
| 18:08 | Shayanjm | sorry alloyed I just dc'd on my BNC :\ What was the last thing I said in the chan? |
| 18:08 | alloyed | 22:03 < Shayanjm> (or it hangs, I can't really tell which is happening) |
| 18:09 | hiredman | serjeem: why not create a factory function and declare that? |
| 18:09 | Shayanjm | Did you answer that, by chance? |
| 18:09 | hiredman | serjeem: if you are using a defrecord you automatically get 2 factory functions, which you can declare and use |
| 18:09 | Shayanjm | The latest logs I have are from technomancy saying "which is basically the whole point of vars" |
| 18:09 | technomancy | serjeem: this is why I hate using things that aren't vars |
| 18:09 | alloyed | I was just asking how you were connecting to the repl. |
| 18:10 | serjeem | hiredman: I’m writing a bunch of macros that more-or-less do some typechecking among their outputs. They output new defrecords, and I’d like to be able to use these new records in potentially recursive ways. |
| 18:10 | Shayanjm | alloyed: I'm trying to use a sublime plugin that supports nrepl |
| 18:10 | Shayanjm | i tried on lighttable as well |
| 18:11 | Shayanjm | sublime plugin: http://sublimerepl.readthedocs.org/en/latest/ |
| 18:11 | hiredman | serjeem: type checking how? |
| 18:11 | alloyed | lets start super-basic then, what does `lein repl :connect` do? |
| 18:11 | hiredman | serjeem: do you mean inserting instance? checks? |
| 18:11 | Shayanjm | alloyed: while lein ring server is running? |
| 18:12 | serjeem | hiredman: yeah, that’s the idea. |
| 18:12 | serjeem | I run the macro on thing A, it gives me a record A and a constructor, make-a, that “type-checks” the fields in cute ways |
| 18:12 | serjeem | More like contract checking, but I digress |
| 18:13 | alloyed | yeah. usually what happens is the lein-ring starts nrepl, then puts the port number in .nrepl-port, and then you lein autoconnects from that |
| 18:14 | hiredman | serjeem: consider separating jvm notions of types from your contracts |
| 18:14 | Shayanjm | alloyed: lein repl :connect <port> works perfectly. It looks like the sublime plugin is a bit messed up :\ |
| 18:15 | Shayanjm | thanks for the help though |
| 18:16 | serjeem | hiredman: I was hoping it wouldn’t have to come to that, but I think I can work around that. |
| 18:16 | alloyed | np |
| 18:17 | hiredman | serjeem: so if you have type X that fulfills contract Y, and type Z that fullfills contract W, in W instead of saying "field whatever is of type X" you say "field whatever fullfills contract Y" |
| 18:18 | hiredman | serjeem: are you dead set on writing this yourself? there are a number of schemaish clojure libraries |
| 18:18 | hiredman | https://github.com/Prismatic/schema is maybe the most well known |
| 18:20 | serjeem | hiredman: We did a survey of a lot of them and not filled the exact hole we were hoping to fill, unfortunately. |
| 18:21 | serjeem | hiredman: We might have to move closer to your suggestion, or just give up and force a linear ordering on types. |
| 18:22 | serjeem | While contracts serve a similar purpose, we were really hoping that we’d be able to be super strict about the kinds of values we’d find in the schemas. |
| 18:22 | serjeem | What I’d do for one more level of indirection between records and the jvm. |
| 18:23 | hiredman | have you considered using a language with a static type system? |
| 18:23 | hiredman | being really strict about types is just not something you really do in clojure |
| 18:24 | serjeem | I argued a little for haskell at the offset, but clojure was a better fit for the project and the team |
| 18:24 | serjeem | We’re all former racketeers, so there’ve been a few rough patches adjusting to the way clojure does stuff. |
| 18:25 | hiredman | if at all possible, any place you might use a defrecord instance, you should be able to use a map |
| 18:25 | technomancy | yeah records make more sense in racket than they do in clojure |
| 18:25 | serjeem | Yeah, it’s been the #1 element of cognitive dissonance since we started |
| 18:25 | hiredman | the reason defrecord implements so much of the same stuff as maps is try and bridge the worlds, which of course you do completely |
| 18:26 | hiredman | so caring strictly about the type of a thing/map/record is weird |
| 18:27 | serjeem | It makes sense, at least to me, when you look at it from the perspective of building interfaces |
| 18:28 | hiredman | what do you mean by building interfaces? |
| 18:28 | serjeem | even in dynamic languages, I’m used to coming from a world where you just kind of say, “this function expects a foo? and returns a bar?” and having meaningful connotations to foo? and bar? |
| 18:28 | serjeem | in racket, for structured data, you define foo? and bar? as structs. Python and ruby, you’ve got classes |
| 18:29 | yedi | TEttinger2: got that job =D |
| 18:29 | technomancy | serjeem: it's un-idiomatic to rely on classes in ruby too |
| 18:29 | hiredman | serjeem: if foo and map are logically associative bags of data, why create new types? |
| 18:29 | technomancy | you're supposed to check for supporting the specific methods you're interested in |
| 18:29 | hiredman | foo is an associative bag of data with at least an association for :a and :b |
| 18:29 | wheeee | Can anyone tell me what ":injections" does in a lein project.clj? |
| 18:30 | wheeee | I'm looking at this: https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L231-L233 |
| 18:30 | technomancy | wheeee: it's a form that gets included whenever lein evals anything |
| 18:30 | ttasterisco | yedi: where at? :) |
| 18:30 | clojurebot | Titim gan éirí ort. |
| 18:32 | serjeem | hiredman: I’m a very HTDP/design recipe focused programmer, and the first step of that process is describing the data |
| 18:32 | yedi | ttasterisco: http://wit.ai |
| 18:32 | ttasterisco | yedi: oh, the yc company. nice |
| 18:32 | serjeem | when you’re writing production-quality clj, what’s the idiomatic way to say “foo is an assoc. bag containing roughly X Y and Z”? |
| 18:33 | hiredman | serjeem: it depends, but generally a function might look at it's arguments and call any number of predicates on them |
| 18:33 | wheeee | technomancy: Thanks. Does that mean just when lein first starts up or every time it evals anything? Sorry for asking a daft question. |
| 18:33 | hiredman | (doc contains?) |
| 18:33 | clojurebot | "([coll key]); Returns true if key is present in the given collection, otherwise returns false. Note that for numerically indexed collections like vectors and Java arrays, this tests if the numeric key is within the range of indexes. 'contains?' operates constant or logarithmic time; it will not perform a linear search for a value. See also 'some'." |
| 18:34 | hiredman | serjeem: the schema library will actually do that sort of thing for you, I think, I've never used it |
| 18:34 | technomancy | wheeee: it's every time |
| 18:34 | technomancy | wheeee: every time it evals in the project jvm, that is |
| 18:35 | wheeee | Ah, thank you. |
| 18:35 | hiredman | serjeem: have you looked at the typed clojure stuff at all, it lets you define type aliases for maps with certain keys and that kind of thing |
| 18:36 | hiredman | but it doesn't do the runtime checking, it does static type checking |
| 18:36 | akurilin | Random question: do you guys know if there's ever been an effort to support passing the db pool explicitly in Korma? |
| 18:37 | akurilin | Right now it's implicit through the dynamic var you can set |
| 18:37 | serjeem | hiredman: For functions, yeah, but if you’re making, say, an IRC server, you’ll have to keep track of your notion of what a “user” is, for instance. |
| 18:37 | hiredman | serjeem: why? |
| 18:38 | hiredman | actually we use https://github.com/danlarkin/subrosa at work (an irc server written in clojure) |
| 18:38 | serjeem | hiredman: I’ll look into the schema library more, but when I looked at it a few weeks ago it wasn’t 100% what we were looking for. It’ll definitely be a good reference. Last time I looked at typed-clj it didn’t seem production ready. |
| 18:39 | hiredman | sure |
| 18:39 | hiredman | we don't use either of those projects at work |
| 18:41 | serjeem | hiredman: in terms of why, philosphically, the idea is that your program represents, on some level, in an abstract way, the transformation of information |
| 18:41 | hiredman | serjeem: http://www.youtube.com/watch?v=rI8tNMsozo0#t=19m is a nice talk from rich, and around the 19 minute mark he talks a little about types vs values |
| 18:41 | serjeem | bits and bytes and users and game characters and server settings |
| 18:42 | hiredman | serjeem: exactly, but the types of data we manipulate are finite, mostly associative things |
| 18:42 | serjeem | and in order to make sense of the chaos of the universe, we peel away kinds of chunks information into numbers and strings and chars and maps and vectors etc |
| 18:43 | serjeem | and the idea is that when you’re writing actual software, the data that you’re dealing with isn’t just simple languge-provided values |
| 18:43 | hiredman | serjeem: the thing is, you can write generic transforms over associative maps easily |
| 18:43 | hiredman | serjeem: not over custom types |
| 18:43 | serjeem | but often something that models in some way some kind of facet of the real world, or some abstract value of something |
| 18:43 | hiredman | (well, not without haskells type system) |
| 18:44 | serjeem | and it makes sense to say, “okay, this think I’m working with is at least conceptually made up of X Y and Z” |
| 18:44 | hiredman | serjeem: it doesn't though |
| 18:44 | serjeem | you don’t necessarily need like a type system to enforce it, but you should have some way to communicate it to others |
| 18:44 | hiredman | serjeem: plenty of simulations and models exist as rows in a spread sheet |
| 18:44 | hiredman | no types for different kinds of things to be found |
| 18:45 | hiredman | simulating the world by mapping it to types is the most primitive type of simulation |
| 18:45 | serjeem | those rows most often have, like, labelled columns, right? |
| 18:45 | serjeem | it’s not just rows of arbitrary information |
| 18:45 | hiredman | serjeem: sure, and maps have keys and values |
| 18:45 | serjeem | see, for instance, the IRC server you linked |
| 18:45 | serjeem | The IRC server you linked, for instance, does this here: https://github.com/danlarkin/subrosa/blob/master/src/subrosa/server.clj |
| 18:46 | hiredman | aphyr has a nice post about modeling somewhere |
| 18:46 | serjeem | it gives you a description of what it expects users, rooms, user-in-rooms, and the server to be |
| 18:46 | hiredman | serjeem: sure, but it doesn't define types, it just says it is some kind of associative thing with these kinds of things in it |
| 18:46 | serjeem | yeah! that’s all I’m saying |
| 18:47 | hiredman | http://aphyr.com/posts/312-clojure-from-the-ground-up-modeling |
| 18:47 | serjeem | the types are just one way to describe the data |
| 18:47 | hiredman | they generally are not though |
| 18:48 | hiredman | defrecords are slightly better than other "types" at this |
| 18:48 | hiredman | but generally every type ends up with its own mini-dsl for reading and writing its data |
| 18:49 | hiredman | maps also have a dsl/api, assoc, dissoc, get, but it applies to all maps |
| 18:49 | hiredman | so if you model everything as maps you can use the same api and create truelly generic data transforms |
| 18:51 | hiredman | I am just trying to convey clojure's generally lean, you can do things differently, but you are going to be fighting the language, so why using the language? |
| 18:52 | hiredman | (also I just really like http://aphyr.com/posts/312-clojure-from-the-ground-up-modeling) |
| 18:53 | serjeem | (I really like that post, too, thanks for linking it!) |
| 18:53 | serjeem | I also really agree that the map api is _fantastic_ in clojure. all of the core datastructure apis are |
| 18:54 | serjeem | and I very much appreciate that the language is lean, and that it makes it wonderful to work with |
| 18:54 | serjeem | it’s seriously a dream |
| 18:54 | hiredman | well, that'll wear off :) |
| 18:54 | serjeem | but one of the great things I love about lisps is that you can leverage them and contort them to your bidding when you need to |
| 18:54 | serjeem | :P |
| 18:55 | tuft | i always struggle with when and if to defrecords |
| 18:55 | tuft | or to use protocols for that matter |
| 18:56 | cbp | if you're in doubt don't use them |
| 18:56 | tuft | always wonder how much it is just to get classes implementing methods at the bytecode level |
| 18:56 | tuft | yeah, seems like you can get along fine without |
| 18:56 | serjeem | after about half a year of using clojure, defrecords seem like the harriest part of the whole langauge |
| 18:56 | tuft | also seems like most of the libraries i pick up make use of them |
| 18:57 | cbp | protocols are nice for client-facing apis |
| 18:57 | hiredman | cbp: the opposite |
| 18:58 | cbp | ahhhh? |
| 18:58 | tuft | cbp: better than simple generic functions / multimethods? they seem really similar in function |
| 18:58 | tuft | i assume you're talking about extension points |
| 18:58 | hiredman | cbp: they are create for spis, you have a library that can be backed via anything that implements some protocol |
| 18:58 | hiredman | the client api is functions implemented on top of the protocol |
| 18:59 | hiredman | the great for |
| 18:59 | hiredman | they are |
| 18:59 | hiredman | ugh |
| 19:00 | hiredman | a big thing that is missing in clojure is some kind of module/compile time polymorphism, so protocols often get abused for that |
| 19:00 | serjeem | +1 to that |
| 19:00 | hiredman | something like mls functors |
| 19:01 | hiredman | (I think, I mean, I don't have much experience with those) |
| 19:01 | serjeem | If clojure could eat rackets heart, and grow three new limbs (really good macros, module system, better docs), it would take over the world |
| 19:01 | serjeem | [and maybe a fourth limb for non-sucky struct/records :P] |
| 19:01 | tuft | is there a benefit to protocols over multimethods beyond performance for that kind of extension point? |
| 19:03 | hiredman | protocols group the functions together which is nice |
| 19:03 | adu | sounds like ObjC |
| 19:03 | hiredman | multimethods bringing in the whole complicated isa? machinery which I've never really seen used |
| 19:04 | tuft | hiredman: yeah i guess that's one difference -- it's all or nothing |
| 19:04 | hiredman | tuft: actually no, you can selectively implement parts of a protocol |
| 19:04 | tuft | oh, hrm |
| 19:04 | hiredman | but don't |
| 19:04 | amalloy | you're not really supposed to |
| 19:04 | amalloy | it's possible, but not for any good reason |
| 19:05 | tuft | it always feels like a little bit of a let-down when the CamelCase symbols creep into your code for non interop purposes |
| 19:05 | cbp | >_> |
| 19:06 | Lanny | perhaps you mean a letDown |
| 19:06 | tuft | heh |
| 19:06 | tuft | :let-down |
| 19:08 | ttasterisco | serjeem: what do you mean by module system? |
| 19:08 | hiredman | something like parameterized namespaces |
| 19:09 | serjeem | ttasterisco: namespaces on ‘roids, a ‘la i.e. racket http://docs.racket-lang.org/reference/module.html?q=module#%28form._%28%28quote._~23~25kernel%29._module%29%29 |
| 19:09 | serjeem | haskell’s got a meh one as well, sml had a fantastic one that programming languages have been trying to emulate for decades |
| 19:11 | hiredman | like, if you have a "genric" namespace full of array operations that will work on any type of arrays as long as you give it a 'get and 'set for the given type of array, it would be nice you be able to say foo is an instance of the generic namespace with get and set for long arrays |
| 19:12 | hiredman | and you just call the functions from foo, and there is no polymorphism |
| 19:12 | serjeem | oh god if this works I don’t think anyone should ever let me touch a macro again: `(-> ~(keyword typ) str symbol resolve) |
| 19:12 | technomancy | serjeem: use "name" instead of keyword+str |
| 19:13 | serjeem | technomancy: good point :P |
| 19:14 | serjeem | OMG IT WORKS |
| 19:14 | serjeem | i am an awful person |
| 19:14 | ttasterisco | anyone here using the latest version korma (0.3.2)? I'm getting a really weird bug where (fields ...) isn't filtering the selection but actually adding a repeated field |
| 19:18 | ttasterisco | (hm, actually happening with all versions > 0.3.0-RC7) |
| 19:18 | ttasterisco | *>= |
| 19:34 | akurilin | Schema question: is it possible to only enforce a certain subset of keys of a map as mandatory and ignore the rest of them? |
| 19:35 | aperiodic | akurilin: not really. you can have keys be optional but you have to explicitly list them; any keys not in the schema will cause an error |
| 19:35 | akurilin | Ok. Sad. |
| 19:38 | aperiodic | akurilin: actually, you can do it with something like {s/Keyword s/String, :required s/String} |
| 19:42 | akurilin | What does that do, not sure I can quite figure it out from reading that |
| 19:43 | aperiodic | allows any keyword keys in the map, and requires :required to be present. maps will only fail to match it if they don't have :required (or if they have any non-keyword keys) |
| 19:45 | TimMc | serjeem: What's an example of something that prismatic/schema didn't have? |
| 19:45 | TimMc | We're using it for a project, so it would be good to know. |
| 19:46 | serjeem | TimMc: i could be totally wrong, but t didn’t seem to have a super solid datomic integration story |
| 19:46 | serjeem | which is 1/2 - 2/3 of what we needed out of the schema stuff we wanted to have |
| 19:46 | TimMc | Hmm, how so? (I haven't used datomic, so this may be difficult to explain to me...) |
| 19:47 | TimMc | And is extending it not an option? |
| 19:48 | akurilin | aperiodic: ah that makes ense, thanks |
| 19:48 | serjeem | TimMc: The hole the package I’m writing fills is, “Our program needs to deal with and describe data that we store in Datomic and manipulate with clj”. prismatic/schema has the second half down pat, but it’s muddy on the first |
| 19:48 | akurilin | aperiodic: if you don't mind me asking, how do you force schema to check if a val of a key isn't nil? I'm using pred in mine |
| 19:49 | serjeem | I could probably extend prismatic/schema, but I figured it’d take me just as long to hack a 200LOC library, while also reconning valuable experience with the SeqEx library and some macro magic for the team |
| 19:51 | aperiodic | akurilin: I think a predicate schema is the way do to it. you can (def ButNil (s/pred (complement nil?))) and then use ButNil in your schema, to cut down on the verbosity a bit. |
| 19:52 | serjeem | That said, and as a general note, seqex is freaking fantastic |
| 19:52 | serjeem | I hope it doesn’t go the way of the dodo, because it makes writing macros fun again |
| 19:52 | tuft | serjeem: i have a similar stack, but i don't quite understand what you mean -- are you having to describe data twice? |
| 19:53 | tuft | i'm now going to have datomic schema, prismatic/schema and test.check generators. seems like there should be something to unif |
| 19:53 | tuft | unify |
| 19:53 | akurilin | aperiodic: That's a great trick actually, thanks! |
| 19:53 | serjeem | tuft: yeah, we have to write everything twice |
| 19:53 | serjeem | which I justify as “double-entry data keeping" |
| 19:54 | serjeem | but really just saves sanity w/r/t db migrations, which is something that would terrify me with a single, non-datomic schema |
| 19:54 | tuft | ah hmm |
| 19:54 | tuft | yeah seems like you should be able to derive one from the other |
| 19:55 | tuft | .. and of course not everything with a prismatic/schema will be persisted |
| 19:55 | serjeem | you can, and https://github.com/Yuppiechef/datomic-schema seems to |
| 19:56 | serjeem | but the idea makes me a little uncomfortable, i dunno |
| 19:56 | serjeem | that said, I wish everything was just protobufs and we’d never have to worry about anything ever again forever~~ |
| 19:57 | hiredman | I've seen code snippets on github to, uh, I think it was generate core.typed declarations from datomic schemas (it could have been the other way around) |
| 19:57 | tuft | yeah i'm using datomic-schema too, incidentally |
| 19:57 | serjeem | tuft: has it been working well? |
| 19:58 | serjeem | hiredman: is core.typed production-ready yet? |
| 19:58 | hiredman | https://gist.github.com/c-spencer/6569571 |
| 19:58 | serjeem | I’ve got about 5 files I’d love to move to it |
| 19:58 | hiredman | serjeem: I dunno |
| 19:59 | tuft | serjeem: i did run into one problem with its strange use of atoms |
| 19:59 | hiredman | huh, that is literally storing type information in datomic |
| 19:59 | tuft | serjeem: i think it should inspect interned vars instead -- messes up when you're doing redef in the repl |
| 20:00 | tuft | prismatic/schema and core.typed seem somewhat orthogonal to me |
| 20:01 | tuft | as in, seems like you'd pick one or the other. static or test driven "type" checking |
| 20:02 | serjeem | It’d be nice to get a mix |
| 20:03 | serjeem | I’d like to know that a bunch of important functions are type checked, and my data is all what I expect to be on a type-level |
| 20:03 | serjeem | but I’d also like to have functionality around metadata associated with different fields in a schema |
| 20:04 | serjeem | like in the thing I’m writing, things can get default values, certain fields can have preconditions on them, etc |
| 20:05 | serjeem | which is stuff you can’t get outside of like, agda maybe |
| 21:05 | benkay | hey y'all - i'm about to start some capacity analysis of a Ring app i derped out recently, and would like to profile it at the same time. is an acceptably professional approach to implement Timbre and siege the thing on a VPS? |
| 21:12 | amalloy | timbre seems silly, use a real profiler |
| 21:12 | amalloy | eg yourkit, jvisualvm |
| 21:13 | benkay | timbre:midje::core.test:{jvisualvm,yourkit} ? |
| 21:14 | benkay | er |
| 21:14 | bbloom | amalloy: i haven't used timbre, but instrumented tracing is extremely valuable for many applications |
| 21:15 | benkay | timbre:{jvisualvm,yourkit}::midje:core.test ? |
| 22:33 | danielcompton | I found timbre not very useful with threaded code |
| 22:44 | blaenk | (ns a (:require [clojure.string :as str :refer [replace]])) |
| 22:44 | blaenk | what's the point of :refer there? |
| 22:44 | blaenk | so make it so I can use clojure.string/replace unqualified? |
| 22:44 | blaenk | s/so/to |
| 22:45 | blaenk | if that's the case, then it's like :only? |
| 22:46 | blaenk | oh I think I see, it seems like it is, that way one doesn't have to use :use |
| 22:47 | mange | blaenk: Correct. :use/:only is the same as :require/:refer, but (:use x) is the same as (:require [x :refer :all]) |
| 22:47 | blaenk | thanks mange |
| 22:49 | blaenk | how about translating (:use (clojure zip xml)) to use require, refer, all; would I not be able to use the prefix notation? |
| 22:50 | blaenk | (:require (clojure [zip :refer :all] [xml :refer :all])) ? |
| 22:52 | Demosthenes_ | hello? |
| 22:52 | clojurebot | BUENOS DING DONG DIDDLY DIOS, fRaUline Demosthenes_ |
| 22:52 | Demosthenes_ | am I in the right place? |
| 22:52 | Frozenlock | No |
| 22:52 | Frozenlock | You should leave |
| 22:52 | Demosthenes_ | What a great community |
| 22:53 | dbasch | Demosthenes_: it depends, if you're looking for #clojure then you are |
| 22:54 | Demosthenes_ | Anyways, I had a reason for coming here. Why does the contains? function not work for in the case (contains? [:a :b :c] :b)) |
| 22:54 | serjeem | (doc contains?) |
| 22:54 | clojurebot | "([coll key]); Returns true if key is present in the given collection, otherwise returns false. Note that for numerically indexed collections like vectors and Java arrays, this tests if the numeric key is within the range of indexes. 'contains?' operates constant or logarithmic time; it will not perform a linear search for a value. See also 'some'." |
| 22:54 | Demosthenes_ | I know the clojuredocs give the reason that "contains is only for indices" but it doesn't make sense to me |
| 22:54 | mange | blaenk: I didn't know it, but apparently (:require [clojure [walk :refer [prewalk]] [test :as test]]) does work. Cool! |
| 22:55 | dbasch | Demosthenes_: contains? does not do what you want for arrays |
| 22:55 | serjeem | Demosthenes_: the reason is that (contains? c k) looks only at the keys, not the values, of c, and compares them to k |
| 22:55 | blaenk | so I guess that's how that would be translated huh |
| 22:56 | serjeem | so, e.g. (contains [:a :b :c] 1) works, since 1 is a key in that vector |
| 22:56 | Demosthenes_ | ah thanks serjeem |
| 22:56 | ddellacosta | Demosthenes_: if you want to find a value try something like |
| 22:56 | blaenk | (:use (prefix some thing)) becomes (:require (clojure [some :refer :all] [thing :refer :all])) |
| 22:56 | ddellacosta | &(filter #(= :a %) [:a :b :c]) |
| 22:56 | lazybot | ⇒ (:a) |
| 22:56 | serjeem | you're probably looking for something more like (first (find #(= v %) col) |
| 22:56 | Demosthenes_ | what is the %? |
| 22:56 | serjeem | ddellacosta: beat me to it! |
| 22:57 | ddellacosta | Demosthenes_: it is the argument getting passed to the function. Here's an alternative synta: |
| 22:57 | ddellacosta | *syntax |
| 22:57 | ddellacosta | &(filter (fn [v] (= v :a)) [:a :b :c]) |
| 22:57 | lazybot | ⇒ (:a) |
| 22:57 | Demosthenes_ | oh I see |
| 22:57 | Lanny | is there a syntax for multiple arguments |
| 22:57 | Demosthenes_ | ty |
| 22:57 | Lanny | and how does one google docs for "#()" |
| 22:57 | ddellacosta | Demosthenes_: np |
| 22:58 | ddellacosta | Lanny: yeah, you can do |
| 22:58 | ddellacosta | &(reduce #(assoc %1 %2 :foo) {} [1 2 3]) |
| 22:58 | lazybot | ⇒ {3 :foo, 2 :foo, 1 :foo} |
| 22:58 | blaenk | Lanny: just search for clojure lambdas or anonymous functions |
| 22:58 | ddellacosta | for example |
| 22:58 | ddellacosta | whoops, backwards |
| 22:58 | ddellacosta | &(reduce #(assoc %1 :foo %2) {} [1 2 3]) |
| 22:58 | lazybot | ⇒ {:foo 3} |
| 22:58 | ddellacosta | well, that's a dumb function |
| 22:58 | ddellacosta | but you get the picture hopefully |
| 22:59 | cbp | Lanny: http://clojure.org/reader |
| 22:59 | dbasch | you could also do |
| 22:59 | Lanny | nifty, thanks |
| 22:59 | dbasch | ,(filter #{:a} [:a :b :c]) |
| 22:59 | clojurebot | (:a) |
| 22:59 | dbasch | ,(filter #{:d} [:a :b :c]) |
| 22:59 | clojurebot | () |
| 23:06 | platz | where in the documentation do I find that set can be used as a Fn? |
| 23:07 | platz | or just something you learn an memorize |
| 23:08 | platz | I mean I know it's on clojure.org somewhere |
| 23:08 | platz | but there probably isn't an wasy way to find out via the repl (doc) |
| 23:08 | dbasch | platz: http://clojure.org/data_structures#Data Structures-Sets |
| 23:09 | platz | dbasch: ah, thanks - reading now |