-
Notifications
You must be signed in to change notification settings - Fork 16
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
Rakudo should ship with a usable REPL that can be easily extended by user code #453
Comments
It would also be nice if the |
I fully agree. Providing users a robust and generally good REPL by default is a must.
I'd be interested to understand the scope of a REPL and how far an extensible REPL can go. Is this mostly open ended? (I.e. we can't tell which interesting functionalities people come up with.) Architecture wise, which hooks does a REPL need to provide to enable the extensibility we dream of? A somehow related question. Assuming I'd want to implement a REPL mostly in userspace, which hooks does the core need to provide so I don't hit a wall in such an effort?
This sucks. But I'm still undecided on what the best remedy is.
Yes, having a package manager available by default is an absolute must. Giving some perspective: All the binaries provided on rakudo.org have a zef (on all the platforms). By extension, all releases installed via So all in all, I'd say we're not that bad on this front.
<backstory> Given the installation times are acceptable, what's the disadvantages of having a smallish and manageably sized dependency tree? Also I'd like to differentiate two approaches:
I believe we need to be very conservative with introducing modules into the core. The maintenance burden is very high, because introducing a breaking change is as hard as it can possibly get. On the other hand, bundling a module with our packages is really unproblematic. Other versions of the bundled module can be installed without issue. If we make clear that our packages are effectively a bundle, then there is no need to be backward compatible at all.
This does indeed sound like a good candidate to have in core. There is a "but" though. I know little about the Linux terminal API. But from what I understand making a terminal "raw" is actually a process of changing about 5-10 individual and independent config options in the terminal config. I guess there are more than 100 different config options. Windows provides fewer options, but making a terminal "raw" is still some mixture of multiple options. We definitely don't want to provide the ability in core to change each of those. But is a single binary "raw" switch really all that we need? Is that set of options really the optimal set to define "raw"? Do we want to have a somehow finer grained control?
I agree, that a "raw" getc is a thing that should work by default. But in general I feel we shouldn't be afraid of the ecosystem. Is it really that bad that a module developer that builds a terminal app needs to depend on a single (currently still imaginary)
I believe this might be a bit of a difficult metric. Up until recently, things have been rather quiet in the Raku terminal space. So that factors in to the low churn in these modules. Also the API surface of these modules is pretty large. If I was tasked to bring these modules into a shape that I feel comfortable to keep stable for the next 10 years or so, I'd probably lock myself into a room for three months and still have a very bad gut feeling afterwards. |
My favorite way forward would look as follows:
As a separate concern, I think it makes sense to think about which REPL specific extension hooks we want to provide in the core. Which hooks do we need to allow a full fledged REPL with all the bells and whistles and full integration into the language (e.g. the |
The Problem
When spinning up
raku
for the first time, users are presented with a list of modules they should install in order to have such niceties as:Note that there are no instrucitons for how to install these modules. No link to a package manager, let alone a package manager being provided.
This might not bother others but I find it to be deeply un-user-friendly and more than a little embarrassing for a language that bills itself as -- and generally lives up to -- "batteries included".
Beyond that pain point, by punting the responsibilities of parsing user input to userspace we also lose the ability to provide meaningful hooks into the REPL experience itself.
And it goes deeper still: Even our
getc
implementation requires a third-party module to be able to read a character of user input without an enter key being pressed.Poterntial Remediations
Ship releases with
zef
This would at least allow users to swiftly install one of the recommended options.
Pros
IMO this is long overdue. It likely deserves its own problem-solving ticket if it doesn't already have one.
Also, we apparently already do this for Windows. Aligning what we ship across platforms makes a lot of sense to me.
Cons
Doesn't do anything to address REPL extensibility /
getc
.Ship releases with
Terminal::LineEditor
Pros
Terminal::LineEditor
is a very comprehensive line editor that is implemented almost entirely in Raku.It supports significantly more than what I would consider the table stakes required for a usable REPL (my essentials are: backspaces, left/right cursor movement, and up/down with session history).
Cons
No direct cons except that poor
getc
is still incapable of collecting raw input.Oh, and the fact that there are four dependencies for this module. More on that next.
Provide all the necessary pieces that are required to write
Terminal::LineEditor
in coreShipping
Terminal::LineEditor
in core begs the question of why we don't just provide the functionalities provided by it's dependencies in core:getc(:raw)
would work? (This is provided byTerminal::MakeRaw
in 55 LoC)Terminal::ANSIParser
, ~300 LoC)Terminal::LineEditor
anyway), why would we not offer a mechanism for modeling terminal capabilities, objects of which are constructed with the lowest common denominator and which could be used to standardize the handling of user expectations with Raku programs in their favorite terminal emulator (Terminal::Capabilities
, ~50 LoC)The only thing missing from a REPL usability standpoint is
Terminal::ANSI
(380 LoC, though some would be omitted because of overlap withTerminal::ANSIParser
). This provides all the ANSI-standard pieces related to text output.Pros
getc
can finally do a thing that users likely assume it is/should be capable of.Every terminal-specific Raku program can benefit. All libraries related to terminal interaction can drop up to 5 dependencies.
Terminal::LineEditor
can live inrakudo/lib
.We can design a basic, functional REPL around which many layers of interaction can be added *without requiring any third party libraries at all.
Cons
The main objection I have heard is related to maintanability. I'd like to note that the update frequencies of each module I have mentioned is very low, meaning that there seems to have been very few causes to modify any of these modules over a matter of years (
Terminal::MakeRaw
is working on Windows support, but it is unique here in that it is the only one that relies on native libraries.)Terminal::MakeRaw
is easy to implement because ofNativeCall
and requires more effort to bring into NQP where it would need to live in order to provide any benefit togetc
.The text was updated successfully, but these errors were encountered: