#clojure logs

2015-05-05

00:02jhnwhy does (get {:a "1"} :a :z) => :z
00:03jhnbut (get {:a "1"} :a (throw (Exception. "woops"))) => Exception woops user/eval786 (NO_SOURCE_FILE:1)
00:03jhnI thought that last expression would only execute if the key is not missing?
00:04justin_smithjhn: it's not a macro
00:04justin_smithjhn: so all the args are evaluated
00:05justin_smithit would be easy to make the macro version that does what you want, of course
00:05jhnah, interesting, that makes sense.
00:08jhnso I ran into this ^ at https://github.com/jhn/clojure/blob/master/src/clj/clojure/gvec.clj#L458
00:09jhnand according to this: http://dev.clojure.org/jira/browse/CLJ-1705 it's better to throw a more informative exception
00:09jhnso my simple solution is this
00:09jhnhttps://gist.github.com/jhn/b6d3e86f521ac903316f
00:10jhnis this good /idiomatic enough?
00:23justin_smithjhn: that's how I would do it if I wanted that behavior. Except for the indentation being a little off
00:24justin_smithalso the idiomatic version of ^{:private true} is ^:private
00:24jhnjustin_smith: I let vim do it for me :-/ what would be proper?
00:24justin_smith:long lining up directly under :int
00:24justin_smithas in the first version
00:25justin_smithfor the metadata, the ^{:something true} version is only needed if you are setting two or more keys
00:26jhnwhat do you mean setting two or more keys?
00:26jhnthe original version https://github.com/jhn/clojure/blob/master/src/clj/clojure/gvec.clj#L458 is not setting anything
00:26jhnbut it has ^{:private true}
00:26justin_smithit's setting the :private key to true in the metadata map
00:27justin_smiththat's only one key, so it can be replaced with ^:private
00:27jhnoh I see, so Rich's style is just outdated? :-)
00:28justin_smithnow if you had ^{:private true :doc "this is a thing"} then you are setting two keys
00:28jhnrichhickey authored on Apr 26, 2010
00:28jhni see
00:28justin_smithjhn: yeah, that's old code, probably had no reason to update it to the newer style
00:28justin_smithbut for new code, you should use the current style
00:28jhncool. will remove it then.
00:30jhnupdated: https://gist.github.com/jhn/b6d3e86f521ac903316f
00:31justin_smith,(meta ^:foo [])
00:31clojurebot{:foo true}
00:32justin_smithjhn: yeah, that looks good
00:33jhnjustin_smith: thanks!
00:37jhnthe ticket in question says "Affects Version/s: Release 1.4, Release 1.6" — does this mean that I'd have to checkout the respective tags from the git repo and apply my changes in each one separately?
00:37jhnhttp://dev.clojure.org/jira/browse/CLJ-1705
00:43ed-ghello everyone. how can I return a binary stream (protocol buffer) as a Ring response?
00:56ed-gok I've figured that out.
00:58ed-gnext question. how do I read a binary file into a byte[] array?
01:07TEttingered-g: there isn't a way in clojure's core lib, but you have access to all of java's core lib too, which includes https://docs.oracle.com/javase/8/docs/api/java/nio/file/Files.html#readAllBytes-java.nio.file.Path-
01:07TEttingerwell there probably is a way with clojure's core lib, but it wouldn't be much simpler than that
01:08TEttinger(java.nio.file.Files/readAllBytes "myfile.bin")
01:11TEttingerhm crap
01:11TEttingerthat takes a Path not a string
01:13TEttinger(java.nio.file.Files/readAllBytes (java.nio.files.Paths/get "path/to/file"))
01:13TEttingered-g, that should work
01:52lvhIs it idiomatic clojure to not use a kw as a fn and instead use get, when you want an early exception if a key is missing?
01:58ed-gTEttinger, thank you!
01:58TEttingerwoo!
01:59TEttingerlvh, IIRC using a kw as a fn actually still allows the default arg
01:59TEttinger,(:not-there {} :default)
01:59clojurebot:default
02:00ed-g(inc TEttinger )
02:00lazybot⇒ 4
02:00TEttingerthanks ed-g, the space after my name there thanks you
02:00TEttinger(identity justin_smith )
02:00lazybotjustin_smith has karma 9.
02:01TEttingerhuh, my bonus-space karma is going up at a faster rate than justin_smith's bonus-space karma despite the actual karma being different
02:01TEttinger(identity justin_smith)
02:01lazybotjustin_smith has karma 250.
02:01ed-gTEttinger, oops. I thought the bot would tokenize
02:01TEttingerit's an odd one
02:01TEttingerit actually allows complex stuff, strange things
02:02TEttinger(inc #_)
02:02lazybot⇒ 1
02:02TEttinger(inc #_ )
02:02lazybot⇒ 1
02:02TEttinger(identity #_)
02:02lazybot#_ has karma 1.
02:03TEttingerfor the record, #_ does deserve more karma, it's quite useful in let bindings
02:04lvhTEttinger: I don't want the default, I want the exception
02:05lvhTEttinger: (:x m) is equivalent to (get m nil), not (get m)
02:05TEttingerahhhh
02:05TEttinger,(:not-there {})
02:05clojurebotnil
02:05lvherr, (get m :x nil) and (get m :x) of course
02:05TEttinger,(get {} :not-there)
02:05clojurebotnil
02:05TEttingeruh
02:06TEttingeryou sure?
02:06lvhhuh, I got an NPE
02:07lvhoh, wait; sorry, I switched between -> and ->>
02:07lvhI probably messed up the order there
02:07lvhis there a way to do map access that eagerly complains?
02:37TEttingerRaynes: did something change in refheap's API? I just got a paste error
02:37TEttingerfailed to paste: peer not authenticated
02:40sm0keany library for code formatting? sql, groovy etc
03:48dfletcherMan, I really appreciate how much clojure reads out like English sometimes. Two neat ones from this file I'm looking at: (.load fxml stream) (.lookup node "#HBox") both doing exactly what they say :)
03:51Sizuri'm really happy that there is a resurgence of homoiconic languages
03:52dfletcherit affects my naming of things a bit. "node" was a better choice than "root" so resulting code reads much nicer. and "fxml" instead of "loader" similarly.
03:52dfletcher(.load root "#HBox") is a little less informative and more misleading. not loading any root anything here ;)
03:54dfletchererr. .lookup not .load. 1am prob time for bed hehe.
04:05dfletcherHmm. Bed or put on a movie and write clojure 'till 4am? I think we all know where this is going.
04:08dfletcherI decided to go with this neat thing for parsing command line opts https://github.com/clojure/tools.cli .. does anyone think it's a terrible idea to re-def a global after parsing args and let rest of program read that? else pass it around everywhere?
04:10dfletcherafter init time it would ofc be treated entirely as a constant. seems a bit nicer to me than passing config into everything.
04:14dfletcherI guess the example does pass the results down into everything. Hmm. Alright nevermind talked myself into it I'll go as clean as possible.
04:22chipf0rkHi! Can someone explain to me why `recur` requires >= 2 args for functions with one arg + optionals?
04:28irctcCan someone explain what is going on here (first (first (map #(do '(%)) (range)))). It returns p1__4908#. Probably it has something to do with lazy seqs. If i do not wrap the % in a list it works as expected.
04:33chipf0rkyou're quoting the list containing the unique symbol that clojure generated to use instead of %. if you want to construct a list, use list. for this specific way of doing things, you could use syntax-quote with splicing instead:
04:34chipf0rk#(do `(~%))
04:34chipf0rknothing to do with lazy seqs; you're just getting a symbol instead of the value you want because you quoted the entire expression
04:35irctcnice it works now
04:35irctcwhat is the better solution (list ) or ~
04:35chipf0rkdefinitely list
04:36chipf0rk~ requires syntax quoting which most of the time is not what you want
04:36clojurebotOk.
05:31zotwhat's really happening when using :exclusions in a project.clj? are the named things just "dropped" with the assumption that some other dependency fulfills the need?
06:07dysfunwhat's the easiest way to slurp a java.io.File?
06:11oddcully(slurp thefile)?
06:12hyPiRionzot: Or with the assumption that you will never use said dependency
06:12dysfundoesn't do that :/
06:12oddcully,(slurp (java.io.File. "/etc/passwd"))
06:12clojurebot#error{:cause "denied", :via [{:type java.lang.SecurityException, :message "denied", :at [clojurebot.sandbox$enable_security_manager$fn__887 invoke "sandbox.clj" 69]}], :trace [[clojurebot.sandbox$enable_security_manager$fn__887 invoke "sandbox.clj" 69] [clojurebot.sandbox.proxy$java.lang.SecurityManager$Door$f500ea40 checkRead nil -1] [java.io.FileInputStream <init> "FileInputStream.java" 135] [c...
06:22milanjhi
06:23milanjsimple questio
06:23milanjanyone has idea why `(1 2 3) is of type Cons
06:23milanjand not List
06:23milanjif '(1 2 3) is List this looks discrepantly
06:28Bronsamilanj: the only guarantee you have is that () will return a seq no guarantee on the concrete type
06:30milanjbut ` and ' should expand to similar things ?
06:30milanjand thus create the same type ?
06:32Bronsano they don't
06:32Bronsait's an implementation detail anyway
06:37milanjwell, probably, for someone with php experience (not saying it's you)
06:37milanjeverything is "implementation detail"
06:38oddcullythat's the reason why ` does something else than ' in php... scnr
06:39milanjhah, not saying it's me anyway, just that mindset
06:39Bronsamilanj: not sure I understand what you're implying here.
06:39milanj"it's implementation detail"
06:39milanjshouldn't be in this case
06:40Bronsawhy?
06:40clojurebotwhy is Why
06:40Bronsamilanj: there are tons of concrete seq implementations in clojure
06:40Bronsa(class (seq []))
06:40Bronsa,(class (seq []))
06:40clojurebotnil
06:40Bronsa,(class (seq [1]))
06:40clojurebotclojure.lang.PersistentVector$ChunkedSeq
06:40Bronsa,(class (seq {1 1}]))
06:40clojurebot#<RuntimeException java.lang.RuntimeException: Unmatched delimiter: ]>
06:40Bronsa,(class (seq {1 1}))
06:40clojurebotclojure.lang.PersistentArrayMap$Seq
06:40milanjnot connected
06:40milanj' and ` should expand to same "sequence" construct code
06:40Bronsaexcept ' and ` do differnt things
06:41Bronsa'`()
06:41Bronsa,'`()
06:41clojurebot(clojure.core/list)
06:41Bronsa,''()
06:41clojurebot(quote ())
06:42milanjof course they do different things
06:42Bronsathen why do you expect them to expand to the same code?
06:43Bronsabut the most important question is -- why do you care what concrete implementation is returned? again, there's no mention on the doc about the returned class
06:59noncom|2can anyone suggest a good code editor for clojure on android?
07:05drguildois there a way of maintaining access to functions like clojure.repl/doc when switching ns inside a cider repl?
07:06drguildowithout having to specify the full path to it
07:06justin_smithdrguildo: you can require clojure.repl in the new ns, or use vinyasa https://github.com/zcaudate/vinyasa
07:07drguildosorry should have said i meant automatically
07:07drguildoi'll take a look at vinyasa though thanks
07:07justin_smithmy preference is to switch back to user for that stuff, then back into some app namespace only as needed
07:07justin_smithbut that's not at all automatic of course
07:09drguildois there a quick way to switch between namespaces in cider?
07:09drguildoi.e. a keybinding
07:10justin_smithif you eval code in some file (eg. C-M-x to load a defun) it will be evaluated in that ns
07:10chipf0rkC-c M-n to switch to the ns of the current file
07:10justin_smithwithout changing the ns of your repl
07:12nilern_milanj: clojure prefers programming to interfaces over concrete types, i.e. ISeq and also encourages us to do so
07:13chipf0rkCan someone explain to me why `recur` requires >= 2 args for functions with one arg + optionals?
07:13chipf0rki.e. (fn [x & xs] ... (recur (inc x))) is invalid code
07:14justin_smith"' and ` should expand to same "sequence" construct code" - yeah, citation needed for that "should"
07:18mpenetnilern_: yes! It also expands to libraries/apis, sadly not everybody thinks that way, even people you would expect to do so
07:20mpenetI was recently bit by an (assert (vector? arg)) in a *very* popular lib and the author rejected a patch using sequential?
07:20justin_smithchipf0rk: Bronsa understands the why of this better than I do, but recur targets don't use varargs normally.
07:20justin_smithmpenet: weird
07:21justin_smithmpenet: was the arg being used for indexed lookup?
07:22mpenetnope
07:23mpenetthe lib is component
07:23chipf0rkSo this is known and "intended" behaviour? I'm aware that this isn't standard coding style, but it made for a really succinct reimplementation of `trampoline` in 4clojure challenges
07:23chipf0rkAnd I kind of expected it to work regardless :)
07:24mpenetI was surprised by the answer, to say the least: https://github.com/stuartsierra/component/pull/27
07:24justin_smithchipf0rk: coding to concrete type is almost always wrong in clojure
07:25chipf0rksorry, not sure what you're saying?
07:25justin_smithchipf0rk: for example {:a 0} returns a PersistentArrayMap and if you assoc enough keys onto it you get a PersistentHashMap back. If you coded against those types, it would be a pain in the ass
07:26justin_smithbut instead, you can code against the interfaces / protocols (like clojure.lang.Associative), and it's not an issue
07:26zoldarjustin_smith: I think you are adressing the wrong person :)
07:26chipf0rkI'm aware, I think you're confusing my convo with milanj's here
07:26justin_smithoops
07:26justin_smithsorry
07:26TEttingerhehe
07:26chipf0rknp
07:26justin_smithchipf0rk: recur doesn't do varargs
07:27justin_smithand yes that's known and I would assume intended
07:31chipf0rkIt does seem to work as long as the varargs part consists at least of one argument
07:31chipf0rkwhich is odd
07:31chipf0rkIf it didn't work with them at all I wouldn't be surprised
07:31justin_smithBronsa: so what's the deal with recur and varargs again?
07:33justin_smithchipf0rk: the args need to be there, but the vararg destructuring is not done ##((fn [a & args] (if (empty? args) a (recur (conj a (first args)) (rest args)))) nil 1 2 3)
07:33lazybot⇒ (3 2 1)
07:34justin_smithor, I should say structuring - they should be provided in their "post listified" form
07:35Bronsajustin_smith: I actually don't remember exactly. had to do with avoiding the need for apply-recur
07:35justin_smithOK
07:36justin_smithyeah, I'it's definitely
07:36justin_smitherr
07:36zoldarchipf0rk: here's a bit dated but probably still accurate explanation of handling varargs in the context recur by Michal Marczyk: http://programming.nullanswer.com/forum/1377301
07:36justin_smithI'd assume it's much easier to implement recur without adding the varargs logic to it
07:38justin_smithzoldar: that site ***umes much about substrings
07:38justin_smithlol
07:38zoldar:)
07:41chipf0rkhad to think about this for a moment, so you're saying this only works because we're using `rest` and thus providing something that is already a list as pseudo-varargs?
07:41chipf0rkthat makes sense. thanks for the link too :)
07:41justin_smithchipf0rk: exactly
07:41oddcullywell or more likely the original http://stackoverflow.com/questions/3670010/apply-recur-macro-in-clojure/3670343#3670343
07:42justin_smith(inc oddcully)
07:42lazybot⇒ 7
07:42chipf0rkwhat is it with these sites that are just restyled stackoverflows
07:42oddcullyif you rip other pages, get the code formatting right
07:42justin_smiththere are sites that do it with irc too
07:42justin_smithif I search for justin_smith I find a lot of it
07:43zoldarharvesting content from other sites -> dodgy seo -> cash from ads
07:43justin_smithwell, there's lots of people with my name, but throw clojure in there too
07:43chipf0rkwell it seems to work... sadly
07:44oddcullyyeah or just a malware catapult
07:44chipf0rkjustin_smith: haha, is (inc ...) the way of giving out karma here?
07:45justin_smithchipf0rk: yessir
07:45chipf0rklove it
07:45justin_smithoddcully: speaking of, the other day I was reading about a mail anonymizer, where on their home page had a link to a cracked copy of the app (normally cost $200+). The cracked copy was a trojan that added your computer to their mailer relay botnet.
07:46justin_smiththe fact that they went ahead and said "here's the cracked version if you don't want to pay for it" on their own site is hilarious
07:48mpenet`technically it's not a "cracked" version
07:48justin_smithsure, but that's what they called it
07:50justin_smithhttp://www.net-security.org/malware_news.php?id=3030
08:16Confusionistjustin_smith, they could have been upfront about that feature (that is now considered a trojan) and just called it the 'payment-in-kind edition'
08:24justin_smithheh
09:00status402Is there a way to integrate with Java that doesn't involve Leiningen subsuming the whole project? I'm wondering if I could just sort of stick the Clojure project in a subdirectory.
09:02agarmanwhen integrating with a large Java application, I added necessary changes to the pom.xml
09:03agarmanusing a project.clj would result in having to maintain dependencies in two files…
09:15status402agarman: So leiningen would work off a pom.xml where no project.clj is present+
09:16status402*?
09:16clojurebot* is just for when you are lazy and sloppy
09:20TimMcstatus402: There are plugins for Maven.
09:20status402TimMC: Thanks. I'll look into it.
09:21TimMcstatus402: https://github.com/talios/clojure-maven-plugin I think
10:41J_ArcaneCan anyone here who's used Monger tell me what a find-one-as-map returns if the item isn't found? Because the docs sure don't seem to.
10:41J_Arcane{}?
10:50TimMcPUrely from the name, one would expect nil...
10:50TimMcCheck the source.
10:53chipf0rkwell, I would expect {} purely from the name. so it's already worth of documentation
10:53chipf0rkworthy*
10:54J_Arcaneyes, {} seems to do the trick, or at least, it returns something that checks true with empty?
10:55chipf0rk(empty? nil)
10:55chipf0rkis also true, but if that's enough of a safeguard in your case, good
10:56J_ArcaneYeah.
10:58TimMcJ_Arcane: com.mongodb.DBCollection/findOne yields a DBObject, which monger then converts into a clojure-y thing.
10:59TimMcfindOne fails to document the behavior when not found, but I bet it returns null.
11:00TimMcThe question then is what monger does with nil...
11:16kaiyini have a 0.1M by 20M matrix that i want to store on harddisk but also make it accessible from clojure without needing to read the entire thing into ram, could anyone suggestion a solution?
11:18nkozakaiyin: http://docs.oracle.com/javase/7/docs/api/java/nio/MappedByteBuffer.html
12:31lvhHow does sqlingvo compare to korma compare to honeysql? They all seem extremely similar.
12:35sobelI'll gladly recommend against DSLs to write DSLs at runtime
12:35sobel(SQL is already a DSL)
12:35wasamasa^
12:35wasamasaalso, the clojure jdbc wrapper is surprisingly good compared to the original
12:36sobelit's so easy to write a clojure function to wrap sql, leave it at that
12:36sobelwhen you have horrible data structures (e.g. objects, reflection) forcing you into complex marshalling systems, maybe. but not in clojure.
12:37sobelthe clojure jdbc wrapper is indeed good. i am pretty sure it covers everything i ever did with Spring JDBCTemplates
12:38lvhsobel: I'm not sure why it's more constrained to runtime than plain old SQL?
12:40sobellvh: it's less about runtime than about stacking DSLs
12:40lvhsobel: OK. Why's that bad?
12:40lvhsobel: I could see why it falls down if you want to express something in the bottom DSL that the top one can't express.
12:40sobellvh: fundamentally, it's a leaky abstraction
12:40sobelthe bottom isn't the only place it leaks
12:41sobelbriefly, trivial data access patterns are already pretty dang portable, and complicated rarely get/need porting and tend to defy ORMs anyway
12:43lvhok, yesql-ghosts convinced me that maybe it's not the worst idea
12:43lvhI'll give it a try; thanks for the suggestion
12:44lvhsobel: I'm assuming that you'd recommend yesql in particular as a way of just using SQL?
12:46sobellvh: not sure why you'd assume that. i see little reason to isolate application queries into files and use that defquery macro to integrate them. i don't see that as valuable.
12:46lvhsobel: OK. What do you suggest instead?
12:46lvhsobel: Just strings in clj files that hold SQL queries?
12:46sobellvh: isolate queries into a domain-specific library
12:47sobellvh: yeah. don't create unnecessary work
12:47lvhThat seems orthogonal to...
12:47lvhOK
12:49sobelhere's the thing. you already have a jdbc library. you won't reuse any part of the domain access library. it will need modification as your schema grows/changes. or maybe reimplementation if the data system changes significantly.
12:53wasamasalvh: yesql is ok, but even that exposes the leakiness
12:53lvhwasamasa: why's that?
12:53wasamasalvh: like, it's fixing the order of arguments
12:53wasamasalvh: you also add a level of indirection by using a separate file and defqueries
12:54wasamasalvh: which had me hunting a bug for half a day because I didn't know about purging the REPL namespaces :D
12:55sobelwhat's the benefit of keeping queries in a separate file?
12:55wasamasayou have syntax highlighting!
12:56sobelsrsly!
12:56wasamasayes
12:56wasamasaand it feels cleaner of course
12:56sobelo/~ feelings o/~
12:56wasamasabut overall I'm not impressed with it, a clear API over your database adaptor delivers pretty much everything else you need
12:56sobelanything tangible besides syntax highlighting?
12:57lvhsobel: The tools are a bit nicer than just syntax highlighting, but sure
12:57tatutother tools can read .sql files and work with them
12:57lvhsobel: You can share the .sql files between projects.
12:57sobeli have design input based on those concerns
12:58sobelif you really find that syntax highlighting is that useful, either your sql-fu is insufficient or the size of query you are cramming into the application adapter is too big. you should probably consider a stored proc or view to keep that under control. the bigger the query, the more likely it tightly couples your app to the schema and that coupling is something you need to manage.
13:00sobelif you really find that you need to share sql between projects, you might consider that either your sql-fu is insufficient or the size of the query you are cramming into the app...blah blah blah...implement a remote facade pattern to share useful access patterns you want to expose to applications. if they are really sharing access patterns, let them share a library too. a sql file isn't a great way to share code though.
13:02tatutsyntax highlight is evidence of *-fu? I use syntax highlighting in all langs I work with :)
13:02tatutof low *-fu I mean
13:02sobeloh, i do too, but i don't sweat it for one-liners embedded in clojure
13:03sobelIOW i have clojure syntax highlighted but the sql is just a string, and i don't let those get out of hand
13:03tatutSQL is language... not "just a string" in my opinion
13:03sobeli did not say or mean to imply using syntax highlighting is evidence of low skill, so much as if it's necessary to have it for the tiny bits of sql in your application interfaces
13:04sobelembedded SQL in Clojure is just a string, in the sense that it is a String
13:04tatutI much prefer having longer queries than doing stored procs
13:04tatutyou have to manage and version those sprocs too
13:04sobelyup, they're code too
13:05tatutand another thing to deploy in your CI pipeline
13:05wasamasabtw, there are programs that can syntax-highlight multiple languages at once :P
13:05pandeirodoes anyone have experience using session cookies with single page apps that do CORS requests to a different host or port? my api server is returning the Set-Cookie header but it seems like the browser (Chrome) is ignoring it
13:05sobelif you don't already test your schema in CI the process is deficient
13:06sobelso the "more work" argument holds no weight with me. if you have a database and don't test it you're missing a spot.
13:06tatutfair enough
13:07sobelthere's also the simple fact that applications can't always be trusted with db access, and we have to implement remote facades just to protect from malicious queries
13:07tatutI'll still keep my longer queries instead of stored procs tho
13:08sobelyou can do that, and you can rip them out of clojure to edit them in a syntax-aware buffer. it's not that hard but it's harder than keeping my stuff in adapter code simple, since my scope includes all the sprocs anyway
13:08wasamasahttp://soft-dev.org/pubs/html/diekmann_tratt__eco_a_language_composition_editor/
13:08ruhehow do you construct your yesql-based code (or any other similar framework) if you need to translate complex query from complex search form into SQL? Are there examples of such code on github?
13:09sobelyesql still uses SQL
13:09wasamasait's just wrappers you'd write around SQL anyways
13:10mavbozopandeiro, i tried it quite some time ago, and i find that my server can not set cookie for different domain other than its own domain
13:11mavbozomaybe things change now
13:11tatutI'm still not quite sold on the benefit of "remote facades", why wouldn't you trust the app you code with db access?
13:12sobeltatut: because it's an unnecessary risk which, in practice, has proven untrustworthy
13:12acyedis anyone here a physics major?
13:13sobeltatut: ask any DBA at a finance agency how many times the max loan size trigger has been tripped by an app gone haywire, attempting to create loans for untold millions. if i hadn't seen it in person i wouldn't be such a proponent of using databases as full safety backstops.
13:13acyedI know that's kind of random, but I've done some modeling in clojure and I need a second set of eyes
13:14tatutsobel: but as both the app and the sprocs are code, both must be tested... why is sproc code inherently safer than app code?
13:14sobeltatut: it's entirely possible for an application to become compromised in a way that can be mitigated by appropriate role restrictions and data constraints in the database
13:14tatutbugs can be in either
13:14tbaldridgea nice thing about using sprocs is that it allows the DBAs to completely re-write the structure of tables under an app, and the app will never know
13:15sobeltatut: because it runs in the database. and constraints are pretty rigorous code to reuse.
13:15tbaldridgeif apps use sprocs and views, the DB structure is essentially abstracted from the app
13:16sobeltbaldridge: where you say sprocs and views i say remote facade
13:16tbaldridgeexactly, I'm agreeing with you. :-)
13:16sobeloutside of the security issues, remote facades let you decouple your schema from the app. that is valuable.
13:16ruhethat's why i liked to use spring jdbc along with stored procedures. it provided really nice API over sprocs
13:16sobeltbaldridge: yes, yes )
13:16sobel:)
13:16hiredmanman, I wish we had a dba to restructure this mess
13:17TimMchahaha DBA
13:17sobeli really liked writing remote facades, testing with PGTap, and deploying extremely reliable code a couple jobs back
13:17tatutI get the abstraction part, that could be useful... but I still don't get the security part
13:17TimMcThe only place I've worked with a true DBA there was so much territoriality about the DB.
13:18amalloyacyed: better to ask your actual question, and hope someone qualified sees it, than to ask for volunteers to help with an unknown task
13:19tbaldridgeTimMc: eh, it can depend on the Job. One place I worked, I was basically the DBA, and all that meant was I handled all sproc implementations and optimizations. Why? Because I was good at it, the only reason.
13:20tbaldridgeNo reason for the entire team to learn all the ins and outs of a query engine, just tell one guy (or two or three), and let him spend the time to get it all working properly.
13:20sobeltatut: you can harden data access in the database in ways you cannot harden it in the application.
13:20TimMctbaldridge: Who ended up designing the data layout?
13:20tatuthow, exactly? or are we getting too deep into specifics
13:20sobelTimMc: bad DBAs aren't an argument against DBAs. sorry you had a territorial twerp on your team. ;)
13:20tbaldridgeTimMc: myself, another DB guy, and the main software architect
13:21TimMcsobel: Oh, they weren't necessarily *bad* -- for all I know, they were defending the DB from people who wanted to abuse it. I was front-end on that job, so I don't know the specifics.
13:21TimMcbut it seemed like a situation ripe for conflict over control
13:22TimMcWhen I said "hahaha DBA" I was thinking about how lots of places don't *have* them.
13:24sobeltatut: it's a great question you can get fully fleshed out on #postgresql but the short version is, databases have a scope-limited duty that makes them a good target for enforcing relations and constraints. then there are some things only a sproc can do (upsert for one popular example)
13:25sobelTimMc: gotcha. in my experience DBAs are always presiding over some nominal conflict for control.
13:25sobelmy current job has what seems to be the blasted-out remains of a battle not even valiantly fought over control of the db
13:25sobel(java devs won)
13:26TimMcI have some trouble understanding who would manage the data layout if there's a DBA because it's so intricately coupled with the code.
13:26TimMcHaving the DBA as an optimizer and advisor makes a lot of sense to me.
13:27VFeThe problem I see with (some) DBAs, is they focus on very abstract optimizations well ignoring practical ones.
13:27sobelthey either have one dev that feels empowered/comfortable taking it over as a dev duty, or they just don't change much
13:27VFei.e. this structure in theory runs great! except for on this hardware it doesnt
13:28tatutthanks guys, good talk :)
13:28sobelVFe: their manager should be telling them what their deliverable goal is, performance, or ...
13:28sobeltatut: likewise, i'm running off to lunch myself now
13:28VFeThough honestly that’s a problem well beyond DBAs, and has more to do with how CS educating is constantly abstracting away performance :)
13:28sobelno, that's squarely in the DBA role duties
13:28acyedhttp://pastebin.com/AeT1MYc9 This is a program I've written to model the trajectory of a 105mm howitzer round side fired from a C-130 to predict the impact point of the bullet. I'm having a hell of a time getting the solution right (I have a ballistics table that gives me the gun depression and lag angles for most altitudes and airspeed). This is more of a physics question, not a clojure question, but I've been working on it for two we
13:29acyedand the guys in #physics don't know clojure
13:29sobeler, sorry, i don't think CS is abstracting away performance. ask michael stonebraker if he's eschewing CS to make kickass databases. ;)
13:30acyedhttp://imgur.com/3YaI6wI this is a plot of what that program outputs.
13:30VFeAs a CS educator I’d disagree, I consistently see programs that graduate people with no understanding of low level performance(and how high level abstractions utilize(or dont) it)
13:31VFeAnd I see that repeated throughout the industry as a result(people who have a firm understanding of logical performance but no grasp of why it may not work on real metal)
13:31sobelwhat do you expect from a 4yr program not in the eng. dept?
13:32sobeli had more than 8yr experience before i started to have a rational clue about i/o and complexity
13:32VFeI see it in PhDs more than 4yrs, 4yrs dont even learn the basics anymore XD
13:33sobelperformance is not as critical as it used to be, either. at 100MHz you just don't have the cycles to burn.
13:33sobelsome laziness is just atrophy
13:33VFeCorrect, though in some domains (particularly DBs) it’s still super relevant
13:34sobeli've always been told to view college as a generalist's certification, though. you're talking about fairly applied topics.
13:34VFeand I was just commenting that I see a lot of the fighting between devs and DBAs in my experience, stems from the mismatch of their ideas on performance
13:34sobel...DBAs have ideas, devs don't? :)
13:34VFeThat’s clearly not what I said.
13:35sobelthe way i figure, most the DBAs i worked with could and have done the regular dev job. but the converse is not true.
13:35VFeIn my experience most DBAs graduate from the system admin role more than the dev side of things.
13:35sobelso when it comes to a question of merits, i seem to side with DBAs culturally. but that is a simple misapprehension of the choice made. it's political hell for me, though.
13:36VFeIt’s not uncommon for many of my clients to have DBAs with very light programming experience.
13:36sobelVFe: i've been lucky/choosy/sheltered in working with a lot of DBAs rooted in the developer side of the shop
13:36sobelbut regardless of the background, perf is perf
13:37sobeland lunch is lunch. catch you later.
13:59NataneSo if i want to eval a single sexp that's inside a function, what's a convenient way to do that using cider?
14:00NataneMy repl works and all, it's just that arguments to that function can't be resolved
14:00Natane(for an obvious reason)
14:00Natanei was wondering if i can go around that
14:06amalloyNatane: i mean, the arguments to that function don't exist, you can't eval the sexp without them. how do you eval (+ x 2)?
14:06amalloyyou can only eval it in an environment that contains a binding for x
14:07amalloywhich could be ((fn [x] (+ x 2)) 5), as your function is usually called, or you could eval (let [x 5] (+ x 2)) if you want to eval a subsection of it selectively
14:09Nataneyeah but say there is a long function that i wanted to debug without writing extra code anywhere
14:10Natanewhat would be the most ninja way to insert an argument?
14:10justin_smithNatane: write smaller functions
14:10justin_smithor user something like cursive or recent cider that lets you do step debugging
14:11amalloythe most ninja way would be with some kind of sword, and climbing boots. but i presume you are looking for a software-developer way
14:11Natanecider can do that?
14:12Natanesounds fun, thanks ^_^
14:12justin_smithrecent versions claim to have that feature
14:12justin_smithbut ugrading cider can be an epic challenge
14:13Nataneyeah my emacs broke and i just had to do that recently D:
14:13justin_smithyeah, cider will test your emacs-fu skills
14:13justin_smithand your patience sometimes
14:14Natanei still couldn't embed cider repl in my program!
14:14Natanea normal repl works just fine
14:15Natanewait, ninjas have climbing boots?
14:15justin_smithfor wall climbing
14:15amalloywell climbing slippers, or something. they climb walls
14:16Natanethey do? i thought they just throw shurikens
14:16TimMcthey strap squirrels to their feet
14:16Nataneand conceal tantos in their mouths
14:17Natanei mean how do you run up a wall with a knife in your mouth, that's insane
14:17justin_smithwell, if we really knew with any accuracy what ninjas were doing, they wouldn't be good ninjas
14:17Nataneso ninjas are like lisp functions?
14:17Natanethat makes sense
14:18TimMcninjas: non-serializable
14:18NataneD:
14:38amalloy,(apply *' (range 1 10))
14:38clojurebot362880
14:40Natanewhat's *'? :D
14:41justin_smith(doc *')
14:41clojurebot"([] [x] [x y] [x y & more]); Returns the product of nums. (*) returns 1. Supports arbitrary precision. See also: *"
14:41justin_smitharbitrary and capricious
14:42Natane(doc *)
14:42clojurebot"([] [x] [x y] [x y & more]); Returns the product of nums. (*) returns 1. Does not auto-promote longs, will throw on overflow. See also: *'"
14:42Natanewhat's auto promotion?
14:43Nataneactually nvm, found an article
15:16underplankHi all. I’ve got the following code. https://www.refheap.com/100457
15:18underplankThe issue is that if an exception is thrown somewhere in the let block then the cleanup that happens on the last two lines dont happen. Which when running with auto-refresh means all the other tests fail. I imagine that I need to use a (try (…) (finally)) block. but thats difficult as if I put it outside the let, then then finally doesnt have lexical scope, and If i put it within, then I can catch the whole thing. Im not sur
15:18underplankhow to get around this issue. Any ideas?
15:28lnostdalhi, i keep getting "not a nrepl dict object: ..." when doing auto-completion via tab key .. i have company-mode enabled
15:29JDShulnostdal: are you using cider?
15:30Cust0dianAnyone here has OP in #clojurescript? Getting spammed there.
15:30w4ffleswow, that's annoying
16:20justin_smith$mail underplank define a promise in an outer let block, wrap try/catch/finally around the inner and deliver to that promise, clean up the thing delivered to the promise in the finally, but only if (realized? p) returns true
16:20lazybotMessage saved.
16:20justin_smithlnostdal: do you heave the clojure-complete nrepl middleware?
16:21justin_smithI think cider's nrepl middleware (delivered via the cider-nrepl plugin) may give you that though?
16:34lnostdaljustin_smith, uhm, sorry, i had to go afk for a bit there ..it turned out to be a version problem; my cider in emacs was too new
16:35justin_smithahh, so it didn't match the middleware you had
16:50kaiyinI really hate the fact that the order of function definition matters in clojure, is there a way around this? I know I can use (declare ...), it's still tedious.
16:53sritchiekaiyin you could make a special defn macro that walks code and automatically declares any symbols in the fn position that it can’t find in the environment?
16:54kaiyinsritchie: ok, i see, i will think about it when i start learning macros.
16:54sritchiekaiyin: in the meantime… just use declare :) or write stuff in order of use.
16:54kaiyinyeah.
16:56amalloysritchie: that sounds super duper hard
16:56sritchiehaha, first one or second one
16:56amalloylike you'd probably need to use tools.analyzer or something
17:02tbaldrid_tools.analyzer.jvm may work quite well
17:02tbaldrid_there's a hook that it calls when it wants to find a var, just have that fn create the var, and you're done
17:03tbaldrid_Pixie does that (creates vars on demand) and it's a blessing and a curse
17:04tbaldrid_misspell a var name an you now have a undefined var lying around
17:04amalloyyeah, but like...you don't want to do that just to allow you to write files in backwards order
17:16TimMcJust set Emacs to display and edit files in character reverse order.
17:23uris77`I actually like that clojure forces you to define the functions before you use them. It is how I tend to think in other languages also, so haven't found it to be much of a problem.
17:35shemone starts to look at a namespace from the bottom of the file, going upwards. from the general to the specific
17:38Jaoodthe joys of a one-pass compiler
17:38joelkuiperHey, I'm trying to use/make a rudimentray type hierarchy in ClojureScript. The problem I hope to solve is the following: I have a series of (reagent) components that I want to be of a certain "type", such that when a user add a component I can make sure it's of the right type (and filter option lists with isa? or decendants). However, I'm not sure multimethods are appropriate, and I'm also not sure how
17:38joelkuiper to use the build-in type hiearchy on something other than ::stuff (things are defined in different namespaces)
17:40joelkuiperWould it be possible to somehow "annotate" functions or maps with the (derive x y)?
17:42tomjackI'm not sure that "when a user add a component I can make sure it's of the right type" actually describes a problem
17:45joelkuipertomjack: yea, you're right. It's more explained in this blog post https://joelkuiper.eu/knowledge; but in short there are a bunch of UI components that can be nested, however they can only be nested at certain places. For example a Markdown block is a Text block, but so is a plain text one. Similarly a sliders is a Number input, but so is a Number field. There is a hierchy of types that I wish to expre
17:45joelkuiperss as different (Reagent) components
17:48TimMc~LISPers |always| turn to the back of the book first to see how it ends
17:48clojurebotAlles klar
17:51joelkuiperAh, I guess I can just do some book keeping somewhere on the namespace-qualified symbols. Might not be pretty, but I guess it would work
17:57tomjackI mean, I just don't understand why you'd want to "make sure it's of the right type"
17:58tomjackclojure style is to let them make the mistake, and then let a random exception or bug pop up :)
17:58tomjackoh, you mean a user user, huh?
18:01tomjackdo you already know you can do ::foo/bar where (:require [com.example.foo :as foo])?
18:01tomjacknot sure what "things are defined in different namespaces" means
18:01joelkuipertomjack: yep, that really helps!
18:02joelkuipertomjack: well I didn't know that a minute ago, but now I do ;-)
18:03joelkuipernever really used the namespace qualified symbols, nor the hierarchy things
18:03joelkuipersomehow they feel a bit weird, but I guess I'll get used to it
18:04joelkuipertomjack: and yeah a user, it's a UI feature...the term type is perhaps a bit confusing
18:15justin_smithis there a trick to using core.async with component? ava.lang.ClassCastException: clojure.core.async.impl.timers.TimeoutQueueEntry cannot be cast to clojure.core.async.impl.timers.TimeoutQueueEntry
18:16justin_smithI guess for now I won't use :reload-all when requiring my top level namespace in the repl
20:53ambrosebs,(meta '^:foo a)
20:53clojurebot{:foo true}
22:10l1xhi
22:11l1xwhat is the best way to use reduce to apply the more computation to the output of the previous function? (map #(clojure.string/replace (.toLowerCase "test string") (first %) (second %)) '([#" " "_"] [#"\?" "_"] [#"\%" "_"]))
22:42justin_smith,(reduce (fn [acc [a b]] (clojure.string/replace acc a b)) (.toLowerCase "Test ?%¥") [[#" " \_][#"\?" \_][#"\?" \_]])
22:42clojurebot#error{:cause "java.lang.Character cannot be cast to clojure.lang.IFn", :via [{:type java.lang.ClassCastException, :message "java.lang.Character cannot be cast to clojure.lang.IFn", :at [clojure.string$replace_by invoke "string.clj" 67]}], :trace [[clojure.string$replace_by invoke "string.clj" 67] [clojure.string$replace invoke "string.clj" 106] [sandbox$eval25$fn__27 invoke "NO_SOURCE_FILE" 0] [c...
22:43justin_smith,(reduce (fn [acc [a b]] (clojure.string/replace acc a b)) (.toLowerCase "Test ?%¥") [[#" " "_"][#"\?" "_"][#"\?" "\"]])
22:43clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading string>
22:44justin_smith,(reduce (fn [acc [a b]] (clojure.string/replace acc a b)) (.toLowerCase "Test ?%¥") [[#" " "_"][#"\?" "_"][#"\?" "\\"]])
22:44clojurebot"test__%¥"
22:47l1xthanks justin_smith