1

If I evaluate:

(:content {:foo "bar" :biz "baf" :content ("Happy Happy Joy Joy")}) 

I get:

java.lang.String cannot be cast to clojure.lang.IFn 

If I wanted the "Happy Happy Joy Joy" string, how do I get it?

In my case, the hash-map is what I have to work with... I didn't create the string value inside a list. I understand clojure considers it a function as it's in the calling position.

1
  • You mentioned that you're getting this list as a return value of a library, so where is the code that you are using to put this list in your map? Commented Nov 28, 2017 at 18:46

3 Answers 3

1

If you're defining that list literally in your code, you'll need to "quote" it so that it isn't evaluated as a function:

user=> (:content {:foo "bar" :biz "baf" :content '("Happy Happy Joy Joy")}) ("Happy Happy Joy Joy") 

The only difference here is the ' character before the opening list parenthesis. You could also use the list function.

If you want just the first item in the :content list, you can then use first:

user=> (first (:content {:foo "bar" :biz "baf" :content '("Happy Happy Joy Joy")})) "Happy Happy Joy Joy" 
Sign up to request clarification or add additional context in comments.

3 Comments

Unfortunately, the list is the return value of a library I'm using that I'm not up for sorting out.
I think you might be getting tripped up on the difference between list values printed in a REPL vs. what you can evaluate in the REPL. Lists are printed plainly with parens (...), but if you try to evaluate that verbatim in the REPL it will interpret the parenthesized form as a function call.
Hmm... I'll ponder that. I am trying to get the string within the parens out to use elsewhere in my code as a string.
1

What is typed that has to include quote (') literals to prevent the error message you are getting will be different from what is being returned from a function that does not have to have quotes in it. So just play with it a bit for the real (non REPL) case.

(def x '(:content {:foo "bar" :biz "baf" :content '("Happy Happy Joy Joy")})) (-> x second :content second first) ;;=> "Happy Happy Joy Joy" 

For the real case (-> x second :content first) might be what you want, where of course x is the function call.

If as you say it is only the hash-map (m) you are concerned with then (-> m :content first) should do the trick.

One solution to the mismatch between the REPL and reality is to just use vectors instead of lists:

(def x [:content {:foo "bar" :biz "baf" :content ["Happy Happy Joy Joy"]}]) 

Here (-> x second :content first) will indeed work.

1 Comment

Upvoted because of the recommendation for using a vector instead of a list
0

The other answers did not fully clarify the effect of quote. Please see this code:

(ns tst.demo.core (:use tupelo.test) (:require [tupelo.core :as t] )) ; Note: ; (def data {:foo "bar" :biz "baf" :content ("Happy Happy Joy Joy")}) ; => exception (def data-1 '{:foo "bar" :biz "baf" :content ("Happy Happy Joy Joy")}) (def data-2 {:foo "bar" :biz "baf" :content '("Happy Happy Joy Joy")}) (def data-3 (quote {:foo "bar" :biz "baf" :content ("Happy Happy Joy Joy")})) (dotest (is= data-1 data-2 data-3) (is= "Happy Happy Joy Joy" (first (:content data-1))) (is= "Happy Happy Joy Joy" (first (:content data-2))) (is= "Happy Happy Joy Joy" (first (:content data-3)))) 

So, data-1 shows we can quote the entire expression at the outer level, and data-2 shows we can also quote each list expression (stuff in parens) to suppress the "function call" interpretation of a "list" type in Clojure.

data-3 shows that the single-quote char ' is just short for the special form (quote ...) in Clojure.

Once you get the data literal form right, we see that data-1 and data-2 and data-3 actually result in identical data structures after being processed by the reader.

The last 3 tests show the proper syntax for extracting the string of interest from any of the 3 data structures.


P.S. The testing stuff dotest and is= is from the Tupelo library.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.