Re: How to safely print structures that may contain infinite lazy seqs?
I wrote a little library for this purpose a while ago: https://github.com/borkdude/finitize -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/clojure/1998dfa5-fd4c-4d39-b5da-9aff44797c36n%40googlegroups.com.
Re: How to safely print structures that may contain infinite lazy seqs?
I'm not 100% happy with this plus it doesn't really answer the original question, but in case it helps in some way ... Recently, I had a record I was working on that holds a seq that could be a lazy infinite seq that I ended up using this as the major part of print-method implementation: (def ^:dynamic *print-look-ahead-length* 2) (defn seq->str [s] (let [[f' r] (split-at *print-look-ahead-length* s) f (apply list f')] (if (seq r) (str "(" (first f) " " (second f) " <+ more>)") (str f I played with checking for instance of a number of things that just got too messy for me at the time. So, for now, I just decided it was good enough to basically see 2 items into the seq and indicate if there are more. This could easily be made more variable in places. Bret On Monday, November 2, 2020 at 7:23:08 PM UTC-6 Austin Haas wrote: > > Thanks, Justin! > > Yeah, I noticed that range doesn't return an instance of > clojure.lang.LazySeq, so I added a print-method for clojure.lang.Iterate. > And that one seems to work as expected, but apparently you can't override > the print-method for clojure.lang.LazySeq. > > But this doesn't seem like a good approach, anyway, because I don't want > to change the printing behavior globally. > > I think I'm just going to have to forego logging arbitrary things, and > maybe implement some optional santization if necessary. > On Monday, November 2, 2020 at 12:40:48 PM UTC-8 noise...@gmail.com wrote: > >> hit send too soon -- >> >> also, that print-method doesn't catch all lazy values >> >> user=> (instance? clojure.lang.LazySeq (range)) >> false >> >> user=> (supers (class (range))) >> #{java.lang.Iterable java.util.List clojure.lang.Obj >> clojure.lang.IPending java.io.Serializable clojure.lang.IHashEq >> java.util.Collection clojure.lang.IObj clojure.lang.Sequential >> clojure.lang.Seqable clojure.lang.IPersistentCollection >> clojure.lang.ASeq clojure.lang.IReduce java.lang.Object >> clojure.lang.ISeq clojure.lang.IMeta clojure.lang.IReduceInit} >> >> On Mon, Nov 2, 2020 at 12:36 PM Justin Smith wrote: >> > >> > > The next step might be to investigate why infinite lazy seqs don't >> print as clojure.lang.LazySeq, like the finite ones. >> > >> > that printing of "clojure.lang.LazySeq@c5d38b66" relies on completely >> > realizing the input, as it relies on the hash, which relies on the >> > fully realized value >> > >> > On Mon, Nov 2, 2020 at 12:32 PM Austin Haas >> wrote: >> > > >> > > Thanks, Juan. >> > > >> > > I don't need to know the length of the seq, though, only that it is >> lazy. I don't want to realize any lazy seqs. Ideally, I'd like to be able >> to print any data structure and have all lazy seqs print just like it does >> in the example I gave above (i.e., "clojure.lang.LazySeq@c5d38b66"), >> whether it is finite or infinite. >> > > >> > > I also don't want to walk through every data structure to check if it >> contains a lazy seq, but maybe that is the only option. >> > > >> > > I've also tried: >> > > >> > > (defmethod print-method clojure.lang.LazySeq [q, w] >> > > (.write w "#clojure.lang.LazySeq")) >> > > >> > > The next step might be to investigate why infinite lazy seqs don't >> print as clojure.lang.LazySeq, like the finite ones. >> > > On Monday, November 2, 2020 at 9:22:58 AM UTC-8 jpmon...@gmail.com >> wrote: >> > >> >> > >> Hi Austin, >> > >> >> > >> Since there is no way to know the length of a lazy-seq without >> realizing it, I think your only choice is to set a limit on it by binding >> *print-length* if you are not sure about the sequence. >> > >> >> > >> Other thing you can try is bounded-count like this : >> > >> >> > >> (defn looks-finite? [xs] >> > >> (let [limit 1000] >> > >> (< (bounded-count limit xs) limit))) >> > >> >> > >> (looks-finite? (map inc (range))) ;; => false >> > >> (looks-finite? (map inc (range 100))) ;; => true >> > >> >> > >> I hope that helps. >> > >> >> > >> Juan >> > >> El domingo, 1 de noviembre de 2020 a las 20:06:39 UTC-3, Austin Haas >> escribió: >> > >>> >> > >>> >> > >>> How can I make sure that a logging function won't try to realize an >> infinite lazy seq that could be anywhere in the arguments passed to the >> logging function? >> > >>> >> > >>> Is there some way to guarantee that lazy seqs won't be realized >> when converting to a string? >> > >>> >> > >>> I know I can bind *print-length*, but I don't want to constrain >> every collection. >> > >>> >> > >>> And I know that lazy seqs aren't always realized, but that doesn't >> seem to help if they are infinite: >> > >>> >> > >>> user=> (str (map inc (range 10))) >> > >>> "clojure.lang.LazySeq@c5d38b66" >> > >>> >> > >>> user=> (str (map inc (range))) >> > >>> >> > >>> >> > >>> Thanks. >> > >>> >> > > -- >> > > You received this message because you are subscribed to the Google >> > > Groups "Clojure" group. >>
Re: How to safely print structures that may contain infinite lazy seqs?
Thanks, Justin! Yeah, I noticed that range doesn't return an instance of clojure.lang.LazySeq, so I added a print-method for clojure.lang.Iterate. And that one seems to work as expected, but apparently you can't override the print-method for clojure.lang.LazySeq. But this doesn't seem like a good approach, anyway, because I don't want to change the printing behavior globally. I think I'm just going to have to forego logging arbitrary things, and maybe implement some optional santization if necessary. On Monday, November 2, 2020 at 12:40:48 PM UTC-8 noise...@gmail.com wrote: > hit send too soon -- > > also, that print-method doesn't catch all lazy values > > user=> (instance? clojure.lang.LazySeq (range)) > false > > user=> (supers (class (range))) > #{java.lang.Iterable java.util.List clojure.lang.Obj > clojure.lang.IPending java.io.Serializable clojure.lang.IHashEq > java.util.Collection clojure.lang.IObj clojure.lang.Sequential > clojure.lang.Seqable clojure.lang.IPersistentCollection > clojure.lang.ASeq clojure.lang.IReduce java.lang.Object > clojure.lang.ISeq clojure.lang.IMeta clojure.lang.IReduceInit} > > On Mon, Nov 2, 2020 at 12:36 PM Justin Smith wrote: > > > > > The next step might be to investigate why infinite lazy seqs don't > print as clojure.lang.LazySeq, like the finite ones. > > > > that printing of "clojure.lang.LazySeq@c5d38b66" relies on completely > > realizing the input, as it relies on the hash, which relies on the > > fully realized value > > > > On Mon, Nov 2, 2020 at 12:32 PM Austin Haas > wrote: > > > > > > Thanks, Juan. > > > > > > I don't need to know the length of the seq, though, only that it is > lazy. I don't want to realize any lazy seqs. Ideally, I'd like to be able > to print any data structure and have all lazy seqs print just like it does > in the example I gave above (i.e., "clojure.lang.LazySeq@c5d38b66"), > whether it is finite or infinite. > > > > > > I also don't want to walk through every data structure to check if it > contains a lazy seq, but maybe that is the only option. > > > > > > I've also tried: > > > > > > (defmethod print-method clojure.lang.LazySeq [q, w] > > > (.write w "#clojure.lang.LazySeq")) > > > > > > The next step might be to investigate why infinite lazy seqs don't > print as clojure.lang.LazySeq, like the finite ones. > > > On Monday, November 2, 2020 at 9:22:58 AM UTC-8 jpmon...@gmail.com > wrote: > > >> > > >> Hi Austin, > > >> > > >> Since there is no way to know the length of a lazy-seq without > realizing it, I think your only choice is to set a limit on it by binding > *print-length* if you are not sure about the sequence. > > >> > > >> Other thing you can try is bounded-count like this : > > >> > > >> (defn looks-finite? [xs] > > >> (let [limit 1000] > > >> (< (bounded-count limit xs) limit))) > > >> > > >> (looks-finite? (map inc (range))) ;; => false > > >> (looks-finite? (map inc (range 100))) ;; => true > > >> > > >> I hope that helps. > > >> > > >> Juan > > >> El domingo, 1 de noviembre de 2020 a las 20:06:39 UTC-3, Austin Haas > escribió: > > >>> > > >>> > > >>> How can I make sure that a logging function won't try to realize an > infinite lazy seq that could be anywhere in the arguments passed to the > logging function? > > >>> > > >>> Is there some way to guarantee that lazy seqs won't be realized when > converting to a string? > > >>> > > >>> I know I can bind *print-length*, but I don't want to constrain > every collection. > > >>> > > >>> And I know that lazy seqs aren't always realized, but that doesn't > seem to help if they are infinite: > > >>> > > >>> user=> (str (map inc (range 10))) > > >>> "clojure.lang.LazySeq@c5d38b66" > > >>> > > >>> user=> (str (map inc (range))) > > >>> > > >>> > > >>> Thanks. > > >>> > > > -- > > > You received this message because you are subscribed to the Google > > > Groups "Clojure" group. > > > To post to this group, send email to clo...@googlegroups.com > > > Note that posts from new members are moderated - please be patient > with your first post. > > > To unsubscribe from this group, send email to > > > clojure+u...@googlegroups.com > > > For more options, visit this group at > > > http://groups.google.com/group/clojure?hl=en > > > --- > > > You received this message because you are subscribed to the Google > Groups "Clojure" group. > > > To unsubscribe from this group and stop receiving emails from it, send > an email to clojure+u...@googlegroups.com. > > > To view this discussion on the web visit > https://groups.google.com/d/msgid/clojure/ab820e20-75ad-4852-aa01-9321cb7487b4n%40googlegroups.com > . > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit
Re: How to safely print structures that may contain infinite lazy seqs?
hit send too soon -- also, that print-method doesn't catch all lazy values user=> (instance? clojure.lang.LazySeq (range)) false user=> (supers (class (range))) #{java.lang.Iterable java.util.List clojure.lang.Obj clojure.lang.IPending java.io.Serializable clojure.lang.IHashEq java.util.Collection clojure.lang.IObj clojure.lang.Sequential clojure.lang.Seqable clojure.lang.IPersistentCollection clojure.lang.ASeq clojure.lang.IReduce java.lang.Object clojure.lang.ISeq clojure.lang.IMeta clojure.lang.IReduceInit} On Mon, Nov 2, 2020 at 12:36 PM Justin Smith wrote: > > > The next step might be to investigate why infinite lazy seqs don't print as > > clojure.lang.LazySeq, like the finite ones. > > that printing of "clojure.lang.LazySeq@c5d38b66" relies on completely > realizing the input, as it relies on the hash, which relies on the > fully realized value > > On Mon, Nov 2, 2020 at 12:32 PM Austin Haas wrote: > > > > Thanks, Juan. > > > > I don't need to know the length of the seq, though, only that it is lazy. I > > don't want to realize any lazy seqs. Ideally, I'd like to be able to print > > any data structure and have all lazy seqs print just like it does in the > > example I gave above (i.e., "clojure.lang.LazySeq@c5d38b66"), whether it is > > finite or infinite. > > > > I also don't want to walk through every data structure to check if it > > contains a lazy seq, but maybe that is the only option. > > > > I've also tried: > > > > (defmethod print-method clojure.lang.LazySeq [q, w] > > (.write w "#clojure.lang.LazySeq")) > > > > The next step might be to investigate why infinite lazy seqs don't print as > > clojure.lang.LazySeq, like the finite ones. > > On Monday, November 2, 2020 at 9:22:58 AM UTC-8 jpmon...@gmail.com wrote: > >> > >> Hi Austin, > >> > >> Since there is no way to know the length of a lazy-seq without realizing > >> it, I think your only choice is to set a limit on it by binding > >> *print-length* if you are not sure about the sequence. > >> > >> Other thing you can try is bounded-count like this : > >> > >> (defn looks-finite? [xs] > >> (let [limit 1000] > >> (< (bounded-count limit xs) limit))) > >> > >> (looks-finite? (map inc (range))) ;; => false > >> (looks-finite? (map inc (range 100))) ;; => true > >> > >> I hope that helps. > >> > >> Juan > >> El domingo, 1 de noviembre de 2020 a las 20:06:39 UTC-3, Austin Haas > >> escribió: > >>> > >>> > >>> How can I make sure that a logging function won't try to realize an > >>> infinite lazy seq that could be anywhere in the arguments passed to the > >>> logging function? > >>> > >>> Is there some way to guarantee that lazy seqs won't be realized when > >>> converting to a string? > >>> > >>> I know I can bind *print-length*, but I don't want to constrain every > >>> collection. > >>> > >>> And I know that lazy seqs aren't always realized, but that doesn't seem > >>> to help if they are infinite: > >>> > >>> user=> (str (map inc (range 10))) > >>> "clojure.lang.LazySeq@c5d38b66" > >>> > >>> user=> (str (map inc (range))) > >>> > >>> > >>> Thanks. > >>> > > -- > > You received this message because you are subscribed to the Google > > Groups "Clojure" group. > > To post to this group, send email to clojure@googlegroups.com > > Note that posts from new members are moderated - please be patient with > > your first post. > > To unsubscribe from this group, send email to > > clojure+unsubscr...@googlegroups.com > > For more options, visit this group at > > http://groups.google.com/group/clojure?hl=en > > --- > > You received this message because you are subscribed to the Google Groups > > "Clojure" group. > > To unsubscribe from this group and stop receiving emails from it, send an > > email to clojure+unsubscr...@googlegroups.com. > > To view this discussion on the web visit > > https://groups.google.com/d/msgid/clojure/ab820e20-75ad-4852-aa01-9321cb7487b4n%40googlegroups.com. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/clojure/CAGokn9L7pzXArLcvu0BUf0x7JnD2wZpjgisuFr6ZPfA0817EZg%40mail.gmail.com.
Re: How to safely print structures that may contain infinite lazy seqs?
> The next step might be to investigate why infinite lazy seqs don't print as > clojure.lang.LazySeq, like the finite ones. that printing of "clojure.lang.LazySeq@c5d38b66" relies on completely realizing the input, as it relies on the hash, which relies on the fully realized value On Mon, Nov 2, 2020 at 12:32 PM Austin Haas wrote: > > Thanks, Juan. > > I don't need to know the length of the seq, though, only that it is lazy. I > don't want to realize any lazy seqs. Ideally, I'd like to be able to print > any data structure and have all lazy seqs print just like it does in the > example I gave above (i.e., "clojure.lang.LazySeq@c5d38b66"), whether it is > finite or infinite. > > I also don't want to walk through every data structure to check if it > contains a lazy seq, but maybe that is the only option. > > I've also tried: > > (defmethod print-method clojure.lang.LazySeq [q, w] > (.write w "#clojure.lang.LazySeq")) > > The next step might be to investigate why infinite lazy seqs don't print as > clojure.lang.LazySeq, like the finite ones. > On Monday, November 2, 2020 at 9:22:58 AM UTC-8 jpmon...@gmail.com wrote: >> >> Hi Austin, >> >> Since there is no way to know the length of a lazy-seq without realizing it, >> I think your only choice is to set a limit on it by binding *print-length* >> if you are not sure about the sequence. >> >> Other thing you can try is bounded-count like this : >> >> (defn looks-finite? [xs] >> (let [limit 1000] >> (< (bounded-count limit xs) limit))) >> >> (looks-finite? (map inc (range))) ;; => false >> (looks-finite? (map inc (range 100))) ;; => true >> >> I hope that helps. >> >> Juan >> El domingo, 1 de noviembre de 2020 a las 20:06:39 UTC-3, Austin Haas >> escribió: >>> >>> >>> How can I make sure that a logging function won't try to realize an >>> infinite lazy seq that could be anywhere in the arguments passed to the >>> logging function? >>> >>> Is there some way to guarantee that lazy seqs won't be realized when >>> converting to a string? >>> >>> I know I can bind *print-length*, but I don't want to constrain every >>> collection. >>> >>> And I know that lazy seqs aren't always realized, but that doesn't seem to >>> help if they are infinite: >>> >>> user=> (str (map inc (range 10))) >>> "clojure.lang.LazySeq@c5d38b66" >>> >>> user=> (str (map inc (range))) >>> >>> >>> Thanks. >>> > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with your > first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > --- > You received this message because you are subscribed to the Google Groups > "Clojure" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to clojure+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/clojure/ab820e20-75ad-4852-aa01-9321cb7487b4n%40googlegroups.com. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/clojure/CAGokn9%2BGw2oZBfMNMGKPVko7gOUDMJMNuz3dEr45vdx%2BuEUgrA%40mail.gmail.com.
Re: How to safely print structures that may contain infinite lazy seqs?
Thanks, Juan. I don't need to know the length of the seq, though, only that it is lazy. I don't want to realize *any* lazy seqs. Ideally, I'd like to be able to print any data structure and have all lazy seqs print just like it does in the example I gave above (i.e., "clojure.lang.LazySeq@c5d38b66"), whether it is finite or infinite. I also don't want to walk through every data structure to check if it contains a lazy seq, but maybe that is the only option. I've also tried: (defmethod print-method clojure.lang.LazySeq [q, w] (.write w "#clojure.lang.LazySeq")) The next step might be to investigate why infinite lazy seqs don't print as clojure.lang.LazySeq, like the finite ones. On Monday, November 2, 2020 at 9:22:58 AM UTC-8 jpmon...@gmail.com wrote: > Hi Austin, > > Since there is no way to know the length of a lazy-seq without realizing > it, I think your only choice is to set a limit on it by binding > *print-length* if you are not sure about the sequence. > > Other thing you can try is bounded-count like this : > > (defn looks-finite? [xs] > (let [limit 1000] > (< (bounded-count limit xs) limit))) > > (looks-finite? (map inc (range))) ;; => false > (looks-finite? (map inc (range 100))) ;; => true > > I hope that helps. > > Juan > El domingo, 1 de noviembre de 2020 a las 20:06:39 UTC-3, Austin Haas > escribió: > >> >> How can I make sure that a logging function won't try to realize an >> infinite lazy seq that could be anywhere in the arguments passed to the >> logging function? >> >> Is there some way to guarantee that lazy seqs won't be realized when >> converting to a string? >> >> I know I can bind *print-length*, but I don't want to constrain every >> collection. >> >> And I know that lazy seqs aren't always realized, but that doesn't seem >> to help if they are infinite: >> >> user=> (str (map inc (range 10))) >> "clojure.lang.LazySeq@c5d38b66" >> >> user=> (str (map inc (range))) >> >> >> Thanks. >> >> -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/clojure/ab820e20-75ad-4852-aa01-9321cb7487b4n%40googlegroups.com.
Re: How to safely print structures that may contain infinite lazy seqs?
Hi Austin, Since there is no way to know the length of a lazy-seq without realizing it, I think your only choice is to set a limit on it by binding *print-length* if you are not sure about the sequence. Other thing you can try is bounded-count like this : (defn looks-finite? [xs] (let [limit 1000] (< (bounded-count limit xs) limit))) (looks-finite? (map inc (range))) ;; => false (looks-finite? (map inc (range 100))) ;; => true I hope that helps. Juan El domingo, 1 de noviembre de 2020 a las 20:06:39 UTC-3, Austin Haas escribió: > > How can I make sure that a logging function won't try to realize an > infinite lazy seq that could be anywhere in the arguments passed to the > logging function? > > Is there some way to guarantee that lazy seqs won't be realized when > converting to a string? > > I know I can bind *print-length*, but I don't want to constrain every > collection. > > And I know that lazy seqs aren't always realized, but that doesn't seem to > help if they are infinite: > > user=> (str (map inc (range 10))) > "clojure.lang.LazySeq@c5d38b66" > > user=> (str (map inc (range))) > > > Thanks. > > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/clojure/5318a41e-7353-4c81-b1d4-99a3c54e3120n%40googlegroups.com.