Closed jefffriesen closed 8 years ago
I added some very basic support for this in the latest released version. This is my attempt to try it out first to get an idea of how integration might work.
You can try it by doing the following:
Now when you execute a block or selection the result will be displayed using Atom Ink as well as in the REPL. This is definitely not the final way this would be implemented. Some initial thoughts:
This is awesome. Those changes you mention above sound great.
Is it crazy to build it so that it automatically evaluates expressions? Now that you have the value positioned next to the functions, they could update as you update code, similar to how Light Table has watch expressions.
You could use a key binding to set a block as a watched expression. But I think it would be a cool experiment to just do it for all expression, even the one you are currently typing. It probably should have a delay, similar to how linting in JS constantly evaluates your syntax as you type. After using JS linting, I can't work without it. I could imagine this could be similar.
Then the repl is used for testing ideas out, but not the main receiver of values. If all functions are watched and evaluated as you type, you may eventually not even use the repl, because you could just test out code inline as you type.
Just an idea. Great work with what you've done - I love it.
Continuing in the saga of improving inline results I've added the ability to autoload the current file whenever there's a change. Results will display inline next to the expressions. You can even combine it with proto-repl-charts so a graph is displayed on every modification. To enable it for the current text editor bring up the command palette and select "Proto Repl: Autoload File". It can be turned off on a file with "Proto Repl: Stop Autoload File".
Jason, This is really great. Your repl plus parinfer just made Atom a serious Clojure/Clojurescript editor.
Are you still planning on adding inline docs, pretty print and loading indicator (mentioned in your comment above)? Once you're good with this you should consider reaching out to some clojure folks to get their take on it. Maybe Hacker News as well.
For inspiration: https://www.youtube.com/watch?v=HnZipJOan54&feature=youtu.be
Thanks for the video. Shem and golem are very interesting. I like the way that golem shows bits of code next to the result where the code is editable and immediately re-evaluated. By splitting up the "REPL" into floating display areas you can mix visualizations and code with results. Mixing visualizations and code in the same display area is one of the next challenges for Proto REPL.
Agreed. It seems like you are building a good foundation on top of Atom for exploring those ideas.
This is really exciting! I already find it easier to use than light table, in terms of starting a repl and getting evaluation going.
Thanks, I'm really glad to hear it's working for you. If you (or anyone else) has ideas on improvements for the Atom Ink integration this thread is a good place to capture them and discuss. I can open new issues for specific improvements.
I had a few ideas:
The way it would be displayed in Proto REPL would likely be different since it doesn't have the same display capabilities as Golem. But it could be displayed next to the specific log
call where the values where saved. There should be a way to recall a specific saved value so that it could be used in further testing.
I can see a big benefit of displaying large datasets as hierarchical trees. I use that all of the time in the Chrome inspector when doing JS. I console.log or console.table out data structures or print them out at a debug point.
As for saving values inside an algorithm - it's interesting but at the moment it may be too far outside of my workflow to really understand it. I need to watch that video again and think about it.
This may be way outside the scope of proto-repl, but I keep thinking about error messages. From my experience, they are pretty obtuse. It doesn't sound like I'm alone: http://blog.cognitect.com/blog/2016/1/28/state-of-clojure-2015-survey-results
To this question:
What has been most frustrating or has prevented you from using Clojure more than you do now?
The number 1 response was error messages.
It's also an issue closely associated with beginner and intermediate Clojure developers. Experienced developers have already created a mental map and decision tree to understand and track down those errors. Experienced developers aren't likely on Atom and proto-repl either (they are typically on Emacs, with some converts over to Cursive). The perfect audience for Atom/proto-repl are people new to the language who don't want to learn Emacs on top of Clojure (And there are a lot of them, based on the survey). So it seems like if error messaging can be improved with proto-repl, that would be a huge draw.
For improved error messaging, it could give the original message along with hints as to what it could be:
#<CompilerException java.lang.NullPointerException (NO_SOURCE_FILE:0)>
Typically this is due to [something]. Try [suggestion]
Again, understandable if it's outside the scope of a repl. But maybe not. Language-level improvements in error messaging eventually needs to be done, but that is a very slow, precise process. A 3rd-party repl can be a lot quicker to implement and update the messages. It can also be given more leniency when incorrect, which is helpful for moving quick. I watched Colin Fleming give this talk in November: https://www.youtube.com/watch?v=kt4haSH2xcs. Clearly having access to the AST seems ideal in terms of what context is available for interpreting and tracking down errors. That is one approach, but there are tradeoffs on speed of development and platform requirements. It reminds me of how early on Coffeescript made popular a lot of language constructs that gave the TC39 working group momentum and confidence to get language additions added to JS. Now we have Babel doing a similar thing and from what I've heard the working group appreciates and needs that kind of real-world usage.
You can still get a lot of information from the error message string and function the error threw in. I'm definitely not an expert at this. But I would explore two paths for this:
java.lang.NullPointerException
?
* Does it contain NO_SOURCE_FILE
: do [a]
* Does it contain xyz
: do [b]Whatever approach to classification you use, it may make sense to make it a separate repo from proto-repl. Then other people could contribute and use it in other projects. As another project I could see it really helpful as a website where people can paste error messages in and get suggestions. Maybe it's written in CLJS (if using something like NaturalNode) or CLJC. Just an idea. I love this project. Thanks.
That's a really good idea. I'm going to put some thought into that and start keeping track of typical Clojure errors I encounter. There may be reasonable error messages that can be displayed for many of them.
RE: Saving values in an algorithm, view results, and recall:
Inside of a function you might have a few different things going on. The function takes input and output and returns a value but you can't see inside it to know what's happening. That's why people typically reach for println
and log
statements. I want to improve on that approach with things like
Golem was attempting to do what Bret Victor showed way back in his Inventing on Principle video. The relevant section starts at 17:30. Here's a screenshot from that video showing a very similar thing. It's showing the values captured during execution of his binary search function.
I want the same thing in Proto REPL. I want to show the values as they change within the code itself. Mr. Victor shows all of the values as soon as they are set. That's a bit harder to accomplish. An easier approach would be to trigger the save with a call to some kind of log function like in Golem. Saved values would automatically be displayed inline as soon as they were captured.
I implemented the inline display as an explorable tree. That's released with a bunch of other fixes in 0.14.0
This is really nice. Unfortunately I can only pull changes and play around right now because heads down in a non-Clojure project. In a couple weeks I'll be starting on a decent size CLJS project where I can really take advantage of this. I'll also keep track of errors that come up and their solutions. I am still thinking through the values saved during execution idea as well.
What's next for this project?
I'm working on the feature I described above to save local bindings and view them. I think I'll have a beta version of it available pretty soon. It's currently being developed in the save_and_recall branch.
I just released the save and view local bindings feature in 0.15.0. https://github.com/jasongilman/proto-repl#saving-and-viewing-local-binding-values It also improves the display of values from Atom Ink by changing to a mono-space font and increase the size of the inline display area.
So sweet. I totally get the saving and viewing local bindings now. It's kind of like the reductions
function in Clojure (https://clojuredocs.org/clojure.core/reductions) but applied to any internal function.
Small typo:
They're not meant to be used in local development only.
You probably mean it's only meant to be used in local development.
As a side note, I talked with Julio Barros who is doing an online Clojure course and suggested he include Atom/proto-repl in his page of resources: http://e-string.com/clojure-resources/. It would be fun to get a bunch of people hammering on this.
Not directly related to atom-ink, but you might also look at using block decorations for larger results, and perhaps inline doc strings.
http://blog.atom.io/2016/02/03/introducing-block-decorations.html https://github.com/atom/atom/pull/9930
I really like the idea of using block decorations. I don't have a great idea of what to put there yet. I like the idea of putting larger results there instead of inline on the right where there's not as much room. I've also thought of using them as a target for visualizations like those provided in proto repl charts instead of putting those in a new tab.
@jasongilman So, I've been using LightTable for some time and have come to really love the inline results, which is why I was watching the block decorations closely, and like what your'e doing with proto-repl.
One area that I think could be improved on for inline results is when you have a larger result than can be displayed on the same line to the right of the end of the expression. With larger expressions they often run off the visible screen to the right. Formatting of the inline results would also be cool.
For instance a function that's being called and returns a number say 101 should just display on the same line. For a defn which returns a var name, perhaps that can be recognized as such and add a green checkmark on the same line to indicate it's been evaluated, and remove it on edit. For a function that's returning a large map, that should break to the next line. Taking it a bit further, format the result based on it's type, so if it's a map, rather than printing out just a raw string, actually format it and also allow it to be copy/pasted. If there's an exception, clean up the raw stack trace and display that inline as well.
Thanks for all your work on proto-repl, I believe having a good repl experience in Atom will really help clojure adoption.
Closing this issue now that Proto REPL has been using Atom ink for a while. Improvement ideas can be filed as new issues.
Having inline, Light Table evaluation and watches is really nice. Here's an Atom project that could allow you to do that: https://github.com/JunoLab/atom-ink
I think it would be cool to have the ability to toggle on and off these inline evaluations, along with a full-blown repl like you already have.