#clojure log - Oct 31 2015

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

0:27 pyon: Let's say that (foo bar) returns a list. How do I instead return a lazy sequence, with the same contents as foo bar?

0:28 justin_smith: (lazy-seq (foo bar)) - but there is little advantage to this, the real advantage is to generating your result lazily

0:28 pyon: Well, in my case (foo bar) is actually a recursive call.

0:28 Wait, just in case - `map` itself returns a lazy sequence, right?

0:28 justin_smith: then instead of (cons h (foo arg)) do (lazy-seq (cons h (foo arg))) inside the body of foo

0:29 sure, map returns a lazy-seq

0:32 pyon: What I really want to delay is the recursive call itself.

0:32 Rather than a cons.

0:33 justin_smith: you need cons to construct the list

0:33 the lazy-seq will delay all evaluation inside it

0:35 pyon: In this situation, I'm almost sure that what needs to be delayed is the recursive call itself: https://www.refheap.com/111230

0:36 justin_smith: pyon: like I said, lazy-seq in that position delays both the cons and the recursive call

0:36 amalloy: it's easier to just wrap the whole body of the function in lazy-seq

0:36 but you can indeed put it just about anywhere and it'd be fine

0:36 justin_smith: fair point

0:37 pyon: :-O

0:37 justin_smith: so yeah, like amalloy says, you can just do (defn mono [k xs] (lazy-seq (when-let ...)))

0:56 jhn: why does (merge-with concat {} {:a [1]}) => {:a [1]}

0:56 but (swap! (atom {}) merge-with concat {:a [1]}) =>

0:56 IllegalArgumentException contains? not supported on type: clojure.core$concat

0:59 amalloy: because that's (merge-with {} concat ...)

1:00 jhn: ah! that makes sense. ty. :)

1:03 is this the least ugly way to make this work?

1:03 (swap! (atom {}) #(merge-with concat % {:a [1]}))

1:05 pyon: Why is lazy-seq called lazy-*seq*, if it can be used on things other than sequences?

1:05 jhn: because seq is the name of the interface.

1:05 so you can use it with anything that is a seq

1:07 essentially, the "things other than sequences" you're referring to *are* actually sequences.

1:12 mungojelly: everything is everything and programming is just an extended meditation on how similar everything is to everything else

1:21 pyon: jhn: Ah!

1:21 Is there any way to delay computations that don't yield (the beginning of) a sequence?

1:22 rhg135: defer

1:22 pyon: Ah!

1:22 rhg135: Err, delay

1:23 ,(def v (delay (println *clojureversion*)))

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

1:24 rhg135: ,(def v (delay (println *clojure-version*)))

1:24 clojurebot: #'sandbox/v

1:24 rhg135: ,@v

1:24 clojurebot: {:major 1, :minor 8, :incremental 0, :qualifier alpha3}\n

3:28 pyon: Is there anything like a recursive macroexpand?

3:29 That is, macroexpand everything. Or, even better, only macroexpand specific macros that I tell it to expand.

3:45 TEttinger: pyon: yeah

3:46 http://clojure.github.io/clojure/clojure.walk-api.html#clojure.walk/macroexpand-all

3:47 ,(clojure.walk/macroexpand-all (if (and true "yay") :hooray :boo))

3:47 ,(clojure.walk/macroexpand-all (if (and true "yay") :hooray :boo)))

3:47 clojurebot: #error {\n :cause "clojure.walk"\n :via\n [{:type java.lang.ClassNotFoundException\n :message "clojure.walk"\n :at [java.net.URLClassLoader$1 run "URLClassLoader.java" 366]}]\n :trace\n [[java.net.URLClassLoader$1 run "URLClassLoader.java" 366]\n [java.net.URLClassLoader$1 run "URLClassLoader.java" 355]\n [java.security.AccessController doPrivileged "AccessController.java" -2]\n [java.net.U...

3:47 #error {\n :cause "clojure.walk"\n :via\n [{:type java.lang.ClassNotFoundException\n :message "clojure.walk"\n :at [java.net.URLClassLoader$1 run "URLClassLoader.java" 366]}]\n :trace\n [[java.net.URLClassLoader$1 run "URLClassLoader.java" 366]\n [java.net.URLClassLoader$1 run "URLClassLoader.java" 355]\n [java.security.AccessController doPrivileged "AccessController.java" -2]\n [java.net.U...

3:47 TEttinger: ,(require '[clojure.walk])

3:47 clojurebot: nil

3:47 TEttinger: ,(clojure.walk/macroexpand-all (if (and true "yay") :hooray :boo))

3:47 clojurebot: :hooray

3:47 TEttinger: ,(clojure.walk/macroexpand-all '(if (and true "yay") :hooray :boo))

3:47 clojurebot: (if (let* [and__4224__auto__ true] (if and__4224__auto__ "yay" and__4224__auto__)) :hooray :boo)

3:49 pyon: TEttinger: Ah, nice, thanks. :-)

3:54 If I defined a function `foo' inside a macro or function `bar', then `foo' can only be used inside `bar', right?

3:54 define*

4:02 Is there anything like `when-let`, but accepting multiple bindings?

4:03 Also, what's the difference between `defn` and `letfn`?

4:03 Or, rather, why do we need them both?

4:15 hiredman: because clojure is not scheme

4:15 def in clojure always creates a top level binding, defn expands to a def + fn

4:16 letfn creates local bindings and the names are all in scope for the functions bound to the names

4:16 (similar to letrec)

4:33 pyon: hiredman: ah!

5:24 zajira: i'm new to clojure, how I import http-kit into the lein REPL? I already added http-kit to my project.clj, but I get "No such namespace: http-kit"

5:47 macro-pyon: What's the convention for embedding code in docstrings?

5:47 Markdown?

6:10 expez: macro-pyon: no real convention, but I've only ever seen people use MD.

6:11 macro-pyon: It's more about what your tools can handle. CIDER will highlight stuff embedded with `` in docstrings and comments for example.

6:11 embedded in*

6:12 Is : a part of the keyword, or is it more correct to think of this as a token for the reader?

6:12 I'm leaning toward the latter

6:12 ,(name :foo)

6:12 clojurebot: "foo"

6:13 expez: which I think should return ":foo", for the former interpretation to hold

6:14 I'm asking because we're still highlighting the : with keyword face in clojure-mode, even though the package prefix is now in a different color. I'm starting to think this is a mistake.

6:14 vijaykiran: ,[(keyword "a")(keyword :a)(keyword "a")]

6:14 clojurebot: [:a :a :a]

6:17 justin_smith: ,(keyword ":do not do this")

6:17 clojurebot: ::do not do this

6:30 WickedShell: Is the ^:const hint considered valid/used with fn's?

6:30 justin_smith: you can use it, bu afaik it won't do anything

6:31 WickedShell: Not surprised to hear that (or really bothered tbh)

7:09 pyon: Is there a better way to do this? https://www.refheap.com/111232

7:09 I've been wondering if I could use `loop` instead.

7:11 Errr, replace diff-loop with differentiate.

7:11 https://www.refheap.com/111234 fix'd

7:20 justin_smith: that seq call is redundant - the destructuring implies it

7:20 pyon: Ah!

7:21 justin_smith: otherwise, looks good to me (maybe you could avoid using the same lhs twice in the let binding).

7:22 ,(let [[h & t] "hello"] [h t])

7:22 clojurebot: [\h (\e \l \l \o)]

7:23 pyon: Ah!

7:23 If let bindings are sequential, this should do what I want it to do.

7:23 But, yeah, I should probably rename the second `xss`.

7:24 justin_smith: yes they are sequential

7:29 pyon: Is there no way to make this code shorter? (fn [[i xs]] [i (cons x xs)]) seems too long for what it achieves.

7:31 justin_smith: #(update-in % 1 conj x) if xs is a list, and [i xs] is a vector

7:31 err

7:31 update, not update-in

7:31 pyon: Ah!

7:32 justin_smith: ,(update [:a '(:b :c :d)] 1 conj :aa)

7:32 clojurebot: [:a (:aa :b :c :d)]

7:32 justin_smith: it breaks if they are not list and vector though

7:44 xeqi: pyon: I'd prolly write that as a variation of https://www.refheap.com/111236

7:44 pyon: Whoa, that's so much neater.

7:45 Alas, incorrect. :-|

7:46 Also, constantly performing (take i) and (drop i) for all values of i... is a little tad inefficient, isn't it? :-O

7:46 xeqi: ack, pasted the wrong one. (drop (inc i) xs)

7:46 pyon: Ah, good.

7:50 xeqi: might be. But I could see it the same as conj-ing the list when the (map fun (map fun (map fun xss))) stack unwinds with a layer for each previous value in the original

7:50 if I was performance sensitive, I'd assume xs is a vector and use (subvec ...)

7:51 pyon: What's subvec do?

7:51 Never mind. Me being stupid. :-|

7:51 Can vectors be efficiently concatenated, though?

7:59 xeqi: `concat` returns a lazy seq that walks underneath, so depends on how you're going to use it later. An alternative is `into` (https://www.refheap.com/111237) which uses transients underneath to build a new sequence

8:00 here's where I refer you to setup a suite with https://github.com/hugoduncan/criterium if this seems performance sensitive

8:00 pyon: Checking.

8:07 From [1 2 3 4 5], how do I get [[] [1] [1 2] [1 2 3] [1 2 3 4] [1 2 3 4 5]]? (not necessarily vectors)

8:07 And also [[1 2 3 4 5] [2 3 4 5] [3 4 5] [4 5] [5] []].

8:09 justin_smith: ,(iterate pop [1 2 3 4 5])

8:09 clojurebot: ([1 2 3 4 5] [1 2 3 4] [1 2 3] [1 2] [1] ...)

8:09 justin_smith: ,(iterate rest [1 2 3 4 5])

8:09 clojurebot: ([1 2 3 4 5] (2 3 4 5) (3 4 5) (4 5) (5) ...)

8:10 justin_smith: you'll want a test for when it ends up empty

8:10 or a take-while

8:10 pyon: Ah!

8:10 justin_smith: ,(take-while seq (iterate rest [1 2 3 4 5]))

8:10 clojurebot: ([1 2 3 4 5] (2 3 4 5) (3 4 5) (4 5) (5))

8:10 justin_smith: ,(take-while seq (iterate pop [1 2 3 4 5]))

8:10 clojurebot: ([1 2 3 4 5] [1 2 3 4] [1 2 3] [1 2] [1])

8:11 justin_smith: when it's not a vector, you can use but-last instead of pop, but pop is much better for vectors

8:11 pyon: Ah!

8:11 ,(let [xs [1 2 3 4 5]] (map vector (range) xs (iterate pop xs) (iterate rest xs)))

8:11 clojurebot: ([0 1 [1 2 3 4 5] [1 2 3 4 5]] [1 2 [1 2 3 4] (2 3 4 5)] [2 3 [1 2 3] (3 4 5)] [3 4 [1 2] (4 5)] [4 5 [1] (5)])

8:12 pyon: Wait, no, I need something like the reverse of (iterate pop xs).

8:13 justin_smith: well, we do have reverse

8:13 pyon: yeah, but that turns out to be O(n²).

8:14 justin_smith: why n squared instead of n?

8:15 pyon: I mean, for the thing. Each reverse is O(n).

8:15 But I need n reverses.

8:17 justin_smith: ,(reduce conj [] [1 2 3 4 5])

8:17 clojurebot: [1 2 3 4 5]

8:17 justin_smith: err

8:17 ,(reductions conj [] [1 2 3 4 5])

8:17 clojurebot: ([] [1] [1 2] [1 2 3] [1 2 3 4] ...)

8:17 pyon: Why can I do (#(vector %1 %2 %1 %2) "foo" "bar"), but not (#([ %1 %2 %1 %2]) "foo" "bar") ?

8:17 Ah!

8:18 justin_smith: ,'#([:a]) ; this should help

8:18 clojurebot: (fn* [] ([:a]))

8:19 pyon: Ah!

8:25 What's the function for getting the i-th element of a vector?

8:25 justin_smith: nth

8:25 with a vector you can also use get

8:25 pyon: Ah, sweet. :-)

8:26 justin_smith: ,((juxt nth get) [:a :b :c] 1)

8:26 clojurebot: [:b :b]

8:26 justin_smith: ,(get-in [:a [:b [:c [:d [:e]]]]] [1 1 1 0])

8:26 clojurebot: :d

8:26 justin_smith: ,(get-in [:a [:b [:c [:d [:e]]]]] [1 1 1 1 0])

8:26 clojurebot: :e

8:30 pyon: I found a neat solution: https://www.refheap.com/111238 :-)

8:31 Well, actually, it's mostly based on what you guys suggested. :-)

8:31 TEttinger: ,([0 1 2 3] 0)

8:31 clojurebot: 0

8:31 TEttinger: ,([0 1 2 3] 3)

8:31 clojurebot: 3

8:31 TEttinger: ,([0 1 2 30] 3)

8:31 clojurebot: 30

8:31 TEttinger: vectors are functions of numerical indices too

8:31 pyon: :-O

8:32 That makes sense.

8:32 TEttinger: similar to maps and their keys

8:32 ,({:a 1 :b 2} :b)

8:32 clojurebot: 2

9:28 sobel: but keys are functions and indices are not, so you can write (:a {:a 1 :b 2}) => 1 but (1 [2 3 4]) yields an exception

9:29 just to note a little asymmetry there :)

9:49 pyon: What was the syntax for creating a record value? (not the record type)

9:50 Oh, there was a dot at the end of the record's name! I forgot that.

9:57 Glenjamin: there's also the clojure function ->Record

9:58 ,(do (defrecord Example [a b]) [(Example. 1 2) (->Example 1 2) (map->Example {:a 1 :b 2})])

9:58 clojurebot: [#sandbox.Example{:a 1, :b 2} #sandbox.Example{:a 1, :b 2} #sandbox.Example{:a 1, :b 2}]

10:10 pyon: Could someone please help me debug this macro? https://www.refheap.com/111241

10:10 When I run this in the REPL, I get the desired result: `[~@(mapcat (partial constructor-partial-derivative :r) node)]

10:10 But, for some reason, when I run it from within the macro, it doesn't work. :-|

10:34 xeqi: pyon: in total-differential you want `map-indexed` instead of `keep-indexed` since you keep everything

10:34 pyon: Ah, thanks!

10:34 Also, I found the solution to the defderivative problem.

10:34 I needed an eval.

10:34 (eval base)

10:41 xeqi: pyon: can defderivative be a function? looks like it just evaluates everything and passes it through?

10:41 pyon: xeqi: defderivative isn't finished.

10:41 In the end, it will be a macro - a much more complex one than defpolynomial.

10:42 It's just that I needed to see something for debugging purposes.

11:34 Is there anything like map, but which leaves the first element untouched?

13:50 gfredericks: pyon: that'd be a pretty weird function to have built in I think, but it's easy to write yourself

13:51 ,(defn map-rest [f coll] (if (empty? coll) coll (cons (first coll) (map f (rest coll)))))

13:51 clojurebot: #'sandbox/map-rest

13:51 gfredericks: ,(map-rest inc (range 5))

13:51 clojurebot: (0 2 3 4 5)

13:51 gfredericks: ,(map-rest dec ())

13:51 clojurebot: ()

13:55 xeqi: ,(map-rest dec nil)

13:55 clojurebot: nil

13:56 xeqi: ah, map returns () cause it uses lazy-seq

13:57 J_Arcane: ,(first ())

13:57 clojurebot: nil

13:57 J_Arcane: ,(rest ())

13:57 clojurebot: ()

14:36 justin_smith: ,(map (juxt rest next) [() [] nil])

14:36 clojurebot: ([() nil] [() nil] [() nil])

14:53 xeqi: what function turns a vec of keys and a vec of vals into a map?

14:53 justin_smith: zipmap

14:53 ,(zipmap [:a :b :c] [1 2 3])

14:53 clojurebot: {:a 1, :b 2, :c 3}

14:54 xeqi: (inc justin_smith)

14:54 oh, right.. no lazybot

15:24 skoude: Noob question,, but I have a json parsed with chesire.. and it's like [ { employee: {firstname: "test", lastname: "test" }, employer: { companyid: "test"} } , {employee: {firstname: "test2", lastname: "test2}, employer: {companyid: "test2"} }].. So how can I get all of the firstnames?

15:25 I tried to use (get-in parsed_json["employee" "firstname"], but it does not work

15:27 justin_smith: if that's the real structure, it should be (get-in parsed_json [0 "employee" "firstname"])

15:28 unless you provided the keywordize option to cheshire, in that case change the strings to keywords

15:28 rhg135: or map it

15:28 justin_smith: oh, all the first names

15:28 missed that part, right you are rhg135

15:29 skoude: thanks, now I got it. I had the keywordize option so I use keywords and it works :)

15:36 hmm.. I used (cheshire.core/parse-string s true)) to parse the json.. and if I print the parsed json, it looks okay.. but still I get only nil when using: get-in parsed_json [0 "employee" "firstname"])

15:36 justin_smith: skoude: those still are not keywords

15:36 and the true option specifies it should make kewords

15:36 skoude: sorry pasted wrong line: ude (+i) 8:fn/#clojure (+cnt) Act: 1,2,3,4,5,6,11,13

15:37 justin_smith: (map #(get-in % [:employee :firstname]) parsed_json)

15:37 skoude: used get-in parsed_json [0 :employee :firstname])

15:38 and still get nil

15:38 justin_smith: what does it look like when you just enter parsed_json at the repl and see the contents?

15:38 skoude: it looks perfectly okay :)

15:38 justin_smith: skoude: can I see it?

15:39 skoude: justin_smith: I cannot paste it straight because it's a json from production system... But it starts like:

15:40 [

15:40 {

15:40 "employee": {

15:40 "firstname": "KAI",

15:40 "lastname": "KALLUNKI",

15:40 justin_smith: that's not parsed

15:40 that's json

15:40 skoude: I use println to print it, and I tough that just a clojures way to display it?

15:41 justin_smith: no, clojure will not display a real hash-map that way, use prn on it

15:41 I bet you will discover an unparsed string with prn

15:42 skoude: yeah prn displays: "[\n {\n \"employee\": {\n \"firstname\": \"KAI\",\n

15:42 justin_smith: yes, that is an unparsed string

15:43 skoude: hmm.. strange, because I still call: (def parsed_json( parse json))

15:44 justin_smith: is the json somehow double-encoded?

15:44 skoude: and parse is the function that has: (cheshire.core/parse-string s true)) -defined

15:46 aah now I got it.. the problem was this: (def json (pr-str(:body (http-get-request

15:46 it should be only: (def json (:body (http-get-request "http

15:48 now if I do prn it shows like: ({:employee {

16:03 Thanks for the help, it works perfectly now.. Just takes a little time to get used to clojure when coming from java

16:05 justin_smith: in general, don't trust println to show you what something actually is - use prn for less ambiguity

16:05 skoude: thanks for the tip, will do and use that

16:06 justin_smith: ,(println {:a "0 :b 1"})

16:06 clojurebot: {:a 0 :b 1}\n

16:06 justin_smith: ,(prn {:a "0 :b 1"})

16:06 clojurebot: {:a "0 :b 1"}\n

16:09 cloj_dev: whats wrong with this destructuring of a vector? http://pastebin.com/kbvDGxCj

16:24 Glenjamin: you have two arguments

16:24 a map, then a vector

16:24 but you're calling it with only a vector

16:25 ianhedoesit: also your map destructuring is not probably how you expect it to be.

16:26 if you try `(foo {0 :a 3 :b} [1 2 3 4])` you might see part of the problem.

16:26 I might recommend this helpful cheatsheat (https://gist.github.com/john2x/e1dca953548bfdfb9844) to compare - specifically https://gist.github.com/john2x/e1dca953548bfdfb9844#maps in this case.

16:27 justin_smith: ,(let [{a 0 b 1} [:foo :bar]] [b a])

16:27 clojurebot: [:bar :foo]

16:27 jonathanj: hmm, how do i return a value from :post! in liberator?

16:28 justin_smith: ianhedoesit: the map syntax works fine for selecting indexes, see above

16:28 ianhedoesit: justin_smith: huh, interesting.

16:28 justin_smith: ianhedoesit: because vectors are associative by index

16:28 ianhedoesit: right, that makes sense.

16:28 irctc: Hello everyone.

16:28 justin_smith: it should fail with a list though

16:29 ianhedoesit: (it does)

16:29 irctc: I need help setting up reagent. I've been trying to figure it out but I just can't get it to work. Can somebody help me please?

16:29 ianhedoesit: I'm still going to assume that that wasn't what cloj_dev was trying to do, however. but maybe I'm wrong

16:30 justin_smith: irctc: do you have specific questions?

16:31 cloj_dev: lein new reagent

16:31 irctc: Yes. I put reagent in the dependencies in the project.clj file in my compojure project and Eclipse/counterclockwise plugin downloaded them all automatically for me. Now, how do I actually imlplement reagent in my web pages?

16:32 Do I put require [reagent.core :as r] in my views.clj file that renders my webpage and write my reagent code there or should I do something else?

16:33 justin_smith: irctc: first step is to set up clojurescript. reagent is not clojure (clj) it is clojurescript (cljs)

16:34 irctc: Ok, so in order for reagent to work I first need to download the dependencies for clojurescript?

16:34 justin_smith: irctc: next step is to have a cljs file that calls reagent.core/render-component, that sets up the rendering and you need to pass it an atom, changes to that atom will make new re-rendering of the page happen

16:34 irctc: your dep manager should do that for you, what you need to do is define a clojurescript build in your project

16:34 irctc: are you using leiningen?

16:35 irctc: Yes I am. leiningen and compojure for my web app.

16:35 And hiccup to render html5 components.

16:35 justin_smith: OK, so your first step is to check out lein-cljsbuild which you can use to set up clojurescript building

16:36 irctc: reagent is similar to hiccup (uses the same input syntax just about) but runs on the browser instead of your server

16:37 irctc: once you can get a basic hello-world cljs built and embedded into your html page and displaying when you load the page, you can move on to pulling in reagent

16:37 irctc: Ok, so I should set up lein-cljsbuild in my compojure app before I set up reagent?

16:37 cloj_dev: I'm trying to do something like this in clj http://pastebin.com/8mz7yZBT

16:37 I know why its wrong but I can't figure out a good solution

16:38 justin_smith: irctc: right, reagent is a dep that cljsbuild will use, cljsbuild will make javascript from your clojurescript code, that the browser will run to create your page

16:39 irctc: Ok, great. Thanks for your guidance. I might have some more questions as I go along setting it up, but I'm gonig to try and set everything up now.

16:39 justin_smith: lein-cljsbuild and the reagent project both have good docs

16:40 cloj_dev: reagent is very easy to get going if you have lein

16:40 ianhedoesit: cloj_dev: are you trying to reverse a vector?

16:40 cloj_dev: sort of

16:41 ianhedoesit: or are you trying to stagger it backwards?

16:41 justin_smith: cloj_dev: that won't ever return - you need a conditional around recur

16:41 cloj_dev: I want (foo [1 2 3 4]) to be [2 1 4 3]

16:42 justin_smith: yeah, all you need is an if check for rest being empty, and just returning [b a] if rest is empty

16:42 well - you might need one or two other things, but that will be a start

16:42 jonathanj: any recommended HTTP client libraries?

16:43 i have no idea how to choose between the top few google results

16:43 justin_smith: jonathanj: I've found http-kit.client better than clj-http.client

16:43 jonathanj: justin_smith: why?

16:44 justin_smith: clj-http has some bad behaviors for poorly behaved endpoints in my experience, and wasn't nearly as nice for async stuff

16:44 for example timeout arguments seemingly not working as expected

16:44 cloj_dev: hm this function won't work

16:44 http://pastebin.com/zhmDfU09

16:45 jonathanj: justin_smith: thanks, that sounds like a good recommendation

16:46 ianhedoesit: cloj_dev: what do you mean it won't work?

16:46 justin_smith: cloj_dev: do you expect your input to be individual items, or a sequence?

16:46 cloj_dev: a sequence I beliece

16:46 ianhedoesit: (foo 1 2 3 4) outputs "fun"

16:46 cloj_dev: like [1 2 3 4]

16:46 oh

16:46 justin_smith: cloj_dev: because as of now it is looking for individual items, you need an extra pair of [] around the arg list

16:46 cloj_dev: ah okay

16:46 good call

16:47 justin_smith: because the recursive version would be a pain without that

16:47 cloj_dev: thanks

16:57 irctc: I ran into a problem installing lein-cljsbuild. When I try to do lein cljsbuild auto like it says on the github page: https://github.com/emezeske/lein-cljsbuild I get an error.

16:57 lein cljsbuild auto Watching for changes before compiling ClojureScript... Exception in thread "main" java.io.FileNotFoundException: Could not locate cljs/util__init.class or cljs/util.clj on classpath: , compiling:(cljs/closure.clj:1:1)

16:58 I have no idea what that exception is all about.

16:58 justin_smith: irctc: can you share your project.clj on refheap?

17:00 irctc: Sure. Here it is: https://www.refheap.com/78c74e95513c162e1816f5cec

17:02 justin_smith: my first guess is an incompatibility between your clojurescript dep version and the lein-cljsbuild dep version

17:03 irctc: I just took the latest ones, like it says on their github pages.

17:03 cloj_dev_: hm, this gives an infinite loop http://pastebin.com/Bbk4rS9x

17:04 justin_smith: irctc: sure, but I don't think they can guarantee they are compatible with every cljs version - and the error you got looks like an incompatible version issue between cljs and cljsbuild

17:05 cloj_dev_: you are never modifying that "rest" argument - it will never change in that loop

17:05 so if it starts non-empty, it can never end up empty

17:05 cloj_dev_: ah right

17:06 irctc: Ok, I'm going back to 0.0-3190 Hopefully that works.

17:06 I tried 1.7.10 but that just produced the same error.

17:11 Ok if it works is it supposed to just say Watching for changes before compiling ClojureScript... and not give me back my prompt?

17:11 justin_smith: right

17:11 unless you provide the "once" arg

17:11 if you provide once it will exit after compiling

17:11 it will recompile if it sees new cljs files or edits to existing files

17:12 next step is to pull the generated js into your html so that it can run

17:12 irctc: Ok. And how do I now run my lein ring server command? Do I just leave this terminal window open and just run it from another one?

17:12 justin_smith: yeah, just run it in a different terminal

17:13 stepping away from the computer for a bit... I'll check in later

17:13 irctc: Oh, ok, so the next step for me is to actually create a clojurescript file and then incorporate it into my views.clj function that will generate my page?

17:13 Ok, thanks a lot for all your help. :)

17:13 jonathanj: justin_smith: how do i send a custom body with http-kit.client?

17:14 justin_smith: in this case i want to send a JSON body in a POST request

17:14 i see :form-params but it sounds like it's form-encoded?

17:15 apparently :body is an option, although the client docs <http://www.http-kit.org/client.html> fail to mention it

17:16 cloj_dev_: darn, still getting an infinite loop http://pastebin.com/ZmDbh6T5

17:21 ianhedoesit: cloj_dev_: you're still not doing anything with the rest of the list. if you change `[d c]` to `(println [d c])` you'll see what's happening

17:24 cloj_dev_: hm tried that

17:24 it did what I expected I think

17:26 oddcully: jonathanj: something like e.g. (es/post (str uri url-part) {:content-type :json :as :json :body (json/generate-string request)}))

17:52 irctc: In clojurescript in my project.clj where it says: :source-paths ["src-cljs"] where is that source path actually supposed to be?

17:52 Is it supposed to be on the same level as src or in the resources or in resources/public?

17:52 Or somewhere else?

18:05 justin_smith: irctc: that is the path from the project.clj to the top level of the sources

18:06 so yeah, same level as src

18:07 irctc: Thank you. :)

18:08 I actually compiled my clojurescript file into a main.js file, but I can't see the newly formed file in my eclipse editor.

18:09 Nevermind. I found it in my file system.

18:09 For some reason eclipse is just not showing it in the file structure.

18:11 So when I have multiple clojurescript files, will they all get compiled into this single main.js file?

18:16 justin_smith: the main.js file will make the rest of them load, but you don't get the single file without advanced compilation iirc

18:18 irctc: Ok.

18:18 And now when I call the main.js in my views.clj file, how do I point to the actual function that I want to display its results on my page?

18:19 I am using this to call the main.js file: (hic-p/include-js "/js/main.js")

18:19 justin_smith: your html should load your main.js and run some function in it

18:19 irctc: That doesn't happen.

18:19 justin_smith: irctc: it has to

18:20 irctc: there's no magic that makes a browser run clojurescript

18:20 there has to be a js file, and there has to be some html file that makes the browser load the js file

18:20 your cljs is just there to be compiled and turned into that js

18:20 irctc: I put the call to the main.js in my hed generating function which works as it generates all other html elements, but it doesn't render the simple "Hello world text" from my clojurescript file.

18:21 Head generating function*

18:21 justin_smith: OK sure, you can generate the html

18:22 point is, the entry point is the html which the browser understands, then you set up your rendering to happen when your main method in cljs gets called

18:22 eventually, that should be a call to reagent

18:22 once you establish you can get your cljs to load and run

18:23 irctc: So do I call the cljs function from my views.clj file just like I would with any other function?

18:23 justin_smith: how would your clj code make anything happen in the browser?

18:24 I mean it can, but you need some mechanism of communication...

18:26 irctc: Well this is what I am confused about. I am calling the main.js file and I am assuming that it loads because I loaded a plain javascript file the same way. Next I want it to display the words "Hello world" on my page that the clojurescript function (hello) makes, but when I open my browser window that doesn't write anything on my page.

18:28 rhg135: You have to call that function

18:28 justin_smith: irctc: right, this is the part where reagent comes in. First verify your cljs runs (eg. you can run (.alert js/window "hello") inside your cljs and verify you get the popup), after that to get rendering happening, that is when you start using reagent

18:28 irctc: If the main.js file makes the rest of the clojurescript files load, then how do I access my hello function in example.cljs and load the results of executing that function on my page?

18:28 justin_smith: rhg135: well, just because some function returned "hello world" isn't enough to make the browser show the message

18:29 irctc: you need a client side renderer, that's what reagent does

18:29 irctc: or you can play with the dom, or with jquery, but right now those would both be wastes of your time

18:29 irctc: Ok, I'm going to verify that it works first with that alert message.

18:30 rhg135: Oh, I misread, justin_smith, right

18:30 justin_smith: cool, and if that works, you can start hooking up reagent, then things get fun :)

18:30 irctc: I can't wait. Keeping my fingers crossed. :)

18:32 It worked!!! :D

18:33 I don't know I've ever been so happy to see an alert message before. lol :D

18:34 justin_smith: irctc: cool, next step, now that you know you can compile cljs and make it run, is make sure you have reagent in your deps, and call reagent/render-component with the apropriate args

18:34 irctc: spend some time with the reagent docs, they are really good and thorough, and you should be able to follow along with any examples now that you have this much set up

18:35 irctc: reagent/render-component will watch an atom, and every time the atom changes, it will update the contents of the page (that's the big picture, of course there are lots of details to set up)

18:36 irctc: Thanks so much! :)

18:36 Btw, when calling reagent/render-component, do I call that in my views.clj file or in the cljs file?

18:37 justin_smith: in the cljs

18:37 irctc: And when I require reagent do I need to require it in my views.clj as well or just in my cljs file?

18:37 justin_smith: since it needs to run in the browser

18:37 irctc: what does views.clj do?

18:37 irctc: Generates my pages.

18:37 Part of my compojure framework.

18:38 justin_smith: yeah, this is actually an alternate way to generate pages - because compojure doesn't run in the browser

18:38 the concept is that instead of making the page on the server and sending to the client, the cljs code constructs the page on the client side, and just asks the server for data - views.clj would be used to make handlers that send data the frontend needs

18:39 irctc: Ok, so in my cljs file, right after I write my function I'll call (reagent/render-component) and that will watch over all of my atoms, and then I can just compile it and load it the same way I did with this previous alert message?

18:41 Ok, cool, because then I can use the client to make some async calls to the server to avoid blocking the user.

18:41 justin_smith: something like that - add the render-component to the main cljs function, and what the reagent docs will show is how to hook up the atoms to manage the page state

18:41 irctc: That's the whole reason why I'm using cljs and trying to use reagent in the first place. :)

18:41 justin_smith: and yeah, make async calls to the server (calling functions in views.clj) that load the data you need to load into the page

18:41 right

18:42 irctc: Cool, thanks. :)

18:42 I am using this for the reagent tutorial https://reagent-project.github.io/ Hopefully I'll be successful in setting it all up.

18:43 justin_smith: yup, that's the one

18:44 irctc: if you scroll down a bit, it shows how to set up the cljs namespace and call render-component

18:46 irctc: Cool. Thanks. :)

18:50 I copied and pasted the entire first example that mentions reagent/render-component except for the name of the namespace just to test it out but I can't get anything to display on my page.

18:51 justin_smith: OK, I bet you will find compilation errors in your cljsbuild window, or js errors in the browser console

18:52 irctc: Compiling ClojureScript... Compiling "resources/public/js/main.js" from ["srccljs"]... Successfully compiled "resources/public/js/main.js" in 7.157 seconds.

18:52 Everything seems allright.

18:52 I even restarted the server.

18:52 justin_smith: ok, how about the browser js console

18:53 irctc: You were right. There is something in the browser js console: mutating the [[Prototype]] of an object will cause your code to run very slowly; instead create the object with the correct initial [[Prototype]] value using Object.create

18:53 Although I don't know what that means.

18:54 justin_smith: that's not an error though

18:56 irctc: I know, but that's all I get and I don't know why I'm not getting any output on my page.

18:57 justin_smith: what do you see when you inspect the page (via right-click)

18:58 irctc: I see it loads the main.js file: <script src="/js/main.js" type="text/javascript"></script>

18:58 justin_smith: is there anything in the page body?

18:59 irctc: Other than that there's nothing else there.

18:59 justin_smith: irctc: in the r/render-component call, what is the last arg?

19:00 irctc: (.-body js/document)

19:00 justin_smith: OK, so you tell reagent to render to the document body, but when you inspect the page there is no body?

19:01 irctc: Exactly.

19:02 justin_smith: how about making sure there is a body to the page so that it can render?

19:02 irctc: Well I mean there is a body, there's jut no content in it.

19:02 justin_smith: I have to go

19:03 irctc: Ok, thanks for all your help.

19:03 I really appreciate it.

19:03 :)

19:30 pyon: I want to make two macros, `deffoo` and `defbar`. `deffoo` creates a bunch of stuff, and the last thing it creates is a variable foo: (`def ~name { :meta ... :data ... :goes ... :here ... }). What I want `defbar` to do is (0) create a foo, (1) some bar-specific work, (2) insert more metadata into the metadata object.

19:31 In a language like Common Lisp, I'd just create the metadata object from `deffoo` and then mutate it from `defbar`.

19:31 What would a more idiomatic Clojure solution, without mutability, look like?

19:49 Is there any function like `map`, but which discards the result of applying the function to the list's elements?

19:50 Basically something like (keep func seq), except (func elem) *always* returns nil.

19:51 rhg135: run!

19:52 in 1.8 of course

19:52 pyon: rhg135: Oh, nice, thanks!

19:52 rhg135: 1.7*

19:52 pyon: I'm using 1.7.0, which comes with my package manager, and run! works.

19:52 rhg135: ok good

20:01 pyon: How do I check whether a symbol refers to an existing variable.

20:01 ?

20:03 rhg135: resolve

20:04 ,(do (resolve 'x2) (resolve '+))

20:04 clojurebot: #'clojure.core/+

20:05 rhg135: uhh, the former returns nil

20:05 justin_smith: ,(resolve 'to-quit-smoking)

20:05 clojurebot: nil

20:06 rhg135: ,(resolve 'to-lose-weight)

20:06 clojurebot: nil

20:06 pyon: Ah!

20:06 justin_smith: haha

20:06 pyon: lol

20:06 rhg135: ty!

20:06 rhg135: not in cljs though

20:07 in cljs you need to intrude on the compiler

20:07 justin_smith: rhg135: can't you do like (aget js/window "your-ns/your-var") or something like that?

20:08 rhg135: that assumes you want to hardcode the ns name. so forget DRY

20:08 justin_smith: rhg135: aget takes a string as an arg...

20:09 rhg135: cljs lacks getting the name at runtime, at least back in 201.r4

20:09 pyon: Is there any way to tell the Clojure REPL “forget every single thing I've defined before”, without restarting it?

20:10 justin_smith: rhg135: it's an array operation, you are treating the object as an array and looking up a key in it

20:10 rhg135: ,(run! (partial ns-unmap *ns*) (ns-publics *ns))

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

20:11 rhg135: err, something lise that

20:11 justin_smith: run takes a function and a collection

20:11 err, run! does I mean

20:12 pyon: :-O

20:13 rhg135: justin_smith: I mean you can't know the actual ns name at runtime without hardcoding at compile time. unless dnolen endowed it by now

20:14 Bronsa: justin_smith: that won't work with advanced compilation

20:14 justin_smith: Bronsa: ahh, good point

20:14 Bronsa: I don't think there's a good way to do resolve in cljs

20:14 justin_smith: rhg135: the ns at runtime is 'user anyway, aside from dev time shenanigans

20:14 rhg135: oh and that. thx Bronsa

20:15 'cljs.user but yeah

20:16 you can do it at compile time via the api

20:16 I think

20:32 pyon: How could I make a macro for asserting multiple things in a single place?

20:32 (multi-assert test1 "failed test1" test2 "failed test2" ...)

20:51 rhg135: ,(defmacro multi-assert [& pairs] `(do ~@(for [[t msg] (partition 2 pairs)] `(assert ~t ~msg))))

20:52 clojurebot: #'sandbox/multi-assert

20:52 justin_smith: why would this need to be a macro?

20:52 rhg135: ah. yeah he's right

20:54 justin_smith: well, because assert is a macro I guess...

20:54 rhg135: maybe lazyness, aka if a certain test is very expensive

20:54 justin_smith: though we can still do this without another macro

20:55 ,(map #(assert (first %) (second %)) [[true "ok"] [false "oops"]])

20:55 clojurebot: #<AssertionError java.lang.AssertionError: Assert failed: oops\n(first p1__68#)>

21:32 pyon: rhg135: justin_smith: ah, thanks!

21:36 https://www.refheap.com/111249 -- here, in constructor-metadata, how do I quote the name?

21:37 If I do 'name , it gives me (quote name), but what I actually want to quote is the *value* of the variable name.

21:38 To be clearer - how do I quote the value of a variable?

21:38 justin_smith: either the caller needs to quote name, or constructor-metadata needs to be a macro

21:39 you can't get the quoted version of an argument in a function

21:39 pyon: Oh.

21:39 But, if I make it a macro, then I can't map over it in defpolynomial. Mmm...

21:40 justin_smith: sounds like the caller needs to quote the names

21:41 pyon: I can think of ways to do it, but not in syntactically pleasing ways. :-|

21:47 cloj_dev: I'm still working on this problem : http://pastebin.com/9mBXSgxm

21:47 anyone have a suggestion?

21:48 justin_smith: cloj_dev: next never changes

21:48 cloj_dev: huh

21:49 ah I see that now

21:49 justin_smith: ,((fn [[a b & rest]] (if (empty? rest) [b a] (concat [b a] (recur rest)))) [1 2 3 4 5 6])

21:49 clojurebot: #error {\n :cause "Can only recur from tail position"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.UnsupportedOperationException: Can only recur from tail position, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6891]}\n {:type java.lang.UnsupportedOperationException\n :message "Can only recur from tail position"\n ...

21:49 justin_smith: hrmph

21:50 ,((fn flipper [[a b & rest]] (if (empty? rest) [b a] (concat [b a] (flipper rest)))) [1 2 3 4 5 6])

21:50 clojurebot: (2 1 4 3 6 ...)

21:50 justin_smith: it's still bad if the arg count is odd though

21:50 cloj_dev: oh nice

21:51 I thought you can't have recursive functions that don't call recur

21:51 justin_smith: you can, they just don't get optimized

21:51 but with laziness (concat) that is less of an issue

21:51 cloj_dev: oh

21:54 justin_smith: cloj_dev: it's normal for lazy functions to use direct self-call instead of recur

21:54 cloj_dev: interesting

21:54 how do you know if a function is lazy?

21:54 is it self evident, or documented?

21:54 or you just know by rote?

21:54 justin_smith: there's basically one lazy class: clojure.lang.LazySeq

21:55 lazy functions are the ones that use that class directly (via the lazy-seq function) or call others that use it (like map or concat or filter)

21:55 functions should document if they are lazy

21:55 cloj_dev: right cool

21:56 rarebreed: there's also the delay macro

21:56 justin_smith: that's not lazy

21:56 rarebreed: which will delay evaluation of a function

21:57 justin_smith: yes, but it's not considered lazy by clojure's standards - with a lazy seq accessing the value can force execution, with delay you need to deref

21:57 I'd group delay closer to future and promise

21:57 in terms of spheres of functionality

21:58 rarebreed: yes, if you use delay, you have to force on the result or deref it

21:58 justin_smith: things that could give you a value, but you may need to wait, and you can check exlicitly whether they are realized

22:01 pyon: Ok, just to be sure. What's the simplest way to make a macro quoteall, such that (quoteall foo bar qux) expands to ['foo 'bar 'qux] ?

22:05 ,(defmacro unusable [foo] (class foo)) (unusable 'foo) ; why?

22:05 clojurebot: #'sandbox/unusable

22:06 pyon: ,(unusable 'foo) ; why?

22:06 clojurebot: clojure.lang.Cons

22:06 pyon: How is this a cons cell?

22:12 justin_smith: ,''foo

22:12 clojurebot: (quote foo)

22:12 justin_smith: that's why

22:13 gfredericks: ,(defmacro quoteall [& args] (mapv #(list 'quote %) args))

22:13 clojurebot: #'sandbox/quoteall

22:13 gfredericks: ,(quoteall foo bar qux)

22:13 clojurebot: [foo bar qux]

22:13 justin_smith: ~macros

22:13 clojurebot: macros are just a game with symbols

22:13 gfredericks: ,(defmacro quoteall [& args] `'[~@args])

22:13 clojurebot: #'sandbox/quoteall

22:13 gfredericks: ,(quoteall foo bar qux)

22:13 clojurebot: [foo bar qux]

22:13 gfredericks: haha I just wrote `'[~@args] #yolo

22:14 pyon: justin_smith: Ah!

22:14 justin_smith: gfredericks: you could have gotten a #reader-macro in there if you tried

22:15 and #yolo doesn't count :P

22:15 pyon: ,(class (first (quoteall (foo bar qux)))

22:15 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

22:15 pyon: oops

22:15 ,(class (first (quoteall (foo bar qux))))

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

22:15 pyon: I'm dumb.

22:15 ,(class (first (quoteall foo bar qux))

22:15 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

22:15 pyon: Never mind.

22:16 gfredericks: ,(class (first (quoteall foo bar qux)))

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

22:16 gfredericks: ,(defmacro quoteall [& args] `'[~@args])

22:16 clojurebot: #'sandbox/quoteall

22:16 gfredericks: ,(class (first (quoteall foo bar qux)))

22:16 clojurebot: clojure.lang.Symbol

22:16 pyon: Ah!

22:16 What exactly does `' do?

22:16 gfredericks: clojurebot is forgetful

22:17 pyon: Heh, makes sense. :-)

22:17 justin_smith: pyon: it wraps quote in syntax-quote, and it is usually a sign of mischeaf

22:17 gfredericks: ,(defmacro quoteall [& args] (list 'quote (vec args)))

22:17 clojurebot: #'sandbox/quoteall

22:17 gfredericks: ,(quoteall foo bar qux)

22:17 clojurebot: [foo bar qux]

22:17 gfredericks: pyon: ^ that oughta be a much simpler definition to understand

22:17 pyon: Ah :-)

22:21 amalloy: ,'`'[~@args]

22:21 clojurebot: (clojure.core/seq (clojure.core/concat (clojure.core/list (quote quote)) (clojure.core/list (clojure.core/apply clojure.core/vector (clojure.core/seq (clojure.core/concat args))))))

22:21 amalloy: ^ that oughta be a less simple explanation to understand

22:21 justin_smith: lol

22:23 OrbitalKitten: hi guys, do you know if there's a way to generate the members in deftype/defrecord without going into eval hell?

22:23 gfredericks: ,(inc amalloy)

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

22:23 gfredericks: (inc amalloy)

22:23 OrbitalKitten: I think defrecord has a way

22:24 ,(defrecord OrbitalKitty [weight velocity])

22:24 clojurebot: sandbox.OrbitalKitty

22:24 gfredericks: ,(OrbitalKitty/getBasis)

22:24 clojurebot: [weight velocity]

22:24 OrbitalKitten: ooh by member I mean implementations of the methods

22:24 gfredericks: ooooh you want to generate implementations of protocol programmatically

22:24 OrbitalKitten: yeah

22:24 gfredericks: ,(doc extend)

22:24 clojurebot: "([atype & proto+mmaps]); Implementations of protocol methods can be provided using the extend construct: (extend AType AProtocol {:foo an-existing-fn :bar (fn [a b] ...) :baz (fn ([a]...) ([a b] ...)...)} BProtocol {...} ...) extend takes a type/class (or interface, see below), and one or more protocol + method map pairs. It will extend the polymorphism of the protocol's methods to call the suppl...

22:25 gfredericks: it's surprisingly easy :)

22:25 OrbitalKitten: thanks, I will look at this

22:30 hmm looks like it only works with Protocols, and i'm implementing a huge ass interface

22:30 basically it's a visitor that has a ton of visit/endVisit methods

22:31 I'm using reflection to find out what I need to implement and generate the corresponding methods

22:31 heh I'll stick with the evil code for now

23:12 pyon: Does Clojure have anything like Common Lisp's keyword arguments?

23:33 TEttinger: pyon: I don't know CL, but we do have keyword destructuring for maps as args. I think it's frowned upon

23:34 ~kwargs

23:34 clojurebot: kwargs are a bad idea.

23:34 TEttinger: ~kwargs

23:34 clojurebot: kwargs are a bad idea.

23:34 TEttinger: hm

23:34 pyon: Ah!

23:34 TEttinger: there's another one

23:34 it doesn't play well with other clojure stuff though

23:34 since you can't make a partial fn of it, for instance

23:35 pyon: Makes sense.

23:35 TEttinger: it technically takes a single arg, a map that may contain lots of keywords and values, so partial would need a whole new map

23:37 pyon: Can I understand a macro as a normal function, except its arguments are passed all quoted?

23:39 amalloy: pyon: yes, except that also its result is expanded into the function calling it, rather than being returned as a value

23:39 pyon: Ah!

23:40 So, in principle, I would write everything in terms of normal functions, and use a single macro `macroize`, that lets me use other existing functions as macros, right?

23:40 s/would/could/

23:41 TEttinger: usually you should prefer fns because macros can't be passed around as first-class values

23:41 ,(reduce and [true true true])

23:41 pyon: Yeah. I've been running into that a lot.

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

23:50 pyon: So, I could use (defmacro macroize [function & arguments] `(~function ~@(map #(list 'quote %1) arguments))), and define all other macros in terms of normal functions and macroize, right?

23:50 Or, is this a bad idea for some reason?

23:51 amalloy: it's not clear how you intend macroize to work but i'm fairly sure it won't work that way

23:58 pyon: Can I “delay a ~”?

23:58 I'm trying to write a macro that produces a macro.

23:59 spradnyesh: can someone please explain this?

23:59 (= (double 1.0) (float 1.0)) => *true*

23:59 and (= (cast java.lang.Double 1.0) (cast java.lang.Float (float 1.0))) => *true*

23:59 but (= (:close (second data)) (:close (second rslt))) => *false*, where

23:59 (:close (second data)) => 95.2

23:59 (:close (second rslt)) => 95.2

23:59 (type (:close (second rslt))) => java.lang.Float

23:59 (type (:close (second data))) => java.lang.Double

Logging service provided by n01se.net