2015-11-27
| 00:13 | elvis4526 | Great, I'm gonna look into schema too, it looks cool |
| 00:41 | rritoch | Hi, I know this is a lazy question, but what is the best way to map the values of a list to nil? (map #(do %1 nil) '("A" "B""C")) seems a bit clumsy and inefficient. |
| 00:47 | tolstoy | What do you mean "map the values to nil"? |
| 00:48 | rritoch | tolstoy: I have a situation where there are two lists of data which are related and should have the same length, if the second list is corrupted it will have an invalid length and therefore cannot be passed as a second list argument to the map function. |
| 00:48 | tolstoy | So you want to remove the nil values of the list? |
| 00:48 | rritoch | tolstoy: To make up for this I plan to pass the second list only if the lengths match, otherwise it'll pass all nil |
| 00:49 | rritoch | tolstoy: No, I want to turn all values of a list into nil |
| 00:49 | tolstoy | Oh. |
| 00:50 | tolstoy | ,(take 10 (cycle [nil])) |
| 00:50 | clojurebot | (nil nil nil nil nil ...) |
| 00:50 | luxbock | ,(repeat 10 nil) |
| 00:50 | clojurebot | (nil nil nil nil nil ...) |
| 00:50 | tolstoy | Yeah, was just looking that one up. ;) |
| 00:52 | rritoch | tolstoy & luxbock: Thanks, (repeat (count '("A" "B" "C")) nil) syntax will solve the problem nicely. |
| 01:15 | rritoch | I forgot all about the clojure cheatsheet... What I really need is some ginko biloba, lol. Thanks again! That solved the problem perfectly. |
| 01:15 | rritoch | ,(inc luxbock) |
| 01:15 | clojurebot | #error {\n :cause "Unable to resolve symbol: luxbock in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: luxbock in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: luxbock i... |
| 01:15 | rritoch | ,(inc tolstoy) |
| 01:15 | clojurebot | #error {\n :cause "Unable to resolve symbol: tolstoy in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: tolstoy in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: tolstoy i... |
| 01:15 | tolstoy | rritoch: Are you on OSX? |
| 01:15 | rritoch | No, windows |
| 01:16 | tolstoy | rritoch: I use Dash a lot. Has a nice Clojure, Java 8 and ClojureScript set of searchable docs. |
| 01:16 | rritoch | I have windows, linux, and hackintosh, but I don't have clojure/leiningen installed on the hackintosh |
| 01:16 | rritoch | What's the rep command for clojurebot? inc nickname didn't work? |
| 01:17 | luxbock | rritoch: without the comma |
| 01:17 | rritoch | luxbock: Thanks. |
| 01:18 | rritoch | (inc luxbock) |
| 01:18 | rritoch | (inc tolstoy) |
| 01:18 | luxbock | although I think it's lazyboy that has that feature |
| 01:18 | luxbock | lazybot* |
| 01:19 | rritoch | Makes sense, lazybot is never online when I'm here. |
| 01:22 | rritoch | Anyhow, that dash app looks good, I'll try that out later, right now I'm upgrading the linux box to wily werewolf so I can't boot the VM until it's done. |
| 01:23 | tolstoy | I have an integration for Dash with Alfred, which is a pop-up command line on OSX (kinda like spotlight). |
| 01:24 | tolstoy | I can just type "clj repeat" and Dash will fire up and find it. I can never remember if it's repeat or repeatedly that takes a function. ;) |
| 01:28 | rritoch | tolstoy: Well, from repl you can just (doc repeat), (doc repeatedly), but doc doesn't help much if you don't know the name of the function your looking for. |
| 01:28 | tolstoy | Yeah. Needs an "apropos" function or something. |
| 01:29 | tolstoy | ,(.size (Thread/getAllStackTraces)) |
| 01:29 | clojurebot | #error {\n :cause "access denied (\"java.lang.RuntimePermission\" \"getStackTrace\")"\n :via\n [{:type java.security.AccessControlException\n :message "access denied (\"java.lang.RuntimePermission\" \"getStackTrace\")"\n :at [java.security.AccessControlContext checkPermission "AccessControlContext.java" 372]}]\n :trace\n [[java.security.AccessControlContext checkPermission "AccessControlContex... |
| 01:42 | tolstoy | justin_smith: Just for kicks, I implemented that "stats" component. No publishing to kafka, of course. Logs once a minute. Kinda neat. Added in "number or threads". |
| 01:45 | tolstoy | Datomic. Not for low mem systems. ;) |
| 01:53 | kenrestivo | ain't that th truth |
| 01:56 | tolstoy | I guess their whole premise was "what would a db look like if we didn't build it assuming 1970s hardware?" |
| 01:57 | tolstoy | Maybe it would have been different if they'd started with "1970's" budgets. ;) |
| 02:04 | rritoch | Sounds like common-lisp... there's a common-lisp that uses java 5 making it fairly useless. Hopefully postgresql will soon be GPU accellerated, some of the features, like geographic search features are just begging for GPU accelleration. I doubt we'll be seeing any significant advancement in databases from commercial markets, most real progress in databases is taking place in open-source. |
| 02:05 | tolstoy | rritoch: Have you looked in to Datomic? It's pretty neat. Kind of a graph database, and a relational db, and a document db, depending on how you query it. |
| 02:09 | rritoch | tolstoy: This is the first I'm hearing of it, but from looking at the site (datomic.com) it looks like it's well suited for a warehouse, but I'm not so sure it would be a good operational database. |
| 02:10 | tolstoy | It does have some interesting innovations, and it's commercial. |
| 02:26 | rritoch | tolstoy: Well, I think it would really need hibernate and/or JPA support to be integrated into existing enterprise infrastructures. As much as possible I try to avoid database architecture dependencies, but sometimes it is unavoidable. PostgreSQL has superior XML and GEO technologies, while MySQL has superior full-text search capabilities. It seems datomic has superior warehousing capabilities |
| 02:30 | rritoch | tolstoy: Does datomic have any specific support for images? That is my biggest complaint with modern databases, keeping databases synchronized with image "stores", even with tools like amazon S3 is an annoying waste of time since it SHOULD be a service provided by the database. |
| 02:36 | rritoch | I don't think I've worked on two different projects which used the same image storage/retrieval strategy, so virtually every web project requires some amount of new image handling code depending on available resources. I believe it is a common problem that's just overlooked, but it doesn't make sense that new code needs to be done for each project that fundamentally provides the same db function. |
| 02:38 | rritoch | I shouldn't complain, since I certainly like the pay for the extra work, it just seems to be a waste of resources to not have image handling integrated with database technologies. |
| 02:41 | rritoch | I believe MsAccess has good image handling, but I'm quite sure that isn't capable of supporting large enterprise infrastructures, at least I've never seen it implemented in a large infrastructure. |
| 02:43 | qsys | what exactly d'you want to see as 'image handling' on the db? |
| 02:49 | rritoch | qsys: I'd say some kind of implicit distribution, so for example if I "INSERT INTO profile ... :image-data:" that data will get distributed to whatever linked storage device can support it as a directly retrievable file. where you can get FILENAME(somefield) & STORAGE_DEVICE(somefield) to retrive the file directly. Running out of storage space requires moving images around which breaks ... |
| 02:49 | rritoch | the database dependency. If storage space were handled by the database itself, life would be much easier. |
| 02:52 | rritoch | Such a system should also return the actual binary data by default, when the data is selected, and the data pulled from whatever storage media it is currently housed in. |
| 02:52 | qsys | ok, I think I get it... I'm not an db, nor datomic-expert, but I'm pretty sure you can write some functions in datomic once and use them |
| 02:52 | qsys | http://docs.datomic.com/database-functions.html |
| 02:53 | rritoch | A great deal of time is wasted "juggling" iamges with most projects. |
| 02:53 | rritoch | iamges=images |
| 02:53 | qsys | but as far as I know, it's not built-in |
| 02:56 | rritoch | qsys: I suppose if there's full clojure support, and the abilty to pull in dependencies, that may be possible. Exsiting database DSL's dont' provide much for library access, as far as I've seen, which could certainly give datomic an advantage, especially if it can solve the image handling problem (even if provided by extension libraries) |
| 02:58 | qsys | yeah, datomic has full clojure support, so you can use register any kind of transaction function in your own transactor (which might be an external one). I'm not sure how to implement it myself, however, but maybe you got some idea, and many others might be interested :p. |
| 03:01 | rritoch | qsys: Sure it sounds possible, which would be great, finding someone willing to pay for the development is another story. I have one project which requires a huge amount of images (and funding for that matter) but the investors I've talked to so far aren't interested because the project is too big. |
| 03:02 | qsys | so you got a project that's to big for your investors? sounds like something really fun!? |
| 03:04 | rritoch | qsys: Yeah, well the system requires significant data resources, probably 200kb average per record, and anywhere from 1 million to 1 billion records. It is an awesome app, I just don't have the resources to host it and don't yet know anyone with the resources required to host it. |
| 03:06 | qsys | damn'd... and 1 billion seems quite a lot as well. Although datomic certainly can handle that amount, if you go that route, I'd certainly check with the datomic devs how to implement datomic for your use case, if I were you. |
| 03:06 | qsys | I wish I had the resources to help you out (incl. development) :p |
| 03:08 | rritoch | qsys: Well half of the development is done, the API for infinite scalability is in but not implemented, but as soon as the resources estimates were in that's when things fell apart. I somehow need to find a way to drastically scale down the app, which is what the investors suggested. |
| 03:09 | qsys | start small, think big? |
| 03:12 | rritoch | qsys: Yeah, that's almost exactly what the investors said, that no one starts "this" big. |
| 03:12 | qsys | :) |
| 04:12 | m1dnight_ | When I use ring/compojure for a JSON webservice, can request happen concurrently? |
| 04:13 | m1dnight_ | the webservice is basically a wrapper around a scraper. So they can happen concurrently. |
| 05:23 | inpiorum | Hi, I am having issues using core.match |
| 05:24 | inpiorum | I am getting a java.lang.ClassNotFound Exception |
| 05:25 | inpiorum | Core.match is loaded via leiningen |
| 05:43 | novak | I have an example project where I want to play with Clojure compilation. |
| 05:43 | novak | It is made with "lein new example". And in example.core there is simply: |
| 05:43 | novak | (ns example.core) |
| 05:43 | novak | |
| 05:43 | novak | (defn -main [greetee] |
| 05:43 | novak | (println (str "Hello " greetee "!"))) |
| 05:43 | novak | |
| 05:43 | novak | When I do (compile 'example.core) |
| 05:43 | novak | And run java example.core Someone |
| 05:44 | novak | I get Error: Could not find or load main class example.core |
| 05:45 | novak | lein classpath contains target/ folder of my project and all the .class files are in it. |
| 05:51 | aurelian | novak: checkout https://github.com/technomancy/leiningen/blob/stable/doc/TUTORIAL.md#uberjar |
| 05:59 | novak | aurelian: I know about Uberjar, but I don't want lein do the job for me, I'm trying http://clojure.org/compilation |
| 06:01 | aurelian | mkay... from your pasted stuff... you're missing (:gen-class) |
| 06:01 | beaky | what is uberjar |
| 06:03 | novak | aurelian: oh yes it missing... But it is same java error with it. |
| 06:28 | kungi | How can I configure lein-cljsbuild to have a production build with advanced optimizations and a development build with whitespace optimizations. I also have the constraint to build an überjar for my production build. |
| 07:50 | beaky | is it just me or is braveclojure.com no longer existing :( |
| 07:51 | J_Arcane_ | beaky: It's just you. |
| 07:52 | beaky | what |
| 07:52 | beaky | http://downforeveryoneorjustme.com/braveclojure.com |
| 07:52 | beaky | seems it really is down :( |
| 07:52 | beaky | dig braveclojure.com -> nxdomain |
| 07:53 | beaky | oh wait seems its back |
| 07:53 | kungi | beaky: worksforme |
| 07:53 | beaky | yay |
| 07:53 | J_Arcane_ | http://imgur.com/ILXkaMF |
| 07:58 | jonathanj | does anyone use refactor-nrepl? |
| 07:59 | kungi | jonathanj: yes |
| 07:59 | jonathanj | i have it telling me that some file is in a bad state but then neglects to tell me what it things is so bad |
| 07:59 | jonathanj | error "documint.flying-saucer is in a bad state! Error: " |
| 07:59 | kungi | jonathanj: yes :-( |
| 08:09 | jonathanj | so after shaving that yak for 20 minutes, now finally i get a prompt when trying to rename a symbol |
| 08:09 | jonathanj | and this happens: |
| 08:09 | jonathanj | cljr--rename-occurrences: Wrong type argument: hash-table-p, (:line-beg 52 :line-end 52 :col-beg 25 :col-end 42 :name "documint.render/flatten-document" ...) |
| 08:17 | jonathanj | looks like my version of nrepl and refactor-nrepl were out of sync |
| 08:17 | jonathanj | hooray, i can rename symbols |
| 08:23 | beaky | is there something like hlint for clojure |
| 08:25 | scottj | beaky: eastwood and kibit |
| 08:33 | beaky | hello |
| 08:33 | beaky | should i use reduce over the stuff from core.reduce |
| 10:05 | jonathanj | if an exception occurs inside a (future) body, how do i communicate this to other code? |
| 10:12 | luma | the exception will be thrown when you deref the future |
| 10:20 | dxlr8r | hello, is there a library for querying and sorting maps? in the case ordering-maps |
| 10:21 | dxlr8r | I have a yaml file that is converted to ordering-maps, and want to query and sort it |
| 10:22 | dxlr8r | the map is nested to btw |
| 10:23 | ARM7 | sorted-map ? |
| 10:57 | dxlr8r | it is nested. so I might want to sort it after a key that is nested several levels |
| 11:11 | justin_smith | dxlr8r: how about this... |
| 11:11 | justin_smith | ,(sort-by #(get-in % [:a :b :c]) (map #(apply sorted-map %) [[:a {:b {:c 0} :d 100}] [:a {:b {:c 1} :d 1}] [:a {:b {:c -1}} :d 22]])) |
| 11:11 | clojurebot | ({:a {:b {:c -1}}, :d 22} {:a {:b {:c 0}, :d 100}} {:a {:b {:c 1}, :d 1}}) |
| 11:12 | justin_smith | that sorts those sorted maps by the nested key :a -> :b -> :c |
| 12:17 | dxlr8r | justin_smith: thx, I don't get how you can just write that without effort. feel like that noob :P I have troubles understanding it, and would use a long time writing it. I am not good at manipulating maps at all it seems |
| 12:37 | justin_smith | dxlr8r: it's not without effort - it's just that the effort is already done - every time I need to find a nested value in a map I use get in, every time I need to update a nested value I use update-in, eventually it comes naturally, but it's not about instinct, it's about practice |
| 12:48 | dxlr8r | justin_smith: :) yeah, I don't get to program more than 3-4 days a month. so I get rusty. I want to master it :) |
| 12:49 | dxlr8r | this was suppose to be a small project :P kinda regret going for a file relation DB as YAML :P sql would have solved it all in minutes. but I want the db to be portable and easy to edit for everyone |
| 12:49 | dxlr8r | so that is why I chose YAML |
| 13:04 | dxlr8r | the trouble is that the map yaml makes doesn't work very well with get-in etc. I guess I have to try and make a better tree structure |
| 13:29 | ben_vulpes | does anyone know how to get cider to catch stacktraces that are otherwise printing to *nrepl-server ...* |
| 14:06 | dent_ | Is clojure the same as f# |
| 14:07 | ARM7 | no, clojure is a lisp, f# is an ml derivate |
| 14:17 | justin_smith | there is a clr port of clojure |
| 14:39 | isarah | i have a clojure web service that returns a clojure set, what's the best way to convert that clojure set into a json object? |
| 14:39 | isarah | the set is a string obj |
| 14:40 | justin_smith | isarah: if you use cheshire, you can give it pretty much any data and get json on the outside |
| 14:41 | isarah | justin_smith: oh, i don't have access to the web service |
| 14:41 | isarah | im accessing it :o |
| 14:41 | isarah | calling it* |
| 14:43 | justin_smith | and when you call the web service, you get a clojure set? |
| 14:43 | isarah | ya w text |
| 14:44 | isarah | looks like this |
| 14:44 | isarah | {:results ({:index 1, :dim :time, :rule "tomorrow", :value {:start "Saturday, 28 November 2015", :grain :day}, :start 0, :pos 0, :route ({:pos 0, :end 8, :text "tomorrow", :groups ["tomorrow"], :rule nil, :route ()}), :label :time, :values ({:start "Saturday, 28 November 2015", :grain :day}), :end 8, :body "tomorrow", :text "tomorrow"})} |
| 14:44 | justin_smith | there are no sets there |
| 14:45 | justin_smith | so you want to turn that into json? what is this, cljs? |
| 14:45 | isarah | yeah |
| 14:46 | justin_smith | you can use the javascript interop in cljs to make json, you can use clj->js to turn clojurescript structures into js objects |
| 14:46 | isarah | justin_smith: yaa i don't have access to the cljs though, im just exposed to that txt |
| 14:47 | justin_smith | wait, what program gets this data? |
| 14:54 | tolstoy | isarah: Some translators: https://github.com/edn-format/edn/wiki/Implementations (I think). |
| 14:56 | isarah | tolstoy: cool! thanks :) |
| 15:12 | kenrestivo | any tips for debugging core.async channels that seem to lock up in production at random times? |
| 15:13 | kenrestivo | i suspected that maybe something was inadvertently pushing nil into a channel and closing it, but that does not seem to be the case. |
| 16:16 | justin_smith | kenrestivo: in my experience what is much more common is exceptions inside core.async threads not bubbling up to print. Using try/catch inside go blocks helps. |
| 16:45 | didibus | I'd like to hear some opinions about setting options for clojure libs. I'm thinking (1) pass opts to each function that needs any (2) have an atom that needs to be set with a map of opts by the consumer before they call any of the function (3) have dynamic Vars with default root bindings (4) consumer needs to call a initialize function which takes all opts and stores them in an atom |
| 16:57 | gfredericks | didibus: I'm strongly opposed to 2 and 4 |
| 16:57 | gfredericks | because global |
| 16:57 | gfredericks | what kind of lib is it? |
| 16:58 | gfredericks | I've been using clojure for >15 years and I only just today found out that clojure.core/newline exists |
| 17:01 | Fhek | hey i want to get started with clojure, anyone have a good recommendation to start with? |
| 17:02 | gfredericks | 4clojure.com |
| 17:02 | gfredericks | braveclojure.com |
| 17:02 | gfredericks | this channel |
| 17:05 | didibus | It's a lib that gets configs from various files arouns the system. But it, itself needs to know certain things, like, which files to get the config from, what dimension you want, etc. |
| 17:05 | gfredericks | didibus: sounds like the sort of thing a user would only call once? |
| 17:06 | didibus | Ya, pretty much |
| 17:06 | gfredericks | in which case there's no downside to a verbose argument-based api |
| 17:06 | gfredericks | and anything else is just harder to figure out how to use |
| 17:10 | didibus | Right, I guess 1 and 3 do feel nicer. What if you were having a lib that had a use case where it could be called many times, most often with the same settings? |
| 17:10 | didibus | You'd suggest (3) ? |
| 17:13 | gfredericks | not necessarily, I would default to (1) until it hurt really badly |
| 17:14 | gfredericks | java.jdbc is an example of a library that migrated from (3) to (1) |
| 17:14 | gfredericks | and that's a library with things that can get called many times |
| 17:15 | didibus | Hum, I see. So you just let the consumers deal with figuring out how they prefer to re-use the options |
| 17:17 | justin_smith | gfredericks: I only knew about newline because it was mentioned in the doc for println |
| 17:17 | gfredericks | ,(doc println) |
| 17:17 | clojurebot | "([& more]); Same as print followed by (newline)" |
| 17:17 | gfredericks | well what do you know. |
| 17:18 | justin_smith | gfredericks: I was trying to figure out why cider wasn't showing me output |
| 17:18 | justin_smith | so I was looking at docs of output-related thingies |
| 17:18 | gfredericks | ah yes |
| 17:18 | gfredericks | cider |
| 17:19 | justin_smith | didibus: if you explicitly pass args, a client who has another preference can easily turn that into a global, or a thread binding, or a different arg, or something looked up in config - all of these things are easy to implement based on explicit arg passing. |
| 17:19 | justin_smith | didibus: the other options are not flexible in this way. So if flexibility is a concern, do arg passing first, and make sure things work with arg passing, even if you also end up using a global for convenience on top of that basis. |
| 17:20 | justin_smith | or a thread local, or whatever - they are all easy to make once you have arg-passing first |
| 17:20 | gfredericks | justin_smith: well you can implement (1) on top of (3) |
| 17:20 | gfredericks | but it'd be annoying to have to |
| 17:21 | justin_smith | gfredericks: right - I'd call that annoyingness a type of inflexibility, even if it's technically possible |
| 17:21 | justin_smith | but it's undisputed that arg passing is a basis from which all other options can be made easily |
| 17:21 | gfredericks | yeah I'm sure as hell not going to dispute that |
| 17:22 | didibus | Ya, 3 is way easier to build on top of 1 |
| 17:22 | didibus | then the opposite |
| 17:23 | justin_smith | didibus: basically, don't be that grocery store that has garlic salt but no garlic powder - you can combine shit if you want, but people will appreciate the flexibility even if it seems a little less convenient |
| 17:24 | didibus | Right, but wouldn't they appreciate some convenience also? Would it be nice to provide both? |
| 17:24 | justin_smith | sure, sure, - just make sure the flexible thing is fully usable |
| 17:24 | justin_smith | that's my take at least |
| 17:25 | justin_smith | and it's much easier to add convenience to an inconvenient api, than it is to add flexibility to an inflexible one - the former just needs a small light wrapper, the latter tends to result in lots of forking of codebases |
| 17:26 | didibus | Right, that's good advice |
| 17:26 | justin_smith | didibus: lesson learned through much pain :) |
| 17:26 | didibus | gfredericks: there's also \newline literral, I think the reader replaces it with (newline) |
| 17:27 | gfredericks | didibus: (newline) actually prints something |
| 17:27 | justin_smith | didibus: (newline) prints a newline and flushes *out* |
| 17:27 | didibus | oh, haha, interesting |
| 17:28 | didibus | ,(println) |
| 17:28 | clojurebot | \n |
| 17:28 | didibus | ,(newline) |
| 17:28 | clojurebot | \n |
| 17:28 | didibus | Seems kind of redundanat |
| 17:28 | didibus | redundant |
| 17:28 | justin_smith | didibus: println calls newline |
| 17:29 | justin_smith | didibus: it's just like we were talking about - first they implement print which outputs your object, and newline, which makes a newline and flushes, and then you can combine them to println for those cases where you want both (typical convenience case) |
| 17:30 | didibus | I guess |
| 17:30 | didibus | Hum, actually, that might be useful |
| 17:31 | didibus | I've noticed (with-logs) wouldn't log anything that you called (print) |
| 17:31 | didibus | but it did log (println) |
| 17:31 | justin_smith | you can call (flush) |
| 17:31 | justin_smith | (if you need output flushed, but can't output a newline) |
| 17:32 | didibus | right, but for a log, I'd probably want to end it all with a newline + flush. So now you can (with-log (print "something") (print "something else") (newline)) |
| 17:32 | justin_smith | yes, that's true |
| 17:40 | didibus | So, I'm thinking: (func1* param1 param2 param3) (func2* param1 param3 param4) and bindings for all of them with defaults and (func1 (func1* *param1* *param2* *param3*)) (func2 (func2* *param1* *param3* *param4*)) |
| 17:40 | didibus | What do you think of that? |
| 17:41 | justin_smith | didibus: another option is arity overloading |
| 17:45 | didibus | Well, arity overloading wouldn't give the exact same thing. It would give defaults, but it would not let the consumer set his own defaults |
| 17:45 | didibus | Oh, I mean it could. You meant arity overloading and keep the bindings? |
| 17:45 | didibus | so if calling the one with arity 0, it checks for the bindings |
| 17:46 | didibus | ? |
| 17:46 | justin_smith | right, an overloaded arity has to pick defaults right? it could easily pick some thread-bound or global options |
| 17:46 | didibus | Ya, that's true |
| 17:46 | didibus | I can do that |
| 17:46 | didibus | Do you think one binding per option? Or a single binding to a map of options? |
| 17:47 | justin_smith | a map seems more usable |
| 17:47 | didibus | Alright, I'm liking this |
| 17:47 | didibus | thanks |
| 17:51 | didibus | Well, but at that point, isn't it kind of the same. Like: (func lib-opts) implements as (defn func [lib-opts] (binding *lib-opts* lib-opts) ... |
| 17:52 | didibus | or you could just have (defn func [] ...) |
| 17:52 | didibus | andd call it liek so: (binding *lib-opts* lib-opts (func)) |
| 17:53 | rhg135 | I'd suggest the other way around |
| 17:53 | justin_smith | the base form should not using binding |
| 17:53 | justin_smith | among other things, thread-bound values can go badly wrong when you have laziness in play |
| 17:53 | rhg135 | ^ |
| 17:54 | rhg135 | Threads too... |
| 17:54 | justin_smith | didibus: "why'd my database call fail here, but not over there" - "you were using a binding form and returned a lazy result which escaped the binding scope" |
| 17:54 | justin_smith | literally a conversation I had with a co-worker the other day |
| 17:55 | didibus | Haha |
| 17:55 | didibus | And how did it conclude? |
| 17:55 | justin_smith | they had to force the lazy object to be fully realized before it left scope |
| 17:56 | didibus | Alright, I see |
| 17:56 | justin_smith | didibus: but this would not have been an issue if the db config had been explicitly passed in, instead of implicitly thread bound |
| 17:57 | didibus | that's when you would do instead: (func [lib-opts] (let [options (binding *lib-opts* lib-opts) ...] |
| 17:59 | didibus | Hum, no that's wrong lol |
| 17:59 | justin_smith | what is that binding form supposed to be doing? |
| 18:01 | didibus | This is what I was thinking of: (defn some-fn [] (let [foo-val *foo*] (lazy-seq [foo-val]))) |
| 18:02 | justin_smith | didibus: yeah, in this case a lazy-seq was calling a function which needed a dynamically scoped db config |
| 18:03 | didibus | oh I see |
| 18:03 | didibus | Ok, that's tricky |
| 18:04 | didibus | Ok, I'm slowly being convinced on the have params on each function |
| 18:05 | didibus | don't even think I'll provide a way to set a global default |
| 18:10 | rhg135 | What is wrong with just using let? |
| 18:10 | rhg135 | From the calling code |
| 18:11 | rhg135 | It's not that verbose |
| 18:15 | troydm | how do I check if object implements some specific protocol or not? |
| 18:16 | rhg135 | satisfies? |
| 18:17 | didibus | rhg135: nothing really. I think I'm just trying to provide too much convenience up front, for little gain |
| 18:18 | troydm | rhg135: what's the difference between extends? and satisfies? |
| 18:18 | didibus | rhg135: And it's my OOP mindset too I think. I feel like like my lib would be new lib(options) and then all future call use those options. Instead of having each call take options over and over |
| 18:19 | rhg135 | Extends? Check |
| 18:19 | rhg135 | If it subclasses it |
| 18:22 | rhg135 | You could implement that, didibus, but in seperate code. In my experience, I usually already have a way to manage state and the dynamic vars just get in the way |
| 18:23 | didibus | Ya I guess. |
| 18:24 | didibus | I think it's just in OOP I would have done: new Config("root/fallback"); Then config.getRoot(). config.getActualRoot(); config.get("option") |
| 18:24 | rhg135 | Also extends? is usually faster since reasons |
| 18:24 | didibus | While in function it's: getRoot("root/fallback"); getActualRoot("root/fallback"); getConfig("option" "root/fallback"); |
| 18:25 | rhg135 | But less flexible |
| 18:25 | didibus | And I find it weird having to pass the same argument over and over |
| 18:26 | rhg135 | Makes it less magic |
| 18:26 | rhg135 | Functions don't pull data out of thin air |
| 18:27 | didibus | I know haha, got to reprogram my brain around that though |
| 18:28 | rhg135 | But . Does pass a reference to the object as this |
| 18:28 | rhg135 | But it's implicit |
| 18:29 | didibus | ya, that's true |
| 18:30 | Fhek | im gettin this error in sublime using REPL package when i open up a REPL console |
| 18:30 | Fhek | SublimeREPL: obtaining sane environment failed in getenv() |
| 18:30 | Fhek | Check console and 'getenv_command' setting |
| 18:30 | Fhek | WARN: Falling back to SublimeText environment |
| 18:30 | rhg135 | So even in OOP you pass it around |
| 18:31 | didibus | rhg135: Never thought of it that way. You're right, it's just the order. config.get(...) or get(config, ...) |
| 18:32 | rhg135 | Once I grew blind to syntax, I realized it was the same symbols but different orders |
| 18:34 | didibus | rhg135: I think you just made me had a small revelation, thanks |
| 18:35 | rhg135 | Np |
| 18:36 | rhg135 | Fp sure seems different |
| 19:17 | hlolli | How can I prevent clojure from doing E-X ,(float 0.00001) |
| 19:17 | hlolli | ,(float 0.0000001) |
| 19:17 | clojurebot | 1.0E-7 |
| 19:17 | hlolli | ,(double 0.000001) |
| 19:17 | clojurebot | 1.0E-6 |
| 19:19 | hlolli | ,(bigint 0.0000001) |
| 19:19 | clojurebot | 0N |
| 19:19 | hlolli | ,(bigdec 0.000001) |
| 19:19 | clojurebot | 0.0000010M |
| 19:19 | justin_smith | hlolli: is you main concern how it prints? if so, use format to control printing |
| 19:19 | justin_smith | ,(double 0.00001) |
| 19:19 | clojurebot | 1.0E-5 |
| 19:20 | hlolli | yes excacly, it's the way it prints, I convert it to a string. |
| 19:20 | justin_smith | ,(format "%f" 0.00001) |
| 19:20 | clojurebot | "0.000010" |
| 19:20 | hlolli | nice! |
| 19:20 | hlolli | perfect |
| 19:21 | justin_smith | hlolli: also you can do all the things with format you can do with the java formatter, which in turn is based on the same C formatter that most languages copy or use |
| 19:21 | justin_smith | ,1.0E42 |
| 19:21 | clojurebot | 1.0E42 |
| 19:22 | hlolli | ok, sounds good! |
| 19:37 | gfredericks | ,1.0e042 |
| 19:37 | clojurebot | 1.0E42 |
| 19:37 | gfredericks | ,1.0e000042 |
| 19:37 | clojurebot | 1.0E42 |
| 19:37 | gfredericks | ,1.0e0000000000000000000000000000000000000000000000000000042 |
| 19:37 | clojurebot | 1.0E42 |
| 19:37 | gfredericks | TIL |
| 19:37 | gfredericks | ,1.0e0002000000000000000000000000000000000000000000000000042 |
| 19:37 | clojurebot | Infinity |
| 19:37 | justin_smith | close enough for IEEE |
| 19:37 | gfredericks | is that java or clojure implementing that logic? |
| 19:38 | justin_smith | oh, now I wonder |
| 19:45 | gfredericks | is there a bigint involved? |
| 19:47 | dxlr8r | ordering maps encapsulates all pairs in a vector, even when I convert it to a regular map etc. everything is still in vectors. any way to "flatten" it |
| 19:48 | TEttinger | dxlr8r: |
| 19:48 | TEttinger | ,(into (sorted-map) {:b 1 :a 2 :c 3}) |
| 19:48 | clojurebot | {:a 2, :b 1, :c 3} |
| 19:49 | TEttinger | not sure if that's what you want |
| 19:51 | dxlr8r | does that do it nested to? |
| 19:56 | justin_smith | dxlr8r: a sorted map sorts by keys not vals, a sorted map inside any other collection acts the same way, a sorted map does not change the ordering of any collection nested within itself |
| 20:00 | dxlr8r | {[:a 1] [:b 2]} vs {:a 1 :b 2} |
| 20:00 | dxlr8r | or nested |
| 20:00 | justin_smith | the first one has a vector as a key, and another vector as the value |
| 20:01 | justin_smith | ,(keys {[:a 1] [:b 2]}) |
| 20:01 | clojurebot | ([:a 1]) |
| 20:01 | justin_smith | ,(get {[:a 1] [:b 2]} [:a 1]) |
| 20:01 | clojurebot | [:b 2] |
| 20:03 | dxlr8r | I see, I would love to have the structur as a regular key value, not [][]. but the library uses ordering-maps |
| 20:04 | justin_smith | I suspect I don't really understand what you are doing here |
| 20:04 | justin_smith | I hope you are not misled by something like -- |
| 20:04 | justin_smith | ,(map identity {:a 0 :b 1}) |
| 20:04 | clojurebot | ([:a 0] [:b 1]) |
| 20:04 | dxlr8r | circleci/clj-yaml that is. first I created a good data structur with regular maps. tested it out and stuff worked. then I converted that map to YAML to get a blueprint. when I then import the blueprint everything gets inside a [] |
| 20:04 | justin_smith | because that's different - seq of map entries, not map |
| 20:05 | justin_smith | dxlr8r: can you use refheap.com to show the starting data, the call you make, and what comes out? |
| 20:05 | dxlr8r | I could try :) |
| 20:09 | dxlr8r | justin_smith: https://www.refheap.com/3cb51e0ed7064e0cff1724b0f |
| 20:10 | dxlr8r | converting it to, say a sorted map, doesn't do anything with everything being in []'s |
| 20:12 | dxlr8r | updated: https://www.refheap.com/13211ec2b0c1a197a0b838009 |
| 20:13 | TEttinger | ,(into (sorted-map) '([:b 1] [:a 2] [:c 3])) |
| 20:13 | clojurebot | {:a 2, :b 1, :c 3} |
| 20:14 | justin_smith | dxlr8r: instead of (map #(apply sorted-map %) ...) do (into (sorted-map) ...) |
| 20:14 | dxlr8r | only works for the first level, :c is still unaffected |
| 20:15 | justin_smith | right, that's not a recursive operation |
| 20:15 | justin_smith | you could look at clojure.walk/postwalk for a function that would recursively transform ordered-maps into sorted-maps |
| 20:16 | dxlr8r | looks scary :P will try |
| 20:16 | justin_smith | ,(use 'clojure.walk) |
| 20:16 | clojurebot | nil |
| 20:18 | justin_smith | (postwalk (fn [e] (if (sequential? e) (set e) e)) '[a [1 2 3] b [1 2 3] [[e f g] h]]) |
| 20:18 | justin_smith | ,(postwalk (fn [e] (if (sequential? e) (set e) e)) '[a [1 2 3] b [1 2 3] [[e f g] h]]) |
| 20:18 | clojurebot | #{a #{1 3 2} b #{#{e g f} h}} |
| 20:18 | justin_smith | should be straightforward to see how the above call turned all the vectors into sets |
| 20:19 | jhn | i'm using clj-http to POST to a bunch of APIs. I'd like to make n calls (one per api) and use the results of the one that comes back first. what would be an idiomatic way of doing this? |
| 20:19 | justin_smith | jhn: you could use core.async/thread and do alts! using the first result and cancelling all the others |
| 20:20 | rvxi | hi |
| 20:20 | dxlr8r | I get: nth not supported on this type: PersistentHashSet |
| 20:20 | justin_smith | dxlr8r: can you share a paste of what you tried? because yeah you can't call nth on a set |
| 20:20 | jhn | justin_smith: cool, can you point me to a specific example of this or do I just google "core.async/thread alt!"? |
| 20:21 | dxlr8r | (postwalk (fn [e] (if (sequential? e) (set e) e)) yaml->map) |
| 20:21 | dxlr8r | I didn't understand much of that. I'd probably try to do it with a loop recur, but I am not very good |
| 20:22 | justin_smith | dxlr8r: oh, that was just an example (in my example turning sequential things into sets), not the thing I suggested you doing |
| 20:22 | dxlr8r | ahhh, ok |
| 20:23 | justin_smith | dxlr8r: what postwalk does is it walks the tree of the input, and then, when it reaches all the leaves, it walks back up, at each step of going up it replaces that subtree with the result of the function you provide |
| 20:23 | justin_smith | dxlr8r: postwalk doesn't always work - for example it might not know how to handle some of your data structures, but clojure.walk/walk is more flexible (you have to tell it how to decide it has reached a leaf, and how to get the children of each branch, is the big difference) |
| 20:23 | dxlr8r | yeah, I have troubles using reduce dude :P |
| 20:24 | dxlr8r | background from java etc. so no lisp guru |
| 20:24 | dxlr8r | but I try |
| 20:24 | justin_smith | dxlr8r: postwalk is specialized, but it's easier than making the full result by hand |
| 20:24 | justin_smith | because doing a full tree transform isn't just a loop, recur |
| 20:24 | dxlr8r | I am sure it is if you can wrap your head around it |
| 20:24 | dxlr8r | I see |
| 20:24 | dxlr8r | hmmm |
| 20:25 | justin_smith | dxlr8r: there is also a wikipedia page for postwalk / prewalk etc. as traversal strategies, checking that out might help |
| 20:25 | justin_smith | this isn't just lisp, it's algorithms / data structures stuff |
| 20:25 | dxlr8r | I think I might look another yaml parse |
| 20:26 | dxlr8r | true justin_smith, guess that ain't my strong side |
| 20:26 | dxlr8r | never got longer than sorting algoritmes at school |
| 20:26 | justin_smith | dxlr8r: here it's called pre-order and post-order https://en.wikipedia.org/wiki/Tree_traversal |
| 20:29 | justin_smith | dxlr8r: it's kind of true that because we are using immutable data structures, we use algorithms and concepts that don't usually come up for a given task in a "normal" language - but IMHO it's really worth trying to sort out how and why that stuff works |
| 20:31 | dxlr8r | yeah, I don't about your education or background. but I see a lot of lazyness, using libraries etc. instead of learning. why should I learn quicksort in C when I can do "new Quicksort"? and then it hit's you, you are a noob programmer :P |
| 20:33 | justin_smith | dxlr8r: self-taught, never enrolled in college of any sort |
| 20:33 | dxlr8r | clojure has a lot of nice functions. but it usually lacks "built-in" recursivness. I seldom have any use of a one dimensional map, so to me most easy examples etc. are useless |
| 20:33 | dxlr8r | justin_smith: impressiv. I have bachelors degree |
| 20:33 | justin_smith | built in recursiveness? |
| 20:34 | dxlr8r | yeah, like go more than one level |
| 20:35 | justin_smith | we have a lot of things that can work on multiple levels of an input - for, doseq, get-in, update-in, assoc-in, zippers, everything in the clojure.walk namespace |
| 20:36 | justin_smith | and of course any function can be recursive by using map or for to work recursively on the next level of the input (if present) |
| 20:36 | dxlr8r | yeah, used zipper once, really liked that one |
| 21:07 | dxlr8r | justin_smith: omgf, it's 03am and I did it |
| 21:07 | dxlr8r | I guess thx for tips, but not giving me the answer |
| 21:07 | dxlr8r | (postwalk #(if (map? %) (into (sorted-map) %) %) yaml->map) |
| 21:08 | justin_smith | dxlr8r: awesome! |
| 21:08 | dxlr8r | yes, I can do it when I want to :P |
| 21:09 | justin_smith | and another day when it isn't 3 am, you might see what the equivalent code would be without using the built in postwalk, if you recursively rebuilt turning maps into sorted-maps with your own function |
| 21:10 | justin_smith | it would probably be informative |
| 21:11 | dxlr8r | hehe, yeah. this was suppose to be an easy YAML -> HTML app for some d&d stuff |
| 21:11 | justin_smith | dxlr8r: I am having similar troubles trying to do basic things in haskell right now |
| 21:12 | dxlr8r | :) , would probably be a lot quicker to do it with JS etc. But I wanted to do it with clojure |
| 21:13 | tolstoy | I remember trying to do something with XML with Haskell (interop with an old system), and encountering zippers or arrows or something ... oy. |
| 21:13 | dxlr8r | been updating my github lately with clojure to. one project I want to put out on clojars |
| 21:14 | tolstoy | The ascii art defeated me. ~*> and so on. ;) |
| 21:17 | dxlr8r | if you ever need to do calculations with IP's btw, https://github.com/dxlr8r/cliptools |
| 21:21 | tolstoy | Heh. I wrote some of those very same functions, I think. |
| 21:21 | dxlr8r | great minds think a like :P |
| 21:24 | tolstoy | Also some related to CIDR stuff. |
| 21:25 | tolstoy | https://gist.github.com/zentrope/6516974 |
| 21:26 | tolstoy | It's all coming back to me ... I needed to generate a lot of fake IP addresses, then search for them as in "find addresses in a given CIDR range" or something. |
| 21:32 | dxlr8r | nice, using more functions I see. bit-and, bit-shift-xxx etc |
| 21:32 | dxlr8r | but, night time :P |
| 21:32 | dxlr8r | gonna make pepperkaker tomorrow. cookies for the holidays :) |
| 23:50 | douglarek` | anyone knows how can I pass x to a func then return x |
| 23:51 | douglarek` | before I saw a func can do it |
| 23:53 | TEttinger | ,(defn go-long [x] (do (println (str "GO LONG, " x "!")) x)) |
| 23:53 | clojurebot | #'sandbox/go-long |
| 23:53 | TEttinger | ,(go-long "douglarek") |
| 23:53 | clojurebot | GO LONG, douglarek!\n"douglarek" |
| 23:54 | douglarek` | , (defn f [x] (take 1 (repeat x))) |
| 23:54 | clojurebot | #'sandbox/f |
| 23:54 | douglarek` | , (f 1) |
| 23:54 | clojurebot | (1) |
| 23:55 | justin_smith | ,(defn id [x] (get x x x)) |
| 23:55 | clojurebot | #'sandbox/id |
| 23:55 | justin_smith | ,(id 1) |
| 23:55 | clojurebot | 1 |
| 23:56 | douglarek` | TEttinger: i remmebered a func in Clojure can do something in Python like this: lambda x:x |
| 23:56 | justin_smith | douglarek`: identity |
| 23:56 | justin_smith | don't do what I did up there, that was a joke |
| 23:56 | douglarek` | justin_smith: yeah, that's it |