Fork me on GitHub
#clojure
<
2024-03-19
>
Melanie01:03:40

Hi, stupid regex problem, I'm not getting what I'm missing... Trying to match "ERROR" in the string "[ERROR]: message" I would think (str/split msg #"\[\w\]:") would match it, but it doesn't seem to match. I feel I'm missing something really stupid.

1
Melanie01:03:11

not looking for re-matches or anything like that, my question is more what's wrong with my actual regex.

Melanie01:03:33

(I do use a str/replace in my actual code with a matching group to extract that part out)

valerauko01:03:17

You're missing a +

valerauko01:03:27

it should be \[\w+\]

thanks2 1
Melanie01:03:37

there's still a weird thing going on that I'm not following...

Melanie01:03:03

I'm doing https://exercism.org/tracks/clojure/exercises/log-levels/edit and i'd think that code would just work fine: (defn log-level "Takes a string representing a log line and returns its level in lower-case." [s] (str/lower-case (str/replace s #"\[(\w+)\]: .*" "$1")) ) but I'm getting "error\r\n" as a result.

Melanie01:03:06

I know I can use trim-newline, but I don't understand why I'd have to do it 😞

andy.fingerhut01:03:12

Regex witt only a dot normally does not match new line or carriage return characters

andy.fingerhut01:03:54

What are you hoping to be returned from this function?

valerauko01:03:23

Are you sure your input doesn't have newlines in it? If you're slurping a file it might have a trailing newline

Melanie01:03:37

it does have a newline in it. that's part of the test

Melanie01:03:54

that's the input string to this function

[ERROR]: \t Corrupt disk\t \t \r\n"

andy.fingerhut01:03:58

You are telling it to replace everything except any new lines after the right square bracket with $1, so the carriage return remains in the replaced string

valerauko01:03:21

Then don't use replace, instead extract the level with match and use that

Melanie01:03:46

Ah that makes sense, thanks Andy!

andy.fingerhut02:03:16

Agreed. If you only want whatever matched the \w+ part, then replace is an odd choice

Melanie02:03:23

thanks valerauko, I'll do that next then. I was just eh replace all the string with the thing I matched... Just couldn't understand why it was adding the \r\n.

🚀 1
andy.fingerhut02:03:07

Yeah, it was not adding those characters. You were, without realizing it, telling it to leave them there

👍 1
Melanie02:03:57

Thanks 🙂 still learning.

Melanie02:03:50

Would this be an idiomatic way to write it? (str/lower-case (get (re-find #"^\[(\w+)\]:" s) 1))

andy.fingerhut02:03:56

Looks good to me

thanks2 1
vlnn02:03:18

Is there a clojure way to measure maximum memory consumption by the function call? (not the object allocation memory). Something like (max-memory-used (fib 300)) ?

1
hifumi12302:03:14

I recommend using an actual profiling tool, but if you want something with absolutely zero dependencies, then simply use this macro:

(import com.sun.management.ThreadMXBean)
(import java.lang.management.ManagementFactory)

(defn get-usage []
  (let [thread-bean (ManagementFactory/getThreadMXBean)]
    (System/gc)
    (.getCurrentThreadAllocatedBytes ^ThreadMXBean thread-bean)))

(defmacro with-memory-statistics [& body]
  `(let [start#     (get-usage)
         result#    (do ~@body)
         end#       (get-usage)]
     (array-map :result result# :diff (- end# start#) :start start# :end end#)))

1
hifumi12302:03:43

following your example, you would then evaluate (with-memory-statistics (fib 300))

valerauko02:03:49

Doesn't the end# call gc before measuring? Is that intended?

hifumi12302:03:27

My intention is indeed to do something like

(System/gc)
(measure)
(run the body)
(System/gc)
(measure)

valerauko02:03:26

Wouldn't that measure memory leak instead of overall usage?

🙌 1
hifumi12302:03:15

ah yeah you’re right… I just took a look at the docs for getCurrentThreadAllocatedBytes, and this returns total # of bytes allocated in the thread (as in, a running total). So running GC is unnecessary at best and, at worst, only measures memory leaks.

hifumi12302:03:42

so just deleting the (System/gc) call should be good enough. the start value is going to be strictly increasing, even if the java heap shrinks, since it measures how many bytes the JVM tried to allocate in total for that specific thread

seancorfield03:03:45

Perhaps worth considering: (System/gc) is advisory and is no guarantee that any GC will actually happen at that point.

vlnn12:03:26

@U04V70XH6 That explains why I got meaningful results for both variations of the script. Thanks, good to know!

arohner10:03:26

I would really like a redis-alike, but with clojure refs and datastructures. Does such a thing exist?

1
valerauko10:03:33

https://github.com/taoensso/carmine translates clojure data structures iirc

respatialized17:03:33

https://github.com/tolitius/redclaw I think this may be similar to what you describe: creating redis-backed data structures that implement the expected interfaces.

arohner10:03:51

and failing that, are there any examples of really fast networked clojure services? i.e. not naive HTTP

p-himik10:03:13

What does "really fast" mean? What does a "network service" mean? Are these really the only metrics?

arohner10:03:57

TCP, low latency per request

p-himik11:03:49

With such a tacit description, I doubt there's anything better than java.net.ServerSocket. :)

asolovyov11:03:21

aleph supports raw tcp/udp services, and it's rather performant, but I suppose you know about it 🙂

arnaud_bos13:03:55

You can also interop with Aeron's Java implementation, I think Onyx did that "back in the days".

onetom14:03:28

Are there any features in the https://www.youtube.com/live/AjjAZsnRXtE?si=TmccD4O4q7irfVNR which Clojure can benefit from? Maybe https://openjdk.org/jeps/458 can simplify packaging and running Clojure programs? I wasn't even aware of the https://docs.oracle.com/en/java/javase/21/docs/specs/man/jwebserver.html command, which came with Java 18...

Alex Miller (Clojure team)15:03:01

Java catching up to where Clojure started :)

😂 9
😄 3
Alex Miller (Clojure team)16:03:36

I look forward to using it in 15 years

🙃 1
seancorfield16:03:06

https://openjdk.org/jeps/461 feels a bit like transducers for streams...?

Alex Miller (Clojure team)16:03:22

it is, and I absolutely think you could write something that took a transducer and implemented a gatherer, which is a very interesting idea to bring our whole transducers library into java streams

🎉 1
👍 2
seancorfield16:03:22

https://openjdk.org/jeps/456 is _ as an "unnamed" variable 🙂 Feels like they've been getting quite a bit of Clojure inspiration here...

emccue16:03:43

It's a rising tides lift all boats kinda thing

emccue16:03:43

I think most changes coming and that have come to Java strengthen Clojure - less so for Kotlin and Scala which kinda do seem sillier

Alex Miller (Clojure team)16:03:14

well several of us in the Clojure core are friendly with Brian Goetz so we try to influence him :)

💯 2
🍻 4
vemv17:03:13

Is there one thing 'missing' in the JVM/JDK with no known JEP for it?

emccue17:03:51

personal opinion: an equivalent to {:deps {lib/name {:mvn/version "..."}}}

Alex Miller (Clojure team)17:03:30

I wish they’d just leave it alone mostly :)

👌 1
hifumi12319:03:01

I agree. The java stdlib is pretty huge as-is and I find it very useful. Outside of tweaks to the JVM and GC, I don’t see much things that interest me much

p-himik21:03:16

20 years later: java.llm.adapters.ChatGptToGeminiAdapter.

onetom17:03:14

now u can program zig-style in java too 😉