2013-12-29
| 00:00 | bitemyapp | arrdem: I might need to get in on your win-streak. |
| 00:00 | bitemyapp | arrdem: down? |
| 00:00 | arrdem | bitemyapp: I can do one more |
| 00:00 | Tolstoy | dnolen: regarding your recent changes on OM getting rid of the "owner" thing... you mention it's now passed in via the constructor. Are you going back to no-local-component-state? |
| 00:06 | bitemyapp | arrdem: my microphone isn't showing up in mumble or in Ubuntu in general. |
| 00:06 | arrdem | bitemyapp: ....funky |
| 00:07 | bitemyapp | arrdem: trying to decide if one game is worth reboot. |
| 00:07 | arrdem | heh. if not I'll just hit the sack. you're keeping me up :P |
| 00:07 | arrdem | scrub that./ |
| 00:07 | arrdem | executive decision, I'm sleeping. |
| 00:07 | arrdem | g'night |
| 00:07 | bitemyapp | arrdem: good idea. Cheers. |
| 00:29 | yedi_ | anyone know of any typeahead / autocomplete libs for cljs? |
| 00:31 | yedi_ | nvm apparently dnolen has a blogpost where he builds one |
| 00:34 | dnolen | Tolstoy: what od you mean? |
| 00:34 | dnolen | s/od/do |
| 00:35 | dnolen | Tolstoy: I just want to remove pointless duplication from the life cycle protocol methods |
| 00:35 | Tolstoy | dnolen: In my practice app, I used the "owner" stuff to hold form data (similar to your todo example). |
| 00:35 | Tolstoy | dnolen: But now the protocols don't take owner. |
| 00:35 | Tolstoy | dnolen: So now I don't know where it is. ;) |
| 00:36 | dnolen | Tolstoy: the component fn takes it |
| 00:36 | dnolen | Tolstoy: the function that makes your component |
| 00:37 | Tolstoy | dnolen: Your todo app example still has those params. |
| 00:37 | Tolstoy | dnolen: Is it an additional param, or just the first param (which is my app state)? |
| 00:37 | dnolen | Tolstoy: yeah was on a plane and didn't get a chance to update TodoMVC |
| 00:37 | dnolen | Tolstoy: updated now |
| 00:37 | Tolstoy | Ah, second param. |
| 00:40 | Tolstoy | Cool, works. ;) |
| 01:24 | Tolstoy | If you want to dismiss a form, how do you tell the owning component not to "build" it anymore? |
| 01:31 | dnolen | Tolstoy: just don't put it in the dom |
| 01:32 | Tolstoy | dnolen: That was my plan, but when the user hits "cancel" I can put a message in a core/async channel, but I'm not sure how to propagate that back to the "thing" that renders it. |
| 01:32 | Tolstoy | dnolen: Except to have the presence/absence be in the "state" object. |
| 01:32 | dnolen | Tolstoy: the parent component can pass a communication channel down the tree |
| 01:32 | dnolen | Tolstoy: if you look at TodoMVC that's how todo deletion works |
| 01:33 | dnolen | Tolstoy: so you pass down a cancel channel, if you ever get anything off of it you can set the state on the parent |
| 01:33 | Tolstoy | dnolen: Hm. |
| 01:34 | Tolstoy | dnolen: Ah, and put it in a go form so as not to block rendering. Great! |
| 02:02 | rhg135 | I had |
| 02:02 | rhg135 | oops |
| 02:02 | rhg135 | wrong window lol |
| 03:41 | yedi_ | can you use alt! within a function (so not explicitly within a go loop) |
| 03:50 | shaunxcode | "Makes a single choice between one of several channel operations, as if by alts!, returning the value of the result expr corresponding to the operation completed. Must be called inside a (go ...) block." |
| 04:18 | yedi_ | does anyone know why adding print statements seem to get these map functions to work? https://gist.github.com/yedi/8168773 |
| 04:18 | yedi_ | kinda baffling me |
| 04:29 | TEttinger | yedi_, try changing map to mapv and remove the print |
| 04:29 | TEttinger | is the problem still resolved? |
| 04:30 | TEttinger | mapv does not return a lazy sequence |
| 04:30 | TEttinger | map does |
| 04:30 | TEttinger | print realizes lazy sequences... |
| 04:31 | yedi_ | ahh makes sense, that did the trick |
| 04:31 | yedi_ | (inc TEttinger) |
| 04:31 | lazybot | ⇒ 9 |
| 04:31 | yedi_ | long overdue |
| 04:32 | TEttinger | sustenance! |
| 05:08 | Ayey_ | I'm trying to read a file line by line, and then add thoses lines to some kind of collection. This is what i came up with http://hastebin.com/minaranota.lisp (It is clojure).. I'm stil new to clojure and properly stuck in some imperativ thought process.. |
| 05:13 | ivan | Ayey_: you can replace the entire doseq with (vec (line-seq rdr)) |
| 05:13 | Clome | ayey_: why do not you use slurp to read the whole file and then use split on a newline |
| 05:13 | ivan | since the vector will be returned, you can get rid of the let |
| 05:14 | magnars | Ayey_: if you're sticking all the lines in memory anyway, you can just (str/split (slurp file-path) #"\n") |
| 05:14 | magnars | Ayey_: where str/ is clojure.string/ |
| 05:15 | ivan | why do protocol methods in clojurescript start with a -? |
| 05:16 | magnars | Ayey_: the reason to use with-open and line-seq is to run over the file contents without "holding onto the head", to avoid keeping the entire file in memory. |
| 05:17 | shock_one | Hi, guys. I'm trying to get a bunch of GET requests asynchronously using http-kit, but execution stops before all the callbacks are called. Is there a way to wait until all of them are finished? Here's the code (the commented out chunk work well, but is too slow) https://gist.github.com/anonymous/f18480ccb99b90abe30a |
| 05:17 | Ayey_ | Ahh, thank you guys for all the soultions |
| 05:19 | magnars | shock_one: sounds like the poster child example for clojure.core.async |
| 05:20 | amalloy | magnars, shock_one: that -main has no effect at all, aside from creating an unrealized lazy sequence. http-kit is already async, there's no pressing need to introduce core.async |
| 05:20 | ivan | somewhere in https://www.youtube.com/watch?v=enwIIGzhahw I saw an example of core.async + httpkit |
| 05:20 | amalloy | shock_one: (dorun (map ...)) would probably do all the work, although i'm not sure of http-kit's details |
| 05:23 | magnars | amalloy: you say http-kit is already async, but isn't the idea behind core.async to help you work effectively with async code? |
| 05:24 | amalloy | magnars: i mean, yes, but currently he's at the "working at all" stage, not "working effectively". there is no place in that code where core.async would make anything easier |
| 05:25 | magnars | thanks for clarifying :) |
| 05:25 | shock_one | amalloy: nope, doesn't work. The thing is that dorun finishes execution sooner than any of the requests get a chance to be finished. Are you familiar with node.js? This http-kit callbacks look exactly like node's except that node automatically tracks callbacks and doesn't exit the process before the callbacks counter is 0. |
| 05:29 | shock_one | Essentially the question is how would I know that all the callbacks are executed. |
| 05:31 | amalloy | i dunno how http-hit manages its callbacks. it may have some mechanism for doing this, or you can roll one yourself with promises or something |
| 05:31 | amalloy | (or, indeed, core.async channels) |
| 06:11 | shock_one | Here's how I managed to do that. Any suggestions how to improve this code? https://gist.github.com/anonymous/74d26af46b69add418c6 |
| 06:18 | amalloy | it's easier if you just create 200 promises and block on each of them in turn |
| 06:32 | shock_one | But what if the 3rd request is finished before the 1st? I'll have to wait for the 1st even though I could meanwhile do some useful work. |
| 06:35 | shock_one | Actually I tried that. The time difference is huge, about 100 times. |
| 06:40 | shock_one | On the server it gets 1000 requests just instantly, but if I increase the number to, say, 100000, I get an error "BindException java.net.BindException: Cannot assign requested address". I believe it's because I don't have enough open ports. Is there a way to open sockets intelligently — without exceeding the port range? |
| 06:45 | Glenjamin | shock_one: i don't know about a built-in way, but you could create an outgoing connection pool abstraction, and have it catch those errors and wait for an existing connection to complete before doing more |
| 06:50 | alex_batsuev | Hello |
| 06:50 | alex_batsuev | Could you please suggest best tutorials/book for learning clojure? :) |
| 06:56 | hyPiRion | http://www.clojurebook.com/ |
| 06:57 | alex_batsuev | thx |
| 07:29 | jph- | is there a way to break out of while true? |
| 07:29 | jph- | oh |
| 07:29 | jph- | sorry thats stupid q |
| 07:33 | JanxSpirit | anyone familiar with composure routes? |
| 07:33 | JanxSpirit | compojure |
| 07:57 | Maruinslun | I did not expect this many people to be in here. |
| 07:59 | jph- | anyone familiar with working with udp responses |
| 07:59 | jph- | im trying to decode a udp response, but i need to wait till it completes... which is kinda hard with udp |
| 08:01 | ivan | in general you build a reliable protocol on top of udp to handle most of your data |
| 08:01 | Maruinslun | Yup. |
| 08:04 | ivan | you almost certainly need a good understanding of how TCP works |
| 08:06 | ivan | are you working with an existing UDP service that has zero docs or a single proprietary client or something? |
| 08:09 | jph- | ivan, my current approach is to stuff response into a future udp receiver |
| 08:09 | jph- | then to do a try block to decode the received udp data |
| 08:09 | jph- | if it dies because incomplete |
| 08:09 | jph- | recur |
| 08:09 | jph- | and concat prior data with next data |
| 08:09 | jph- | and try to decode again |
| 08:10 | ivan | I guess you might have to do that if it's the only way to do it |
| 08:10 | jph- | yeh |
| 08:10 | jph- | theres no "EOF" equiv with what i'm working with |
| 08:10 | jph- | but if it decodes properly, that's good enough for me |
| 08:10 | jph- | heh |
| 08:10 | jph- | soi just keep reading data, building up the received data and attempting to decode till it works |
| 08:11 | ivan | I feel like that might go into an endless loop if you lose a packet and never finish a read |
| 08:11 | ivan | endless because you get more packets from a subsequent response |
| 08:14 | ivan | anyway, watch out because any packet can get lost or reordered |
| 08:15 | ivan | if possible try to talk some sense into whoever is running this UDP service |
| 08:27 | jph- | ivan, yep, thankfully i can smack the udp service dev around |
| 08:27 | ivan | most people choose UDP for no good reason |
| 08:27 | jph- | heh |
| 08:27 | jph- | this is for admin interface to a network service |
| 08:27 | ivan | demand some framed TCP data or something |
| 08:27 | jph- | i dont really think that aspect needs udp |
| 08:28 | jph- | especially since 9/10 you'll be connecting to service running on localhost |
| 09:16 | s0x | hey guys, is there a way to unset a defmulti in repl? atm its kind of a hazzle to play around with multimethods using lighttable, cause im not able to overwrite it and therefore have to define new methods all the time |
| 09:17 | s0x | or even better, does anyone know how to reset the lighttable repl results |
| 09:19 | hyPiRion | s0x: (.removeMethod multifn dispatch-value) |
| 09:20 | hyPiRion | so if you do (defmulti foo identity) and (defmethod foo 10 [_] 11), then (.removeMethod foo 10) would remove the method |
| 09:20 | s0x | actually not one implementation but the mutlimethod itself |
| 09:25 | s0x | oh well ... i've got the one (ns-unmap *ns* 'foo) will do the job |
| 09:25 | s0x | still i dont see the point why lighttable does not allow to reset the repl over all ... anyway ... |
| 09:26 | hyPiRion | Time consuming |
| 09:29 | sherbondy | s0x: what about in the "connect" tab? Is that not the kind of reset you're talking about? |
| 09:30 | sherbondy | and maybe https://github.com/clojure/tools.namespace would be helpful for what you're trying to do? If you find the need to "reset" things, as you say |
| 09:32 | s0x | sherbondy: well, i was searching for a conventient way like calling just a command rather then do a disconnect ... and add a new connection again |
| 09:33 | s0x | sherbondy: well that think looks quite interesting ... still would prefere a easy and fast way to do it provided by the ide |
| 09:33 | s0x | i dont need it for production but for testing |
| 09:42 | sherbondy | s0x: I'm still not quite sure what you're trying to achieve, but you may well find the repl part of tools.namespace to be just what you're looking for. Seems like you could use it for testing. You might enjoy reading this post too if you have a few minutes: http://thinkrelevance.com/blog/2013/06/04/clojure-workflow-reloaded |
| 09:50 | s0x | sherbondy: thx for that one :) |
| 09:51 | s0x | well, i was just wondering how to reset the running repl in lighttable or codewise ... using this workflow i'd actually avoid it :p |
| 11:20 | patrickod | I'm having issues with the home and end keys in the leiningen repl on OS X. googling hasn't helped much. Has anyone here had a similar issue? |
| 11:21 | justin_smith | patrickod: what are they doing? |
| 11:21 | patrickod | instead of working they both input a ~ character |
| 11:22 | justin_smith | lein repl should be using readline, so likely the answer is in your readline config |
| 11:22 | justin_smith | or the configuration of the terminal you are using |
| 11:22 | justin_smith | I assume home and end work in regular bash? |
| 11:22 | patrickod | actually, it's only present when the repl session is in tmux. |
| 11:22 | justin_smith | do you have rlwrap installed? |
| 11:22 | patrickod | yeah so this is an issue introduced by tmux I think. lein repl in iTerm works as expected |
| 11:23 | justin_smith | lein repl uses it if it is available |
| 11:23 | diadara | I have just started with clojure koans, is there a way to run lein koans run directly from emacs ? |
| 11:23 | justin_smith | and it should handle these things as well as bash does |
| 11:23 | patrickod | nope I don't have it. but I'll install it now and see if it helps |
| 11:23 | justin_smith | rlwrap is also going to be better than the fake java based readline |
| 11:23 | justin_smith | in general |
| 11:24 | patrickod | hrmm rlwrap still causes issues. |
| 11:24 | justin_smith | diadara: well, you can open M-x eshell and lein run from there |
| 11:24 | justin_smith | patrickod: oh, odd |
| 11:24 | patrickod | justin_smith yeah going to search around and see if it's a known tmux issue |
| 11:25 | justin_smith | patrickod: I wonder if is a tmux termcap issue |
| 11:25 | justin_smith | yeah, jynx |
| 11:25 | patrickod | hrmm could be an issue with my TERM variable |
| 11:27 | justin_smith | diadara: emacs has a few ways to host another process, eshell is a pretty easy way to do it. Maybe cider has something fancier by now? I am still using the outdated nrepl because upgrading from slime to nrepl was such a pain I don't feel like repeating it quite yet |
| 11:27 | diadara | justin_smith: emacs question,but the path will be different right ? |
| 11:28 | justin_smith | diadara: by default the current directory is the directory of the current window's buffer |
| 11:28 | justin_smith | so if you start eshell while looking at project.clj, it will be in the right place to run lein |
| 11:28 | justin_smith | or you can use cd to put it in the right place |
| 11:29 | diadara | justin_smith: aah, just found projectile-lein-test-cmd variable ! |
| 11:30 | justin_smith | OK. I don't use projectile. Good luck. |
| 11:48 | danneu | Does anyone have a Clojurescript workflow in Emacs that's better than copy and pasting cljs source into clojure.browser.repl? |
| 11:49 | danneu | I really need to level up my workflow |
| 11:49 | CaptainLex | I'm having an astonishing issue. Whenever I read a time from my Postgres database, the time that gets read in is 12 hours off of the time in the database. Have anyone ever encountered a similar issue? |
| 11:50 | justin_smith | CaptainLex: what OS? |
| 11:50 | justin_smith | and by any chance are you in a time zone that is 12 hours away from GMT? |
| 11:52 | CaptainLex | justin_smith: Arch Linux. Haha nope, I'm in CST. But wait a minute, I've misunderstood the problem. The time read in from the database is in UTC, and represents the real time from the database. However, when clj-time displays the time, it gets the hours rights but the AM/PM wrong |
| 11:52 | CaptainLex | That is to say |
| 11:53 | justin_smith | CaptainLex: maybe it is an issue with your TZ config - or how the jvm understands your tz config |
| 11:53 | justin_smith | like a -5 where there should be a +5 |
| 11:53 | CaptainLex | 19:30 CST in the datavase -> 03:30 UTC immediately after reading -> 07:30 CST after to-local-date-time |
| 11:54 | CaptainLex | justin_smith: Perhaps! I've never been one to bother much with my localization settings |
| 11:54 | justin_smith | I can imagine flipping the sign on a timezone offset would be an easy mistake to make |
| 11:54 | danneu | CaptainLex: is it possible that you're just using the wrong clj-time formatter? |
| 11:55 | justin_smith | ##(System/getProperty "user.timezone") |
| 11:55 | lazybot | java.security.AccessControlException: access denied (java.util.PropertyPermission user.timezone read) |
| 11:56 | justin_smith | anyway, what does the above show you CaptainLex ? |
| 11:56 | justin_smith | (System/getProperty "user.timezone") --> "America/Los_Angeles" |
| 11:58 | justin_smith | parsimony wise, your jvm is more likely to be misconfigured than your system, and your system being misconfigured is more likely than your system clock being wrong, and all of thsoe are more likely than the libraries being broken - that is my hunch at least |
| 11:58 | CaptainLex | US/Central |
| 11:59 | CaptainLex | Oh wait a minute |
| 11:59 | CaptainLex | Lemme test a thing real quick |
| 12:00 | justin_smith | what does date --utc output in your shell? |
| 12:02 | ddellacosta | danneu: these days I simply leave lein cljsbuild auto running, to be honest. But I *thought* you could set up a repl in emacs using cider + austin, and send to your running CLJS repl that way. I could be mistaken, but it would be worth looking into. |
| 12:07 | CaptainLex | justin_smith: Sun Dec 29 17:01:55 UTC 2 |
| 12:08 | justin_smith | CaptainLex: so it looks like your timezone setting, and your OS time setting are both correct |
| 12:08 | justin_smith | is the postgres server local? |
| 12:10 | CaptainLex | justin_smith: Yes it is. I'm currently trying to see if I'm misunderstanding clj-time.local |
| 12:11 | ddellacosta | danneu: for the record, just tried setting it up now, seems to work! |
| 12:11 | danneu | ddellacosta: thanks, austin looks good |
| 12:12 | ddellacosta | danneu: cheers. |
| 12:13 | justin_smith | CaptainLex: by any chance is central time currently GMT-6 ? |
| 12:14 | justin_smith | if so applying the offset twice would replicate your error |
| 12:14 | CaptainLex | justin_smith: My understanding is that it is |
| 12:14 | CaptainLex | So it would! |
| 12:14 | CaptainLex | Hmmmm |
| 12:15 | justin_smith | CaptainLex: I am going out for breakfast, I will be back later, but likely you will have figured this out by then |
| 12:15 | justin_smith | bbl |
| 12:16 | CaptainLex | justin_smith: Enjoy! And thank you for help so far! |
| 12:20 | mrhanky | can anybody give me a hint how i can get all keys from js localstorage in clojurescript? |
| 12:20 | mrhanky | i tried (for), but this wont work |
| 12:23 | justin_smith | mrhanky: any chance keys would work? |
| 12:23 | justin_smith | or is it not a compatible structure? |
| 12:24 | justin_smith | ,(keys {:a 0 :b 1 :c 2}) |
| 12:24 | clojurebot | (:a :c :b) |
| 12:25 | mrhanky | justin_smith, like this? |
| 12:25 | mrhanky | (def storage (.-localStorage js/window)) |
| 12:25 | mrhanky | (for [x (keys storage)] x) |
| 12:26 | mrhanky | #<Error: No protocol method ISeqable.-seq defined for type object: [object Storage]> |
| 12:27 | Glenjamin | mrhanky: it seems like it has a weird interface |
| 12:27 | Glenjamin | see http://stackoverflow.com/questions/3138564/looping-through-localstorage-in-html5-and-javascript |
| 12:28 | mrhanky | i don't get it |
| 12:28 | mrhanky | -it +how to get this into clojure(script) |
| 12:29 | dnolen | mrhanky: if you want standard library fns to work on Storage you need to extend it to the right protocols |
| 12:29 | Glenjamin | i'm not great at clojurescript, but if you can get a protocol for localStorage, you could implement Seq on it |
| 12:30 | Glenjamin | but you basically need to call key a bunch of times |
| 12:30 | dnolen | mrhanky: otherwise use the JS apis |
| 12:31 | dnolen | mrhanky: http://stackoverflow.com/questions/5410820/how-can-i-show-all-the-localstorage-saved-variables |
| 12:32 | Glenjamin | I'm seeing in this when using "lein ring uberjar" - If you only need AOT for your uberjar, consider adding :aot :all into your:uberjar profile instead. |
| 12:32 | Glenjamin | does anyone know where i can find more info about whether this is a good idea? |
| 12:45 | mrhanky | i got it: (for [x (range 0 (.-length (.-localStorage js/window)))] (.key storage x)) |
| 12:48 | mrhanky | is anybody here using intellij idea for clj/cljs dev? |
| 12:49 | CaptainLex | Isn't that the one where the extension is deprecated or some such a business? Or is that Netbeans? |
| 12:51 | CaptainLex | justin_smith: The problem was a misunderstanding on my part on how to display localized times in clj-time |
| 12:51 | mrhanky | at the moment there are two extensions for intellij, the "la clojure" from jetbrains and theres a new one which im currently using, called "cursive". there will be an clojure IDE based on intellij community edition and cursive |
| 12:52 | patrickod | https://github.com/paraseba/lein-reload how would I go about using this with leiningen 2? I've tried adding a :dev profile with this listed as a dependency |
| 12:52 | patrickod | but running lein with-profile dev interactive doesn't work. |
| 12:53 | patrickod | sorry if this is has an obvious answer that I'm missing, I'm new to clojure and the differences between leiningen 1 and 2 are tripping me up a bit it would seem |
| 12:56 | hyPiRion | patrickod: that project seems so old that it uses things no longer within leiningen (lein interactive) |
| 12:56 | patrickod | hyPiRion hrmm ok. I found another plugin that does something similar on the leiningin plugins page |
| 12:56 | hyPiRion | Is the use case you need autotesting? |
| 12:57 | hyPiRion | ah, okay |
| 12:57 | patrickod | nope it was that when editing code and using a repl I'd like the ability to reload the files that have been changed |
| 12:57 | patrickod | or have the repl do it itself |
| 12:57 | hyPiRion | ah |
| 13:16 | JasonFelice | Say I want to make a gnuplot-type graph in Clojure. What's the best way to do this? |
| 13:21 | rovar | JasonFelice: probably load a graphing library in java |
| 13:21 | rovar | also maybe check out http://incanter.org/ |
| 13:53 | bbloom | dnolen: lol i love that om has an "ecosystem" already, heh |
| 13:58 | justin_smith | CaptainLex: glad you got it sorted out |
| 13:58 | CaptainLex | justin_smith: Thanks! And now of course on to a new problem, as per usual :P |
| 13:59 | justin_smith | in the tooling, or your code? |
| 13:59 | CaptainLex | justin_smith: In my code. It's in a different domain, though. It's about reading in parameters via compojure where multiple values correspond to one key |
| 14:07 | marcopolo` | anyone use vim with the solarized theme? |
| 14:19 | codelahoma | marcopolo`: sometimes. Why? |
| 14:21 | marcopolo` | codelahoma: The color of the parens are red, which are also the color of mismatched parens :( |
| 14:21 | marcopolo` | codelahoma: So I'm messing around with colors right now, did you find a solution? |
| 14:25 | Glenjamin | Hi guys, for a web app, would you generally recommend using a variety of small services, or one "big" process? |
| 14:25 | codelahoma | marcopolo`: I use rainbow_parentheses.vim with the colors suggested here: http://www.deepbluelambda.org/programming/clojure/programming-clojure-with-vim-2013-edition |
| 14:25 | Glenjamin | eg. Should sessions be stored in memory, or put in an external store |
| 14:26 | Glenjamin | likewise for a queue, delayed jobs, etc etc |
| 14:26 | codelahoma | marcopolo`: Red still shows up, but I also use paredit so a mismatch is pretty rare. :-) |
| 14:26 | bbloom | Glenjamin: sessions should almost always be stored exclusively in cookies... |
| 14:26 | Glenjamin | i've always deferred such things to external processes, but i've noticed some clojure people just throwing these into an atom - which i guess is similar to how jboss stuff would be done? |
| 14:27 | Glenjamin | bbloom: there's an http overhead tradeoff there, but i take your point - that may not be the best example |
| 14:27 | bbloom | Glenjamin: how many users are you expecting to have on day one? And what about on day 100? day 1000? |
| 14:27 | Glenjamin | <100 |
| 14:28 | bbloom | then the correct answer is single process. full stop |
| 14:28 | bbloom | Glenjamin: also, i have an article for just this purpose: http://www.brandonbloom.name/blog/2013/06/26/slurp-and-spit/ |
| 14:28 | bbloom | :-) |
| 14:28 | Glenjamin | i'm more worried about losing things during a restart than scalability |
| 14:28 | bbloom | my post covers that too |
| 14:28 | patrickod | is there an idiomatic way to use if-let and destructuring when a function returns a vector? |
| 14:29 | bbloom | ,(if-let [[x y] [5 10]] true false) |
| 14:29 | clojurebot | true |
| 14:29 | bbloom | ,(if-let [[x y] [5 10]] x false) |
| 14:29 | clojurebot | 5 |
| 14:29 | bbloom | ,(if-let [[x y] nil] x false) |
| 14:29 | clojurebot | false |
| 14:29 | bbloom | patrickod: is that what you want? |
| 14:29 | Glenjamin | patrickod: are you wanting the if to check one of the items in the vector? |
| 14:29 | marcopolo` | codelahoma: thanks for that link! |
| 14:30 | patrickod | Glenjamin I'm looking to check teh first item in the vector |
| 14:30 | Bronsa | ,(if-let [[a b] []] true false) ;; this screwed me over more than once |
| 14:30 | clojurebot | true |
| 14:30 | Glenjamin | yeah |
| 14:30 | marcopolo` | codelahoma: I can't handle paredit though, sometimes I just need to delete a paren, and it doesn't let me |
| 14:30 | justin_smith | marcopolo`: that is what M-w is for |
| 14:30 | patrickod | ,(if-let [[a b] [false {:error "Not valid"}] "Valid" "Not valid") |
| 14:30 | clojurebot | #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: )> |
| 14:30 | Glenjamin | bbloom: oh, i just remembered - i'm currently running on heroku |
| 14:30 | patrickod | ,(if-let [[a b] [false {:error "Not valid"}]] "Valid" "Not valid") |
| 14:30 | clojurebot | "Valid" |
| 14:31 | marcopolo` | justin_smith: on emacs? I'm using vim, what's M-w do? |
| 14:31 | patrickod | Glenjamin in the case above I'm looking to get "not valid". Make sense? |
| 14:31 | Glenjamin | yeah |
| 14:31 | justin_smith | marcopolo`: delete region |
| 14:31 | Glenjamin | if think you'll need a custom macro |
| 14:32 | patrickod | hmm not a problem. I can just forego error messages at the moment |
| 14:32 | bbloom | Glenjamin: you should still read my article. the same ideas apply to non-filesystem situations |
| 14:32 | Glenjamin | bbloom: the advice seems solid, although it feels a bit "eggs in basket", which habit forces me away from |
| 14:32 | bbloom | Bronsa: yeah, clojure's destructuring is not pattern matching, until if-let and when-let were introduced, then they became broken pattern matching :-P |
| 14:32 | Glenjamin | but that me be habit rather than experience |
| 14:32 | Glenjamin | *may be |
| 14:33 | justin_smith | marcopolo`: d`<m> would be the vim equivalent iirc |
| 14:33 | justin_smith | with <m> being a specific letter mark |
| 14:33 | codelahoma | marcopolo`: to each there own, but I'd suggest giving the full paredit help file a read before writing it off entirely. |
| 14:33 | bbloom | Glenjamin: i'd rather have all my eggs in one simple basket then spread the same amount of wicker out between many baskets |
| 14:33 | Glenjamin | seems reasonable |
| 14:33 | bbloom | Glenjamin: backups. they are useful :-P |
| 14:34 | justin_smith | marcopolo`: that is to say, go to start of area to delete, 'ma', go to other end of area to delte 'd`a' |
| 14:34 | Glenjamin | mm, intuition tells me know - but i can't see a logical reason not to just serialise to disk |
| 14:34 | justin_smith | unless vim paraedit is much stricter than emacs paredit is |
| 14:34 | Glenjamin | s/know/no/ |
| 14:34 | bbloom | Glenjamin: your intuition has been poisoned by years of frameworks |
| 14:34 | Glenjamin | mm |
| 14:35 | codelahoma | marcopolo`: for a single character, <Ctrl-V, d> works for me, but that might be a paredit bug. |
| 14:35 | Bronsa | bbloom: it's just.. too tempting to expect if-let to return false in that case. ofc it would be wrong and it's just a matter of calling `seq` on [], but it still fools me sometimes |
| 14:35 | Glenjamin | so given that i have a read-only filesystem, any suggestions for what simple storage mechanism i should use for serialising? |
| 14:36 | bbloom | ,(when-let [[x x] [5 10] x) ; Bronsa: This is the one that got me early on |
| 14:36 | clojurebot | #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: )> |
| 14:36 | bbloom | ,(when-let [[x x] [5 10]] x) ; Bronsa: This is the one that got me early on |
| 14:36 | clojurebot | 10 |
| 14:39 | marcopolo` | codelahoma: I used paredit for a month, and I can find ways around deleting a specific paren (I think I did x or r<space>), but yeah I wasn't sold on it. I did love the slurping/barfing. So I'm using vim-sexp now, which doesn't modify insert behavior |
| 14:40 | marcopolo` | codelahoma: I tweaked the colors of errors to make them more visible in the vim solarized theme: https://github.com/MarcoPolo/vim-colors-solarized |
| 14:40 | codelahoma | marcopolo`: I'm less than a month into it, so maybe I'll become disenchanted as well. |
| 14:41 | Glenjamin | damn disconnect, so - what's the next simplest thing to a filesystem for spit/splurping EDN? I'm thinking maybe redis? |
| 14:41 | marcopolo` | codelahoma: I've been using vim-sexp with Tim Pope's mappings (https://github.com/tpope/vim-sexp-mappings-for-regular-people) and I'm pretty happy with it so far |
| 14:42 | marcopolo` | justin_smith: I feel like I should learn emacs enough to try out it's paredit. I hear it's much better than vim's implementation |
| 14:44 | justin_smith | marcopolo`: it's nothing to be undertaken lightly, but having learned vim you probably have some idea of that. |
| 14:55 | marcopolo` | justin_smith: yeah, haha. On second thought, I might just ask my emacs friends to demo it :P |
| 15:01 | patrickod | what are strings encased in #{} ? are they special types? |
| 15:01 | patrickod | they're sets? |
| 15:01 | bbloom | ,(class #{"like this?"}) ; pretty easy to figure out at the repl! |
| 15:01 | clojurebot | clojure.lang.PersistentHashSet |
| 15:02 | patrickod | bbloom wasn't aware of the class method. neat :) thanks |
| 15:02 | bbloom | but yeah, #{} is just set notation |
| 15:02 | bbloom | it's often used for membership predicates too: |
| 15:03 | bbloom | ,(filter #{:bar} [:foo :bar :baz]) |
| 15:03 | clojurebot | (:bar) |
| 15:03 | bbloom | ,(filter #{:foo baz} [:foo :bar :baz]) |
| 15:03 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: baz in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 15:03 | bbloom | ,(filter #{:foo :baz} [:foo :bar :baz]) |
| 15:03 | clojurebot | (:foo :baz) |
| 15:03 | bbloom | yes, gfredericks is right. beware the nil/false edge case :-P |
| 15:05 | patrickod | hrmm. not sure I understand the edge case. isn't that what you'd expect given that :bar isn't present in the test set? |
| 15:05 | bbloom | ,(filter #{false} [true false true]) |
| 15:05 | clojurebot | () |
| 15:05 | bbloom | patrickod: that explain it? |
| 15:06 | patrickod | ah that does :) thanks |
| 15:06 | bbloom | gfredericks: language design is, kinda inherently, weird :-) |
| 15:08 | Wild_Cat | bbloom: wait, I don't understand why this example doesn't work. |
| 15:08 | bbloom | Wild_Cat: in your repl, experiment with using sets as functions, then look at (source filter) |
| 15:09 | jonasen | anyone seen the error 'Variable binding depth exceeds max-specpdl-size' when evaluating (C-x C-e) an ns-form in Cider? It works if I pretty-print the result (using C-c C-p) |
| 15:09 | Wild_Cat | bbloom: oh, wait, (#{a} a) returns a, right? |
| 15:10 | bbloom | Wild_Cat: i dunno (evil grin) why don't you try it with clojurebot? |
| 15:10 | Wild_Cat | bbloom: I just tried it in a REPL on my local box, it does :p |
| 15:10 | Wild_Cat | ...which I find kind of weird, but I'm sure there's a good reason for that, kind of like how and/or in Python always return one of their operands |
| 15:11 | bbloom | Wild_Cat: the solution to the edge case is to explicitly use contains? |
| 15:11 | bbloom | ,(filter #(contains? #{false} %) [true false true]) |
| 15:11 | clojurebot | (false) |
| 15:11 | Wild_Cat | yeah, figures. |
| 15:11 | bbloom | clojure defines sets to be a map of keys to themselves |
| 15:11 | bbloom | which is a pretty useful definition in many cases |
| 15:12 | bbloom | it's common to see javascript programs do things like {foo: true, bar: true} to emulate sets |
| 15:12 | bbloom | but you may also see {foo: "foo", bar: "bar"} :-) |
| 15:14 | Wild_Cat | bbloom: makes sense. Although sets don't implement java.util.Map |
| 15:14 | gfredericks | bbloom: I've never heard an argument that it's more useful than being a true predicate |
| 15:15 | gfredericks | presumably 90% of use of sets as functions is predicate-like |
| 15:15 | gfredericks | so by returning the item we're incurring an edge case and gaining something that makes the edge case worth it? |
| 15:15 | bbloom | gfredericks: i'd have to think about that |
| 15:16 | gfredericks | certainly in pure math sets and predicates are often interchangeable |
| 15:16 | bbloom | gfredericks: seems that scala chooses to implement sets as functions which return booleans |
| 15:17 | gfredericks | yeah in my head clojure's approach seems to have something to do with dynamic typing |
| 15:17 | Wild_Cat | actually, I think Clojure is the only example I know of sets-as-predicates returning the operand if true. |
| 15:18 | gfredericks | but I don't know why I would think that; certainly no straightforward connection there |
| 15:18 | gfredericks | it definitely feels weird partly because it's not obviously useful -- calling a set isn't giving you something you don't already have, by definition |
| 15:19 | bbloom | gfredericks: not saying this is the reason, but just noting: if sets as functions returned booleans, then there would be no way to use a set where somebody was expecting a map |
| 15:19 | bbloom | without wrapping the object & doing delegation |
| 15:19 | bbloom | which is what sets do anyway :-P |
| 15:19 | bbloom | (sets are built from maps) |
| 15:20 | justin_smith | Since keywords and symbols are defined to invoke get when used in the calling position, having the set lookup also be a get is convenient. It reduces the number of cases / semantics to keep track of. |
| 15:20 | Wild_Cat | bbloom: If they return booleans, then sets-as-functions are analog to {object: bool} maps, aren't they? |
| 15:20 | justin_smith | and of course get should return the matching item in the set, if present |
| 15:20 | gfredericks | using a set where a map is expected feels contrived to me; I don't think I've ever done it |
| 15:20 | bbloom | Wild_Cat: yeah |
| 15:20 | gfredericks | ,(get #{42} 42) |
| 15:20 | clojurebot | 42 |
| 15:20 | gfredericks | huh; |
| 15:21 | gfredericks | justin_smith: that's an interesting point |
| 15:21 | bbloom | gfredericks: so one other thing worth realizing is that the object returned need only be =, not identical? to the invoke argument |
| 15:21 | justin_smith | what else would you expect get on a set to do? |
| 15:21 | gfredericks | bbloom: yeah I thought of that; some interesting normalization possibilities I suppose |
| 15:21 | gfredericks | but every convenience pointed out seems a lot more marginal than having a proper predicate |
| 15:22 | gfredericks | justin_smith: I didn't know it would work at all :) |
| 15:22 | justin_smith | fair enough |
| 15:22 | bbloom | gfredericks: agreed. just thinking aloud |
| 15:22 | gfredericks | ,(get :foo 98) |
| 15:22 | clojurebot | nil |
| 15:22 | gfredericks | ,(get (Object.) 42) |
| 15:22 | clojurebot | nil |
| 15:22 | justin_smith | it keeps things unified - that way both maps and sets in the calling position do the same thing as well |
| 15:22 | gfredericks | bbloom: thanks for the thinks :) |
| 15:23 | justin_smith | ,((juxt #{42} {42 :secret}) 42) |
| 15:23 | clojurebot | [42 :secret] |
| 15:23 | gfredericks | yeah I guess all the IFns that aren't Fns are doing get, eh? |
| 15:23 | justin_smith | unless I am forgetting some case, yeah |
| 15:23 | bbloom | gfredericks: the other thing to consider is uniformity with contains? vs get |
| 15:23 | bbloom | gfredericks: calling a data structure as a function is a shorthand for get, not contains? |
| 15:23 | bbloom | ,([5 10 15] 1) |
| 15:23 | clojurebot | 10 |
| 15:24 | bbloom | ,(get #{5 10} 5) |
| 15:24 | clojurebot | 5 |
| 15:24 | gfredericks | oh man except for vectors |
| 15:24 | gfredericks | ,([] nil) |
| 15:24 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: Key must be integer> |
| 15:24 | gfredericks | ,(get [] nil) |
| 15:24 | clojurebot | nil |
| 15:24 | justin_smith | ,(get [5 10 15] 1) |
| 15:24 | clojurebot | 10 |
| 15:24 | bbloom | well here's the one that burns EVERYBODY: |
| 15:24 | bbloom | ,(contains? [5 10 15] 10) |
| 15:24 | clojurebot | false |
| 15:24 | bbloom | b/c contains? operates on keys, not values |
| 15:24 | gfredericks | well that's just naming |
| 15:25 | bbloom | heh, yeah |
| 15:25 | bbloom | should be has-key? |
| 15:25 | gfredericks | totes |
| 15:25 | dnolen | bbloom: heh yeah, I suppose it fills a perceived gap? |
| 15:25 | gfredericks | has there been any discussion about to what extent breaking changes are tolerated in clojure 2.0? |
| 15:25 | gfredericks | would be interesting to know what's worth fantasizing about |
| 15:26 | justin_smith | and what people want when they usually use contains? on a vector would be has-value? |
| 15:26 | justin_smith | s/usually/naively |
| 15:26 | bbloom | gfredericks: just guessing: these things would not change. more internal things would change, like interfaces->protocols |
| 15:26 | bbloom | gfredericks: and namespacing of primitives :-P |
| 15:26 | bbloom | gfredericks: frankly, i would be surprised if a 2.0 ever happens |
| 15:26 | gfredericks | I want the conj edge case removed |
| 15:26 | bbloom | which edge case? |
| 15:26 | gfredericks | ,(conj {} {3 4}) |
| 15:26 | clojurebot | {3 4} |
| 15:27 | gfredericks | I've never heard any justification for that |
| 15:27 | bbloom | bwha? lol |
| 15:27 | gfredericks | results in weird things like ##(merge #{} #{}) |
| 15:27 | lazybot | ⇒ #{#{}} |
| 15:27 | gfredericks | which bit me yesterday |
| 15:27 | gfredericks | (because merge is implemented via the conj edge case) |
| 15:28 | justin_smith | woah, that is weird |
| 15:28 | gfredericks | I mean merge isn't meant to be used with sets |
| 15:28 | gfredericks | but I would've expected something louder to happen :) |
| 15:28 | bbloom | ,(conj {} {3 4 5 6}) |
| 15:28 | clojurebot | {5 6, 3 4} |
| 15:28 | justin_smith | ,(merge #{1} #{3}) |
| 15:28 | clojurebot | #{1 #{3}} |
| 15:28 | bbloom | wtf? |
| 15:29 | gfredericks | bbloom: APersistentMap#cons accepts either a pair or a sequence of pairs |
| 15:29 | gfredericks | good ole duck-wrapping |
| 15:29 | bbloom | yeah, i'm looking at that now |
| 15:29 | gfredericks | or unwrapping |
| 15:29 | gfredericks | so at some level it was intentional |
| 15:29 | bbloom | https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/APersistentMap.java#L39-L44 |
| 15:29 | justin_smith | ,(merge #{1 2} #{3 4}) |
| 15:29 | clojurebot | #{1 2 #{3 4}} |
| 15:29 | bbloom | i'm not exactly sure why those few lines are there... |
| 15:29 | gfredericks | justin_smith: it's just calling (conj a b) |
| 15:30 | justin_smith | yeah, I am reveling in my WTF moment is all |
| 15:30 | gfredericks | bbloom: yeah I'd expect a throw there instead, eh? |
| 15:30 | gfredericks | I bet we could get a weird type error |
| 15:30 | gfredericks | ,(conj {} :foo) |
| 15:30 | clojurebot | #<ExceptionInfo clojure.lang.ExceptionInfo: Don't know how to create ISeq from: clojure.lang.Keyword {:instance :foo}> |
| 15:30 | gfredericks | ^ yep |
| 15:30 | gfredericks | why on earth would it want an ISeq? :) |
| 15:30 | bbloom | ooooh that's what that exception means lol |
| 15:31 | bbloom | clojure has lots of little oddities in their polymorphic behavior of the base structures. some of them are actually intentionally, subtle, and quite brilliant. others are just like rich hickey being like "i've made too much awesome stuff, i'll just settle for some stuff being horribly awkward. no biggie" |
| 15:31 | bbloom | the only language without weird edge cases is the null language :-) |
| 15:32 | gfredericks | yeah I'm sure if he was trying to make a language that anticipated the pain of ten thousand users he would not have finished |
| 15:32 | justin_smith | I think brainfuck has a pretty complete semantics |
| 15:32 | gfredericks | take yourself too seriously and => analysis paralysis |
| 15:34 | gfredericks | one of the major selling points of clojure over other languages is that clojure exists |
| 15:34 | bbloom | lol true story |
| 15:40 | ddima | gfredericks: but how one develop without an "enterprise architecture/patterns" bible for any given languag? ;) |
| 15:41 | yedi | "By default the templates are located relative to the ClassLoader URL." -- how do i find out what/wjere the ClassLoader URL is? |
| 15:41 | gfredericks | ddima: by utilizing the Enterprise Architecture/Patterns Hammock |
| 15:42 | bbloom | gfredericks: that needs a cartoon lol |
| 15:42 | bbloom | i'm seeing a mega tricked out hammock |
| 15:42 | bbloom | like with spinners |
| 15:42 | gfredericks | ha I like the pun on "pattern" |
| 15:42 | gfredericks | also "architecture" if you can make it more building-like |
| 15:49 | mandu__ | hi guys |
| 15:49 | mandu__ | I want to make a 2 dimensional data structure |
| 15:49 | gfredericks | hi |
| 15:49 | mandu__ | something like a seq but it can iterate in 2 directions |
| 15:49 | justin_smith | mandu__: a seq of seqs? |
| 15:50 | mandu__ | yeah, that's just not working for me |
| 15:50 | gfredericks | using rest and (partial map rest) |
| 15:50 | mandu__ | it gets too complicated |
| 15:50 | justin_smith | because seqs are not associative |
| 15:50 | justin_smith | a vector of vectors is a bit more useful |
| 15:50 | mandu__ | i'm in a (map vector coll) jungle right now |
| 15:51 | justin_smith | mandu__: mapv |
| 15:51 | mandu__ | I want to now implement something like 2dseq |
| 15:51 | hyPiRion | Iterate in 2 directions? |
| 15:51 | mandu__ | yeah... |
| 15:51 | mandu__ | like instead of doing first and rest |
| 15:51 | yedi | anyone with selmer experience know how to find where selmer looks for template files? i know i can explicitly set the resource location, but i don't want to use an absolute path. i would like to use a path relative to where the project is located |
| 15:51 | gfredericks | I think everybody has a different concept of what you're talking about |
| 15:51 | mandu__ | i want to do right and right-rest |
| 15:51 | mandu__ | and down and down-rest |
| 15:51 | justin_smith | zipper |
| 15:51 | justin_smith | sounds like you want a zipper |
| 15:52 | mandu__ | what's that? |
| 15:52 | gfredericks | mandu__: what do down and right return? |
| 15:52 | mandu__ | i'm having trouble explaining it seems |
| 15:52 | justin_smith | http://clojuredocs.org/clojure_core/clojure.zip/zipper |
| 15:52 | mandu__ | sorry about that guys |
| 15:52 | hyPiRion | no worries |
| 15:52 | justin_smith | I don't know if zipper does exactly what you want, but it has operations like down / up / right/ left |
| 15:52 | mandu__ | i was thinking like a 2-d matrix, but it's a lazy functional data structure |
| 15:53 | mandu__ | from each cell i can go in not just one (like normal seqs), but two directions |
| 15:53 | mandu__ | so i can have a map-horizontal |
| 15:53 | mandu__ | and a map-vertical function, for example |
| 15:53 | mandu__ | and all the rest of them |
| 15:53 | hyPiRion | mandu__: I tend to have a maps of [y x] values for such purposes. Could that be sufficient for your use case? |
| 15:54 | mandu__ | sorry, can you explain a little, hyPiRion? |
| 15:55 | hyPiRion | ,(into {} (for [x [0 1 2] y [0 1 2]] [[y x] (+ y x)])) |
| 15:55 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: y in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 15:55 | gfredericks | o_O |
| 15:56 | hyPiRion | magic |
| 15:56 | justin_smith | there was a nonbreaking space in your code |
| 15:56 | hyPiRion | ,(into {} (for [x [0 1 2] y [0 1 2]] [[y x] (+ y x)])) |
| 15:56 | justin_smith | two actually |
| 15:56 | clojurebot | {[2 1] 3, [1 0] 1, [2 2] 4, [0 0] 0, [1 1] 2, ...} |
| 15:56 | hyPiRion | yeah |
| 15:56 | gfredericks | hyPiRion: how on earth do you typo a NBS |
| 15:57 | justin_smith | there was a variable called y but none called y |
| 15:57 | justin_smith | broken IRC clients do things like that |
| 15:57 | hyPiRion | mandu__: so the idea is that you have such a structure, and you iterate over x/y-values to perform mappings |
| 15:57 | hyPiRion | gfredericks: Norwegian keyboard with strange shortcuts |
| 15:58 | hyPiRion | Have a keyboard named Alt Gr. Pressing it while pressing space gives me NBS, and I haven't bothered to unmap |
| 15:58 | gfredericks | hyPiRion: that's positively unamerican |
| 15:59 | hyPiRion | I also have shortcuts for → π ð ½ «» µ and friends too |
| 15:59 | gfredericks | why do you hate democracy |
| 15:59 | hyPiRion | lol |
| 15:59 | mandu__ | justin_smith think zipper kinda looks like what i want. But i can't make much sense of that doc |
| 16:01 | mandu__ | hyPiRion, ah, that's actually a pretty great idea |
| 16:01 | mocker | Ok, why does (= (list :a :b :c) [:a :b :c]) ; => true |
| 16:01 | gfredericks | (->> unicode-chars (sort-by utility) (take 10)) |
| 16:01 | mandu__ | use the 2 coordinates as a key... |
| 16:01 | gfredericks | mocker: sequential things can compare equal |
| 16:01 | mocker | Going through the 4clojure and each individually returns either (:a :b :c) or [:a :b :c] |
| 16:02 | hyPiRion | gfredericks: The most useful by far is → |
| 16:02 | justin_smith | if they are sequential, and have the same content in the same order, = returns true |
| 16:02 | gfredericks | hyPiRion: what do you use it for? |
| 16:02 | mandu__ | is that pretty standard for keeping multi-demension data in clojure? |
| 16:02 | justin_smith | http://www.exampler.com/blog/2010/09/01/editing-trees-in-clojure-with-clojurezip/ mandu__: maybe this link helps? |
| 16:03 | hyPiRion | Handy in notes and documents instead of =>. Maybe I just use that often |
| 16:03 | gfredericks | mandu__: I've often used nested vectors; get-in and assoc-in work well there; subvec can be okay when you want sub-rectangles |
| 16:03 | gfredericks | I've started doing math in org-mode and realized you could do inline latex |
| 16:04 | hyPiRion | mandu__: Really depends on use cases |
| 16:04 | gfredericks | at one point I rewrote <= as \leq ten times |
| 16:04 | hyPiRion | gfredericks: wat, show me |
| 16:04 | mocker | gfredericks: Any links where I can read more about? Failing at search terms in google. |
| 16:04 | gfredericks | hyPiRion: you can do $3 \leq 5$ for example |
| 16:04 | gfredericks | also \begin{equation} |
| 16:05 | gfredericks | hyPiRion: it works nicely with html export; I think the X version of emacs can show inline images but I haven't gotten that to work yet |
| 16:05 | gfredericks | it wants a `latex` command to shell out to or something |
| 16:05 | hyPiRion | gfredericks: oh, so it displays when exporting. I was hoping for the latter case there |
| 16:05 | gfredericks | I don't have latex on this computator yet |
| 16:05 | justin_smith | mocker: what would you want to read about it? it is how equality in clojure works for anything ordered |
| 16:05 | gfredericks | ,(doc =) |
| 16:05 | clojurebot | "([x] [x y] [x y & more]); Equality. Returns true if x equals y, false if not. Same as Java x.equals(y) except it also works for nil, and compares numbers and collections in a type-independent manner. Clojure's immutable data structures define equals() (and thus =) as a value, not an identity, comparison." |
| 16:06 | gfredericks | mocker: ^ there's the docstring at least |
| 16:06 | hyPiRion | gfredericks: I would've died if I hadn't LaTeX on my computer. It's almost more important than Clojure |
| 16:06 | gfredericks | hyPiRion: I haven't had homework for a few years |
| 16:07 | gfredericks | I've just recently gotten back into some serious math study |
| 16:07 | mocker | justin_smith: gfredericks Ahh, it's the 'value/not an identity' part, right? |
| 16:07 | mocker | whoops, sorry. |
| 16:07 | justin_smith | yeah |
| 16:07 | gfredericks | mocker: no that's kind of different |
| 16:07 | justin_smith | sorry for what? |
| 16:08 | hyPiRion | gfredericks: ah. I do a lot of math equations for work |
| 16:08 | gfredericks | the value identity distinction means e.g. two different lists with the same contents are equal |
| 16:08 | gfredericks | it doesn't say anything about equality across types |
| 16:08 | hyPiRion | gfredericks: "and compares numbers and collections in a type-independent" |
| 16:08 | gfredericks | hyPiRion: people pay you money to do equations AND parentheses? |
| 16:08 | justin_smith | gfredericks: I think it is pretty closely related - they are not of identical types but have "equal" contents |
| 16:09 | gfredericks | justin_smith: the word identity there is talking about platform objects, as respected by the identical? function |
| 16:10 | justin_smith | but the two sequences are not = because they are the same, and not because they are the same type, but because the contents are equal |
| 16:11 | gfredericks | which types can compare equal isn't really obvious |
| 16:11 | hyPiRion | gfredericks: Well, the equations are for AI stuff I realise in Clojure. Like, tricks to manipulate support vector machines and the like |
| 16:12 | gfredericks | ,(= (list 1 2 3) (sorted-set 1 2 3)) |
| 16:12 | clojurebot | false |
| 16:12 | gfredericks | ,(= 72 72.0) |
| 16:12 | clojurebot | false |
| 16:12 | gfredericks | ,(= {42 42} #{42}) |
| 16:12 | clojurebot | false |
| 16:13 | Wild_Cat | quick poll: what's the "right" naming convention for a project that attempts to be a Clojure interface to XXX? clj-xxx, clojure-xxx or simply xxx? |
| 16:14 | ddima | gfredericks: is there are rule of thumb or do you just have to know? |
| 16:15 | gfredericks | ddima: there aren't many surprises past a few initial principles |
| 16:15 | gfredericks | e.g., exact numbers and inexact numbers don't normally compare |
| 16:15 | gfredericks | vectors and seqs are probably the most surprising part |
| 16:15 | gfredericks | unless you find (not= 42 42.0) surprising |
| 16:15 | gfredericks | which a lot of people do, but I think it makes sense |
| 16:17 | hyPiRion | Wild_Cat: clj-xxx is the common one |
| 16:17 | ddima | never actually had problems so far, I wouldt have expected list/sorted-set and dict/set to be equal, but still thought maybe there's more then I knew so far. yeah, the numbers thing is a little different, but it's ok. no mad about it ;) |
| 16:17 | Wild_Cat | hyPiRion: OK, thanks. |
| 16:18 | gfredericks | ddima: the numeric thing is virtually never an issue for me, and if it is == exists for the looser behavior |
| 16:18 | gfredericks | I bet I have never used == |
| 16:18 | ddima | gfredericks: if you consider that it could be "niminally" the same but only through floating-point rounding/precision |
| 16:18 | ddima | though, could be bigdecimal, but still |
| 16:20 | gfredericks | ,(= 3.0M 3.00M) |
| 16:20 | clojurebot | true |
| 16:20 | mrhanky | how to use clojure.browser.dom/dombuilder ? |
| 16:20 | mrhanky | i want to use clojure.browser.dom to add a <li> to an <ul> |
| 16:22 | ddima | gfredericks: well, I meant the fact that some numbers are not representable by floats/doubles, so they could be equal by accident. usually one would compare stuff like this given an epsilon or something, so its not bad to have such a behaviour as a safeguard - that's what I meant |
| 16:22 | gfredericks | righto |
| 16:23 | gfredericks | I was actually surprised about (= 3.0M 3.00M) |
| 16:23 | gfredericks | I thought different precision means not= |
| 16:25 | hyPiRion | gfredericks: no, that's for == |
| 16:25 | hyPiRion | ,(== 3.0M 3.00M) |
| 16:25 | clojurebot | true |
| 16:25 | hyPiRion | oh, that must've changed in 1.6 then |
| 16:25 | hyPiRion | &(== 3.0M 3.00M) |
| 16:25 | lazybot | ⇒ false |
| 16:29 | Wild_Cat | isn't clojure.data.json part of the "standard" Clojure distribution as of 1.5? |
| 16:30 | Wild_Cat | hrmm. My info sucks. |
| 16:49 | gfredericks | we don't have a good vocabulary for explaining why clojure.walk and clojure.data.json are different |
| 16:49 | gfredericks | it takes like whole sentences |
| 17:01 | justin_smith | I like cheshire better than data.json anyway |
| 17:22 | Clome | Does requiring or using whole namespaces hider the performance of your application? If so is this even noticeable. |
| 17:25 | akhudek | Clome: I would guess that there might be some imperceptible start up cost, but no runtime cost once compiled. |
| 17:26 | justin_smith | use has other problems, but the main space cost is paid in full namespace increments, no matter how you make it accessible |
| 17:27 | justin_smith | like many things in clojure, usage of space is pretty much ignored, but time cost is optimized (namespaces are hashes to the values defined in them) |
| 17:33 | Clome | so basically a namespace is a hashmap and whenever you access something you are doing a hesh kookup? |
| 17:36 | akhudek | Clome: only during compile |
| 17:38 | Arafangion | RAM is _insanely_ cheap these days, except on phones. |
| 17:39 | Clome | does clojure get translated to java or all down to bytecode? |
| 17:39 | noncom | why is not (nth) supported on sorted sets? as far as i understand, their elements are fully ordered and (nth) would be perefectly legal? |
| 17:39 | noncom | Clome: bytecode |
| 17:40 | Clome | akhudek: do you know where can I read more about clojure compilation? |
| 17:40 | technomancy | it's technically a field lookup, which the JVM is really good at inlining and optimizing |
| 17:40 | Clome | the behind the scene stuff |
| 17:40 | noncom | Clome: clojure source? |
| 17:40 | akhudek | Clome: source or the dev wiki |
| 17:41 | noncom | so why (nth) on sorted sets is not allowed? what am i missing? |
| 17:42 | akhudek | noncom: you could do (nth (seq myset) 5) |
| 17:42 | akhudek | not sure how heavy seq is for a set |
| 17:42 | akhudek | guessing it's pretty lightweight though |
| 17:43 | noncom | ,(time (nth (seq (apply sorted-set (repeat 9001 (rand 9000)))) 5000)) |
| 17:43 | clojurebot | #<IndexOutOfBoundsException java.lang.IndexOutOfBoundsException> |
| 17:44 | noncom | ,(time (nth (seq (apply sorted-set (repeat 9001 (range 9000)))) 5000)) |
| 17:44 | akhudek | noncom: sets won't have duplicates |
| 17:44 | clojurebot | #<IndexOutOfBoundsException java.lang.IndexOutOfBoundsException> |
| 17:44 | noncom | oh |
| 17:44 | noncom | i am so stupid |
| 17:44 | noncom | ,(time (nth (seq (apply sorted-set (range 9001))) 5000)) |
| 17:44 | clojurebot | "Elapsed time: 52.425151 msecs"\n5000 |
| 17:44 | noncom | ,(time (nth (seq (apply sorted-set (range 9001))) 5000)) |
| 17:44 | clojurebot | "Elapsed time: 35.489225 msecs"\n5000 |
| 17:44 | noncom | ,(time (nth (seq (apply sorted-set (range 9001))) 5000)) |
| 17:44 | clojurebot | "Elapsed time: 33.219544 msecs"\n5000 |
| 17:45 | noncom | ,(time (nth (seq (apply [] (range 9001))) 5000)) |
| 17:45 | clojurebot | #<ArityException clojure.lang.ArityException: Wrong number of args (21) passed to: PersistentVector> |
| 17:45 | noncom | ,(time (nth (seq (apply vec (range 9001))) 5000)) |
| 17:45 | clojurebot | #<ArityException clojure.lang.ArityException: Wrong number of args (21) passed to: core/vec> |
| 17:45 | noncom | go to hell |
| 17:45 | Clome | ,(+ 1 1) |
| 17:45 | clojurebot | 2 |
| 17:46 | hyPiRion | noncom: you know, it's possible to private message the bots |
| 17:46 | noncom | actually i am pretty lame at IRC |
| 17:46 | ddima | also possible to run own repl ;) |
| 17:46 | noncom | :) |
| 17:49 | noncom | so why (nth) is not allowed on sorted sets? is it a mathematical point or an implementation detail? |
| 17:52 | akhudek | noncom: not sure |
| 17:53 | bbloom | noncom: has to do with the data structure being used |
| 17:53 | akhudek | noncom: mathematically I don't think sets can have order |
| 17:53 | bbloom | will be here soon: https://github.com/clojure/data.avl |
| 17:53 | Arafangion | Generally, sets do not have an order. |
| 17:53 | ddima | sets do not implements any index based operators iirc |
| 17:53 | bbloom | yes, but SORTED sets do have an order :-P |
| 17:53 | Arafangion | What's a 'sorted set'? |
| 17:53 | bbloom | (doc sorted-set) |
| 17:53 | clojurebot | "([& keys]); Returns a new sorted set with supplied keys. Any equal keys are handled as if by repeated uses of conj." |
| 17:54 | bbloom | there are mathematical models of sorted sets too |
| 17:54 | bbloom | see https://github.com/michalmarczyk/avl.clj for sorted map & sets with rank queries |
| 17:54 | ddima | (by which I mean java sets, navigatableset etc) |
| 17:55 | hyPiRion | noncom: having nth on sorted sets means nodes must track child count, which reduces performance for insertion |
| 17:55 | hyPiRion | and removal. |
| 17:55 | Arafangion | bbloom: Isn't that just a list, really? |
| 17:55 | bbloom | Arafangion: no. |
| 17:55 | bbloom | Arafangion: lists can have duplicate entires |
| 17:56 | Arafangion | bbloom: With algorithms to detect duplications. |
| 17:56 | bbloom | also, a "list" in the data structure sense, ie a Linked List, is a particular type of data structure, as an AVL tree is a particular type of data structure which can be used to implement sorted sets |
| 17:56 | bbloom | Arafangion: then you'll just get an inefficient sorted set |
| 17:56 | Arafangion | I'm looking for references to set theory and sorting. |
| 17:57 | hyPiRion | Arafangion: Mathematically, a sorted set is a list with elements such that a0 < a1 < ... < an |
| 17:57 | bbloom | Arafangion: http://en.wikipedia.org/wiki/List_of_order_structures_in_mathematics |
| 17:57 | bbloom | hyPiRion: it's math. there is always an alternative representation available when convenient :-) |
| 17:57 | akhudek | Arafangion: you want to use the keyword "ordered" not "sorted" |
| 17:58 | Arafangion | akhudek: Ah, that'd do it. Mathematics do seem to use their own language. |
| 17:58 | Arafangion | bbloom: Perfect, that does it. |
| 17:58 | hyPiRion | bbloom: Yeah, I guess :p |
| 17:59 | bbloom | Arafangion: the word "order" implies that there is a sequence. You can have multiple orderings for any given set. The word "sorted", at least to me, implies that the set itself is ordered, rather than simply having an ordering |
| 17:59 | bbloom | clojure has sorted-set and sorted-set-by |
| 17:59 | akhudek | Has anyone seen any existing work on SQL synthesis for common entity relation queries? |
| 17:59 | Arafangion | bbloom: "Total Order", as referred to on your link. |
| 17:59 | Arafangion | akhudek: One moment... |
| 17:59 | akhudek | This seems like the realm of ORMs, but really the object mapping part is unnecessary. |
| 18:00 | bbloom | Arafangion: not necessarily. you can have a partial ordering for a clojure set, but you'll probably run in to some bugs/edge cases |
| 18:00 | akhudek | especially in clojure where maps are natural ways to represent a tuple |
| 18:00 | bbloom | ,(Math/sign 5) |
| 18:00 | clojurebot | #<CompilerException java.lang.IllegalArgumentException: No matching method: sign, compiling:(NO_SOURCE_PATH:0:0)> |
| 18:00 | Arafangion | akhudek: Have you seem: http://homepages.inf.ed.ac.uk/slindley/papers/practical-theory-of-linq.pdf |
| 18:00 | bbloom | ok well assume that function exists |
| 18:00 | bbloom | (defn sign [x] (cond (pos? x) 1 (neg? x) -1 :else 0)) |
| 18:00 | akhudek | Arafangion: no I haven't, thanks! |
| 18:00 | Arafangion | akhudek: I have attended one of his presentatiosn on the topic, and while I was unable to apply it to practice (due to a seriously stupid language: Delphi), I was impressed. |
| 18:00 | bbloom | now: (sorted-set-by sign) |
| 18:01 | bbloom | if you stick some integers in there, you have a partial ordering |
| 18:01 | bbloom | there are some mailing list discussions about having a universal total order |
| 18:01 | hyPiRion | Don't need partial ordering, even. |
| 18:01 | bbloom | but there are problems with that idea |
| 18:02 | bbloom | Arafangion: look at http://hackage.haskell.org/package/base-4.6.0.1/docs/Data-Ord.html -- haskell has Ordered types and Orderings as separate concepts |
| 18:03 | hyPiRion | ,(into (sorted-set-by (fn [a b] (dec (rand-int 3)))) [0 1 2]) ; Don't try this at home |
| 18:03 | clojurebot | #{0 2} |
| 18:06 | AeroNotix | any books which have a lot of questions/do it yourself sections? |
| 18:07 | Raynes | Oh God |
| 18:07 | Raynes | I don't remember how to use paredit in Emacs at all. |
| 18:12 | tufflax | tpope and others, do you know why vim-fireplace gives the following error message when im trying to eval something? https://www.refheap.com/22283 |
| 18:13 | Arafangion | bbloom: I wasn't disputing the ability to have them - only the concept in mathematics. |
| 18:13 | Arafangion | bbloom: I had no idea that maths itself supported ordered sets. |
| 18:13 | bbloom | Arafangion: math supports any idea you can dream up and then convince other math people it is sometimes occasionally useful. even if it's only useful for explaining the paragraph immediately after you invented it |
| 18:14 | Arafangion | bbloom: Yes, but I think you know what I meant. |
| 18:15 | bbloom | Arafangion: i know exactly what you meant, which is why i was correcting your misconception. at this point, you should pretty much assume that there is a formalism for any offhand thought you've ever had without careful prior research :-) |
| 18:16 | Arafangion | bbloom: Point taken. :) |
| 18:18 | Glenjamin | is there a good way to work with more than one repl instance at once? |
| 18:19 | Glenjamin | hrm, in fact thats not my problem |
| 18:19 | Glenjamin | my problem is global state :s |
| 18:21 | tufflax | Glenjamin: maybe this is useful to you http://thinkrelevance.com/blog/2013/06/04/clojure-workflow-reloaded |
| 18:21 | Glenjamin | tufflax: that was my starting point |
| 18:21 | tufflax | i see |
| 18:21 | Glenjamin | thinking about to work my app into that |
| 18:21 | Glenjamin | i've got an env var for "force-ssl" |
| 18:22 | Glenjamin | my tests require that force-ssl is on, because there's a test for that behaviour |
| 18:22 | Glenjamin | but for local dev i leave it off |
| 18:22 | Glenjamin | currently i just run an autotest JVM and a dev server JVM |
| 18:22 | Glenjamin | but i think a better idea is to have the tests run a separate instance of the app with different config in the same JVM |
| 18:24 | noncom | that discussion on sets was interesting and besides answered my question, thanks |
| 18:28 | tufflax | Glenjamin: Maybe. I don't know what autotest is and I don't have a lot of tests, but I just use fns in the user namespace to test (and no global state) |
| 18:29 | Glenjamin | basically the tests require production settings |
| 18:29 | Glenjamin | but the issue is because of how i've implemented my settings abstraction |
| 18:30 | tufflax | ok :p |
| 18:30 | Glenjamin | i'm planning to switch to https://github.com/stuartsierra/component/ and the reloaded workflow, and i now think the act of refactoring will make the issue disappear |
| 18:34 | cjfrisz | Anybody have a good naming convention for variables that represent sets? |
| 18:35 | cjfrisz | For instance, I'm used to a variable for a list of a certain type of thing be named "thing*" |
| 18:35 | cjfrisz | (without the quotes) |
| 18:35 | bbloom | cjfrisz: just use a plural noun & don't try to encode the type unless you need to disambiguate |
| 18:36 | cjfrisz | bbloom: sounds good |
| 18:36 | Glenjamin | set-of-x if you really need to i guess |
| 18:38 | bbloom | cjfrisz: if you need to disambiguate, it's pretty common to add a -set suffix to a singular noun |
| 18:39 | cjfrisz | Yeah, though I was thinking of a shorter, one or two character thing |
| 18:39 | bbloom | cjfrisz: i've seen single letter prefixes and suffixes in some code, like cakes and vcakes for a seq and vector respectively |
| 18:41 | bbloom | cjfrisz: but it's not really important as long as it's a lexical name in a small function. so i might even call vcakes v if it's clear i just need a vector for a small scope |
| 18:53 | akhudek | Arafangion: hmm, this paper isn't quite what I was after. After much deliberation on ORMs, I've come to recognize that there is actually a class of simple queries that can benefit from some light sql synthesize. E.g. accessing a single field from a unique row by primary key. The sql for this, though simple, contains a lot of repetition if you write it over and over. At the same time, I deeply dislike ORMs for how much they hide the actual |
| 18:53 | akhudek | database. (Plus, there is no 'object mapping' needed in clojure). |
| 18:55 | Arafangion | akhudek: The advantage of using the concepts in that paper is that you can write advanced queries in the language, rather than writing SQL itself, and you'll still get just one SQL statement coming out. |
| 18:56 | akhudek | Right, but it won't help reduce repetition (and thus errors) for this small class of queries, which is more what I'm after. |
| 18:56 | Arafangion | akhudek: Couldn't you write a macro or some sort of function for that? |
| 18:57 | akhudek | yes, of course, I'm just trying to see if there is something better that can be done |
| 18:57 | akhudek | while avoiding the pitfalls of orms |
| 18:57 | Arafangion | akhudek: I wonder the same. ORMs seem nice, but they do seem to result in excessive SQL queries. |
| 18:58 | akhudek | plus, they often couple unnecessary features such as DDL and 'object mapping' |
| 18:58 | Arafangion | akhudek: The other problem I have with ORMs is that they encourage using the ORM models themselves as the basic data types. |
| 18:59 | Arafangion | akhudek: Which embeds the database interaction implementation detail into the rest of the app. |
| 19:01 | Arafangion | akhudek: Sometimes I wonder if we've overthought this whole problem, and wonder just what is so bad with having a series of functions in a 'db' namespace, which do all the sql stuff and return the result, using whatever library/framework it chooses, and returning either dictionaries, lists, and/or simple data types. Nice, simple abstraction. |
| 19:03 | Arafangion | akhudek: But ORMs often also consider caching. |
| 19:03 | akhudek | Arafangion: That's where I'm heading right now. |
| 19:03 | akhudek | Arafangion: yeah, another coupling that probably doesn't need to be there. |
| 19:04 | akhudek | Arafangion: I've been trying to work out if the functions of an orm can be cleanly decoupled so that we can build composable libraries for them. |
| 19:04 | Arafangion | akhudek: I do have to admit, using ORMs have sometimes resulted in seriously efficient implementations. (In terms of dev time) - Despite its warts, I liked django's ORM. |
| 19:05 | Arafangion | akhudek: You want to be able to separate your data structures from that of the ORM, and allow serialization/convertibility between them. |
| 19:06 | Arafangion | akhudek: You might also want such a DB layer to determine if a particular 'row' has been modified locally (ie, is there any point in saving it?) |
| 19:06 | akhudek | Arafangion: So the neat thing about clojure is that you can perfectly express a database tuple as a clojure map. Even the database lit often talks about tuples as maps of column names to values. There is no mismatch in the data model in other words. |
| 19:06 | Arafangion | akhudek: And you'd want to do that _without_ a database query. |
| 19:06 | Arafangion | akhudek: Hardly unique, I'd expect? |
| 19:07 | akhudek | Arafangion: no, but it's not something I've seen any state before. |
| 19:07 | akhudek | Arafangion: everyone always talks about data model mismatches. |
| 19:07 | akhudek | Arafangion: probably because many main stream languages, although having maps, tend to use objects to store data instead. |
| 19:08 | Arafangion | That, imho, is because they're trying to embed the database library itself as a first-class citizen, with objects that directly map to database rows. |
| 19:08 | akhudek | Arafangion: you are right about serialization, that is something that would also be handy to be somewhat automated |
| 19:09 | Arafangion | And they do not want any implementation details to leak through. If a "property" (ie, column) gets updated, they want that to follow regular, conventional rules. Also with inheritance of classes and all that stuff. |
| 19:09 | Arafangion | The mismatch is the implemetnation leaking through the abstraction - imho, it's the wrong abstraction. |
| 19:09 | akhudek | I agree. |
| 19:09 | dyreshark | i have a function that has side-effects that i want to apply to each element of a list. is (dorun (map my-fn the-list)) the most idiomatic way to do this? |
| 19:09 | akhudek | I'd prefer something that doesn't hide the fact that you are working with a database. |
| 19:10 | hyPiRion | no, (doseq [item the-list] (my-fn item)) is more idiomatic |
| 19:10 | akhudek | I still need to write complex SQL at times, just not most of the time. |
| 19:10 | dyreshark | hyPiRion: ok, thanks |
| 19:10 | Arafangion | akhudek: I'd prefer an implementation that makes typical usage patterns clear. |
| 19:11 | Arafangion | akhudek: django bit me a few weeks ago because I didn't realise that it enforces relationships on the *client side*, and if you have an FK relationship: A -> B, but B isn't in the database yet and doesn't have a PK, then the A -> B gets broken, silently. You have to save B _before_ you even link it up in teh application code. |
| 19:12 | Arafangion | akhudek: A separate, clear, distinct DB boundary would have clarified and eased that considerably, I'd like to say: "Save this structure", and let it figure it out. |
| 19:13 | akhudek | Arafangion: are you talking about a big denomalized data structure that you are trying to save to a normalized database? |
| 19:14 | Arafangion | akhudek: No, although for various reasons, my db is very unnormalised. |
| 19:14 | Arafangion | akhudek: And that structure is exposed 1:1 in the application as well. |
| 19:19 | akhudek | Arafangion: ok, thanks for the thoughts. If I come up with anything useful I'll release it as a library. For now I'll see how useful some light synthesis using a copy of the db schema is. |
| 19:20 | akhudek | basically remove some repetition, provide automatic data transforms, and do some name checking to remove typing errors |
| 19:22 | JanxSpirit | is anything special needed to make lein repl include the project dependencies? |
| 19:23 | Arafangion | akhudek: More useful, I suspect, would be a design pattern, or thoughts about which is the best one. |
| 19:23 | JanxSpirit | getting class not found when trying to require libraries that work within my project |
| 19:24 | akhudek | Arafangion: yep, going to try to incorporate some common db patterns |
| 19:24 | Arafangion | akhudek: Years ago, though, as a personal investigation, I wrote a naive ORM for python that attempted to eliminate all "unneccessary" duplication, and also eleminited the need to statically generate models. |
| 19:25 | Arafangion | akhudek: But it was just too slow - it's expensive querying the database for the schema and type information. |
| 19:25 | akhudek | Arafangion: not planning on querying the database for the schema, it will have to be user supplied |
| 19:25 | Arafangion | akhudek: Good. |
| 19:30 | Arafangion | akhudek: You will still want to allow even that code to be generated though, but how do you identify what parts of the schema are neccessary? That will also be a good thing to investigate. |
| 19:30 | Arafangion | akhudek: Querying the schema isn't expensive at compile time. ;) |
| 19:32 | akhudek | Arafangion: yeah, though it isn't always possible to easily do that. For example, postgres has no way to access the schema from java. Plus, you might want to add extra app specific information to the schema such as transform functions for serializing and deserializing columns. |
| 19:32 | Arafangion | akhudek: You can easily get the schema in postgresql. |
| 19:32 | Arafangion | akhudek: I haven't done it from java, but postgresql does hold the schema information in a separate database. |
| 19:33 | akhudek | Arafangion: that's true, I did come across that method, though I haven't looked into it in depth. Tools to make sure your schema matches the database would indeed be useful. |
| 19:33 | Arafangion | As for app-specific information, you'd want to do that as serialization routines. |
| 19:33 | Arafangion | Although you _could_ define helper functions on the database side. |
| 19:34 | Arafangion | But that's an unneccessary complication. |
| 19:36 | Arafangion | akhudek: A frightfully large number of database users, however, are ignorant of database theory, such as maintaining the ability to change the database schema without impacting on application's expectations of that schema. |
| 19:36 | akhudek | Arafangion: that is a much harder problem to solve :-) |
| 19:39 | hyPiRion | say no to "SELECT *" ? |
| 19:39 | deadghost | Arafangion, what do you mean |
| 19:39 | deadghost | ^ |
| 19:39 | deadghost | is that what you're saying? |
| 19:39 | deadghost | in addition to normalizing? |
| 19:40 | Arafangion | deadghost: The application really only needs to access the database. It shouldn't care about how the database maps those views to internal tables. |
| 19:42 | Arafangion | deadghost: Developers barely seem to even realise that the database can enforce fairly complex constraints. Most ORMs do that on the application side. |
| 19:42 | deadghost | oh man |
| 19:42 | deadghost | ORMs! |
| 19:42 | Arafangion | (As they should.. The problem is that they do so *ONLY* on the application side) |
| 19:42 | deadghost | I haven't met an ORM I've liked |
| 19:43 | akhudek | I think a lot of the problem is that there is a hard boundary between the app and the database and thus some of the schema/constraint/query code that would ideally be shared by the two isn't shared. |
| 19:44 | deadghost | definitely |
| 19:44 | Arafangion | akhudek: And most ORMs and database libraries define the data structures and all related systems in that database. |
| 19:45 | Arafangion | akhudek: This language - these nouns, should be separated so that the application can use them without dependency on the database library, and the library can use them without dependency on the application. |
| 19:45 | deadghost | so uh how do you guys feel about korma |
| 19:47 | akhudek | deadghost: I don't like it because it has needless coupling to things like a default connection pool and also hides access to the jdbc too much. Thus when something goes wrong, you have a hard time escaping to jdbc. |
| 19:47 | Arafangion | deadghost: I haven't used it. (As I have yet to use clojure), but superficially it seems useful - akhudek's looking at the problem from an application design poitn of view, though. |
| 19:48 | akhudek | it also has something a bit like what we've been discussing, a simple notion of schema with some light sql generation for common patterns |
| 19:48 | Arafangion | akhudek: I'm having trouble finding documentation on how schema design should be approached, online, weirdly I can only find minimal information about the three-layer approach. |
| 19:48 | Arafangion | deadghost: Also it seems to be far too simplistic. |
| 19:49 | Arafangion | deadghost: How does it handle transactions - mysql and postgresql have fairly different notions of what is considered part of a transaction. |
| 19:49 | deadghost | dunno my sql ability is light at best |
| 19:49 | akhudek | Arafangion: I used to work on a project that took the opposite approach, you could define a schema that included both the logical part and the physical part and then compile relational queries over this down to high performance plans. |
| 19:50 | Arafangion | akhudek: Don't you get that for free in postgresql? |
| 19:50 | akhudek | Arafangion: it could describe both in memory application data as well as relational data and write plans that use data from any source. |
| 19:50 | akhudek | Arafangion: postgres has a little bit of support for this, but it's not nearly as expressive as what we were working on. |
| 19:50 | clojurebot | Huh? |
| 19:51 | Arafangion | Cool. Would love to chat more, but I have to get going. |
| 19:52 | akhudek | Arafangion: some other time. :-) |
| 19:52 | Arafangion | Later. :) |
| 19:54 | ryanf | the readme for clojurescript.test says |
| 19:54 | ryanf | All of the test-definition macros (deftest and with-test, as well as the set-test utility) add to a global registry of available tests (necessary given ClojureScript's lack of namespaces), so you can also define, redefine, and run tests interactively: |
| 19:54 | ryanf | what does it mean by "ClojureScript's lack of namespaces"? |
| 19:54 | ryanf | I am a noob but clojurescript appears to have namespaces to me |
| 20:02 | dnolen | ryanf: they aren't first class like they are in Clojure |
| 20:06 | Tolstoy | dnolen: Hello! Re: om, for some reason set-state isn't working. Is it broken lately? |
| 20:06 | Tolstoy | dnolen: (om/set-state! owner [:key] "value") |
| 20:07 | dnolen | Tolstoy: I recently built both the examples and TodoMVC w/ master, no issues |
| 20:07 | Tolstoy | dnolen: right after, I do (om/get-state owner) -> nothing. ;) |
| 20:07 | Tolstoy | dnolen: okay. |
| 20:07 | ryanf | dnolen: /whois dnolen |
| 20:07 | ryanf | haha |
| 20:07 | ryanf | oops |
| 20:07 | ryanf | :) |
| 20:08 | ryanf | anyway thanks, it hadn't occurred to me to check that |
| 20:08 | dnolen | Tolstoy: oh that won't work, I need to think about that |
| 20:08 | dnolen | Tolstoy: currently you can't immediately read state that you wrote |
| 20:09 | dnolen | Tolstoy: React team is thinking about adding a way to read pending state, we should maybe consider that too. |
| 20:09 | Tolstoy | dnolen: When does the state get updated? Only on a render? |
| 20:10 | dnolen | Tolstoy: it gets commited after IDidUpdate |
| 20:10 | Tolstoy | dnolen: I bet this "worked" before because I had a 1 sec clock constantly updated on the screen, thus renders happening all the time. |
| 20:10 | dnolen | Tolstoy: actually that's wrong |
| 20:11 | dnolen | Tolstoy: reading the life cycle methods in the source is informative |
| 20:11 | dnolen | and the source of truth |
| 20:11 | Tolstoy | dnolen: yep. As long as you know you've got a lifecycle problem in the first place.... ;) |
| 20:11 | dnolen | Tolstoy: pending state gets merged in after IWillUpdate |
| 20:11 | dnolen | Tolstoy: sorry I just mean reading the Om source |
| 20:12 | dnolen | Tolstoy: https://github.com/swannodette/om/blob/master/src/om/core.cljs#L122 |
| 20:14 | Tolstoy | dnolen: Interesting. I think I've got this form stuff all wrong due to my previous practice of having a constant clock tick updating the UI. |
| 20:14 | Tolstoy | dnolen: Which means things should get simpler. == good! ;) |
| 20:36 | devn | How do I get dependency information for a remote lib, like something on clojars? lein-ancient exists, which is nice. I'd like to get an artifact's dependency information in addition to its latest version string. |
| 20:37 | devn | Suggestions welcome. |
| 20:37 | Tolstoy | devn: lein deps :tree |
| 20:37 | devn | Tolstoy: without leiningen, only in clojure |
| 20:38 | Tolstoy | devn: Maybe this? https://github.com/cemerick/pomegranate |
| 20:38 | devn | heh, funny you should mention that |
| 20:38 | devn | in this particular instance i want to find which version of pomegranate an external artifact is using |
| 20:39 | devn | Tolstoy: and by funny I mean I think that's exactly what I need |
| 20:40 | Tolstoy | devn: I went down that path looking for something to resolve "ivy" stuff for a super-legacy java project, but gave up. |
| 20:46 | devn | Tolstoy: hm, pomegranate gets me closer |
| 20:46 | devn | but it gives me the entire tree, and all I want here is basically what is in the remote artifact's project.clj |
| 20:46 | Tolstoy | Would that be the immediate children of the artifact? |
| 20:47 | Tolstoy | Hm. Not quite. |
| 20:47 | devn | hmmmm, actually i think i found it |
| 20:47 | devn | just hard to wade through the giant output from add-dependencies |
| 20:48 | devn | [[mything "1.2.3"] #{[...] [...]}] |
| 20:55 | Tolstoy | Weird. Using om/react, if I prepoulate a form field with a value, I can't type anything else in that field. |
| 20:56 | Tolstoy | [:input {:value nil} ] is okay, though. Oy. |
| 21:06 | Tolstoy | Gosh: http://facebook.github.io/react/docs/forms.html |
| 21:40 | coventry | Is there an easy way to pass arguments to the closure compiler via clojurescript options in project.clj? |
| 22:07 | cgag | Are the protocols that the standard persistent datasctures implement documented anywhere? Like if I wanted to write a drop in replacement for clojure's maps, how do I find which protocols I need to implement? |
| 22:15 | ddellacosta | cgag: it seems pretty much like you could just extend-type clojure.lang.PersistentHashMap and you're good to go, no? |
| 22:17 | cgag | what if i were writing something that expected a map and I wanted it to work with any implementation of a map? |
| 22:17 | ddellacosta | sorry, I meant extend-protocol, not extend-type |
| 22:22 | cgag_ | battery died if someone happened to answer my question in the last minute or two |
| 22:24 | ddellacosta | cgag_: whoops |
| 22:25 | cgag_ | ddellacosta: the problem is i'm working with something that is explicitly checking for instances of java.util.Map and i have a datomic entity |
| 22:25 | cgag_ | which seems to work like a normal map |
| 22:26 | ddellacosta | cgag_: ah, okay. Give me a sec |
| 22:26 | cgag_ | i guess it might not actually be one though |
| 22:27 | ddellacosta | cgag_: it's not, it's a Java data structure |
| 22:27 | ddellacosta | it's mutable |
| 22:28 | cgag_ | Usage: (map? x) |
| 22:28 | cgag_ | Return true if x implements IPersistentMap |
| 22:28 | cgag_ | looks like IPersistentMap is what i'm looking for |
| 22:29 | ddellacosta | cgag_: so, there is a wide variety of constructs in clojure to do something like what you want, but I'm still a bit confused as to what you are trying to do--you have some Java interop stuff that you need to handle a diatomic entry? |
| 22:29 | cgag_ | though it apparently doesn't actually implement that interface |
| 22:29 | ddellacosta | diatomic = datomic (freaking spellcheck...) |
| 22:29 | cgag_ | I'm using expectations |
| 22:29 | cgag_ | and you can write things like |
| 22:29 | ddellacosta | entry -> entity |
| 22:30 | cgag_ | (expect :a (in {:a :b})) |
| 22:30 | cgag_ | if i do |
| 22:30 | cgag_ | (expect :db/id (in my-entity)) |
| 22:30 | cgag_ | it tells me i have to give it a map |
| 22:30 | cgag_ | and it's doing (instance? java.util.Map ...), I was hoping I could patch it with something other than java.util.Map and get it to work as i expect it to |
| 22:31 | ddellacosta | cgag_: Clojure's PersistentMap implements Map |
| 22:31 | ddellacosta | cgag_: so should work, I would think |
| 22:32 | ddellacosta | https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/APersistentMap.java#L16 |
| 22:32 | cgag_ | yeah it works for a normal map, I wanted it to work with a datomic entity |
| 22:33 | ddellacosta | cgag_: I see, I'm not very familiar with diatomic, but looks like Entity is pretty much unrelated. http://docs.datomic.com/javadoc/datomic/Entity.html |
| 22:33 | cgag_ | it looks like (associative? my-entity) returns true, i might be able to work with that |
| 22:33 | ddellacosta | cgag_: looks like it can give you a set |
| 22:35 | ddellacosta | cgag_: assuming you want to test the keys, you can use that. otherwise I would argue that you are overthinking it, and should simply get what you want out of the Entity and test it in a simpler way. |
| 22:35 | cgag_ | ddellacosta: yeah it's pretty trivial for me to write my test in a way that'll work, i just expected this to work and wanted to see if it were possible |
| 22:36 | ddellacosta | cgag_: I think that the short answer is no, as an Entity seems to be pretty much unrelated to any notion of a map as it exists in Clojure |
| 22:37 | ddellacosta | cgag_: but again, I'm not too familiar with datomic so maybe there is something I'm missing. |
| 22:37 | ddellacosta | cgag_: ah, but wait, here it says it implements associative: http://docs.datomic.com/clojure/#datomic.api/entity |
| 22:37 | cgag_ | http://docs.datomic.com/clojure/#datomic.api/entity |
| 22:37 | cgag_ | ha |
| 22:37 | cgag_ | nice timing |
| 22:37 | ddellacosta | sorry, should have looked that up first... |
| 22:38 | ddellacosta | yeah, heh |
| 22:38 | ddellacosta | wow, dealing with types in Clojure, really is a pain, isn't it. *light bulb* |
| 22:39 | ddellacosta | compared to...other type systems. Sorry, not trying to start a flame war, just recollecting a conversation had recently. |
| 22:39 | ddellacosta | cgag_: anyways, hopefully that'll help ya... |
| 23:45 | cjfrisz | Uuuuuuuuugggghh...just spent a very long time confounded over why a hash-map was giving me the wrong values before I figured out it was created via a zipmap with a a set for the keys list |
| 23:45 | cjfrisz | I promise to never forget this lesson for it was quite painful |