Fork me on GitHub
#beginners
<
2022-01-19
>
Chase01:01:24

I'm doing an exercism problem involving Big Decimals and I'm failing the last couple of tests due to what I think is some kind of precision error:

``````; FAIL in (annual-balance-update-large-positive-balance-test) (NO_SOURCE_FILE:54)
; expected: (= 1016.210101621M (interest-is-interesting/annual-balance-update 1000.0001M))
;   actual: (not (= 1016.210101621M 1016.2101016209999M))``````

Chase01:01:03

The function is just:

``````(defn annual-balance-update
[balance]
(bigdec
(+ balance
(* 0.01 (.abs balance) (interest-rate balance)))))``````
where `interest-rate` returns a double like 1.621

Chase02:01:31

The other failing test is:

``````; FAIL in (annual-balance-update-huge-positive-balance-test) (NO_SOURCE_FILE:57)
; expected: (= 920352587.26744292868451875M (interest-is-interesting/annual-balance-update 898124017.826243404425M))
;   actual: (not (= 920352587.26744292868451875M 920352587.267443M))      ``````
which seems to be the same issue of precision.

Chase02:01:43

I've tried turning everything in that fn to a Big Decimal and such but my answer isn't changing.

hiredman03:01:00

Doubles are contagious, so interest rate returning a double will cause imprecise double math to be used for the whole expression

Chase03:01:30

Interesting. The exercise required the interest rate to return a double. When I convert the interest rate to a BigDecimal in the `annual-balance-update` fn I still get the same incorrect precision.

have you tried `with-precision`?

i will either do that or define an appropriate `EPSILON` and have a `equal-within-tolerance?` test helper.

randomm char14:01:16

This may or may not be helpful `user=> (* 0.1 0.2)` `0.020000000000000004` `user=> (bigdec (* 0.1 0.2))` `0.020000000000000004M` `user=> (* (bigdec 0.1) (bigdec 0.2))` `0.02M` `user=> (= (* (bigdec 0.1) (bigdec 0.2)) (bigdec 0.02))` `true`

Chase15:01:04

Yeah, the solution was to multiply by `0.01M` instead of `0.01` which I was sure I had tried early on in the process. Thanks folks.

jason poage09:01:30

im using clj-http, and when my server sends a 422 response, clj-http throws an exception inside my try-catch statement, and i cannot read the response, which is in json. i can read the response body on postman, just not sure how to get past the exception. If i don’t use try/catch, clojure gives me an error. not sure where to go from here

delaguardo10:01:52

you can use option `:unexceptional-status` to specify that 422 should be treated as OK response https://github.com/dakrone/clj-http#exceptions

delaguardo10:01:36

there are other options as well. for example: with `:throw-exceptions false` instead of exception thrown from clj-http you will get normal ring response if you want to handle status yourself

Tilak11:01:33

Got this error trying to install deps-new tool, any idea please? Execution error (ExceptionInfo) at clojure.tools.deps.alpha.extensions.git/coord-err (git.clj:45). Library io.github.seancorfield/deps-new has invalid tag: v0.4.9

1
Tilak11:01:14

Tried with v0.4.8 and got same error. Something wrong on my side? clojure -Ttools install io.github.seancorfield/deps-new '{:git/tag "v0.4.8"}' :as new Execution error (ExceptionInfo) at clojure.tools.deps.alpha.extensions.git/coord-err (git.clj:45). Library io.github.seancorfield/deps-new has invalid tag: v0.4.8

MatElGran11:01:22

Are you on windows using cmd ?

Tilak11:01:42

Yes, installed CLI via scoop.

Tilak11:01:42

Thank you. It was quote issue. This one worked - clojure -Ttools install io.github.seancorfield/deps-new '{:git/tag ""v0.4.9""}' :as new

👍 1
Alastair Hole13:01:20

I was having warnings about SL4J defaulting to a noop backend, I added `[ch.qos.logback/logback-classic "1.2.10"]` and it seems happy with this and now I can see logs output to the console. Is this sufficient, or is there a more suitable or ‘standard’ alternative?

stopa16:01:28

Hey team curious q: https://clojuredocs.org/clojure.core/read-string I know read-string can execute arbitrary code. What is an example of such an execution? (i.e an example of some code a nefarious user could write, which when run by `read-string`, borks us)

Ben Sless16:01:21

dpsutton16:01:24

`(read-string "(slurp \"\")")` just returns the form for me

Alex Miller (Clojure team)16:01:04

it can construct arbitrary Java classes using # or run arbitrary code with #=

❤️ 1
Ben Sless16:01:42

I mean the string passed to read string will call read string on a slurped file

Ben Sless16:01:06

Letting you load arbitrary code from outside. Fun :)

Alex Miller (Clojure team)16:01:15

`(read-string "#=(launch-missiles)")`

💥 4
dpsutton16:01:15

here’s a very concrete example with arbitrary shell access

``(read-string "#=(clojure.java.shell/sh \"echo\" \"hi\")")``

andy.fingerhut16:01:04

That ClojureDocs page still holds up well. The Clojure version numbers mentioned seem pretty old now 🙂

jumar17:01:46

Concrete example:

``````\$ clj                                                                                                                                                                                                 Clojure 1.10.3
user=> (read-string "#=(java.lang.System/exit 1)")

\$``````

❤️ 1
stopa04:01:27

Veery good to know. Thanks team!

Eddy Emmanuel Asturiano Peralta20:01:04

Is anyone using VSCode with the Calva extension? I got the https://github.com/sicmutils/sicmutils library working on my script and so far everything's working as intended but it's throwing me "unresolved symbols" errors. I installed SICMUtils from https://clojars.org/sicmutils using the depens.edn option. And it worked! I CAN use SICMUtils, only issue is that in my script if I use SICMUtils an unresolved symbol error is thrown like on the image I linked. Any ideas how to solve this?

Sam Ritchie21:01:07

The problem is the macro in my getting started example!

👀 1
borkdude22:01:27

Perhaps you can add a hook to an exported clj-kondo which expands in a :refer [x y z] thing so clj-kondo knows what vars are imported from SICMUtils

borkdude22:01:05

I think we discussed this issue before, somewhere, not sure

👍 1
Sam Ritchie23:01:44

We did! I avoided it as an emacs user, https://github.com/sicmutils/sicmutils/issues/378 but this was the ticket

borkdude23:01:06

In emacs you will have the same problems I think.

borkdude23:01:55

but yes, the approach described in the issue would still be what I would recommend, or hardcode (programmatically perhaps) the vars in the hook expansion. that would be even more robust.

Sam Ritchie23:01:29

I should have said, as an emacs user with an old pre-clj-kondo config :)

Sam Ritchie23:01:51

I will bump this way up! And turn on kondo for myself

borkdude23:01:24

ok let me know if you need help, we will fix it

borkdude23:01:29

off to bed now 💤

Eddy Emmanuel Asturiano Peralta03:01:45

Hold up, made a new project with the exact same deps.edn file and the issue seems to have magically solved itself (image of my .clj file linked) :thinking_face:. I have the suspicion the bug is on the Calva extension side, unless I did something different I haven't noticed yet.

Eddy Emmanuel Asturiano Peralta03:01:54

Yup, on my other file the linting error is like stuck somehow.

Sam Ritchie05:01:35

very strange, @easturiano! well, I still have some tidying to do with my clj-kondo integration so I wouldn’t be surprised if you hit more stuff. but this is good news!

Sam Ritchie05:01:58

@easturiano also would love to hear what you’re up to with #sicmutils, ask any Qs and feel free to chat whenever!

seancorfield21:01:56

@easturiano How are you making the symbols available in that file? what does your `ns` form look like?

Eddy Emmanuel Asturiano Peralta21:01:55

I was following one of the begninner's tutorials so in my src/playground.clj file I only typed in `(ns playground)` `(require '[sicmutils.env :as env :refer :all])`

Eddy Emmanuel Asturiano Peralta21:01:44

From the tutorial I additionally made a deps.edn file on the same directory and copy pasted `{:paths ["resources" "src"]`  `:deps {org.clojure/clojure {:mvn/version "1.10.3"}`         `nrepl/nrepl {:mvn/version "0.9.0"}`         `sicmutils/sicmutils {:mvn/version "0.20.1"}}}`

Sam Ritchie21:01:58

Interesting, :refer :all should totally work. I have that issue when I use (require '[sicmutils.env :as env]) (env/bootstrap-repl!)

Sam Ritchie21:01:28

I can try to recreate when I get to a machine, but it would be great if you could paste the full contents of the file that causes those linting issues

Eddy Emmanuel Asturiano Peralta22:01:50

My file is src/playground.clj and its contents are

``````(ns playground)

(require '[sicmutils.env :as e :refer :all])

(comment
(- (* 7 (/ 1 2)) 2)
(asin -10)
)``````
And `asin` it throws this error: "resource": "/home/eddya/cljProjects/test/src/playground.clj", "owner": "generateddiagnostic_collection_name_#0", "code": "unresolved-symbol", "severity": 8, "message": "Unresolved symbol: asin", "source": "clj-kondo", "startLineNumber": 7, "startColumn": 4, "endLineNumber": 7, "endColumn": 8 }] Also there´s a linting warning on `:all` [{ "resource": "/home/eddya/cljProjects/test/src/playground.clj", "owner": "generateddiagnostic_collection_name_#0", "code": "refer-all", "severity": 4, "message": "use alias or :refer", "source": "clj-kondo", "startLineNumber": 3, "startColumn": 39, "endLineNumber": 3, "endColumn": 43 }]

seancorfield21:01:03

Ah, looks like sicmutils uses potemkin to import vars from other namespaces so that isn't going to be something that clj-kondo understands, because those vars aren't actually defined in the sicmutils.env namespace .

Sam Ritchie21:01:10

It is not quite that, it is this macro I created to simulate :refer :all for cljs users :(

Sam Ritchie21:01:23

Good news is that is not needed in clj only, so I can help here

borkdude21:01:36

clj-kondo understands potemkin

borkdude21:01:29

but you do need to lint your dependencies, there might be an issue with that

borkdude21:01:23

repro welcome

seancorfield21:01:14

@borkdude As a beginner, I doubt Eddy will be able to create a repro for you...?

borkdude21:01:41

without a repro, I can't repro

borkdude21:01:09

perhaps @sritchie09 also has an idea what's going on, as the author of #sicmutils

👍 1
roelof21:01:28

Do not know if this is a good chat but how do I start a shadow-cljs/reagent server so the project is compiled and the server is started so I can show the app on a website. I remember it's something as `npx .. `

dpsutton21:01:09

. The command is `npx shadow-cljs watch app` where watch is either `watch` to keep recompiling on change, or `compile` to compile once. The argument `app` is whatever you named the build in your shadow-cljs.edn file

Lucas21:01:38

Hey folks! Does anyone know if it's possible not eval a `*data-readers*`? I would like to do something similar what the `quote` does with a form.

``````(defn not-eval-form
[]
'(+ 1 2 3))

(not-eval-form) ;; => (+ 1 2 3)``````
``````;; Assuming that the *data-readers* are
;; { hey/dont-execute-it clojure.core/inc }
[]
;; Do something magic on that step
{:foo #hey/dont-execute-it 5})

(not-eval-data-reader) ;; => 6

;; But I would like to return something like
(not-eval-data-reader) ;; => {:foo #hey/dont-execute-it 5}``````

hiredman21:01:17

it is possible, but the way to do it is to make a function that returns a list that starts with the symbol quote

hiredman21:01:23

better to just use quote

hiredman21:01:49

`'foo` is short hand for `(quote foo)` which is a list of two symbols `quote` and `foo`

hiredman21:01:25

which a list where the first symbol is `quote` is evaluted the result is just the second part of the list, in this case the symbol `foo`

hiredman21:01:06

the way the reader works is it constructs datastructures (lists, symbols, maps, etc) that are then evaluated

hiredman21:01:43

the way data readers work, is they allow you to have a custom function that is called and returns its own datastructures to be evaluated

hiredman21:01:23

something to keep in mind is not everything can be quoted successfully

hiredman21:01:02

quoted things have pass through the evaluator, and clojure's evaluator compiles to jvm bytecode

hiredman21:01:29

so whatever is quoted, the compiler has to know how to serialize it in someway in bytecode, and then reconstruct it from there

hiredman22:01:08

``````Clojure 1.10.2
user=> (set! *data-readers* (assoc *data-readers* 'foo (fn [x] (Object.))))
user=> #foo 1
user=> (fn [] #foo 1)
Syntax error compiling fn* at (REPL:1:1).
Can't embed object in code, maybe print-dup not defined: java.lang.Object@388b401d
user=> (set! *data-readers* (assoc *data-readers* 'foo (fn [x] (list 'clojure.core/+ 1 1))))
{foo #object[user\$eval143\$fn__144 0x78faea5f "user\$eval143\$fn__144@78faea5f"]}
user=> #foo 1
2
user=>``````

Lucas13:01:33

Thank you so much for the answer but I in my case I wouldn't like to execute the code of the data-readers, for example:

``(set! *data-readers* (assoc *data-readers* 'foo (fn [x] (list 'clojure.core/+ 1 1))))``
When calling the data-reader the desirable result should be something like that:
``````(fn []
{:a #foo 1})
=> {:a #foo 1}``````
But currently the result is
``{:a 2}``

Lucas13:01:36

I don't really know if it's possible since as far as I know the reader step is made before the evaluation. But I don't have sure about that

Lucas13:01:04

@U0NCTKEV8 I don't know if I was clear enough, please let me know if I need to elaborate the question a little bit more.