Re: Why is next.jdbc using my IP address?

2022-03-04 Thread Cora Sutton
And also change your password now.

On Fri, Mar 4, 2022 at 8:09 AM Orestis Markou  wrote:

> You might need to quote the string with single quotes, otherwise bash will
> probably try and interpolate a var `$n`...
>
>
> On 4 Mar 2022, at 15.58, Lawrence Krubner  wrote:
>
> Okay, this seems to have to do with characters acting as wildcards in the
> password itself. This is in the .env file:
>
> vvv*8Ezr30R%$n?L5!
>
> but printlin in the Clojure code outputs:
>
> vvv*8Ezr30R%?L5!
>
> The "$n" simply vanishes.
>
> Why is that? This is not a regular expression. I didn't think plain
> strings in Clojure would be interpreted like this.
>
> Or is this how bash interprets it?
>
>
>
>
> On Friday, March 4, 2022 at 8:06:56 AM UTC-5 Lawrence Krubner wrote:
>
>> So, as a new way to test this, I've ssh'ed to an EC2 instance that is in
>> the same VCP as the RDS database. I upload my jar file so I can run it on
>> this EC2 instance.
>>
>> println the hash map at startup:
>>
>> {:dbtype mysql, :dbname pulsedata, :user pulseuser, :password , :host
>>  pulse-data.cclr8stksfch.us-west-2.rds.amazonaws.com}
>> This gets me the above error. But if I copy and paste the values and use
>> them with the mysql client:
>>
>> mysql -u pulseuser -h pulse-data.cclr8stksfch.us-west-2.rds.amazonaws.com
>>  -p pulsedata
>>
>> I am able to log in. This is in the same terminal window: the MySQL
>> client, at the command line in my terminal, logs me into MySQL, but "java
>> -jar user.jar" in the same terminal window gives me this error, about me
>> being rejected. I am copying and pasting the same values for user and host
>> and password.
>>
>> It has to be something about the Clojure code.
>>
>>
>> On Friday, March 4, 2022 at 6:35:59 AM UTC-5 ore...@orestis.gr wrote:
>>
>>> The error message indicates that you connect with user `pulseuser` - is
>>> that the expected user?
>>>
>>> I would print out the configuration that you’re passing in to jdbc.next
>>> to be absolutely certain it contains the values you expect it does.
>>>
>>> When you say “cli”, do you mean a mysql client? Double check the
>>> credentials (dbname, user, password) that *it* uses.
>>>
>>> Best,
>>> Orestis
>>>
>>> On 4 Mar 2022, at 13.27, Lawrence Krubner  wrote:
>>>
>>> But, again, I can connect from the cli using my terminal. I'm using my
>>> Spectrum connection to the Internet in both cases. If I run the app on my
>>> laptop, or I connect from the terminal, using the CLI, then in all cases
>>> I'm connecting over my Spectrum connection to the Internet. If MySQL was
>>> going to block one, then it would block the other, yes? I think the issue
>>> must have something to do with the Clojure code, since that is the only
>>> difference. I mean, if I do "java -jar user.jar" in the same terminal
>>> window, it fails, but then in that same terminal window I can connect to
>>> RDS without a problem using the CLI.
>>>
>>>
>>> On Thursday, March 3, 2022 at 3:26:31 PM UTC-5 red...@gmail.com wrote:
>>>
 That is a message from MySQL, not next.jdbc.

 MySQL allows you to grant permissions to a user base on the host they
 are connecting from so permission denied kinds of errors include the
 username and the host the users connection came from.

 On Thu, Mar 3, 2022, 11:18 Lawrence Krubner 
 wrote:

> I just wrote a small app that needs to connect to a MySQL app. I was
> running it on my laptop, connecting to MySQL on the laptop, and everything
> was working fine. Then I wanted to connect to one of our test databases in
> RDS in AWS. I've a simple function that finds the environment variables 
> and
> returns them as a map:
>
> (defn get-config
>   []
>   (check-config)
>   {
>:dbtype "mysql"
>:dbname (System/getenv "DATABASE_NAME")
>:user (System/getenv "DATABASE_USER")
>:password (System/getenv "DATABASE_PASSWORD")
>:host (System/getenv "DATABASE_HOST")
>})
>
> This is used simply:
>   ds (jdbc/get-datasource  (get-config))
>
> I've checked the environment values several times and they are
> correct. But when the code tries to write to the RDS database, I get:
>
> *java.sql.SQLException*: *Access denied for user
> 'pulseuser'@'cpe-74-71-234-49.nyc.res.rr.com
> ' (using password: YES)*
>
> I am connecting to the Internet through Spectrum, and apparently "
> rr.com" is Spectrum. I'm confused, why would next.jdbc use this info?
> Did I forget some important value in the hash map?
>
> From my laptop, I can reach the RDS database using the MySQL CLI, so
> there are no problems with connectivity. I whitelisted the IP address of 
> my
> house. This is something specific about what next.jdbc needs in that hash
> map, I think.
>
>
>
> --
> You received this message because you are subscribed to the Google
> Groups 

Re: common ways to run regex against either Hickory HTML or zippers?

2022-02-02 Thread Cora Sutton
If all you're looking for is the format CVE--N then by all means
just use regex against the plain text of the page. If you need to do dom
traversal then jsoup is a good choice. Otherwise, like Mark said, tree-seq
is a great choice if you don't want to play with clojure.walk.

On Wed, Feb 2, 2022 at 2:58 PM Mark Nutter  wrote:

> I don't know how common it is, but have you looked at the `tree-seq`
> function in Clojure? This seems like a good use case for it.
>
> Mark
>
> On Wed, Feb 2, 2022 at 3:22 PM lawrence...@gmail.com <
> lawrence.krub...@gmail.com> wrote:
>
>> Assume I've been cursed to scrape HTML. If I convert the pages to Hickory
>> I end up with a big mass of data which, sadly, lacks many "class" or "id"s
>> that would let me easily pick out the data I need. However, for the most
>> part, the only thing I really need off this page is the CVEs, which look
>> like this:
>>
>> CVE-2021-40539
>>
>> I'm thinking I might write regex against the plain text of the page, but
>> I'm also curious, is it common to take something like Hiccup or Hickory or
>> a zipper and run regex through it? If yes, how is that done?
>>
>> A small part of the data looks like this:
>>
>> :content
>> [{:type :element,
>>   :attrs
>>   {:class "tip-intro", :style "font-size: 15px;"},
>>   :tag :p,
>>   :content
>>   [{:type :element,
>> :attrs nil,
>> :tag :em,
>> :content
>> ["This Joint Cybersecurity Advisory uses the MITRE
>> Adversarial Tactics, Techniques, and Common Knowledge (ATT®) framework,
>> Version 8. See the "
>>  {:type :element,
>>   :attrs
>>   {:href
>>"
>> https://attack.mitre.org/versions/v9/techniques/enterprise/"},
>>   :tag :a,
>>   :content ["ATT for Enterprise"]}
>>  " for  referenced threat actor tactics and for
>> techniques."]}]}
>>  "\n\n"
>>  {:type :element,
>>   :attrs nil,
>>   :tag :p,
>>   :content
>>   ["This joint advisory is the result of analytic efforts
>> between the Federal Bureau of Investigation (FBI), United States Coast
>> Guard Cyber Command (CGCYBER), and the Cybersecurity and Infrastructure
>> Security Agency (CISA) to highlight the cyber threat associated with active
>> exploitation of a newly identified vulnerability (CVE-2021-40539) in
>> ManageEngine ADSelfService Plus—a self-service password management and
>> single sign-on solution."]}
>>  "\n\n"
>>  {:type :element,
>>   :attrs nil,
>>   :tag :p,
>>   :content
>>   ["CVE-2021-40539, rated critical by the Common
>> Vulnerability Scoring System (CVSS), is an authentication bypass
>> vulnerability affecting representational state transfer (REST) application
>> programming interface (API) URLs that could enable remote code execution.
>> The FBI, CISA, and CGCYBER assess that advanced persistent threat (APT)
>> cyber actors are likely among those exploiting the vulnerability. The
>> exploitation of ManageEngine ADSelfService Plus poses a serious risk to
>> critical infrastructure companies, U.S.-cleared defense contractors,
>> academic institutions, and other entities that use the software. Successful
>> exploitation of the vulnerability allows an attacker to place webshells,
>> which enable the adversary to conduct post-exploitation activities, such as
>> compromising administrator credentials, conducting lateral movement, and
>> exfiltrating registry hives and Active Directory files."]}
>>  "\n\n"
>>
>> --
>> 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/5f2bd2a4-5c35-463b-9cb4-eecb9148fc89n%40googlegroups.com
>> 
>> .
>>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to 

Re: Strange Vector failure

2021-07-24 Thread Cora Sutton
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)))
>>>>>   (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)
>>>>>>
>>>>>

Re: Strange Vector failure

2021-07-23 Thread Cora Sutton
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$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 function

Re: Strange Vector failure

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

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

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

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

> Did. That suggestion was made earlier. Did not change anything.
>
> Here's a test which ran just fine
> (def x (evaluate_and (list true true)))
>   (println "A" x)
>   (def y (evaluate_and (list true false)))
>   (println "B" y)
>
> But, the moment I attempt to make a list with two functions in it, the
> code breaks and returns - without any errors - not a boolean, but the
> structure I passed it.
>
>
> On Mon, Jul 19, 2021 at 3:43 PM Cora Sutton  wrote:
>
>> Those are functions that call booleans as functions. Try this:
>>
>> (defn simple-true [] true)
>>
>> On Mon, Jul 19, 2021 at 5:41 PM Jack Park 
>> wrote:
>>
>>> Great points!
>>> They are filled with functions which look like this
>>>
>>> (defn simple_true [] (true))
>>>
>>> They are not booleans but functions which return a boolean.
>>> Here is a list of two of those as produced by the code:
>>>
>>> (#object[ie4clj.Tests$simple_false 0x3a4621bd
>>> ie4clj.Tests$simple_false@3a4621bd]
>>>  #object[ie4clj.Tests$simple_false 0x3a4621bd
>>> ie4clj.Tests$simple_false@3a4621bd])
>>>
>>> Or maybe I missed something.
>>>
>>> On Mon, Jul 19, 2021 at 3:33 PM Cora Sutton  wrote:
>>>
>>>> Your members list needs to be filled with things that can be called as
>>>> functions, since that's what that code snippet does, and booleans
>>>> definitely cannot be called as functions. That's what the error means,
>>>> there's a boolean in your list and it's trying to cast it to an IFn (a
>>>> Clojure function interface) when it is called as (member).
>>>>
>>>> Can you show the lists you construct? Are they full of functions that
>>>> take no arguments? Do you want the lists to be able to contain booleans 
>>>> too?
>>>>
>>>> On Mon, Jul 19, 2021 at 2:57 PM Jack Park 
>>>> wrote:
>>>>
>>>>> Cora
>>>>>
>>>>> (every? (fn [member] (member)) members)
>>>>> works fine on [constantly true & false
>>>>> but fails with
>>>>> java.lang.Boolean cannot be cast to clojure.lang.IFn
>>>>> on the lists I construct.
>>>>>
>>>>> In truth, I thought all the code was working, but that turned out ot
>>>>> be an artifact of the test I designed. When I changed the test conditions,
>>>>> evaluate_and failed.
>>>>>
>>>>>
>>>>> On Sun, Jul 18, 2021 at 5:00 PM Cora Sutton  wrote:
>>>>>
>>>>>> Hello again Jack,
>>>>>>
>>>>>> On Sun, Jul 18, 2021 at 6:21 PM Jack Park 
>>>>>> wrote:
>>>>>>
>>>>>>> (every? eval members)  does not appear to work on a list of
>>>>>>> functions designed to evaluate to a boolean.
>>>>>>>
>>>>>>
>>>>>> If members is a list of functions then you would do:
>>>>>>
>>>>>> (every? (fn [member] (member)) members)
>>>>>>
>>>>>> Showing it work here:
>>>>>>
>>>>>> (every? (fn [member] (member)) [(constantly true) (constantly true)])
>>>>>> ;; => true
>>>>>> (every? (fn [member] (member)) [(constantly true) (constantly false)])
>>>>>> ;; => false
>>>>>>
>>>>>>
>>>>>>> That code is used in a function evaluateAnd
>>>>>>>
>>>>>>> Two simple tests
>>>>>>> (evaluateAnd [true true] --> true
>>>>>>> (evaluateAnd [true false] --> nil (why not "false" as the every?
>>>>>>> examples show?)
>>>>>>>
>>>>>>
>>>>>> In Clojure things are either "truthy" or "falsey", and the only
>>>>>> "false" values are false and nil so returning nil is usually fine.
>>>>>

Re: Strange Vector failure

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

(defn simple-true [] true)

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

> Great points!
> They are filled with functions which look like this
>
> (defn simple_true [] (true))
>
> They are not booleans but functions which return a boolean.
> Here is a list of two of those as produced by the code:
>
> (#object[ie4clj.Tests$simple_false 0x3a4621bd
> ie4clj.Tests$simple_false@3a4621bd]
>  #object[ie4clj.Tests$simple_false 0x3a4621bd
> ie4clj.Tests$simple_false@3a4621bd])
>
> Or maybe I missed something.
>
> On Mon, Jul 19, 2021 at 3:33 PM Cora Sutton  wrote:
>
>> Your members list needs to be filled with things that can be called as
>> functions, since that's what that code snippet does, and booleans
>> definitely cannot be called as functions. That's what the error means,
>> there's a boolean in your list and it's trying to cast it to an IFn (a
>> Clojure function interface) when it is called as (member).
>>
>> Can you show the lists you construct? Are they full of functions that
>> take no arguments? Do you want the lists to be able to contain booleans too?
>>
>> On Mon, Jul 19, 2021 at 2:57 PM Jack Park 
>> wrote:
>>
>>> Cora
>>>
>>> (every? (fn [member] (member)) members)
>>> works fine on [constantly true & false
>>> but fails with
>>> java.lang.Boolean cannot be cast to clojure.lang.IFn
>>> on the lists I construct.
>>>
>>> In truth, I thought all the code was working, but that turned out ot be
>>> an artifact of the test I designed. When I changed the test conditions,
>>> evaluate_and failed.
>>>
>>>
>>> On Sun, Jul 18, 2021 at 5:00 PM Cora Sutton  wrote:
>>>
>>>> Hello again Jack,
>>>>
>>>> On Sun, Jul 18, 2021 at 6:21 PM Jack Park 
>>>> wrote:
>>>>
>>>>> (every? eval members)  does not appear to work on a list of functions
>>>>> designed to evaluate to a boolean.
>>>>>
>>>>
>>>> If members is a list of functions then you would do:
>>>>
>>>> (every? (fn [member] (member)) members)
>>>>
>>>> Showing it work here:
>>>>
>>>> (every? (fn [member] (member)) [(constantly true) (constantly true)])
>>>> ;; => true
>>>> (every? (fn [member] (member)) [(constantly true) (constantly false)])
>>>> ;; => false
>>>>
>>>>
>>>>> That code is used in a function evaluateAnd
>>>>>
>>>>> Two simple tests
>>>>> (evaluateAnd [true true] --> true
>>>>> (evaluateAnd [true false] --> nil (why not "false" as the every?
>>>>> examples show?)
>>>>>
>>>>
>>>> In Clojure things are either "truthy" or "falsey", and the only "false"
>>>> values are false and nil so returning nil is usually fine. Everything else
>>>> is "truthy". I wouldn't worry about it returning nil since other things
>>>> were broken anyways.
>>>>
>>>> https://clojure.org/guides/learn/flow#_truth
>>>>
>>>>
>>>>> The specific code for building the list of functions is this
>>>>>
>>>>> (def x (atom []))
>>>>>   (let [result (list (ref SimpleTrue) (ref SimpleFalse))]
>>>>> (println "BAL1" result )
>>>>> (reset! x result)
>>>>> )
>>>>>   (println "BAL2" @x )
>>>>>
>>>>>   (@x) <<<< returns the atom's value
>>>>>
>>>>> And the final println is this
>>>>>
>>>>> BAL2 (#object[clojure.lang.Ref 0x335b5620 {:status :ready, :val
>>>>> #object[ie4clj.Tests$SimpleTrue 0x6eb2384f 
>>>>> ie4clj.Tests$SimpleTrue@6eb2384f]}]
>>>>> #object[clojure.lang.Ref 0x3c9c0d96 {:status :ready, :val
>>>>> #object[ie4clj.Tests$SimpleFalse 0x31dadd46
>>>>> ie4clj.Tests$SimpleFalse@31dadd46]}])
>>>>>
>>>>> evaluateAnd never saw the result, with this error message
>>>>>
>>>>> clojure.lang.PersistentList cannot be cast to clojure.lang.IFn
>>>>>
>>>>
>>>> Refs are the wrong thing to use here. In fact I'd stay away from atoms
>>>> and refs unless you have multiple threads that need to mutate the same
>>&g

Re: Strange Vector failure

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

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

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

> Cora
>
> (every? (fn [member] (member)) members)
> works fine on [constantly true & false
> but fails with
> java.lang.Boolean cannot be cast to clojure.lang.IFn
> on the lists I construct.
>
> In truth, I thought all the code was working, but that turned out ot be an
> artifact of the test I designed. When I changed the test conditions,
> evaluate_and failed.
>
>
> On Sun, Jul 18, 2021 at 5:00 PM Cora Sutton  wrote:
>
>> Hello again Jack,
>>
>> On Sun, Jul 18, 2021 at 6:21 PM Jack Park 
>> wrote:
>>
>>> (every? eval members)  does not appear to work on a list of functions
>>> designed to evaluate to a boolean.
>>>
>>
>> If members is a list of functions then you would do:
>>
>> (every? (fn [member] (member)) members)
>>
>> Showing it work here:
>>
>> (every? (fn [member] (member)) [(constantly true) (constantly true)])
>> ;; => true
>> (every? (fn [member] (member)) [(constantly true) (constantly false)])
>> ;; => false
>>
>>
>>> That code is used in a function evaluateAnd
>>>
>>> Two simple tests
>>> (evaluateAnd [true true] --> true
>>> (evaluateAnd [true false] --> nil (why not "false" as the every?
>>> examples show?)
>>>
>>
>> In Clojure things are either "truthy" or "falsey", and the only "false"
>> values are false and nil so returning nil is usually fine. Everything else
>> is "truthy". I wouldn't worry about it returning nil since other things
>> were broken anyways.
>>
>> https://clojure.org/guides/learn/flow#_truth
>>
>>
>>> The specific code for building the list of functions is this
>>>
>>> (def x (atom []))
>>>   (let [result (list (ref SimpleTrue) (ref SimpleFalse))]
>>> (println "BAL1" result )
>>> (reset! x result)
>>> )
>>>   (println "BAL2" @x )
>>>
>>>   (@x) <<<< returns the atom's value
>>>
>>> And the final println is this
>>>
>>> BAL2 (#object[clojure.lang.Ref 0x335b5620 {:status :ready, :val
>>> #object[ie4clj.Tests$SimpleTrue 0x6eb2384f 
>>> ie4clj.Tests$SimpleTrue@6eb2384f]}]
>>> #object[clojure.lang.Ref 0x3c9c0d96 {:status :ready, :val
>>> #object[ie4clj.Tests$SimpleFalse 0x31dadd46
>>> ie4clj.Tests$SimpleFalse@31dadd46]}])
>>>
>>> evaluateAnd never saw the result, with this error message
>>>
>>> clojure.lang.PersistentList cannot be cast to clojure.lang.IFn
>>>
>>
>> Refs are the wrong thing to use here. In fact I'd stay away from atoms
>> and refs unless you have multiple threads that need to mutate the same
>> values. They're just confusing things now, I think.
>>
>>
>>>
>>> The test which fails is this
>>>
>>>  (def result (evaluateAnd  (buildAndList) ))  <<< fails here
>>>   (println "bar" result)
>>>   (result)
>>>
>>> The googleverse seems to agree that there are extra parens around the
>>> value. Google isn't giving me an obvious way to take that value outside of
>>> its surrounding parens (bal2 above).
>>> Still looking, and hoping that solves the problem.
>>> Maybe there's a way to go back to buildAndList and not return the value
>>> with parens.
>>>
>>
>> I think a key thing to explain is that in Clojure generally you're not
>> making new types of collections. There's this famous-ish saying that
>> Clojure holds to pretty well:
>>
>> "It is better to have 100 functions operate on one data structure than 10
>> functions on 10 data structures."
>> - Alan Perlis
>>
>> Most functions in the Clojure world operate on a handful of basic data
>> types and structures. This makes it really easy to chain and combine
>> functions to slice and dice data since you don't need to convert between
>> types.
>>
>> I don't think I've ever made a special c

Re: Strange Vector failure

2021-07-18 Thread Cora Sutton
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).
>>>> 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 

Re: Strange Vector failure

2021-07-18 Thread Cora Sutton
Hello again Jack,

On Sun, Jul 18, 2021 at 6:21 PM Jack Park  wrote:

> (every? eval members)  does not appear to work on a list of functions
> designed to evaluate to a boolean.
>

If members is a list of functions then you would do:

(every? (fn [member] (member)) members)

Showing it work here:

(every? (fn [member] (member)) [(constantly true) (constantly true)])
;; => true
(every? (fn [member] (member)) [(constantly true) (constantly false)])
;; => false


> That code is used in a function evaluateAnd
>
> Two simple tests
> (evaluateAnd [true true] --> true
> (evaluateAnd [true false] --> nil (why not "false" as the every? examples
> show?)
>

In Clojure things are either "truthy" or "falsey", and the only "false"
values are false and nil so returning nil is usually fine. Everything else
is "truthy". I wouldn't worry about it returning nil since other things
were broken anyways.

https://clojure.org/guides/learn/flow#_truth


> The specific code for building the list of functions is this
>
> (def x (atom []))
>   (let [result (list (ref SimpleTrue) (ref SimpleFalse))]
> (println "BAL1" result )
> (reset! x result)
> )
>   (println "BAL2" @x )
>
>   (@x) <<<< returns the atom's value
>
> And the final println is this
>
> BAL2 (#object[clojure.lang.Ref 0x335b5620 {:status :ready, :val
> #object[ie4clj.Tests$SimpleTrue 0x6eb2384f ie4clj.Tests$SimpleTrue@6eb2384f]}]
> #object[clojure.lang.Ref 0x3c9c0d96 {:status :ready, :val
> #object[ie4clj.Tests$SimpleFalse 0x31dadd46
> ie4clj.Tests$SimpleFalse@31dadd46]}])
>
> evaluateAnd never saw the result, with this error message
>
> clojure.lang.PersistentList cannot be cast to clojure.lang.IFn
>

Refs are the wrong thing to use here. In fact I'd stay away from atoms and
refs unless you have multiple threads that need to mutate the same values.
They're just confusing things now, I think.


>
> The test which fails is this
>
>  (def result (evaluateAnd  (buildAndList) ))  <<< fails here
>   (println "bar" result)
>   (result)
>
> The googleverse seems to agree that there are extra parens around the
> value. Google isn't giving me an obvious way to take that value outside of
> its surrounding parens (bal2 above).
> Still looking, and hoping that solves the problem.
> Maybe there's a way to go back to buildAndList and not return the value
> with parens.
>

I think a key thing to explain is that in Clojure generally you're not
making new types of collections. There's this famous-ish saying that
Clojure holds to pretty well:

"It is better to have 100 functions operate on one data structure than 10
functions on 10 data structures."
- Alan Perlis

Most functions in the Clojure world operate on a handful of basic data
types and structures. This makes it really easy to chain and combine
functions to slice and dice data since you don't need to convert between
types.

I don't think I've ever made a special collection type in Clojure, it's not
all that common. So I'd suggest that while you're at this point in your
journey you try to stick to the built-in Clojure collection types and use
the built-in functions to operate on them.

To give you a little direction, instead of a Person object you could make a
hashmap like {:first-name "Jack" :last-name "Park"} and pass that around.
And then you can make a function that operates on that.

(defn full-name
  [person]
  (str (get person :first-name) " " (get person :last-name)))

And then you could expand that to maybe {:first-name "Jack" :last-name
"Park" :people-talked-to-on-mailing-list ["Cora Sutton"]} and then operate
on a collection of people like:

(defn people-talked-to-on-mailing-list
  [person all-people]
  (let [people-to-find (set (get person :people-talked-to-on-mailing-list))]
(filter (fn [p]
  (people-to-find (full-name p))
all-people))

(people-talked-to-on-mailing-list jack all-people)
;; => {:first-name "Cora" :last-name "Sutton"
:people-talked-to-on-mailing-list ["Jack Park"]}



> On Sun, Jul 18, 2021 at 11:23 AM Cora Sutton  wrote:
>
>> Hi Jack!
>>
>> I could be wrong but I think this could just be: (every? eval members)
>>
>> I see a few things here that seem strange to me so I wanted to share a
>> few points that might be helpful (or might not, let me know either way) for
>> future code.
>>
>> * So typically you don't want to def or defn within another function call
>> since that will define a new value at the top level.
>>
>> (defn foo []
>>   (def bar 1)
>>   (println (inc bar))
>>
>> (foo)
>> ;; ^^ calling fo

Re: Strange Vector failure

2021-07-18 Thread Cora Sutton
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 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://cloj

Re: Strange Vector failure

2021-07-18 Thread Cora Sutton
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 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:
>>>
>

Re: Strange Vector failure

2021-07-18 Thread Cora Sutton
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 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]
>>   

Re: Strange Vector failure

2021-07-18 Thread Cora Sutton
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:
> :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
> 
> .
>

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

Re: [ANN] Discontinuing 4clojure.com

2021-07-05 Thread Cora Sutton
Thanks so much for 4clojure! Tools like this help so many people and helped
me in particularly when I was just getting started.

I am in no way affiliated with them but
https://exercism.io is another site with code challenges that I used for
clojure while I was learning it.

On Mon, Jul 5, 2021 at 12:23 PM Gary Verhaegen 
wrote:

> Thanks a lot for keeping it running for so long! 4clojure was really
> instrumental in my Clojure journey.
>
> On Sun, 4 Jul 2021 at 22:26, Alan Malloy  wrote:
>
>> TL;DR: Turning off 4clojure.com by the end of July 2021
>>
>> Hello, 4clojure problem solvers. You've probably noticed SSL errors on
>> 4clojure.com over the last week. The old decrepit system 4clojure runs
>> on has finally gotten out of date enough that I can't even figure out how
>> to get it recent enough that SSL certs will auto-renew anymore.
>>
>> In principle I could start from scratch on a new server and move 4clojure
>> over, but I won't. 4clojure has been piggybacking along on a server that I
>> use for personal reasons, and over the years I have less and less reason to
>> keep paying for that server - it's now pretty much just 4clojure costing me
>> an embarrassing amount of money every month because I haven't wanted to
>> disappoint the community by shutting it down. This SSL thing is just what
>> made me finally pull the trigger.
>>
>> I don't have a specific EOL date in mind, but sometime near the end of
>> the month, since that's the billing cycle. Until that time, 4clojure still
>> works, as long as you don't mind clicking through the security warnings -
>> it really is still me hosting the site, and since the connection is still
>> HTTPS (albeit with an invalid cert) I think that means your data is still
>> safe. If you have solutions to problems you're proud of, you've still got
>> some time to print them out and put them up on your refrigerator.
>>
>> I'm not seeking new maintainers. I'd feel uncomfortable handing over a
>> database with so many email addresses and password hashes in it to anyone.
>> The service has had a good run - just over a decade since the first
>> release
>> .
>> I hope you enjoyed it during that time.
>>
>> --
>> 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/385cdef8-fa40-47ba-b5b1-0b3a7cc34935n%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 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/CAGqyAaqMztmQqLdax2Z-d-qOS_qaQqsMFvykosDVe655hkQ8mw%40mail.gmail.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 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/CAMZDCY3o%2BROLGQg4m29%2Bkqkeafbo0TXzvLMnUCfvCrpGgsD3VA%40mail.gmail.com.