2015-05-05
| 00:02 | jhn | why does (get {:a "1"} :a :z) => :z |
| 00:03 | jhn | but (get {:a "1"} :a (throw (Exception. "woops"))) => Exception woops user/eval786 (NO_SOURCE_FILE:1) |
| 00:03 | jhn | I thought that last expression would only execute if the key is not missing? |
| 00:04 | justin_smith | jhn: it's not a macro |
| 00:04 | justin_smith | jhn: so all the args are evaluated |
| 00:05 | justin_smith | it would be easy to make the macro version that does what you want, of course |
| 00:05 | jhn | ah, interesting, that makes sense. |
| 00:08 | jhn | so I ran into this ^ at https://github.com/jhn/clojure/blob/master/src/clj/clojure/gvec.clj#L458 |
| 00:09 | jhn | and according to this: http://dev.clojure.org/jira/browse/CLJ-1705 it's better to throw a more informative exception |
| 00:09 | jhn | so my simple solution is this |
| 00:09 | jhn | https://gist.github.com/jhn/b6d3e86f521ac903316f |
| 00:10 | jhn | is this good /idiomatic enough? |
| 00:23 | justin_smith | jhn: that's how I would do it if I wanted that behavior. Except for the indentation being a little off |
| 00:24 | justin_smith | also the idiomatic version of ^{:private true} is ^:private |
| 00:24 | jhn | justin_smith: I let vim do it for me :-/ what would be proper? |
| 00:24 | justin_smith | :long lining up directly under :int |
| 00:24 | justin_smith | as in the first version |
| 00:25 | justin_smith | for the metadata, the ^{:something true} version is only needed if you are setting two or more keys |
| 00:26 | jhn | what do you mean setting two or more keys? |
| 00:26 | jhn | the original version https://github.com/jhn/clojure/blob/master/src/clj/clojure/gvec.clj#L458 is not setting anything |
| 00:26 | jhn | but it has ^{:private true} |
| 00:26 | justin_smith | it's setting the :private key to true in the metadata map |
| 00:27 | justin_smith | that's only one key, so it can be replaced with ^:private |
| 00:27 | jhn | oh I see, so Rich's style is just outdated? :-) |
| 00:28 | justin_smith | now if you had ^{:private true :doc "this is a thing"} then you are setting two keys |
| 00:28 | jhn | richhickey authored on Apr 26, 2010 |
| 00:28 | jhn | i see |
| 00:28 | justin_smith | jhn: yeah, that's old code, probably had no reason to update it to the newer style |
| 00:28 | justin_smith | but for new code, you should use the current style |
| 00:28 | jhn | cool. will remove it then. |
| 00:30 | jhn | updated: https://gist.github.com/jhn/b6d3e86f521ac903316f |
| 00:31 | justin_smith | ,(meta ^:foo []) |
| 00:31 | clojurebot | {:foo true} |
| 00:32 | justin_smith | jhn: yeah, that looks good |
| 00:33 | jhn | justin_smith: thanks! |
| 00:37 | jhn | the 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:37 | jhn | http://dev.clojure.org/jira/browse/CLJ-1705 |
| 00:43 | ed-g | hello everyone. how can I return a binary stream (protocol buffer) as a Ring response? |
| 00:56 | ed-g | ok I've figured that out. |
| 00:58 | ed-g | next question. how do I read a binary file into a byte[] array? |
| 01:07 | TEttinger | ed-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:07 | TEttinger | well there probably is a way with clojure's core lib, but it wouldn't be much simpler than that |
| 01:08 | TEttinger | (java.nio.file.Files/readAllBytes "myfile.bin") |
| 01:11 | TEttinger | hm crap |
| 01:11 | TEttinger | that takes a Path not a string |
| 01:13 | TEttinger | (java.nio.file.Files/readAllBytes (java.nio.files.Paths/get "path/to/file")) |
| 01:13 | TEttinger | ed-g, that should work |
| 01:52 | lvh | Is 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:58 | ed-g | TEttinger, thank you! |
| 01:58 | TEttinger | woo! |
| 01:59 | TEttinger | lvh, IIRC using a kw as a fn actually still allows the default arg |
| 01:59 | TEttinger | ,(:not-there {} :default) |
| 01:59 | clojurebot | :default |
| 02:00 | ed-g | (inc TEttinger ) |
| 02:00 | lazybot | ⇒ 4 |
| 02:00 | TEttinger | thanks ed-g, the space after my name there thanks you |
| 02:00 | TEttinger | (identity justin_smith ) |
| 02:00 | lazybot | justin_smith has karma 9. |
| 02:01 | TEttinger | huh, 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:01 | TEttinger | (identity justin_smith) |
| 02:01 | lazybot | justin_smith has karma 250. |
| 02:01 | ed-g | TEttinger, oops. I thought the bot would tokenize |
| 02:01 | TEttinger | it's an odd one |
| 02:01 | TEttinger | it actually allows complex stuff, strange things |
| 02:02 | TEttinger | (inc #_) |
| 02:02 | lazybot | ⇒ 1 |
| 02:02 | TEttinger | (inc #_ ) |
| 02:02 | lazybot | ⇒ 1 |
| 02:02 | TEttinger | (identity #_) |
| 02:02 | lazybot | #_ has karma 1. |
| 02:03 | TEttinger | for the record, #_ does deserve more karma, it's quite useful in let bindings |
| 02:04 | lvh | TEttinger: I don't want the default, I want the exception |
| 02:05 | lvh | TEttinger: (:x m) is equivalent to (get m nil), not (get m) |
| 02:05 | TEttinger | ahhhh |
| 02:05 | TEttinger | ,(:not-there {}) |
| 02:05 | clojurebot | nil |
| 02:05 | lvh | err, (get m :x nil) and (get m :x) of course |
| 02:05 | TEttinger | ,(get {} :not-there) |
| 02:05 | clojurebot | nil |
| 02:05 | TEttinger | uh |
| 02:06 | TEttinger | you sure? |
| 02:06 | lvh | huh, I got an NPE |
| 02:07 | lvh | oh, wait; sorry, I switched between -> and ->> |
| 02:07 | lvh | I probably messed up the order there |
| 02:07 | lvh | is there a way to do map access that eagerly complains? |
| 02:37 | TEttinger | Raynes: did something change in refheap's API? I just got a paste error |
| 02:37 | TEttinger | failed to paste: peer not authenticated |
| 02:40 | sm0ke | any library for code formatting? sql, groovy etc |
| 03:48 | dfletcher | Man, 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:51 | Sizur | i'm really happy that there is a resurgence of homoiconic languages |
| 03:52 | dfletcher | it 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:52 | dfletcher | (.load root "#HBox") is a little less informative and more misleading. not loading any root anything here ;) |
| 03:54 | dfletcher | err. .lookup not .load. 1am prob time for bed hehe. |
| 04:05 | dfletcher | Hmm. Bed or put on a movie and write clojure 'till 4am? I think we all know where this is going. |
| 04:08 | dfletcher | I 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:10 | dfletcher | after init time it would ofc be treated entirely as a constant. seems a bit nicer to me than passing config into everything. |
| 04:14 | dfletcher | I 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:22 | chipf0rk | Hi! Can someone explain to me why `recur` requires >= 2 args for functions with one arg + optionals? |
| 04:28 | irctc | Can 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:33 | chipf0rk | you'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:34 | chipf0rk | #(do `(~%)) |
| 04:34 | chipf0rk | nothing to do with lazy seqs; you're just getting a symbol instead of the value you want because you quoted the entire expression |
| 04:35 | irctc | nice it works now |
| 04:35 | irctc | what is the better solution (list ) or ~ |
| 04:35 | chipf0rk | definitely list |
| 04:36 | chipf0rk | ~ requires syntax quoting which most of the time is not what you want |
| 04:36 | clojurebot | Ok. |
| 05:31 | zot | what'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:07 | dysfun | what's the easiest way to slurp a java.io.File? |
| 06:11 | oddcully | (slurp thefile)? |
| 06:12 | hyPiRion | zot: Or with the assumption that you will never use said dependency |
| 06:12 | dysfun | doesn't do that :/ |
| 06:12 | oddcully | ,(slurp (java.io.File. "/etc/passwd")) |
| 06:12 | clojurebot | #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:22 | milanj | hi |
| 06:23 | milanj | simple questio |
| 06:23 | milanj | anyone has idea why `(1 2 3) is of type Cons |
| 06:23 | milanj | and not List |
| 06:23 | milanj | if '(1 2 3) is List this looks discrepantly |
| 06:28 | Bronsa | milanj: the only guarantee you have is that () will return a seq no guarantee on the concrete type |
| 06:30 | milanj | but ` and ' should expand to similar things ? |
| 06:30 | milanj | and thus create the same type ? |
| 06:32 | Bronsa | no they don't |
| 06:32 | Bronsa | it's an implementation detail anyway |
| 06:37 | milanj | well, probably, for someone with php experience (not saying it's you) |
| 06:37 | milanj | everything is "implementation detail" |
| 06:38 | oddcully | that's the reason why ` does something else than ' in php... scnr |
| 06:39 | milanj | hah, not saying it's me anyway, just that mindset |
| 06:39 | Bronsa | milanj: not sure I understand what you're implying here. |
| 06:39 | milanj | "it's implementation detail" |
| 06:39 | milanj | shouldn't be in this case |
| 06:40 | Bronsa | why? |
| 06:40 | clojurebot | why is Why |
| 06:40 | Bronsa | milanj: there are tons of concrete seq implementations in clojure |
| 06:40 | Bronsa | (class (seq [])) |
| 06:40 | Bronsa | ,(class (seq [])) |
| 06:40 | clojurebot | nil |
| 06:40 | Bronsa | ,(class (seq [1])) |
| 06:40 | clojurebot | clojure.lang.PersistentVector$ChunkedSeq |
| 06:40 | Bronsa | ,(class (seq {1 1}])) |
| 06:40 | clojurebot | #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: ]> |
| 06:40 | Bronsa | ,(class (seq {1 1})) |
| 06:40 | clojurebot | clojure.lang.PersistentArrayMap$Seq |
| 06:40 | milanj | not connected |
| 06:40 | milanj | ' and ` should expand to same "sequence" construct code |
| 06:40 | Bronsa | except ' and ` do differnt things |
| 06:41 | Bronsa | '`() |
| 06:41 | Bronsa | ,'`() |
| 06:41 | clojurebot | (clojure.core/list) |
| 06:41 | Bronsa | ,''() |
| 06:41 | clojurebot | (quote ()) |
| 06:42 | milanj | of course they do different things |
| 06:42 | Bronsa | then why do you expect them to expand to the same code? |
| 06:43 | Bronsa | but 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:59 | noncom|2 | can anyone suggest a good code editor for clojure on android? |
| 07:05 | drguildo | is there a way of maintaining access to functions like clojure.repl/doc when switching ns inside a cider repl? |
| 07:06 | drguildo | without having to specify the full path to it |
| 07:06 | justin_smith | drguildo: you can require clojure.repl in the new ns, or use vinyasa https://github.com/zcaudate/vinyasa |
| 07:07 | drguildo | sorry should have said i meant automatically |
| 07:07 | drguildo | i'll take a look at vinyasa though thanks |
| 07:07 | justin_smith | my preference is to switch back to user for that stuff, then back into some app namespace only as needed |
| 07:07 | justin_smith | but that's not at all automatic of course |
| 07:09 | drguildo | is there a quick way to switch between namespaces in cider? |
| 07:09 | drguildo | i.e. a keybinding |
| 07:10 | justin_smith | if you eval code in some file (eg. C-M-x to load a defun) it will be evaluated in that ns |
| 07:10 | chipf0rk | C-c M-n to switch to the ns of the current file |
| 07:10 | justin_smith | without changing the ns of your repl |
| 07:12 | nilern_ | milanj: clojure prefers programming to interfaces over concrete types, i.e. ISeq and also encourages us to do so |
| 07:13 | chipf0rk | Can someone explain to me why `recur` requires >= 2 args for functions with one arg + optionals? |
| 07:13 | chipf0rk | i.e. (fn [x & xs] ... (recur (inc x))) is invalid code |
| 07:14 | justin_smith | "' and ` should expand to same "sequence" construct code" - yeah, citation needed for that "should" |
| 07:18 | mpenet | nilern_: yes! It also expands to libraries/apis, sadly not everybody thinks that way, even people you would expect to do so |
| 07:20 | mpenet | I was recently bit by an (assert (vector? arg)) in a *very* popular lib and the author rejected a patch using sequential? |
| 07:20 | justin_smith | chipf0rk: Bronsa understands the why of this better than I do, but recur targets don't use varargs normally. |
| 07:20 | justin_smith | mpenet: weird |
| 07:21 | justin_smith | mpenet: was the arg being used for indexed lookup? |
| 07:22 | mpenet | nope |
| 07:23 | mpenet | the lib is component |
| 07:23 | chipf0rk | So 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:23 | chipf0rk | And I kind of expected it to work regardless :) |
| 07:24 | mpenet | I was surprised by the answer, to say the least: https://github.com/stuartsierra/component/pull/27 |
| 07:24 | justin_smith | chipf0rk: coding to concrete type is almost always wrong in clojure |
| 07:25 | chipf0rk | sorry, not sure what you're saying? |
| 07:25 | justin_smith | chipf0rk: 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:26 | justin_smith | but instead, you can code against the interfaces / protocols (like clojure.lang.Associative), and it's not an issue |
| 07:26 | zoldar | justin_smith: I think you are adressing the wrong person :) |
| 07:26 | chipf0rk | I'm aware, I think you're confusing my convo with milanj's here |
| 07:26 | justin_smith | oops |
| 07:26 | justin_smith | sorry |
| 07:26 | TEttinger | hehe |
| 07:26 | chipf0rk | np |
| 07:26 | justin_smith | chipf0rk: recur doesn't do varargs |
| 07:27 | justin_smith | and yes that's known and I would assume intended |
| 07:31 | chipf0rk | It does seem to work as long as the varargs part consists at least of one argument |
| 07:31 | chipf0rk | which is odd |
| 07:31 | chipf0rk | If it didn't work with them at all I wouldn't be surprised |
| 07:31 | justin_smith | Bronsa: so what's the deal with recur and varargs again? |
| 07:33 | justin_smith | chipf0rk: 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:33 | lazybot | ⇒ (3 2 1) |
| 07:34 | justin_smith | or, I should say structuring - they should be provided in their "post listified" form |
| 07:35 | Bronsa | justin_smith: I actually don't remember exactly. had to do with avoiding the need for apply-recur |
| 07:35 | justin_smith | OK |
| 07:36 | justin_smith | yeah, I'it's definitely |
| 07:36 | justin_smith | err |
| 07:36 | zoldar | chipf0rk: 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:36 | justin_smith | I'd assume it's much easier to implement recur without adding the varargs logic to it |
| 07:38 | justin_smith | zoldar: that site ***umes much about substrings |
| 07:38 | justin_smith | lol |
| 07:38 | zoldar | :) |
| 07:41 | chipf0rk | had 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:41 | chipf0rk | that makes sense. thanks for the link too :) |
| 07:41 | justin_smith | chipf0rk: exactly |
| 07:41 | oddcully | well or more likely the original http://stackoverflow.com/questions/3670010/apply-recur-macro-in-clojure/3670343#3670343 |
| 07:42 | justin_smith | (inc oddcully) |
| 07:42 | lazybot | ⇒ 7 |
| 07:42 | chipf0rk | what is it with these sites that are just restyled stackoverflows |
| 07:42 | oddcully | if you rip other pages, get the code formatting right |
| 07:42 | justin_smith | there are sites that do it with irc too |
| 07:42 | justin_smith | if I search for justin_smith I find a lot of it |
| 07:43 | zoldar | harvesting content from other sites -> dodgy seo -> cash from ads |
| 07:43 | justin_smith | well, there's lots of people with my name, but throw clojure in there too |
| 07:43 | chipf0rk | well it seems to work... sadly |
| 07:44 | oddcully | yeah or just a malware catapult |
| 07:44 | chipf0rk | justin_smith: haha, is (inc ...) the way of giving out karma here? |
| 07:45 | justin_smith | chipf0rk: yessir |
| 07:45 | chipf0rk | love it |
| 07:45 | justin_smith | oddcully: 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:46 | justin_smith | the 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:48 | mpenet` | technically it's not a "cracked" version |
| 07:48 | justin_smith | sure, but that's what they called it |
| 07:50 | justin_smith | http://www.net-security.org/malware_news.php?id=3030 |
| 08:16 | Confusionist | justin_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:24 | justin_smith | heh |
| 09:00 | status402 | Is 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:02 | agarman | when integrating with a large Java application, I added necessary changes to the pom.xml |
| 09:03 | agarman | using a project.clj would result in having to maintain dependencies in two files… |
| 09:15 | status402 | agarman: So leiningen would work off a pom.xml where no project.clj is present+ |
| 09:16 | status402 | *? |
| 09:16 | clojurebot | * is just for when you are lazy and sloppy |
| 09:20 | TimMc | status402: There are plugins for Maven. |
| 09:20 | status402 | TimMC: Thanks. I'll look into it. |
| 09:21 | TimMc | status402: https://github.com/talios/clojure-maven-plugin I think |
| 10:41 | J_Arcane | Can 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:41 | J_Arcane | {}? |
| 10:50 | TimMc | PUrely from the name, one would expect nil... |
| 10:50 | TimMc | Check the source. |
| 10:53 | chipf0rk | well, I would expect {} purely from the name. so it's already worth of documentation |
| 10:53 | chipf0rk | worthy* |
| 10:54 | J_Arcane | yes, {} seems to do the trick, or at least, it returns something that checks true with empty? |
| 10:55 | chipf0rk | (empty? nil) |
| 10:55 | chipf0rk | is also true, but if that's enough of a safeguard in your case, good |
| 10:56 | J_Arcane | Yeah. |
| 10:58 | TimMc | J_Arcane: com.mongodb.DBCollection/findOne yields a DBObject, which monger then converts into a clojure-y thing. |
| 10:59 | TimMc | findOne fails to document the behavior when not found, but I bet it returns null. |
| 11:00 | TimMc | The question then is what monger does with nil... |
| 11:16 | kaiyin | i 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:18 | nkoza | kaiyin: http://docs.oracle.com/javase/7/docs/api/java/nio/MappedByteBuffer.html |
| 12:31 | lvh | How does sqlingvo compare to korma compare to honeysql? They all seem extremely similar. |
| 12:35 | sobel | I'll gladly recommend against DSLs to write DSLs at runtime |
| 12:35 | sobel | (SQL is already a DSL) |
| 12:35 | wasamasa | ^ |
| 12:35 | wasamasa | also, the clojure jdbc wrapper is surprisingly good compared to the original |
| 12:36 | sobel | it's so easy to write a clojure function to wrap sql, leave it at that |
| 12:36 | sobel | when you have horrible data structures (e.g. objects, reflection) forcing you into complex marshalling systems, maybe. but not in clojure. |
| 12:37 | sobel | the clojure jdbc wrapper is indeed good. i am pretty sure it covers everything i ever did with Spring JDBCTemplates |
| 12:38 | lvh | sobel: I'm not sure why it's more constrained to runtime than plain old SQL? |
| 12:40 | sobel | lvh: it's less about runtime than about stacking DSLs |
| 12:40 | lvh | sobel: OK. Why's that bad? |
| 12:40 | lvh | sobel: 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:40 | sobel | lvh: fundamentally, it's a leaky abstraction |
| 12:40 | sobel | the bottom isn't the only place it leaks |
| 12:41 | sobel | briefly, trivial data access patterns are already pretty dang portable, and complicated rarely get/need porting and tend to defy ORMs anyway |
| 12:43 | lvh | ok, yesql-ghosts convinced me that maybe it's not the worst idea |
| 12:43 | lvh | I'll give it a try; thanks for the suggestion |
| 12:44 | lvh | sobel: I'm assuming that you'd recommend yesql in particular as a way of just using SQL? |
| 12:46 | sobel | lvh: 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:46 | lvh | sobel: OK. What do you suggest instead? |
| 12:46 | lvh | sobel: Just strings in clj files that hold SQL queries? |
| 12:46 | sobel | lvh: isolate queries into a domain-specific library |
| 12:47 | sobel | lvh: yeah. don't create unnecessary work |
| 12:47 | lvh | That seems orthogonal to... |
| 12:47 | lvh | OK |
| 12:49 | sobel | here'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:53 | wasamasa | lvh: yesql is ok, but even that exposes the leakiness |
| 12:53 | lvh | wasamasa: why's that? |
| 12:53 | wasamasa | lvh: like, it's fixing the order of arguments |
| 12:53 | wasamasa | lvh: you also add a level of indirection by using a separate file and defqueries |
| 12:54 | wasamasa | lvh: which had me hunting a bug for half a day because I didn't know about purging the REPL namespaces :D |
| 12:55 | sobel | what's the benefit of keeping queries in a separate file? |
| 12:55 | wasamasa | you have syntax highlighting! |
| 12:56 | sobel | srsly! |
| 12:56 | wasamasa | yes |
| 12:56 | wasamasa | and it feels cleaner of course |
| 12:56 | sobel | o/~ feelings o/~ |
| 12:56 | wasamasa | but overall I'm not impressed with it, a clear API over your database adaptor delivers pretty much everything else you need |
| 12:56 | sobel | anything tangible besides syntax highlighting? |
| 12:57 | lvh | sobel: The tools are a bit nicer than just syntax highlighting, but sure |
| 12:57 | tatut | other tools can read .sql files and work with them |
| 12:57 | lvh | sobel: You can share the .sql files between projects. |
| 12:57 | sobel | i have design input based on those concerns |
| 12:58 | sobel | if 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:00 | sobel | if 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:02 | tatut | syntax highlight is evidence of *-fu? I use syntax highlighting in all langs I work with :) |
| 13:02 | tatut | of low *-fu I mean |
| 13:02 | sobel | oh, i do too, but i don't sweat it for one-liners embedded in clojure |
| 13:03 | sobel | IOW i have clojure syntax highlighted but the sql is just a string, and i don't let those get out of hand |
| 13:03 | tatut | SQL is language... not "just a string" in my opinion |
| 13:03 | sobel | i 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:04 | sobel | embedded SQL in Clojure is just a string, in the sense that it is a String |
| 13:04 | tatut | I much prefer having longer queries than doing stored procs |
| 13:04 | tatut | you have to manage and version those sprocs too |
| 13:04 | sobel | yup, they're code too |
| 13:05 | tatut | and another thing to deploy in your CI pipeline |
| 13:05 | wasamasa | btw, there are programs that can syntax-highlight multiple languages at once :P |
| 13:05 | pandeiro | does 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:05 | sobel | if you don't already test your schema in CI the process is deficient |
| 13:06 | sobel | so 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:06 | tatut | fair enough |
| 13:07 | sobel | there'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:07 | tatut | I'll still keep my longer queries instead of stored procs tho |
| 13:08 | sobel | you 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:08 | wasamasa | http://soft-dev.org/pubs/html/diekmann_tratt__eco_a_language_composition_editor/ |
| 13:08 | ruhe | how 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:09 | sobel | yesql still uses SQL |
| 13:09 | wasamasa | it's just wrappers you'd write around SQL anyways |
| 13:10 | mavbozo | pandeiro, 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:11 | mavbozo | maybe things change now |
| 13:11 | tatut | I'm still not quite sold on the benefit of "remote facades", why wouldn't you trust the app you code with db access? |
| 13:12 | sobel | tatut: because it's an unnecessary risk which, in practice, has proven untrustworthy |
| 13:12 | acyed | is anyone here a physics major? |
| 13:13 | sobel | tatut: 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:13 | acyed | I know that's kind of random, but I've done some modeling in clojure and I need a second set of eyes |
| 13:14 | tatut | sobel: but as both the app and the sprocs are code, both must be tested... why is sproc code inherently safer than app code? |
| 13:14 | sobel | tatut: 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:14 | tatut | bugs can be in either |
| 13:14 | tbaldridge | a 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:15 | sobel | tatut: because it runs in the database. and constraints are pretty rigorous code to reuse. |
| 13:15 | tbaldridge | if apps use sprocs and views, the DB structure is essentially abstracted from the app |
| 13:16 | sobel | tbaldridge: where you say sprocs and views i say remote facade |
| 13:16 | tbaldridge | exactly, I'm agreeing with you. :-) |
| 13:16 | sobel | outside of the security issues, remote facades let you decouple your schema from the app. that is valuable. |
| 13:16 | ruhe | that's why i liked to use spring jdbc along with stored procedures. it provided really nice API over sprocs |
| 13:16 | sobel | tbaldridge: yes, yes ) |
| 13:16 | sobel | :) |
| 13:16 | hiredman | man, I wish we had a dba to restructure this mess |
| 13:17 | TimMc | hahaha DBA |
| 13:17 | sobel | i really liked writing remote facades, testing with PGTap, and deploying extremely reliable code a couple jobs back |
| 13:17 | tatut | I get the abstraction part, that could be useful... but I still don't get the security part |
| 13:17 | TimMc | The only place I've worked with a true DBA there was so much territoriality about the DB. |
| 13:18 | amalloy | acyed: better to ask your actual question, and hope someone qualified sees it, than to ask for volunteers to help with an unknown task |
| 13:19 | tbaldridge | TimMc: 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:20 | tbaldridge | No 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:20 | sobel | tatut: you can harden data access in the database in ways you cannot harden it in the application. |
| 13:20 | TimMc | tbaldridge: Who ended up designing the data layout? |
| 13:20 | tatut | how, exactly? or are we getting too deep into specifics |
| 13:20 | sobel | TimMc: bad DBAs aren't an argument against DBAs. sorry you had a territorial twerp on your team. ;) |
| 13:20 | tbaldridge | TimMc: myself, another DB guy, and the main software architect |
| 13:21 | TimMc | sobel: 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:21 | TimMc | but it seemed like a situation ripe for conflict over control |
| 13:22 | TimMc | When I said "hahaha DBA" I was thinking about how lots of places don't *have* them. |
| 13:24 | sobel | tatut: 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:25 | sobel | TimMc: gotcha. in my experience DBAs are always presiding over some nominal conflict for control. |
| 13:25 | sobel | my current job has what seems to be the blasted-out remains of a battle not even valiantly fought over control of the db |
| 13:25 | sobel | (java devs won) |
| 13:26 | TimMc | I 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:26 | TimMc | Having the DBA as an optimizer and advisor makes a lot of sense to me. |
| 13:27 | VFe | The problem I see with (some) DBAs, is they focus on very abstract optimizations well ignoring practical ones. |
| 13:27 | sobel | they either have one dev that feels empowered/comfortable taking it over as a dev duty, or they just don't change much |
| 13:27 | VFe | i.e. this structure in theory runs great! except for on this hardware it doesnt |
| 13:28 | tatut | thanks guys, good talk :) |
| 13:28 | sobel | VFe: their manager should be telling them what their deliverable goal is, performance, or ... |
| 13:28 | sobel | tatut: likewise, i'm running off to lunch myself now |
| 13:28 | VFe | Though honestly that’s a problem well beyond DBAs, and has more to do with how CS educating is constantly abstracting away performance :) |
| 13:28 | sobel | no, that's squarely in the DBA role duties |
| 13:28 | acyed | http://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:29 | acyed | and the guys in #physics don't know clojure |
| 13:29 | sobel | er, sorry, i don't think CS is abstracting away performance. ask michael stonebraker if he's eschewing CS to make kickass databases. ;) |
| 13:30 | acyed | http://imgur.com/3YaI6wI this is a plot of what that program outputs. |
| 13:30 | VFe | As 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:31 | VFe | And 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:31 | sobel | what do you expect from a 4yr program not in the eng. dept? |
| 13:32 | sobel | i had more than 8yr experience before i started to have a rational clue about i/o and complexity |
| 13:32 | VFe | I see it in PhDs more than 4yrs, 4yrs dont even learn the basics anymore XD |
| 13:33 | sobel | performance is not as critical as it used to be, either. at 100MHz you just don't have the cycles to burn. |
| 13:33 | sobel | some laziness is just atrophy |
| 13:33 | VFe | Correct, though in some domains (particularly DBs) it’s still super relevant |
| 13:34 | sobel | i've always been told to view college as a generalist's certification, though. you're talking about fairly applied topics. |
| 13:34 | VFe | and 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:34 | sobel | ...DBAs have ideas, devs don't? :) |
| 13:34 | VFe | That’s clearly not what I said. |
| 13:35 | sobel | the way i figure, most the DBAs i worked with could and have done the regular dev job. but the converse is not true. |
| 13:35 | VFe | In my experience most DBAs graduate from the system admin role more than the dev side of things. |
| 13:35 | sobel | so 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:36 | VFe | It’s not uncommon for many of my clients to have DBAs with very light programming experience. |
| 13:36 | sobel | VFe: i've been lucky/choosy/sheltered in working with a lot of DBAs rooted in the developer side of the shop |
| 13:36 | sobel | but regardless of the background, perf is perf |
| 13:37 | sobel | and lunch is lunch. catch you later. |
| 13:59 | Natane | So if i want to eval a single sexp that's inside a function, what's a convenient way to do that using cider? |
| 14:00 | Natane | My repl works and all, it's just that arguments to that function can't be resolved |
| 14:00 | Natane | (for an obvious reason) |
| 14:00 | Natane | i was wondering if i can go around that |
| 14:06 | amalloy | Natane: 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:06 | amalloy | you can only eval it in an environment that contains a binding for x |
| 14:07 | amalloy | which 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:09 | Natane | yeah but say there is a long function that i wanted to debug without writing extra code anywhere |
| 14:10 | Natane | what would be the most ninja way to insert an argument? |
| 14:10 | justin_smith | Natane: write smaller functions |
| 14:10 | justin_smith | or user something like cursive or recent cider that lets you do step debugging |
| 14:11 | amalloy | the 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:11 | Natane | cider can do that? |
| 14:12 | Natane | sounds fun, thanks ^_^ |
| 14:12 | justin_smith | recent versions claim to have that feature |
| 14:12 | justin_smith | but ugrading cider can be an epic challenge |
| 14:13 | Natane | yeah my emacs broke and i just had to do that recently D: |
| 14:13 | justin_smith | yeah, cider will test your emacs-fu skills |
| 14:13 | justin_smith | and your patience sometimes |
| 14:14 | Natane | i still couldn't embed cider repl in my program! |
| 14:14 | Natane | a normal repl works just fine |
| 14:15 | Natane | wait, ninjas have climbing boots? |
| 14:15 | justin_smith | for wall climbing |
| 14:15 | amalloy | well climbing slippers, or something. they climb walls |
| 14:16 | Natane | they do? i thought they just throw shurikens |
| 14:16 | TimMc | they strap squirrels to their feet |
| 14:16 | Natane | and conceal tantos in their mouths |
| 14:17 | Natane | i mean how do you run up a wall with a knife in your mouth, that's insane |
| 14:17 | justin_smith | well, if we really knew with any accuracy what ninjas were doing, they wouldn't be good ninjas |
| 14:17 | Natane | so ninjas are like lisp functions? |
| 14:17 | Natane | that makes sense |
| 14:18 | TimMc | ninjas: non-serializable |
| 14:18 | Natane | D: |
| 14:38 | amalloy | ,(apply *' (range 1 10)) |
| 14:38 | clojurebot | 362880 |
| 14:40 | Natane | what's *'? :D |
| 14:41 | justin_smith | (doc *') |
| 14:41 | clojurebot | "([] [x] [x y] [x y & more]); Returns the product of nums. (*) returns 1. Supports arbitrary precision. See also: *" |
| 14:41 | justin_smith | arbitrary and capricious |
| 14:42 | Natane | (doc *) |
| 14:42 | clojurebot | "([] [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:42 | Natane | what's auto promotion? |
| 14:43 | Natane | actually nvm, found an article |
| 15:16 | underplank | Hi all. I’ve got the following code. https://www.refheap.com/100457 |
| 15:18 | underplank | The 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:18 | underplank | how to get around this issue. Any ideas? |
| 15:28 | lnostdal | hi, i keep getting "not a nrepl dict object: ..." when doing auto-completion via tab key .. i have company-mode enabled |
| 15:29 | JDShu | lnostdal: are you using cider? |
| 15:30 | Cust0dian | Anyone here has OP in #clojurescript? Getting spammed there. |
| 15:30 | w4ffles | wow, that's annoying |
| 16:20 | justin_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:20 | lazybot | Message saved. |
| 16:20 | justin_smith | lnostdal: do you heave the clojure-complete nrepl middleware? |
| 16:21 | justin_smith | I think cider's nrepl middleware (delivered via the cider-nrepl plugin) may give you that though? |
| 16:34 | lnostdal | justin_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:35 | justin_smith | ahh, so it didn't match the middleware you had |
| 16:50 | kaiyin | I 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:53 | sritchie | kaiyin 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:54 | kaiyin | sritchie: ok, i see, i will think about it when i start learning macros. |
| 16:54 | sritchie | kaiyin: in the meantime… just use declare :) or write stuff in order of use. |
| 16:54 | kaiyin | yeah. |
| 16:56 | amalloy | sritchie: that sounds super duper hard |
| 16:56 | sritchie | haha, first one or second one |
| 16:56 | amalloy | like you'd probably need to use tools.analyzer or something |
| 17:02 | tbaldrid_ | tools.analyzer.jvm may work quite well |
| 17:02 | tbaldrid_ | 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:03 | tbaldrid_ | Pixie does that (creates vars on demand) and it's a blessing and a curse |
| 17:04 | tbaldrid_ | misspell a var name an you now have a undefined var lying around |
| 17:04 | amalloy | yeah, but like...you don't want to do that just to allow you to write files in backwards order |
| 17:16 | TimMc | Just set Emacs to display and edit files in character reverse order. |
| 17:23 | uris77` | 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:35 | shem | one starts to look at a namespace from the bottom of the file, going upwards. from the general to the specific |
| 17:38 | Jaood | the joys of a one-pass compiler |
| 17:38 | joelkuiper | Hey, 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:38 | joelkuiper | to use the build-in type hiearchy on something other than ::stuff (things are defined in different namespaces) |
| 17:40 | joelkuiper | Would it be possible to somehow "annotate" functions or maps with the (derive x y)? |
| 17:42 | tomjack | I'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:45 | joelkuiper | tomjack: 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:45 | joelkuiper | ss as different (Reagent) components |
| 17:48 | TimMc | ~LISPers |always| turn to the back of the book first to see how it ends |
| 17:48 | clojurebot | Alles klar |
| 17:51 | joelkuiper | Ah, 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:57 | tomjack | I mean, I just don't understand why you'd want to "make sure it's of the right type" |
| 17:58 | tomjack | clojure style is to let them make the mistake, and then let a random exception or bug pop up :) |
| 17:58 | tomjack | oh, you mean a user user, huh? |
| 18:01 | tomjack | do you already know you can do ::foo/bar where (:require [com.example.foo :as foo])? |
| 18:01 | tomjack | not sure what "things are defined in different namespaces" means |
| 18:01 | joelkuiper | tomjack: yep, that really helps! |
| 18:02 | joelkuiper | tomjack: well I didn't know that a minute ago, but now I do ;-) |
| 18:03 | joelkuiper | never really used the namespace qualified symbols, nor the hierarchy things |
| 18:03 | joelkuiper | somehow they feel a bit weird, but I guess I'll get used to it |
| 18:04 | joelkuiper | tomjack: and yeah a user, it's a UI feature...the term type is perhaps a bit confusing |
| 18:15 | justin_smith | is 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:16 | justin_smith | I guess for now I won't use :reload-all when requiring my top level namespace in the repl |
| 20:53 | ambrosebs | ,(meta '^:foo a) |
| 20:53 | clojurebot | {:foo true} |
| 22:10 | l1x | hi |
| 22:11 | l1x | what 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:42 | justin_smith | ,(reduce (fn [acc [a b]] (clojure.string/replace acc a b)) (.toLowerCase "Test ?%¥") [[#" " \_][#"\?" \_][#"\?" \_]]) |
| 22:42 | clojurebot | #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:43 | justin_smith | ,(reduce (fn [acc [a b]] (clojure.string/replace acc a b)) (.toLowerCase "Test ?%¥") [[#" " "_"][#"\?" "_"][#"\?" "\"]]) |
| 22:43 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading string> |
| 22:44 | justin_smith | ,(reduce (fn [acc [a b]] (clojure.string/replace acc a b)) (.toLowerCase "Test ?%¥") [[#" " "_"][#"\?" "_"][#"\?" "\\"]]) |
| 22:44 | clojurebot | "test__%¥" |
| 22:47 | l1x | thanks justin_smith |