This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-01-26
Channels
- # aleph (9)
- # announcements (31)
- # babashka (23)
- # beginners (35)
- # biff (2)
- # calva (5)
- # cider (10)
- # clara (11)
- # clerk (114)
- # clj-kondo (18)
- # cljdoc (37)
- # clojars (7)
- # clojure (24)
- # clojure-austin (10)
- # clojure-europe (27)
- # clojure-nl (1)
- # clojure-norway (23)
- # clojure-uk (2)
- # clojurescript (18)
- # conjure (2)
- # core-async (6)
- # cursive (21)
- # datomic (3)
- # fulcro (15)
- # introduce-yourself (7)
- # lsp (32)
- # malli (57)
- # meander (5)
- # music (1)
- # nbb (2)
- # off-topic (17)
- # pathom (6)
- # rdf (4)
- # reagent (8)
- # releases (2)
- # shadow-cljs (4)
- # slack-help (23)
- # spacemacs (6)
- # tools-build (32)
is there a way to determine the line number read-string fails on in parsing a large edn file?
(let [input "{:a\n :b\n\n\n\n\n:c\n1.a[1\n2\n3\n\n\n]}"
stream (clojure.lang.LineNumberingPushbackReader.
(java.io.StringReader. input))]
(edn/read stream))
which has line and column information
public static class ReaderException extends RuntimeException{
final int line;
final int column;
persisted-info=> (reflect/reflect *e)
{:bases #{java.lang.RuntimeException},
:flags #{:public},
:members #{#clojure.reflect.Field{:name line,
:type int,
:declaring-class clojure.lang.EdnReader$ReaderException,
:flags #{:final}}
#clojure.reflect.Constructor{:name clojure.lang.EdnReader$ReaderException,
:declaring-class clojure.lang.EdnReader$ReaderException,
:parameter-types [int
int
java.lang.Throwable],
:exception-types [],
:flags #{:public}}
#clojure.reflect.Field{:name column,
:type int,
:declaring-class clojure.lang.EdnReader$ReaderException,
:flags #{:final}}}}
but they are not public. You could use reflection to make those fields visible and then grab themi think you could open up an http://ask.clojure.org ticket about maybe making those visible? Seems useful
if you keep the reference to the reader then there are methods to get line and col:
(.getLineNumber rdr) and (.getColumnNumber rdr)
but they will not be accurate because EdnReader doesn't unread
erroneous symbols on failure.
Is it safe to call empty?
on an infinite lazy-seq? It calls seq
inside and I was looking into implementation of clojure.lang.RT
but I can't find the constructor. Maybe I don't know Java anymore...? š
looks safe enough to me š
yes it is safe. You can call seq
on an infinite range. Just donāt print it. If you type (seq (range))
in a repl youāll blow up. But it is just because you are printing an infinite sequence, not that the seq
call did anything
There are difficulties in this thought. For instance (filter neg? (range))
is empty as we know. But calling (empty? (filter neg? (range)))
will lock your repl.
Because it doesnāt reason about things like we can. It never finds an element to prove that itās not empty, but never exhausts the (range)
to prove that it is empty. So it keeps trying
Thanks for the answer. I already tried to print it and it printed it. But it was weird that I can simply convert it into a seq (ok, I have some work experience with Clojure but it's good to revisit the old known things)
Yes but the question also was about how would I make sense of what the Clojure compiler do? Does it actually call a method of RT.java
?
(defn empty?
"Returns true if coll has no items - same as (not (seq coll)).
Please use the idiom (seq x) rather than (not (empty? x))"
{:added "1.0"
:static true}
[coll] (not (seq coll)))
it calls seq
. so check (source seq)
:
(def
^{:arglists '(^clojure.lang.ISeq [coll])
:doc "Returns a seq on the collection. If the collection is
empty, returns nil. (seq nil) returns nil. seq also works on
Strings, native Java arrays (of reference types) and any objects
that implement Iterable. Note that seqs cache values, thus seq
should not be used on any Iterable whose iterator repeatedly
returns the same mutable object."
:tag clojure.lang.ISeq
:added "1.0"
:static true}
seq (fn ^:static seq ^clojure.lang.ISeq [coll] (. clojure.lang.RT (seq coll))))
Thereās your
> Thereās your
I know the source. This is how I know that it calls RT.java. But I wanted to know whether it just calls this method: https://github.com/clojure/clojure/blob/e6fce5a42ba78fadcde00186c0b0c3cd00f45435/src/jvm/clojure/lang/RT.java#L531
Iām not sure I follow. It does call that from the source of seq
. And there donāt seem to be any other calls besides not
I wanted to know whether (seq ...)
converts into the call of seq(Object object)
from RT.java by compiler or does it do something different? Does the compiler call that method directly or by some other means?
I expected to see an interpreter like switch op { "seq": seq(obj) }
or something similar but there is nothing like that
Oh I see.
I thought of (. clojure.lang.RT (seq coll))
not as a function call but as a (clojure.lang.RT. (seq coll))
. This is why I was looking for a constructor š
Thanks.
This actually works as code:
(clojure.lang.RT.)
But there is no constructor with a param so the (seq ...)
one won't work š This was my misconception š