beginners

Getting started with Clojure/ClojureScript? Welcome! Also try: https://ask.clojure.org. Check out resources at https://gist.github.com/yogthos/be323be0361c589570a6da4ccc85f58f.
practicalli-john 2021-07-01T10:34:29.296800Z

I would like to understand all of this Clojure error message (not just the first line)

class java.lang.Long cannot be cast to class clojure.lang.IFn (java.lang.Long
   is in module java.base of loader 'bootstrap'; clojure.lang.IFn is in unnamed
   module of loader 'app')
The error is from evaluating (1) as an expression, which I expect to fail as 1 is not defined as a function anywhere in the code. So this explains the java.lang.Long is not a clojure.lang.IFn part of the message. I assume the second line is referring to the name of the class loader used to include java.lang in the JVM of the REPL. Is app a specific class loader for all code in the REPL? I see this last part of the message in many error messages and its about time I understood what it means :)

alexmiller 2021-07-01T13:33:13.298Z

that's correct

alexmiller 2021-07-01T13:34:26.299300Z

it's also including module information - since Java 9, there is a module loading system in Java and the java.base module includes the core set of modules needed to start Java (other modules can be added as needed). for backwards compatibility you can still mostly ignore the module stuff but then you're loading stuff in the "unnamed" module

👍 1
ghadi 2021-07-01T13:35:26.299900Z

https://docs.oracle.com/en/java/javase/16/docs/api/java.base/java/lang/ClassLoader.html lots of info about the classloader chain here ^

👍 1
popeye 2021-07-01T15:36:07.304200Z

I have a scenario, where my function will execute more than 10 mins which is expected, I want to stop the execution if it reaches more than 10 mins, How can I achieve it in clojure ?

bnstvn 2021-07-02T09:30:15.359Z

what does it depend on exactly whether (future-cancel) works or not? current thread state?

2021-07-02T17:28:57.410300Z

I linked the Thread.interrupt docs above (future-cancel uses that method): > If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException. > > If this thread is blocked in an I/O operation upon an InterruptibleChannel then the channel will be closed, the thread's interrupt status will be set, and the thread will receive a ClosedByInterruptException. > > If this thread is blocked in a Selector then the thread's interrupt status will be set and it will return immediately from the selection operation, possibly with a non-zero value, just as if the selector's wakeup method were invoked. > > If none of the previous conditions hold then this thread's interrupt status will be set

2021-07-02T17:29:47.410500Z

it always "works" in that if the thread in question doesn't invoke any of the specific methods mentioned there, a flag is set and you can check the flag

2021-07-02T17:30:25.410700Z

it "doesn't work" in that if you are doing work that never uses any of those methods, and don't check that flag, it has no effect on the thread's execution

2021-07-02T17:32:19.410900Z

there's a more powerful method to force stop a thread (which some code shared above uses), but there are no guarantees about safety when you use that, and it can crash the vm or leave objects in inconsistent states or leave locks that can't be unlocked

2021-07-02T17:33:21.411100Z

the code shared above is arguably OK, because it's for a IRC bot that's mainly there for entertainment and education and if it crashes it auto restarts

2021-07-02T17:33:33.411300Z

your code might deal with something more serious where those risks are not OK

bnstvn 2021-07-06T07:30:42.106700Z

thank you! so as plain function doesnt have an periodic interrupt check, if it is busy inside intensive computation interrupt does nothing — while if io is happening an exception will be raised (but still possible it will be swallowed i guess?)

Fredrik 2021-07-01T15:39:41.304500Z

What is your function doing? Listening on a socket, processing data in a loop?

popeye 2021-07-01T15:40:45.304700Z

My function doing caluclation on huge data, if it take more time I need to return nil , - which is my requirement

2021-07-01T15:44:01.304900Z

https://clojuredocs.org/clojure.core/future-cancel

(def job (future (Thread/sleep 10000)))

(future-cancel job)

2021-07-01T15:51:06.305500Z

cancelling threads preemptively is technically possible but risks crashing the vm if your job periodically sleeps, or waits on IO, or explicitly checks the cancellation status of its thread and exits if cancelled, future-cancel will work, but it won't do anything to a "hot loop"

2021-07-01T15:51:50.305700Z

(future-cancel is not using a preemptive cancellation, it's relying on one of the "cancellable" methods being called)

2021-07-01T15:53:21.305900Z

also the deref function (what @ expands to) takes an optional time-out number and an alternative value to return if the time-out is exceeded

2021-07-01T15:53:28.306100Z

which might match what you want

popeye 2021-07-01T15:55:13.306300Z

https://stackoverflow.com/questions/6694530/executing-a-function-with-a-timeout how about example given here/

2021-07-01T15:55:17.306600Z

also, on some operating systems, it might be simpler to spawn a second vm, and force that vm to shut down

2021-07-01T16:01:47.306800Z

the "accepted answer" is from a source I usually trust - amalloy is a smart guy I learned a lot from (we were both very active on IRC back in the day), but this answer is dangerously wrong. it uses the stop method on Thread, which is extremely dangerous and can crash the vm: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Thread.html#stop() future-cancel is safe, you just need to make sure the code you are cancelling is inside a future and that it periodically waits on IO, or calls Thread/sleep, or in some other way makes itself cancellable details here: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Thread.html#interrupt()

2021-07-01T16:03:31.307Z

to be extra safe you could make sure the loop executing in the thread checks the return value of the interrupted method

popeye 2021-07-01T16:05:20.307200Z

how about writing similar code https://github.com/flatland/clojail/blob/master/src/clojail/core.clj#L24

ghadi 2021-07-01T16:05:42.307500Z

again, Thread.stop is not safe

popeye 2021-07-01T16:05:58.307700Z

oh yeah!

ghadi 2021-07-01T16:06:03.307900Z

what is your work doing for more than 10 minutes?

ghadi 2021-07-01T16:06:10.308100Z

if it's IO, it can be interrupted()

popeye 2021-07-01T16:06:22.308300Z

My function doing caluclation on huge data, if it take more time I need to return nil , - which is my requirement

2021-07-01T16:06:29.308500Z

writing code like that is a lot more complex than just using a future and calling future-cancel after some time period, that code you linked is what I was referring to being unsafe because of stop

ghadi 2021-07-01T16:06:33.308700Z

please describe the calculation?

ghadi 2021-07-01T16:06:40.308900Z

pure math? I/O?

popeye 2021-07-01T16:07:09.309100Z

it calls the lambda service

2021-07-01T16:07:18.309300Z

then it's waiting on IO (network)

2021-07-01T16:07:26.309600Z

then future-cancel will work

ghadi 2021-07-01T16:08:36.309800Z

is the Lambda the thing you're trying to stop? or are you trying to stop the thing calling the lambda?

popeye 2021-07-01T16:09:22.310Z

lamda taking more time to perform calculation. my requirement is timeout if more than 10 mis

Endre Bakken Stovner 2021-07-01T16:10:37.311500Z

Is str/index-of the best way to see if a string contains a char (represented as a string)? I love writing if "a" in "casablanca" in Python

2021-07-01T16:12:16.313Z

for a simple character check, index-of is your best bet, unlike python clojure values simplicity of syntax over intuitive / natural language like syntax

Endre Bakken Stovner 2021-07-01T16:13:09.313900Z

I felt like contains? sounded like it could have done the job, but it is for associative structures.

2021-07-01T16:13:47.314700Z

I guess you could do (contains? (set "casablanca") \a) but I don't think that really addresses your needs

2021-07-01T16:13:57.315Z

and it does a lot of work you don't need to do

Endre Bakken Stovner 2021-07-01T16:14:33.316400Z

Agreed. But I felt like checking the value of an int was a bit... C-like?

2021-07-01T16:14:52.317200Z

you could also do (first (filter (set "a")) "casablanca") but that still does a lot of work you don't need to do

dpsutton 2021-07-01T16:15:09.318Z

There’s str/includes? That has a name that indicates what it does similar to your expectation for contains?

💯 2
ghadi 2021-07-01T16:16:21.318800Z

AWS Lambda?

2021-07-01T16:16:46.319400Z

@endrebak85 one nitpick: it's not c-like in that (if (str/index-of "casablanca" "a") :yes :no) actually works direcly - it returns nil which if treats as false, on failure

popeye 2021-07-01T16:16:50.319500Z

yes

Endre Bakken Stovner 2021-07-01T16:16:53.319700Z

Thanks! It did not show in lein rebl for some reason

Endre Bakken Stovner 2021-07-01T16:17:07.320Z

So I assumed it did not exist

popeye 2021-07-01T16:17:17.320200Z

@noisesmith future-cancel how to pas the minutes?

2021-07-01T16:17:18.320400Z

what clojure version?

Endre Bakken Stovner 2021-07-01T16:18:33.320700Z

True! I just assumed that it would return -1 instead of false. But that would have been extremely unclojuric.

2021-07-01T16:18:35.320900Z

you need something else (eg. (future (Thread/sleep (* 10 60 1000)) (future-cancel worker)))

Endre Bakken Stovner 2021-07-01T16:18:51.321200Z

Bad habits (assumptions?) die hard. Should have tested in the REPL.

dpsutton 2021-07-01T16:19:10.322100Z

apropos and find-doc and dir are your friends here

🤯 1
popeye 2021-07-01T16:19:18.322300Z

worker is function-name here?

ghadi 2021-07-01T16:19:33.322500Z

why not just let the lambda timeout and be killed?

2021-07-01T16:19:33.322700Z

here (* 10 60 1000) turns minutes into seconds (multiply by 60), then turns seconds into ms (multiply by 1000)

2021-07-01T16:19:41.322900Z

worker would be the thing being cancelled

Endre Bakken Stovner 2021-07-01T16:19:44.323100Z

[org.clojure/clojure "1.10.3"]

popeye 2021-07-01T16:20:06.323300Z

where i can pass my function name

2021-07-01T16:20:12.323500Z

@ghadi makes a good point - lambda already has facilities to shut down after a time-out, that's the expensive resource here, it can just shut down the whole vm

Endre Bakken Stovner 2021-07-01T16:20:35.323700Z

Wow! Thanks for the tip about clojure.repl/find-doc

2021-07-01T16:20:53.323900Z

@popeyepwr you would need to use future to start it and use the return value of future, but the way @ghadi is suggesting is better since this is running in its own vm on a lambda

popeye 2021-07-01T16:22:09.325600Z

oh, let me search on it! all the above conversation really helped

dpsutton 2021-07-01T16:22:13.325900Z

Leveraging the queryable nature of clojure with the built in tools will serve you well. I use those constantly. After you’re comfortable with them, learn if your editor has some integrations on top of them. Many do

👍 1
2021-07-01T16:22:45.326200Z

in C, simple type consistency is valued over semantic clarity, the jvm's comparitive complexity allows things that are closer to the intent of the code to be expressed

👍 1
2021-07-01T16:23:57.326400Z

I frequently use find-doc and apropos and javadoc to answer questions here - I usually start with a good hunch of what should be there (or a vague memory) and let the built in introspection in the language do the rest of the work

2021-07-01T16:24:16.326600Z

and those tools are much more direct and helpful than google

2021-07-01T16:25:07.326800Z

looking up the most poetic doc string in the clojure codebase:

(ins)user=> (find-doc #"if possible")
-------------------------
clojure.core.protocols/interface-or-naive-reduce
([coll f val])
  Reduces via IReduceInit if possible, else naively.
-------------------------
clojure.core/future-cancel
([f])
  Cancels the future, if possible.
nil

👍 1
🤯 2
Karo 2021-07-01T19:22:07.339600Z

Hi team how can I query current timestamp from database in Clojure project using Korma? "select current_timestamp"

Karo 2021-07-01T19:31:17.340Z

(defn foo []
  (select my_table
          (fields (raw "CURRENT_TIMESTAMP"))))

borkdude 2021-07-01T19:51:11.341200Z

@vnazaryan Korma isn't very maintained anymore I think, but I could be wrong. Instead I would recommend taking a look at #honeysql which is, if you ask me, one of the the best SQL generation libraries for Clojure,

Karo 2021-07-01T19:58:22.341400Z

thanks for suggestion, will take a look.

seancorfield 2021-07-01T20:58:46.342800Z

In addition to the #honeysql channel for HoneySQL, there's also a more general #sql channel for general SQL questions -- and that also tends to be where folks ask about next.jdbc which is the replacement for clojure.java.jdbc. Also #hugsql if you like your SQL in separate files, outside of your Clojure code.

👍 1
tws 2021-07-01T21:10:30.344800Z

is there a canonical way to parallel parse/process a large file based on a regex to split up the chunks? instaparse was overkill - all the backtracking it kept blew up the memory. I was thinking iota and reducers but each ‘chunk’ of the file is processed as a whole, not line by line, and marked with clear begin/end blocks. It’s a super regular unambiguous grammar, but not XML or such.

2021-07-02T17:37:24.411500Z

you can use re-seq to get a lazy seq of matches of a charsequence, there's at least one lib out there that implements charsequence over very large files https://github.com/fge/largetext - may or may not work for you

2021-07-02T17:37:47.411800Z

but for the use case where it applies it's probably the most straightforward approach

2021-07-02T17:39:50.412Z

(charsequence is the superclass of string, and you can do most "string ops" on a charsequence, they are more abstract eg. unlike string don't need to promise to exist in memory all at once)

2021-07-01T21:32:34.347800Z

Whats the (better?) Clojure equivalent of a SAX parser + lots of messy Java code? I know there are several ways to parse XML, and a bunch of ways to traverse the result but haven’t tried any so far.

seancorfield 2021-07-01T21:46:57.348Z

Probably zippers.

seancorfield 2021-07-01T21:48:25.349Z

At work, we use clojure.data.xml (`org.clojure/data.xml`) to parse XML and clojure.zip to navigate/modify https://clojure.github.io/clojure/clojure.zip-api.html

2021-07-02T07:10:11.355700Z

Thanks! 👍

bnstvn 2021-07-02T09:55:06.359400Z

actually, i recently just wanted to count some elements in a jvm with 512mb heap with a ~30Mb xml. i got an out of memory error (with zippers as well), and went with plain java stax. any idea what could have been a clean clojure solution?

(->> "huge.xml"
            io/resource
            io/input-stream
            xml/parse
            xml-seq
            (filter #(= (:tag %) :Event))
            count)

Execution error (OutOfMemoryError) at clojure.data.xml/seq-tree$fn (xml.clj:183).
Java heap space

pithyless 2021-07-02T11:06:58.363500Z

@ban.istvan I wonder if this would work:

(x/count
 (comp
  xml-seq*
  (filter #(= (:tag %) :Event)))
 (-> "huge.xml"
     io/resource
     io/input-stream
     xml/parse))
where 1. xml is clojure.data.xml 2. x/count is from https://github.com/cgrand/xforms 3. transducer version of xml-seq, something like:
(def xml-seq*
  (fn [rf]
    (fn
      ([] (rf))
      ([result] (rf result))
      ([result input]
       (rf result (xml/xml-seq input))))))

pithyless 2021-07-02T11:07:29.363900Z

(I have not actually tested this code ;))

2021-07-02T12:14:04.369800Z

So, speaking of - can anyone point to code, or pseudo-code, or any inspiration on how to idiomatically traverse a tree (SAX-style), where you obviously sometimes need to keep track of the depth or other data to figure out what to do with leaf nodes.

2021-07-02T12:14:46.370Z

(Slowly trying to leave my Java/imperative brain behind, but it’s… sticky.)

ghadi 2021-07-02T13:28:25.373800Z

SAX style is awful because it presumes mutation and accumulators

ghadi 2021-07-02T13:28:37.374Z

StAX is a bit nicer, IMHO, and lends itself to a more functional handling

2021-07-02T13:30:58.375400Z

Ah, hadn’t even heard of StAX. Will study and catch up with the times…

ghadi 2021-07-02T13:33:18.375600Z

ghadi 2021-07-02T13:34:13.375800Z

non-lazy xml -> clojure data routine

2021-07-02T17:43:46.412600Z

🍻

greg 2021-07-01T21:52:20.349100Z

I noticed there are two libraries: clojure.xml and clojure.data.xml . What's the difference between them?

seancorfield 2021-07-01T21:55:59.349300Z

clojure.xml is built-in but it is old/deprecated and should not be used. clojure.data.xml is a Contrib lib that is well-maintained, more modern, more feature-rich.

greg 2021-07-01T21:56:17.349500Z

Ok, thanks @seancorfield

Fredrik 2021-07-01T22:25:17.349900Z

Could something like pipeline and partition-by from clojure.core.async be an idea? Read the file line by line onto a channel, partition into chunks which then get further processed in a pipeline.

Fredrik 2021-07-01T22:26:57.350100Z

It allows for a nice decoupling between reading, splitting into chunks and parsing.