Re: Strange Vector failure

2021-07-24 Thread Jack Park
That's precisely how I coded it. Just need to run some tests, then on to
more complex testing with nested lists and so forth.

Thanks!

On Sat, Jul 24, 2021 at 12:03 AM Cora Sutton  wrote:

> not, in clojure, is itself a function, so it would just be wrapping a
> other function call in (not (my-fn)). there is no limit to the recursion
> here, you can have functions in functions in functions
>
> On Fri, Jul 23, 2021 at 9:54 PM Jack Park 
> wrote:
>
>> Cora,
>>
>> That's simply amazing. I added one more "or" test: all-false.
>>
>> I confess, I'm not yet at the place where I look at that pattern and
>> recognize it, but, thanks  to you and to the other hints I received here, I
>> now have something to work with.
>>
>> Next up for me will be to test the "not" functions.
>>
>> Many thanks!
>>
>> -Jack
>>
>> On Fri, Jul 23, 2021 at 6:03 PM Cora Sutton  wrote:
>>
>>> You can stay away from eval unless you have extremely special needs,
>>> really. I never use it myself. The evaluate-or-fns and evaluate-and-fns
>>> don't care what the function is, it could be another call to
>>> evaluate-or-fns or evaluate-and-fns, and in this way you can recurse as
>>> deeply as you desire and only evaluate when you actually want values out of
>>> it.
>>>
>>> (defn evaluate-and-fns
>>>   "Returns true if every function in members returns a value that is
>>> true-ish according to Clojure's
>>>   truthiness rules. Otherwise returns false."
>>>   [members]
>>>   (every? (fn [member]
>>> (member))
>>>   members))
>>>
>>> (defn evaluate-or-fns
>>>   "Returns true if any function in members returns a value that is
>>> true-ish according to Clojure's
>>>   truthiness rules. Otherwise returns false."
>>>   [members]
>>>   (boolean
>>>(some (fn [member]
>>>(member))
>>>  members)))
>>>
>>> (evaluate-or-fns [(fn []
>>> (evaluate-and-fns [(fn [] (evaluate-and-fns
>>> [simple-true-fn simple-true-fn]))
>>>simple-true-fn]))
>>>   (fn []
>>> (evaluate-and-fns [simple-true-fn
>>> simple-false-fn]))])
>>>
>>> On Fri, Jul 23, 2021 at 7:22 PM Jack Park 
>>> wrote:
>>>
>>>> Hello again, Cora (and list!)
>>>>
>>>> I have your gist running, then added a new feature
>>>>
>>>> https://gist.github.com/KnowledgeGarden/330b4147cd3d4909ef55684fc4c1f00d
>>>>
>>>> The first code was for conjunctive lists, I added disjunctive lists
>>>>
>>>> There, I started with some? but could not make the grade, ended up with
>>>> some fn where fn is eval. That's the code.
>>>> It's behaving strangely, but maybe I'm on the right track.
>>>>
>>>> Where this is going is that a list can be populated with things other
>>>> than simple functions like SimpleTrue; can be populated with conjunctive
>>>> and disjunctive lists, each of which can be similarly populated. That, of
>>>> course, means that evaluating a single inferrable list is the same as
>>>> walking a possibly complex (no loops, hopefully) spider web.
>>>>
>>>> Thanks
>>>> Jack
>>>>
>>>> On Mon, Jul 19, 2021 at 6:04 PM Cora Sutton  wrote:
>>>>
>>>>> 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)))
>>>&

Re: Strange Vector failure

2021-07-23 Thread Jack Park
Cora,

That's simply amazing. I added one more "or" test: all-false.

I confess, I'm not yet at the place where I look at that pattern and
recognize it, but, thanks  to you and to the other hints I received here, I
now have something to work with.

Next up for me will be to test the "not" functions.

Many thanks!

-Jack

On Fri, Jul 23, 2021 at 6:03 PM Cora Sutton  wrote:

> You can stay away from eval unless you have extremely special needs,
> really. I never use it myself. The evaluate-or-fns and evaluate-and-fns
> don't care what the function is, it could be another call to
> evaluate-or-fns or evaluate-and-fns, and in this way you can recurse as
> deeply as you desire and only evaluate when you actually want values out of
> it.
>
> (defn evaluate-and-fns
>   "Returns true if every function in members returns a value that is
> true-ish according to Clojure's
>   truthiness rules. Otherwise returns false."
>   [members]
>   (every? (fn [member]
> (member))
>   members))
>
> (defn evaluate-or-fns
>   "Returns true if any function in members returns a value that is
> true-ish according to Clojure's
>   truthiness rules. Otherwise returns false."
>   [members]
>   (boolean
>(some (fn [member]
>(member))
>  members)))
>
> (evaluate-or-fns [(fn []
> (evaluate-and-fns [(fn [] (evaluate-and-fns
> [simple-true-fn simple-true-fn]))
>simple-true-fn]))
>   (fn []
> (evaluate-and-fns [simple-true-fn simple-false-fn]))])
>
> On Fri, Jul 23, 2021 at 7:22 PM Jack Park 
> wrote:
>
>> Hello again, Cora (and list!)
>>
>> I have your gist running, then added a new feature
>>
>> https://gist.github.com/KnowledgeGarden/330b4147cd3d4909ef55684fc4c1f00d
>>
>> The first code was for conjunctive lists, I added disjunctive lists
>>
>> There, I started with some? but could not make the grade, ended up with
>> some fn where fn is eval. That's the code.
>> It's behaving strangely, but maybe I'm on the right track.
>>
>> Where this is going is that a list can be populated with things other
>> than simple functions like SimpleTrue; can be populated with conjunctive
>> and disjunctive lists, each of which can be similarly populated. That, of
>> course, means that evaluating a single inferrable list is the same as
>> walking a possibly complex (no loops, hopefully) spider web.
>>
>> Thanks
>> Jack
>>
>> On Mon, Jul 19, 2021 at 6:04 PM Cora Sutton  wrote:
>>
>>> 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$sim

Re: Strange Vector failure

2021-07-23 Thread Jack Park
Hello again, Cora (and list!)

I have your gist running, then added a new feature

https://gist.github.com/KnowledgeGarden/330b4147cd3d4909ef55684fc4c1f00d

The first code was for conjunctive lists, I added disjunctive lists

There, I started with some? but could not make the grade, ended up with
some fn where fn is eval. That's the code.
It's behaving strangely, but maybe I'm on the right track.

Where this is going is that a list can be populated with things other than
simple functions like SimpleTrue; can be populated with conjunctive and
disjunctive lists, each of which can be similarly populated. That, of
course, means that evaluating a single inferrable list is the same as
walking a possibly complex (no loops, hopefully) spider web.

Thanks
Jack

On Mon, Jul 19, 2021 at 6:04 PM Cora Sutton  wrote:

> 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 li

Re: Strange Vector failure

2021-07-23 Thread Jack Park
Ok. I got back to this, now running Cora's gist. It gives me a different
place to explore these issues.
More soon.
Jack

On Tue, Jul 20, 2021 at 5:31 PM Jack Park  wrote:

> Hi Cora,
>
> I got dragged away but plan to study your contribution, which I deeply
> appreciate.
>
> My project plans to be a very simple clojure re-implementation of an
> inference engine I wrote in Forth more than 20 years ago, a kind of list
> processor in which you have an interface which advertises a simple
> "eval"-like method, applicable to structures as well as atoms. Thus,
> conjunctive and disjunctive lists, plus not, all of which can be populated
> with combinations of those and atoms, tiny computational objects which do
> stuff within the same interface. Atoms can ask questions at the UI, do
> computations on databases, and so forth.
>
> I benchmarked that against a more traditional symbolic (frame-based)
> inference I had written to control autoclaves for curing polymer resins - a
> contract for the military which ended up helping to fix fighter jets which
> were grounded because of bird impacts penetrating composite leading edges
> and crashing - we were able to cure improved leading edges; the new code
> executed more than 10 times faster than the old symbolic code. That was
> then (Forth), this is now (Java/Clojure). I've done it in Java. Now it's
> time to use that as a learning exercise.
>
> Many thanks
> Jack
>
> On Mon, Jul 19, 2021 at 6:04 PM Cora Sutton  wrote:
>
>> 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
>>>>>

Re: Strange Vector failure

2021-07-20 Thread Jack Park
Hi Cora,

I got dragged away but plan to study your contribution, which I deeply
appreciate.

My project plans to be a very simple clojure re-implementation of an
inference engine I wrote in Forth more than 20 years ago, a kind of list
processor in which you have an interface which advertises a simple
"eval"-like method, applicable to structures as well as atoms. Thus,
conjunctive and disjunctive lists, plus not, all of which can be populated
with combinations of those and atoms, tiny computational objects which do
stuff within the same interface. Atoms can ask questions at the UI, do
computations on databases, and so forth.

I benchmarked that against a more traditional symbolic (frame-based)
inference I had written to control autoclaves for curing polymer resins - a
contract for the military which ended up helping to fix fighter jets which
were grounded because of bird impacts penetrating composite leading edges
and crashing - we were able to cure improved leading edges; the new code
executed more than 10 times faster than the old symbolic code. That was
then (Forth), this is now (Java/Clojure). I've done it in Java. Now it's
time to use that as a learning exercise.

Many thanks
Jack

On Mon, Jul 19, 2021 at 6:04 PM Cora Sutton  wrote:

> 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 agai

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

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).
>>

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-lis

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
> <https://gist.github.com/KnowledgeGarden/572ab649c9266e0f804c93ff4ba2c43c>
>  :)
>
> 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
>

Re: Strange Vector failure

2021-07-18 Thread Jack Park
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 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

Re: Strange Vector failure

2021-07-18 Thread Jack Park
Tanya,

Here is a gist with the three files being hacked at the moment; the test
file is in a different place than I've sketched above.
You will have to remove a couple of :remove lines from test because I
didn't include that code - it's not in play yet.

Hope that helps.
The program is just a simple list-based inference engine which allows you
to build rule trees from conjunctive and disjunctive lists, members of
which can be any object which can eval to return a boolean, which happens
to include the two list forms; it includes "not" which can take another
such object.

On Sun, Jul 18, 2021 at 8:01 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 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 t

Re: Strange Vector failure

2021-07-18 Thread Jack Park
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 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 (ful

Re: Strange Vector failure

2021-07-18 Thread Jack Park
(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  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 thiiink 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 
> 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 thi

Re: ClassNotFoundException when importing a clojure interface

2021-07-18 Thread Jack Park
Thanks Alex!

I am beginning to move away from design by interface. Actually making
progress now.

Cheers,
Jack

On Sun, Jul 18, 2021 at 12:34 PM Alex Miller 
wrote:

> definterface is generally considered a low-level tool in Clojure and
> typically Clojure developers do not create interfaces directly like this.
>
> The two primary means of function abstraction/polymorphism are
> multimethods (can dispatch on any aspect of any of the parameters to a
> function) and protocols (which dispatch on the type of the first parameter
> to the function). There are tradeoffs between these - the former is very
> flexible, the latter is very similar to interfaces (and does use them under
> the hood) so is limited to type-based dispatch but gets all the JVM
> performance of that operation.
>
> On Saturday, July 17, 2021 at 7:44:18 PM UTC-5 jack...@topicquests.org
> wrote:
>
>> Tanya,
>>
>> That did help, swapping  ie4clj.api.Inferrable for its import.
>> That, of course, got me into the next coding bug, about which I shall ask
>> next (I am attempting to use doseq to walk a list and AND its Inferrable
>> members)
>>
>> Meanwhile, I am truly surprised that you said
>>
>> I don't think it is the right way to use interfaces in clojure.
>>>
>> It's likely a result of dyslexia that I did not see that coming after
>> studying all the online banter about interfaces and protocols.. I chose
>> definterface because the examples showed how to specify the return values,
>> and programming by interface is how I do Java. I'd like to discover what,
>> precisely, to read and get past dyslexic events to learn how to use
>> interfaces.
>>
>> Many thanks
>> Jack
>>
>> On Sat, Jul 17, 2021 at 4:10 PM Tanya Moldovan 
>> wrote:
>>
>>> Hi,
>>>
>>> I don't think it is the right way to use interfaces in clojure. Take a
>>> look at  this
>>> <https://medium.com/@ujjawaldixit099/implementing-java-interfaces-in-clojure-3e5f0b80ba14>
>>>  and this
>>> <https://stackoverflow.com/questions/8614734/how-do-i-implement-a-java-interface-in-clojure/8615002>
>>> .
>>> You could create a java project with the interfaces you need and import
>>> that instead.
>>>
>>> I think the issue is that this setup requires AOT and it might be
>>> missing from your configuration.
>>> To fix it try adding this to project.clj file:
>>>
>>> :profiles {:dev {:aot [ie4clj.api]}}
>>>
>>> It can be tricky If you want to do lein uberjar and generate a jar file.
>>>
>>> Alternatively, you can use compile-files
>>> <https://clojuredocs.org/clojure.core/*compile-files*> (then you don't
>>> need import statement).
>>> (note that in your gist you had some errors when defining AndList, I've
>>> fixed it)
>>> (also take a look at the clojure style guide
>>> <https://github.com/bbatsov/clojure-style-guide>, as AndList is not
>>> really the way to name things in clojure )) )
>>>
>>> (ns ie4clj.api)
>>>
>>> (definterface Inferrable
>>>   (^boolean eval [])
>>>   (^boolean evalMembers [members]))
>>>
>>> (ns ie4clj.AndList)
>>>
>>> (when *compile-files*
>>>   (require 'ie4clj.api))
>>>
>>> (def AndList
>>>   (reify
>>>ie4clj.api.Inferrable
>>>(eval [_] true)
>>>(evalMembers [_ m] true)))
>>>
>>> Hope this helps,
>>>
>>>
>>>
>>> On Sat, 17 Jul 2021 at 21:06, Jack Park  wrote:
>>>
>>>> I created a gist
>>>> https://gist.github.com/KnowledgeGarden/39742ae9ae641f0d8facb31b288ece4c
>>>>
>>>> which explains a ClassNotFoundException when I am importing and
>>>> reifying a particular interface in another clj file.
>>>>
>>>> It's really baffling because, in the load order, core calls a test in a
>>>> test file - getting that to compile landed on the solution of an (:import
>>>> ...) statement; once that worked, then the code in that test calls another
>>>> file AndList.clj which happens to have several places where it reifies the
>>>> same interface. Except, with the same import statement, on that file, I get
>>>> the error.  Difficult to even find a decent StackOverflow because one such
>>>> StackOverflow appears to be very similar, and the suggested fix is what I
>>>> have now.
>>>>
>>>> Thanks in advance for ideas.
>>>> Ja

Re: Strange Vector failure

2021-07-18 Thread Jack Park
Cora and Alex,

I think you are both hitting some nails on their heads.
Yes, the java mentality creates a kind of flow and patterns which clearly
do not apply to clojure (eliding jokes like "what must they be smoking").

In java, I can make a list structure and do whatever I want with it - *because
it's not immutable*. Now that we're not in Kansas anymore, I must get over
relying on changing variable objects at will, but then, declaring atoms
seems to have its own issues. So, try to avoid those. "Let" declares its
own context but it might be creating a result you want to return in the
outer context - that crops up from time to time.

So, where am I now?
I really want to build a set of classes which, in a weak sense (the java
way) of extending sequence to give it new behaviors.
But, the lesson today is that I am trying to build a *class* which evals as
if it is a method, so I must ditch those classes and migrate those
behaviors to a collection of functions.

That's the work in progress, and it includes ditching the api interface
altogether.

That's work in progress (painful but fun). I'll report back.
It's strange - to me - that the issues I face are non-issues for others
here, mostly because of my deep java biases.

Thanks
Jack

On Sun, Jul 18, 2021 at 12:47 PM Cora Sutton  wrote:

> Oh! I just saw your post from earlier and Alex's response, I strongly
> believe we have an XY problem here. In Clojure you most likely wouldn't use
> interfaces like this. We can move this discussion over there since Alex has
> kicked it off.
>
> On Sun, Jul 18, 2021 at 2:37 PM Cora Sutton  wrote:
>
>> And for what it's worth, I hte how condescending that site (
>> https://xyproblem.info/) is. It could be so much kinder.
>>
>> On Sun, Jul 18, 2021 at 2:34 PM Cora Sutton  wrote:
>>
>>> No worries! Deep Java experience is such a huge asset when it comes to
>>> Clojure, there's nothing to be ashamed of!
>>>
>>> So, for reify, if I understand what you're attempting, I think you'd
>>> have something like:
>>>
>>> (reify
>>>   ie4clj.api.Inferrable
>>>   (evalMembers [members]
>>> (every? evalSelf members
>>>
>>> Tha is, if evalSelf is really what you want there.
>>>
>>> But, Jack, and I mean this in the kindest way possible, do you think
>>> it's possible we have an XY situation going on here?
>>> https://xyproblem.info/
>>>
>>> It's possible we're helping you solve the wrong thing and I'd love to be
>>> sure we're pointing you down the best path possible. So, can I ask what
>>> problem you're solving? Can you share more code somewhere, maybe in a
>>> GitHub gist?
>>>
>>> I just worry that maybe you're solving a problem the "Java way" when
>>> there's an easier way to go about it in the "Clojure way".
>>>
>>> Hope this is helpful!
>>> Cora
>>>
>>>
>>> On Sun, Jul 18, 2021 at 2:14 PM Jack Park 
>>> wrote:
>>>
>>>> Thank you, Cora. That's awesome, and it opens new issues for me. Here
>>>> is my revised code from your first level comment
>>>> (defn AndList
>>>>   [members]
>>>>   (reify
>>>> ie4clj.api.Inferrable
>>>> (every? evalSelf members)
>>>>
>>>> ))
>>>> Which opens new issues:
>>>>
>>>>- Right at "(reify" I get this error message
>>>>
>>>> Syntax error (IllegalArgumentException) compiling at
>>>> (ie4clj/AndList.clj:8:3).
>>>> Don't know how to create ISeq from: clojure.lang.Symbol
>>>> It's as if the ability to reify an interface is not recognized
>>>> Notice there is an interface call which, itself, is not :require'd
>>>> evalSelf, which leads to
>>>>
>>>>- evalSelf is not recognized
>>>>
>>>> That one is beginning to suggest to me that I should, instead, not use
>>>> an interface, but just write code which can use clojure's eval.
>>>> But, I've been creating classes, not functions. If I modify my code
>>>> such that the members sequence contains functions, then perhaps that would
>>>> work.
>>>>
>>>> I confess, I'm saddled with a deep java experience.
>>>> Your coaching is extremely helpful.
>>>> Many thanks
>>>> Jack
>>>>
>>>> On Sun, Jul 18, 2021 at 11:23 AM Cora Sutton  wrote:
>>>>
>>>>> Hi Jack!
>>>>>
>>>>> I could be wrong but I think 

Re: Strange Vector failure

2021-07-18 Thread Jack Park
Thank you, Cora. That's awesome, and it opens new issues for me. Here is my
revised code from your first level comment
(defn AndList
  [members]
  (reify
ie4clj.api.Inferrable
(every? evalSelf members)

))
Which opens new issues:

   - Right at "(reify" I get this error message

Syntax error (IllegalArgumentException) compiling at
(ie4clj/AndList.clj:8:3).
Don't know how to create ISeq from: clojure.lang.Symbol
It's as if the ability to reify an interface is not recognized
Notice there is an interface call which, itself, is not :require'd
evalSelf, which leads to

   - evalSelf is not recognized

That one is beginning to suggest to me that I should, instead, not use an
interface, but just write code which can use clojure's eval.
But, I've been creating classes, not functions. If I modify my code such
that the members sequence contains functions, then perhaps that would work.

I confess, I'm saddled with a deep java experience.
Your coaching is extremely helpful.
Many thanks
Jack

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 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 thiiink 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 
> 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:
&

Strange Vector failure

2021-07-18 Thread Jack Park
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.


Re: ClassNotFoundException when importing a clojure interface

2021-07-17 Thread Jack Park
Tanya,

That did help, swapping  ie4clj.api.Inferrable for its import.
That, of course, got me into the next coding bug, about which I shall ask
next (I am attempting to use doseq to walk a list and AND its Inferrable
members)

Meanwhile, I am truly surprised that you said

I don't think it is the right way to use interfaces in clojure.
>
It's likely a result of dyslexia that I did not see that coming after
studying all the online banter about interfaces and protocols.. I chose
definterface because the examples showed how to specify the return values,
and programming by interface is how I do Java. I'd like to discover what,
precisely, to read and get past dyslexic events to learn how to use
interfaces.

Many thanks
Jack

On Sat, Jul 17, 2021 at 4:10 PM Tanya Moldovan 
wrote:

> Hi,
>
> I don't think it is the right way to use interfaces in clojure. Take a
> look at  this
> <https://medium.com/@ujjawaldixit099/implementing-java-interfaces-in-clojure-3e5f0b80ba14>
>  and this
> <https://stackoverflow.com/questions/8614734/how-do-i-implement-a-java-interface-in-clojure/8615002>
> .
> You could create a java project with the interfaces you need and import
> that instead.
>
> I think the issue is that this setup requires AOT and it might be missing
> from your configuration.
> To fix it try adding this to project.clj file:
>
> :profiles {:dev {:aot [ie4clj.api]}}
>
> It can be tricky If you want to do lein uberjar and generate a jar file.
>
> Alternatively, you can use compile-files
> <https://clojuredocs.org/clojure.core/*compile-files*> (then you don't
> need import statement).
> (note that in your gist you had some errors when defining AndList, I've
> fixed it)
> (also take a look at the clojure style guide
> <https://github.com/bbatsov/clojure-style-guide>, as AndList is not
> really the way to name things in clojure )) )
>
> (ns ie4clj.api)
>
> (definterface Inferrable
>   (^boolean eval [])
>   (^boolean evalMembers [members]))
>
> (ns ie4clj.AndList)
>
> (when *compile-files*
>   (require 'ie4clj.api))
>
> (def AndList
>   (reify
>ie4clj.api.Inferrable
>(eval [_] true)
>(evalMembers [_ m] true)))
>
> Hope this helps,
>
>
>
> On Sat, 17 Jul 2021 at 21:06, Jack Park  wrote:
>
>> I created a gist
>> https://gist.github.com/KnowledgeGarden/39742ae9ae641f0d8facb31b288ece4c
>>
>> which explains a ClassNotFoundException when I am importing and reifying
>> a particular interface in another clj file.
>>
>> It's really baffling because, in the load order, core calls a test in a
>> test file - getting that to compile landed on the solution of an (:import
>> ...) statement; once that worked, then the code in that test calls another
>> file AndList.clj which happens to have several places where it reifies the
>> same interface. Except, with the same import statement, on that file, I get
>> the error.  Difficult to even find a decent StackOverflow because one such
>> StackOverflow appears to be very similar, and the suggested fix is what I
>> have now.
>>
>> Thanks in advance for ideas.
>> 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/ffb09a94-5aa4-4600-8c9a-e0d00901df72n%40googlegroups.com
>> <https://groups.google.com/d/msgid/clojure/ffb09a94-5aa4-4600-8c9a-e0d00901df72n%40googlegroups.com?utm_medium=email_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 th

ClassNotFoundException when importing a clojure interface

2021-07-17 Thread Jack Park
I created a gist
https://gist.github.com/KnowledgeGarden/39742ae9ae641f0d8facb31b288ece4c

which explains a ClassNotFoundException when I am importing and reifying a 
particular interface in another clj file.

It's really baffling because, in the load order, core calls a test in a 
test file - getting that to compile landed on the solution of an (:import 
...) statement; once that worked, then the code in that test calls another 
file AndList.clj which happens to have several places where it reifies the 
same interface. Except, with the same import statement, on that file, I get 
the error.  Difficult to even find a decent StackOverflow because one such 
StackOverflow appears to be very similar, and the suggested fix is what I 
have now.

Thanks in advance for ideas.
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/ffb09a94-5aa4-4600-8c9a-e0d00901df72n%40googlegroups.com.


Re: First post: how to mimic a Java List with types?

2020-08-16 Thread Jack Park
Brandon,

Just a quick note to say that I conquered ConjunctiveList and have
DisjunctiveList coded.
After further tests to validate what it's doing, I'll post a gist to show
the working code.

You were entirely right: using definterface and defrecord, I can construct
these structures. Still a few tests to run.

Many thanks
Jack

On Sat, Aug 15, 2020 at 2:28 PM Brandon R  wrote:

> Hey Jack,
>
> Just been a fly on the wall for this convo, and aside from offering a
> specific solution, which others have done, I'm pretty certain this can be
> done with just protocols and records. Make a record (like your type) that
> implements the two protocols (like your interfaces). You could achieve your
> desired functionality without records and protocols but what you describe
> sounds like a fitting case for them.
>
> Members in such lists can be either other evaluable lists, or they can be
>> evaluable objects which perform computations
>>
>
> A simple Clojure list/vector can hold any type of data you put into it. So
> your record can hold a vector of these things, which can be represented as
> Clojure data structure (lists / maps / etc).
>
> You say you *need* to construct a type, but I urge you to challenge this
> assumption, again and again if needed. I think it's natural to think you
> need a type because of coming from Java/OOP land, especially if you were
> there a long time. Old patterns die hard?
>
> I could be wrong though. :)
>
>
> My 2 cents,
> Brandon
>
> On Sat, Aug 15, 2020 at 12:42 PM Jack Park 
> wrote:
>
>> Hi Erik,
>>
>> I think that teasing things apart helps along some dimensions, but the
>> problem I face, still thinking like a Java hacker, is that I need to put
>> things together:
>>
>> I need to construct a *type*  (deftype) which honors two different
>> interfaces, a list, and an evaluable object. I need the type because I want
>> to create it, then add members to the list, and then one of:
>> a) insert the object into another one (building and/or trees)
>> b) evaluate it - when it is the root of the tree.
>>
>> Members in such lists can be either other evaluable lists, or they can be
>> evaluable objects which perform computations - even with side effects - but
>> which return a boolean.
>>
>> The several ideas posted in this thread are greatly helping me to see
>> through this situation with fresh eyes, but, thus far, nothing has
>> convinced me to drop the goal of creating a type which is a list and
>> evaluable, into which I can insert conjunction or disjunction evaluators.
>>
>> Many thanks,
>> Jack
>>
>> On Sat, Aug 15, 2020 at 12:14 AM Erik Assum  wrote:
>>
>>> Why not tease things apart?
>>>
>>> (defn eval [x] ...)
>>>
>>> (some eval my-list) ;; or list
>>> (every? eval my-list) ;; and list
>>>
>>> https://clojuredocs.org/clojure.core/some
>>> https://clojuredocs.org/clojure.core/every_q
>>>
>>> Now, you can make the eval function polymorphic in several ways,
>>> simplest is to case or cond on some property of x. You could also use
>>> multimethods or a protocol to achieve this.
>>>
>>> https://insideclojure.org/2015/04/27/poly-perf/
>>>
>>> Erik.
>>> --
>>> i farta
>>>
>>> 15. aug. 2020 kl. 02:04 skrev matthew...@gmail.com <
>>> matthewdowne...@gmail.com>:
>>>
>>> 
>>>
>>> Another option would be to do what Alex is suggesting and define and as
>>> a function. Just because it’s a macro in clojure.core doesn’t mean you
>>> can’t write your own :)
>>>
>>> (defn eval' [x]
>>>   (if (map? x)
>>> (apply (:fn x) (:coll x))
>>> x))
>>>
>>> (defn and-list [& items]
>>>   (let [if? (fn [x] (if x true false))
>>> and' (fn [& args] (every? if? args))]
>>> {:fn and' :coll items}))
>>>
>>> (eval' true) ;=> true
>>> (eval' false) ;=> false
>>> (eval' (and-list 1 2 3)) ;=> true
>>> (eval' (and-list 1 2 3 false)) ;=> false
>>>
>>> Ditto with or.
>>> ​
>>> On Friday, August 14, 2020 at 4:27:19 PM UTC-5 jack...@topicquests.org
>>> wrote:
>>>
>>>> Alex,
>>>>
>>>> I plan to explore this idea.
>>>> Many thanks!
>>>>
>>>> Jack
>>>>
>>>> On Fri, Aug 14, 2020 at 1:38 PM Oleksandr Shulgin <
>>>> oleksand...@zalando.de> wrote:
>>>>
>>>>>

Re: First post: how to mimic a Java List with types?

2020-08-15 Thread Jack Park
My first attempt at using records (showing my ignorance here) is found in
this gist
https://gist.github.com/KnowledgeGarden/0f6ce01ed9300d4f9bd0ee0c61e3d91b

It fails with this error (which doesn't give very good google)

Syntax error macroexpanding clojure.core/defn at (cljtest/core.clj:123:1).
>   - failed: vector? at: [:fn-tail :arity-1 :params] spec:
> :clojure.core.specs.alpha/param-list
>   - failed: (or (nil? %) (sequential? %)) at: [:fn-tail :arity-n :bodies]
> spec: :clojure.core.specs.alpha/params+body
>

I wonder what I am missing.
Thanks in advance for ideas.

-Jack

On Sat, Aug 15, 2020 at 4:18 PM Jack Park  wrote:

> Brandon!
>
> That just might be the idea I needed. Thank you.
>
> Film at 11...
>
> On Sat, Aug 15, 2020 at 2:28 PM Brandon R  wrote:
>
>> Hey Jack,
>>
>> Just been a fly on the wall for this convo, and aside from offering a
>> specific solution, which others have done, I'm pretty certain this can be
>> done with just protocols and records. Make a record (like your type) that
>> implements the two protocols (like your interfaces). You could achieve your
>> desired functionality without records and protocols but what you describe
>> sounds like a fitting case for them.
>>
>> Members in such lists can be either other evaluable lists, or they can be
>>> evaluable objects which perform computations
>>>
>>
>> A simple Clojure list/vector can hold any type of data you put into it.
>> So your record can hold a vector of these things, which can be represented
>> as Clojure data structure (lists / maps / etc).
>>
>> You say you *need* to construct a type, but I urge you to challenge this
>> assumption, again and again if needed. I think it's natural to think you
>> need a type because of coming from Java/OOP land, especially if you were
>> there a long time. Old patterns die hard?
>>
>> I could be wrong though. :)
>>
>>
>> My 2 cents,
>> Brandon
>>
>> On Sat, Aug 15, 2020 at 12:42 PM Jack Park 
>> wrote:
>>
>>> Hi Erik,
>>>
>>> I think that teasing things apart helps along some dimensions, but the
>>> problem I face, still thinking like a Java hacker, is that I need to put
>>> things together:
>>>
>>> I need to construct a *type*  (deftype) which honors two different
>>> interfaces, a list, and an evaluable object. I need the type because I want
>>> to create it, then add members to the list, and then one of:
>>> a) insert the object into another one (building and/or trees)
>>> b) evaluate it - when it is the root of the tree.
>>>
>>> Members in such lists can be either other evaluable lists, or they can
>>> be evaluable objects which perform computations - even with side effects -
>>> but which return a boolean.
>>>
>>> The several ideas posted in this thread are greatly helping me to see
>>> through this situation with fresh eyes, but, thus far, nothing has
>>> convinced me to drop the goal of creating a type which is a list and
>>> evaluable, into which I can insert conjunction or disjunction evaluators.
>>>
>>> Many thanks,
>>> Jack
>>>
>>> On Sat, Aug 15, 2020 at 12:14 AM Erik Assum  wrote:
>>>
>>>> Why not tease things apart?
>>>>
>>>> (defn eval [x] ...)
>>>>
>>>> (some eval my-list) ;; or list
>>>> (every? eval my-list) ;; and list
>>>>
>>>> https://clojuredocs.org/clojure.core/some
>>>> https://clojuredocs.org/clojure.core/every_q
>>>>
>>>> Now, you can make the eval function polymorphic in several ways,
>>>> simplest is to case or cond on some property of x. You could also use
>>>> multimethods or a protocol to achieve this.
>>>>
>>>> https://insideclojure.org/2015/04/27/poly-perf/
>>>>
>>>> Erik.
>>>> --
>>>> i farta
>>>>
>>>> 15. aug. 2020 kl. 02:04 skrev matthew...@gmail.com <
>>>> matthewdowne...@gmail.com>:
>>>>
>>>> 
>>>>
>>>> Another option would be to do what Alex is suggesting and define and
>>>> as a function. Just because it’s a macro in clojure.core doesn’t mean you
>>>> can’t write your own :)
>>>>
>>>> (defn eval' [x]
>>>>   (if (map? x)
>>>> (apply (:fn x) (:coll x))
>>>> x))
>>>>
>>>> (defn and-list [& items]
>>>>   (let [if? (fn [x] (if x true 

Re: First post: how to mimic a Java List with types?

2020-08-15 Thread Jack Park
Brandon!

That just might be the idea I needed. Thank you.

Film at 11...

On Sat, Aug 15, 2020 at 2:28 PM Brandon R  wrote:

> Hey Jack,
>
> Just been a fly on the wall for this convo, and aside from offering a
> specific solution, which others have done, I'm pretty certain this can be
> done with just protocols and records. Make a record (like your type) that
> implements the two protocols (like your interfaces). You could achieve your
> desired functionality without records and protocols but what you describe
> sounds like a fitting case for them.
>
> Members in such lists can be either other evaluable lists, or they can be
>> evaluable objects which perform computations
>>
>
> A simple Clojure list/vector can hold any type of data you put into it. So
> your record can hold a vector of these things, which can be represented as
> Clojure data structure (lists / maps / etc).
>
> You say you *need* to construct a type, but I urge you to challenge this
> assumption, again and again if needed. I think it's natural to think you
> need a type because of coming from Java/OOP land, especially if you were
> there a long time. Old patterns die hard?
>
> I could be wrong though. :)
>
>
> My 2 cents,
> Brandon
>
> On Sat, Aug 15, 2020 at 12:42 PM Jack Park 
> wrote:
>
>> Hi Erik,
>>
>> I think that teasing things apart helps along some dimensions, but the
>> problem I face, still thinking like a Java hacker, is that I need to put
>> things together:
>>
>> I need to construct a *type*  (deftype) which honors two different
>> interfaces, a list, and an evaluable object. I need the type because I want
>> to create it, then add members to the list, and then one of:
>> a) insert the object into another one (building and/or trees)
>> b) evaluate it - when it is the root of the tree.
>>
>> Members in such lists can be either other evaluable lists, or they can be
>> evaluable objects which perform computations - even with side effects - but
>> which return a boolean.
>>
>> The several ideas posted in this thread are greatly helping me to see
>> through this situation with fresh eyes, but, thus far, nothing has
>> convinced me to drop the goal of creating a type which is a list and
>> evaluable, into which I can insert conjunction or disjunction evaluators.
>>
>> Many thanks,
>> Jack
>>
>> On Sat, Aug 15, 2020 at 12:14 AM Erik Assum  wrote:
>>
>>> Why not tease things apart?
>>>
>>> (defn eval [x] ...)
>>>
>>> (some eval my-list) ;; or list
>>> (every? eval my-list) ;; and list
>>>
>>> https://clojuredocs.org/clojure.core/some
>>> https://clojuredocs.org/clojure.core/every_q
>>>
>>> Now, you can make the eval function polymorphic in several ways,
>>> simplest is to case or cond on some property of x. You could also use
>>> multimethods or a protocol to achieve this.
>>>
>>> https://insideclojure.org/2015/04/27/poly-perf/
>>>
>>> Erik.
>>> --
>>> i farta
>>>
>>> 15. aug. 2020 kl. 02:04 skrev matthew...@gmail.com <
>>> matthewdowne...@gmail.com>:
>>>
>>> 
>>>
>>> Another option would be to do what Alex is suggesting and define and as
>>> a function. Just because it’s a macro in clojure.core doesn’t mean you
>>> can’t write your own :)
>>>
>>> (defn eval' [x]
>>>   (if (map? x)
>>> (apply (:fn x) (:coll x))
>>> x))
>>>
>>> (defn and-list [& items]
>>>   (let [if? (fn [x] (if x true false))
>>> and' (fn [& args] (every? if? args))]
>>> {:fn and' :coll items}))
>>>
>>> (eval' true) ;=> true
>>> (eval' false) ;=> false
>>> (eval' (and-list 1 2 3)) ;=> true
>>> (eval' (and-list 1 2 3 false)) ;=> false
>>>
>>> Ditto with or.
>>> ​
>>> On Friday, August 14, 2020 at 4:27:19 PM UTC-5 jack...@topicquests.org
>>> wrote:
>>>
>>>> Alex,
>>>>
>>>> I plan to explore this idea.
>>>> Many thanks!
>>>>
>>>> Jack
>>>>
>>>> On Fri, Aug 14, 2020 at 1:38 PM Oleksandr Shulgin <
>>>> oleksand...@zalando.de> wrote:
>>>>
>>>>> 
>>>>>
>>>>>
>>>>> Nevermind transducers: I've just realized that reduced can be used
>>>>> with the normal reduce.  E.g. here's short-circuiting AND-reduction fn:
>>>>>
>>>>

Re: First post: how to mimic a Java List with types?

2020-08-15 Thread Jack Park
Hi Erik,

I think that teasing things apart helps along some dimensions, but the
problem I face, still thinking like a Java hacker, is that I need to put
things together:

I need to construct a *type*  (deftype) which honors two different
interfaces, a list, and an evaluable object. I need the type because I want
to create it, then add members to the list, and then one of:
a) insert the object into another one (building and/or trees)
b) evaluate it - when it is the root of the tree.

Members in such lists can be either other evaluable lists, or they can be
evaluable objects which perform computations - even with side effects - but
which return a boolean.

The several ideas posted in this thread are greatly helping me to see
through this situation with fresh eyes, but, thus far, nothing has
convinced me to drop the goal of creating a type which is a list and
evaluable, into which I can insert conjunction or disjunction evaluators.

Many thanks,
Jack

On Sat, Aug 15, 2020 at 12:14 AM Erik Assum  wrote:

> Why not tease things apart?
>
> (defn eval [x] ...)
>
> (some eval my-list) ;; or list
> (every? eval my-list) ;; and list
>
> https://clojuredocs.org/clojure.core/some
> https://clojuredocs.org/clojure.core/every_q
>
> Now, you can make the eval function polymorphic in several ways, simplest
> is to case or cond on some property of x. You could also use multimethods
> or a protocol to achieve this.
>
> https://insideclojure.org/2015/04/27/poly-perf/
>
> Erik.
> --
> i farta
>
> 15. aug. 2020 kl. 02:04 skrev matthew...@gmail.com <
> matthewdowne...@gmail.com>:
>
> 
>
> Another option would be to do what Alex is suggesting and define and as a
> function. Just because it’s a macro in clojure.core doesn’t mean you can’t
> write your own :)
>
> (defn eval' [x]
>   (if (map? x)
> (apply (:fn x) (:coll x))
> x))
>
> (defn and-list [& items]
>   (let [if? (fn [x] (if x true false))
> and' (fn [& args] (every? if? args))]
> {:fn and' :coll items}))
>
> (eval' true) ;=> true
> (eval' false) ;=> false
> (eval' (and-list 1 2 3)) ;=> true
> (eval' (and-list 1 2 3 false)) ;=> false
>
> Ditto with or.
> ​
> On Friday, August 14, 2020 at 4:27:19 PM UTC-5 jack...@topicquests.org
> wrote:
>
>> Alex,
>>
>> I plan to explore this idea.
>> Many thanks!
>>
>> Jack
>>
>> On Fri, Aug 14, 2020 at 1:38 PM Oleksandr Shulgin 
>> wrote:
>>
>>> 
>>>
>>>
>>> Nevermind transducers: I've just realized that reduced can be used with
>>> the normal reduce.  E.g. here's short-circuiting AND-reduction fn:
>>>
>>> (defn andr
>>>   ([] true)
>>>   ([i] i)
>>>   ([r i] (let [o (and r i)]
>>>(if o
>>>  o
>>>  (reduced o)
>>>
>>> When it comes to the actual lists, it depends how you'd like to
>>> represent them.  E.g. I could imagine something like the following can be a
>>> useful notation:
>>>
>>> [:and 1 2 [:or 3 4] 5]
>>>
>>> or even more direct:
>>>
>>> (quote (and 1 2 (or 3 4) 5))
>>>
>>> If you really want an interface-like look and feel, then protocols might
>>> be the right answer:
>>>
>>> (defprotocol Evaluable
>>>   (evaluate [this]))
>>>
>>> (defrecord AndList [items]
>>>   Evaluable
>>>   (evaluate [this]
>>> (reduce andr (:items this
>>>
>>> user> (evaluate (->AndList [1 2 3]))
>>> 3
>>> user> (evaluate (->AndList [1 false 3]))
>>> false
>>>
>>> To complete it, you'll need to add the OrList and sneak (map evaluate)
>>> in the reduce call in both And- and OrList.
>>>
>>> Cheers,
>>> --
>>> Alex
>>>
>> 
>>>
>> --
> 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/cfac729f-b8e4-4f95-94b0-78345d10f457n%40googlegroups.com
> 
> .
>
> --
> 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 

Re: First post: how to mimic a Java List with types?

2020-08-14 Thread Jack Park
Alex,

I plan to explore this idea.
Many thanks!

Jack

On Fri, Aug 14, 2020 at 1:38 PM Oleksandr Shulgin <
oleksandr.shul...@zalando.de> wrote:

> 
>
>
> Nevermind transducers: I've just realized that reduced can be used with
> the normal reduce.  E.g. here's short-circuiting AND-reduction fn:
>
> (defn andr
>   ([] true)
>   ([i] i)
>   ([r i] (let [o (and r i)]
>(if o
>  o
>  (reduced o)
>
> When it comes to the actual lists, it depends how you'd like to represent
> them.  E.g. I could imagine something like the following can be a useful
> notation:
>
> [:and 1 2 [:or 3 4] 5]
>
> or even more direct:
>
> (quote (and 1 2 (or 3 4) 5))
>
> If you really want an interface-like look and feel, then protocols might
> be the right answer:
>
> (defprotocol Evaluable
>   (evaluate [this]))
>
> (defrecord AndList [items]
>   Evaluable
>   (evaluate [this]
> (reduce andr (:items this
>
> user> (evaluate (->AndList [1 2 3]))
> 3
> user> (evaluate (->AndList [1 false 3]))
> false
>
> To complete it, you'll need to add the OrList and sneak (map evaluate) in
> the reduce call in both And- and OrList.
>
> Cheers,
> --
> Alex
> 
>

-- 
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/CAH6s0fwVA5zhAJVdUaEMZN%2BhzThM8XMU1VtEWcej3PogPmxoLg%40mail.gmail.com.


Re: First post: how to mimic a Java List with types?

2020-08-14 Thread Jack Park
Wow!

I say that because that might be getting closer to what I have in mind but
still not there yet.
I'm really trying to develop a type which honors two interfaces, one for
the list object, and one for the IEvaluable object.

As a type, I invoke it, then add objects to it, then place it, as an
IEvaluable object inside another such collection. Perhaps it is the first -
root - which begins an and/or network of IEvaluable objects, some of which
are the workers which go outside and make computations before returning
their boolean.

But, I have been wandering down another rabbit hole, the one where I ignore
list comprehensions and proxy an ArrayList.

I have code which almost runs, but which is far from perfect.
I created a gist which exposes my current experiment - which is close, but
no cigars yet.

https://gist.github.com/KnowledgeGarden/004fd93a78e2238c878b585f158759f9

Thanks
Jack

On Fri, Aug 14, 2020 at 1:38 PM Oleksandr Shulgin <
oleksandr.shul...@zalando.de> wrote:

> On Fri, Aug 14, 2020 at 8:44 PM Jack Park 
> wrote:
>
>> This idea shows up early in Clojure text books. This concept comes to
>> mind rather quickly:
>>
>> (def and_list (ArrayList.)
>>...
>> )
>>
>> But, in the end it is an ArrayList which has an interface-defined
>> behavior, e.g. boolean eval(); (from Java)
>> Thus far, in a tiny VSCode project, I defined
>>
>> (definterface IEvaluable
>>(^boolean runIt []))
>>
>> and defined a simple object which will return false and one which will
>> return true. I'll use those to populate a conjunctive and a disjunctive
>> list.
>>
>> Now I must define a list object which runs that interface.
>>
>> Still digging and experimenting, but, on the surface, this approach
>> appears to be possible.
>>
>> From above, as a sketch:
>>
>> (def and_list (ArrayList.)
>>   IEvaluable
>>   (runIt [this]
>>   ))
>> )
>>
>> Meanwhile, I found this https://clojuredocs.org/clojure.core/proxy-super
>> which is now on the table to explore.
>>
>
> Nevermind transducers: I've just realized that reduced can be used with
> the normal reduce.  E.g. here's short-circuiting AND-reduction fn:
>
> (defn andr
>   ([] true)
>   ([i] i)
>   ([r i] (let [o (and r i)]
>(if o
>  o
>  (reduced o)
>
> When it comes to the actual lists, it depends how you'd like to represent
> them.  E.g. I could imagine something like the following can be a useful
> notation:
>
> [:and 1 2 [:or 3 4] 5]
>
> or even more direct:
>
> (quote (and 1 2 (or 3 4) 5))
>
> If you really want an interface-like look and feel, then protocols might
> be the right answer:
>
> (defprotocol Evaluable
>   (evaluate [this]))
>
> (defrecord AndList [items]
>   Evaluable
>   (evaluate [this]
> (reduce andr (:items this
>
> user> (evaluate (->AndList [1 2 3]))
> 3
> user> (evaluate (->AndList [1 false 3]))
> false
>
> To complete it, you'll need to add the OrList and sneak (map evaluate) in
> the reduce call in both And- and OrList.
>
> Cheers,
> --
> Alex
>
> On Fri, Aug 14, 2020 at 3:41 AM Jesús Gómez  wrote:
>>
>>> Why not to Java-Interop with that Interface and those Classes directly,
>>> the same way you use them in Java?
>>>
>>> El jue., 13 ago. 2020 a las 22:54, Jack Park ()
>>> escribió:
>>>
>>>> The problem:
>>>>
>>>> In Java, I have an interface *IInferrable* which is basically  boolean
>>>> eval();
>>>>
>>>> Any Java object which extends IInferrable, no matter what it is, will
>>>> answer to eval() and return a boolean.
>>>> The idea lies at the heart of an inference engine.
>>>>
>>>> But, I also define a class *AndList* which implements IInferrable and
>>>> extends java.util.ArrayList
>>>>
>>>> So, AndList, and its sibling OrList behave just like a List object, but
>>>> also will answer to eval() by running the collection and dealing with what
>>>> each element returns when it, too, is eval()'d.
>>>>
>>>> I'd really love to discover how to pull that off in Clojure.
>>>>
>>>> Many thanks in advance. -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

Re: First post: how to mimic a Java List with types?

2020-08-14 Thread Jack Park
This idea shows up early in Clojure text books. This concept comes to mind
rather quickly:

(def and_list (ArrayList.)
   ...
)

But, in the end it is an ArrayList which has an interface-defined behavior,
e.g. boolean eval(); (from Java)
Thus far, in a tiny VSCode project, I defined

(definterface IEvaluable
   (^boolean runIt []))

and defined a simple object which will return false and one which will
return true. I'll use those to populate a conjunctive and a disjunctive
list.

Now I must define a list object which runs that interface.

Still digging and experimenting, but, on the surface, this approach appears
to be possible.

>From above, as a sketch:

(def and_list (ArrayList.)
  IEvaluable
  (runIt [this]
  ))
)

Meanwhile, I found this https://clojuredocs.org/clojure.core/proxy-super
which is now on the table to explore.

Many thanks
Jack

On Fri, Aug 14, 2020 at 3:41 AM Jesús Gómez  wrote:

> Why not to Java-Interop with that Interface and those Classes directly,
> the same way you use them in Java?
>
> El jue., 13 ago. 2020 a las 22:54, Jack Park ()
> escribió:
>
>> The problem:
>>
>> In Java, I have an interface *IInferrable* which is basically  boolean
>> eval();
>>
>> Any Java object which extends IInferrable, no matter what it is, will
>> answer to eval() and return a boolean.
>> The idea lies at the heart of an inference engine.
>>
>> But, I also define a class *AndList* which implements IInferrable and
>> extends java.util.ArrayList
>>
>> So, AndList, and its sibling OrList behave just like a List object, but
>> also will answer to eval() by running the collection and dealing with what
>> each element returns when it, too, is eval()'d.
>>
>> I'd really love to discover how to pull that off in Clojure.
>>
>> Many thanks in advance. -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/3e2ffc86-0e4f-4c0c-92c3-58e0848d5ba7o%40googlegroups.com
>> <https://groups.google.com/d/msgid/clojure/3e2ffc86-0e4f-4c0c-92c3-58e0848d5ba7o%40googlegroups.com?utm_medium=email_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/CAO9z-97N15E_17FRkDN_gbneXfkMkrS615RV5UwGMf3%2Bos%3DSLQ%40mail.gmail.com
> <https://groups.google.com/d/msgid/clojure/CAO9z-97N15E_17FRkDN_gbneXfkMkrS615RV5UwGMf3%2Bos%3DSLQ%40mail.gmail.com?utm_medium=email_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/CAH6s0fxiGQiZ4gUgEs42ScKWmxhQDtEd_N8bfgcbr2TObu7gww%40mail.gmail.com.


Re: First post: how to mimic a Java List with types?

2020-08-14 Thread Jack Park
Mapping and transducers seems appropriate, though I'm still wrapping my
head around how to make this work.
>From the "class with functions" mindset, I need an ArrayList into which I
can:
a) add members to the list from time to time
b) run eval() on it; a conjunctive list will exit false on first false
firing of any member, or default exit true otherwise; a disjunctive list
will exit true on first true firing of a member, and default false.

When I read the code here, I am not yet clear (sorry, it's  on me, not the
code) how to make such a "class-like" object.

I am still exploring this avenue, as well as looking at java-interop or
something about a proxy.

Many thanks.
Jack

On Fri, Aug 14, 2020 at 1:25 AM Oleksandr Shulgin <
oleksandr.shul...@zalando.de> wrote:

> On Fri, Aug 14, 2020 at 9:05 AM Oleksandr Shulgin <
> oleksandr.shul...@zalando.de> wrote:
>
>> On Fri, Aug 14, 2020 at 7:51 AM Alexandre Almosni <
>> alexandre.almo...@gmail.com> wrote:
>>
>>> Maybe your objects could be defined by a map containing functions and
>>> objects.
>>>
>>> So exampleAndList = {:fn and, :coll [a b c]}
>>>
>>>
>>> And then eval goes through your objects recursively, using
>>>
>>> (def eval [o]
>>> (apply (:fn o) (map eval (:coll o
>>>
>>> - with a special case that if o is not a map but say a Boolean you just
>>> return itself
>>>
>>
>> A slight problem with that approach is that clojure.core/and is not a
>> function, but a macro: the reason being is that it stops evaluating forms
>> as soon as it hits a falsey value (similar for "or").
>> A smart implementation of And/OrList would like to short-circuit as well
>> I guess, so you'll need to express that somehow.
>>
>> Of the clojure.core library that property is satisfied by transducers:
>> https://clojure.org/reference/transducers#_early_termination
>>
>
> I came up with the following:
>
> ;; and-transducer with early termination:
>  (defn xand [rf]
>(fn
>  ([] (rf))
>  ([res] (rf res))
>  ([res inp] (if inp
>   (rf res inp)
>   (reduced inp)
>
> ;; reducing function implementing and:
>   (defn andr
>([] true)
>([i] i)
>([r i] (and r i)))
>
> ;; noisy variant of get:
>  (defn noisy-get
>   ([k]
>(fn [m]
>  (noisy-get m k)))
>   ([m k]
>(println "noisy-get" m k)
>(get m k)))
>
> ;; all in action:
> user> (def xf (comp (map (noisy-get :data))
> xand))
> #'user/xf
> user> (transduce xf andr [{:data 1} {:data false} {:no-data 3}])
> noisy-get {:data 1} :data
> noisy-get {:data false} :data
> false
> user> (transduce xf andr [{:data 1} {:data 2} {:no-data 3} {:data 4}])
> noisy-get {:data 1} :data
> noisy-get {:data 2} :data
> noisy-get {:no-data 3} :data
> nil
> user> (transduce xf andr [{:data 1} {:data 2} {:data 3} {:data 4}])
> noisy-get {:data 1} :data
> noisy-get {:data 2} :data
> noisy-get {:data 3} :data
> noisy-get {:data 4} :data
> 4
>
> It does feel a bit redundant to have the reducing function on top of a
> transducer that accomplishes mostly the same, but I haven't found a way to
> make it shorter.
>
> Cheers,
> --
> Alex
>
>> On 14 Aug 2020, at 02:24, Jack Park  wrote:
>>>
>>> 
>>> The problem:
>>>
>>> In Java, I have an interface *IInferrable* which is basically  boolean
>>> eval();
>>>
>>> Any Java object which extends IInferrable, no matter what it is, will
>>> answer to eval() and return a boolean.
>>> The idea lies at the heart of an inference engine.
>>>
>>> But, I also define a class *AndList* which implements IInferrable and
>>> extends java.util.ArrayList
>>>
>>> So, AndList, and its sibling OrList behave just like a List object, but
>>> also will answer to eval() by running the collection and dealing with what
>>> each element returns when it, too, is eval()'d.
>>>
>>> I'd really love to discover how to pull that off in Clojure.
>>>
>>>
>
> --
> 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
> -

First post: how to mimic a Java List with types?

2020-08-13 Thread Jack Park
The problem:

In Java, I have an interface *IInferrable* which is basically  boolean 
eval();

Any Java object which extends IInferrable, no matter what it is, will 
answer to eval() and return a boolean.
The idea lies at the heart of an inference engine.

But, I also define a class *AndList* which implements IInferrable and 
extends java.util.ArrayList

So, AndList, and its sibling OrList behave just like a List object, but 
also will answer to eval() by running the collection and dealing with what 
each element returns when it, too, is eval()'d.

I'd really love to discover how to pull that off in Clojure.

Many thanks in advance. -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/3e2ffc86-0e4f-4c0c-92c3-58e0848d5ba7o%40googlegroups.com.