#clojure logs

2014-07-02

00:18nexIm 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:18nexorm to those sets
00:20ambrosebsnex: tools.analyzer only collects enough information to inform the emitter of reflection stuff.
00:21ambrosebsnex: your idea of annotating a set of known return types is a good one.
00:23nexambrosebs: i wouldnt mind the effort, but it would be a lot better to be able to do this on arbitrary fns.
00:24ambrosebsnex: you'd need to write a type inferencer then, probably based on success typing like dialyzer
00:25ambrosebsso, not trivial
00:25ambrosebsyou could kinda use core.typed, but gradual typing is much more annoying to do arbitrary analysis with.
00:25ambrosebssuccess typing is forgiving.
00:28ambrosebsalso it depends what you're actually using this for?
00:28nexambrosebs: 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:29ambrosebssure, but we don't know how to do type checking on arbitrary clojure code yet.
00:29ambrosebscore.typed is the best bet so far.
00:29ambrosebsthat's best described as a subset of clojure
00:30fitzohAnyone 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:31nexambrosebs: 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:33nexambrosebs: 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:34icmaanyone know why I can't require clojure.contrib.trace? https://gist.github.com/anonymous/38f34eddc3fc0430aa59
00:35puredangerclojure.contrib.trace is part of the old "monolithic contrib" used prior to Clojure 1.3
00:36puredangerhttp://dev.clojure.org/display/community/Where+Did+Clojure.Contrib+Go
00:36puredangerthe trace stuff is now in https://github.com/clojure/tools.trace/ which is a library you will need to include in your project
00:37icmapuredanger: excellent. thanks.
00:38ambrosebsnex: 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:39rufoafitzoh: (defn f [k v m] (update-in m [:root] (fn [ms] (map #(assoc % k v) ms))))
00:39ambrosebsicma: where did you hear about contrib.trace btw?
00:40fitzohrufoa: awesome, ty
00:40rufoanp
00:41icmaambrosebs: not sure anymore. lost the page. I was just searching for "clojure deftrace" and "deftrace".
00:42ambrosebsicma: ok
00:44mangezanes: 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:14amalloyvery impressive, bbloom
01:26yediwhat are some things you must know if you;re going to interview for clojure position
01:34TEttingeryedi: what does this type hint mean: ^"[[Z"
01:34yediO_O
01:34TEttingerhehe
01:35TEttingerit's a 2d boolean array
01:35puredangerarray of array of boolean
01:35TEttingeryou won't need to know that unless you work at prismatic...
01:35puredanger[ = array, Z = boolean
01:37TEttingeryedi, 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:39TEttinger(___ __ _ [[1 2][3 4][[5][6]]])
01:39TEttingerfill in some blanks
01:40TEttingerit should return [1 2 3 4 [5] [6]]
01:42razum2umwhen i start a new clj new should i prefer dashed-name or underscore_name ?
01:42razum2umi mean lib name
01:43razum2umah, I see only dashes here http://crossclj.info/
01:45yediTEttinger: I feel like I can do it iteratively but filling in those blanks is a different story
01:45yedioh wait
01:45yedireduce into []
01:45TEttingeryep!
01:45TEttingernice
01:45TEttingerthat's a good trick
01:46amalloywell, apply concat is more typical than reduce into [] there
01:46TEttingerwell true
01:46amalloydepends what data type you want back
01:46TEttingerI mostly used it for maps
01:46TEttingerso I never really got used to apply concat
01:47ivanhttps://www.refheap.com/9d8f8ea4d4d4f8bdbed6c817c/raw nrepl woes
01:48TEttingerivan, it is failing to eval /1, then it evals 2 on the next line
01:48ivan(I'm fixing a few things in REPL-y's standalone REPL and looking a lot at what nREPL and clojure.main do)
01:48TEttingerso it isn't returning 24, it's 2 then 4 and the real value is 4
01:49ivanyeah, I know that much :)
01:49TEttingermaybe just stick a newline after that stuff
02:18akurilinRandom 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:52ttasteriscoakurilin: I structure my projects roughly following Amit's DDD http://www.infoq.com/presentations/DDD-Clojure
03:00akurilinttasterisco: I'll check that video out, seems relevant :)
03:03clgvttasterisco: is that only a "conceptual" talk. the slides seemed very spartanic when browsing through
03:03clgv?
03:06ttasteriscoclgv: it's mostly conceptual but he goes into the practicalities close to the end
03:07ttasteriscoI felt that his presentation at the SF Clojure meetup last year was more direct
03:12magopian,(Character/isWhitespace "a")
03:12clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: No matching method found: isWhitespace>
03:12amalloymagopian: \a
03:12magopian?
03:13ttasteriscocharacter
03:13ttasterisconot string
03:13magopianohhh
03:13magopianit's my python background ;) (no difference between a char and a one-char string ;)
03:13magopianthanks
03:16magopian,(every? :nothing nil)
03:16clojurebottrue
03:16magopian,(every? :nothing "")
03:16clojurebottrue
03:17magopian(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:17magopian(but seems that "every?" returns true for those cases, so it works the same... weird though, that every? returns true for nil/empty)
03:17magopian,(some? :nothing "")
03:17clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (2) passed to: core/some?>
03:18magopian,(some? :nothing nil)
03:18clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (2) passed to: core/some?>
03:18magopian,(not-any? :nothing nil)
03:18clojurebottrue
03:19amalloymagopian: every object in the empty collection is equal to five, and equal to six, and...
03:19amalloyfeel free to find a counterexample
03:21clgvmange: yeah thats the mathematical definition of the all quantifier
03:22clgvmagopian: ^^
03:22magopianyup ;)
03:22clgvthe exist quantifier alas `some` returns nil meaning false ;)
03:23clgvfor empty collections
03:27magopianclgv: that's what i'm looking at atm ;)
03:36magopianare the books on it-ebooks really free... or pirated?
03:37magopianbecause i can see a lot of cloure books on there, downloadable for free
03:37magopianclojure*
03:41ambrosebsmagopian: what's on there?
03:43magopianambrosebs: http://it-ebooks.info/tag/clojure/
03:43ambrosebsI don't particularly want to click
03:45magopianambrosebs: i'm sorry, i don't understand your question
03:45magopianthere's a list of most (all?) of the clojure books I heard of
03:45magopianfreely downloadable
03:45magopianbut... dunno, the site doesn't look legit, so i'm wondering if those are "stolen"
03:46magopiani've seen at least some of those ebooks sold in various places, so having them freely downloadable here feels strange
03:48ambrosebsright, must be pirated.
03:50magopianambrosebs: ah, thanks
03:51magopiani'll buy/download the ebooks from the publisher's sites
03:52magopianambrosebs: which book would you recommend ?
03:53ambrosebsmagopian: I like Clojure Programming or Joy of Clojure
03:54magopianthanks again
03:57clgvmagopian: yeah those are not legally available without payment
03:58clgvmagopian: the decision between "Clojure Programming" and "Programming Clojure (2nd edition)" depends on what style of book you like
04:01magopianclgv: ah... can you tell me a bit more?
04:04clgvmagopian: 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:05magopiani see
04:05clgvso in fact reading both probably has a complementary effect. I'd read the available sample chapters to decide which style I like most
04:39magopianclgv: that's what i'm doing right now ;)
04:58magopianclgv: i went with programming clojure, bought on pragprog, thanks for the advices!
04:59clgvmagopian: glad to help :)
05:53sveriHi, did anyone here do authentication with websockets or sente and http-kit? Are there any best practices or examples available?
05:55erghdoes clojure have a neat way to say "give me a vector of this value n times"?
05:58erghoh, "(take 10 (repeat 1)" works. i knew there was something :p
05:58Bronsa.(repeat 10 1)
05:59Bronsa,(repeat 10 1)
05:59clojurebot(1 1 1 1 1 ...)
06:01erghBronsa: oh that's better, thanks
07:25rurumateis there an easy way to call a private method of a java object?
07:25stain_I believe you may have to introspect and make the method public
07:26rurumatethere used to be method-call in contrib.reflect or something but I can't find it in clojure.refect
07:29clgvhmm the seesaw :popup property seems broken. at least the examples from the code base wont work ... :(
07:39clgvdamn, the copied example works. but not the analogue one in the codebase...
07:49perplexahai
07:53perplexawhat's considered the best practice to handle configurations in clojure?
07:55cmdrdats1perplexa: 'best practise' is pretty subjective - but I would recommend http://12factor.net/config - regardless of language
07:56perplexayeah but that's really meta :P
07:56cmdrdats1not really - just use environment variables
07:56perplexai won't.
07:56perplexanobody wants a complete config in environment vars
07:57cmdrdats1ok - hence subjective :)
07:57perplexathat works when you want to override single parameters
07:57perplexabut having like 50 params completely in the environment violates the whole point of having a config
07:58perplexai'm just not sure whether i should go for yaml or propertiy files
07:58cmdrdats1environments can be entirely localised to process though?
07:58perplexaand how to properly access the params from within clojure
07:58Janiczekperplexa: EDN instead of yaml maybe?
08:00perplexathat looks good :)
08:01razum2um1perplexa: look at https://github.com/weavejester/environ it uses EDN-like .lein-env file as config
08:01razum2um1but also accepts ENV
08:05sveriHi, did anyone here do authentication with websockets or sente and http-kit? Are there any best practices or examples available?
08:06perplexarazum2um1: thx
08:51perplexahm. 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:52perplexaany ideas why that is, or how i would properly do what i'm trying to do?
08:58justin_smithperplexa: how are you accessing the property-file? as a resource or as a file?
08:58justin_smithin a jar, you should probably use clojure.java.io/resource
08:59jcromartieperplexa: why don't you use alter-var-root ?
08:59justin_smithor, at least, (def config) rather than (def config nil)
09:00perplexajava.io.reader ;p
09:00justin_smithperplexa: a reader of what though?
09:00perplexajcromartie: cos i have no idea what you are telling me :D
09:00justin_smitha resource or a file or a URI?
09:00perplexaneed to check
09:00jcromartieperplexa: BTW *ns* is bound to the namespace of the caller
09:00jcromartie,(do (ns foo) (defn bar [] (println *ns*)))
09:00clojurebot#'foo/bar
09:01perplexajustin_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:01jcromartie,(ns user)
09:01clojurebotnil
09:01jcromartie,(foo/bar)
09:01clojurebot#<Namespace sandbox>\n
09:01perplexajcromartie: yeah i expected that. so when i run the jar, it might just intern the var in the wrong place
09:01justin_smithperplexa: oh, so you are running the uberjar in a place where that file is guaranteed to exist?
09:01perplexajustin_smith: yep
09:01perplexareading works, just overwriting my config def doesn't
09:02justin_smithOK, yeah, then it is likely some AOT binding of the var value
09:02jcromartieperplexa: instead, do this: (alter-var-root #'my.main.ns/config (constantly (load-config …)))
09:02justin_smithyeah, this is what alter-var-root is for
09:02perplexajcromartie: thanks!
09:02perplexa(inc jcromartie)
09:02lazybot⇒ 7
09:02jcromartieI'm currently grappling with config woes
09:03jcromartiewe used to load it all from a file
09:03jcromartiebut then devops said we couldn't upload config files willy-nilly
09:03jcromartieso now we read it all in from env vars
09:03perplexaeeww :x
09:03jcromartiewell it makes sense
09:04perplexaone more thing
09:04justin_smithjcromartie: I find having some abstraction for binding config that both files or other config loading methods use in common is helpful
09:04perplexawhy (constantly)?
09:04justin_smiththis also makes testing easier
09:04jcromartieyeah
09:04justin_smithperplexa: because alter-var-root acts on the previous value
09:04jcromartiewe're using environ
09:04perplexajustin_smith: wat
09:04jcromartieand I have a config namespace and a defconfig macro that enables a config check
09:04jcromartieso in the config namespace we use (defconfig api-url :parser parse-url) etc.
09:05justin_smith,(do (def x "hello") (alter-var-root x #(str % " world!")) x)
09:05clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.Var>
09:05jcromartieand then we can run (check-config) to assert that there are no missing config values
09:05justin_smitherr
09:05justin_smith,(do (def x "hello") (alter-var-root #'x #(str % " world!")) x)
09:05clojurebot"hello world!"
09:05justin_smithperplexa: that^
09:06jcromartieand (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:07perplexajustin_smith: i still don't get it :)
09:07perplexa,(do (def x "hello") (alter-var-root #'x "replaced ;p") x)
09:07clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn>
09:07jcromartieperplexa: 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:08perplexaah
09:08jcromartie,(def x)
09:08clojurebot#'sandbox/x
09:08perplexathe function part was the missing puzzle piece :)
09:08jcromartie,x
09:08clojurebot"hello"
09:08perplexathx
09:08jcromartiek
09:08jcromartie,#'x
09:08clojurebot#'sandbox/x
09:08jcromartie,(var x)
09:09clojurebot#'sandbox/x
09:09jcromartie,(deref (var x))
09:09clojurebot"hello"
09:09jcromartie,(deref (var sandbox/x))
09:09clojurebot"hello"
09:09clgv,(-> "x" symbol resolve deref)
09:09clojurebot"hello"
09:12perplexajcromartie: we're just migrating our aggregations from old perl+sql shizzle to cascalog ;x
09:12jcromartieawesome
09:13perplexaand i'm trying to build a rather flexible bootstrapping framework around that, so have it integrate easily with our other etl processes ;x
09:14jcromartieIf I may suggest having: config values actually defined as vars in a namespace is really useful
09:14jcromartieerr, that
09:14jcromartiethat colon was supposed to go after "suggest"
09:15perplexai seem to miss the point
09:15jcromartiebut anyway, it's better to get a load-time "unable to resolve symbol" error than to have a mysterious nil at runtime
09:21Glenjaworki tend to have an (env!) function, which throws when the key doesn't exist
09:22Glenjaworkand tells me what environment variable it wanted
09:36perplexai hate it when code runs in the repl but not as jar :|
10:05clgvperplexa: that's a clear sign that you did something wrong ;)
10:05perplexaException in thread "main" java.lang.RuntimeException: Invalid token: /user/camus/output
10:05perplexa:|
10:05perplexayeah clgv :P
10:06clgvwell probably not a string?
10:06perplexawell
10:06perplexa(defn mk-src [in-path schema-path fields]
10:06perplexa (println "fufufu" (str (:aggregations.input.base (cached-props)))))
10:06perplexashould be a str ;p
10:06perplexaand works fine in repl
10:07clgvno the error messages sounds as if you inserted the path literally and not as a string
10:07perplexathe path is (:aggregations.input.base (cached-props))
10:07perplexaand it's a symbol
10:07perplexabut (str ...) works locally at least ;/
10:11augustlperplexa: (cached-props) - that's not an argument to that function? :)
10:12augustlperplexa: do you get the error on the call to str, or the call to println, or something else?
10:13augustlseems 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:13augustlg2g
10:14clgvas I said I get the error when I just enter that path into the REPL => RuntimeException Invalid token: /user/camus/output
10:14perplexaaugustl: yeah it's the argument
10:14clgvso that path is actually read somewhere by clojures read where it probably should be specified as string
10:14clgvperplexa: ^^
10:15clgv,/user/camus/output
10:15clojurebot#<RuntimeException java.lang.RuntimeException: Invalid token: /user/camus/output>
10:15clgv,"/user/camus/output"
10:15clojurebot"/user/camus/output"
10:15clgv^^
10:15perplexai know.
10:16clgvwell then fix it by making it a string or deleting the occurence ;)
10:17perplexait's not that easy
10:17perplexai'm always converting it to a string
10:17perplexawhen passing it to other calls
10:17perplexai just don't get why it works in repl but not when i run the jar
10:18clgv,(type (read-string "/user/camus/output"))
10:18clojurebot#<RuntimeException java.lang.RuntimeException: Invalid token: /user/camus/output>
10:19clgv,(type (read-string "/user"))
10:19clojurebot#<RuntimeException java.lang.RuntimeException: Invalid token: /user>
10:19clgv,(type (read-string "user"))
10:19clojurebotclojure.lang.Symbol
10:20clgvah right it is not even a legal symbol, so in this phase the reader fails
10:20perplexawtf
10:20perplexayeah locally i use a different config.. which does start with hdfs://
10:21clgvyou 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:21perplexa,(type (read-string "hdfs:///user/camus/output"))
10:21clojurebotclojure.lang.Symbol
10:21perplexa:|
10:21clgvthere is no meaningful reason why that should be specified as symbol
10:23perplexaclgv: 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:25puredangercglv: looks like a symbol to the reader :)
10:25ndpperplexa: Could it be that you're missing quotes in the string itself? ex: (read-string "\"foo\"")
10:25ndp,(type (read-string "\"foo\""))
10:25clojurebotjava.lang.String
10:25clgvpuredanger: what do you mean? (I was just investigating whether the read fails on trying to read it as symbol)
10:26perplexandp: see the link that i just pasted :)
10:26perplexai should probably just switch to edn and have proper values
10:26clgvperplexa: if that really happens on Properties/load you should see it in the stacktrace
10:27perplexaclgv: yes it does
10:27perplexaat properties$load_props.invoke(properties.clj:8)
10:27clgvperplexa: ah no I spotted the read-string in the code
10:27clgvjust surround the path in the conifg with ""
10:27clgvas I told you all the time :P
10:28perplexayeah but it shouldn't be like that :|
10:28ndpI 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:28ndpSo, let's try this:
10:28perplexalike, that's not really how a property file should work :)
10:28clgvperplexa: well then don't use read-string there
10:28ndp,(type (read-string "[\"foo\", \"bar\"]"))
10:28clojurebotclojure.lang.PersistentVector
10:29clgvperplexa: perplexa: do you really want to specify clojure data structures in the property file?
10:29perplexaclgv: nope, but scalars, like doubles, strings, ints. that would be good.
10:29clgvperplexa: that would not be really how a property file should work as well ;)
10:29perplexai'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:30clgvperplexa: then just skip the read-string for non-numeric read texts
10:30gfredericksis there a library somewhere for combining several defn'd functions into a single -main that dispatches on the first arg?
10:30clgvperplexa: you will need to wrap the path in "" in edn as well :P
10:30gfredericksI've got an ad hoc one in my latest project and might make it a lib if it makes sense
10:31ndpYou're going to have to quote the path whether you use EDN or not
10:31clgvgfredericks: a comp-main macro?
10:31perplexaclgv: yeah but it's a different format in general :) a property file shouldn't break when you put paths without quotes in them.
10:31perplexai'm fine with quotes in edn ;p
10:32ndpThe property file didn't break, your postprocessing did =)
10:32clgvperplexa: well you are not reading it as property file because of your read-string usage, that the reason
10:32ndpThe other option is to wrap your read-string in a try-catch and ignore the exception
10:32perplexaclgv: yep
10:33perplexaor just drop read-string completely and replace it with something that returns proper types based on regexes :)
10:33gfredericksclgv: doesn't have to be a macro it could be var-based
10:33gfredericksclgv: my current version just looks in the current namespace for vars with :command metadata
10:33clgvgfredericks: oh are you building a complete -main with tools.cli that way?
10:34gfredericksumms
10:34gfrederickshadn't decided the scope yet
10:34gfrederickshandling the subsequent args is complicated :(
10:34clgvthat would indeed be an awesome shortcut for default use cases ;)
10:35clgvgfredericks: if not position you mean?
10:35clgv*positional
10:35gfredericksyeah
10:35gfredericksit could have a hook for providing a function from [String] -> [Object]
10:35gfrederickswhich would let you do arbitrary things
10:35gfrederickslike hook in tools.cli
10:35clgvjust make them named as tools.cli offers you
10:36gfredericksbut the main point is to let you have different tasks spread around different defns
10:37gfredericksthe current approach is you put ^:command on the defn and the main bit finds it that way
10:37clgvlein run -- awesome-calc 42 23 => calling (awesome-calc 42 239 ?
10:37gfredericks(awesome-calc "42" "239")
10:37clgvah right ;) could be with conversion if you parse the arg meta
10:38gfredericksyeah don't know how far to take it
10:41yeoj___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:44clgvgfredericks: 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:44clgvgfredericks: that would be the main selling point, right?
10:45gfrederickswhat does a generic conversion interface look like?
10:45gfredericksthe metedata has a symbol to lookup that resolves to a function to do the conversion?
10:46gfredericksclgv: I normally end up creating a dispatch map for my main, so that's what's getting replaced mostly
10:47clgvgfredericks: keyword for default builtin-case cases (:string, :long, :double ...) function for custom conversion
10:48clgvifn? vs fn?
10:48clgvor keyword? vs fn? ;)
10:50gfredericksthere 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:50gfrederickslike when the keyword is also an IFn in this case
10:51Glenjaminis this the whole "should strings be iterable" thing?
10:51clgvyeah the distinction whether you want to support IFn or Fn is sometimes not trivial
10:53clgvyeoj___: afair clojure.jdbc/query returns a clojure sequence, hence you cant call a resultset method on it
10:53clgvyeoj___: at least not on the returned result. maybe you can use one of the hooks to extract the desired data
10:54gfredericksI wonder if it'd be weird if java.jdbc put the result set in the metadata of the return value
10:54yeoj___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:54clgvgfredericks: I think there are hooks to access it
10:54Glenjaminyou can drop down a level in the api and get the resultset
10:54Glenjaminone sec
10:55Glenjaminhttp://clojure.github.io/java.jdbc/#clojure.java.jdbc/db-query-with-resultset
10:55Glenjaminquery just uses db-query-with-resultset and runs the resultset through result-set-seq
10:56yeoj___Glenjamin: ah, cool thanks.
11:01agarmanis there a way to examine the :pre & :post conditions on a fn?
11:02agarmansomething like get-validator for Var
11:03ambrosebsagarman: no
11:06agarmanI couldn't find a way, but wanted to ask just in case there's something I missed
11:07ambrosebsagarman: there's nothing magic about :pre, it's just code. See clojure.core/fn
11:14dave-7Hi 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:19agarman(inc ambrosebs)
11:19lazybot⇒ 9
11:21agarmanambrosebs: didn't think of it as magic, but had looked in clojure.lang for where it was executed, skipping past (source fn)
11:22ambrosebsI just think validators are slightly more magic than pre :)
11:43razum2um1is there any way to use "-quote in a docstring?
11:48clgv,(println "\"\"")
11:48clojurebot""\n
11:48clgv,"\"\""
11:48clojurebot"\"\""
11:48rurumate,(fn ^{:doc "\"-quote" } foo [])
11:48clojurebot#<sandbox$eval71$foo__72 sandbox$eval71$foo__72@1a0fea4>
11:49clgv,(defn f "\"bla\"" [x] (* x x))
11:49clojurebot#'sandbox/f
11:49clgv,(doc f)
11:49clojurebot"([x]); \"bla\""
11:50clgvworks on my repl
11:59skinkitten(1)
12:00razum2um1yep, escaping works, but wouldn't it be cool to have triple-quotes like python?
12:02philandstuffor reader macros :trollface:
12:05clgvof #ifdefs ?
12:05gfredericksI was able to use reflection to add heredocs to the clojure reader in like 20 minutes
12:05gfrederickscan't seem to find the code for it though
12:05gfredericksit's probably lost in refheap
12:06clgvgfredericks: refheap needs a random "did you know this gist?" functionality
12:06clgvthen you could find it again by chance :P
12:07clgvor I guess registering an account there would work as well ;)
12:14dbaschgfredericks: do you remember more or less when that was?
12:15dbaschsite:refheap.com helps me find my stuff sometimes
12:17gfredericksyes.
12:18gfredericksBetween 2014-02-25 and 2014-03-10
12:18gfredericksbut I'm not 100% positive it's on refheap
12:24tickingsorenmacbeth: Nice work with flambo! :)
12:38expezhttps://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:38rurumateA go block will always wrap the return value in a channel. Will that channel remain open?
12:44dbaschexpez: what does bar do and why can't it take nil arguments for x, y and z?
12:45Glenjaminexpez: http://clojuredocs.org/clojure_core/clojure.core/defn#example_137
12:48expezdbasch: 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:52dbaschexpez: why are you making foo a three-arity function instead of an argument list of variable lengths, or different arities?
12:52expezbecause it's being called with results from the db where x y and z can all by nil :(
12:52expezI hate null values so much
12:54dbaschexpez: so just OR your argument list with the default values and call bar with that
12:55expezNot sure why I didn't think of that, so obvious now. Thanks!
12:55dbasche.g.
12:55dbasch,(map #(or %1 %2) [nil nil 5] [1 2 3])
12:55clojurebot(1 2 5)
12:55dbaschnp
12:59TimMcAssuming none can be false
13:01puredangerfnil?
13:04TimMc,((fnil (fn [a b c] [a b c]) 1 2 3) nil nil 5)
13:04clojurebot[1 2 5]
13:10tuftgood morning clojuresphere
13:13tspotAfter 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:13cbptspot: you can try asking for help
13:13tspotI'm also finding too many things have multiple meanings eg. keywords as functions
13:15TimMctspot: To be fair, I tend to avoid multimethods.
13:15tspotI was inspired by Rich Hickey's decomplecting but Cloure seems more complex than any language I've learned before.
13:15TimMcTry Scala. :-P
13:16gfredericksnamespaces and multimethods is a weird pairing for a book chapter o_O
13:17justin_smithyeah, that is really odd
13:18ambrosebskeywords being functions isn't complex, in that sense. Possibly confusing and unintuitive.
13:18justin_smithtspot: keywords as functions is a syntax shortcut, you can just use get
13:18aperiodictspot: "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:18mikerodtspot: Be careful to interpret simple as easy and complex as difficult
13:19tspotThere'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:19justin_smithtspot: well that's not complex, it's just different. mutability, on the other hand, is massively complex.
13:19mikerodtspot: And are you already familiar with functional-orientation in programming?
13:20tbaldridgetspot: 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:20ndptspot: It really depends on which languages you're coming from. What's your background?
13:20tspotndp: Ruby
13:20tspotndp: Perl before that
13:20tbaldridgetspot: so talk to me about blocks vs lambdas vs procedures :-P
13:21ndptspot: Ok, both of those are Algol-family languages; it'll take a little while before you fully internalize the characteristics of Lisps.
13:21mikerodClojure takes huge steps to promote simplicity. This may involve moving away from what is easy / familiar.
13:21tspottbaldridge: .each is as straightforward as it gets
13:21tbaldridgetspot: 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:22tbaldridge,({:a 42} 42)
13:22clojurebotnil
13:22tbaldridgebleh
13:22tbaldridge,({:a 42} :a)
13:22clojurebot42
13:22ndptspot: I had a somewhat extended settling in time whne I first picked up Lisp after only having done C-like languages.
13:22tbaldridge,(:a {:a 42})
13:22clojurebot42
13:22tspotmikerod: I actually like the Lisp roots. It's just the contextual switching that throws me.
13:23tbaldridgetspot: and that just takes time (I came from C#/Python). You just have to start small and after awhile it'll come.
13:23tspottbaldridge: I like the functional/immutable alternative to OO but Clojure has a LOT of syntax. Too much.
13:24tbaldridgetspot: 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:24tbaldridgetspot: define syntax?
13:24mikerodtspot: I'm not seeing this "too much" syntax argument I guess
13:24dbaschtspot: 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:24GlenjaminJoC is possibly not a great intro do clojure book - i think it says that in chapter 2 actually
13:24dbaschtspot: have you tried the 4clojure exercises?
13:24Glenjaminor maybe it says not a great intro to programming, i forget
13:25mikerodI'd argue that Clojure, along with pretty much all popular Lisps, have the least "amount of syntax" when compared to other mainstream langs
13:25dbaschtspot: JoC can be overwhelming if you don't have some lisp and/or java background
13:25mikerodClojure 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:25tspotGlenjamin: Yes, I'm also reading "Clojure in Action" for first steps. Much clearer but I'm only at the early chapters.
13:26tbaldridge(inc mikerod)
13:26lazybot⇒ 1
13:26Glenjaminaphyr's blog series i think is excellent
13:26mikerodRich Hickey has a good discussion of why he added a few more data literals.
13:26tbaldridge(let ((a 42) (b 433)) (+ a b)) is just gross
13:26Glenjaminbut once you're beyond the basics, i think building something useful teaches you loads
13:26mikerodI can't recall the exact talk.
13:27Glenjaminthe 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:28mdrogalismikerod: http://www.infoq.com/presentations/Simple-Made-Easy 25:13
13:28atyzHey 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:28tbaldridgeatyz: perhaps log the GC some and see if there is a connection?
13:29tspotIt'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:29Glenjaminns is a mess
13:29atyztbaldridge: thats a good idea, although I thoguht that would affect the memory more
13:30Glenjaminespecially if you get the literals slightly wrong, the error messages are next-to useless
13:30TimMcatyz: Can you induce a thread dump?
13:30TimMcMaybe you'll find something that is spawning threads.
13:31atyzTimMc: 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:32TimMcThey should, yeah. But I think those are on a pool of limited size.
13:32mikerodmdrogalis: Thanks :)
13:32atyzThey are, 2 per core I believe
13:33atyzDo you think it could be that there are too many being spawned for the processor to keep up?
13:33aperiodictspot: @~ 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:34aperiodictspot: 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:34TimMcatyz: Dunno. But try running jstack PID if it's available.
13:34TimMcatyz: What happens to the CPU if you take a machine out of the scaling group? (Can you do that?)
13:34mikerodQuoting is more of a Lisp thing than a Clojure-specific. I don't see why it would "leak out far beyond macros"
13:35mikerodThe syntax-quote ` ~@ stuff is just shorthand for quoting things.
13:35mikerodAnd all this just relates back to having homoiconicity.
13:35mikerodI think aperiodic is right that this shouldn't be the focus when getting started learning and using the language.
13:36mikerodThe ns macro is a bit whacky though, I'd agree. Just don't typo there. :)
13:37ambrosebsclojure is not a good language to make mistakes in.
13:37TimMc,`[0 ~@(range 1 5) 0] ;; aperiodic, it's useful outside of macros as well
13:37clojurebot[0 1 2 3 4 ...]
13:38aperiodicoh, cool
13:39atyzTimMc 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:39mikerodTimMc: do you find yourself often doing things like that?
13:39atyzBut thats just a guess
13:39atyzI'll try to do so now
13:40mikerodI don't think I have many cases where that'd be something I wrote. Perhaps you have good use-cases though.
13:41mikerodIt is certainly convenient if you needed to unroll a bunch of stuff into a literal form :P
13:42TimMcatyz: Err yes, the LB. :-)
13:42TimMcmikerod: It's rare, but when I do use it, it's super convenient. :-)
13:47mr-foobarin clojure does a symbol follow a protocol or an api ?
13:47atyzTimMc: I just pulled it out of the load balancer, so I guess we will see what happens in a few minutes
13:48dbaschmr-foobar: not sure what you're asking, can you rephrase your question?
13:49dbaschmr-foobar: a symbol is just an instance of clojure.lang.Symbol
13:50mr-foobardbasch: clojure.lang.Symbol is what I was looking for.
13:52mr-foobardbasch: symbols can be used like enums right ? ( i am in the js land. need something like symbols / js )
13:53nkozamr-foobar: the common idiom is to use keywords for that
13:53nkozamr-foobar: as in :red :blue :green
13:54mr-foobarnkoza: oh, I am aware of that. I am using js :( I want to port that idiom to js basically.
13:58atyzTimMc: Interesting... Its still at 100 % after being out of the LB for 10 minutes
13:58TimMcSo, it's definitely stuck on something. Do you have jstack on that machine? Should come with the JDK.
13:59atyzTimMc: I do indeed. sudo jstack 1277
13:59atyz1277: Unable to open socket file: target process not responding or HotSpot VM not loaded
13:59atyzThe -F option can be used when the target process is not responding
14:00atyzYep, it seems there is a deadlcok
14:00TimMcApparently the -l option will print locks.
14:01atyzhttps://www.refheap.com/87785
14:01atyzThere is no locks I don't think
14:01atyzBut a bunch of the processes are locked
14:02TimMc"No deadlocks found"
14:03atyzYep - this is really curious - I can't help but think this is because of my use of futures
14:03TimMcI'm not sure if those blocked threads are normal, though -- maybe they're a threadpool waiting for requests.
14:03TimMcCheck the thread dump for a server that is behaving nicely.
14:04atyzWell TimMc the issue is that *all* of the servers get into this state
14:04atyzEventually
14:04atyzI'm having to kill the oldest one
14:05atyzPeriodically
14:05TimMcCan you take one out of LB that is not yet at 100%, check the threads, and compare it?
14:06atyzI could do that
14:08TimMcI'm not entirely sure how to interpret these entrails, but there might be something obvious.
14:08hiredmanhttp://wiki.eclipse.org/Jetty/Howto/High_Load#Thread_Pool
14:21atyzTimMc: https://www.refheap.com/87787 <-- the new one... Its the same
14:31hotcore,({:a 42} :a)
14:31clojurebot42
14:32cbpTIL multimethods don't realize sequences when you're dispatching on (map type x)
14:35atyzhiredman: that could be something! Thank you. Now to find where to configure this
14:35atyzAlthough that wouldn't explain why the cpu usage i still at 100% now
14:38hiredmanatyz: who knows what the queue depth is, could take forever to chew through
14:40atyzhiredman: would this just be api requests that havent been processed? or threads pushing out data that haven't been sent yet?
14:42hiredmaneither
14:43hiredmanthe picture may be more complicated if you are using the async reply features of pedastal
14:44hiredmanand 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:45atyzhiredman: that is something, atleast
14:45hiredmanyep
14:49amalloycbp: that doesn't sound right. the first thing isa? does is check whether (= parent child)
14:49hiredmanI 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:49amalloyso it should realize the sequence of (map type x)
14:50atyzhiredman: you seem quite confident that this has something to do with jetty?
14:50amalloyif you mean that the elements of x are themselves sequences, and it doesn't realize *those* sequences, then well, of course not
14:51hiredmanatyz: 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:52hiredmanatyz: something must be "sticking" it jetty's queue for some reason, which is causing the back up of requests in the queue
14:52yeoj___ 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:52cbpamalloy: https://www.refheap.com/87790
14:53cbper
14:53cbpi messed up there
14:54hiredmanatyz: it could be some other place you are doing unbounded queueing, futures run on an unbounded threadpool
14:55hiredmanjetty 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:56cbpamalloy: https://www.refheap.com/87791
14:56cbp:-P
14:57cbp(mapv type x) does make that work though
14:57atyzhiredman: howw ould you create a future on an unbounded threadpool, I thought inheritly they were restricted?
14:57cbpalso note that (foo [1 2]) doesnt work
14:58hiredmanatyz: futures are not
14:58arrdemcbp: mapv :P
14:58hiredmanclojure has two built in thread pools, futures use the unbounded one
14:59arrdemcbp: 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:59amalloycbp: that's nothing to do with realizing sequences
15:00amalloythe lazy seq is in fact realized there
15:00amalloyyou could see that by using, for example, (map #(doto (type %) prn) x)
15:01amalloyrather, isa?'s behavior to "look inside vectors to see if their elements are isa?" only applies when both objects are specifically vectors
15:01atyzhiredman: thats very interesting, I'm even more confident that that is my problem now
15:02amalloy(and of course (map type x) is not a vector)
15:03hiredmanatyz: 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:05atyzhiredman: I am not at all. futures were just a really simple way to do some fire-and forget asynchronous work done
15:06atyzI could probably also use core.async too
15:06hiredmanatyz: I would be very careful with core.async
15:07atyzYou think I would end up with the same problem if I don't configure the channel properly?
15:07hiredmanforkjoin threadpools are not supposed to have io schedule on them
15:07hiredman(any blocking operation really)
15:08hiredmanatyz: 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:08atyzhiredman: they are. they are usually api calls
15:09atyzto other services
15:09atyzBut in a lot of the cases it should have its own threadpool. https://github.com/dakrone/clj-http
15:10hiredmancore.async can make those async calls look synchronous, but it doesn't obviate the need for a an io threadpool
15:10hiredmanatyz: but clj-http is still blocking
15:10atyzIt is, I realise that
15:10atyzI think that that is the issue
15:11hiredmanso you are spinning out these futures to do this blocking operation without any back pressure
15:11hiredmaninfact executors might not work very well, they don't have a good way to do back pressure
15:12atyzWell those clj-http calls aren't done through futures
15:12atyzclj-http allows you to create your own threadpool
15:12atyzto work from
15:12tbaldridgeas an aside, http-kit has a really nice async http client
15:12dakronehiredman: they do, you can spin up an executor with a fixed-size queue
15:12dakroneand then adding to the queue will block until work completes
15:12atyzhttps://www.refheap.com/87792
15:13hiredmandakrone: sure, but the Executors factory class won't make one of those for you
15:13dakronehiredman: yes, quite true
15:13hiredmanatyz: 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:14atyzOH that makes sense
15:24cbpamalloy: Oh so it will work as long as it's = and doesn't have to check for isa?
15:24cbpas in (defmethod foo [Long Long] ..) would work there
15:28atyzhiredman: 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:28ohpauleezMy ears are ringing :)
15:30ohpauleezatyz: Are you using Pedestal 0.3.0?
15:30atyzohpauleez: not yet
15:31atyz[io.pedestal/pedestal.service "0.2.2"]
15:31ohpauleezAhh, that uses the latest Connection bits in the latest Jetty release
15:31ohpauleezbut requires you are on JDK 1.7 or higher
15:31atyzohpauleez: I"m afraid to upgrade - I've had to make some changes to how pedestal boots
15:31ohpauleezIf you're making clj-http calls within your service, it's advised you wrap them in Hystrix
15:32ohpauleezThe 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:32ohpauleezor reach deep into the container to toggle whatever you need
15:33atyzWell lets see what happens if I upgrade it qucikly
15:33atyzMaybe it will work
15:35atyzohpauleez: well surprisingly it worked!
15:36ohpauleezYou may have to adjust some of your startup code, and adjust your namespaces
15:36ohpauleezie: there's no more *.service.*
15:36atyzOh... Then some stuff is probably broken
15:38atyzAnyway, to the issue at hand.. woudl you maybe point me in the direction of where I could possibly configure jetty?
15:40ohpauleezHow 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:41ohpauleezin 0.3.0, you can reach even deeper, into the Container's context setup
15:41ohpauleezwhich is difficult to do unless the hooks are exposed or you jump through a lot of hoops
15:42ohpauleezIf what you want is to specify your own interceptor chain, you do that on the :interceptors key on the service map
15:42ohpauleezinstead of accepting the default stack, you just assembly your own
15:42atyzohpauleez: yes, but that didn't allow me to specify the order in which they were loaded
15:43ohpauleezyes
15:43ohpauleezif you specify them in the original service map, the default ones aren't added
15:43ohpauleezand the processing is always sequential to how they're specified
15:44ohpauleezIf you add :interceptors in your own function, that function *has-to* run before any startup or processing function on the Pedestal side
15:44ohpauleezif Pedestal sees :interceptors on the service-map, it takes them and runs with them
15:45ohpauleezYou 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:47sveriHi, 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:47cbpmethinks isa? should be better documented
15:52tbaldridge,(doc isa?)
15:52clojurebot"([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:54cbpthere's nothing there about (isa? [Long Long] [Number Number]) working or (isa? (list Long Long) [Number Number]) not working
15:56TimMccbp: What? That's absurd. D-:
16:04dbasch,(isa? '(Long Long) '(Number Number))
16:04clojurebotfalse
16:04dbasch,(isa? [Long Long] [Number Number])
16:04clojurebottrue
16:04tbaldridge,(source isa?)
16:05clojurebotSource not found\n
16:05Glenjamindoes anyone know why PersistentQueue doesn't have a function to create one in core?
16:06Glenjamin,(-> (clojure.lang.PersistentQueue/EMPTY) (conj 1 2 3) pop)
16:06clojurebot#<PersistentQueue clojure.lang.PersistentQueue@402>
16:06Glenjaminor a printer implementation apparently
16:06Glenjamin,(-> (clojure.lang.PersistentQueue/EMPTY) (conj 1 2 3) pop vec)
16:06clojurebot[2 3]
16:07amalloyGlenjamin: there's no good reason
16:07dbasch,(isa? {Long Long} {Long Number})
16:07clojurebotfalse
16:07dbaschactually that one makes sense
16:07bhaumanGlenjamin: I have often missed that function, medley has it though
16:07Glenjamini only noticed because mori exposes it as a primary datatype http://swannodette.github.io/mori/#queue
16:07tbaldridgedbasch: ick, yeah, isa? has a special case for vectors
16:08tbaldridgewhy? I haven't a clue
16:08Glenjaminalthough i want a structure which does random access, efficient append and effcient dropping of "old" entries in a windowing-fashion
16:08Glenjaminwhich i don't think exists
16:08eevara circle buffer?
16:09amalloy$google amalloy ring-buffer
16:09lazybot[amalloy/ring-buffer · GitHub] https://github.com/amalloy/ring-buffer
16:09amalloyGlenjamin: doesn't actually expose random-access, but there's no reason it couldn't
16:11GlenjaminOh, in pure js
16:12GlenjaminOh I see, it's vector-backed
16:12puredangerGlenjamin: re Queue stuff, vote: http://dev.clojure.org/jira/browse/CLJ-1078
16:13GlenjaminTa
16:14Glenjaminamalloy: I might see if I can port this to JS backed on a mori vector if that's ok with you?
16:15amalloysure. i don't own the idea of ring buffers; there's probably not even anything novel in my implementation
16:16GlenjaminI'll have to read up on some thing it seems :)
16:18TimMcdbasch: ##(isa? '[Long Long] '[Number Number])
16:18lazybot⇒ false
16:18TimMcso your list example wouldn't have worked anyhow
16:18TimMc,(isa? (list Number Number) [Number Number])
16:18clojurebottrue
16:19dbasch,(isa? (list Long Long) (list Number Number))
16:19clojurebotfalse
16:47borkdudeI 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:49bob2https://github.com/clojure/clojurescript/wiki/Differences-from-Clojure#lisp i guess
16:50borkdudebob2 I've done that: https://www.refheap.com/87798
16:50bob2i feel like you missed the "The :as prefix selector is required in :require-macros." bit
16:51borkdudehmz
16:51borkdudethen why isn't it required in [cljs.core.async.macros :refer [go go-loop]]
16:52borkdudebut I will try
16:52bob2no idea
16:52borkdudenope, still the same
16:53borkdudeit's like it doesn't pick up the clj file
16:57borkdudeClojurescript up and running says: "This assumes that a Clojure source file is available on the classpath at my_project/
16:57borkdudefoo.clj containing defmacro foo.". How can I assure that this is the case with lein cljsbuild auto?
16:58PigDudewhat does this mean? clojure.lang.ArityException: Wrong number of args (4) passed to: PersistentArrayMap>
16:58PigDudei get this error with no line number or anything
16:59amalloyPigDude: 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:59hiredmanPigDude: the stack trace will have line numbers in it
17:01PigDudehiredman: when?
17:01PigDudehiredman: there is no stack trace
17:01hiredmanPigDude: there is always a stracktrace, your tooling may not be displaying it
17:02hiredmanthe exception will be in *e
17:02hiredmanyou can use clojure.stacktrace/print-stack-trace to print it, or call the method I never case correctly on it
17:03tbaldrid_hiredman: except when it says "No trace found" still no clue what that means
17:03PigDudehiredman: my tooling consists of a terminal, bash, and leiningen
17:03PigDudewhere is *e?
17:03PigDudehiredman: ^
17:03hiredmantbaldrid_: the jit can some sometimes elide traces, there is some jvm option to turn it off
17:04hiredmanPigDude: type *e in the repl
17:04ShayanjmSo 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:04PigDudehiredman: what repl
17:04PigDudehiredman: i'm running `lein test`
17:04Shayanjmeverything starts fine, and I can access the server
17:04hiredman:(
17:04Shayanjmbut I can't access the nrepl
17:04Shayanjmif I try to connect, it just hangs
17:04hiredmanPigDude: I find it very hard to believe that lein test isn't printing a stacktrace
17:05PigDudehiredman: do you want a screenshot?
17:05ShayanjmI tried passing join? false through the :adapter settings in the project.clj but it doesn't seem to be working
17:05hiredmanPigDude: sure
17:05dbaschhiredman: that particular exception in cider doesn't print a trace either
17:05dbasch, ({} 1 2 3 4)
17:05clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (4) passed to: PersistentArrayMap>
17:05dbasch,(print *e)
17:05clojurebot#<Unbound Unbound: #'clojure.core/*e>
17:05hiredmandbasch: that is because cider has a stupid option that defaults to not displaying the stacktrace
17:06amalloytbaldridge: "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:06hiredmandbasch: don't assume clojurebot's evaluation environment is like the repls
17:06dbaschhiredman: but even *e has no stacktrace
17:06PigDudeso do you want to see the screenshot still hiredman
17:06PigDudedbasch seems to be right
17:06hiredmanPigDude: show me lein test not printing a stacktrace
17:06dbaschthere are a bunch of cases like that in core.clj, I remember one like that recently
17:07dbaschwhere it essentially eats the stacktrace
17:07hiredmanPigDude: he is not
17:08PigDudehiredman: here's a paste, i hope you trust me not to have doctored it https://www.refheap.com/b7f57290f403ef0dda758f63e
17:08hiredmanPigDude: right, so you are catching the exception somewhere and printing it out
17:08hiredman(try … (catch Exception e (prn e)))
17:08hiredmanactually
17:08hiredmanthat is core.async
17:09amalloyyeah, notice that didn't even count as a failure in the tests. someone caught it and printed it
17:09hiredmanthere is a stupid line that got committed in core.async that prints out unhandled exceptions like that
17:09PigDudehiredman: the only exception handling in my program is in clojurescript code
17:09PigDudehiredman: seriously?
17:09hiredmanPigDude: right, but you have a go routine somewhere that is throwing that exception
17:09benkayso 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:09hiredmanPigDude: yep
17:09cbp hiredman: :|
17:10hiredmanit may have been fixed in a later release, dunno
17:10PigDudeso when programming with core.async, you don't get stacktraces??
17:10lazybotPigDude: Uh, no. Why would you even ask?
17:10hiredmanPigDude: if you catch the exception yourself you will
17:10cbpcore dont need no silly stacktraces
17:11amalloyhiredman: https://github.com/clojure/core.async/blob/76b25bf91c670b0c3542ed9cb687ff29fb2183a7/src/main/clojure/clojure/core/async/impl/exec/threadpool.clj#L24-L33 ?
17:11dbaschhiredman: you're wrong, there are cases in core where you don't get stacktraces
17:11stuartsierraPigDude: You get a stacktrace, but it can be difficult to predict where and when the stacktrace will appear.
17:11hiredmanhttps://github.com/clojure/core.async/blob/master/src/main/clojure/clojure/core/async/impl/exec/threadpool.clj#L33
17:11PigDudediscussion changed, is clojure a ghetto? :)
17:11hiredmanstuartsierra: you don't, the executor prints out the exception, no trace
17:12hiredmanamalloy: yeah
17:12hiredmandbasch: no, you just don't know where to look
17:12amalloydbasch: i don't think that's true
17:12stuartsierraWait, when did that happen?
17:12dbaschamalloy hiredman I remember an example that we found here a few weeks ago
17:12dbaschtrying to find it in the logs
17:12PigDudethanks for helping me figure this out dbasch and hiredman
17:12amalloystuartsierra: https://github.com/clojure/core.async/commit/9fcae99576c0735a804bbd4cbec81307e2d34d90
17:13amalloyspecifically https://github.com/clojure/core.async/commit/9fcae99576c0735a804bbd4cbec81307e2d34d90#diff-2193dd8597437d6454bb74edd2f15e00L26
17:13hiredmancore.async, land of random stuff
17:13dbaschit was an exception that did not even show a line number
17:13PigDudestuartsierra: so in my case i did not get a stacktrace because it was a special case in core, nothing to do with async
17:13hiredmandbasch: not having a line number and not have a stacktrace are different
17:14dbaschhiredman: it had neither
17:14hiredmandbasch: nope
17:14amalloyi think you can get exceptions with no stack trace at all if the jit has done something particularly aggressive
17:14amalloy"trace missing"
17:14hiredmanamalloy: and -XX:-OmitStackTraceInFastThrow will fix that
17:15hiredman(in theory)
17:15dbaschamalloy: technically it had a stacktrace, but it was shallow because it was a freshly thrown exception that caught another one
17:15hiredmanwell, there you go, it had a stacktrace
17:15dbaschit was a really silly line, but I can't find it
17:16amalloyi 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:16amalloyi wonder if that's fixed
17:18yediis there a function that unqualifies a keyword
17:19amalloyi regard keywords as unqualified if they haven't got at least a bachelor's degree
17:20FrozenlockIs there a way to give a name to the :sender/:from in postal?
17:20cbpyedi: name
17:20cbpo you scared him away
17:20FrozenlockI'd like the recipient to see "Frozenlock" instead of "frozenlock@gmail.com" :-/
17:21wheeee:injections in project.clj
17:21wheeeeErr whoops.
17:22cbp$mail yedi (name :a/b)
17:22lazybotMessage saved.
17:24FrozenlockAh got it... :from "Frozenlock <frozenlock@gmail.com>"
17:26dbaschFrozenlock: :from can be "Mr. Frozenlock <frozenlock@gmail.com>"
17:26dbaschyou beat me to it
17:26FrozenlockBy a single minute ;-p
17:27dbaschFrozenlock: I had to go look into an app of mine that does that :P
17:28FrozenlockIs this a javax/mail thing, or it's a universal email thing that I should have known?
17:32KlaufirI 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:32KlaufirI need some help determining the reason for that nullptr exception
17:33amalloyFrozenlock: it's an email thing
17:34hiredmanKlaufir: that tutorial is bogus, their code was never run and would never have worked
17:34Frozenlockamalloy: Awww, shame on me then.
17:34hiredmanKlaufir: they are using #() incurrectly
17:34hiredmanKlaufir: it would always generate an npe
17:34stuartsierraamalloy, hiredman, PigDude, dbasch: I'm going to fix this.
17:35hiredmanincorrectly
17:35hiredmanKlaufir: 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:36hiredmanand of course the result of a call to println is nil
17:36hiredmanswitch to (fn [] ...) or #(do ...)
17:36Klaufirhiredman: ah, thank you.
17:36Klaufirhiredman: can you recommend a better text for learning stm?
17:37hiredmanKlaufir: don't bother, you'll never use it
17:37dbaschFrozenlock: http://tools.ietf.org/html/rfc2822#appendix-A.1
17:39wheeeeCan someone tell me what :injections does within a lein project.cljs?
17:39wheeeeproject.clj
17:39nhll.
17:40amalloya 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:40cbpKlaufir: clojure programming has nice diagrams on the retry mechanisms of the different clojure refs
17:40Klaufircbp: thanks
17:42hiredmanhah they must have been running their code in some environment that sent the npe stacktraces somewhere else, so they never saw them
17:43hiredmanclojurebot: bloggers |are| the worst
17:43clojurebotIn Ordnung
17:44amalloyhiredman: my guess was that it was originally written with (future #((...))), which squelches the exceptions
17:45amalloyand then they switched to Thread/start to avoid having to explain futures or something
17:45hiredmanamalloy: well, no future wouldn't call the function
17:45amalloyoh, right
17:47PigDudeis it cleaner to use separate async channels than to share one and tag messages?
17:47PigDudematching tagged messages isn't easy like in erlang
17:47hiredmanPigDude: maybe use the pub/sub stuff
17:48hiredmanhttps://github.com/clojure/core.async/blob/master/src/main/clojure/clojure/core/async.clj#L823
17:50PigDudei wish async walkthrough.clj covered that usage, do you know of one?
17:50hiredmannoppe
17:50PigDude(example of using async pub/sub)
17:50PigDudeok :)
17:50PigDudeit looks like what i want though, thanks
17:53stuartsierrahttp://dev.clojure.org/jira/browse/ASYNC-76
17:58ShayanjmDoes anyone know why `lein ring server` would start & execute correctly, but the nrepl hangs?
17:58Shayanjmhttps://gist.github.com/shayanjm/65942169797fd2f84a54
18:01benkaydid the optional query clauses ever make it into datomic? https://groups.google.com/d/msg/datomic/p3FLisquFH8/J1kXJ_9pQngJ
18:03BobSchackbenkay: yep see http://docs.datomic.com/query.html#expression-clauses
18:03benkaythanks BobSchack
18:03BobSchackNP
18:03alloyed@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:04Shayanjmalloyed: Everything works fine, and it says nrepl has started on XXXX as well as the ring server has started on XXXXX
18:04Shayanjmeverything "works" I just can't connect to the repl :\
18:04Shayanjmit doesn't even error upon connection either - it just keeps trying to connect indefinitely
18:04Shayanjm(or it hangs, I can't really tell which is happening)
18:06alloyedhmm, what nrepl client are you using? just `lein repl :connect"?
18:06serjeemIs there an equivalent to (declare …) for classes/records?
18:07technomancyserjeem: no, you can't seamlessly replace a class or record afaik
18:08technomancywhich is basically the whole point of vars
18:08serjeemtechnomancy: heartbreaking :(. Is there some kind of hack I could use to forward-reference a class before I define it?
18:08Shayanjmsorry alloyed I just dc'd on my BNC :\ What was the last thing I said in the chan?
18:08alloyed22:03 < Shayanjm> (or it hangs, I can't really tell which is happening)
18:09hiredmanserjeem: why not create a factory function and declare that?
18:09ShayanjmDid you answer that, by chance?
18:09hiredmanserjeem: if you are using a defrecord you automatically get 2 factory functions, which you can declare and use
18:09ShayanjmThe latest logs I have are from technomancy saying "which is basically the whole point of vars"
18:09technomancyserjeem: this is why I hate using things that aren't vars
18:09alloyedI was just asking how you were connecting to the repl.
18:10serjeemhiredman: 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:10Shayanjmalloyed: I'm trying to use a sublime plugin that supports nrepl
18:10Shayanjmi tried on lighttable as well
18:11Shayanjmsublime plugin: http://sublimerepl.readthedocs.org/en/latest/
18:11hiredmanserjeem: type checking how?
18:11alloyedlets start super-basic then, what does `lein repl :connect` do?
18:11hiredmanserjeem: do you mean inserting instance? checks?
18:11Shayanjmalloyed: while lein ring server is running?
18:12serjeemhiredman: yeah, that’s the idea.
18:12serjeemI 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:12serjeemMore like contract checking, but I digress
18:13alloyedyeah. 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:14hiredmanserjeem: consider separating jvm notions of types from your contracts
18:14Shayanjmalloyed: lein repl :connect <port> works perfectly. It looks like the sublime plugin is a bit messed up :\
18:15Shayanjmthanks for the help though
18:16serjeemhiredman: I was hoping it wouldn’t have to come to that, but I think I can work around that.
18:16alloyednp
18:17hiredmanserjeem: 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:18hiredmanserjeem: are you dead set on writing this yourself? there are a number of schemaish clojure libraries
18:18hiredmanhttps://github.com/Prismatic/schema is maybe the most well known
18:20serjeemhiredman: We did a survey of a lot of them and not filled the exact hole we were hoping to fill, unfortunately.
18:21serjeemhiredman: We might have to move closer to your suggestion, or just give up and force a linear ordering on types.
18:22serjeemWhile 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:22serjeemWhat I’d do for one more level of indirection between records and the jvm.
18:23hiredmanhave you considered using a language with a static type system?
18:23hiredmanbeing really strict about types is just not something you really do in clojure
18:24serjeemI argued a little for haskell at the offset, but clojure was a better fit for the project and the team
18:24serjeemWe’re all former racketeers, so there’ve been a few rough patches adjusting to the way clojure does stuff.
18:25hiredmanif at all possible, any place you might use a defrecord instance, you should be able to use a map
18:25technomancyyeah records make more sense in racket than they do in clojure
18:25serjeemYeah, it’s been the #1 element of cognitive dissonance since we started
18:25hiredmanthe reason defrecord implements so much of the same stuff as maps is try and bridge the worlds, which of course you do completely
18:26hiredmanso caring strictly about the type of a thing/map/record is weird
18:27serjeemIt makes sense, at least to me, when you look at it from the perspective of building interfaces
18:28hiredmanwhat do you mean by building interfaces?
18:28serjeemeven 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:28serjeemin racket, for structured data, you define foo? and bar? as structs. Python and ruby, you’ve got classes
18:29yediTEttinger2: got that job =D
18:29technomancyserjeem: it's un-idiomatic to rely on classes in ruby too
18:29hiredmanserjeem: if foo and map are logically associative bags of data, why create new types?
18:29technomancyyou're supposed to check for supporting the specific methods you're interested in
18:29hiredmanfoo is an associative bag of data with at least an association for :a and :b
18:29wheeeeCan anyone tell me what ":injections" does in a lein project.clj?
18:30wheeeeI'm looking at this: https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L231-L233
18:30technomancywheeee: it's a form that gets included whenever lein evals anything
18:30ttasteriscoyedi: where at? :)
18:30clojurebotTitim gan éirí ort.
18:32serjeemhiredman: I’m a very HTDP/design recipe focused programmer, and the first step of that process is describing the data
18:32yedittasterisco: http://wit.ai
18:32ttasteriscoyedi: oh, the yc company. nice
18:32serjeemwhen 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:33hiredmanserjeem: it depends, but generally a function might look at it's arguments and call any number of predicates on them
18:33wheeeetechnomancy: Thanks. Does that mean just when lein first starts up or every time it evals anything? Sorry for asking a daft question.
18:33hiredman(doc contains?)
18:33clojurebot"([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:34hiredmanserjeem: the schema library will actually do that sort of thing for you, I think, I've never used it
18:34technomancywheeee: it's every time
18:34technomancywheeee: every time it evals in the project jvm, that is
18:35wheeeeAh, thank you.
18:35hiredmanserjeem: 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:36hiredmanbut it doesn't do the runtime checking, it does static type checking
18:36akurilinRandom question: do you guys know if there's ever been an effort to support passing the db pool explicitly in Korma?
18:37akurilinRight now it's implicit through the dynamic var you can set
18:37serjeemhiredman: 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:37hiredmanserjeem: why?
18:38hiredmanactually we use https://github.com/danlarkin/subrosa at work (an irc server written in clojure)
18:38serjeemhiredman: 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:39hiredmansure
18:39hiredmanwe don't use either of those projects at work
18:41serjeemhiredman: in terms of why, philosphically, the idea is that your program represents, on some level, in an abstract way, the transformation of information
18:41hiredmanserjeem: 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:41serjeembits and bytes and users and game characters and server settings
18:42hiredmanserjeem: exactly, but the types of data we manipulate are finite, mostly associative things
18:42serjeemand 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:43serjeemand 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:43hiredmanserjeem: the thing is, you can write generic transforms over associative maps easily
18:43hiredmanserjeem: not over custom types
18:43serjeembut often something that models in some way some kind of facet of the real world, or some abstract value of something
18:43hiredman(well, not without haskells type system)
18:44serjeemand it makes sense to say, “okay, this think I’m working with is at least conceptually made up of X Y and Z”
18:44hiredmanserjeem: it doesn't though
18:44serjeemyou don’t necessarily need like a type system to enforce it, but you should have some way to communicate it to others
18:44hiredmanserjeem: plenty of simulations and models exist as rows in a spread sheet
18:44hiredmanno types for different kinds of things to be found
18:45hiredmansimulating the world by mapping it to types is the most primitive type of simulation
18:45serjeemthose rows most often have, like, labelled columns, right?
18:45serjeemit’s not just rows of arbitrary information
18:45hiredmanserjeem: sure, and maps have keys and values
18:45serjeemsee, for instance, the IRC server you linked
18:45serjeemThe IRC server you linked, for instance, does this here: https://github.com/danlarkin/subrosa/blob/master/src/subrosa/server.clj
18:46hiredmanaphyr has a nice post about modeling somewhere
18:46serjeemit gives you a description of what it expects users, rooms, user-in-rooms, and the server to be
18:46hiredmanserjeem: 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:46serjeemyeah! that’s all I’m saying
18:47hiredmanhttp://aphyr.com/posts/312-clojure-from-the-ground-up-modeling
18:47serjeemthe types are just one way to describe the data
18:47hiredmanthey generally are not though
18:48hiredmandefrecords are slightly better than other "types" at this
18:48hiredmanbut generally every type ends up with its own mini-dsl for reading and writing its data
18:49hiredmanmaps also have a dsl/api, assoc, dissoc, get, but it applies to all maps
18:49hiredmanso if you model everything as maps you can use the same api and create truelly generic data transforms
18:51hiredmanI 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:52hiredman(also I just really like http://aphyr.com/posts/312-clojure-from-the-ground-up-modeling)
18:53serjeem(I really like that post, too, thanks for linking it!)
18:53serjeemI also really agree that the map api is _fantastic_ in clojure. all of the core datastructure apis are
18:54serjeemand I very much appreciate that the language is lean, and that it makes it wonderful to work with
18:54serjeemit’s seriously a dream
18:54hiredmanwell, that'll wear off :)
18:54serjeembut 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:54serjeem:P
18:55tufti always struggle with when and if to defrecords
18:55tuftor to use protocols for that matter
18:56cbpif you're in doubt don't use them
18:56tuftalways wonder how much it is just to get classes implementing methods at the bytecode level
18:56tuftyeah, seems like you can get along fine without
18:56serjeemafter about half a year of using clojure, defrecords seem like the harriest part of the whole langauge
18:56tuftalso seems like most of the libraries i pick up make use of them
18:57cbpprotocols are nice for client-facing apis
18:57hiredmancbp: the opposite
18:58cbpahhhh?
18:58tuftcbp: better than simple generic functions / multimethods? they seem really similar in function
18:58tufti assume you're talking about extension points
18:58hiredmancbp: they are create for spis, you have a library that can be backed via anything that implements some protocol
18:58hiredmanthe client api is functions implemented on top of the protocol
18:59hiredmanthe great for
18:59hiredmanthey are
18:59hiredmanugh
19:00hiredmana big thing that is missing in clojure is some kind of module/compile time polymorphism, so protocols often get abused for that
19:00serjeem+1 to that
19:00hiredmansomething like mls functors
19:01hiredman(I think, I mean, I don't have much experience with those)
19:01serjeemIf clojure could eat rackets heart, and grow three new limbs (really good macros, module system, better docs), it would take over the world
19:01serjeem[and maybe a fourth limb for non-sucky struct/records :P]
19:01tuftis there a benefit to protocols over multimethods beyond performance for that kind of extension point?
19:03hiredmanprotocols group the functions together which is nice
19:03adusounds like ObjC
19:03hiredmanmultimethods bringing in the whole complicated isa? machinery which I've never really seen used
19:04tufthiredman: yeah i guess that's one difference -- it's all or nothing
19:04hiredmantuft: actually no, you can selectively implement parts of a protocol
19:04tuftoh, hrm
19:04hiredmanbut don't
19:04amalloyyou're not really supposed to
19:04amalloyit's possible, but not for any good reason
19:05tuftit always feels like a little bit of a let-down when the CamelCase symbols creep into your code for non interop purposes
19:05cbp>_>
19:06Lannyperhaps you mean a letDown
19:06tuftheh
19:06tuft:let-down
19:08ttasteriscoserjeem: what do you mean by module system?
19:08hiredmansomething like parameterized namespaces
19:09serjeemttasterisco: 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:09serjeemhaskell’s got a meh one as well, sml had a fantastic one that programming languages have been trying to emulate for decades
19:11hiredmanlike, 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:12hiredmanand you just call the functions from foo, and there is no polymorphism
19:12serjeemoh god if this works I don’t think anyone should ever let me touch a macro again: `(-> ~(keyword typ) str symbol resolve)
19:12technomancyserjeem: use "name" instead of keyword+str
19:13serjeemtechnomancy: good point :P
19:14serjeemOMG IT WORKS
19:14serjeemi am an awful person
19:14ttasteriscoanyone 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:18ttasterisco(hm, actually happening with all versions > 0.3.0-RC7)
19:18ttasterisco*>=
19:34akurilinSchema question: is it possible to only enforce a certain subset of keys of a map as mandatory and ignore the rest of them?
19:35aperiodicakurilin: 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:35akurilinOk. Sad.
19:38aperiodicakurilin: actually, you can do it with something like {s/Keyword s/String, :required s/String}
19:42akurilinWhat does that do, not sure I can quite figure it out from reading that
19:43aperiodicallows 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:45TimMcserjeem: What's an example of something that prismatic/schema didn't have?
19:45TimMcWe're using it for a project, so it would be good to know.
19:46serjeemTimMc: i could be totally wrong, but t didn’t seem to have a super solid datomic integration story
19:46serjeemwhich is 1/2 - 2/3 of what we needed out of the schema stuff we wanted to have
19:46TimMcHmm, how so? (I haven't used datomic, so this may be difficult to explain to me...)
19:47TimMcAnd is extending it not an option?
19:48akurilinaperiodic: ah that makes ense, thanks
19:48serjeemTimMc: 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:48akurilinaperiodic: 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:49serjeemI 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:51aperiodicakurilin: 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:52serjeemThat said, and as a general note, seqex is freaking fantastic
19:52serjeemI hope it doesn’t go the way of the dodo, because it makes writing macros fun again
19:52tuftserjeem: i have a similar stack, but i don't quite understand what you mean -- are you having to describe data twice?
19:53tufti'm now going to have datomic schema, prismatic/schema and test.check generators. seems like there should be something to unif
19:53tuftunify
19:53akurilinaperiodic: That's a great trick actually, thanks!
19:53serjeemtuft: yeah, we have to write everything twice
19:53serjeemwhich I justify as “double-entry data keeping"
19:54serjeembut really just saves sanity w/r/t db migrations, which is something that would terrify me with a single, non-datomic schema
19:54tuftah hmm
19:54tuftyeah seems like you should be able to derive one from the other
19:55tuft.. and of course not everything with a prismatic/schema will be persisted
19:55serjeemyou can, and https://github.com/Yuppiechef/datomic-schema seems to
19:56serjeembut the idea makes me a little uncomfortable, i dunno
19:56serjeemthat said, I wish everything was just protobufs and we’d never have to worry about anything ever again forever~~
19:57hiredmanI'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:57tuftyeah i'm using datomic-schema too, incidentally
19:57serjeemtuft: has it been working well?
19:58serjeemhiredman: is core.typed production-ready yet?
19:58hiredmanhttps://gist.github.com/c-spencer/6569571
19:58serjeemI’ve got about 5 files I’d love to move to it
19:58hiredmanserjeem: I dunno
19:59tuftserjeem: i did run into one problem with its strange use of atoms
19:59hiredmanhuh, that is literally storing type information in datomic
19:59tuftserjeem: i think it should inspect interned vars instead -- messes up when you're doing redef in the repl
20:00tuftprismatic/schema and core.typed seem somewhat orthogonal to me
20:01tuftas in, seems like you'd pick one or the other. static or test driven "type" checking
20:02serjeemIt’d be nice to get a mix
20:03serjeemI’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:03serjeembut I’d also like to have functionality around metadata associated with different fields in a schema
20:04serjeemlike in the thing I’m writing, things can get default values, certain fields can have preconditions on them, etc
20:05serjeemwhich is stuff you can’t get outside of like, agda maybe
21:05benkayhey 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:12amalloytimbre seems silly, use a real profiler
21:12amalloyeg yourkit, jvisualvm
21:13benkaytimbre:midje::core.test:{jvisualvm,yourkit} ?
21:14benkayer
21:14bbloomamalloy: i haven't used timbre, but instrumented tracing is extremely valuable for many applications
21:15benkaytimbre:{jvisualvm,yourkit}::midje:core.test ?
22:33danielcomptonI found timbre not very useful with threaded code
22:44blaenk(ns a (:require [clojure.string :as str :refer [replace]]))
22:44blaenkwhat's the point of :refer there?
22:44blaenkso make it so I can use clojure.string/replace unqualified?
22:44blaenks/so/to
22:45blaenkif that's the case, then it's like :only?
22:46blaenkoh I think I see, it seems like it is, that way one doesn't have to use :use
22:47mangeblaenk: Correct. :use/:only is the same as :require/:refer, but (:use x) is the same as (:require [x :refer :all])
22:47blaenkthanks mange
22:49blaenkhow about translating (:use (clojure zip xml)) to use require, refer, all; would I not be able to use the prefix notation?
22:50blaenk(:require (clojure [zip :refer :all] [xml :refer :all])) ?
22:52Demosthenes_hello?
22:52clojurebotBUENOS DING DONG DIDDLY DIOS, fRaUline Demosthenes_
22:52Demosthenes_am I in the right place?
22:52FrozenlockNo
22:52FrozenlockYou should leave
22:52Demosthenes_What a great community
22:53dbaschDemosthenes_: it depends, if you're looking for #clojure then you are
22:54Demosthenes_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:54serjeem(doc contains?)
22:54clojurebot"([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:54Demosthenes_I know the clojuredocs give the reason that "contains is only for indices" but it doesn't make sense to me
22:54mangeblaenk: I didn't know it, but apparently (:require [clojure [walk :refer [prewalk]] [test :as test]]) does work. Cool!
22:55dbaschDemosthenes_: contains? does not do what you want for arrays
22:55serjeemDemosthenes_: the reason is that (contains? c k) looks only at the keys, not the values, of c, and compares them to k
22:55blaenkso I guess that's how that would be translated huh
22:56serjeemso, e.g. (contains [:a :b :c] 1) works, since 1 is a key in that vector
22:56Demosthenes_ah thanks serjeem
22:56ddellacostaDemosthenes_: if you want to find a value try something like
22:56blaenk(:use (prefix some thing)) becomes (:require (clojure [some :refer :all] [thing :refer :all]))
22:56ddellacosta&(filter #(= :a %) [:a :b :c])
22:56lazybot⇒ (:a)
22:56serjeemyou're probably looking for something more like (first (find #(= v %) col)
22:56Demosthenes_what is the %?
22:56serjeemddellacosta: beat me to it!
22:57ddellacostaDemosthenes_: it is the argument getting passed to the function. Here's an alternative synta:
22:57ddellacosta*syntax
22:57ddellacosta&(filter (fn [v] (= v :a)) [:a :b :c])
22:57lazybot⇒ (:a)
22:57Demosthenes_oh I see
22:57Lannyis there a syntax for multiple arguments
22:57Demosthenes_ty
22:57Lannyand how does one google docs for "#()"
22:57ddellacostaDemosthenes_: np
22:58ddellacostaLanny: yeah, you can do
22:58ddellacosta&(reduce #(assoc %1 %2 :foo) {} [1 2 3])
22:58lazybot⇒ {3 :foo, 2 :foo, 1 :foo}
22:58blaenkLanny: just search for clojure lambdas or anonymous functions
22:58ddellacostafor example
22:58ddellacostawhoops, backwards
22:58ddellacosta&(reduce #(assoc %1 :foo %2) {} [1 2 3])
22:58lazybot⇒ {:foo 3}
22:58ddellacostawell, that's a dumb function
22:58ddellacostabut you get the picture hopefully
22:59cbpLanny: http://clojure.org/reader
22:59dbaschyou could also do
22:59Lannynifty, thanks
22:59dbasch,(filter #{:a} [:a :b :c])
22:59clojurebot(:a)
22:59dbasch,(filter #{:d} [:a :b :c])
22:59clojurebot()
23:06platzwhere in the documentation do I find that set can be used as a Fn?
23:07platzor just something you learn an memorize
23:08platzI mean I know it's on clojure.org somewhere
23:08platzbut there probably isn't an wasy way to find out via the repl (doc)
23:08dbaschplatz: http://clojure.org/data_structures#Data Structures-Sets
23:09platzdbasch: ah, thanks - reading now