Skip to content

Rakudo should ship with a usable REPL that can be easily extended by user code #453

Open
@ab5tract

Description

@ab5tract

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:

  • backspaces
  • left/right cursor movement
  • up/down for scrolling through previous incantations

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 core

Shipping Terminal::LineEditor in core begs the question of why we don't just provide the functionalities provided by it's dependencies in core:

  • Why don't we provide a way to switch on the terminal's raw mode, so that for example getc(:raw) would work? (This is provided by Terminal::MakeRaw in 55 LoC)
  • Why don't we provide the ability for all Raku programs to easily interpret user input from terminal emulators that support ANSI sequences (eg, more or less all of them)? (Terminal::ANSIParser, ~300 LoC)
  • To round out these offerings (and the dependencies required to ship 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 with Terminal::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 in rakudo/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 of NativeCall and requires more effort to bring into NQP where it would need to live in order to provide any benefit to getc.

Metadata

Metadata

Assignees

No one assigned

    Labels

    languageChanges to the Raku Programming Language

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions