Fork me on GitHub
#clojure
<
2023-12-11
>
Lidor Cohen09:12:12

Hello everyone! πŸ‘‹ Does anyone knows how doc generators work on cljs sources? I have a couple of hidden assumptions here so please correct me if I'm wrong: 1. Prominent tools for doc generation are written in clj (not cljs). 2. Doc generator written in clj has no issue generating docs for cljs. 3. Doc generators take advantages of homoiconicity and work on the source code as data and not as string. My main interest is: How does a clj program that read cljs sources and turn them into data for processing looks like? Especially the part that read the sources (I assume a generic tree of source code not just a single file) and turn them into data without evaluating (as evaluation of cljs is not necessarily possible in clj env).

jpmonettas12:12:43

you can read Clojure source files into Clojure datastructures by using read over a reader, like this :

(require '[ :as io])

(def r (clojure.lang.LineNumberingPushbackReader. (io/reader "./main.clj")))

(read r) ;; will read and return the first form
(read r) ;; will read and return the second form, etc 

πŸ™ 1
Lidor Cohen12:12:11

What happens with reader literals specific to cljs (like #js)?

jpmonettas12:12:27

there are more than one way for dealing with that, but I think the easiest way to read cljs files is to use cljs.analyzer.api/forms-seq from the ClojureScript project

jpmonettas12:12:54

it will basically do what I described before but binding *data-readers* to the cljs readers like #js

Alex Miller (Clojure team)14:12:46

the reader has a "read-preserving" mode you can enable that retains tagged literals

Alex Miller (Clojure team)14:12:28

actually, that's for reader conditionals, sorry, but you can bind no data readers and use the tagged-literal reader as the default data reader fn to preserve that info

jpmonettas14:12:17

interesting, how would you use that to read something like (read-string "#js {:a 1}") ?

Alex Miller (Clojure team)14:12:53

user=> (binding [*data-readers* {}, *default-data-reader-fn* tagged-literal] (read-string "#js {:a 1}"))
#js {:a 1}

Alex Miller (Clojure team)14:12:43

the tagged-literal function reads a tag and a literal and puts it in a TaggedLiteral object (no semantics here). The object supports ILookup for keywords :tag and :form. It prints back to the tagged literal form.

jpmonettas14:12:01

nice, thanks!

Alex Miller (Clojure team)14:12:20

the general idea behind tagged literals is that anyone can read and pass them on without understanding them

Lidor Cohen08:12:26

thanks for the thread everyone πŸ™

Aviv09:12:23

Hello everyone, is there a way to read meta using read-string, for example (read-string "(def ^{:meta \"meta\"} a 1)") return (def a 1) (without the meta) Thanks πŸ™

delaguardo09:12:50

Metadata is there, you just can't see it because of how the result is printed.

πŸ‘ 1
phill09:12:40

The setting (whether or not to print metadata) can be managed with https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/*print-meta*

Aviv10:12:12

Thanks! I managed to read the meta using what @U04V4KLKC said. I'm trying to understand why meta isn't the second? I thought it would be a list: First - def Second - ^meta.. Third - a Is there a way to achieve that?

Aviv10:12:49

ok i guess, the meta is being evaluated when it’s read

delaguardo10:12:40

it is evaluated even when outer form is quoted

delaguardo10:12:34

but as in the first example, the second item in the list is symbol a with attached metadata

Aviv10:12:10

I see, thanks! πŸ™

p-himik11:12:15

Some bizarre behavior:

java.lang.UnsupportedOperationException: nth not supported on this type: PersistentArrayMap
    at clojure.lang.RT.nthFrom(RT.java:992)
    at clojure.lang.RT.nth(RT.java:940)
    at taoensso.sente$unpack.invokeStatic(sente.cljc:225)
    at taoensso.sente$unpack.invoke(sente.cljc:223)
    at taoensso.sente$make_channel_socket_server_BANG_$ring_handler__53007$on_msg__53020.invoke(sente.cljc:795)
The function unpack where line 225 is this unabridged destructuring that results in what I assume to be the call to nth:
(defn- unpack "packed->[clj ?cb-uuid]"
  [packer packed]
  (let [[packed ?format] (parse-packed packed)
        ...]
    ...))
The mentioned parse-packed function:
(defn- parse-packed [packed]
  (if (string? packed)
    (cond
      (enc/str-starts-with? packed "+") [(subs packed 1) :v1/wrapped]
      (enc/str-starts-with? packed "-") [(subs packed 1) :v1/unwrapped]
      :else                             [      packed    :v2/unwrapped])
    [packed :v2/unwrapped]))
How on Earth could an array map be made here? Is it just another case of the reported exception line being wrong? The unpack function does have another destructuring at line 233.

seancorfield16:12:39

Try it on Clojure 1.10 - I think this is a side effect of the changes in 1.11 to allow both unrolled k/v pair arguments or hash maps in destructuring.

seancorfield16:12:27

(I'm not saying that explains the exception, just that I think you'll get different behavior on 1.10)

p-himik18:12:08

Heh, I would, but it's the only exception, from production, at a time when nobody can possibly use this internal app. I have absolutely no clue how to trigger it again.

seancorfield18:12:30

That is a weird one -- I can't see how it would produce that exception, without someone redefining parse-packed...

1
valerauko11:12:09

Are you sure you're looking at the correct version of the source code?

p-himik11:12:10

Yes. I even logged into that very server and checked the output of (source ...) for those functions.

valerauko14:12:11

Call me paranoid but if this happened on my work internal production I'd investigate on the assumption that someone penetrated the system. (And then when you find the inevitable weird bug, like the health check sending a null websocket packet, it's gonna be a huge relief)

βœ… 1
πŸ‘ 1
p-himik14:12:43

Heroku forces me to log in every new day that I use the WUI and around every week or so that I use the CLI, plus the app itself is a CMS for a music learning app. The worst someone can do is replace the notes for "Twinkle Twinkle Little Star" with the notes of "Raining Blood" by Slayer. So I'm not that worried. :)

p-himik10:01:28

Turns out, Clojure is to blame. Well, at least for most time that I spent on the issue. It reported the line wrong, by whopping 8 lines.

πŸ‘ 1
πŸ‘€ 1
Takis_23:12:09

Hello, i am reading a apache-flink book, so i tried the examples in clojure, i found this to help use clojure functions, but its still so verbose, are there any better solutions? https://github.com/keytiong/flink-clojure#example

Takis_23:12:48

i heard that in clojure 12, lambdas will work with fn, i hope it will be working, so Clojure makes all those java functional libraries much easier than they are in Java or in Scala. Maybe if this is done in Clojure 12 the above flink problem will be solved also.

Alex Miller (Clojure team)02:12:14

Not sure, depends what the Java api is there. But generally you should be able to invoke Java methods that take functional interfaces with Clojure fns

gratitude-thank-you 1
πŸ™‚ 1
Takis_14:12:46

i want to use Clojure to be data engineer, and even if clojure is great, because i can't use lambdas code becomes so verbose, it will be very nice if clojure can use fn as lambdas in kafka,spark,flink etc like java does, clojure is so good we need this, hope someone to be able to do it 😞

Takis_14:12:05

i hope its possible thank you ❀️