Re: Strange Vector failure

2021-07-19 Thread Tanya Moldovan
I think you forgot to link it, but I think I found it

 :)

You don't really need line 11. It will run without it.
Don't use defs inside a function. Use let. Always.
Don't use atoms inside a function. In fact, unless you need some shared
state between processes - just don't use them. Same goes for refs.

(I changed the name of function to be more clojure like (ie: SimpleTrue ->
simple-true and so on)

It's not clear what you want to do with the SimpleTrue, SimpleFalse. Do you
need it to be a list? Or a boolean value?
If boolean - then do this:

(defn simple-true [] true)
(defn simple-false [] false)
(defn not-simple-true [] (not simple-true))
(defn not-simple-false [] (not simple-false))

If you need a list, just do:

(defn simple-true [] '(true)) ;<--- notice the quote before the parenthesis
(defn simple-true [] [true]) ; or just use vectors

In clojure, if you need lists, always put a quote before the parenthesis,
otherwise it will be interpreted as a function.
So (true) will throw an exception, but '(true) will work:

ie4clj.core=> (true)
Execution error (ClassCastException) at ie4clj.core/eval1490
(form-init3173779095201492457.clj:1).
java.lang.Boolean cannot be cast to clojure.lang.IFn

ie4clj.core=> '(true)
(true)


Another place where it will throw an error is line 41

(@x)

Do you want to return the result as a list or just return the result?
If you want a list you do this:

'(@x) ; <-- notice the quote
[@x] ; or use vector

If you want to return a result just do this:

@x

Also, don't use atoms )

On line 37 you are assigning the result of let to that atom, BAL2 will be
the same as BAL1, so you can just skip it and return the result from let.
Like this:

(defn build-and-list []
  (println "BAL")
  (let [result (flatten (list simple-true simple-false))] ;<--
actually not sure if this is the thing you want here. This will be a
list of functions.
(println "BAL1" result )
result))


Another thing is with the test function. Don't use defs there, just use a
let clause, like this:

(defn first-test []
  (println "First Test")
  (let [x (evaluate-and [(constantly true) (constantly true)])
y (evaluate-and [(constantly true) (constantly false)])
l (build-and-list)
result (evaluate-and l)]
(println "A" x)
(println "B" y)
(println "C" l)
(println "bar" result)
result))

And here is the evaluate-and function with let instead of def.

(defn evaluate-and
  [members]
  (println "EA" members)
  (let [result (every?  (fn [member] (member)) members)]
(println "EA+" result)
result)) ;<-- I added this line, as (println) one return nil, and
I thought you needed the result true or false (?)

This compiles and runs for me (unless I forgot something). (if it doesn't
just tell me, I'll commit the code so you can play with it)


On Mon, 19 Jul 2021 at 05:16, Jack Park  wrote:

> Cora, I agree. A gist was just submitted here. I'm in the clojurians
> slack; I have a weak memory of being there once before. But, happy to put a
> summary of this in #beginners as you suggest.
>
>
>
> On Sun, Jul 18, 2021 at 8:13 PM Cora Sutton  wrote:
>
>> Code would be helpful for sure! Also, it might be time to move this to
>> Clojurians Slack http://clojurians.net/
>>
>> There is a #beginners channel where volunteers are available to help in a
>> more synchronous fashion which might help get to the bottom of this a bit
>> quicker.
>>
>> On Sun, Jul 18, 2021 at 10:00 PM Tanya Moldovan 
>> wrote:
>>
>>> Hey,
>>>
>>> Could you share the code you have now?
>>>
>>> On Mon, 19 Jul 2021, 02:18 Jack Park,  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  wrote:

> Hello again Jack,
>
> On Sun, Jul 18, 2021 at 6:21 PM Jack Park 
> 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 

Re: clojure is supposed to be 'code is data' yet I can't add to the end of a list?

2021-07-19 Thread SideStep
Thanks James, will for something like it I think. Still, would be nice if 
code was manipulatable with ease - clojure style. Code-is-data such a 
powerful idea. 

On Sunday, July 18, 2021 at 7:43:20 PM UTC+2 James Reeves wrote:

> "Code is data" comes up in Clojure less than newcomers might expect. As a 
> rule of thumb, it should be the last tool you reach for, as it's easier to 
> work with data structures that have a simpler and more constrained syntax.
>
> It's often hard to give good advice when context is lacking, but if you 
> have a grid, and want to supply a sequence of instructions to modify it, 
> and you want to inspect and manipulate those instructions, then I'd suggest 
> something like:
>
> (transform
>  (grid 10 10)
>  [[:toggle 2 3 4 5]
>   [:off 2 3 4 5]
>   [:on 2 3 4 5]])
>
> On Sun, 18 Jul 2021, at 5:40 PM, SideStep wrote:
>
> Thanks Tania! The point I'm making is that list (data structure for 
> evaluatable data/code) is not easily manipulatable with code in clojure. So 
> much for 'code-is-data'... 
> Thanks for the suggestion.
> In regards to rethinking it: it is supposed to be commands coming-in that 
> sets parts of the grid with on/off/toggle... I want to append those 
> commands (code) as data to the representation of a grid and evaluate the 
> list of commands to get the final state of the grid.
> Trying to embrace this code-is-data thing here.
> On Saturday, July 17, 2021 at 9:21:29 PM UTC+2 tanya.m...@gmail.com wrote:
>
>
> Hi,
>
> conj  adds at the end of a 
> vector, but at the beginning of a list. It is how it is implemented. I 
> think this 
> 
>  and 
> this  
> sums 
> it up why.
>
> You could achieve what you want by using concat 
>  (note this returns a 
> LazySeq):
>
> user=> (concat grid '((off 1 2 3 6)))
> (-> (grid 10 10) (toggle 2 3 4 5) (off 2 3 4 5) (on 2 3 4 5) (off 1 2 3 6))
>
> Though I'm not exactly sure what is the end goal of this but I'd rethink 
> the way it is done. 
>
>
>
>
> On Sat, 17 Jul 2021 at 14:24, SideStep  wrote:
>
>
> 
>
> I have a representation of a matrix in grid.clj file:
>
> (-> (grid 10 10)
> (toggle 2 3 4 5)
> (off 2 3 4 5)
> (on 2 3 4 5))
>
> It's a list of functionts, first one initializes a grid, others modify it.
> Clojures' 'code is data' supposed to make it easy for me to modify that 
> representation by adding an instrucion at the *end* of collection. List 
> is an ordered collection right? Order matters. How do I add an instruction 
> to the end of the list then?
> Something like this:
>
> (def grid (read-string (slurp "grid.clj")))
> (conj grid '(off 1 2 3 6))
>
> Yet I can't add to the end of the list, which is a data structure that is 
> evaluatable as code. How is it 'code as data' if I can't add to the end of 
> the ordered collection that is meant for code (as data)?
>
>
> -- 
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clo...@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+u...@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+u...@googlegroups.com.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/clojure/efd72013-a85e-46e8-b9db-10dde1a8a235n%40googlegroups.com
>  
> 
> .
>
>
> -- 
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clo...@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+u...@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+u...@googlegroups.com.
>
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/clojure/6cf09a4d-aedd-42e4-860c-35efcb68ed50n%40googlegroups.com
>  
> 

Re: clojure is supposed to be 'code is data' yet I can't add to the end of a list?

2021-07-19 Thread James Reeves
Don't get be wrong: Clojure can manipulate lists easily. You can append items 
to a list with (concat xs '(5)) or use syntax quoting `(~@xs 5). You just can't 
use conj specifically, as that function has a particular use case.

The problem with manipulating code is that code is complex. The same 
functionality can be written in many different ways, and it's hard to account 
for every possibility, so any abstraction that treats code as data tends to be 
either be leaky or very simple (or occasionally, very complex).

Clojure *can* treat code as data, but it's one of those tools that has a narrow 
use case. Clojure's philosophy more revolves around *replacing* code with pure 
data, where possible. Reading is safer and more predictable than evaluating, 
and evaluating within narrow constraints is often better than reaching for the 
more general purpose eval.

On Mon, 19 Jul 2021, at 2:00 PM, SideStep wrote:
> Thanks James, will for something like it I think. Still, would be nice if 
> code was manipulatable with ease - clojure style. Code-is-data such a 
> powerful idea. 
> 
> On Sunday, July 18, 2021 at 7:43:20 PM UTC+2 James Reeves wrote:
>> __
>> "Code is data" comes up in Clojure less than newcomers might expect. As a 
>> rule of thumb, it should be the last tool you reach for, as it's easier to 
>> work with data structures that have a simpler and more constrained syntax.
>> 
>> It's often hard to give good advice when context is lacking, but if you have 
>> a grid, and want to supply a sequence of instructions to modify it, and you 
>> want to inspect and manipulate those instructions, then I'd suggest 
>> something like:
>> 
>> (transform
>>  (grid 10 10)
>>  [[:toggle 2 3 4 5]
>>   [:off 2 3 4 5]
>>   [:on 2 3 4 5]])
>> 
>> On Sun, 18 Jul 2021, at 5:40 PM, SideStep wrote:
>>> Thanks Tania! The point I'm making is that list (data structure for 
>>> evaluatable data/code) is not easily manipulatable with code in clojure. So 
>>> much for 'code-is-data'... 
>>> Thanks for the suggestion.
>>> In regards to rethinking it: it is supposed to be commands coming-in that 
>>> sets parts of the grid with on/off/toggle... I want to append those 
>>> commands (code) as data to the representation of a grid and evaluate the 
>>> list of commands to get the final state of the grid.
>>> Trying to embrace this code-is-data thing here.
>>> On Saturday, July 17, 2021 at 9:21:29 PM UTC+2 tanya.m...@gmail.com wrote:
 
 Hi,
 
 conj  adds at the end of a 
 vector, but at the beginning of a list. It is how it is implemented. I 
 think this 
 
  and this 
  sums 
 it up why.
 
 You could achieve what you want by using concat 
  (note this returns a 
 LazySeq):
 `user=> (concat grid '((off 1 2 3 6)))
 (-> (grid 10 10) (toggle 2 3 4 5) (off 2 3 4 5) (on 2 3 4 5) (off 1 2 3 
 6))`
 Though I'm not exactly sure what is the end goal of this but I'd rethink 
 the way it is done. 
 
 
 
 
 On Sat, 17 Jul 2021 at 14:24, SideStep  wrote:
> 
>  
> 
> I have a representation of a matrix in grid.clj file:
> 
> `(-> (grid 10 10)
> (toggle 2 3 4 5)
> (off 2 3 4 5)
> (on 2 3 4 5))
`
> 
> 
> It's a list of functionts, first one initializes a grid, others modify it.
> Clojures' 'code is data' supposed to make it easy for me to modify that 
> representation by adding an instrucion at the *end* of collection. List 
> is an ordered collection right? Order matters. How do I add an 
> instruction to the end of the list then?
> Something like this:
> 
> 
> `(def grid (read-string (slurp "grid.clj")))
> (conj grid '(off 1 2 3 6))
`
> Yet I can't add to the end of the list, which is a data structure that is 
> evaluatable as code. How is it 'code as data' if I can't add to the end 
> of the ordered collection that is meant for code (as data)?
> 
> 
> 
> -- 
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clo...@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+u...@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+u...@

Re: Strange Vector failure

2021-07-19 Thread Jack Park
So, that did the trick. No more defs or atoms, a few tweeks, and it ran.
naming conventions brought into line with clojure.

Next step is to prove it can return a false, and then continue adding
features.

Many thanks to all, and particularly to Tanya for reviewing my code.

On Mon, Jul 19, 2021 at 12:36 AM Tanya Moldovan 
wrote:

> I think you forgot to link it, but I think I found it
> 
>  :)
>
> You don't really need line 11. It will run without it.
> Don't use defs inside a function. Use let. Always.
> Don't use atoms inside a function. In fact, unless you need some shared
> state between processes - just don't use them. Same goes for refs.
>
> (I changed the name of function to be more clojure like (ie: SimpleTrue ->
> simple-true and so on)
>
> It's not clear what you want to do with the SimpleTrue, SimpleFalse. Do
> you need it to be a list? Or a boolean value?
> If boolean - then do this:
>
> (defn simple-true [] true)
> (defn simple-false [] false)
> (defn not-simple-true [] (not simple-true))
> (defn not-simple-false [] (not simple-false))
>
> If you need a list, just do:
>
> (defn simple-true [] '(true)) ;<--- notice the quote before the parenthesis
> (defn simple-true [] [true]) ; or just use vectors
>
> In clojure, if you need lists, always put a quote before the parenthesis,
> otherwise it will be interpreted as a function.
> So (true) will throw an exception, but '(true) will work:
>
> ie4clj.core=> (true)
> Execution error (ClassCastException) at ie4clj.core/eval1490 
> (form-init3173779095201492457.clj:1).
> java.lang.Boolean cannot be cast to clojure.lang.IFn
>
> ie4clj.core=> '(true)
> (true)
>
>
> Another place where it will throw an error is line 41
>
> (@x)
>
> Do you want to return the result as a list or just return the result?
> If you want a list you do this:
>
> '(@x) ; <-- notice the quote
> [@x] ; or use vector
>
> If you want to return a result just do this:
>
> @x
>
> Also, don't use atoms )
>
> On line 37 you are assigning the result of let to that atom, BAL2 will be
> the same as BAL1, so you can just skip it and return the result from let.
> Like this:
>
> (defn build-and-list []
>   (println "BAL")
>   (let [result (flatten (list simple-true simple-false))] ;<-- actually not 
> sure if this is the thing you want here. This will be a list of functions.
> (println "BAL1" result )
> result))
>
>
> Another thing is with the test function. Don't use defs there, just use a
> let clause, like this:
>
> (defn first-test []
>   (println "First Test")
>   (let [x (evaluate-and [(constantly true) (constantly true)])
> y (evaluate-and [(constantly true) (constantly false)])
> l (build-and-list)
> result (evaluate-and l)]
> (println "A" x)
> (println "B" y)
> (println "C" l)
> (println "bar" result)
> result))
>
> And here is the evaluate-and function with let instead of def.
>
> (defn evaluate-and
>   [members]
>   (println "EA" members)
>   (let [result (every?  (fn [member] (member)) members)]
> (println "EA+" result)
> result)) ;<-- I added this line, as (println) one return nil, and I 
> thought you needed the result true or false (?)
>
> This compiles and runs for me (unless I forgot something). (if it doesn't
> just tell me, I'll commit the code so you can play with it)
>
>
> On Mon, 19 Jul 2021 at 05:16, Jack Park  wrote:
>
>> Cora, I agree. A gist was just submitted here. I'm in the clojurians
>> slack; I have a weak memory of being there once before. But, happy to put a
>> summary of this in #beginners as you suggest.
>>
>>
>>
>> On Sun, Jul 18, 2021 at 8:13 PM Cora Sutton  wrote:
>>
>>> Code would be helpful for sure! Also, it might be time to move this to
>>> Clojurians Slack http://clojurians.net/
>>>
>>> There is a #beginners channel where volunteers are available to help in
>>> a more synchronous fashion which might help get to the bottom of this a bit
>>> quicker.
>>>
>>> On Sun, Jul 18, 2021 at 10:00 PM Tanya Moldovan <
>>> tanya.moldo...@gmail.com> wrote:
>>>
 Hey,

 Could you share the code you have now?

 On Mon, 19 Jul 2021, 02:18 Jack Park,  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  wrote:
>
>> Hello again Jack,
>>
>> On Sun, Jul 18, 2021 at 6:21 PM Jack Park 
>> 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)
>>

Re: Strange Vector failure

2021-07-19 Thread Jack Park
Cora

(every? (fn [member] (member)) members)
works fine on [constantly true & false
but fails with
java.lang.Boolean cannot be cast to clojure.lang.IFn
on the lists I construct.

In truth, I thought all the code was working, but that turned out ot be an
artifact of the test I designed. When I changed the test conditions,
evaluate_and failed.


On Sun, Jul 18, 2021 at 5:00 PM Cora Sutton  wrote:

> Hello again Jack,
>
> On Sun, Jul 18, 2021 at 6:21 PM Jack Park 
> 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  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

Re: Strange Vector failure

2021-07-19 Thread Cora Sutton
Your members list needs to be filled with things that can be called as
functions, since that's what that code snippet does, and booleans
definitely cannot be called as functions. That's what the error means,
there's a boolean in your list and it's trying to cast it to an IFn (a
Clojure function interface) when it is called as (member).

Can you show the lists you construct? Are they full of functions that take
no arguments? Do you want the lists to be able to contain booleans too?

On Mon, Jul 19, 2021 at 2:57 PM Jack Park  wrote:

> Cora
>
> (every? (fn [member] (member)) members)
> works fine on [constantly true & false
> but fails with
> java.lang.Boolean cannot be cast to clojure.lang.IFn
> on the lists I construct.
>
> In truth, I thought all the code was working, but that turned out ot be an
> artifact of the test I designed. When I changed the test conditions,
> evaluate_and failed.
>
>
> On Sun, Jul 18, 2021 at 5:00 PM Cora Sutton  wrote:
>
>> Hello again Jack,
>>
>> On Sun, Jul 18, 2021 at 6:21 PM Jack Park 
>> 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))]
>> (filt

Re: Strange Vector failure

2021-07-19 Thread Jack Park
Great points!
They are filled with functions which look like this

(defn simple_true [] (true))

They are not booleans but functions which return a boolean.
Here is a list of two of those as produced by the code:

(#object[ie4clj.Tests$simple_false 0x3a4621bd
ie4clj.Tests$simple_false@3a4621bd]
 #object[ie4clj.Tests$simple_false 0x3a4621bd
ie4clj.Tests$simple_false@3a4621bd])

Or maybe I missed something.

On Mon, Jul 19, 2021 at 3:33 PM Cora Sutton  wrote:

> Your members list needs to be filled with things that can be called as
> functions, since that's what that code snippet does, and booleans
> definitely cannot be called as functions. That's what the error means,
> there's a boolean in your list and it's trying to cast it to an IFn (a
> Clojure function interface) when it is called as (member).
>
> Can you show the lists you construct? Are they full of functions that take
> no arguments? Do you want the lists to be able to contain booleans too?
>
> On Mon, Jul 19, 2021 at 2:57 PM Jack Park 
> wrote:
>
>> Cora
>>
>> (every? (fn [member] (member)) members)
>> works fine on [constantly true & false
>> but fails with
>> java.lang.Boolean cannot be cast to clojure.lang.IFn
>> on the lists I construct.
>>
>> In truth, I thought all the code was working, but that turned out ot be
>> an artifact of the test I designed. When I changed the test conditions,
>> evaluate_and failed.
>>
>>
>> On Sun, Jul 18, 2021 at 5:00 PM Cora Sutton  wrote:
>>
>>> Hello again Jack,
>>>
>>> On Sun, Jul 18, 2021 at 6:21 PM Jack Park 
>>> 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

Re: Strange Vector failure

2021-07-19 Thread Cora Sutton
Those are functions that call booleans as functions. Try this:

(defn simple-true [] true)

On Mon, Jul 19, 2021 at 5:41 PM Jack Park  wrote:

> Great points!
> They are filled with functions which look like this
>
> (defn simple_true [] (true))
>
> They are not booleans but functions which return a boolean.
> Here is a list of two of those as produced by the code:
>
> (#object[ie4clj.Tests$simple_false 0x3a4621bd
> ie4clj.Tests$simple_false@3a4621bd]
>  #object[ie4clj.Tests$simple_false 0x3a4621bd
> ie4clj.Tests$simple_false@3a4621bd])
>
> Or maybe I missed something.
>
> On Mon, Jul 19, 2021 at 3:33 PM Cora Sutton  wrote:
>
>> Your members list needs to be filled with things that can be called as
>> functions, since that's what that code snippet does, and booleans
>> definitely cannot be called as functions. That's what the error means,
>> there's a boolean in your list and it's trying to cast it to an IFn (a
>> Clojure function interface) when it is called as (member).
>>
>> Can you show the lists you construct? Are they full of functions that
>> take no arguments? Do you want the lists to be able to contain booleans too?
>>
>> On Mon, Jul 19, 2021 at 2:57 PM Jack Park 
>> wrote:
>>
>>> Cora
>>>
>>> (every? (fn [member] (member)) members)
>>> works fine on [constantly true & false
>>> but fails with
>>> java.lang.Boolean cannot be cast to clojure.lang.IFn
>>> on the lists I construct.
>>>
>>> In truth, I thought all the code was working, but that turned out ot be
>>> an artifact of the test I designed. When I changed the test conditions,
>>> evaluate_and failed.
>>>
>>>
>>> On Sun, Jul 18, 2021 at 5:00 PM Cora Sutton  wrote:
>>>
 Hello again Jack,

 On Sun, Jul 18, 2021 at 6:21 PM Jack Park 
 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 C

Re: Strange Vector failure

2021-07-19 Thread Jack Park
Did. That suggestion was made earlier. Did not change anything.

Here's a test which ran just fine
(def x (evaluate_and (list true true)))
  (println "A" x)
  (def y (evaluate_and (list true false)))
  (println "B" y)

But, the moment I attempt to make a list with two functions in it, the code
breaks and returns - without any errors - not a boolean, but the structure
I passed it.


On Mon, Jul 19, 2021 at 3:43 PM Cora Sutton  wrote:

> Those are functions that call booleans as functions. Try this:
>
> (defn simple-true [] true)
>
> On Mon, Jul 19, 2021 at 5:41 PM Jack Park 
> wrote:
>
>> Great points!
>> They are filled with functions which look like this
>>
>> (defn simple_true [] (true))
>>
>> They are not booleans but functions which return a boolean.
>> Here is a list of two of those as produced by the code:
>>
>> (#object[ie4clj.Tests$simple_false 0x3a4621bd
>> ie4clj.Tests$simple_false@3a4621bd]
>>  #object[ie4clj.Tests$simple_false 0x3a4621bd
>> ie4clj.Tests$simple_false@3a4621bd])
>>
>> Or maybe I missed something.
>>
>> On Mon, Jul 19, 2021 at 3:33 PM Cora Sutton  wrote:
>>
>>> Your members list needs to be filled with things that can be called as
>>> functions, since that's what that code snippet does, and booleans
>>> definitely cannot be called as functions. That's what the error means,
>>> there's a boolean in your list and it's trying to cast it to an IFn (a
>>> Clojure function interface) when it is called as (member).
>>>
>>> Can you show the lists you construct? Are they full of functions that
>>> take no arguments? Do you want the lists to be able to contain booleans too?
>>>
>>> On Mon, Jul 19, 2021 at 2:57 PM Jack Park 
>>> wrote:
>>>
 Cora

 (every? (fn [member] (member)) members)
 works fine on [constantly true & false
 but fails with
 java.lang.Boolean cannot be cast to clojure.lang.IFn
 on the lists I construct.

 In truth, I thought all the code was working, but that turned out ot be
 an artifact of the test I designed. When I changed the test conditions,
 evaluate_and failed.


 On Sun, Jul 18, 2021 at 5:00 PM Cora Sutton  wrote:

> Hello again Jack,
>
> On Sun, Jul 18, 2021 at 6:21 PM Jack Park 
> 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 ge

Re: Strange Vector failure

2021-07-19 Thread Cora Sutton
Hello again, Jack. I'm not sure what your code looked like before or looks
like now but I think maybe a different way of helping you out with this is
in order. Here's some code that does what I think you're going for and runs:

https://gist.github.com/corasaurus-hex/1c86b545644b734310a15d984f61ad99

Have a look, play with it a bit, change around value and see what breaks.
Hope that's helpful!

On Mon, Jul 19, 2021 at 5:55 PM Jack Park  wrote:

> Did. That suggestion was made earlier. Did not change anything.
>
> Here's a test which ran just fine
> (def x (evaluate_and (list true true)))
>   (println "A" x)
>   (def y (evaluate_and (list true false)))
>   (println "B" y)
>
> But, the moment I attempt to make a list with two functions in it, the
> code breaks and returns - without any errors - not a boolean, but the
> structure I passed it.
>
>
> On Mon, Jul 19, 2021 at 3:43 PM Cora Sutton  wrote:
>
>> Those are functions that call booleans as functions. Try this:
>>
>> (defn simple-true [] true)
>>
>> On Mon, Jul 19, 2021 at 5:41 PM Jack Park 
>> wrote:
>>
>>> Great points!
>>> They are filled with functions which look like this
>>>
>>> (defn simple_true [] (true))
>>>
>>> They are not booleans but functions which return a boolean.
>>> Here is a list of two of those as produced by the code:
>>>
>>> (#object[ie4clj.Tests$simple_false 0x3a4621bd
>>> ie4clj.Tests$simple_false@3a4621bd]
>>>  #object[ie4clj.Tests$simple_false 0x3a4621bd
>>> ie4clj.Tests$simple_false@3a4621bd])
>>>
>>> Or maybe I missed something.
>>>
>>> On Mon, Jul 19, 2021 at 3:33 PM Cora Sutton  wrote:
>>>
 Your members list needs to be filled with things that can be called as
 functions, since that's what that code snippet does, and booleans
 definitely cannot be called as functions. That's what the error means,
 there's a boolean in your list and it's trying to cast it to an IFn (a
 Clojure function interface) when it is called as (member).

 Can you show the lists you construct? Are they full of functions that
 take no arguments? Do you want the lists to be able to contain booleans 
 too?

 On Mon, Jul 19, 2021 at 2:57 PM Jack Park 
 wrote:

> Cora
>
> (every? (fn [member] (member)) members)
> works fine on [constantly true & false
> but fails with
> java.lang.Boolean cannot be cast to clojure.lang.IFn
> on the lists I construct.
>
> In truth, I thought all the code was working, but that turned out ot
> be an artifact of the test I designed. When I changed the test conditions,
> evaluate_and failed.
>
>
> On Sun, Jul 18, 2021 at 5:00 PM Cora Sutton  wrote:
>
>> Hello again Jack,
>>
>> On Sun, Jul 18, 2021 at 6:21 PM Jack Park 
>> 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.
>>
>>
>>>
>