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.
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