#clojure log - Nov 27 2015

The Joy of Clojure
Main Clojure site
Google Group
List of all logged dates

0:13 elvis4526: Great, I'm gonna look into schema too, it looks cool

0: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.

0:47 tolstoy: What do you mean "map the values to nil"?

0: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.

0:48 tolstoy: So you want to remove the nil values of the list?

0: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

0:49 tolstoy: No, I want to turn all values of a list into nil

0:49 tolstoy: Oh.

0:50 ,(take 10 (cycle [nil]))

0:50 clojurebot: (nil nil nil nil nil ...)

0:50 luxbock: ,(repeat 10 nil)

0:50 clojurebot: (nil nil nil nil nil ...)

0:50 tolstoy: Yeah, was just looking that one up. ;)

0:52 rritoch: tolstoy & luxbock: Thanks, (repeat (count '("A" "B" "C")) nil) syntax will solve the problem nicely.

1:15 I forgot all about the clojure cheatsheet... What I really need is some ginko biloba, lol. Thanks again! That solved the problem perfectly.

1:15 ,(inc luxbock)

1: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...

1:15 rritoch: ,(inc tolstoy)

1: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...

1:15 tolstoy: rritoch: Are you on OSX?

1:15 rritoch: No, windows

1:16 tolstoy: rritoch: I use Dash a lot. Has a nice Clojure, Java 8 and ClojureScript set of searchable docs.

1:16 rritoch: I have windows, linux, and hackintosh, but I don't have clojure/leiningen installed on the hackintosh

1:16 What's the rep command for clojurebot? inc nickname didn't work?

1:17 luxbock: rritoch: without the comma

1:17 rritoch: luxbock: Thanks.

1:18 (inc luxbock)

1:18 (inc tolstoy)

1:18 luxbock: although I think it's lazyboy that has that feature

1:18 lazybot*

1:19 rritoch: Makes sense, lazybot is never online when I'm here.

1:22 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.

1:23 tolstoy: I have an integration for Dash with Alfred, which is a pop-up command line on OSX (kinda like spotlight).

1:24 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. ;)

1: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.

1:28 tolstoy: Yeah. Needs an "apropos" function or something.

1:29 ,(.size (Thread/getAllStackTraces))

1: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...

1: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".

1:45 Datomic. Not for low mem systems. ;)

1:53 kenrestivo: ain't that th truth

1:56 tolstoy: I guess their whole premise was "what would a db look like if we didn't build it assuming 1970s hardware?"

1:57 Maybe it would have been different if they'd started with "1970's" budgets. ;)

2: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.

2: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.

2: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.

2:10 tolstoy: It does have some interesting innovations, and it's commercial.

2: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

2:30 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.

2:36 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.

2:38 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.

2:41 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.

2:43 qsys: what exactly d'you want to see as 'image handling' on the db?

2: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 ...

2:49 the database dependency. If storage space were handled by the database itself, life would be much easier.

2:52 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.

2: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

2:52 http://docs.datomic.com/database-functions.html

2:53 rritoch: A great deal of time is wasted "juggling" iamges with most projects.

2:53 iamges=images

2:53 qsys: but as far as I know, it's not built-in

2: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)

2: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.

3: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.

3:02 qsys: so you got a project that's to big for your investors? sounds like something really fun!?

3: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.

3: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.

3:06 I wish I had the resources to help you out (incl. development) :p

3: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.

3:09 qsys: start small, think big?

3:12 rritoch: qsys: Yeah, that's almost exactly what the investors said, that no one starts "this" big.

3:12 qsys: :)

4:12 m1dnight_: When I use ring/compojure for a JSON webservice, can request happen concurrently?

4:13 the webservice is basically a wrapper around a scraper. So they can happen concurrently.

5:23 inpiorum: Hi, I am having issues using core.match

5:24 I am getting a java.lang.ClassNotFound Exception

5:25 Core.match is loaded via leiningen

5:43 novak: I have an example project where I want to play with Clojure compilation.

5:43 It is made with "lein new example". And in example.core there is simply:

5:43 (ns example.core)


5:43 (defn -main [greetee]

5:43 (println (str "Hello " greetee "!")))


5:43 When I do (compile 'example.core)

5:43 And run java example.core Someone

5:44 I get Error: Could not find or load main class example.core

5:45 lein classpath contains target/ folder of my project and all the .class files are in it.

5:51 aurelian: novak: checkout https://github.com/technomancy/leiningen/blob/stable/doc/TUTORIAL.md#uberjar

5: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

6:01 aurelian: mkay... from your pasted stuff... you're missing (:gen-class)

6:01 beaky: what is uberjar

6:03 novak: aurelian: oh yes it missing... But it is same java error with it.

6: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.

7:50 beaky: is it just me or is braveclojure.com no longer existing :(

7:51 J_Arcane_: beaky: It's just you.

7:52 beaky: what

7:52 http://downforeveryoneorjustme.com/braveclojure.com

7:52 seems it really is down :(

7:52 dig braveclojure.com -> nxdomain

7:53 oh wait seems its back

7:53 kungi: beaky: worksforme

7:53 beaky: yay

7:53 J_Arcane_: http://imgur.com/ILXkaMF

7:58 jonathanj: does anyone use refactor-nrepl?

7:59 kungi: jonathanj: yes

7: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

7:59 error "documint.flying-saucer is in a bad state! Error: "

7:59 kungi: jonathanj: yes :-(

8:09 jonathanj: so after shaving that yak for 20 minutes, now finally i get a prompt when trying to rename a symbol

8:09 and this happens:

8:09 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" ...)

8:17 looks like my version of nrepl and refactor-nrepl were out of sync

8:17 hooray, i can rename symbols

8:23 beaky: is there something like hlint for clojure

8:25 scottj: beaky: eastwood and kibit

8:33 beaky: hello

8:33 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 I have a yaml file that is converted to ordering-maps, and want to query and sort it

10:22 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 ,(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 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 so that is why I chose YAML

13:04 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 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 im accessing it :o

14:41 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 looks like this

14:44 {: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 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 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 because global

16:57 what kind of lib is it?

16:58 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 braveclojure.com

17:02 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 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 You'd suggest (3) ?

17:13 gfredericks: not necessarily, I would default to (1) until it hurt really badly

17:14 java.jdbc is an example of a library that migrated from (3) to (1)

17:14 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 so I was looking at docs of output-related thingies

17:18 gfredericks: ah yes

17:18 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 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 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 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 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 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 that's my take at least

17:25 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 ,(println)

17:28 clojurebot: \n

17:28 didibus: ,(newline)

17:28 clojurebot: \n

17:28 didibus: Seems kind of redundanat

17:28 redundant

17:28 justin_smith: didibus: println calls newline

17:29 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 Hum, actually, that might be useful

17:31 I've noticed (with-logs) wouldn't log anything that you called (print)

17:31 but it did log (println)

17:31 justin_smith: you can call (flush)

17:31 (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 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 Oh, I mean it could. You meant arity overloading and keep the bindings?

17:45 so if calling the one with arity 0, it checks for the bindings

17:46 ?

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 I can do that

17:46 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 thanks

17:51 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 or you could just have (defn func [] ...)

17:52 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 among other things, thread-bound values can go badly wrong when you have laziness in play

17:53 rhg135: ^

17:54 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 literally a conversation I had with a co-worker the other day

17:55 didibus: Haha

17:55 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 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 Ok, that's tricky

18:04 Ok, I'm slowly being convinced on the have params on each function

18:05 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 From the calling code

18:11 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 If it subclasses it

18:22 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 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 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 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 SublimeREPL: obtaining sane environment failed in getenv()

18:30 Check console and 'getenv_command' setting

18:30 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 Fp sure seems different

19:17 hlolli: How can I prevent clojure from doing E-X ,(float 0.00001)

19:17 ,(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 ,(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 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 ,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 ,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 ,(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 or nested

20:00 justin_smith: the first one has a vector as a key, and another vector as the value

20:01 ,(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 I hope you are not misled by something like --

20:04 ,(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 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 justin_smith: https://www.refheap.com/3cb51e0ed7064e0cff1724b0f

20:10 converting it to, say a sorted map, doesn't do anything with everything being in []'s

20:12 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 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 ,(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 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 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 background from java etc. so no lisp guru

20:24 but I try

20:24 justin_smith: dxlr8r: postwalk is specialized, but it's easier than making the full result by hand

20:24 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 I see

20:24 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 this isn't just lisp, it's algorithms / data structures stuff

20:25 dxlr8r: I think I might look another yaml parse

20:26 true justin_smith, guess that ain't my strong side

20:26 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 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 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 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 justin_smith: omgf, it's 03am and I did it

21:07 I guess thx for tips, but not giving me the answer

21:07 (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 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 https://gist.github.com/zentrope/6516974

21:26 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 but, night time :P

21:32 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 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 don't do what I did up there, that was a joke

23:56 douglarek`: justin_smith: yeah, that's it

Logging service provided by n01se.net