This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-08-17
Channels
- # beginners (47)
- # boot (1)
- # calva (18)
- # cider (16)
- # cljs-dev (6)
- # cljsrn (14)
- # clojure (46)
- # clojure-dev (6)
- # clojure-italy (3)
- # clojure-sweden (2)
- # clojure-uk (1)
- # clojurescript (21)
- # css (1)
- # data-science (1)
- # emacs (2)
- # figwheel-main (2)
- # graalvm (11)
- # leiningen (3)
- # nrepl (19)
- # off-topic (1)
- # pathom (4)
- # re-frame (17)
- # reagent (4)
- # shadow-cljs (49)
Hi everyone,
I have a weird question. I was writing a macro and encountered this :
('flsakjf 12)
=> nil
flsakjf
is some symbol
why does it return nil
?
symbols are similar to keywords in Clojure, in that when you put them in first position like a function call, they "look themselves up" in a collection like a map, or a set, given as an argument.
e.g. (:foo {:foo 1 :bar 2})
returns 1
Looking up keys in non-map things returns nil
hi, trying to build a currency converter in re-frame so far it works in one direction (eur->yen) if I enter stuff in the euro field, I would like to have it both ways though, i.e. if I enter anything in the euro field it shows me the amount in yen and vice versa one direction makes sense to me, but I get confused about what :value and :on-change should be when thinking about doing it in both ways...
Making two inputs intertwined like this is quite difficult and making it work 100% across all possible browsers may require a lot of work. If this is a real project I suggest that you output the result of the conversion to a label rather than in another input field. If this is just for fun then I'd suggest storing both text value and "calculated numeric value" in to the app-db and overriding the input value with a calculated value only when the other input has sane values. Maybe something like this:
[:input
{:value (or eur-val eur-input)
:on-change #(re-frame/dispatch [::calc-yen (-> % .-target .-value)])}]
(re-frame/reg-event-db
::calc-yen
(fn [db [_ eur-input]]
(let [eur-val (parse-num eur-input)]
(-> db
(assoc :eur-input eur-input)
(assoc :yen-val (when eur-val (* eur-val eur->yen-rate)))))))
And similar input and event for the other direction(first '(+ 1 2))
returns the symbol +
@shabbir.r.bhojani good question! the reason is that (first '(+ 1 2))
returns the symbol +
, not the function. since symbols are functions in Clojure (just like keywords), you are calling (+ 3 4)
with +
as a symbol, which is meant for associative lookups (compare (= ('+ {'+ 1}) 1)
), where the second argument is the value to return if the mapping is not found
What needs to be put in (first '(? 1 2))
to make it return the function instead of the symbol?
@U04VDQDDY I just got around to trying this and ((first '(~+ 1 3)) 2 4)
produced the error `Execution error (ClassCastException) at clojure-test-project.core/eval1600 (form-init15410744857529963710.clj:1).
class clojure.lang.PersistentList cannot be cast to class clojure.lang.IFn (clojure.lang.PersistentList and clojure.lang.IFn are in unnamed module of loader 'app')`. What did I do wrong?
The quote should be a "backtick", called "syntax-quote".:
((first `(~+ 1 3)) 2 4)
Which when called in function position tries to look itself up in 3
with the default 4
, hence returning 4
keywords and symbols when used as functions try to look themselves up in the first argument return nil if there is no second argument, and the second argument otherwise.
so when 3
is regarded as a map, which it clearly isn't, the behavior is to just return nil, instead of throwing some kind of typing exception?
Try these in your REPL:
user=> (:a {:a 42})
42
user=> (:a {:b 42})
nil
user=> (:a {:b 42} 100)
100
Same with symbolsYes. Many other things in Clojure just return nil
instead of throwing.
Here's the relevant code for keywords: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Keyword.java#L136 this delegates to RT.get which in this case uses RT.getFrom which returns null instead of throwing.
Expects the 3
to be a map and looks up the key +
in it.
What needs to be put in (first '(? 1 2))
to make it return the function instead of the symbol?
What does it mean when functions or other things are surrounded by *
? as in *print-readably*
in
(defn print
"Prints the object(s) to the output stream that is the current value
of *out*. print and println produce output for human consumption."
{:added "1.0"
:static true}
[& more]
(binding [*print-readably* nil]
(apply pr more)))
It is a naming convention that the var is 'dynamic', meaning it can be dynamically bound per thread using binding
.
There is also a compiler warning if you name something like that, but do not make it dynamic, so in this case it is a slightly more enshrined naming convention than most.
A bit more info on what a dynamic Var means here: https://clojure.org/reference/vars
Thank you @andy.fingerhut
hmm this is weird:
{:type java.lang.IllegalArgumentException
:message No matching method withRegion found taking 1 args for class com.amazonaws.services.s3.AmazonS3ClientBuilder
:at [clojure.lang.Reflector invokeMatchingMethod Reflector.java 154]}
But two of those methods exist: https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/client/builder/AwsClientBuilder.html#withRegion-java.lang.String-not a solution to your problem (sorry!), but if youโre doing AWS with Clojure you may want to check out https://github.com/cognitect-labs/aws-api!
but it doesn't do a specific thing i need, which is creating pre-signed S3 urls: https://github.com/cognitect-labs/aws-api/issues/5
I'm trying to use cljs-ajax
to perform a request from my re-frame event to my localhost web server. However, it seems like the uri
parameter cannot specify a port. only the endpoint.
(POST
""
{:format :json
:params {:value (:value db)}
:handler #(re-frame/dispatch [::update-database %])
:error-handler #(re-frame/dispatch [::error-handler %])})
this example returns status 0. Seems like my endpoint cannot be reach. If I change the uri
to /save
it calls some html page. I think I have to make a previous setup to let the library knows the whole url address of my backend service. But I could not find where I specify that