Fork me on GitHub
#beginners
<
2016-08-12
>
niwinz08:08:14

@polymeris: you can't deref the promise value as is in cljs, because deref is a sync operation and in clj blocks until the promise is resolved, but in cljs, no blocking is posible, this is because in cljs you can't deref a promise

niwinz08:08:20

Additionally, clj promise is blocking and does not offers composability of the promise abstraction in js/cljs world. funcool/promesa is an attempt to create an uniform abstraction that works in very similar way in both platforms 😉

oahner18:08:34

@scott.haleen: your macro is working against the expression passed as cfg, not its result

scott.haleen18:08:28

@oahner: it works with a map is passed {:a 1} but not a form (assoc {:a 1} :b 2) how do I force it to evaluate the form if need?

seancorfield18:08:42

A macro is a function that is called on code-as-data before that code is evaluated.

seancorfield18:08:52

You could try using eval but you’ll likely run into bizarre behavior (trying to evaluate expressions in the context of the reader).

seancorfield18:08:27

I’d ask: what are you really trying to do? You probably don’t need a macro.

scott.haleen18:08:19

I agree probably not, I was just trying to have a utility that is pretty much exactly like the sample. The idea being you can pull keys from a map and have it *auto* assigned to a variable. Opposed to (sample {:a 1} [:a] (fn [a] (identity a))

jswart18:08:28

If it really is as simple as what you have above you can do (let [{:keys [a b]} cfg] a)

jswart18:08:53

you could make a function or simple syntax-quote macro on top of destructuring which is essentially what you want.

scott.haleen18:08:58

Also I am just trying to understand this better.

jswart18:08:09

Yah that makes sense

jswart18:08:27

My friend wrote this book, you shoudl check it out: http://www.braveclojure.com/writing-macros/

scott.haleen18:08:51

I have been using that as well, thanks

seancorfield18:08:01

(defmacro sample [cfg keys form]
  `(let [{:keys ~(mapv (comp symbol name) keys)} ~cfg] ~form))

jswart18:08:09

Basically macros happen before your code evaluates. The map you pass in is just data. But the expression is not simple data. Its code in the form of data.

jswart18:08:25

@seancorfield: just made it work

jswart18:08:40

~ says “run this code first and place it here”.

jswart18:08:11

thats not scientific, but intuitive-ish explanation on my part

scott.haleen18:08:14

@seancorfield: awesome

seancorfield18:08:36

Well, to be clear ~cfg will put the literal value of cfg there, not the "run" version.

jswart18:08:50

yeah, as I said

jswart18:08:59

i fudge’d it a bit

jswart18:08:06

maybe not helpful

seancorfield18:08:18

The literal expression (assoc {:a 1} :b 2) is dropped into the expansion:

boot.user=> (macroexpand-1 '(sample (assoc {:a 1} :b 2) [:a :b] a))
(clojure.core/let [{:keys [a b]} (assoc {:a 1} :b 2)] a)

seancorfield18:08:29

(full macro expansion is confusing in this case)

scott.haleen18:08:02

In my original version why doesn't changing cfg to ~cfg work. I tried that or was at least along that path and got Attempting to call unbound fn: #'clojure.core/unquote

seancorfield18:08:28

Because you did not use the backtick to quote the syntax expression.

seancorfield18:08:45

~ only works inside a backtick’d expression

seancorfield18:08:04

(well, that’s not quite true but close)

seancorfield18:08:58

I find it much easier to write macros using the backtick and then ~-"escaping" the bits I want evaluated.

oahner18:08:04

basically the backtick allows you to return the expression itself instead of the evaluation of that expression

seancorfield19:08:54

In real world Clojure code, macros are rarely needed — we have about 33,000 lines of production Clojure and only 10 macros in all of that.

seancorfield19:08:47

So they’re good to learn and know but are only needed occasionally.

scott.haleen19:08:06

right, I already know I can do what I am trying to do with a function ... it is really syntactic sugar probably a little fragile to just auto let the symbol

scott.haleen19:08:34

but i spent way to long trying to figure it out

vinnyataide20:08:56

Is there a sente channel around?

seancorfield20:08:15

'fraid not. I’ve used Sente in the past so I can try to help (but it’s been a fair while now).