Hey, Could you share the code you have now?
On Mon, 19 Jul 2021, 02:18 Jack Park, <jackp...@topicquests.org> wrote: > Cora! > > I made those changes. It is still working to the degree it was, with the > same error > clojure.lang.LazySeq cannot be cast to clojure.lang.IFn > > > which, according to the intertubes, means that my buildAndList returns > (value) instead of value. I tried flatten. No cigar. > > Thanks > Jack > On Sun, Jul 18, 2021 at 5:00 PM Cora Sutton <c...@sutton.me> wrote: > >> Hello again Jack, >> >> On Sun, Jul 18, 2021 at 6:21 PM Jack Park <jackp...@topicquests.org> >> wrote: >> >>> (every? eval members) does not appear to work on a list of functions >>> designed to evaluate to a boolean. >>> >> >> If members is a list of functions then you would do: >> >> (every? (fn [member] (member)) members) >> >> Showing it work here: >> >> (every? (fn [member] (member)) [(constantly true) (constantly true)]) >> ;; => true >> (every? (fn [member] (member)) [(constantly true) (constantly false)]) >> ;; => false >> >> >>> That code is used in a function evaluateAnd >>> >>> Two simple tests >>> (evaluateAnd [true true] --> true >>> (evaluateAnd [true false] --> nil (why not "false" as the every? >>> examples show?) >>> >> >> In Clojure things are either "truthy" or "falsey", and the only "false" >> values are false and nil so returning nil is usually fine. Everything else >> is "truthy". I wouldn't worry about it returning nil since other things >> were broken anyways. >> >> https://clojure.org/guides/learn/flow#_truth >> >> >>> The specific code for building the list of functions is this >>> >>> (def x (atom [])) >>> (let [result (list (ref SimpleTrue) (ref SimpleFalse))] >>> (println "BAL1" result ) >>> (reset! x result) >>> ) >>> (println "BAL2" @x ) >>> >>> (@x) <<<< returns the atom's value >>> >>> And the final println is this >>> >>> BAL2 (#object[clojure.lang.Ref 0x335b5620 {:status :ready, :val >>> #object[ie4clj.Tests$SimpleTrue 0x6eb2384f >>> ie4clj.Tests$SimpleTrue@6eb2384f]}] >>> #object[clojure.lang.Ref 0x3c9c0d96 {:status :ready, :val >>> #object[ie4clj.Tests$SimpleFalse 0x31dadd46 >>> ie4clj.Tests$SimpleFalse@31dadd46]}]) >>> >>> evaluateAnd never saw the result, with this error message >>> >>> clojure.lang.PersistentList cannot be cast to clojure.lang.IFn >>> >> >> Refs are the wrong thing to use here. In fact I'd stay away from atoms >> and refs unless you have multiple threads that need to mutate the same >> values. They're just confusing things now, I think. >> >> >>> >>> The test which fails is this >>> >>> (def result (evaluateAnd (buildAndList) )) <<< fails here >>> (println "bar" result) >>> (result) >>> >>> The googleverse seems to agree that there are extra parens around the >>> value. Google isn't giving me an obvious way to take that value outside of >>> its surrounding parens (bal2 above). >>> Still looking, and hoping that solves the problem. >>> Maybe there's a way to go back to buildAndList and not return the value >>> with parens. >>> >> >> I think a key thing to explain is that in Clojure generally you're not >> making new types of collections. There's this famous-ish saying that >> Clojure holds to pretty well: >> >> "It is better to have 100 functions operate on one data structure than 10 >> functions on 10 data structures." >> - Alan Perlis >> >> Most functions in the Clojure world operate on a handful of basic data >> types and structures. This makes it really easy to chain and combine >> functions to slice and dice data since you don't need to convert between >> types. >> >> I don't think I've ever made a special collection type in Clojure, it's >> not all that common. So I'd suggest that while you're at this point in your >> journey you try to stick to the built-in Clojure collection types and use >> the built-in functions to operate on them. >> >> To give you a little direction, instead of a Person object you could make >> a hashmap like {:first-name "Jack" :last-name "Park"} and pass that >> around. And then you can make a function that operates on that. >> >> (defn full-name >> [person] >> (str (get person :first-name) " " (get person :last-name))) >> >> And then you could expand that to maybe {:first-name "Jack" :last-name >> "Park" :people-talked-to-on-mailing-list ["Cora Sutton"]} and then >> operate on a collection of people like: >> >> (defn people-talked-to-on-mailing-list >> [person all-people] >> (let [people-to-find (set (get person >> :people-talked-to-on-mailing-list))] >> (filter (fn [p] >> (people-to-find (full-name p)) >> all-people)) >> >> (people-talked-to-on-mailing-list jack all-people) >> ;; => {:first-name "Cora" :last-name "Sutton" >> :people-talked-to-on-mailing-list ["Jack Park"]} >> >> >> >>> On Sun, Jul 18, 2021 at 11:23 AM Cora Sutton <c...@sutton.me> wrote: >>> >>>> Hi Jack! >>>> >>>> I could be wrong but I think this could just be: (every? eval members) >>>> >>>> I see a few things here that seem strange to me so I wanted to share a >>>> few points that might be helpful (or might not, let me know either way) for >>>> future code. >>>> >>>> * So typically you don't want to def or defn within another function >>>> call since that will define a new value at the top level. >>>> >>>> (defn foo [] >>>> (def bar 1) >>>> (println (inc bar)) >>>> >>>> (foo) >>>> ;; ^^ calling foo will define bar at the top level >>>> >>>> bar >>>> ;; => 1 >>>> ;; whoops, didn't mean to have that at the top level like that >>>> ;; imagine if two different threads called that in parallel ::grimace:: >>>> >>>> Instead, you usually want to use the let function: >>>> https://clojuredocs.org/clojure.core/let >>>> >>>> So in your code you might use this something like: >>>> >>>> (let [result (atom true)] >>>> ....) >>>> >>>> The error you're seeing is from the (defn result ...) in your code, >>>> you're missing the argument vector [] after result -- so it would look >>>> like (defn result [] (atom true)) -- but you really don't want to defn >>>> like that, I think. >>>> >>>> * To update an atom's value you don't want to assign like that, you >>>> want to use swap! https://clojuredocs.org/clojure.core/swap! >>>> >>>> (swap! f >>>> (fn [cur-val new-val] (and cur-val new-val)) >>>> (eval member)) >>>> >>>> * You probably don't want to use an atom here. Atoms are usually for >>>> data that you intend to have multiple threads accessing. In this case it's >>>> just a value that changes during a single thread's execution here. >>>> >>>> How else could you solve this if not for the very convenient every? >>>> function? There are a bunch of ways! Here are a few, with things written >>>> out pretty explicitly so they're more clear. >>>> >>>> loop/recur: >>>> >>>> (loop [result true >>>> remaining-members members] >>>> (let [member (first remaining-members) >>>> remaining-members (rest members) >>>> new-result (eval member)] >>>> (if new-result >>>> (recur true remaining-members) >>>> false))) >>>> >>>> reduce v1: >>>> >>>> (reduce (fn [result member] >>>> (and result >>>> (eval member))) >>>> true >>>> members) >>>> >>>> reduce v2.0, that will now stop iterating once one of the members evals >>>> to false: >>>> >>>> (reduce (fn [_ member] >>>> (or (eval member) >>>> (reduced false))) >>>> true >>>> members) >>>> >>>> My point with sharing these is that in clojure usually the best way to >>>> solve these problems is to pass new values to the next iteration while >>>> accumulating a result instead of changing a variable on each iteration. Or >>>> to use one of these sweet built-in functions. >>>> >>>> Does that make sense? >>>> >>>> * I thiiiiiiink you might not mean eval but I'm interested in what kind >>>> of problem you're solving! :) >>>> >>>> Hope that helps! >>>> Cora >>>> >>>> On Sun, Jul 18, 2021 at 12:41 PM Jack Park <jackp...@topicquests.org> >>>> wrote: >>>> >>>>> I have a class which treats a sequence as a conjunctive list of >>>>> objects which, when evaluated, return a boolean. It is an attempt to use >>>>> doseq to walk along that list, evaluating each entry, and anding that >>>>> result with boolean atom. It fails. A sketch of the code is this - taken >>>>> from the error message: >>>>> >>>>> inside (defn AndList... >>>>> >>>>> (reify >>>>> ie4clj.api.Inferrable >>>>> (defn evalMembers >>>>> [members] >>>>> (defn result (atom true)) >>>>> (doseq [x members] >>>>> (result = (and result (eval x)))) >>>>> (println (clojure.core/deref result)) >>>>> (result))) - *failed: vector? at: [:fn-tail :arity-1 :params] >>>>> spec: :clojure.core.specs.alpha/param-list* >>>>> >>>>> It could be that my Java background is clouding my use of clojure. Any >>>>> comments will be appreciated. >>>>> >>>>> Thanks >>>>> Jack >>>>> >>>>> -- >>>>> You received this message because you are subscribed to the Google >>>>> Groups "Clojure" group. >>>>> To post to this group, send email to clojure@googlegroups.com >>>>> Note that posts from new members are moderated - please be patient >>>>> with your first post. >>>>> To unsubscribe from this group, send email to >>>>> clojure+unsubscr...@googlegroups.com >>>>> For more options, visit this group at >>>>> http://groups.google.com/group/clojure?hl=en >>>>> --- >>>>> You received this message because you are subscribed to the Google >>>>> Groups "Clojure" group. >>>>> To unsubscribe from this group and stop receiving emails from it, send >>>>> an email to clojure+unsubscr...@googlegroups.com. >>>>> To view this discussion on the web visit >>>>> https://groups.google.com/d/msgid/clojure/f67cfcd0-8e1e-4780-bc00-f6993979e7afn%40googlegroups.com >>>>> <https://groups.google.com/d/msgid/clojure/f67cfcd0-8e1e-4780-bc00-f6993979e7afn%40googlegroups.com?utm_medium=email&utm_source=footer> >>>>> . >>>>> >>>> -- >>>> You received this message because you are subscribed to the Google >>>> Groups "Clojure" group. >>>> To post to this group, send email to clojure@googlegroups.com >>>> Note that posts from new members are moderated - please be patient with >>>> your first post. >>>> To unsubscribe from this group, send email to >>>> clojure+unsubscr...@googlegroups.com >>>> For more options, visit this group at >>>> http://groups.google.com/group/clojure?hl=en >>>> --- >>>> You received this message because you are subscribed to the Google >>>> Groups "Clojure" group. >>>> To unsubscribe from this group and stop receiving emails from it, send >>>> an email to clojure+unsubscr...@googlegroups.com. >>>> To view this discussion on the web visit >>>> https://groups.google.com/d/msgid/clojure/CAMZDCY3BWybiXzgoYaKK958z%2BWqTKf0o_5p9fq-huwutco9onw%40mail.gmail.com >>>> <https://groups.google.com/d/msgid/clojure/CAMZDCY3BWybiXzgoYaKK958z%2BWqTKf0o_5p9fq-huwutco9onw%40mail.gmail.com?utm_medium=email&utm_source=footer> >>>> . >>>> >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "Clojure" group. >>> To post to this group, send email to clojure@googlegroups.com >>> Note that posts from new members are moderated - please be patient with >>> your first post. >>> To unsubscribe from this group, send email to >>> clojure+unsubscr...@googlegroups.com >>> For more options, visit this group at >>> http://groups.google.com/group/clojure?hl=en >>> --- >>> You received this message because you are subscribed to the Google >>> Groups "Clojure" group. >>> To unsubscribe from this group and stop receiving emails from it, send >>> an email to clojure+unsubscr...@googlegroups.com. >>> To view this discussion on the web visit >>> https://groups.google.com/d/msgid/clojure/CAH6s0fwv-rKrWnXji_r4scaX9_jtAi1CRUWGLLNRj7iZtme4UA%40mail.gmail.com >>> <https://groups.google.com/d/msgid/clojure/CAH6s0fwv-rKrWnXji_r4scaX9_jtAi1CRUWGLLNRj7iZtme4UA%40mail.gmail.com?utm_medium=email&utm_source=footer> >>> . >>> >> >> On Sun, Jul 18, 2021 at 6:21 PM Jack Park <jackp...@topicquests.org> >> wrote: >> >>> (every? eval members) does not appear to work on a list of functions >>> designed to evaluate to a boolean. >>> >>> That code is used in a function evaluateAnd >>> >>> Two simple tests >>> (evaluateAnd [true true] --> true >>> (evaluateAnd [true false] --> nil (why not "false" as the every? >>> examples show?) >>> >>> The specific code for building the list of functions is this >>> >>> (def x (atom [])) >>> (let [result (list (ref SimpleTrue) (ref SimpleFalse))] >>> (println "BAL1" result ) >>> (reset! x result) >>> ) >>> (println "BAL2" @x ) >>> >>> (@x) <<<< returns the atom's value >>> >>> And the final println is this >>> >>> BAL2 (#object[clojure.lang.Ref 0x335b5620 {:status :ready, :val >>> #object[ie4clj.Tests$SimpleTrue 0x6eb2384f >>> ie4clj.Tests$SimpleTrue@6eb2384f]}] >>> #object[clojure.lang.Ref 0x3c9c0d96 {:status :ready, :val >>> #object[ie4clj.Tests$SimpleFalse 0x31dadd46 >>> ie4clj.Tests$SimpleFalse@31dadd46]}]) >>> >>> evaluateAnd never saw the result, with this error message >>> >>> clojure.lang.PersistentList cannot be cast to clojure.lang.IFn >>> >>> The test which fails is this >>> >>> (def result (evaluateAnd (buildAndList) )) <<< fails here >>> (println "bar" result) >>> (result) >>> >>> The googleverse seems to agree that there are extra parens around the >>> value. Google isn't giving me an obvious way to take that value outside of >>> its surrounding parens (bal2 above). >>> Still looking, and hoping that solves the problem. >>> Maybe there's a way to go back to buildAndList and not return the value >>> with parens. >>> >>> On Sun, Jul 18, 2021 at 11:23 AM Cora Sutton <c...@sutton.me> wrote: >>> >>>> Hi Jack! >>>> >>>> I could be wrong but I think this could just be: (every? eval members) >>>> >>>> I see a few things here that seem strange to me so I wanted to share a >>>> few points that might be helpful (or might not, let me know either way) for >>>> future code. >>>> >>>> * So typically you don't want to def or defn within another function >>>> call since that will define a new value at the top level. >>>> >>>> (defn foo [] >>>> (def bar 1) >>>> (println (inc bar)) >>>> >>>> (foo) >>>> ;; ^^ calling foo will define bar at the top level >>>> >>>> bar >>>> ;; => 1 >>>> ;; whoops, didn't mean to have that at the top level like that >>>> ;; imagine if two different threads called that in parallel ::grimace:: >>>> >>>> Instead, you usually want to use the let function: >>>> https://clojuredocs.org/clojure.core/let >>>> >>>> So in your code you might use this something like: >>>> >>>> (let [result (atom true)] >>>> ....) >>>> >>>> The error you're seeing is from the (defn result ...) in your code, >>>> you're missing the argument vector [] after result -- so it would look >>>> like (defn result [] (atom true)) -- but you really don't want to defn >>>> like that, I think. >>>> >>>> * To update an atom's value you don't want to assign like that, you >>>> want to use swap! https://clojuredocs.org/clojure.core/swap! >>>> >>>> (swap! f >>>> (fn [cur-val new-val] (and cur-val new-val)) >>>> (eval member)) >>>> >>>> * You probably don't want to use an atom here. Atoms are usually for >>>> data that you intend to have multiple threads accessing. In this case it's >>>> just a value that changes during a single thread's execution here. >>>> >>>> How else could you solve this if not for the very convenient every? >>>> function? There are a bunch of ways! Here are a few, with things written >>>> out pretty explicitly so they're more clear. >>>> >>>> loop/recur: >>>> >>>> (loop [result true >>>> remaining-members members] >>>> (let [member (first remaining-members) >>>> remaining-members (rest members) >>>> new-result (eval member)] >>>> (if new-result >>>> (recur true remaining-members) >>>> false))) >>>> >>>> reduce v1: >>>> >>>> (reduce (fn [result member] >>>> (and result >>>> (eval member))) >>>> true >>>> members) >>>> >>>> reduce v2.0, that will now stop iterating once one of the members evals >>>> to false: >>>> >>>> (reduce (fn [_ member] >>>> (or (eval member) >>>> (reduced false))) >>>> true >>>> members) >>>> >>>> My point with sharing these is that in clojure usually the best way to >>>> solve these problems is to pass new values to the next iteration while >>>> accumulating a result instead of changing a variable on each iteration. Or >>>> to use one of these sweet built-in functions. >>>> >>>> Does that make sense? >>>> >>>> * I thiiiiiiink you might not mean eval but I'm interested in what kind >>>> of problem you're solving! :) >>>> >>>> Hope that helps! >>>> Cora >>>> >>>> On Sun, Jul 18, 2021 at 12:41 PM Jack Park <jackp...@topicquests.org> >>>> wrote: >>>> >>>>> I have a class which treats a sequence as a conjunctive list of >>>>> objects which, when evaluated, return a boolean. It is an attempt to use >>>>> doseq to walk along that list, evaluating each entry, and anding that >>>>> result with boolean atom. It fails. A sketch of the code is this - taken >>>>> from the error message: >>>>> >>>>> inside (defn AndList... >>>>> >>>>> (reify >>>>> ie4clj.api.Inferrable >>>>> (defn evalMembers >>>>> [members] >>>>> (defn result (atom true)) >>>>> (doseq [x members] >>>>> (result = (and result (eval x)))) >>>>> (println (clojure.core/deref result)) >>>>> (result))) - *failed: vector? at: [:fn-tail :arity-1 :params] >>>>> spec: :clojure.core.specs.alpha/param-list* >>>>> >>>>> It could be that my Java background is clouding my use of clojure. Any >>>>> comments will be appreciated. >>>>> >>>>> Thanks >>>>> Jack >>>>> >>>>> -- >>>>> You received this message because you are subscribed to the Google >>>>> Groups "Clojure" group. >>>>> To post to this group, send email to clojure@googlegroups.com >>>>> Note that posts from new members are moderated - please be patient >>>>> with your first post. >>>>> To unsubscribe from this group, send email to >>>>> clojure+unsubscr...@googlegroups.com >>>>> For more options, visit this group at >>>>> http://groups.google.com/group/clojure?hl=en >>>>> --- >>>>> You received this message because you are subscribed to the Google >>>>> Groups "Clojure" group. >>>>> To unsubscribe from this group and stop receiving emails from it, send >>>>> an email to clojure+unsubscr...@googlegroups.com. >>>>> To view this discussion on the web visit >>>>> https://groups.google.com/d/msgid/clojure/f67cfcd0-8e1e-4780-bc00-f6993979e7afn%40googlegroups.com >>>>> <https://groups.google.com/d/msgid/clojure/f67cfcd0-8e1e-4780-bc00-f6993979e7afn%40googlegroups.com?utm_medium=email&utm_source=footer> >>>>> . >>>>> >>>> -- >>>> You received this message because you are subscribed to the Google >>>> Groups "Clojure" group. >>>> To post to this group, send email to clojure@googlegroups.com >>>> Note that posts from new members are moderated - please be patient with >>>> your first post. >>>> To unsubscribe from this group, send email to >>>> clojure+unsubscr...@googlegroups.com >>>> For more options, visit this group at >>>> http://groups.google.com/group/clojure?hl=en >>>> --- >>>> You received this message because you are subscribed to the Google >>>> Groups "Clojure" group. >>>> To unsubscribe from this group and stop receiving emails from it, send >>>> an email to clojure+unsubscr...@googlegroups.com. >>>> To view this discussion on the web visit >>>> https://groups.google.com/d/msgid/clojure/CAMZDCY3BWybiXzgoYaKK958z%2BWqTKf0o_5p9fq-huwutco9onw%40mail.gmail.com >>>> <https://groups.google.com/d/msgid/clojure/CAMZDCY3BWybiXzgoYaKK958z%2BWqTKf0o_5p9fq-huwutco9onw%40mail.gmail.com?utm_medium=email&utm_source=footer> >>>> . >>>> >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "Clojure" group. >>> To post to this group, send email to clojure@googlegroups.com >>> Note that posts from new members are moderated - please be patient with >>> your first post. >>> To unsubscribe from this group, send email to >>> clojure+unsubscr...@googlegroups.com >>> For more options, visit this group at >>> http://groups.google.com/group/clojure?hl=en >>> --- >>> You received this message because you are subscribed to the Google >>> Groups "Clojure" group. >>> To unsubscribe from this group and stop receiving emails from it, send >>> an email to clojure+unsubscr...@googlegroups.com. >>> To view this discussion on the web visit >>> https://groups.google.com/d/msgid/clojure/CAH6s0fwv-rKrWnXji_r4scaX9_jtAi1CRUWGLLNRj7iZtme4UA%40mail.gmail.com >>> <https://groups.google.com/d/msgid/clojure/CAH6s0fwv-rKrWnXji_r4scaX9_jtAi1CRUWGLLNRj7iZtme4UA%40mail.gmail.com?utm_medium=email&utm_source=footer> >>> . >>> >> -- >> You received this message because you are subscribed to the Google >> Groups "Clojure" group. >> To post to this group, send email to clojure@googlegroups.com >> Note that posts from new members are moderated - please be patient with >> your first post. >> To unsubscribe from this group, send email to >> clojure+unsubscr...@googlegroups.com >> For more options, visit this group at >> http://groups.google.com/group/clojure?hl=en >> --- >> You received this message because you are subscribed to the Google Groups >> "Clojure" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to clojure+unsubscr...@googlegroups.com. >> To view this discussion on the web visit >> https://groups.google.com/d/msgid/clojure/CAMZDCY1wvo_N32dKV1g-9cZAmTbZUO5bRAXDGkdHm-7_VD_-Rg%40mail.gmail.com >> <https://groups.google.com/d/msgid/clojure/CAMZDCY1wvo_N32dKV1g-9cZAmTbZUO5bRAXDGkdHm-7_VD_-Rg%40mail.gmail.com?utm_medium=email&utm_source=footer> >> . >> > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with > your first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > --- > You received this message because you are subscribed to the Google Groups > "Clojure" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to clojure+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/clojure/CAH6s0fzjBE_F8%2BZ0fR69_1%3DWGs%3Duy5oJ3aGouYAmeQK9vRx6DA%40mail.gmail.com > <https://groups.google.com/d/msgid/clojure/CAH6s0fzjBE_F8%2BZ0fR69_1%3DWGs%3Duy5oJ3aGouYAmeQK9vRx6DA%40mail.gmail.com?utm_medium=email&utm_source=footer> > . > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/clojure/CADBYUPta6ZJf1gWCFq0L236aOZm077YeRrVqOxnfov%2Bk%2BjcZuQ%40mail.gmail.com.