This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-12-31
Channels
- # adventofcode (4)
- # ai (1)
- # announcements (13)
- # babashka (1)
- # beginners (42)
- # calva (15)
- # chlorine-clover (28)
- # cider (7)
- # cljsrn (1)
- # clojure (3)
- # clojure-china (1)
- # clojure-dev (4)
- # clojure-europe (7)
- # clojure-losangeles (1)
- # clojure-nl (3)
- # clojure-nlp (2)
- # clojure-sweden (12)
- # clojure-uk (2)
- # clojurescript (30)
- # code-reviews (36)
- # core-async (5)
- # cursive (10)
- # data-science (1)
- # datalevin (1)
- # fulcro (11)
- # introduce-yourself (1)
- # lsp (10)
- # malli (7)
- # minecraft (24)
- # missionary (10)
- # monads (6)
- # nrepl (4)
- # off-topic (11)
- # portal (4)
- # rdf (1)
- # reagent (3)
- # releases (4)
- # shadow-cljs (4)
- # spacemacs (4)
(.then (.symbol (:contract @state-data)) #(js/console.log %)) ;this works fine
(.then (.balanceOf (:contract @state-data) addr1) #(js/console.log %)) ;this gives the error
WARNING in app/cards/ethers.cljs
52 | [:button {:on-click #(log (:contract @state-data))} "Log: contract from state data"] [:br]
53 | [:button {:on-click (fn [] (.then (.decimals (:contract @state-data)) #(js/console.log %)))} "Log: Erc20 decimals"] [:br]
54 | [:button {:on-click (fn [] (.then (.symbol (:contract @state-data)) #(js/console.log %)))} "Log: Erc20 symbol"] [:br]
55 | [:button {:on-click (fn [] (.then (.balanceOf (:contract @state-data) addr1) #(js/console.log %)))} "Log: Erc20 Balance"] [:br]
----------------------------------------------^---------------------------------
Cannot infer target type in expression (. (:contract (clojure.core/deref state-data)) balanceOf addr1)
and here is the whole code: https://codeshare.io/eVmLg7
instead of this dot notation (.balanceOf (:contract @state-data) ...)
I started to use (aget (:contract @state-data) "balanceOf")
now it's working. but still I would like to know what does *Cannot infer target type in expression*
means
@UJ35GLZU7 The fact that aget
works but trying to "call" balanceOf
does not, suggests that it's a field, not a method. Maybe try (.-balanceOf (:contract @state-data))
and see if that works?
(which is a bit odd, based on my reading of that code you shared, but I don't do much cljs and I know nothing about cryptocurrency -- and generally avoid it and the people who work with it 🙂 )
The error message says that the ClojureScript cannot determine the type of the expression well enough to be able to compile the dot-expression -- which, as I say, seems odd since those other invocations all seem to work on (:contract @state-data)
-- and, based on the source of the cljs compiler, seem most likely to be triggered when you try to access fields of Object
or of non-JS data where the field is not resolvable against an existing extern(? whatever that means in cljs/js).
if you are using shadow-cljs this section has information for you: https://shadow-cljs.github.io/docs/UsersGuide.html#infer-externs
(.-balanceOf (:contract @state-data))
caused exact same error. after I read infer-externs
I understood whats going on finally 🙂 so first code I had works as expected but when shadow-cljs compiles it didn't recognize it as a method. thank you for your time seancornfield, dpsutton 🙏
@UJ35GLZU7 Good to know! We've both learned things from this thread!
here is a scheme macro for thread-last
(define-syntax ~>>
(syntax-rules ()
((_ value)
value)
((_ value (subr args ...) other-clauses ...)
(~>> (subr args ... value) other-clauses ...))
((_ value subr other-clauses ...)
(~>> (subr value) other-clauses ...))))
and I want to write a thread-last
macro myself, reference this scheme macro, how should I write it ??(defmacro ->>
"Threads the expr through the forms. Inserts x as the
last item in the first form, making a list of it if it is not a
list already. If there are more forms, inserts the first form as the
last item in second form, etc."
{:added "1.1"}
[x & forms]
(loop [x x, forms forms]
(if forms
(let [form (first forms)
threaded (if (seq? form)
(with-meta `(~(first form) ~@(next form) ~x) (meta form))
(list form x))]
(recur threaded (next forms)))
x)))
this is the definition in core.cljI experimented with implementing scheme like macros with meander https://gist.github.com/bsless/ef07a7ab21a614720a36c698b5121d6e
eh, is this ok ?
(defmacro thread-last
([value] value)
([value next-expr & other]
(if (symbol? next-expr)
`(thread-last (~next-expr ~value) ~@other)
(let [[subr & args] next-expr]
`(thread-last (~subr ~@args ~value) ~@other)))))
I have test it with
(assert (=
(->> (range)
(map #(* % %))
(filter even?)
(take 10)
(reduce +))
(thread-last (range)
(map #(* % %))
(filter even?)
(take 10)
(reduce +)))
"Fuck You"
)
(assert (=
(->> (range)
(filter even?)
(take 5))
(thread-last (range)
(filter even?)
(take 5)))
"Fuck You")
it works fineI have a problem while writing macro, in expr
(defmacro thread-last
([value] value)
([value next-expr & other]
(if (symbol? next-expr)
`(thread-last (~next-expr ~value) ~@other)
(let [[subr & args] next-expr]
`(thread-last (~subr ~@args ~value) ~@other)))))
does the ~next-expr
mean replace the ~next-expr
with the s-expression of next-expr
, or evaluate the next-expr
?syntax quote is quoting (so read but not evaluate). - is unquote so will evaluate the unquoted form
Hm. I may actually need clarification on this as well. If next-expr was (+ 1 2), would 3 be inserted, or would we insert (+ 1 2) and then evaluate the output expression after macroexpansion was complete? (e.g. would (defmacro tester [x] `(quote ~x)) give out (+ 1 2) or 3?)
It would be 3 in this case
In the first question that is
In the second, it would be (+ 1 2)
Because of the quote
Ah, ok, so internally it's first inserting the S-exp, and then it evals the resulting expression like any other code, but we only actually see the end result after the eval. Same as Common Lisp, then.
There is no “inserting”, unquote just turns on normal eval
Yes, I was referring to the whole situation of unquoting an input to a macro in a syntax quoted form inside the macro. In non-macro code I assume `(quote ~(+ 1 2)) would give us (quote 3) as a result (and my REPL agrees)
Macros are not special - they're just functions that get uneavluated forms
You can use syntax quote at your repl or anywhere else
@U064X3EF3 but how do you explain this code
(assert (=
(->> (range)
(map #(* % %))
(filter even?)
(take 10)
(reduce +))
(thread-last (range)
(map #(* % %))
(filter even?)
(take 10)
(reduce +)))
"Fuck You"
)
if is evaluate, the (range)
should be a infinite sequence, and clojure will calculate forever, right ?If you haven't found it yet, macroexpand-1
is useful for checking what a macro expands to
->> is not evaluating that first form, just emitting it unevaluated
In yours, this is value, and you also don't evaluate it
Or I guess you do in the latter arity
Although range is lazy so it's not realized