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

Consider displaying proto-repl with atom-ink #22

Closed
jefffriesen opened this Issue Jan 10, 2016 · 22 comments

Comments

Projects
None yet
4 participants
@jefffriesen

jefffriesen commented Jan 10, 2016

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 added a commit that referenced this issue Jan 15, 2016

@jasongilman

This comment has been minimized.

Show comment
Hide comment
@jasongilman

jasongilman Jan 16, 2016

Owner

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:

  • Need to pretty print results to display there. Or show non pretty printed results but when the tree is expanded show the pretty printed results.
  • Integrate Ivy for display documentation, lists of functions in a namespace
  • Take advantage of the Ivy's ability to show things loading
Owner

jasongilman commented Jan 16, 2016

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:

  • Need to pretty print results to display there. Or show non pretty printed results but when the tree is expanded show the pretty printed results.
  • Integrate Ivy for display documentation, lists of functions in a namespace
  • Take advantage of the Ivy's ability to show things loading
@jefffriesen

This comment has been minimized.

Show comment
Hide comment
@jefffriesen

jefffriesen Jan 17, 2016

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.

jefffriesen commented Jan 17, 2016

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

This comment has been minimized.

Show comment
Hide comment
@jasongilman

jasongilman Jan 25, 2016

Owner

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

Owner

jasongilman commented Jan 25, 2016

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

This comment has been minimized.

Show comment
Hide comment
@jasongilman
Owner

jasongilman commented Jan 25, 2016

proto_repl_autoload_tweet

@jefffriesen

This comment has been minimized.

Show comment
Hide comment
@jefffriesen

jefffriesen Jan 25, 2016

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 Jan 25, 2016

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

This comment has been minimized.

Show comment
Hide comment

jasongilman added a commit that referenced this issue Jan 30, 2016

@jasongilman

This comment has been minimized.

Show comment
Hide comment
@jasongilman

jasongilman Feb 2, 2016

Owner

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.

Owner

jasongilman commented Feb 2, 2016

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

This comment has been minimized.

Show comment
Hide comment
@jefffriesen

jefffriesen Feb 2, 2016

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

jefffriesen commented Feb 2, 2016

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

@saulshanabrook

This comment has been minimized.

Show comment
Hide comment
@saulshanabrook

saulshanabrook Feb 3, 2016

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

saulshanabrook commented Feb 3, 2016

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

This comment has been minimized.

Show comment
Hide comment
@jasongilman

jasongilman Feb 3, 2016

Owner

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.

Owner

jasongilman commented Feb 3, 2016

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

This comment has been minimized.

Show comment
Hide comment
@jasongilman

jasongilman Feb 3, 2016

Owner

I had a few ideas:

  • When pretty printing a data structure for inline display convert it into a hierarchical tree so that each level can be expanded or collapsed. This would make exploring a large data structure easier.
  • Allow saving values inside an algorithm. Display the values inline next to where they were captured. I saw a tweet from Michal Srb on twitter showing Golem doing this. Here's a labeled screen cap showing Golem:

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.

Owner

jasongilman commented Feb 3, 2016

I had a few ideas:

  • When pretty printing a data structure for inline display convert it into a hierarchical tree so that each level can be expanded or collapsed. This would make exploring a large data structure easier.
  • Allow saving values inside an algorithm. Display the values inline next to where they were captured. I saw a tweet from Michal Srb on twitter showing Golem doing this. Here's a labeled screen cap showing Golem:

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

This comment has been minimized.

Show comment
Hide comment
@jefffriesen

jefffriesen Feb 4, 2016

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.

jefffriesen commented Feb 4, 2016

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

This comment has been minimized.

Show comment
Hide comment
@jasongilman

jasongilman Feb 4, 2016

Owner

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

  • The ability to save those values and recall them to use for manual testing in the REPL.
  • Showing values saved over time. (Atom ink inline display)
  • Visualizing values over time.

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.

Owner

jasongilman commented Feb 4, 2016

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

  • The ability to save those values and recall them to use for manual testing in the REPL.
  • Showing values saved over time. (Atom ink inline display)
  • Visualizing values over time.

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

This comment has been minimized.

Show comment
Hide comment
@jasongilman

jasongilman Feb 6, 2016

Owner

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

inline_results

Owner

jasongilman commented Feb 6, 2016

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

This comment has been minimized.

Show comment
Hide comment
@jefffriesen

jefffriesen Feb 8, 2016

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?

jefffriesen commented Feb 8, 2016

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

This comment has been minimized.

Show comment
Hide comment
@jasongilman

jasongilman Feb 12, 2016

Owner

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.

Owner

jasongilman commented Feb 12, 2016

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

This comment has been minimized.

Show comment
Hide comment
@jasongilman

jasongilman Feb 16, 2016

Owner

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.

Owner

jasongilman commented Feb 16, 2016

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

This comment has been minimized.

Show comment
Hide comment
@jefffriesen

jefffriesen Feb 16, 2016

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.

jefffriesen commented Feb 16, 2016

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

This comment has been minimized.

Show comment
Hide comment
@mikeball

mikeball Feb 21, 2016

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
atom/atom#9930

mikeball commented Feb 21, 2016

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
atom/atom#9930

@jasongilman

This comment has been minimized.

Show comment
Hide comment
@jasongilman

jasongilman Feb 23, 2016

Owner

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.

Owner

jasongilman commented Feb 23, 2016

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

This comment has been minimized.

Show comment
Hide comment
@mikeball

mikeball Feb 23, 2016

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

mikeball commented Feb 23, 2016

@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

This comment has been minimized.

Show comment
Hide comment
@jasongilman

jasongilman Mar 15, 2016

Owner

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

Owner

jasongilman commented Mar 15, 2016

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment