This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-02-02
Channels
- # beginners (72)
- # boot (68)
- # cider (51)
- # clara (20)
- # cljs-dev (44)
- # cljsrn (7)
- # clojure (168)
- # clojure-brasil (1)
- # clojure-dev (48)
- # clojure-greece (2)
- # clojure-nl (29)
- # clojure-russia (4)
- # clojure-spec (19)
- # clojure-uk (28)
- # clojurescript (2)
- # cursive (9)
- # datascript (1)
- # datomic (105)
- # dirac (1)
- # docker (2)
- # duct (11)
- # emacs (19)
- # events (1)
- # figwheel (1)
- # fulcro (23)
- # garden (4)
- # graphql (5)
- # hoplon (46)
- # jobs (5)
- # juxt (13)
- # leiningen (6)
- # lumo (12)
- # off-topic (29)
- # parinfer (5)
- # re-frame (7)
- # reagent (6)
- # ring (2)
- # sql (5)
- # yada (6)
I have a java project with some clojure interop, and I’m having trouble converting the maps passed back from my clojure code into java objects. The error I’m getting is clojure.lang.PersistentArrayMap cannot be cast to MyObject
Also is there a separate slack channel or community for this kind of thing? Or is this the correct place to ask questions on Java projects with Clojure interop
Here’s fine!
It looks like you’re trying to pass a Clojure map where a MyObject is expected
If you really need a MyObject, you’ll need to construct it and invoke setters using data from the map. Constructor looks like (MyObject.)
and doto
is pretty useful for calling a bunch of setters
Like this? (MyObject. my-map)
@alexmiller
Depends - does the MyObject constructor take a Map?
Could I do something like (List<MyObject>. (data :id my-map) (data :title my-map) (data :description my-map))
?
@Will almost like that - <MyObject>
is something only the java compiler uses, it means nothing in clojure
and List is an interface - you can use list
to make something that implements List though - and so does `map
eg. (map #(data % my-map) [:id :title :description])
returns a List containing the data you want in the right order
I don't know what that data
function is - you usually would use the keyword directly with the map to look it up
Hi, how can I "extract a list" like (a b c)
into a b c
? I need it because i have an argument opts on a function, and I want to pass it to another function as is:
(defn function-b
[& opts]
(do-something))
(defn function-a
[a b & opts]
(function-b opts))
(apply function-b opts)
might work
If function-b looks like something like this, then can I still use apply?
(defn function-b
[b & opts]
(do-something))
(defn function-a
[a b & opts]
(apply function-b b opts))
or maybe unquote splicing? ~@
@hawari.rahman17 in that case maybe you'd want to cons
b
and opts
in the (apply function-b ...)
expression?
Apply is var arg and never needs cons, (apply f a [b c])
is the same as (apply f [a b c])
I'll try those solutions that you provided and look which one suits best. Thank you @michael740!
:thumbsup:
i suspect there's a lot going on in syntax quoting. it might be overkill
Yep, I think apply
does it the best for me, less "alien" character to read, thanks again @michael740
You don't need unquote splicing or cons, as I described in a thread above
What is the most idiomatic way if there are two defmethod
that has exactly the same implementation?
(defmulti multifn :type)
(defmethod multifn "type a"
[item]
(function-a item))
(defmethod multifn "type b"
[item]
(function-a item))
@hawari.rahman17 What's "type a"/"type b"?
just a string, the multifn will be called like this (multifn {:type "type a" :other-key "other value"})
basically what I want to do is processing a list of items based on their :type
, but some of this types shares identical characteristic
@hawari.rahman17 So since they're strings you can't use derive
, hence my question. You just have to call a fn like you do in your example, there is no build in way to bundle these
I see, so in that case there's no way but to define it into different defmethod
right?
Ah so if it's a keyword, I can make some kind of parent-child relationship, is it?
(Just got back from reading docs on derive
)
If my data looks like this
({:description Entry, :amount -730.74M, :date #inst "2018-01-26T07:00:00.000000000-00:00"}{:description food, :amount -30M, :date #inst "2018-01-27T07:00:00.000000000-00:00"})
How would I loop over each one and create a list from it? Or is there a different approach I should take?a list of what?
Is there a way to convert it to my java object in clojure and pass it back? Or should I try to convert the map on the java side
I can call my constructor like this (Transaction. (:description data) (:amount data) (:date data))
Which can convert to a single object but how do i loop over the list of clojure maps and convert it to a list of java Transaction objects?
@josmith2016 try (map (comp (partial apply #(Transaction. %1 %2 %3)) (juxt :description :amount :date)) data)
not sure why being so complicated
am i missing something
@joelsanchez no, i think i am the one who missed something. i blame fatigue 😁
@josmith2016 use his
If I have a BigDecimal I want to convert to a BigInteger, would I do something like this? (BigInteger. (BigDecimal/toBigIntegerExact (BigDecimal/scaleByPowerOfTen decimal 2)))
actually there's a biginteger
function @josmith2016
Ok that worked thanks @sundarj, my BigDecimal that is set to 730.34
turns into 730
, Is there a way to retain the value on the right of the decimal point, and turn it into 73034
?
+user=> 1.03M
1.03M
+user=> (BigDecimal. 1.03)
1.0300000000000000266453525910037569701671600341796875M
both of those create BigDecimal rather than bigint / biginteger
if you want exactly two digits to the right of the decimal point at all times, the simplest thing is to use x*100
You’re right @noisesmith I should have thought of that, thanks!