Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clojure clojure.lang.LazySeq errors

I seem to have nasty problem with clojure I/O (or typesystem). The point is that this function, which I expect to consume collection of collections of strings and numbers or strings, and returns dictionary of strings associated with numbers, like

(costlist '( '("Milk" 4) '("Bread" 2) '("Milk")))

giving

{"Milk" 4, "Bread" 2 }

Defined by

(defn costlist [lst]
    ;returns list of costs and appropriate names
          (let  [snds (filter (fn [x] (not (identical? nil x))) (seconds lst))]
          (zipmap 
                   (firsts (take (count snds) (firsts lst))) 
                   (snds  lst))))

when consuming lists of type clojure.lang.PersistentList (which I converted from clojure.lang.LazySeq) throws error message

clojure.lang.LazySeq cannot be cast to clojure.lang.IFn

Which only confuses me, as any of its arguments don't seem to be LazySeq to me.

like image 996
Jakub Bartczuk Avatar asked Jan 26 '26 19:01

Jakub Bartczuk


2 Answers

The problem is that snds is the lazy seq, so (snds lst) throws an error. filter always returns a lazy seq.

Your function also is too complicated. Try to make it simpler:

(defn costlist [lst]
  (zipmap (map first lst)
          (remove nil? (map second lst))))

Now you can do what you want:

(costlist (list '("Milk" 4) '("Bread" 2) '("Milk")))

I'm using list because quote prevents evaluation of an expression (see ToBeReplaced's answer):

=> '( '("Milk" 4) '("Bread" 2) '("Milk"))
((quote ("Milk" 4)) (quote ("Bread" 2)) (quote ("Milk")))

So, you should avoid using quote for building lists.

Your solution also suggests that nil values may occur only at the end of the list. You can easily fix it:

(defn costlist [lst]
  (->>  (filter (comp #{2} count) lst)
        (map vec)
        (into {})))

So, now

(costlist (list '("Milk" 4) '("Milk") '("Bread" 2)))

will work too.

like image 123
Leonid Beschastny Avatar answered Jan 28 '26 17:01

Leonid Beschastny


It's hard to give you a precise answer because you are also using some of your own functions (seconds and firsts). However, you should consider whether you want costlist to be the quoted form you give above.

The above is equivalent to:

((quote ("Milk" 4)) (quote ("Bread" 2)) (quote ("Milk")))

I think you want something more like:

(list '("Milk" 4) '("Bread" 2) '("Milk"))

In your example, the outermost quote is causing the inner quotes to be quoted!

like image 35
ToBeReplaced Avatar answered Jan 28 '26 16:01

ToBeReplaced



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!