Fork me on GitHub
#clojure
<
2021-07-25
>
meta-meta00:07:17

(symbol "+1") => +1 (symbol? (symbol "+1")) => true (symbol? '+1) => false (symbol? '+) => true Why isn't +1 read as a a symbol? It seems valid based on https://clojure.org/reference/reader#_symbols

vemv00:07:37

(class '+1) you can figure out the answer from this ^ :)

meta-meta00:07:54

ah yes that makes sense. thank you!

đŸ» 3
meta-meta00:07:05

tunnel vision

greg01:07:50

I don't get it. (class '+1) => java.lang.Long Why is it a long?

vemv01:07:29

+1 is analogous to -1, i.e. a number literal

👍 3
😅 3
didibus06:07:53

Something else that needs to be said is that symbols don't have any real restrictions on their valid value for now, but the reader cannot read all values of symbols. So with the function symbols you can create any symbol, but you can't use the literal syntax for all of them:

(symbol "this is a valid symbol even!")

;; But off course it can't be read as one
'this is a valid symbol even!

;; Though there's an ugly hack using the eval reader
'#=(clojure.lang.Symbol/intern "this is a valid symbol even!")

;; which works for +1 as well
'#=(clojure.lang.Symbol/intern "+1")
But never use the reader to read untrusted input, especially not if you intend to allow use of the eval reader, since it can run arbitrary code, it is not safe, instead use the clojure.edn namespace to read things.

🙏 2
zimablue17:07:00

I found a weird thing, not sure if a bug, but I'm playing with middleware so pushing reflected information through edn serialization. It blows up on the metadata for "max" in clojure.core, because the :inline value is #function[clojure.core/nary-inline/fn--5541] which is an invalid symbol (I think), having 3 elements

potetm18:07:57

@U63D7UXJB You sure about that?

user=> (:inline (meta #'max))
#object[clojure.core$nary_inline$fn__5558 0x591fd34d "clojure.core$nary_inline$fn__5558@591fd34d"]

vemv18:07:36

as for the middleware, perhaps I'd cheat my way and dissoc :inline in that case and possibly other entries, like :tag (:tag, I think can have symbols, strings or classes as its values. Classes may not be always serializable / or something you want to serialize, considering that the receiving end may have a different classpath)

potetm18:07:26

#function does not appear to be a thing in clojure

potetm18:07:29

I’ve never seen it before.

zimablue18:07:36

hm dunno why I'm getting a different result than you potetm, I'll have another look

vemv18:07:43

it depends on the stack, dunno about the specifics

zimablue18:07:13

oh I see vemv, glad I'm not going mad

🙃 3
potetm18:07:37

@U45T93RA6 what do you mean it depends on “the stack?”

potetm18:07:44

How did you get the first result?

vemv18:07:43

the former is a lein repl with a lot of stuff in the classpath the latter is a raw clj repl sorry I can't give a super specific answer, I'm sure someone will chime in

potetm18:07:51

Yeah some library ya’ll are using is jacking with the print-method

👀 3
potetm18:07:02

all dis seems not-so-good 😄

vemv18:07:33

nice find! yes I use cider-nrepl

potetm19:07:31

:disapprove:

👎 3
didibus20:07:12

Meta doesnt normally get serialized when you use pr, so it shouldn't cause a problem.

potetm01:07:09

there’s a lot of “doesn’t normally” and “shouldn’t” in that statement

potetm01:07:11

you don’t want something as fundamental as serialization to have differences between prod and dev

potetm01:07:18

just a recipe for bugs

potetm01:07:35

Generally: You should’t be extending protocols/type-driven multimethods if you don’t either own the protocol or the type.

potetm01:07:50

It will cause bugs. (I’ve seen it.)

didibus04:07:06

You have to extend print-method to add custom types to EDN, the "E" is for extensible, and so that's the functionality for it. I'd personally prefer clojure.edn had its own write multi-method, but alas. What this means is that something is not properly extending print-method and I'd cut them a ticket, since print-method should handle the *print-readably* flag where when true, it should print in a way that is readable by the reader.

didibus04:07:43

Though for custom types, you'll also need to provide clojure.edn with how to read it

zimablue09:07:02

just got back to this, thanks a lot for the discussion it's educational

zimablue09:07:23

it did indeed cause me a quite strange bug where edn wouldn't roundtrip (clj=>cljs), and the only way to work out why was to do an element-by-element search partitioning the push of a giant structure, but first I looked in several wrong places for the origin

zimablue09:07:17

@U07S8JGF7 what do you prefer to cider nrepl?

potetm13:07:22

And I manually start up my own socket repl.

didibus15:07:42

I don't think we've established that the issue is due to cider yet. How are you doing the edn serialization?

didibus15:07:30

Are you on purpose serializing the meta?

didibus06:07:21

Oh I see. And it's the deserialization which fails? Or the serialization?

didibus06:07:23

So basically in EDN, neither #object[...] nor #function[...] are standard tagged elements. So you'll need to provide edn/read with a custom reader for them. By default, pr and prn do not serialize everything to proper EDN as well, Java objects for example won't automatically serialize to EDN. You need to extend print-method for those yourself, and have the implementation of print-method for it when *print-readably* is true return their EDN compatible serialized form. That's normally done with a tagged element. But a function is non-trivial to serialize and deserialize FYI. So you might not be able to do that.

didibus06:07:25

Your best bet here is to just skip over :inline keys when serializing here. In fact, since people can shove whatever in the meta, and you're making a Middleware, I would go with an include-list. So filter the meta with keys you know you can round-trip so only those get serialized and ignore the rest.

zimablue17:07:14

this doesn't seem important but I found it kind of interesting