#clojure log - Sep 17 2015

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

2:05 justin_smith: win 15

4:26 Olajyd: Hi All

4:27 gilliard: Morning

4:27 Olajyd: Hi, TEttinger :D

4:27 TEttinger: hey Olajyd!

4:30 Olajyd: I want to split a comma seperated values, “Costa Rica, El Salvador,Paris” :(clojure.string/split “Costa Rica, El Salvador,Paris” (re-pattern “,”)) => [“Costa Rica”,”El Salvador”,”Paris”], I’m kinda lost on the regex to use ;)

4:33 luma: ,(clojure.string/split "Costa Rica, El Salvador,Paris" #", *")

4:33 clojurebot: ["Costa Rica" "El Salvador" "Paris"]

4:43 Olajyd: (clojure.string/split "Costa Rica, El Salvador,Paris" (re-pattern “, *”))

4:43 ,(clojure.string/split "Costa Rica, El Salvador,Paris" (re-pattern “, *”))

4:43 clojurebot: #error {\n :cause "Unable to resolve symbol: “ in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: “ 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: “ in this context"\n ...

4:44 Olajyd: ,(clojure.string/split "Costa Rica, El Salvador,Paris" (re-pattern ", *"))

4:44 clojurebot: ["Costa Rica" "El Salvador" "Paris"]

4:51 TEttinger: looks like you got it on your own, Olajyd!

4:52 (inc Olajyd) ; for learning by doing

4:52 (dec lazybot) ; for never being online

4:52 Olajyd: (inc TEttinger) for the support :D

4:59 oddcully: (inc luma)

5:08 wombawomba: So I have a ^:dynamic var, that I would like to be able to set in the repl, *without* wrapping every single call to a function that touches it with (binding [...] ). How do I accomplish this?

5:09 (I would be cool with having something like a set-my-var-to-the-repl-value function, that could be manually called)

6:07 hyPiRion: wombawomba: (set! *var* foo), no?

6:08 ,(set! *print-length* 7)

6:08 clojurebot: 7

6:08 hyPiRion: ,(range 10)

6:08 clojurebot: (0 1 2 3 4 ...)

6:08 hyPiRion: ,*print-length*

6:08 clojurebot: 5

6:09 hyPiRion: ,( o (set! *print-length* 7) (range 10))

6:09 clojurebot: #error {\n :cause "Unable to resolve symbol: o in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: o 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: o in this context"\n ...

6:09 hyPiRion: ,(do (set! *print-length* 7) (range 10))

6:09 clojurebot: (0 1 2 3 4 5 6 ...)

6:28 noncom: justin_smith: yes, in reagent. i think that having a per-page small status atoms, like what subpage is displayed is ok, and have a browser-local database-like state in a dedicated namespace where all the main data model is stored

6:29 however, maybe there is a better design or maybe this one can bring complexions later

6:29 *complications

6:35 voytech: Hello all, I have a question, I'd like to do something like (binding []) but to be able to initialize var automatically and to have dynamic scope to be able to get binding value in inner function. Is this possible ?

6:36 I want almost the same functionality as binding, but to not to be required to initialize var ealier.

6:48 hyPiRion: voytech: bound-fn?

6:52 voytech: hyPiRion: As I see bound-fn is rather to move bindings into different thread. I'd like to not have to call: def :^dynamic somevar before we can use it in binding []

6:53 hyPiRion: I think I can do this by interning var then accessing in nested function by var-get and then removing from ns

6:54 hyPiRion: But I was looking for better way.

6:55 hyPiRion: My question is because I have some function local vars which I want to be visible in nested function with the same binding, but I do not want to use def :^ dynamic inside function.

7:10 Empperi: hmm, I'm trying to open an InputStream against a File object with explicitly defined encoding

7:10 but it looks like clojure.java.io doesn't use the applied opts at all in that scenario

7:10 first it goes here https://github.com/clojure/clojure/blob/master/src/clj/clojure/java/io.clj#L229

7:11 where it creates FileInputStream object directly from the given File object, no problem here

7:11 however, then it goes here https://github.com/clojure/clojure/blob/master/src/clj/clojure/java/io.clj#L191

7:11 and there opts is silently ignored

7:12 which kinda sucks ass

7:12 but! now I understand

7:12 of course... I should use a Reader

7:12 forget it ppl :)

7:34 wombawomba: if I'm interacting with a library from the repl, and that library requires me to bind a ^:dynamic var to work, is there any way to get around having to wrap every single call in (binding [lib/var myvalue] ...)?

7:35 ane: https://www.refheap.com/109644 is this the right way to do this?

7:36 justin_smith: wombawomba: you could just set the root binding with set! right?

7:36 or does that not work with dynamic vars...

7:36 wombawomba: no idea lol, I'll try that right away

7:36 justin_smith: ane: instead of an atom plus while, use go-loop and a branch where you don't call recur

7:37 ane: oh, that exists

7:37 justin_smith: ane: also, alts! returns a two element vector, the value and the channel it came from

7:37 ane: yeah, but i don't need the channel

7:38 justin_smith: then don't use it!

7:38 because right now v is the two element vector :)

7:38 ane: <! will work just fine?

7:38 justin_smith: if you are only reading from one channel, indeed it will

7:38 wombawomba: justin_smith: java.lang.IllegalStateException: Can't change/establish root binding of: *the-thing-i-want-to-set* with set

7:38 justin_smith: well OK then

7:40 "Currently, it is an error to attempt to set the root binding of a var using set!, i.e. var assignments are thread-local."

7:41 the next question should be obvious...

7:42 wombawomba: welp I don't know what the next question should be :(

7:43 justin_smith: how to set the thread-local rather than root value

7:43 wombawomba: oh, okay

7:43 justin_smith: (other than binding which is impractical of course)

7:43 wombawomba: yeah

7:43 justin_smith: but I don't know the answer to that one yet

7:48 wombawomba: justin_smith: I tried using https://clojuredocs.org/clojure.core/push-thread-bindings, but I can't get it working in the repl..

7:51 justin_smith: wombawomba: you can set dynamic vars for your repl in project.clj, maybe doing it that way is easiest?

7:51 though I would really prefer something that you could do from scratch in a repl

7:53 ane: justin_smith: replaced it with this https://www.refheap.com/109646

7:53 i guess that could be even shorter with if-let

7:53 *when-let

7:54 justin_smith: yup, that would probably be the thing, and at that point it would be perfect I guess

8:02 wombawomba: justin_smith: how would I do that?

8:02 visof__: how can i generate random numbers between 0 and 1?

8:02 wombawomba: I guess I could make the library check if some var is set, to try to figure out if it's part of the repl, but... eh

8:02 it seems there should be a better way..

8:02 justin_smith: ,(rand) ; visof__

8:03 clojurebot: 0.004625421258164786

8:04 visof__: ,(rand 1)

8:04 clojurebot: 0.47916350622420223

8:04 visof__: ,(rand 1)

8:04 clojurebot: 0.3507468588750795

8:04 visof__: ,(rand 1)

8:04 clojurebot: 0.16249550680299163

8:04 visof__: ,(rand 1)

8:04 clojurebot: 0.4649720453046504

8:04 visof__: that's great

8:04 justin_smith: visof__: you don't need the arg

8:04 ,(rand)

8:04 clojurebot: 0.22746045171118823

8:04 visof__: justin_smith: its limit to 1

8:04 ?

8:04 ,(rand)

8:04 clojurebot: 0.09761248165826408

8:04 visof__: ,(rand)

8:04 clojurebot: 0.27152246889876974

8:04 visof__: ,(rand)

8:04 clojurebot: 0.5025658325879707

8:04 visof__: ,(rand)

8:04 clojurebot: 0.11801785522003727

8:04 visof__: ,(rand)

8:04 clojurebot: 0.7971211475060466

8:04 visof__: ,(rand)

8:04 clojurebot: 0.1795771621448604

8:05 justin_smith: ,(apply (juxt min max) (repeatedly 1000 rand))

8:05 clojurebot: [2.9476404946426893E-4 0.9995800375194103]

8:05 justin_smith: out of 1000 calls, those were the smallest and largest resulting values

8:05 wombawomba: is there any way to modify lein repl commands before they are run?

8:06 justin_smith: wombawomba: you can set root bindings in project.clj

8:06 visof__: ,(apply (juxt min max) (repeatedly 1000 (rand 1)))

8:06 clojurebot: #error {\n :cause "java.lang.Double cannot be cast to clojure.lang.IFn"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.Double cannot be cast to clojure.lang.IFn"\n :at [clojure.core$repeatedly$fn__5099 invoke "core.clj" 4924]}]\n :trace\n [[clojure.core$repeatedly$fn__5099 invoke "core.clj" 4924]\n [clojure.lang.LazySeq sval "LazySeq.java" 40]\n [clojure.lang.LazySeq seq...

8:06 justin_smith: visof__: repeatedly needs a function

8:06 wombawomba: https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L258

8:07 visof__: ,(apply (juxt min max) (repeatedly 1000 (fn [] (rand 1))))

8:07 clojurebot: [1.0407398903533593E-4 0.9988080589538587]

8:07 wombawomba: justin_smith: but I only want this to happen in the repl

8:07 visof__: ,(apply (juxt min max) (repeatedly 1000 (fn [] (rand 1))))

8:07 clojurebot: [9.545941192781182E-4 0.9993885416513495]

8:07 justin_smith: wombawomba: then put it in the repl profile?

8:08 gilliard: visof__: have you looked at the source for (rand) ?

8:08 visof__: justin_smith: is there more accurate to only get random numbers between 0 and 1?

8:08 gilliard: nope

8:08 gilliard: (rand n) just does (* n (rand))

8:08 justin_smith: visof__: accurate? what do you mean?

8:08 wombawomba: justin_smith: ok

8:08 justin_smith: visof__: those min and max values are pretty damn close to 0 and 1

8:09 visof__: ok

8:11 wombawomba: justin_smith: so the binding I want to change is part of a specific namespace, and it seems I can't override that using the :global-vars thing

8:12 (because that's only for global vars, I guess)

8:12 justin_smith: oh, because the ns is not loaded yet

8:12 all vars are global, once they exist

8:12 wombawomba: alright

8:12 justin_smith: (except with-local-vars but nobody uses that)

8:12 wombawomba: maybe an injection that loads the ns before setting the global binding? not sure

8:13 wombawomba: yeah, maybe

8:13 that's also kinda bad though

8:13 justin_smith: or make an alternate -main that launches an nrepl server inside a (binding [...] ...) block

8:13 dynamic vars seem like a real pain in the ass

8:14 wombawomba: ideally I would want this to happen *from* the repl

8:14 basically, what I'm doing is I'm writing a docker wrapper, that starts up or attaches to containers and helps you communicate with them

8:16 when running the actual code, I want to always get fresh containers (the goal is to use this for testing)

8:16 but in the repl, I want to be able to either start a container or attach to one that's already running

8:17 also, I don't want to have to pass references to the containers around everywhere

8:17 which is why I'm using bindings

8:18 which works great, since it allows me to have different threads spin up and manage their own containers

8:18 aand it allows me to override the default behaviour when I'm working in the repl, so I don't have to deal with restarts etc

8:19 ..but then that requires me to wrap everything in (binding [*container-a* my-repl-container *container-b* my-other-repl-container] ...), which is bad

8:19 maybe there's another approach I could take that would work?

8:24 cross: [A

8:44 wombawomba: justin_smith: in case you're interested, I did find a solution that works pretty well :)

9:37 visof___1: ,(reduce and false [false false true])

9:37 clojurebot: #error {\n :cause "Can't take value of a macro: #'clojure.core/and"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/and, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Can't take value of a macro: #'clojure....

9:38 visof___1: ,(every? true [false false true])

9:38 clojurebot: #error {\n :cause "java.lang.Boolean cannot be cast to clojure.lang.IFn"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.Boolean cannot be cast to clojure.lang.IFn"\n :at [clojure.core$every_QMARK_ invokeStatic "core.clj" 2553]}]\n :trace\n [[clojure.core$every_QMARK_ invokeStatic "core.clj" 2553]\n [clojure.core$every_QMARK_ invoke "core.clj" -1]\n [sandbox$eval48 invoke...

9:38 visof___1: ,(every? [false false true] true)

9:38 clojurebot: #error {\n :cause "Don't know how to create ISeq from: java.lang.Boolean"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Don't know how to create ISeq from: java.lang.Boolean"\n :at [clojure.lang.RT seqFrom "RT.java" 535]}]\n :trace\n [[clojure.lang.RT seqFrom "RT.java" 535]\n [clojure.lang.RT seq "RT.java" 516]\n [clojure.core$seq__4116 invokeStatic "core.clj" 137]\n [cloj...

9:40 visof___1: ,(every? true? [true false false])

9:40 clojurebot: false

10:11 lodin-away: visof___1: You can wrap and in a function, #(and %1 %2), but note that it will not short circuit.

10:55 TimMc: What's a reasonable way to determine if a value appears anywhere in the leaves of a data structure?

10:55 I'm looking for a string somewhere in a big pile of records, vectors, and seqs.

10:55 clojurebot: Titim gan éirí ort.

10:56 TimMc: Of note, flatten (which I was eyeing suspiciously) doesn't flatten maps.

10:57 sobel: TimMc: maybe useful? https://mwfogleman.github.io/posts/20-12-2014-flatcat.html

11:01 TimMc: ah, tree-seq!

11:02 expez: functions updating the state of an agent are subject to retries, right?

11:03 Or is there an internal queue of next states?

11:03 static class ActionQueue

11:03 sweet

11:05 TimMc: (.contains (tree-seq coll? #(if (map? %) (vals %) %) ds) "search-item")

11:06 Even better: (tree-seq coll? seq ds)

11:19 phaseNi: Hello, is it possible to use reify dynamically? for instance, pass it a generated seq of methods rather than putting it in the code

11:20 sobel: i don't see why not

11:23 phaseNi: i get a null pointer exception from the compiler

11:23 (reify VariousMessageListenerAdapter methods)

11:24 luma: reify is a macro, you can't pass the methods dynamically

11:24 phaseNi: would eval work?

11:25 * phaseNi tries

11:30 lodin-: What do you usually use for handle expected failures when just returning nil is not enough? I often just return [:success ...] or [:failure ...] and use core.match on the returned value. Any nice library out there that you use?

11:38 sobel: could you wrap reify in a fn?

11:40 voytech: lodin-: I'd probably end up with something like throwing ex-info and maybe core.match on exception data ?? (but this is only my first thought - I'm not convinced it will match your needs)

11:41 lodin-: voytech: I avoid throwing when the failure is a valid response.

11:42 phaseNi: I rarely use reify, but all methods must belong to an interface (possibly genereted by defprotocol), right?

11:43 voytech: lodin-: Ah ok, if it is something expected then throwing seems to be not best choice.

11:47 sobel: if you make your functions nil-tolerant then you can get away with fewer throws from creational code

11:47 or that's been my nominal experience

11:49 lodin-: sobel: Right, but nil does not convey any information, so to be able to handle the failure you need to pass out some kind of failure information.

11:50 sobel: that's fair. my error handling fu in clojure is not very strong yet

11:52 lodin-: Returning [:success x] instead of x and [:failure info] instead of (throw (ex-info "Failure" info)), and unpacking with core.match works rather well.

11:54 I'd prefer to use a library that might add some sugar and what-not, if such a library exists. A superficial search on clojars didn't turn up any though.

12:00 sobel: yes, tagging returns sounds pretty hip

12:13 zippr: I'm building a Hacker News reader in ClojureScript as a learning exercise. I'm building up a vector of maps of stories, but I'm mutating an atom to do so. I'm wondering if there's a better way to do this, using pure functions? The thing that's throwing me off is that the requests are async, so I'm not sure if I could use something like reduce. http://pastebin.com/Xbpg8LzU

12:14 I'm using this lib for ajax calls https://github.com/JulianBirch/cljs-ajax

12:19 My example above works, but I'd like to batch the 30 calls together, and reset! the atom after I've gotten results for all API calls

12:19 Not sure if I need futures or core.async for this

12:27 lodin-: zippr: I don't have a full understanding of your problem, but I'd say core.async.

12:29 zippr: lodin-: Basically I'm wondering if I can use pure functions to build up a data struct instead of mutating the atom repeatedly.

12:32 blake_: I have a string I want to put into HTML output: <link href="/style.css" rel="stylesheet" type="text/css">

12:33 I found htmlize but I was wondering if there wasn't something amongst the many libraries I've been using that would do this.

12:33 Deraen: zippr: https://github.com/r0man/cljs-http works great with core.async for doing http calls

12:33 blake_: Maybe not, considering I haven't had to do it until now.

12:33 lodin-: zippr: I have not used cljs-ajax. I assume that GET returns immediately and handler is invoked when the response is available?

12:33 zippr: lodin-: correct

12:35 lodin-: zippr: In that case you can use a promise and deliver in the handler, and the other code in the handler is pure. Like (let [stuff (promise)] (GET :handler #(deliver stuff (f %))) @stuff). But I'd opt for core.async.

12:37 zippr: lodin-: Interesting; I'll check that out. Thanks.

12:40 Deraen: zippr: lodin-: Cljs doesn't have promises

12:40 blake_: Hmm. HTMLize is an emacs macro.

12:41 lodin-: Deraen: I always forget that cljs not= clj. I haven't learned the differences yet. I do it the hard way (i.e. code as if it was clj and discover I need to do it differently). :-/

12:42 zippr: Correction. I *really* opt for core.async. ;-)

12:43 zippr: lodin-: Deraen: :-) core.async it is

12:43 Deraen: And instead of trying to use cljx-ajax with core.async I would suggest using cljs-http

12:44 zippr: Any recommended resources for learning core.async?

13:03 joefromct: does anyone know where i can find more help or documentation on sparkling? Specifically i'm trying to understand how to deploy with a master on yarn.

13:15 zerokarmaleft: zippr: https://github.com/cognitect/async-webinar

13:18 WorldsEndless: I'm trying to get the hang of monger/mongodb and can't seem to figure out the syntax to use $set in my update function

13:18 zerokarmaleft: zippr: the core.async repo has a repl-friendly walkthrough also under examples/

13:19 WorldsEndless: (coll/update libdb "books" {:author "Tolkien"} {$set {:title "The Fellowship of the Ring"}}) ;; fails "unable to resolve symbol: $set"

13:22 justin_smith: I just got my copy of Clojure Applied in the mail

13:23 WorldsEndless: what is $set supposed to be? it's not a valid definition clearly

13:23 WorldsEndless: $set is a mongo symbol to simply change the given without altering the other items; supposedly monger supports it, so I'm trying to get it to work

13:24 justin_smith: WorldsEndless: then maybe you want a symbol

13:24 '$set is a symbol

13:24 WorldsEndless: justin_smith: You are correct. Odd that the documentation gave a different example of usage

13:25 justin_smith: WorldsEndless: maybe they quoted the whole hash-map

13:25 uris77: I've used "$set"

13:25 justin_smith: '{$set {:title ...}}

13:25 WorldsEndless: Oh, wait. They have [monger.operators :refer :all] in the ns declaration; I'm guessing that does it

13:26 uris77: yeah

13:27 i've used it like this, now that I recall, https://github.com/uris77/pasmo-gigi-clj/blob/master/src%2Fpasmo_gigi%2Fdb%2Foutlet_surveys.clj#L7

13:27 I remember struggling to find the namespace

13:34 WorldsEndless: Whoa... just discovered the grimoire. I have a feeling that clojure just got easier.

13:46 triss: so laziness.... when we do a `map` or `filter` or whatever the first 30 elements in the seq are evaluated immediately aren't they?

13:46 Is it possible to defer evaluation right up until the values are used?

13:48 lodin-: triss: Google for dechunk and/or seq1.

13:48 triss: cheers lodin-

13:53 justin_smith: triss: also, you could use something like reduce/reduced where you can separate the laziness of the source from the optional creation of side effects

13:54 triss: thanks justin_smith ... got some serious mulling over to do.

13:54 lodin-: triss: Or use transducers, see http://stuartsierra.com/2015/08/25/clojure-donts-lazy-effects .

13:55 triss: I've got seqs with functions embedded that may or may not use state from the outside world.

13:55 justin_smith: triss: or even doseq of course

13:55 (doseq [el (take 10 source)] (frob el))

13:55 in that case, the chunking of "source" does not matter

13:56 only 10 elements will be frobbed

13:56 mavbozo: ,(take 2 (map println (range 50)))

13:56 clojurebot: (0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n24\n25\n26\n27\n28\n29\n30\n31\nnil nil)

13:56 justin_smith: ,(doseq [el (take 2 (range 50))] (println el))

13:56 clojurebot: 0\n1\n

13:56 justin_smith: see, much better behaved

13:57 triss: aha..... thanks justin_smith

13:57 doseq looks like what I'm after I think....

13:59 noncom: https://pbs.twimg.com/media/CPDVoj8WUAA56UD.jpg think different..

14:00 justin_smith: wow that's annoying

14:00 I hope someone makes adaptors

14:00 noncom: haha :) that pretty much encompasses the overal experience of working with apple thinkgs for me..

14:00 blkcat: lol

14:00 luma: that would be fun if it were true

14:00 blkcat: oh apple, those lovable scamps

14:00 snowell: That seems overly contrarian even for Apple

14:01 luma: all manufacturers use the "apple connector" nowadays

14:01 noncom: heh, just a little fun, yeah :)

14:01 justin_smith: also, it's long established that your ground is the ring that is furthest out

14:01 like, pretty much every ring and tip plug ever does this

14:01 but of course they have to not do that because reasons

14:04 noncom: justin_smith: so, about the state for a single-page app. i am thinking of having one db-like namespace to store all app space and little atoms to store things like "current-catalog-page-number" locally in the relevant namespaces

14:04 its reagen atoms

14:04 how do you think, that's ok?

14:04 justin_smith: noncom: that sounds reasonable. In my own current app we somewhat accidentally ended up with all state in a single atom, and then having a special :page key that gets overwritten for different view states

14:05 but separate atoms per page would be nice for a few reasons...

14:06 noncom: yeah, mainly to have it in small portions and to have it locally.. okay then!

14:07 lodin-: noncom: I've been going back and forth on this. I think the replayability you get if you do it re-frame style could be quite valuable. I have not had the chance to utilize that yet.

14:07 justin_smith: noncom: for example, if we have a request to some endpoint, where the endpoint returns data that is only relevant to a specific page

14:07 if the page data was separate, the user could come back to that view and get data that had trickled in

14:08 as opposed to maybe randomly getting data stuck on your page that was originally meant for a different page

14:09 triss: is there a pred that returns true if value passed to it is a vector or a list but not any other type of value?

14:09 justin_smith: #(or (vector? %) (list? %))

14:09 but checking for lists is pretty much useless

14:09 lazy seqs are not lists

14:09 (for example)

14:10 lodin-: (every-pred vector? list?), if you don't like %. :-)

14:10 oh. no.

14:10 justin_smith: lodin-: wrong logical operator

14:10 noncom: i see...

14:10 lodin-: Yes.

14:10 justin_smith: you want some-pred

14:10 heh

14:10 sdegutis: justin_smith: what router do you use

14:10 for http routing

14:10 justin_smith: sdegutis: I wrote one from scratch in like 50 lines

14:10 sdegutis: niiiice

14:10 lodin-: justin_smith: I read and, but then I was like "can't be both list and vector". Heh.

14:10 justin_smith: sdegutis: oh, http, never mind

14:11 sdegutis: justin_smith: does it have functionality similar to clout?

14:11 justin_smith: by http I meant e.g. compojure

14:11 justin_smith: sdegutis: http I wrote one in more than 50 lines it is called polaris (also other people helped) caribou/polaris

14:11 polaris uses clout (but if it were up to me alone it would not have)

14:11 snowell: ,(doc some-pred)

14:11 clojurebot: Pardon?

14:12 justin_smith: snowell: I don't think that actually exists

14:12 snowell: That's what I was seeing, and I was confused :)

14:12 lodin-: ,(doc some-fn)

14:12 clojurebot: "([p] [p1 p2] [p1 p2 p3] [p1 p2 p3 & ps]); Takes a set of predicates and returns a function f that returns the first logical true value returned by one of its composing predicates against any of its arguments, else it returns logical false. Note that f is short-circuiting in that it will stop execution on the first argument that triggers a logical true result against the original predicates."

14:12 sdegutis: justin_smith: why not?

14:12 re: clout

14:12 justin_smith: sdegutis: I'd rather use a trie based approach rather than multiple regexes

14:13 sdegutis: justin_smith: you mean tree-based?

14:13 justin_smith: it's cleaner / cheaper

14:13 sdegutis: no I mean trie based

14:13 sdegutis: justin_smith: is that the thing bidi and silk do?

14:13 triss: thanks guys!

14:13 justin_smith: sdegutis: you can take a series of routes and from them build a trie that quickly finds an input's destination

14:14 it's as if it is making a single regex out of all your routes, and can call the apropriate handler based on the match

14:14 sdegutis: hmm, I don't know if they use tries...

14:14 sdegutis: justin_smith: sounds like it would have an ugly API

14:14 not as convenience as e.g. compojure

14:14 justin_smith: sdegutis: nah, you hand it a series of strings and functions, it returns a function that finds the first match among those strings given an input, and returns the apropriate function

14:14 sdegutis: justin_smith: I mean for variables inside paths.

14:15 justin_smith: variables only make it slightly harder to implement

14:16 sdegutis: justin_smith: why didn't you use a trie?

14:16 justin_smith: it doesn't look like bidi uses a trie, no

14:16 sdegutis: I didn't design that part of polaris

14:17 silk doesn't either

14:18 DomKM: As far as I know the only trie-based Clojure router is Pedestal.

14:28 agarman_: is there a way to get the enclosing var name from a macro?

14:28 justin_smith: agarman_: as in, a macro knowing its own name?

14:29 agarman_: (defn foo [] (insert-macro-here)) ;; where inserted macros determines it's in #'foo

14:29 justin_smith: absolutely not

14:29 agarman_: yeah, all I could find is line numbers

14:29 which is about 80% useful

14:30 oh and file name

14:30 justin_smith: knowing what surrounds it that breaks a basic clojure assumption about scope and power of expressions (and that assumption brings a lot of sanity with it)

14:30 agarman_: so very round about I could read into the file to get the info, but in an ugly way

14:30 justin_smith: not to say your own plan is totally insane, but in general, it keeps things sane

14:30 agarman_: yeah, that's not my plan

14:31 justin_smith: like, imagine if when I wrote code I had to stop and wonder about special case forms that totally change in behavior based on their caller?

14:32 agarman_: yeah, it'd be pretty basic stuff available to C#

14:32 that's useful for logging with context without the pain of adding boiler plate

14:33 * ane spent five minutes staring at a compiler error: "Unable to resolve symbol: defprocotol in this context"

14:34 justin_smith: uh...

14:34 agarman_: you can get context from the stack trace, you can get the stack trace of the current thread, and walk up until you find a "relevant" namespace

14:35 agarman_: I guess the hard part would be the "is this namespace relevant" code

14:35 agarman_: I'd want the info at compile time.

14:46 ane: can i somehow examine a reified object to see what method it has

14:48 methods*

14:53 justin_smith: ane: you can check what interfaces it claims to implement

14:55 ,(instance? clojure.lang.IDeref (reify clojure.lang.IDeref (deref [this] "hi")))

14:55 clojurebot: true

14:55 justin_smith: ,@(reify clojure.lang.IDeref (deref [this] "hi"))

14:55 clojurebot: "hi"

14:58 gfredericks: ,@@@@@@@@@@@@@@(reify clojure.lang.IDeref (deref [this] this))

14:58 clojurebot: #object[sandbox$eval77$reify__78 0x24980d0 {:status :ready, :val #object[sandbox$eval77$reify__78 0x24980d0 {:status :ready, :val #object[sandbox$eval77$reify__78 0x24980d0 {:status :ready, :val #object[sandbox$eval77$reify__78 0x24980d0 {:status :ready, :val #object[sandbox$eval77$reify__78 0x24980d0 {:status :ready, :val #object[sandbox$eval77$reify__78 0x24980d0 {:status :ready, :val #object[sa...

15:01 sdegutis: justin_smith: I don't understand.. why does polaris use an :identifying-key instead of just a map of a route to a function?

15:03 justin_smith: sdegutis: so that we can do reverse routing, or store routes in a db

15:03 sdegutis: Oooh, reverse routing. That makes sense.

15:03 Storing routes in a DB seems strange...

15:03 justin_smith: routes as pure data opens up a lot of power

15:03 sdegutis: in caribou, you can use the cms to create a page

15:03 when you create a page, you need to also create a new route

15:03 sdegutis: oooh

15:04 Well that's one way of looking it up I guess.

15:04 justin_smith: sdegutis: this means that frontend guys, or even a producer, can throw a new page into the app

15:04 :)

15:04 it is all about RAD

15:04 sdegutis: sure but RAD means something different for us

15:04 we dont need CMS functionality

15:05 reverse-routing however would be nice

15:05 justin_smith: or, more likely, a producer doesn't create a page, but a client demands a different name for some route string (bikeshed!) and the producer can just go in and change it in the cms ui to the db

15:05 and thanks to reverse routing, even our generated links to that URI in other pages are automatically still correct

15:06 and if we were smart enough not to hard code any routes, nothing breaks!

15:15 mungojelly: my thinking keeps getting confused where "everything is data" meets "everything is an infinite lazy sequence"

15:17 opqdonut: but everything is not an infinite lazy sequence

15:17 e.g. [1 2 3], nil or :hotdog

15:17 or (defn factorial [n] (if (= n 0) 0 (* n (factorial (dec n)))

15:18 blake_: I'm having a Java freakout. https://www.refheap.com/109660

15:19 If I have a function a that returns an javaObject, then outside-fn(a) should be the same as outside-fn(javaObject.), right?

15:19 Especially if javaObject returns the SAME object every time?

15:20 i.e., (= a javaObject.)?

15:20 opqdonut: blake_: looks really weird

15:21 blake_: I guess .-text is resolving to a different method in the different calls somehow

15:21 or at least I've had something like that happen in the past

15:21 blake_: It is weird. The problem I'm having is that in code (not in REPL) is ALWAYS giving the formula, and it should not.

15:22 opqdonut: or perhaps .apply is getting resolved differently

15:22 blake_: Well, .apply returns a CellFormatResult which has, like, three methods.

15:22 Maybe apply. CellFromat is more complex.

15:22 opqdonut: there's a .apply(Cell c) and .apply(Object o)

15:22 yes that must be it

15:22 the variable cf isn't hinted

15:22 so it will resolve to the Object version

15:22 the call CellFormat is hinted (because it's java)

15:23 try: (.-text (.apply ^CellFormat cf cell))

15:23 err no

15:23 blake_: opqdonut: That breaks it! I'd say that's progress. =P

15:23 opqdonut: disregard my explanation, it's Cell vs Object not CellFormat vs Object

15:24 try: (.-text (.apply cf ^Cell cell))

15:24 blake_: opqdonut: Aha!! That may have done it!

15:25 opqdonut: yeah now that I think of it this is exactly the case that I had

15:25 some object had both .foo(Something s) and .foo(Object o) methods

15:25 blake_: Bingo!!!

15:25 (inc opqdonut)

15:25 (I think points are even more imaginary than usual these days, but the intention is there.)

15:26 opqdonut: you might want to write a helper function to make sure you get the right .apply

15:26 instead of sprinkling hints left and right :)

15:27 blake_: opqdonut: Yeah, I may. I'm working on cleaning up some example code written in Java, and moving as much as I can into Clojure.

15:27 So, that's good to know. I don't know if I'd have been able to figure that one out.

17:10 justin_smith: ,(map count ((juxt identity set) (remove #{\space \, \!} "sphinx of the black quartz, judge my vow!")))

17:10 clojurebot: (32 26)

17:12 justin_smith: so it re-uses 6 letters, but it uses all of the basic lower case letters

17:14 ,(map count ((juxt identity set) (remove #{\space \, \!} "sphinx f black qurtz, jdge my vow!")))

17:14 clojurebot: (26 26)

17:15 justin_smith: that version is dumb

17:21 phorse: I need to deploy a clojure webapp with apache. Do I have to mess about with Tomcat or can I just proxy to whatever port lein ring server shows up on?

17:21 ed-g: phorse, I prefer to reverse proxy to the lein ring server port

17:21 justin_smith: phorse: don't use lein on production

17:21 phorse: it's a waste of ram

17:21 (among other issues)

17:22 phorse: Okay, so there is a preformance benifet to using tomcat.

17:22 justin_smith: well, you can also use "java -jar my-uber.jar"

17:22 DeepSymmetry: You don’t need to use tomcat, … right, what justin_smith said.

17:22 justin_smith: lein uberjar - simple

17:23 phorse: Great! I've been wrestling with out-of-date tomcat docs all day. Thanks.

17:23 justin_smith: other advantages include being able to go back to a previous deployed version all you need is a single file backed up, faster startup

17:23 sobel: even up-to-date tomcat docs would be unnecessary

17:25 ed-g: I've been trying to use uberjar for deployment but when I attempt to build the jar it says my class file is too large.

17:25 justin_smith: ed-g: the class file for your main ns?

17:25 ed-g: justin_smith, yes

17:26 justin_smith: ed-g: a quick fix for that would be to move functions into another namespace (so they end up in a different compiled class)

17:26 ed-g: also, it's possible to do an uberjar with no aot / no gen-class

17:26 ed-g: justin_smith, ok for some reason I thought aot was required when building an uberjar

17:26 justin_smith: ed-g: the key is that you run it with "java -cp my-uber.jar clojure.main -m my-ns.core"

17:27 ed-g: it just makes it easier to run

17:27 ed-g: justin_smith, thanks for the help! I spent a number of hours on this a few months ago and eventually gave up.

17:27 justin_smith: but with a command line like the above you can run whatever

17:27 ed-g: another awesome trick - on prod you can run "java -cp my-uber.jar clojure.main" and get a clojure repl running on prod

17:27 with all your code available in that repl (as of jar packaging time, of course)

17:28 ed-g: that's cool. I've been running an nREPL server (on a private port) but that's handy because I only really use it every once in a blue moon.

17:29 DeepSymmetry: The advantage of the nREPL server is that it will let you connect to your running VM.

17:29 justin_smith: that's true

17:47 phorse: I've built an uberjar that works fine on my dev machine, but when I try to java -jar myapp.jar on the server, it throws an error about Buddy's bcrypt. I thought that the magic was supposed to work the same everywhere, is there something I'm missing?

17:47 justin_smith: phorse: it generates two files

17:47 you want my-app-standalone.jar

17:48 phorse: Oh, I didn't even notice the other one. I'l ltry that.

17:51 DeepSymmetry: The smaller one is a library jar you can use in conjunction with other library jars (like would be served from Clojars) with Leiningen. The standalone jar embeds all the libraries you used into one massive jar that can be used all by itself.

17:54 phorse: Ok. Actually, it looks like I was using the larger file, it just wasn't labelled 'standalone'.

17:54 When I run java -jar myapp.jar (the big one), it boots up on localhost:3000 and works just fine.

17:54 Transfer it over to the server and the same thing generates a stacktrace.

17:54 justin_smith: phorse: can you share the stack trace?

17:55 phorse: Sure:

17:55 justin_smith: for example on http://refheap.com

17:55 don't paste it here

17:55 phorse: Exception in thread "main" java.lang.UnsupportedClassVersionError: buddy/impl/bcrypt/BCrypt : Unsupported major.min or version 51.0

17:55 at java.lang.ClassLoader.defineClass1(Native Method)

17:55 at java.lang.ClassLoader.defineClass(ClassLoader.java:643)

17:55 at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)

17:55 at java.net.URLClassLoader.defineClass(URLClassLoader.java:277)

17:55 at java.net.URLClassLoader.access$000(URLClassLoader.java:73)

17:55 at java.net.URLClassLoader$1.run(URLClassLoader.java:212)

17:55 at java.security.AccessController.doPrivileged(Native Method)

17:55 at java.net.URLClassLoader.findClass(URLClassLoader.java:205)

17:55 at java.lang.ClassLoader.loadClass(ClassLoader.java:323)

17:55 justin_smith: phorse: it's a problem with your jdk version

17:55 phorse: at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)

17:55 at java.lang.ClassLoader.loadClass(ClassLoader.java:268)

17:55 justin_smith: and don't paste things like that here

17:55 phorse: at java.lang.Class.forName0(Native Method)

17:55 at java.lang.Class.forName(Class.java:274)

17:55 ane: eurgh

17:56 phorse: at clojure.lang.RT.classForName(RT.java:2154)

17:56 at clojure.lang.RT.classForNameNonLoading(RT.java:2167)

17:56 at buddy.hashers$loading__5340__auto____23.invoke(hashers.clj:15)

17:56 at buddy.hashers__init.load(Unknown Source)

17:56 at buddy.hashers__init.<clinit>(Unknown Source)

17:56 at java.lang.Class.forName0(Native Method)

17:56 at java.lang.Class.forName(Class.java:274)

17:56 at clojure.lang.RT.classForName(RT.java:2154)

17:56 at clojure.lang.RT.classForName(RT.java:2163)

17:56 at clojure.lang.RT.loadClassForName(RT.java:2182)

17:56 at clojure.lang.RT.load(RT.java:436)

17:56 at clojure.lang.RT.load(RT.java:412)

17:56 justin_smith: ane: I really hate emacs "paste protection" which simply slows down your paste to prevent booting, instead of making you not paste

17:56 phorse: at clojure.core$load$fn__5448.invoke(core.clj:5866)

17:56 at clojure.core$load.doInvoke(core.clj:5865)

17:56 at clojure.lang.RestFn.invoke(RestFn.java:408)

17:56 ane: justin_smith: i think that's just standard irc server behaviour

17:57 justin_smith: ane: no, the server kicks you for pasting too fast

17:57 ane: it may be his client then, don't know if he's using erc

17:57 amalloy: ane: he's talking about clients that circumvent the (useful) server behavior

17:57 justin_smith: ane: dysfunctional clients slow down your paste so you don't get kicked

17:57 amalloy: usually it's ERC

17:57 ane: irssi does this too

17:58 justin_smith: OK, I hate how irssi does it too (but erc also makes it easy to accidentally paste a huge block)

17:58 ane: irssi does have paste protection though, which is great

17:58 defaults to five lines after which it'll ask "are you sure?"

18:11 noncom|2: i have bootstrap and jquery in my project deps so they are included in my webapp. now i want to have this: https://github.com/CWSpear/bootstrap-hover-dropdown

18:11 in their installation section they say that their lib is to be included AFTER bootstrap and jquery

18:11 how do I ensure that?

18:12 on my single html page there is no mention of either bootstrap or jquery

19:16 noffle: is there a way of killing a running clojure program (that you started from the repl via (-main)) that doesn't result in the repl also dying?

19:16 justin_smith: noffle: Control-C in an nrepl at least

19:18 blake_: OK, working over a table in rows and columns (nested doseqs) and want to know what column and row I'm on.

19:19 justin_smith: blake_: you probably don't need nested doseq

19:19 blake_: justin_smith: Probably not. I'm working over someone else's code. It =is= side effect driven, at least until I rewrite it.

19:20 But I got a collection of rows, and I use the individual rows to get the columns.

19:20 My intern put a counter in there, which of course didn't work. ;)

19:21 noffle: justin_smith: thanks. I think the library I'm using is starting a subprocess that opens a window, and I don't see a way to kill that window without crashing nrepl. But this smells like a lib-specific Q rather than a purely nrepl thing.

19:21 justin_smith: ,(doseq [[i row] (map list (range) [[:a :b :c] [:d :e :f]]) [j e] (map list (range) row)] (print i j e \; \space)) ; blake

19:21 clojurebot: 0 0 :a ; 0 1 :b ; 0 2 :c ; 1 0 :d ; 1 1 :e ; 1 2 :f ;

19:21 justin_smith: blake_: see above, I get each item, with a row number and a column number

19:22 with one doseq, no nesting

19:22 blake_: justin_smith: Thanks...I think. =P

19:23 justin_smith: blake_: if it's confusing, feel free to ask more questions, but that's not an unusual usage of doseq, it's supposed to go down into nested indexes like that

19:24 blake_: justin_smith: I'm just under the gun. I'll do it right. Or righter...

19:25 justin_smith: blake_: anyway, (map list (range) c) or (map-indexed list c) are standard ways to get indexes for each item

19:25 ,(map list (range) [:a :b :c])

19:25 clojurebot: ((0 :a) (1 :b) (2 :c))

19:26 blake_: justin_smith: Thanks. I forget about map-indexed.

19:26 justin_smith: ,(map-indexed list [:a :b :c])

19:26 clojurebot: ((0 :a) (1 :b) (2 :c))

19:26 blake_: (fake-inc justin_smith)

19:26 justin_smith: I tend to just use the map list version, it's exactly the same number of characters :P

19:27 blake_: ,(count "map-indexed")

19:27 clojurebot: 11

19:27 blake_: ,(count "map list")

19:27 clojurebot: 8

19:27 justin_smith: remember it also has (range) in there

19:27 and you call list in both cases

19:28 ,(map count ["(map-indexed list c)" "(map list (range) c)"])

19:28 clojurebot: (20 20)

19:28 blake_: Ahhh. =P

19:29 So...in Clojure JVM interop .- = . ?

19:30 justin_smith: blake_: .- is for field access

19:30 . is either field or method

19:30 blake_: with the jvm it is guaranteed unambiguous but you still might like .- for style reasons, with js it is not guaranteed unambiguous

19:30 blake_: I was trying to figure out if this was because there could be no class in Java.

19:31 Er, clash, not class.

19:31 Java's got all kinds of class.

19:31 justin_smith: heh

19:31 blake_: justin_smith: Right.

19:31 justin_smith: classy as fuck

19:31 blake_: Yuge Classes. Gold leafed. Leather bound.

19:32 justin_smith: with an emphasis on hereditary inheretance to make sure that the class division stays in the future

19:32 unlike those commie non-oo langs

19:34 blake_: ha

19:38 Ah, I think I got it. Thanks.

19:42 justin_smith: Crap, what if I need to do something between the row and the column? Like print out a <tr>?

19:42 justin_smith: blake_: aha, then you might want a nested doseq... - or just test for the first index going down

19:43 wait second index

19:43 test if second index is 0

19:43 blake_: I guess I could wrap the...oh, yeah, that'd work. Sorta old school. Right.

19:43 justin_smith: then bob's your uncle

19:51 then bob's your uncle

19:56 blake_: justin_smith: Do we have a way of knowing we're at the end of one of the internal loops in a doseq?

19:57 I mean, I can call the same thing I called in the doseq and count it, but I was wondering if there was a better way. Nested doseqs might not have been bad here. =P

19:59 justin_smith: blake_: if you also need that, yeah, that might make it easier

20:00 blake_: Eh, good enough for now. This is "prove it can work" time.

20:03 tolstoy: I use loop/recur when I have to do that kind of thing and can't think of a different design.

23:00 tmtwd: is there source code for a macro that does the same thing as "if"?

23:09 jeremylite: tmtwd: it would have to be implemented in terms of cond

23:20 neoncontrails: When implementing message passing, is it more idiomatic to pass the message as a keyword, quote literal, or string?

Logging service provided by n01se.net