#clojure logs

2015-11-03

02:37jeayeHow can I explode the result of a function call to the remaining arguments of another?
02:38jeaye(wants-three 1 (explode (gives-two)))
02:39jeayePulling it out into a let would be my first move, I just wonder if there's a library macro for this.
02:41opqdonutapply?
02:41jeayeYup.
02:41opqdonut,(apply + 1 (concat [2 3] [4 5]))
02:41jeayeJust had found that apply can do it.
02:41clojurebot15
02:42jeayeThanks.
02:48jeayeWhat's a good way of organizing helper functions in a namespace? foo.core has some helpers, foo.bar has some of its own, etc.
02:49jeayeIn C++, it's common to have a `detail` or `impl` namespace per each namespace that has helpers.
02:59jonathanjis there a convenient way to do: (f (.foo o) (.bar o) (.baz o))?
03:00jonathanjsince .foo is a reader macro (or something?) ((juxt .foo .bar .baz) o) won't work
03:48TEttingerjonathanj: there is memfn for turning java methods into fns
03:49TEttinger(doc memfn)
03:49clojurebot"([name & args]); Expands into code that creates a fn that expects to be passed an object and any args and calls the named instance method on the object passing the args. Use when you want to treat a Java method as a first-class fn. name may be type-hinted with the method receiver's type in order to avoid reflective calls."
03:49tdammersoh wow that looks super useful
03:53jonathanjthat's useful, just not really so much here
03:55tdammersit kind of is, indirectly
03:55tdammersyou can use memfn to wrap those methods, and then you can thread or compose them
03:56tdammersmemfn creates actual clojure fns, so unlike the sugared java method calls, you can use those in threading macros without further ado
04:45cflemingI'm having a problem with lazy seqs and mutually recursive functions.
04:45cflemingI read on SO a post by amalloy saying that they were fundamentally incompatible, but I don't understand why.
04:46cflemingI have some code which looks like it should be ok, but blows the stack immediately, with what looks like an infinite loop.
04:46cflemingThere isn't enough data for it to be the problem from Stuart Sierra's concat post.
04:48Fenderdo you have a link to the source code?
04:48cflemingI can refheap it, one sec
04:51cflemingFender: https://www.refheap.com/111314
04:52cflemingIt's basically a simple top-down parser for a simplified EDN, which should output a lazy sequence of formatting primitives (the {:op...} maps)
04:54cflemingThe issue appears to be in map-entry, which uses lazy-cat to recursively generate the ops for a series of map entries
04:54FenderI don't fully understand what's going on in the top part but a nice way to get an SO over there would be to have #(expression lexer) always return something non-nil
04:55Fenderyou could rule that out by putting some (take 1000) in between
04:55cflemingYeah, it's additionally tricky because the lexer is mutable
04:56cflemingI'll try just taking one element from the lexer instead of iterating at line 48
04:57Fenderyes, you'll probably see by what the lexer generates where it's stuck
04:57Fenderobviously peek is supposed to consume something in the mutable state there
04:57cflemingNo, if I replace lines 48-50 with just (expression lexer) it still barfs, it's something in the mutually recursive functions.
04:58cflemingNo, (peek) doesn't consume - (token) does.
05:00Fenderis the stacktrace clear as to where it repeats?
05:00Fenderalternatively you could println something at the entry of each fn
05:01Fenderadditionally, can you make sure that (token) consumes something? because idiomatically it could also be written as (token!)
05:01cflemingYeah, I'm thinking that's what I'll have to do. The loop is RT.seq -> LazySeq.seq -> LazySeq.sval -> concat/cat/fn
05:02Fenderfrom my limited understanding I suppose lazyseqs shouldnt be the problem because in the worst case you'd just traverse it all
05:02Fenderwell, that is ...
05:02FenderI think you don't know the mutable state when the lazy-seq is executed
05:03FenderIOW, you don't know when each lazy-seq is realized
05:05Fenderso when it's realized it's calling the lexer but it might be that this is not in order
05:06Fenderso if you have a lazy-seq and you first realize elements 0 and 1 and then deep dive into 0->0 then there could be a problem
05:07Fenderin get-in syntax this would mean (get-in x [0]) (get-in x [1]) (get-in x [0 0]) would not be the intended order of traversal in a depth-first traversal because [1] should come after [0 0]
05:08cflemingI'm pretty sure in this case that the element should always be traversed in order
05:10cflemingOh, I see the problem
05:10cflemingI'm not correctly checking for the case where the lexer has no more entries
05:11cflemingIt's nothing to do with laziness or anything, just a common or garden bug :)
05:11Fenderhaha
05:12Fenderlet me guess, the when-let always returns something because of the vector decomposition?
05:12Fender(line 9?)
05:13lumano, when-let checks the value of the expression (token lexer), and if that is truthy, destructures that into [type text]
05:13cflemingNo, in that case when-let... right
05:14cflemingI'm not quite sure how it's happening, but map-entry is somehow getting called when the lexer has no more elements, which it shouldn't. It doesn't check for that case, because it shouldn't have to - it should always get a closing }
05:16FenderI stand corrected
05:18Fenderok, well how about: map-entry is calling itself and collection-element as well
05:18Fenderthat's probably what you mean
05:20Fenderanyone here knows how to reference a simple clj file with just definitions from cljs?
05:21Fenderthe clj file just contains def'ed code and no dependencies
05:21Fenderand all of it without side effects
05:32kungiProgramming: Solving problems yourself you created yourself ... :-|
05:45cflemingFender: So this is a little embarrassing: (= ClojureTokenTypes/LEFT_CURLY)
05:45cfleming(always true)
05:46Fenderhaha ok^^
05:46cflemingIronically I'm actually doing this as part of prep for my conj talk, where I will be talking about how to fix just this sort of error :)
05:47cflemings/fix/get warned about/
05:50Fenderlike in the old days when the compiler writing guys would have been happy to have a compiler that they could use
07:28Glenjamindoes anyone know a good way to find out what has started an agent? My uberjar compilation is hanging while the agent pool closes
08:37jeayeIs there something like update-in which just accesses nested elements based on a "path" of indices?
08:37filbenget-in?
08:37jeayemuahaha
08:37jeayeMakes sense; thanks.
08:37filbennp
08:39puredangerGlenjamin: you can build a hacked version of Clojure that dumps stack at the point where an action is dispatched
08:40Glenjamin:'(
08:40Glenjamini suppose maybe i could alter-var-root something if i get it in early
08:43noncomGlenjamin: also you could avoid building and just redefine things inside the core
08:43noncomalthough, i heard, it may be impossible with clojure 1.8+
08:52puredangerThe th no you can't do in 1.8 is with-redefs of something in core and have other things in core see it
08:56puredangerBut it's worth a try - the main things that dispatch are future and send
08:57gfredericksGlenjamin: user.clj is a good trick for alter-var-rooting things early
09:08visofhi guys
09:12visofassume i have list of methods like this (foo bar xxx yyy) and want to apply on something as (yyy (xxx (bar (foo something)))) but method's list has undetermined number of rules, what is the best way to do this (apply comp list-methods something) ?
09:12visofthis is the right way to do this?
09:13oddcullywhat do you mean by "number of rules"?
09:14visofnumber of methods
09:15visof(foo bar xxx yyy) contain 4 methods, maybe 3 or whatever n methods in the list
09:15oddcullywell apply comp does not look bad?
09:15oddcully,((apply comp [inc inc dec]) 5)
09:15clojurebot6
09:16visofoddcully: ok
09:19visofoddcully: but dec is applied first right?
09:19gfredericksyep
09:19visof(inc (inc (dec 5)))
09:20visofah okay
09:20visofso i need to reverse before apply if i want to apply from the beginning of the list
09:22oddcully,(reduce #(%2 %1) 5 [inc inc dec])
09:22clojurebot6
09:50phaseNi,(-> 5 inc inc dec)
09:50clojurebot6
09:50phaseNi:P
09:56justin_smith,(-> 5 / / /)
09:56clojurebot1/5
09:56justin_smith,(-> 5 / / / /)
09:56clojurebot5N
09:56oddcully,(defmacro apply-rules [init fns] `(-> ~init ~@fns))
09:56clojurebot#'sandbox/apply-rules
09:56oddcully,(apply-rules 5 [inc str seq])
09:56clojurebot(\6)
09:58timvisheris anyone aware of a `safe-min` implementation somewhere in the standard libraries. something like `(defn safe-nil [&args] (->> args (remove nil?) seq (apply min))`?
09:59justin_smithno, but I'd do it as (reduce (fn [i n] (if (and n (< n i)) n i)) coll)
09:59timvisherjustin_smith: 👍
10:00justin_smithtimvisher: that symbol doesn't work in my irc client :(
10:01justin_smithhaha, just found it in the log, same to you buddy :)
10:01justin_smith( http://clojure-log.n01se.net/ for those curious)
10:02timvisherjustin_smith: ah. y u no emoji? :)
10:02gfredericksjustin_smith: doesn't work for me in my client *or* my browser
10:02timvisheri don't have ascii art for thumbsup
10:02justin_smithtimvisher: tty client running on a virtual ocean droplet - I guess it might be misconfigured?
10:02justin_smithgfredericks: it's a thumbs up
10:03timvisherjustin_smith: mmm. i'm running in a tty session in erc in emacs and it displays for me. but i have fonts set up that can handle it. ¯\_(ツ)_/¯
10:03timvisheri wonder what that looks like? :)
10:04gfredericksthat one looks fine
10:04justin_smithtimvisher: yeah, it's somewhere between the terminal I am running natively, the tty settings on my vhost, and the settings on my irc client - I'm getting "unknown unicode" directly as a symbol - I assume the client does that?
10:05justin_smithtimvisher: with broken unicode I expect to at least get some gibberish I can paste into another window and figure out what it really was
10:05timvisherjustin_smith: i'd guess so. i think the character codes are still present so i'd expect that as well
10:06justin_smithI might just switch from this irc client to emacs running just so it can run erc
10:06justin_smithhah
10:06justin_smithat least I could trust it to handle weird characters
10:06justin_smith(even if the font is wrong, it will at least tell you the *name* of the character)
10:06timvisherjustin_smith: i have a dedicated emacs instance running with just erc that i mosh to to irc :)
10:07justin_smithI might be joining that club
10:07timvisheri think i picked that up from technomancy
10:07justin_smithis mosh that much better than ssh + screen?
10:08timvisherjustin_smith: mosh + (screen|tmux) is _so_ much better than ssh + (screen|tmux)
10:09gfredericksI've stopped using tmux and just use an emacs server now
10:10justin_smiththat makes sense - emacsclient in a tty is cool
10:10justin_smithand who am I kidding - I don't need to do anything on this host I can't do inside an emacs window
10:11gfredericksyeah who are you kidding
10:11gfredericksit even works better than tmux for having multiple computers logged in
10:11gfrederickswith tmux I always had to detach everything else so that I wouldn't get sizing constraints
10:12justin_smithwith screen I learned to love "C-a F"
10:12justin_smith(force size to size of current screen)
10:12gfredericksI can't even remember anything about screen
10:12justin_smithha
10:12gfredericksbut I've learned I can use screen inside an emacs term buffer :)
10:13tdammersscreen inside screen is where it gets weird
10:13justin_smithgfredericks: to me, tmux is that program I need to know how to use because I have projects where people think running lein run inside a tmux session is an OK way to run a server
10:13justin_smithtdammers: C-aC-a - easy!
10:13gfredericksjustin_smith: I must be reverse of you; my team does a lot of prod stuff w/ screen
10:14tdammersjustin_smith: simple vs. easy, huh
10:14justin_smithgfredericks: ugh, really everybody, use uberjars and nohup, or better yet, stop using printlns for logs and use a file appender
10:14timvisherjustin_smith, gfredericks: i've been unable to get anything like the kind of isolation i'm used to with multiple emacs instances inside many tmux sessions in a single emacs server instance.
10:14SchrostfutzI'm doing a course on clojure and they introduce head recursion on the example of element count or frequencies, where they pass the count/frequencies to each recursive call. Is there a advantage of doing that instead of tailrecursion which should work there, too?
10:14timvishereverything that tries to solve that problem is an ugly hack compared to just running multiple instances.
10:16tdammersSchrostfutz: the problem with head recursion is that it leaks stack space; tail recursion can be TCO'd and thus run in constant stack space
10:16timvisherbut my usage patterns are pathological in many ways, i'm sure :P
10:16tdammersSchrostfutz: I have no idea why one would not use tail recursion when that is possible, other than maybe pedagogical reasons
10:16justin_smithSchrostfutz: the question of tail recursion or not is much less important when the recursive call generates the next item in a lazy-seq (because the continuation gets turned into a thunk and no longer claims immediate stack), but otherwise I'd think tail recursion is always better
10:17Schrostfutztdammers, justin_smith: okay, thank you.
10:17Schrostfutztdammers: Even if it is pedagocial I think it is bad to use examples where it is the wrong approach
10:18justin_smithtdammers: I don't think you can build a lazy seq via tail recursion, but you can via non-tail recursion
10:18tdammersSchrostfutz: I'm thinking it might help illustrate the difference
10:18Glenjaminjustin_smith: 12factor principles says log to stdout and let the process manager handle files/rotation etc :)
10:18tdammersjustin_smith: well, as you said, when you're building a lazy seq, you don't need to TCO
10:18tdammersjustin_smith: that's how Haskell gets away with not doing TCO at all (or always doing TCO, depending how you look at it)
10:18justin_smithGlenjamin: OK, but screen/tmux are not process managers :P
10:19Glenjaminheh, don't disagree there
10:19Schrostfutztdammers: But then you should make sure that you mention tail recursion would be the better option
10:19tdammersSchrostfutz: agree
10:20justin_smithSchrostfutz: here's the thing - sometimes laziness is better, and laziness can't really be tail recursive
10:20justin_smithI don't think...
10:20tdammersin a way, it's not recursive at all
10:21tdammersas in, the recursive call is deferred
10:21tdammerstransparent continuation-passing or something like that
10:21Schrostfutzjustin_smith: yes, but we have not been introduced to anything lazy yet.
10:22justin_smithfair enough, sounds like bad choice of example then, unless they are leading to a brilliant gotcha
10:22justin_smithlike "see how this blows the stack, now lets look at ways of preventing that"
10:22justin_smith(the whole teaching philosophy of "show why you need it, before showing the solution")
10:25tdammerssomeone at work just pasted an article about the problem/solution ordering thing
10:25justin_smithtdammers: that's what I was thinking of
10:25justin_smiththe whole thing with video games, keys, doors
10:25tdammersyeah, that's the one
10:25tdammersheadaches and aspirin
10:25tdammersmonads and monad tutorials :D
10:26justin_smithtdammers: of course I see exceptions to this in the real world "show your child the consequences of running into traffic, then teach them to look both ways"
10:26justin_smithbut in the digital world, we are lucky :)
10:26tdammers"have your child run into the traffic, then you won't need to bother with the teaching anymore" :x
10:26justin_smithlol
10:27tdammersalso explains why security is such an orphan child in the digital world
10:27tdammersit's impossible to create the headache in a safe way there
10:28justin_smithThat's true - by the time it hits, you are screwed. And you are strongly disincentivised to talk about the experience (admitting you had the problem makes you look bad in the market).
10:31adamretterI have inherited some Java code which is using Clojure as a library. I have a com.github.krukow.clj_lang.IPersistentVector and I somehow need to sort this by a key function (in Java). Can anyone give me any pointers to how to do this?
10:32justin_smithadamretter: if it behaves similarly to a clojure.lang.PersistentVector you can use the methods in java.util.collections to get it into an array or ArrayList and then use it natively
10:34justin_smithadamretter: sorry, I think I was wrong about collections there - but I know there is a way to get an arbitrary clojure sequential into an array or arralist
10:35adamretterjustin_smith: having never written a line or clojure or worked with these collections before… I might need a bit more handholding ;-)
10:36justin_smithadamretter: sure - check the other interfaces it implements for one (IPersistentVector is not a type, it's an interface, right?)
10:36justin_smithadamretter: experimenting in my clojure to get you something concrete right now
10:37justin_smithadamretter: if you are comfortable with a bit of clojure (into-array v) should give you a java array of Object containing the elements of the vector
10:37justin_smith,(into-array Object [1 2 3])
10:37clojurebot#object["[Ljava.lang.Object;" 0x651f98f8 "[Ljava.lang.Object;@651f98f8"]
10:38adamretterjustin_smith: yes it's an interface, but all the interfaces it implements are from Clojure, so I can't see how to tie it back to a Java array or whatever
10:38adamretterjustin_smith: erm, sorry I don't know how to write `(into-array v)` in the equivalent java
10:38justin_smithadamretter: you can get into-array via clojure.lang.Var, and call it with the args of Object.class and v
10:40justin_smithclojure.lang.IFn into_array = clojure.lang.RT.var("into-array"); into_array.invoke(Object.class, v);
10:40justin_smithsoemthing like this
10:40justin_smithit's easier in clojure code :)
10:40adamretterhmm RT.var doesn't seem to be a valid method
10:41justin_smithadamretter: https://clojurefun.wordpress.com/2012/12/24/invoking-clojure-code-from-java/ I missed an arg
10:41justin_smiththe args are "clojure.core" "into-array"
10:41justin_smithbut really that article above is better than my memory right now, heh
10:43adamretterjustin_smith: hmm but com.github.krukow.clj_lang.RT doesn't seem to have a `var` method?
10:43justin_smithadamretter: no! clojure.lang.RT
10:43justin_smithyou use clojure.lang.RT.var to look up vars
10:43justin_smithor do they have some weird version of clojure they are using?
10:43adamretterjustin_smith: ah so I think the issue os that the project is using this (I just googled it) https://github.com/krukow/clj-ds
10:44justin_smithadamretter: OK, I thought you were using clojure
10:44justin_smithadamretter: in that case, yeah I'd see what interfaces that object implements, and one of them should give you a toArray or iterator
10:44adamretterjustin_smith: yeah so did I
10:47justin_smithadamretter: looks like that persistentvector has an iterator method, and it should implement count too, you could easily build up an array from its contents given those
10:47adamretterjustin_smith: okay cool, I will try that, thanks :-)
11:06justin_smithTIL instead of "who am i" you can run "who killed jfk" and get the same output
11:15TimMc"If ARG1 ARG2 given, -m presumed: `am i' or `mom likes' are usual."
11:15TimMcTIL
11:16justin_smithTimMc: sadly "who is your daddy" is rejected - too many args
11:25justin_smithadamretter: also, looking at krukow.clj_lang.RT - it has a toArray method that should work if you pass the vector in
12:51Glenjaminanyone know a similar shorthand to (-> (doto prn)) which works with ->> ?
12:54muhukwhat are you doing to prn? that's cruel
12:55SchrostfutzIs there a way to have a helper function that's only available from within a function?
12:55justin_smithSchrostfutz: yes, via fn or letfn
12:55justin_smithSchrostfutz: though we don't do as much information hiding, immutability reduces its utility
12:55Schrostfutzjustin_smith: can the function also be recursive?
12:55justin_smithyes
12:56justin_smith(fn foo [] (if hmm? (foo)))
12:56justin_smithor just via recur also
13:04Schrostfutzjustin_smith: ah, thanks.
13:08Schrostfutzjustin_smith: Am I doing something wrong or will recur not work when using the #() notation?
13:08justin_smith,(#(if (< % 0) % (recur (- % 10))) 42)
13:09clojurebot-8
13:09justin_smiththat would be much more readable using fn, but recur works there
13:29{blake}Does asyc.core use "port" and "channel" interchangeably?
13:40amalloya channel probably has two ports, if i had to guess. the read and write ports
13:45{blake}Hmmm. We pass the channel to both puts and gets, ref'ed as "port", but for close! (and I think close! alone) it's ref'ed as "chan".
14:49baz_hi, have a logging related question
14:50baz_I'm using the tomcat-embed-jasper dependency
14:50baz_when I run my program (lein run)
14:50baz_I get jasper related logging
14:51baz_something like
14:51baz_INFO: At least one JAR was scanned for TLDs yet contained no TLDs
14:51baz_I would like to disable this output
14:51baz_currently looking at clj-logging-config
14:52baz_but something like (set-logger-level! "org.apache.jasper.servlet.TldScanner" :off) doesn't work
14:53baz_any hints on how to approach this?
15:18justin_smithbaz_: it might be easier to make a plist file
15:24baz_justin_smith: not familiar with a plist file, where can I find more information?
15:25justin_smithbaz_: http://tutorials.jenkov.com/java-logging/configuration.html
15:26justin_smithmaybe that's actually a "properties" file now that I reconsider
15:32baz_mmm, I would prefer a programmatic way with clj-logging-config
15:47ambrosebsBronsa: can you release a tools.analyzer version with this commit? https://github.com/clojure/tools.analyzer/commit/ef985c4a193470b13edb8822e9b74a1dc1368626
15:48SchrostfutzCan I have nested anonymous functions? If so, how do I get the arguments?
15:48{blake}Schrostfutz: You can't nest the #() notation but you can nest (fn[x y]...) till the cows come home.
15:49{blake},((fn[a b] ((fn [x y] (+ x y)) a b)) 2 3)
15:50clojurebot5
15:50{blake}Schrostfutz: Terrible example, but you get the idea?
15:51Bronsaambrosebs: sure
15:52ambrosebsBronsa: thanks, just requires a few changes and I'd rather fix them now.
15:55{blake}Given an vector of symbols, is there an elegant way to sort them in an arbitrary way? So, the vector might use :a :b :c :d, but I need them in :d :a :c :b?
16:00Schrostfutz{blake}: yes I do.
16:01ambrosebsBronsa: will that commit break core.async?
16:02Bronsaunlikely
16:02{blake},(sort-by {:a 2 :b 4 :c 3 :d 1} [:a :b :c :d])
16:02clojurebot(:d :a :c :b)
16:03{blake}Neat.
16:05luma,(defn ->order [s] (zipmap s (range)))
16:05clojurebot#'sandbox/->order
16:05luma,(sort-by (->order [:d :b :a :c]) [:a :b :c :d])
16:05clojurebot(:d :b :a :c)
16:08{blake}luma: Nice!
16:15SchrostfutzWhat is wrong with something like this: #(func param %)? The compiler does not expect % it seems...
16:18hiredmanthe compiler actaully has nothing to do with %
16:19hiredmanby the time the reader is done with #(func param %) % is gone
16:19hiredman,'#(func param %)
16:19clojurebot(fn* [p1__25#] (func param p1__25#))
16:20hiredmanthe error is almost certainly in the surrounding context, and it is hard to say what it is because you have edditorialized it and halfway incorrectly diagnosed it
16:20hiredmanlikely you are using -> or ->> without understanding that they are purely syntactic transforms
16:21hiredmanor you are trying to nest #() forms, which isn't allowed, or func just doesn't take the arguments you thing it does
16:21hiredmanto narrow that down you need to paste bin the actual error you get
17:52gfredericksdoes cljs have a mechanism for programmatically generating docstrings, via alter-meta! or equivalent?
18:05neoncontrailsHas anyone worked through the canonical Functional Data Structures textbook?
18:06neoncontrailsSorry... *Purely* Functional Data Structures (Okasaki)
18:06amalloy~anyone
18:06clojurebotJust a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..."
18:06neoncontrailsHeh. Touche, clojurebot
18:07dnolengfredericks: at runtime? no since docstrings aren't a thing at runtime
18:07clojurebotExcuse me?
18:07neoncontrailsI'm wondering the applicability of Okasaki to Clojure specifically, as all the textbook exercises are ML with a dash of Haskell
18:07gfredericksdnolen: the use case is reducing duplication in docstrings; I'm guessing I'll just have to put up with it?
18:08amalloyclojure still has functions. you can do the exercises in clojure, and mostly just skip the types. you do have to at least recognize ML type signatures to know what you're supposed to implement
18:13neoncontrailsamalloy: would the data structures translate well into a React environment.? I'd like to have a better understanding how to exploit the monolithic "app-state" paradigm
18:15amalloybeats me. i'd guess not, but i'm no expert
18:25didibusI've been wondering inside a let expression, it seems I cannot do _ (println "hey") more then once. Anyway around it?
18:27didibusHum, nevermind, it seems it works
18:27didibusI must have something else that's the issue
18:29TEttinger,(let [_ (print "hey, ") _ (print "party ") _ (print "people!") _ 5] _)
18:29clojurebothey, party people!5
18:32didibusI just found my problem, I was trying to bind a name that I have a function defined for, so it ws complaining about how it can't cast the bind into an IFn
18:32McDougalHi, is anyone here using luminus?
18:32didibusAnd that was causing the let to fail past that point
19:19didibusDo (deftest) run in the order they are declared? And do they run one after the other or in parralel?
19:21vilmibmdidibus, run in the order you declared, sequentially
19:21didibusok, thanks
19:40dnolengfredericks: need some more context on what you are trying to do?
19:41dnolenyou want to automatically generate docstrings for some fns w/o having to write a macro or something?
19:46gfredericksdnolen: I don't care what I have to write, I just have 5 functions whose docstrings are 95% identical
19:46gfredericksI'll show you how I'm doing it in clj-jvm
19:47dnolengfredericks: you can this with a macro then
19:47gfrederickshttps://github.com/clojure/test.check/blob/6a2f74d4088c11bb16b26899c63fe6887ac17c25/src/main/clojure/clojure/test/check/generators.clj#L598
19:47dnolenjust add :doc meta
19:47gfredericksoh right
19:47dnolens/can/can do
19:47gfredericksI'm so used to punching vars that I don't think of macros for that :)
19:47gfrederickscool, thanks
19:48amalloygfredericks is just embarrassed to admit he doesn't know how to use macros
19:48gfredericksit's a bit less composable, but it works in this case
19:49numbertenis there a core function for this functionality: (fn [pred f x] (if (pred x) (f x) x))
19:49numbertenit seems like that would be common, but I can't think of anything off the top of my head
19:50dnolengfredericks: yeah alter-meta! unfortunately in ClojureScript works on runtime ref types
19:51dnolenso that excludes using it for banging on compiler information like var metadata
19:51gfredericksright
19:52amalloywell alter-meta! does the same thing in clj-jvm, right? it's just that vars are also runtime ref types
19:53gfredericksyeah
20:09gfredericksoh actually
20:09gfredericksin clojure you can also use expressions for the docstring
20:09gfredericksin either metadata position
20:09gfredericksI wonder if that works in cljs too
20:11celwellHello, I recently added some java code to my lein project (using :java-source-paths in project.clj). It works well when I 'lein ring server', but when I deploy to my AWS instance I'm getting: java.lang.UnsupportedClassVersionError: ...... : Unsupported major.minor version 52.0
20:12hiredmanbecause the java on your aws instance is older than the java on you local machine where you are compiling your java class files
20:13amalloyyou can fix it by adding a thing in your project.clj saying what version of java to target when compiling
20:13celwellHow can I target lower version? I tried :javac-options ["-target" "1.6"] but it didn't help.
20:13celwellmaybe I need to try some even older version
20:14hiredmanif I recall it is actually kind of a pain to do that, have you considered upgrading your aws instance to a newer version of java?
20:14celwellI will look into that, I'm actually on AWS Elastic Beanstalk, using Tomcat 7 server, I'm not sure how easy it is to choose java version.
20:15hiredman52.0 is java 8 (jdk 1.8), and I think java 7 is already EOL
20:15gfredericksnope :(
20:16amalloythat -target stuff works fine
20:18hiredmanapparently you can run in to issues if you don't also set the bootclasspath to point to the rt.jar for the correct java version, but I don't think I have every run in to that
20:19hiredmanhttps://docs.oracle.com/javase/8/docs/technotes/tools/windows/javac.html#BHCIJIEG
20:22amalloyyeah, in theory that is a problem but in practice it has never mattered to me either
20:50dnolenpeople should try ClojureScript master if they can - we're going to ship a new release on Friday - many fixes
20:54gfredericksis there a portable way for checking if a transient set contains an element?
20:55dnolen@gfredericks hrm don't think so
20:55gfrederickswelp that's what cljc is for I guess :)
20:55dnolenhttps://github.com/clojure/clojurescript/releases/tag/r1.7.166
20:56dnolenactually just try the prelease should hit Maven shortly
20:57McDougalHow is the web story for clojure nowadays ref basic stuff like emailing html templates, image resize, etc? And how does performance compare with a Go web app?
21:10owlbirdwhat's the best way to do if-return earlier in clojure?
21:13McDougalIs there an elseif in Clojure?
21:13justin_smithMcDougal: cond
21:14McDougaljustin_smith: Aha, gotcha. Thanks. Btw, would you use jetty or immutant or http-kit for a persistence heavy CRUD app?
21:14gfredericksI'm finally adding generators to test.check for collections of distinct elements (of particular sizes, optionall)
21:14gfredericksit's harder than it sounds
21:15justin_smithMcDougal: I'd use ring, use the jetty adaptor during dev because that's just easy, and then leave the production decisions based on how you want to deploy
21:16McDougaljustin_smith: Thanks. Being new to lisp, how long do you think it may take for the simplicity of lisp to kick in. I can get an app working, but at the mo, it sure does feel v diff. As its so new, more thinking everything through vs simplicity. I'm hoping to have that aha moment ref lisp vs reg OO
21:18justin_smithMcDougal: well, of course complexity is different from unfamiliarity. There are a lot of little revelations to find. One of them is realizing that you rarely need to hunt through code for a needle in a haystack to see why somthing ended up the state it is in - immutable values mean you just look at the immediate context and call stack
21:20McDougaljustin-smith: I'm about a week in and stuff gets hard wired quicker on a real project. So I'll just keep at it till its fluent
21:22McDougalIs clojure-toolbox the best place to look for libs?
21:24owlbirdIt's fantastic to write web app by using clojure (compojure) :-)
21:26sotojuan:-)
21:26justin_smithMcDougal: I start with google to find leads, then crossclj.info to see who uses the lib and how, then github to do a sanity check on the repo / code / developer activity
21:27justin_smithMcDougal: also, sometimes the best option is to just use interop with a java lib - it's not hard, and there's java libs out there for pretty much everything it would be reasonable to do with clojure
21:28justin_smithMcDougal: I know that as a newcomer the exciting part is fp, but clojure makes a good lightweight glue for using a few java libs too
21:29justin_smith(lightweight in developer time / energy, not lightweight in machine resources)
21:30McDougaljustin_smith: Thank you, am checking crossclj.info. When you say who the lib is used by, you mean companies or inidividual devs. I agree, it would be good to get a handle on java interop for max flexibility.
21:30justin_smithMcDougal: I mean look at how widely used it is, as well as what code that uses that lib looks like
21:32McDougaljustin_smith: Thanks, that's a more holistic approach to gauge lib quality. What have you settled on for rendering views? I'm looking at Hiccup and Selmer.
21:33justin_smithMcDougal: I'm a contributer to the caribou project (not super active right now, we used to have a company funding us but no longer...) - we have our own markup lib called antlers that I use, but it's similar to selmber. I like hiccup for ad-hoc stuff, especially making templates out of existing html and then doing data transformations. Also I use reagent, which uses hiccup syntax. So yeah, hiccup is great too.
21:34justin_smithbut for something a designer or frontend-only dev might touch? antlers or selmer is better for that
21:35McDougaljustin_smith: I looked at caribou about a year ago, it has a v nice admin and looked really slick for doing crud type apps. So clojure community still not leaning towards frameworks for productivity?
21:36justin_smithno, for the most part not. Though liberator is a great "framework" for doing REST right.
21:38McDougalProb because its so easy to stitch things together with just the needed libs. Thank you for the tips, I'm having a lot of fun with clojure, its stretching my mind in a v diff way
21:39justin_smithMcDougal: for some things though, like security, a framework would be so much better
21:39justin_smithbecause security is a weakest link kind of thing, and that's where loose ad-hoc collections tend to fail
21:40McDougaljustin_smith: I saw the talk on that. Have you found a good approach, mix of libs to plug that hole?
21:41justin_smithkind of - I mean, bcrypt, make sure you have nginx with ssl as a reverse proxy (because jvm ssl is a pain in the ass, not worth it)
21:42justin_smiththe ring middlewares for importing params, clojure.java.jdbc for prepared statements instead of string concatenation for sql
21:42McDougalYeah I always use that, got into bcrypt habit from rails exp. Haven't done the ssl on nginx as reverse proxy tho.
21:43McDougalSo with string concatenation sql injection is still wide open?
21:43justin_smithMcDougal: I mean, if you string concatenate and get stuff from a user, how can any environment prevent vulns there?
21:44McDougalGotcha, that makes sense. Ref ssl reverse proxy, does that mean running the entire app in ssl or just persistence?
21:45justin_smithit means all access through ssl via the reverse proxy, yeah
21:45justin_smithand letting nginx do all the work
21:46McDougalThat's a good default. What are you using for persistence, java.jdbc or some other lib?
21:48McDougalAm leaning towards yesql
21:49sobeli just write functions that isolate the queries/jdbc access
21:50justin_smithright now? a mixture of caribou's persistence layer (a map oriented thing built on top of jdbc) for the data that really matters and monger (mongodb) for stuff that needs to be fast cheap and easy and we could totally live if it all crashed and burned and we had to recreate the dataset
21:52owlbirdI've tried compojure/jdbc a few days, and figure out that the best structure of a web app only has 3 files, project.clj, db.clj, handler.clj, and write all business logic and jdbc/query in the handler.clj.....
21:53justin_smithowlbird: that works until you have thousands of lines of handler, heh
21:53McDougalGotcha. I'll have to try monger, first foray into nosql. Mostly postgres so far. I'll check into java interop in clojure for the brave, he does pretty good coverage on it
21:53justin_smithmongo has some bit gotchas so far in my experience - unless we just use it all wrong :P
21:54justin_smitheg. updates leaving a thread open trying to read a socket, and the thread and socket never being released until the app crashes because it runs out of one or the other...
21:54McDougaljustin_smith: Have you seen Rethinkdb, its an interesting nosql project
21:54justin_smithyeah, I've seen it
21:54justin_smithalmost tried it once
21:54McDougalHow about Cassandra or any graph dbs?
21:54justin_smithMcDougal: from a clojure point of view. datomic is pretty interesting
21:55McDougaljustin_smith: What's the pricing model on Datomic?
21:55justin_smithMcDougal: we are doing a lot of heavy duty graph stuff, but found that our graphs were too dense for the graph dbs to really pay off -- once a graph is dense enough regular tables make sense again
21:55McDougalDatomic is immutable db right?
21:56McDougalWhich graph dbs did you try out?
21:56justin_smithI think that's a good way to put it - yeah - of course you can do inserts / drops / updates, but it's all done with snapshots of time
21:56McDougalIs the benefit in Datomic performance or an audit trail?
21:57justin_smithMcDougal: the stuff about graph dbs is second hand actually, my team / tech lead tried them before I got hired, and I don't remember all the names, but I know they tried a few
21:57justin_smithMcDougal: correctness
21:57justin_smithand avoidance of some common concurrency related mistakes that happen even with a proper transactional db
21:58McDougalI'll check it out, at v least as its Rich Hickey. The graphdb I was checking out is orientdb for a recommendation engine
22:00mysamdogHey, does anyone here use dommy?
22:00mysamdogI can't seem to get scroll events to work, but click events work just fine
22:01McDougalV interesting, a free tier on Datomic, I'm def going to try that, would be a good learning experience
22:03mysamdog(dommy/listen! (dommy/sel1 :body) :click check-scroll) works, but (dommy/listen! (dommy/sel1 :body) :scroll check-scroll) doesn't
22:03McDougaljustin_smith: Is Datomic considered a relational or nosql db?
22:09mysamdogNvm, I figured it out
22:09mysamdogI replaced (dommy/sel1 :body) with js/window
22:12McDougaljustin_smith: Thanks for all your tips, much appreciated. Going through the Datomic docs.
22:59matthavener#
22:59matthavenerwhoops
23:23wegryHey all, I'm wondering if anyone has used cljs-ajax here?