Fork me on GitHub
#clojure
<
2022-02-07
>
deas09:02:07

Hi! cli with subcommands - preferrably working with babashka. cli-matic might do the trick. Any other suggestions?

lread14:02:33

@U06FLL69W I'm using docopt with babashka for dev tasks for rewrite-clj. I wrapped it to be more task usage oriented than command line usage oriented.

👍 1
Max17:02:47

Just wanted to point out you can do this with tools.cli too using https://github.com/clojure/tools.cli#in-order-processing-for-subcommands

👍 2
GGfpc09:02:40

Do the testing macros in have any purpose other than documentation? I initially thought of them as blocks similar to rspec where tests have "narratives" but they can't be used for that without allowing bindings

Noah Bogart14:02:52

Purely documentation.

mike_ananev12:02:09

Hello, all! How to check memory consuption in JVM if I do?

(def ba (very-large-byte-array))
(byte-array (drop 15 ba))
I need to skip first 15 bytes from ba, and then apply the rest of ba to java function. I'm seeking the most effective way to do that from point of RAM consumption.

wotbrew12:02:53

Have a look at java.util.Arrays/copyOfRange

wotbrew12:02:33

seq version will likely require more intermediate allocation, copyOfRange should be a JVM intrinsic (though not 100% on that) that just allocates the new array up front

mike_ananev12:02:51

Thank you. I'm already implemented my solution using java.util.Arrays/copyOfRange but I'm interested to compare seq vs copyOfRange versions and how to see memory consumption in JVM?

wotbrew12:02:18

in either case the resultant byte array will be the same size on the heap, the only difference will be in intermediate allocations to create the copy.

wotbrew12:02:49

the intermediate collections will be garbage collected as you go so really the impact will be felt in the time it takes to copy

mike_ananev12:02:07

Thank you. I'll take VisualVM to see it.

mike_ananev12:02:49

if I have 1 000 000 array, then Arrays/copyOfRange makes new array of the same size minus 15 bytes. so it is O(n) solution. I thought that seq may be lazy and I can use this property to consume more effectively the rest of array. e.g. apply fn to current array but starting from 15th byte and not to copy it to another almost the same size.

wotbrew12:02:09

when you call (byte-array seq) you will realise the entire sequence and allocate an array with the same size as the seq.

wotbrew12:02:51

it might help if we knew the use case because it may be you do not need to allocate a byte-array at all, in which case the seq version (or something else) may be better

wotbrew12:02:16

but if you need a new array which is a slice of another one copyOfRange is the best you can get afaik

mike_ananev12:02:54

My case: I have encrypted data in bytes buffer [header, data]. I need to read header, make header analysis, then decrypt data (skip 15 bytes of header). I need to do it in a most effective way cause buffers can be large.

wotbrew12:02:11

What options do you have to decrypt? can you take an iterator, nio buffer?

wotbrew12:02:22

if its gotta be an array, best I can do is copyOfRange 🙂

mike_ananev12:02:27

I can take any option

wotbrew12:02:01

what does the (presumably java?) function to decrypt look like?

wotbrew12:02:10

(i.e signature)

mike_ananev12:02:18

it is a clojure wrapper function on Bouncycastle java function, so signature is (decrypt-bytes ^Cipher cipher ^bytes encrypted-buffer)

mike_ananev12:02:20

Or to be effective we should wait for Project Valhalla? 🙂 (to apply fn to byte-array starting from nth position)?

mike_ananev13:02:28

I changed my solution to read by 1024 bytes and decrypt step by step without memory consumption.

👍 1
mike_ananev13:02:11

I think this is not for large buffers

ghadi15:02:32

use bytebuffers

ghadi15:02:54

(ByteBuffer/wrap your-byte-array)

ghadi15:02:30

you can then slice the buffer and pass it to a Cipher. (Be careful using BouncyCastle, it is a very error prone library)

👍 1
mike_ananev15:02:37

oh, thank you. where I can read about errors in BC ? I need some investigation for my cases.

ghadi15:02:16

what algorithm are you attempting to use?

mike_ananev15:02:45

only gost. I’m working on wrapper for Clojure for Gost

ghadi15:02:52

(the general topic here is called 'misuse resistance' -- aka use google/tink rather than a low level swiss-army knife style library, such as BC)

ghadi15:02:20

i think BC is your only option for GOST

eelke15:02:29

Hello all, maybe this is a noob question. But currently I see this:

eelke15:02:46

Why are the results different?

p-himik15:02:20

Peculiarities of floating point operations. I believe this section explains it: https://en.wikipedia.org/wiki/Floating-point_arithmetic#Representable_numbers,_conversion_and_rounding

2
Colin P. Hill16:02:14

TL;DR is that decimal numbers are generally only approximate in nearly all languages. In Clojure you can get precise results using rationals (+ 1/2 1/10 3/10) or BigDecimals (+ 0.5M 0.1M 0.3M), but both of these come with some more overhead that might matter if you're doing a lot of number crunching.

Colin P. Hill16:02:29

Also, between those, BigDecimals are of course only precise for things with a closed decimal form (e.g., 1/3 will still have some imprecision as a BigDecimal), and both are imprecise for anything that isn't rational (e.g., the square root of 2).

👍 1
Joshua Suskalo16:02:42

congrats eelke, you just found one of the monsters at the bottom of computing! floating point maths is neither commutative nor associative!

ghadi16:02:13

this is a really really good video on floating point in java

❤️ 1
ghadi16:02:35

(or for that matter, in any lang)

p-himik16:02:36

Thanks, haven't seen that one.

Sam Ritchie02:02:24

Here are some compensated summation algorithms you can use to limit the error accumulation if you're adding many numbers : https://github.com/sicmutils/sicmutils/blob/main/src/sicmutils/series.cljc

Sam Ritchie02:02:56

kahan-babushka-neumaier is the one to use usually

eelke08:02:56

Thanks all, interesting stuff

Harel Opler15:02:34

Hi there Im wondering if Clojure has an optimization for empty maps - when I write {}, is a new map created or some static empty map referenced?

p-himik16:02:13

Indeed, the singleton clojure.lang.PersistentArrayMap.EMPTY is used. You can double-check by calling (System/identityHashCode {}) multiple times.

🙌 1
Harel Opler16:02:43

Cool, thank you!

GGfpc16:02:17

Can I rely on the order of clojure lazy sequences?

dpsutton16:02:58

@ggfpc12495 sequence is an ordered notion. But it really depends on if you can rely on the order of the underlying producer of a lazy sequence. What’s the source?

p-himik16:02:54

It also depends on what the question means. It can mean "order of subsequent iterations over the same collection" - and if so, then the answer is "yes, you can rely on it."

GGfpc16:02:23

I have an endpoint that receives a list of Json objects. In my handler I map a bunch of functions over each element of the list and return it. Can I trust that the output is in the same order as the input?

Joshua Suskalo17:02:29

using map and similar operations are single-threaded and operate on the sequence in the order they are received in, so yes, the order will always match the source.

Joshua Suskalo17:02:20

The thing to be careful of is that maps and sets don't have any guarantees about their order remaining consistent when new items are added or old ones removed, or even with the same set of items that the order will be consistent across runs of the JVM or on different JVMs.

emccue20:02:20

what is the relative maturity of the “other clojures” like clojerl