#clojure log - Oct 08 2015

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

0:50 nXqd: !help

0:50 ,(def a "something")

0:50 clojurebot: #'sandbox/a

0:51 nXqd: a bit offtopic, how is this clojurebot created ? it's pretty neat

0:51 justin_smith: nXqd: it's a repl with a whitelist and sandbox, the source is easy to find on github

0:52 nXqd: made by hiredman

4:27 sm0ke: is there something like doseq which returns list instead of side effect?

4:28 wmealing: dorun ?

4:28 schmir: sm0ke: doall

4:28 sm0ke: ,(for [x (range 10)] (inc x))

4:28 wmealing: isnt what is returned.. what you want ?

4:28 clojurebot: (1 2 3 4 5 ...)

4:28 sm0ke: i guess i can use `for`

4:29 i always seem to forget about `for` in clojure

4:30 its such an underrated expression in clojure tbh

4:33 patrkris: /part/part

4:33 borkdude: sm0ke for, or map

4:34 sm0ke but for is more similar to doseq, with a fancy binding and :let, :when

4:34 sm0ke possibly multiple bindings yielding a cartesian product

4:37 sm0ke: yes multiple bindings is also unique about `for` compared to a map

4:38 a single map in short can be an equivalent of chains of map filter

4:38 muhuk: suppose (unique? [1 2 3]) => true & (unique? [:x :x]) => false, what should (unique? nil) or (unique? []) do?

4:38 borkdude: I never realized that doseq also supports multiple bindings until now

4:39 sm0ke: ,(doseq [x [1 2] y 3] (prn (str x "," y)))

4:39 clojurebot: #error {\n :cause "Don't know how to create ISeq from: java.lang.Long"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Don't know how to create ISeq from: java.lang.Long"\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 [clojure.co...

4:39 sm0ke: ,(doseq [x [1 2] y [3]] (prn (str x "," y)))

4:39 borkdude: sm0ke 3 should be [3] there

4:39 clojurebot: "1,3"\n"2,3"\n

4:39 sm0ke: nice i didnt knew this either

4:40 does it also supports :when ?

4:40 heh

4:40 borkdude: hmm

4:40 sm0ke: oh it does

4:40 "with bindings and filtering as provided by "for""

4:41 borkdude: yes, it does!

4:41 wow

4:41 sm0ke: ,(doseq [x [1 2] y [1 3]] (prn (str x "," y)) :when (= x y))

4:41 clojurebot: "1,1"\n"1,3"\n"2,1"\n"2,3"\n

4:42 sm0ke: huh

5:18 TEttinger: ,(doseq [x [1 2] y [1 3] :when (= x y)] (prn (str x "," y)))

5:18 clojurebot: "1,1"\n

5:18 TEttinger: sm0ke: ^

5:19 sm0ke: heh thanks TEttinger

5:19 TEttinger: no prob, those :when and :while etc. are handy

7:51 bordeltabernacle: Hi! I'm new to Clojure (and IRC!) and just thought I'd introduce myself and "join in the conversation" y'know.

7:53 dstockton: hey bordeltabernacle

7:53 welcome

7:53 bordeltabernacle: Hi dstockton, thanks.

7:53 feel kinda high school goofy!

7:55 dstockton: things seem quiet today

7:56 snowell: Welcome, bordeltabernacle!

7:57 bordeltabernacle: Thanks, snowell!

8:07 noncom: what's the most idiomatic way to update all values in a {} by a function? (except for reduce, if possible)

8:07 or is reduce the most idiomatic one?

8:08 dstockton: i'd say its fine noncom, or you can (into {} (for [kv] ...

8:08 there is also https://clojure.github.io/algo.generic/clojure.algo.generic.functor-api.html#clojure.algo.generic.functor/fmap

8:08 user=> (fmap inc {:a 1 :b 3 :c 5})

8:08 {:a 2, :b 4, :c 6}

8:09 noncom: oh wow

8:09 dstockton: this uses the into (empty m) version

8:09 noncom: right

8:09 interesting!

8:09 dstockton: https://github.com/clojure/algo.generic/blob/aa028f7467d193a5cfad0626b324f4c682b91c15/src/main/clojure/clojure/algo/generic/functor.clj#L29

8:10 there was a whole load of discussion here yesterday about it

8:11 noncom: gotta read that from the archive

8:11 dstockton: is it going to be in the core sometimes?

8:12 dstockton: don't know, actually i didn't catch all of the discussion yesterday either

8:13 noncom: well, good that the bots are taking care of logs

8:16 dstockton: most of it was about type systems and haskell

8:21 noncom: dstockton: yes, i already found it! just yesterday me and a friend of mine were talking about the same thing, also mentioning haskell, but we did not see it here. what a synchronicity!

8:36 taharqa: Hi there !

8:36 I'm new to Clojure as well, what can I say to someone that told me "Clojure is not a Lisp" ?

8:39 MasseR: taharqa: what was his reasoning?

8:42 taharqa: MasseR: « a lisp should be a langage built on top of functions that are primitives (atom, quote, eq, car, cdr, cons, cond, lambda, apply, etc ) and should rely entirely on this primitives »

8:44 opqdonut: well clojure is built on top of the primitives

8:44 listed on http://clojure.org/special_forms

8:45 and what does it matter what some guy thinks

8:45 clojure certainly isn't a very traditional lisp

8:45 maybe you can settle on calling it lisp-like :)

8:45 MasseR: Besides, that's the first I've heard of that kind of condition for being a lisp

8:46 taharqa: opqdonut: the guy in my opinion mix the language and the platform

8:47 opqdonut: the fact that Clojure share with java may seems to them that those are not primitives

8:47 opqdonut: MasseR: it's quite widely repeated, see e.g. http://steve-yegge.blogspot.fi/2006/04/lisp-is-not-acceptable-lisp.html

8:48 taharqa: MasseR: yes strange, he points me to http://axisofeval.blogspot.fr/2010/04/why-i-ignore-clojure.html

8:48 opqdonut: or http://stackoverflow.com/questions/3482389/how-many-primitives-does-it-take-to-build-a-lisp-machine-ten-seven-or-five

8:48 taharqa: opqdonut: excellent ^^

8:49 opqdonut: even axisofeval ends with

8:49 > Now, go ahead and have fun using Clojure if it floats your boat, but stop whining about how it's a more modern or better Lisp. That doesn't make the slightest bit of sense.

8:51 noncom: taharqa: clojure is a lisp because it is a list processing language and it is homoiconic. it is not the grahams lisp, however, and it is not scheme and it is not common lisp. it is clojure...

8:52 taharqa: it has some jvm interop which may frighten pure lisp people, but this is the reality of jvm and actually a bliss

10:51 gfredericks: apparently the 4clojure test suite has been broken (uncompileable) for over two years

10:53 it's made it through six or so commits without anybody noticeing

11:07 sobel: is there a prettier way to say this: (merge-with (fn [_ s] s) default-config file-config)

11:07 specifically the (fn [_ s] s)

11:10 michaniskin: (comp peek vector)

11:11 luma: sobel, isn't that just using the value from the second map, so the same as (merge default-config file-config)

11:12 tdavis: is there any way to expand to a symbol's full namespace a-la syntax quote when inside a quoted list? as in, '(reify SomeClass (foo [bar baz] ...)) i need 'SomeClass' to be 'com.ns.SomeClass' because it's being used in a macro expansion.

11:15 sobel: luma: thx

11:35 justin_smith: tdavis: syntax-quote does namespace expansion, not class-name, I think...

11:35 ,`String

11:36 clojurebot: java.lang.String

11:36 justin_smith: oh, never mind :)

11:40 ,'String

11:40 clojurebot: String

11:51 tdavis: has anybody ever gotten "NullPointerException clojure.lang.Reflector.invokeNoArgInstanceMember" just trying to call macroexpand on something?

11:52 justin_smith: tdavis: no, but if a macro is buggy, it can npe while expanding

11:52 tdavis: is there any way to debug it?

11:53 i wrote a macro, it works fine, but calling it in a loop from a function is NPE'ing despite the fact that i've confirmed none of the arguments are nil.

11:53 and for whatever reason i can't even expand the call to see what could be wrong

11:54 justin_smith: maybe try expanding the surrounding loop form?

11:54 tdavis: i pulled it out of the loop entirely, same result.

11:57 progress, maybe! ClassCastException clojure.lang.PersistentList cannot be cast to clojure.lang.Symbol clojure.core/ns-resolve (core.clj:4216)

11:57 justin_smith: sobel: michaniskin: I benchmarked a few variants, #(do %2) was the fastest shorthand, (comp second list) was slowest, (comp peek vector) did OK https://www.refheap.com/110425

11:59 yeah, that sounds like a macro that is either broken, or being used improperly

12:00 sorry, beyond expanding things I don't have any good macro writing / macro debugging tips

12:00 I'm not so great at macros myself, maybe someone else can help

12:01 tdavis: justin_smith: yeah... once i eliminated all the other macros involved (i forgot, e.g., `let') i'm getting more of a stack trace. might be something to do with (to-array) usage... Constructor.newInstance() usage is convoluted from clojure.

12:11 interesting! i am passing a macro a argument of type java.lang.Class but inside the macro the type is clojure.lang.PersistentList

12:15 justin_smith: ,(type ''foo)

12:15 clojurebot: clojure.lang.PersistentList

12:15 justin_smith: could it be an extraneous quoting / not enough evaluation issue?

12:16 tdavis: the macro isn't receiving the value just the raw list which i guess makes sense since it's being expanded prior to the calling function being evaluated

12:20 justin_smith: well, the idea with macros is you want them to get the raw form, and need to explicitly do any level of evaluation needed to get the compile time value they need

12:32 clgv: Hello, is there an option to set the timeout for an aleph tcp client connection attempt?

12:41 ok :bootstrap-transform and setting CONNECT_TIMEOUT_MILLIS is the solution

14:39 boxed: is there a way to make a macro expand into two forms? in my case I want to output both a defn and another macro from a macro

14:43 justin_smith: boxed: `(do ...)

14:44 boxed: ah crap, that was obvious in hind sight, thanks :P

14:44 but I guess this only works for outputting two things that are side effect-y right?

14:45 (for my case fine, but I’m thinking about the general case)

14:45 snowell: For multiple return values you can just return a vector

14:45 justin_smith: boxed: otherise, output a collection containing both results

14:46 right

14:46 boxed: well, that doesn’t work in reagent when I want to output say two [:td]s at some point

14:46 justin_smith: boxed: in that case I use into

14:47 snowell: You'd return a [:div] with the two [:td]s in it :)

14:47 justin_smith: (into [:div] (thing-returning-tow-tds))

14:47 boxed: snowell: you can’t have a a div randomly inside a tr

14:47 snowell: Er…what he said

14:47 Not with that attitude

14:47 justin_smith: haha

14:47 boxed: hah, yea, “works” is a bad attitude

14:48 seriously though, I’ll take this as “nope"

14:48 snowell: I'd take what justin_smith said

14:48 justin_smith: boxed: I have had good luck using into (or occasionally just conj) to combine stuff in reagent

14:48 though my literal suggestion above is not correct for that case

14:49 snowell: ,(into [:div] [[:td :first] [:td :second]])

14:49 clojurebot: [:div [:td :first] [:td :second]]

14:49 boxed: justin: problem with that is that the code ends up really ugly because the internal behavior of the component leaks out.. in that you have to (into) it

14:50 snowell: that produces an invalid DOM

14:50 justin_smith: boxed: that's true, and I wish there were a better solution, maybe using om :P

14:51 boxed: justin_smith: yep, at least I’m doing the right thing currently :P pity, I would want clojure macros to be just a tiiiny bit more powerful :P

14:51 justin_smith: boxed: essentially for your case you would need the ability to modify the containing form, and that is just --- eww

14:52 skeuomorf: How do people do DTLS in Clojure land?

14:53 Please don't tell me bouncy castle :(

14:53 boxed: justin_smith: nah, just the ability for a macro to output several forms. Like C macros can :P

14:55 justin_smith: boxed: that's a modification of the parent form

14:55 c macros don't even have a concept of "form", and can clearly modify parent forms at will

14:55 reified concept of form that is, of course

14:56 boxed: justin_smith: I don’t see what you’re saying. Changing the contents of the parent form is all that macros do. A macro that can’t modify the parent form isn’t a macro, it’s just a literal

14:57 justin_smith: no, there is a difference between your form (args to a macro) and the parent form (the thing containing the macro), one aspect of the parent form, which you would be altering, is the argument count

14:58 boxed: justin_smith: another aspect is the contents.. I really don’t see the big difference

14:58 justin_smith: it's all the difference

14:58 boxed: yea, in my case between nice code and eeeeww :P

14:59 between useful and not so much

14:59 justin_smith: boxed: it would mean a much messier compiler

15:00 boxed: justin_smith: don’t buy that. Instead of “append x” you could do “append x, append y”

15:00 “much messier” seems like an exaggeration

15:02 justin_smith: boxed: I would not be surprised if it doubled the line count - because it makes a bunch of shitty things possible that are not possible in the current design.

15:02 boxed: “shitty”? didn’t you just above say it would be much nicer?

15:03 simplicity of the compiler should not be confused by simplicity of the user code

15:05 I guess the big problem is that reagent templating is done in clojure native forms, which just can’t express things cleanly for these cases

15:06 oh yea, and another problem is that HTML is shite of course, but that almost goes withouth saying :P

15:29 daniel__1: if i write code for someone with no contact and hand it over, do i have any rights over said code?

15:30 contract*

15:31 hiredman: http://copyright.gov/help/faq/faq-general.html#mywork

15:38 daniel__1: thanks hiredman

15:48 Cr8: in future though, don't do that -- copyright isn't magic, they can't redistribute or make derivative works of the code, but you also can't force them to delete it/not run it

15:49 boxed: is there some tool that makes developing macros somewhat non-horrible?

16:00 TMA: daniel__1: even in the common law you do have a contract; however as it is not a written one it is hard to tell what are its terms

16:03 daniel__1: im actually not concerned with giving up rights to what i produce, im concerned with contracts i dont fully understand taking rights from things i havent yet but might produce

16:03 i think im talking about simple transfer of copyright

16:10 sobel: actually unless you give them permission to run your code, you can assert copy rights to make them stop using it

16:10 it's tricky to prove your copyright if you don't register it properly but that's how the law reads

16:10 Frozenlo`: sobel: Don't they get the copyright if they hired you to write the code?

16:11 sobel: it depends on how the employment is arranged

16:11 daniel__1: and how complicated does this contract have to be

16:11 sobel: if the person is hired to do some work, the work product (code) belongs to the employer

16:12 e.g. code written as a coder on the clock or on salary

16:12 it's different if someone contracts a solution you might dig out of your toolbox of existing solutions, which may be your copyrighted material

16:12 daniel__1: i actually meant to start this discussion in another channel, heh

16:12 just realised it was clojure

16:13 and getting helpful responses anyway

16:13 sobel: relevant here though

16:13 daniel__1: basically, i got given a contract which scares me a bit because its long and i dont understand it

16:14 sobel: use a real atty if it matters

16:14 and beware of giant contracts

16:14 daniel__1: yeah, im not sure it does matter that much

16:14 TMA: for example, there is a special work-for-hire provision in our copyright law that takes precedence over any terms agreed between the parties; however if you are a corporation instead of a naural person, these need not apply

16:15 daniel__1: anyone ever worked for two competing business simultaneously?

16:15 and how do you handle that

16:16 sobel: usually the employer has wanted my exclusive service

16:16 TMA: daniel__1: tricky. you might need the first employer's permission to work for the second

16:17 daniel__1: yep, i've been open with both

16:17 skoude: I make a get request to a web service that returns json document, and I use clj-http.client get function for that.. The problem is that how can I read it to vector in clojure? I I try to use parse-string function in chesire, I get error: PersistenMap cannot be cast to java.lang.String..

16:17 daniel__1: but its still tricky, i don't want to get into conflicts with any contractual obligations

16:17 hiredman: software engineers are basically the worst people to ask about law and ip

16:17 daniel__1: heh hiredman, im sure thats true

16:18 ane: will and evaluate all its forms or stop at the first falsey?

16:18 daniel__1: but maybe it is a case of over-thinking

16:18 TMA: daniel__1: there is a reason for the lawyers being paid handsomely :)

16:18 ane: e.g. (and false (expensive-computation)) will it short-circuit

16:18 justin_smith: skoude: likely clj-http.client is giving you a hash map describing the entire result of the request (including headers), and the :body key will have the actual contents that you can parse or whatever

16:18 snowell: ane: It will stop at the first falsey

16:18 ,(doc and)

16:18 daniel__1: TMA: i know, law is incredibly boring

16:18 clojurebot: "([] [x] [x & next]); Evaluates exprs one at a time, from left to right. If a form returns logical false (nil or false), and returns that value and doesn't evaluate any of the other expressions, otherwise it returns the value of the last expr. (and) returns true."

16:18 daniel__1: i don't envy anyone who has to learn it all

16:19 TMA: ane: it will stop

16:19 skoude: justin_smith: thanks.. I will check that..

16:19 justin_smith: ,(and false (prinln "expensive$$$$")

16:19 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

16:19 justin_smith: ,(and false (prinln "expensive$$$$"))

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

16:19 irctc: Hiya. I'd like to be able to execute a function multiple times in parallel and return the results in a list. Like this: (pmap (fn [_] (myfunc)) (range 10)). Is there a standard function that can do this without the use of range and an underscore parameter?

16:19 justin_smith: ergh

16:19 ane: snowell: ok thanks

16:20 justin_smith: irctc: dotimes

16:20 well, you would need to create the futures in the dotimes body, so never mind, there isn't a fully pre-baked solution

16:21 ~pmap

16:21 clojurebot: pmap is not what you want

16:21 justin_smith: (also)

16:21 ane: is there any way of making this a bit simpler (if (and (= @data []) (realized? my-future)) @data @data) i.e. i want it to return @data immediately otherwise wait for my-future to finish (which modifies data)

16:21 (if data is [])

16:21 irctc: pmap seemed to have worked but not sure if there is something more straightforward.

16:21 justin_smith: ane: (do @my-future @data)

16:21 that returns @data, but only after my-future is done

16:23 irctc: Does dotimes run in parallel?

16:23 justin_smith: no, that's why I decided it wasn't a replacement

16:25 irctc: So I guess the easiest way is the way I already have it then. Can I simplify (fn [_] (myfunc)) ? I tried (constantly #(myfunc)) but it only calls myfunc once and repeats the result.

16:25 hiredman: ane: that is all a big race condition

16:26 also (if x y y) is y

16:26 ane: yes, i just want to execute the future if (= @data []) is t

16:27 otherwise use the currently committed value

16:27 justin_smith: more like (do x y) - x has a side effect here

16:27 hiredman: futures are executed when they are created

16:27 hlolli: Im using lein droid for the first time, and I connect to my android device repl trough port 9999, but changing something in emacs and evaluating does not change my running app on my device. Is this expected behaviour, do you need to do lein droid doall to see every change?

16:27 ane: hiredman: yeah, i've defined it earlier, but i want the function to block until it's finished if it's empty

16:28 hiredman: ane: futures have a great built in way to do that called deref

16:28 justin_smith: so, like I said above, (do @my-future @data)

16:29 ane: would that block even if @data has something in it?

16:30 justin_smith: (or (not-empty @data) (do @my-future @data))

16:30 hiredman: ane: so other things are writing to data?

16:30 ane: no, just the future

16:30 justin_smith: but yeah, still messy

16:30 hiredman: so why would it have something in it unless the future has a value to produce?

16:31 justin_smith: wait, are you sure you couldn't just deref the future and get its result and skip the atom?

16:31 hiredman: you almost certainly want one of the j.u.c queues and not an atom

16:33 ane: well i'm periodically fetching some data and storing it inside a ref. but i want the actual fetching only to happen every n calls to the function

16:35 sigh. i've designed this all ass-backwards

16:35 hiredman: you want to queue up calls

16:38 ane: what would be the best method for doing that? agents?

16:39 hiredman: http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/SynchronousQueue.html or core.async channels

16:40 ane: what about just using add-watch on the counter ref? when it's at every N steps run something in the background

16:41 justin_smith: ane: when did you switch from atom to ref?

16:41 or are you using one of these terms "generically" - because they are two different htings

16:41 hiredman: create a queue, spin up a thread/future/process of some kind that consumes N messages from the queue and then executes the bulk request, and then each message in the queue has another queue or promise that the response can be multiplexed to

16:41 ane: no

16:42 core.async may even have some machinery that would do this already

16:43 ane: justin_smith: oh i don't think i mentioned atoms, but maybe

16:44 justin_smith: ane: sorry, poor reading comprehension on my part

16:44 you didn't mention atoms

16:46 ane: hiredman: sounds a bit more complicated, but infinitely smarter

16:47 hiredman: no way

16:47 * akkad looks for someone with a clue about c3p0

16:47 hiredman: the STM is way more complicated and you are way more likely to screw up using it

16:47 ane: hiredman: i just can't figure out what the queue contents actually are at this point

16:47 hiredman: I do not recommend using refs

16:48 Jabberz: do folks use visualVM for clojure app memory profiling, or something else?

16:48 hiredman: ane: the queue contents are the arguments to the function you are batching up (and if you care about getting results back a promise for the results)

16:49 then you have a thread that loops around consuming from the queue and once it has consumed N items, it takes those items and executes a batch, then takes the results from executing that batch and debatches them out to the promises (if you need the results)

16:50 ane: ah, now i see. well i have no arguments to pass to the function, and i just need the result to be stored elsewhere, not to be returned, like a database or an in-memory ref

16:51 hiredman: Jabberz: I've used visualvm, there are nicer profiles for the jvm with all kinds of features but you'll have to shell out money for licenses

16:53 ane: in that case you might actually consider an agent or an executor

16:54 if your value can be the value in an agent, you can store a "last-updated" in the value and if a refresh request is sent, ignore it if last-updated is less than whatever time frame

16:55 but in that case you really might just want to consider unconditionally refreshing every time period, and never have explicit refresh requests

16:56 you have an atom containing some value, and a scheduled executor refreshes the value of the atom every time period and clients just deref the atom

16:56 ane: yeah, that's actually what i was going to implement, using a java timer or some such

16:57 thought it'd be simpler to initially prototype using just a global variable and simple cache

16:59 hiredman: a looping future and an atom are very straight forward

17:00 but in your initial discussion you mentioned waiting for the future to be realized, which you wouldn't do

17:00 ane: indeed

17:25 hlolli: Still having problem with lein droid and cider. No matter how I change the profiles.clj I always get this error ONLY with droid: WARNING: The following required nREPL ops are not supported:

17:25 classpath format-code format-edn refresh

17:25 Please, install (or update) cider-nrepl 0.9.1 and restart CIDER

17:42 WorldsEndless: How do I use :rename in my ns declaration? e.g:

17:42

17:42 (ns mine.styles

17:42 (:require [garden.color :as c :refer [{:rename '{hex->rgb hr}}]])) ;; doesn't work

17:42 I've tried several variation on it

17:42 justin_smith: don't use ' inside the ns form

17:42 and I don't think :rename should go inside :refer...

17:43 WorldsEndless: I can't seem to find any examples, other than the main docs that say :rename can go SOMEWHERE...

17:45 justin_smith: ,(require '[clojure.string :as s :refer [split] :rename {split schmoop})

17:45 clojurebot: #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: )>

17:45 justin_smith: ,(require '[clojure.string :as s :refer [split] :rename {split schmoop}])

17:45 clojurebot: nil

17:45 justin_smith: ,(schoop "hello world" #" ")

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

17:45 justin_smith: ,(schmoop "hello world" #" ")

17:45 clojurebot: ["hello" "world"]

17:45 WorldsEndless: Say, that clojurebot is pretty cool!

17:45 justin_smith: WorldsEndless: ^ see above, but without the leading ' before the vector in the ns form

17:46 WorldsEndless: yes, it's a nice feature

17:47 that's a slightly unintuitive mix when you have refer and rename together, to be sure

17:48 WorldsEndless: So, It compiles but doesn't work for me

17:48 (ns turbo-tenure.styles

17:48 (:require [garden.color :rename {hex->rgb hr}]))

17:48 justin_smith: well, you aren't using refer there

17:48 WorldsEndless: Yeah, took it out for clarity

17:48 justin_smith: OK

17:48 so hex->rgb works, but hr does not?

17:48 WorldsEndless: I'm just trying to rename the ugly function, but hr does not work

17:49 "unable to resolve symbol"

17:49 I guess if I have to I can use "require" outside of the ns declaration, but I was hoping I wouldn't need to do that

17:49 justin_smith: WorldsEndless: note that it should be :refer [hex->rgb] :rename {:hex->rgb hr}

17:49 :require runs the same code, so you don't need to do that

17:50 WorldsEndless: Ah! Beautiful

17:50 Getting the right combo of refer and rename was what I was missing

17:50 justin_smith: WorldsEndless: that's what I meant about it being unintuitive

17:50 you ask to refer to the un-renamed version, and you get the renamed

17:50 WorldsEndless: Thanks, justin_smith (thought you were referring to my code with that)

17:51 sdegutis: What's the best way to handle text fields in Reagent?

17:53 WorldsEndless: sdegutis: what are you trying to do?

17:53 sdegutis: Just create normal forms that can be submitted via AJAX.

17:55 WorldsEndless: I'm pretty new to reagent myself, but I would think you'd just handle them in the normal DOM way (i.e. give them an id, refer to them)

17:55 ^ sdegutis

17:56 justin_smith: sdegutis: in reagent, I tie the state of the form elements to some part of an ratom, and read the ratom on submit to build the ajax request

17:56 sdegutis: I was under the impression that any text you type into it gets squashed as soon as you type if you try to store it in an atom or anything?

17:56 justin_smith: squashed?

17:57 sdegutis: Like, the field is tied to ratom, ratom is empty, field is empty, you click the field, type "f", and since the change isn't propagated back to the ratom, it asks the ratom what to display, which is nothing, and the field says ""

17:57 justin_smith: sdegutis: more specifically, an on-change that modifies the ratom

17:57 sdegutis: Mainly because during onchange event (or whatever), it --- ooh, so you specifically change the ratom during onchange.

17:57 justin_smith: sdegutis: I'm not talking about the ratom that renders the component

17:58 sdegutis: Okay that makes sense. But then how do you handle the cursor always going to the end of the field?

17:58 justin_smith: something is making redraws happen because you are watching data for rendering that you modify while typing

17:58 don't do that, and that behavior stops

17:59 or at least, watch it in a different component, not the same one accepting the input

17:59 sdegutis: So another component should be responsible for input validation than the input itself?

17:59 Ah maybe a higher level component, I guess, one that sees both the input and the error field which it should show upon error...

17:59 justin_smith: sdegutis: insanely simplified version of the problem: you tell joe to follow bob, you tell bob to follow joe, nobody does anything interesting and they walk in circles

17:59 so don't do that

18:00 sdegutis: right

18:00 Thanks, I think I understand enough to solve this now.

18:46 skeuomorf: Is there a way to write multiline docstrings for functions inside a protocol? e.g. (defprotocol MyProtocol "A protocol which represents an entity." (my-function [this] "multiline docstring here!!"))

18:48 argh, had an unescaped `\` in the docstring

18:48 which is weird, that I have to escape characters inside the docstring

18:52 justin_smith: skeuomorf: \ inside strings needs escaping, because \c for most characters c is not valid

18:53 skeuomorf: ah

18:54 justin_smith: being the escape string itself, it needs escaping (mind you this is all invalid inside the crazy world of regex)

18:54 ,#"\a"

18:54 clojurebot: #"\a"

18:55 skeuomorf: Yeah, ofc

18:56 justin_smith: ,"\a"

18:56 clojurebot: #<RuntimeException java.lang.RuntimeException: Unsupported escape character: \a>

20:24 skeuomorf: let's say I have a record R which has two "properties", x and y, x is an atom holding a map and y is an int. Let's say we have two instance (def r1 (->R (atom {}) 2)) and (def r2 (->R (atom {:my-key r1}) 3)). Now, what I want to do is change the value of y which is inside r1 which is inside x which is inside r2, what would be the cleanest way to do that?

20:27 for the sake argument, assuming "properties" inside records weren't private, what I would want to change is (y (:my-key @(x r2))

20:28 s/sake/sake\ of/

20:28 wmealing: well, i've started using specter for that kind of manipulation.

20:28 i'm by no means cool though

20:28 so i'm probablly doing things all kinds of wrong

20:29 * skeuomorf looks at spectre

20:29 skeuomorf: I'd prefer to use it without external libs though, I could define that y field as mutable but that seems dirty

20:32 wmealing: A quick glimpse, I think spectre doesn't work with records? If I were using a regular map, I would've just made a new version with the new value out of the old one, but records' members are private

21:01 Screw it, did it with getter/setter :)

21:07 wmealing: skeuomorf: sorry man had to bail , i had a meeting

21:10 skeuomorf: wmealing: No worries :)

21:51 justin_smith: skeuomorf is gone, but he should know you can do everything you can do with maps to record

21:51 s

21:51 htmldrum: Anyone got some material on setting up a Ring application on AWS? I'm used to preparing hosts via cloudformation or a provisioning tool like Puppet/Chef but am looking for resources on where to start as a newbie to Clojure/Java web services.

21:52 justin_smith: htmldrum: it's a lot easier to use elasticbeanstalk

21:52 you can use lein ring to make an uberwar, hand the uberwar to elasticbeanstalk, and that's it

21:53 htmldrum: justin_smith: Thank you :)

23:16 TimMc: justin_smith: Except for call empty or (sometimes) dissoc on them, because then you get a map again. :-P

23:16 justin_smith: TimMc: you can do those things though!

23:17 TimMc: True!

23:17 justin_smith: you just get a different data type back

Logging service provided by n01se.net