Fork me on GitHub
#clojure
<
2022-07-04
>
rmxm12:07:29

Don't know if that's important or not, but was just looking through TIOBE for something else but noticed Clojure is completely gone: https://www.tiobe.com/tiobe-index/. I know relevance of TIOBE is very disputed, but still I didnt think clojure would fall behind "Xojo" whatever language that is 🙂

3
p-himik13:07:01

Perhaps they've grouped it all into "Lisp". Even though a dedicated page there says that "Lisp", "Common Lisp", "Elisp", "Clojure" are all separate languages that are not grouped together, only "Lisp" is mentioned by the index itself.

p-himik13:07:36

On the other hand, Scheme is there, as well as Racket...

Kamuela15:07:40

I don't take it too personally... as you said, other lisps are there. I don't think it's too much of a reach for interest in LISP to take you in the direction of Clojure in 2022

Darrick Wiebe15:07:55

I had an executive politically attack my use of Clojure based on its non-presence in this list just the other day. It would be nice if this were rectified, especially considering how distinct Clojure is from "common lisp".

clj 6
Kamuela19:07:57

https://redmonk.com/sogrady/2022/03/28/language-rankings-1-22/ Check out the graph. Clojure is not doing that badly, all things considered. Falls firmly at the head of the pack of "future-leaning" languages with the exception of Haskell alone

Kamuela19:07:07

According to RedMonk WebAssembly is dead 😛 Ymmv

rmxm23:07:19

@U0KLE4WHZ I know clojure is alright, I am not alarmed 🙂 Just hinting that one particular public ranking does not exhibit that. But yeah, it actually looks pretty good on redmonk.

practicalli-johnny14:07:56

According to the TIOBE website, all they do is search for the number of hits when doing a search for +<language> programming So in theory, we should encourage everyone who writes articles about Clojure to include Clojure programming in their content and metadata (assuming TIOBE bothered to include Clojure as one of their searches) I rarely use the term programming in any of my content, so wouldnt be surprised if its not included. They also use a limited set of search engines. TIOBE seems a pretty limited approach to understanding popularity, but then popularity is such a vague and unimportant aspect to making software engineering decisions. If executives are discounting a language I was using, then I would ask them which language I should use and if they are willing to stake their own reputation upon my delivery of (or politely suggest they leave the technical decisions to those who are hired to make them)

Kamuela15:07:47

@U05254DQM I just saw the HOPL IV talk the other day where Rich Hickey suggested people who want traction with their new languages create something that's easily searchable because it's a unique word... poor guy wasn't thinking about TIOBE when everyone out there is just searching for Clojure 😛

Kamuela17:07:42

Also, btw, sorry to beat this dead thread, but Clojure is most definitely on TIOBE's July list. It's in its usual place of somewhere between 51-100. So don't worry, it's not dead yet 😛

kirill.salykin13:07:19

Hi please help: is it possible to have mutable fields inside reify/defrecord? I am implementing logback encoder https://logback.qos.ch/manual/encoders.html and i need to save OutputStream somewhere thanks --- UPD Probably i need to go with deftype

deftype supports mutable fields, defrecord does not 

Alex Miller (Clojure team)13:07:35

No, but you can put an atom in a record if you need state

kirill.salykin13:07:34

how i can mutate field of deftype? or i misread documentation?

Dumch13:07:16

Hey! There is a syntax in Kotlin and Dart that allows to put expressions inside strings, like "Num ${1 + 1} is $2". I wonder, (1) is there a library, that do this with Clojure? example: (str$ "did you know that 1 + 2 equals $(+ 1 2)?") (2) could it be done with macro at compile time? For example, parse string and rewrite it with something like (apply str parts)` (3) is it possible to tell clj-kondo to check syntax inside $(...) inside string?

borkdude13:07:14

@arturdumchev I was actually thinking about writing this for nbb since JS has this too. It can work at compile time and it's possible to write a clj-kondo hook for this of course too.

borkdude14:07:30

I wonder why this didn't end up in core or clojure.string, it seems really handy

1
borkdude14:07:53

I think the macro could just support ~x and ~(+ 1 2 x) though, I don't see the need to differentiate between "single" and "composite" things

delaguardo14:07:27

then you also need to know when there is a qualified symbol to interpolate and when continuation of the string. foo ~

borkdude14:07:24

This just works fine though:

(prn (<< "hello ~clojure.core/inc"))

borkdude14:07:36

not sure what the problem is exactly?

borkdude14:07:00

(prn (let [name "apple"] (<< "These are ~(do name)s")))
"These are apples"

delaguardo14:07:32

then clj-kondo would complain about redundant do 🙂 My comment was about ~x in your example

borkdude14:07:33

Yeah, I get that ~{name}s might read a little bit nicer, but not sure if there's much difference

borkdude14:07:03

(prn (let [name "apple"] (<< "These are ~(-> name)s")))

borkdude14:07:18

clj-kondo does not complain about redundant do's from hook macro-expansions

delaguardo14:07:28

at least the difference is three chars in do

borkdude14:07:56

fair enough. and inlining maps seems uncommon enough to re-use these chars for that

borkdude14:07:35

Other languages have:

${...}
and not having a special case for the composite case might make sense then:
${ (+ 1 2 3) }

delaguardo14:07:22

~{ {:x 1} } still should be possible, but I agree that inlining maps is uncommon

borkdude14:07:54

yes, so just having ${ ... } seems enough and seems to align with at least JS:

> `Hello $x`
"Hello $x"
> `Hello ${x}`
"Hello 123"

borkdude14:07:01

It's awesome that we can do this in a Clojure macro though and not depend on some language committee :)

🔥 1
teodorlu14:07:22

What if ~ simply let's the clojure reader read until it's done?

delaguardo14:07:26

interesting, but could it work with reader conditionals? doesn’t look like so

borkdude14:07:21

@U3X7174KS That's what I got now in the linked issue, but as delaguardo said, this doesn't play nice with: (let [name "apple"] (<< "I've got 10 ~names"))

teodorlu14:07:40

Oh, right 👍 (I skimmed a bit)

borkdude14:07:08

so, tl;dr: I think just supporting ${ ... } is enough for both single and composite values, and the notation aligns with other languages.

👍 2
borkdude15:07:08

Reading this now: https://openjdk.org/jeps/8273943 It seems the ~x shorthand is also supported in some other languages Well, maybe Chas just had it right and I should take it over verbatim :)

borkdude15:07:00

Eh no, now I was confused. Chas had ~{ ... } and ~( ....) while I think you could just have ${ x } and ${ (+ 1 2 3) } while supporting ~x could be a nice-to-have

didibus22:07:43

Everytime I've asked about string interpolation and HEREDOC style strings it seems the core team is against that

didibus22:07:11

Though I think since Java is getting them soon, maybe that will be a good time for Clojure as well

Dumch18:07:47

One more problem with Chas's implementation is That

(<< "val a: ~{nil}") ;=> "val a: "
But other langs will have:
main() {
  final b = null;
  print("val a: $b"); // val a: null
}
So format should be used instead of str

delaguardo18:07:25

Maybe then pr-str?

👍 1
borkdude20:07:00

It depends which semantics you would like to have. I would like to embed a string literal within a string I think?

(let [x "dude"] (<< "val: ~{x}"))
should return val: dude and not val: "dude"

borkdude20:07:39

in that sense, maybe it's also fine to have nothing for nil, not sure

delaguardo06:07:04

Or there could be pr-<< macro with pr-str behavior

borkdude14:07:25

and if you wanted to escape ~ within a string, you could write: ~\\~

diego.videco15:07:35

Can anyone help with clj-pdf ? I am trying to create a pdf but not write it immediately to a file, I want to be able to send it to s3 or via an email (still not sure). The docs however are not too clear about working with streams (which I guess is what I need), but I am not too familiar with streams either. My first question is why do the docs call this function (all in lowercase), it doesn’t seem to exist and I can only find a camel case version of it:

(def doc1 (java.io.bytearrayoutputstream.))
My next question is once I call this:
(pdf [{} "first document"] doc1)
What do I do with doc1 to make it into something that can be sent as an email attachment or to s3? ( I suppose that would be a byte array, am I right?)

p-himik18:07:04

As to your first question, the documentation is probably incorrect. And regarding sending the data somewhere - depends on what exactly you're using for email sending or S3 uploading.

diego.videco19:07:25

I am using the aws sdk, both for s3 and ses (for email)

diego.videco19:07:44

great, thanks!

jdkealy23:07:48

I’m pretty confused with regards to bigdec’s.

;;; i have these two values and calculating a percent change
(def price (bigdec 25.21))
(def average-price (bigdec  25.23))

;; calculating the change
(with-precision 2 (/
  (- price average-price)
  average-price)) => 0.0083M 
;; ^ weird, it should be negative

;; do a little debugging, manually get the delta before doing division 
(- price average-price) => -0.02M 

(with-precision 2 (/ -0.02M average-price)) => -0.00079M 
^ how are these results different 

;; add some precision perhaps ? 
(with-precision 4 (/
   (- price average-price)
   average-price)) => -0.0007927M

;; get same result? 
(with-precision 4 (/
  (bigdec -0.02)
   average-price)) => -0.0007927M

seancorfield23:07:52

user=> (with-precision 2 :rounding CEILING (/ (- price average-price) average-price))
0.0084M
user=> (with-precision 2 :rounding FLOOR (/ (- price average-price) average-price))
-0.032M
user=> (with-precision 2 :rounding HALF_DOWN (/ (- price average-price) average-price))
0.0083M
user=> (with-precision 2 :rounding DOWN (/ (- price average-price) average-price))
0.0083M
user=> (with-precision 2 :rounding UP (/ (- price average-price) average-price))
-0.032M
user=>

seancorfield23:07:17

See the docstring:

user=> (doc with-precision)
-------------------------
clojure.core/with-precision
([precision & exprs])
Macro
  Sets the precision and rounding mode to be used for BigDecimal operations.

  Usage: (with-precision 10 (/ 1M 3))
  or:    (with-precision 10 :rounding HALF_DOWN (/ 1M 3))

  The rounding mode is one of CEILING, FLOOR, HALF_UP, HALF_DOWN,
  HALF_EVEN, UP, DOWN and UNNECESSARY; it defaults to HALF_UP.

jdkealy23:07:49

Oh i see the issue.

(- price average-price) => -0.02M 
(with-precision 2 (- price average-price)) => 0.21M why would that be ?

seancorfield23:07:12

See my threaded response to your first post but also:

user=> (with-precision 2 (- price average-price))
0.21M
user=> (with-precision 2 :rounding UP (- price average-price))
-0.79M
user=> (with-precision 2 :rounding DOWN (- price average-price))
0.21M
user=>