-
Notifications
You must be signed in to change notification settings - Fork 113
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Provide default pretty-printing at repl #314
Comments
Later it occurred to me to add a few remarks on abbreviating large matrices. It seemed appropriate for a separate comment. Although in OCaml, large data structures such as lists are truncated in the utop repl, in Clojure, this doesn't happen with any of the built-in data structures. I know of at least one plugin that will truncate lists with an ellipsis, but I find it annoying. When I evaluate a large list or a map at the repl, I know what I'm doing, and I often want to see what's at the end of it. Why should matrices be treated differently in Clojure? Shouldn't large matrices be fully displayed if we're going to have a nice way of displaying of matrices by default? No, because matrices have a two-dimensional structure. That's their point. Dumping a large matrix into the space of a small terminal window just produces chaotic output that obscures relationships that are essential to a matrix. There's almost no point to it. All of the common Clojure data structures are either linear (lists, sequences) or unstructured (sets, maps, records). Dumping them as a long line of text that wraps at the edge of the window is perfectly reasonable. Matrices are different. (You might call a map 2D, with key and value as one dimension, but it's such a short dimension that it's appropriate to display a map as if it's a sequence of pairs.) (What about n-D arrays? How should they be displayed? I'm not sure, but the R language repl's method seems OK: Display a series of 2-D matrices, one on top of the other. In any event, I presume that 2-D matrices are more common than n-D arrays, and that asking for a nice two-dimensional display of something that has three or more dimensions is probably asking for too much. I'm not asking for that.) |
I don't think there is any way we can generically display the contents of a matrix / array at the REPL without changes to Clojure itself (unlikely to happen...). The reason for this is that an arbitrary object may implement the core.matrix protocols, and you have no way to guarantee they will all print in the same way. At best, you could establish a few optional conventions that implementations could follow. Also, I think that it is pretty hard to define a standard way of printing that works for everyone, e.g.:
I'm all for improvements to |
Thanks. I understand. Just thinking out loud: Every implementation has to present some way of displaying matrices, although in some cases this may be done via a default that isn't very explicitly chosen. In some cases this display function seems to incorporate the result of I don't know how much sense this idea makes. I also know that adding an implementation isn't necessarily trivial, so there's a cost to adding another quasi-requirement. However, I feel that the benefit is significant. Clojure is a joy to use. I know I'm not the only person who feels that way. I'm suggesting a way to increase the convenience--the joy--of using core.matrix, which is already a pleasure to use. |
I don't mean truly global variables. I had in mind something like the dynamic variables in implementations.cljc. |
I guess it would be possible to recommend that implementation override https://clojuredocs.org/clojure.core/print-method with |
I have as well a bit of a problem by printing large matrices or data sets on the screen of the repl. For me it is more the problem of the repl, as for example Emacs crashes, if I press "return" to quick and it wants to print a big dataset. I like a lot the behavior of "dplyr" datsets in R. In my view the printing method of any data structure should not print more then fits on the screen. It tries to optimize the column with by finding out the terminal width... Maybe an additional protocol "pmos" (print-on-screen), could be envisioned which should be implemented and trying to avoid to print larger then screen. |
This is a followup to this conversation in the Numerical Clojure group.
I've been playing around with OCaml lately, using matrices from the Owl numerical library. Owl matrices automatically display themselves at the repl in a form that I find very convenient. (It's not perfect, but the flaws are insignificant. See examples below.)
I've also been struck by the fact that neither of implementations of sets in the two main OCaml standard libraries (Batteries and Core.Std) displays the contents of a set at the repl. Unlike Clojure sets, in OCaml you have to explicitly extract a set's elements in the form of a list in order to see them. (I submitted an issue about this for Batteries, so maybe it will change in the future.)
Both of these experiences have brought home to me how valuable it is to be able to easily see the contents of data structures when you're experimenting in a repl. I've come to feel that the fact that the contents of most Clojure data structures are automatically displayed in readable formats is something that makes a significant contribution to the value of the repl.
So if core.matrix automatically displayed matrices of all implementations in the same (or similar) convenient form(s) at the repl, this would provide a real benefit. At present, some matrix implementations display matrices in an inconvenient form (see Google group discussion), and some implementations, such as aljabr, don't display matrices' contents at all.
Explicitly using
pm
to display matrix contents is a workaround, but it's not a full solution. It's a glitch in the exploratory process at a repl. core.matrix matrices should be like other Clojure data structures in this respect. (Well, maybe not precisely. Clojure data structures normally dump their entire contents to the terminal. I don't think that that should be the default for large matrices. See Owl example below.)OCaml Owl example ("#" is the prompt):
The text was updated successfully, but these errors were encountered: