Fork me on GitHub
#clojure
<
2022-07-15
>
pinkfrog03:07:20

(defn outer [] 
  (fn inner [],,,))
How can I add doc string for the inner function?

phronmophobic03:07:43

I don't think it's possible. Why not use a comment?

Cora (she/her)03:07:06

the section Metadata Reader Macros has a method to add docs

Cora (she/her)03:07:33

> ^{:doc "How it works!"} - adds the metadata map to the metadata of the next value read

hiredman03:07:55

The difference between doc strings and comments is you can use doc in the repl to read doc strings

hiredman03:07:31

You cannot use doc to read the doc string on something that is not stored in a var (a top level def)

hiredman03:07:55

Just write a comment

Cora (she/her)03:07:21

would adding it to the metadata and then assigning it to a car work?

hiredman03:07:30

I don't believe so, if I recall def copies metadata from the symbol to the var, but not from the value

pinkfrog10:07:02

Is there a builtin function that returns true if x is logically true?

amithgeorge11:07:01

if you are used to 0 being false, in clojure it is treated logically true. I trip up on it from time to time :) - https://clojuredocs.org/clojure.core/boolean#example-54f09be3e4b0b716de7a652d

p-himik11:07:49

That would return false for (true? 1).

Yuriy Zaytsev12:07:11

Thanks, @U2FRKM4TW, I guess I misunderstood the question.

pinkfrog12:07:33

I often need a debug toggle in the code. Something like

(when *debug* ,,,)
but clojure.core does not have such variable. Normally how would you do this? Devise your own var?

delaguardo12:07:42

debug might have many meanings: special environment, nuances of the state, explicit intent. So you have to have your way to say “execute this form only when debug-mode”

borkdude12:07:14

you can also do it with an environment variable

vemv14:07:14

java System properties are particularly suitable: • can be set from Lein / t.deps • can be toggled at runtime • are not erased by Clojure code reloading

👍 2
danieroux14:07:50

I am failing to call a public inner class builder method, marked #{:public :bridge :synthetic}

danieroux14:07:00

(clj-otel does not do Metrics, only Traces. We want metrics too, so a "quick Java interop" and a few hours later):

danieroux14:07:11

This is the failure:

;; com.github.steffan-westcott/clj-otel-api {:mvn/version "0.1.4"}
(ns journal.2022-07-15-interop-for-metrics
  (:require
    [clojure.reflect])
  (:import
    (io.opentelemetry.api GlobalOpenTelemetry OpenTelemetry)))

(def global ^OpenTelemetry  (steffan-westcott.clj-otel.api.otel/get-global-otel!))
(def meterBuilderBuilder (.build (.meterBuilder global "wot")))
(def longBuilder (.counterBuilder meterBuilderBuilder "wotwot"))
(def by-method-name (group-by :name (:members (clojure.reflect/reflect longBuilder))))
(by-method-name 'setUnit)
; =>
;[#clojure.reflect.Method{:name setUnit,
;                         :return-type io.opentelemetry.api.metrics.LongCounterBuilder,
;                         :declaring-class io.opentelemetry.sdk.metrics.SdkLongCounter$Builder,
;                         :parameter-types [java.lang.String],
;                         :exception-types [],
;                         :flags #{:public :bridge :synthetic}}]
(.setUnit longBuilder "unit")
; => No matching method setUnit found taking 1 args for class io.opentelemetry.sdk.metrics.SdkLongCounter$Builder

danieroux14:07:13

@U2C6SPLDS did you get somewhere with Metrics? And also thank you, loving clj-otel for traces!

Ed15:07:58

If you can find the method with reflection, can you invoke it reflectively?

ghadi15:07:53

(.setUnit ^io.opentelemetry.api.metrics.LongCounterBuilder longBuilder "unit")

ghadi15:07:03

(.setUnit longBuilder "unit") works directly for me, too

ghadi15:07:25

looks like it fails on java8 but succeeds on 11

ghadi15:07:38

it = (.setUnit longBuilder "unit")

ghadi15:07:02

correction: it works on both

danieroux15:07:46

Can confirm the type hint works. Thank you!

danieroux15:07:02

Without it, not: $ java --version openjdk 11.0.11 2021-04-20 OpenJDK Runtime Environment AdoptOpenJDK-11.0.11+9 (build 11.0.11+9)

ghadi15:07:26

I'm still unclear on why it failed for you

ghadi15:07:56

In general though, trying interop calls with objs deffed to vars is challenging because the Vars are hinted to Object by default

👌 1
ghadi15:07:13

all interop calls will reflect if the compiler doesn't know anything more specific than Object

danieroux16:07:28

Ok, reproducing is a weird one: • I had to add more dependencies • And move to def binds. In a let inside a fn it all still worked.

danieroux16:07:45

(that repository now with a README that shows what I see)

steffan16:07:54

@U9E8C7QRJ Sorry for the late reply, I'm on holiday (vacation). I'm glad you are enjoying the traces support in clj-otel 🙂 As noted in the README, there's no support yet for metrics or logs. I plan to start work on this when I return. Feel free to drop in #clj-otel

p-himik15:11:56

Encountered the same here, along with the author: https://ask.clojure.org/index.php/12362/environment-variables-interactive-process-processbuilder (.put env "a" "b") fails on openjdk version "11.0.16" but (.put ^java.util.Map env "a" "b") works. Found a similar ticket: https://clojure.atlassian.net/browse/CLJ-1243

rickmoynihan16:07:14

I’m writing some pitch/design documents, and am looking for an alternative term to “accretive data model”. Is there a more widely established term for this in computing? I’m obviously aware of “append only” and I can coin a variant like “additive data model” etc… or perhaps reference something like “monotonically increasing” or a “semi-lattice”. But I have issues with all of these. My favourite is by far Rich Hickey’s “Accreting”; but whenever I say it (in the context the audience associated with this document) things always get derailed in a discussion involving google trends “accrete vs append” etc… • My issue with “append-only” is that implies a sequence. • My issue with “additive data model” is that googling it yields more popular results about non-parametric regression methods in statistics. This is obviously not what I’m referring too; but it’s also confused by the fact that the context for my work is also statistics. • My issue with “monotonically increasing” / “semi-lattice” etc are that they’re too mathematical, for the audience. I’d rather speak plainly, but also reference something established. Any thoughts?

hiredman16:07:09

merge only?

rickmoynihan16:07:58

nice idea, but google doesn’t turn up anything

rickmoynihan16:07:15

but that again is getting pretty technical

hiredman16:07:27

if you want people to be able to google it, you have to use the name for it, which is going to be technical, if you want to describe it in plain language it is going to be generic and not something you can google

rickmoynihan16:07:31

I suspect Rich may have coined “accreting information model” because of these issues 😐

Alex Miller (Clojure team)16:07:41

non-destructive data model :)

👏 3
Alex Miller (Clojure team)16:07:00

makes the downsides of the alternative more visible :)

rickmoynihan16:07:36

non-destructive data model has a lot going for it — I guess the only problem with that is that people will think they have that already; but really don’t.

sheluchin18:07:08

If I need a chain of network requests where response data is used to form subsequent requests, is that something I can do inside transduce's transformation stack? I've read somewhere that IO shouldn't be done inside the xform and should instead be done in the input collection and the rf, but I haven't seen that advice echoed elsewhere.

hiredman19:07:03

Check out the new clojure.core/iteration

sheluchin19:07:51

Thanks, I'll take a look. I've heard of it but haven't familiarized myself with it. Interesting to see that it was your post back in 2016 that originally got the ball rolling on adding this functionality to core!

qqq20:07:56

Say you're building a web app and you want to embed a CLJS like scripting language (like the way Emacs embeds elisp), is the way to go: replumb, klipse, babashka/sci, planck, lumo, ... or something else ?

borkdude20:07:41

Here's a demo using SCI + nextjournal clojure-mode: https://nextjournal.github.io/clojure-mode/

borkdude20:07:16

You can find more projects using SCI on the SCI README.md in github, to see if there's anything like what you want to build. Feel free to post questions in #sci if you're interested

Sakib22:07:14

Why java interop doesn't work with map filter etc? (map .toUpperCase ["saku" "monu"])

Jesse22:07:02

I forgot why that doesn't work; but what I normally do is wrap the interop in a function: (map #(.toUpperCase %) ["saku" "monu"])

hiredman22:07:16

(.toUpperCase x) is syntax sugar for (. x (toUpperCase))

hiredman22:07:10

.toUpperCase itself is not a function and isn't a symbol that evaluates to some function object that can be invoked, so cannot be passed as an argument

✔️ 2
isak22:07:36

Another case is (map Long/valueOf ["1"])

hiredman22:07:13

same thing, just once is a static method one is an instance method

hiredman22:07:39

neither is reified as a first class value by default on the jvm

hiredman22:07:06

(Long/valueOf x) is syntax sugar for (. Long (valueOf x))

thanks3 1
Alex Miller (Clojure team)22:07:36

this is actually something we've done some work on for 1.12, but not sure it will survive

2
👍 4
hiredman22:07:46

https://clojure.org/reference/java_interop#_the_dot_special_form the . and new special forms don't get used a ton since the syntax sugar was added on top of them, but they can be easier to generate in macros

Alex Miller (Clojure team)22:07:19

"this" = using Java static methods as clojure fns

isak22:07:33

To me the static one is more surprising, since you could otherwise think of clojure functions kind of like static functions

Alex Miller (Clojure team)22:07:48

it's more complicated than you think due to arities and overloads

1
Sakib22:07:57

Then how come these are valid?

(.toUpperCase "monu")

(Long/valueOf "123")

Alex Miller (Clojure team)23:07:12

those get rewritten to the . as mentioned above

hiredman23:07:27

(and true) is valid, but (map and [true]) is not

1
hiredman23:07:49

the reason it doesn't work for add is and is a macro, which is expanded away at compile time, and sort of doesn't have a runtime value

👍 2
hiredman23:07:32

.toUpperCase and Long/valueOf are similar

Sakib23:07:11

So in general no macro will not work inside map filter etc? Is this right?

hiredman23:07:59

you cannot take the value of a macro

hiredman23:07:56

similar to calling java methods, with a macro if you wrap it in a function, you can take the value of that

hiredman23:07:04

it's like in say some language with a C like syntax (js, java, C, C++, C#, etc) you cannot invoke && the and operator as function/method/whatever

hiredman23:07:54

js might be the best example because it has first class functions

hiredman23:07:48

[].reduce(function (x, y) { return x && y}, true) is fine, but [].reduce(&&, true) is not

👍 1
🤯 1