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.

tschady14:01:10

have you tried with-precision?

tschady14:01:03

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

(read-string (slurp url))

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\")")
from https://clojuredocs.org/clojure.core/read

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)
data-readers
;; Assuming that the *data-readers* are
;; { hey/dont-execute-it clojure.core/inc }
(defn not-eval-data-reader
  []
  ;; 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.))))
{foo #object[user$eval1$fn__137 0x7aad3f7d "user$eval1$fn__137@7aad3f7d"]}
user=> #foo 1
#object[java.lang.Object 0x6f667ad1 "java.lang.Object@6f667ad1"]
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.