jasongilman / proto-repl

A Clojure Development Environment package for the Atom editor
https://atom.io/packages/proto-repl
MIT License
562 stars 50 forks source link

Consider displaying proto-repl with atom-ink #22

Closed jefffriesen closed 8 years ago

jefffriesen commented 8 years ago

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.

jasongilman commented 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:

  1. Upgrade to the latest Proto REPL
  2. Install Atom Ink
  3. Reload atom (Restart it or go to View -> Reload)
  4. Click "Show Inline Results" in the Proto REPL settings.

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:

jefffriesen commented 8 years ago

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.

jasongilman commented 8 years ago

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".

jasongilman commented 8 years ago

proto_repl_autoload_tweet

jefffriesen commented 8 years ago

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.

jefffriesen commented 8 years ago

For inspiration: https://www.youtube.com/watch?v=HnZipJOan54&feature=youtu.be

jasongilman commented 8 years ago

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.

jefffriesen commented 8 years ago

Agreed. It seems like you are building a good foundation on top of Atom for exploring those ideas.

saulshanabrook commented 8 years ago

This is really exciting! I already find it easier to use than light table, in terms of starting a repl and getting evaluation going.

jasongilman commented 8 years ago

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.

jasongilman commented 8 years ago

I had a few ideas:

https___pbs_twimg_com_tweet_video_cgwbu8rwgaa6zhd_mp4

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.

jefffriesen commented 8 years ago

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:

  1. keyword search in a string with manual logic: does it contain java.lang.NullPointerException? * Does it contain NO_SOURCE_FILE: do [a] * Does it contain xyz: do [b]
  2. Natural language processing + bayesian classification: I've used this library with success: https://github.com/NaturalNode/natural#classifiers

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.

jasongilman commented 8 years ago

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.

bret_victor_-_inventing_on_principle_on_vimeo

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.

jasongilman commented 8 years ago

I implemented the inline display as an explorable tree. That's released with a bunch of other fixes in 0.14.0

inline_results

jefffriesen commented 8 years ago

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?

jasongilman commented 8 years ago

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.

jasongilman commented 8 years ago

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.

jefffriesen commented 8 years ago

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.

mikeball commented 8 years ago

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

jasongilman commented 8 years ago

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.

mikeball commented 8 years ago

@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.

jasongilman commented 8 years ago

Closing this issue now that Proto REPL has been using Atom ink for a while. Improvement ideas can be filed as new issues.