dart-lang / sdk

The Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.
https://dart.dev
BSD 3-Clause "New" or "Revised" License
10.28k stars 1.59k forks source link

Dart need a dart REPL now #39965

Open He-Pin opened 4 years ago

He-Pin commented 4 years ago

I think Dart needs a REPL to be more productive and accessible. This is the Scala REPL: image image

and Dart currently lack it. image

Update: Scala may moving to scala-cli.virtuslab.org, and there is a sip too: https://contributors.scala-lang.org/t/pre-sip-scala-cli-as-new-scala-command/5628/8

kennethnym commented 4 years ago

What about dartpad.dartlang.org?

He-Pin commented 4 years ago

I mean a REPL running on my local computer, out of box.

mkustermann commented 4 years ago

/cc @mit-mit

mit-mit commented 4 years ago

Thanks for the suggestion @hepin1989, this is something we've discussed a few times, but don't have a concrete timeline for.

He-Pin commented 4 years ago

@mit-mit Thanks for your update; REPL is really handy for offline learning, practicing, looking forward to that.

micimize commented 4 years ago

And here we are, 35,556 issues after #4409

willhaslett commented 4 years ago

Often you want/need to try things out locally, right away, that require the environment that you load in Pubspec. Communicating with vaguely documented APIs is a typical example. This absence is a real productivity weakness for the language.

davelnewton commented 4 years ago

The lack of a REPL is indeed a pain point.

I will say that just running local code in VS Code (which respects pubspecs) isn't terrible, but it lacks the immediacy of Lisp/JS/etc.

willhaslett commented 4 years ago

Well-put. Having the environment at your fingertips isn't the unique thing with the REPL, it's being able to execute one-liners and set up class instances that you want to play with in a flash, with state that isn't polluted by what's going on in the app itself.

He-Pin commented 4 years ago

And here we are, 35,556 issues after #4409 How I got on board of Scala 、Clojure and Elixir is they all have a REPL...

pinyin commented 4 years ago

+1. A Local REPL is essential when playing around with unfamiliar libraries.

thebalaa commented 4 years ago

How can DART claim to be a modern alternative to JS if it doesn't have a REPL?!?! :)

Found this: https://iiro.dev/2019/08/15/how-to-eval-in-dart/

jiridanek commented 4 years ago

Nobody yet mentioned unittests as a workaroud, so let me do that now. Instead of experimenting with a REPL, it is quite doable to write unittests either in a separate experimental project, or in the current project itself. IDEs provide a way to quickly run only a selected unittest, which approximates sending a line of code into REPL by pressing the Enter key. Unittests also scale better to programs that have 5 or more lines of code and can be checked into source control for sharing or reuse.

I'd love to reduce my dependency on Python!

Why? Python is a good calculator :D

davelnewton commented 4 years ago

You don’t need to write a unit test to experiment with code, you can just write code. The whole point of a REPL is to have an immediate experience; there’s no difference between writing regular code or a unit test other than a unit test has more boilerplate than just writing code.

jiridanek commented 4 years ago

Sure, that's why I call my approach a workaround. The whole point of unittesting is to have immediate feedback, and IDEs tend to have decent support for e.g. shortcuts to run test under cursor and so on; that's why it can be used as a poor person's substitute when a REPL is not available.

fzyzcjy commented 3 years ago

In addition, it would be even better to have something like IPython and Jupyter notebook, especially when we need to do some exploration with data, etc.

venkatd commented 3 years ago

As far as implementation, maybe some inspiration can be taken from how Flutter works with hot reload? With Flutter we are already able to add functions, execute them at runtime, access existing state, and so on.

When I develop in JS and Elixir, my productivity is much higher because I can quickly try things out.

willhaslett commented 3 years ago

@mit-mit , I can't imagine what it has been like to implement sound null-safety, and bring the whole ecosystem along for the ride.

Maybe that effort is sunsetting? If so, please do consider the REPL again. It's hard to overstate how much time a REPL saves. If this is an unreasonable lift for Dart, out of curiosity, could you describe the challenges? Not knowing any better, it seems that JIT compilation would make this doable.

fzyzcjy commented 3 years ago

@willhaslett @mit-mit Completely agree. In my naive thought, the REPL for a JIT language is not very difficult, e.g.

willhaslett commented 3 years ago

@fzyzcjy, while I agree with the spirit of your comment, those languages are all interpreted languages. Just-in-time compilation is something quite different. This user-level thread asks the question "why not?", and a language designer might help us understand, in general terms, what's involved.

fzyzcjy commented 3 years ago

@willhaslett Aha good point. Python, JS, and Matlab are interpreted actually.

Julia is JIT compiled, though https://agilescientific.com/blog/2014/9/4/julia-in-a-nutshell.html.

P.S. Julia says it is very fast and very easy to use. I think dart is similar ;)

Silentdoer commented 3 years ago

please support repl..

jiridanek commented 3 years ago

@willhaslett Aha good point. Python, JS, and Matlab are interpreted actually.

Strictly speaking, compiled/Interpretted/JITted is a property of language implementation, not of the language itself. So in case of Python e.g. CPython is interpreted, whereas PyPy has a JIT.

russeg commented 3 years ago

dartpad was suggested, however it does not have light mode. fyi, dark mode is awful for people with astigmatism.

elektronik2k5 commented 3 years ago

dartpad works only in a browser. I want an installable, offline, CLI solution. dartpad is an excuse. However, dartpad is proof that a REPL is possible and in fact already implemented. Why not refactor the core of dartpad into a package which would be the basis of dartpad and a CLI REPL?

willhaslett commented 3 years ago

Strictly speaking, compiled/Interpretted/JITted is a property of language implementation, not of the language itself. So in case of Python e.g. CPython is interpreted, whereas PyPy has a JIT.

@jiridanek, yes, that such-and-such language being compiled or interpreted is a property of its implementation, not the language, goes without saying.

I think that this discussion might be wandering off-topic. The key is to be able to launch a console with an environment/state. Ruby's Pry is a good example. Once you've seen the benefits of "stop here and give me a console with all of the current state", you want it everywhere. I don't know whether or not Dart's JIT compilation mode makes this possible or not. My knowledge doesn't run nearly that deep. But in any event, Dartpad is not a REPL. It's just an online environment where you can run a Dart program.

jiridanek commented 3 years ago

I think that this discussion might be wandering off-topic.

+1; I think this is because all has been said already. We know what we expect from a REPL, we want it, we want it now. Nothing substantive to add, really. Certainly not from us on the peanut gallery.

I don't know whether or not Dart's JIT compilation mode makes this possible or not.

There is a REPL even for C++ (https://root.cern/cling/); so it surely can be done. I think I already wrote somewhere that "compiled/Interpreted/JITted is a property of language implementation, not of the language itself."

Similarly, I feel a strong urge to say again that thoughtful use of unit-tests can recover for you some of the "stop the program and run repl at the current state" interactivity. It only confirms my feeling that all has been said already and now it's the time to implement it. Or close as won't fix. Or provide some kind of a guidance in the form "core project team won't work on this[1], if you want to write it yourself, we will gladly review and merge it in, though".

[1] objective justification should exist --- and preferably be publicly communicated --- in that case, e.g. "because 90% Dart developers come from Java and don't care about REPLs, and the rest is unlikely to seriously use Dart even if we added REPL. And we know this because we measured it reasonably well in a survey, so it is not just a gut feeling".

edit: forgot that Java has a REPL, nowadays; jshell

mraleph commented 3 years ago

There are no plans to provide REPL in foreseeable future. Core Dart team simply does not have resources for that. I encourage interested engineers to try and create REPL as a package. Dart platform exposes a lot of necessary features (eg hot reload, expression evaluation, etc)

annagrin commented 2 years ago

Related feature request (repl for expression evaluation in the debugger): https://github.com/dart-lang/webdev/issues/1480. It would require repl support in the incremental compiler.

maks commented 2 years ago

I just realised after being pinged on this by @annagrin and @elliette via dart-lang/webdev#1480 that its never been mentioned here that there is actually some prior art for this and that a while ago I did a small limited scope update to that concept for a project I was working on.

Its been on my todo list for a while to try to improve on the above to make a more general purpose package as suggested by @mraleph but from memory back then I ran into a lack of documentation around how to use hot-reload via the vmservice. @mraleph are you aware of any good docs or examples for using hot-reload programmatically short of reading src for Dart SDK testsuite or Flutter SDK srcs?

mraleph commented 2 years ago

@maks VM service protocol is documented here, also there is already a number of packages which implement hot reload through the protocol, e.g. https://pub.dev/packages/hotreloader - so you should be able to peak into the code there or just use it as is by creating a temporary file in a temporary directory to represent the REPL program and pointing hotreloader to that folder.

maks commented 2 years ago

Ok mvp version of the package published: https://pub.dev/packages/repl Please see the readme version on github for the list of features I'm working on in the immediate future.

Thanks to @mraleph for the neat idea of using a "scratch" dart file for input into an isolate and then using hotreload on it, I've got a basic version of that working on local branch and should be in the next release of the package.

And thanks to @BlackHC as I'm also incorporating some great ideas and code that he did in his original repl POC.

And of course any contributions most welcome!

maks commented 2 years ago

Just a quick update on progress with my package:

I have expression working fairly well using the vm service. Statements however are not working well.

Unfortunately while it sounded promising, using hot-reload with a "scratch" dart file seems to work inconsistently at best with correct correct code and is very fragile with any errors in the code breaking hot reload completely. BlackHC's previous work used nested library include's to try to get around some of the problems along with using separate Isolates, but for my goals this isn't going to be helpful as one of my key use cases is to access and manipulate a run Dart program (eg. Http server) from the repl, not just use the repl as a standalone sandbox.

I am now thinking that I will need to take the approach for handling statements that was used in this old repl implementation and use the Dart embedder C API, though likely via FFI (per @mraleph advice from another issue: https://github.com/dart-lang/sdk/issues/44083#issuecomment-722944631) though in 2022 and Dart 2.x this means I will need to do compiling Dart src to kernels vs the simpler API that existed in Dart 1.x days of just supplying a url, eg. instead of Dart_LoadLibrary(url, source) its now Dart_LoadLibraryFromKernel(const uint8_t* kernel_buffer, intptr_t kernel_buffer_size);

mit-mit commented 2 years ago

Hi @maks can you detail just how the hot-reload based approach breaks?

Have you considered checking if the code is free from analyzer errors prior to issuing the hot reload, and if that makes it less error prone?

maks commented 2 years ago

I've done some more work and testing on this and you were correct @mit-mit , all the failures that I've been able to replicate were due to (sometimes subtle) errors in the statements code I was adding and trying to hot-reload. Now that I'm using the analyzer to check input before hot-reload it seems to be working well, with bonus of having an error message from the analyzer to print for users, though it does add a bit of latency to the repl printing results or errors.

fzyzcjy commented 2 years ago

Hi, is there any updates for this feature? I am willing to contribute as well.

EDIT: Prototyping now.

fzyzcjy commented 2 years ago

Seems I made a full version. It supports:

Link: https://github.com/fzyzcjy/dart_interactive

Thanks @mraleph for pointing towards hot reload, @maks for making a prototype, and @BlackHC for another prototype!

maks commented 2 years ago

@fzyzcjy good stuff, great to see some one pickup the ball and keep running with this!

I should point out that @BlackHC did all the hard work with his POC, I just built my package initially just as an update of his to get it working with Dart 2.

I notice that you use runtime mirrors with kRuntimeSupportImport so I guess this won't be possible to use in Flutter and Dart Web or is that something you plan on replacing later on?

fzyzcjy commented 2 years ago

@maks Hi, thanks for the reply! Then I will move the order in "contributors" section.

I notice that you use runtime mirrors with kRuntimeSupportImport so I guess this won't be possible to use in Flutter and Dart Web or is that something you plan on replacing later on?

Good question, I should check whether it is removeable. https://github.com/fzyzcjy/dart_interactive/issues/40

fzyzcjy commented 2 years ago

@maks dart:mirror dependency removed :) (Currently a bit like a hack, but I guess in the scenarios the hack causes no harm, so will wait to see if someone sees problems)

BlackHC commented 2 years ago

Thanks that's really kind of you! I'm really amazed by all the progress on the repl! I'm mostly working with Python for ML these days, but it's great to see Dart doing so well

fzyzcjy commented 2 years ago

@BlackHC You are welcome!

Btw I have been working with Python (Jupyter) for years for deep learning, and will probably continue using it when doing PhD in the future (just like you ;) )

Thribs commented 2 months ago

I need this feature as well. Willing to contribute

Thribs commented 2 months ago

Seems I made a full version. It supports:

* expressions

* statements

* functions

* classes, redefine without losing state, extends/implements

* global variables, read write redefine

* import 3rd party dependencies

* downloading 3rd party dependencies

* ...etc

Link: https://github.com/fzyzcjy/dart_interactive

Thanks @mraleph for pointing towards hot reload, @maks for making a prototype, and @BlackHC for another prototype!

awesome. Can we have it out of the box when running dart?