This and other RFCs are available on the web at
  http://dev.perl.org/rfc/

=head1 TITLE

Perl should support an interactive mode.

=head1 VERSION

  Maintainer: Ariel Scolnicov <[EMAIL PROTECTED]>
  Date: 31 Aug 2000
  Last Modified: 3 Sep 2000
  Mailing List: [EMAIL PROTECTED]
  Version: 2
  Number:  184
  Status: Developing

=head1 ABSTRACT

Perl5 does not have an interactive mode.  The debugger is fine for
testing a single line, but it is inadequate for running a set of
commands interactively.  The Perl6 parser (and possibly the language)
should contain hooks to allow full interactive environments to be
written. 

=head1 DESCRIPTION

Perl does not have an interactive mode.  It has C<perl -de 42>, but
that is not the same.  An interactive mode is useful not only for a
debugger, but also for exploring the capabilities of a module, or even
for performing simple "one-off" programming tasks.

The most serious obstacle to easy interaction is the difficulty in
typing multiple line commands to a Perl debugger (see below).
However, the Perl debugger also limits this use in other ways, notably
by evaluating each line in a separate C<eval>.  This too has
unfortunate consequences.

Languages which include better interactive capabilities than Perl's
include Python and zsh.

=head2 Example

Observe an interaction with another language whose name begins with a
`P': 

    Python 1.5.1 (#1, Jul 28 1998, 22:02:27)  [GCC 2.7.2.3] on sunos5
    Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
    >>> def fact(x):
    ...   if x <= 1:
    ...     return 1
    ...   else:
    ...     return x*fact(x-1)
    ... 
    >>> fact(10)
    3628800
    >>> ^D

Note in particular the definition of C<fact>, which spans multiple
lines. 

With Perl5, it doesn't work:

    <bioserv 108 [13:31] ~ >perl -de 42

    Loading DB routines from perl5db.pl version 1.0402
    Emacs support available.

    Enter h or `h h' for help.

    main::(-e:1):   42
    DB<1> sub fact {
    Missing right bracket at (eval 5) line 4, at end of line
    syntax error at (eval 5) line 4, at EOF

[ oops... must fit it all on one line ]

    < shift; if ($x < 2) { return 1 } else { return $x*fact($x-1) } 

    Missing right bracket at (eval 12) line 4, at end of line
    syntax error at (eval 12) line 4, at EOF

[ can't see the beginning of the line I'm editing, and forgot a close
brace; might as well forget about any indentation to help remind me ]

    <if ($x < 2) { return 1 } else { return $x*fact($x-1) } }

[ Finally!  But I can't even see what I typed! ]

    DB<4> print fact(10)
    3628800

Michael Maraist and Tom Christiansen point out that the debugger
allows explicit marking of continuation lines by backslashes:

    <selena 150 [14:37] ~ >perl -de 42

    Loading DB routines from perl5db.pl version 1.0402
    Emacs support available.

    Enter h or `h h' for help.

    main::(-e:1):   42
    DB<1> sub fact {             \
    cont:   my $x = shift;       \
    cont:   if ($x < 2) {        \
    cont:     return 1           \
    cont:   } else {             \
    cont:     return $x*fact($x-1) \
    cont:   }                    \
    cont: }

    DB<2> x fact 10
    0  3628800

This is inconvenient.  Syntax in an interactive mode should mirror
normal Perl syntax as far as possible; C<perldoc perldebug> goes so
far as to say

             Note that this business of escaping a newline is
             specific to interactive commands typed into the
             debugger.


=head2 Separate eval()s

C<my> and C<local> variables don't work in the debugger as one would
expect; their scope does not propagate between lines:

    <bioserv 112 [14:08] ~ >perl -de 42

    Loading DB routines from perl5db.pl version 1.0402
    Emacs support available.

    Enter h or `h h' for help.

    main::(-e:1):   42
    DB<1> $x = 17

    DB<2> my $x=5 

    DB<3> x $x
    0  17

The ability to be able to create variables is essential for serious
interactive use of Perl.

What causes all this is that the debugger evaluates every line in a
separate C<eval>; this is not what is desired in an interactive
environment.

This is another limitation on using the debugger for interactive work.
For another example, it is impossible to change packages persistently:

    DB<3> package foo

    DB<4> $x = 2

    DB<5> x $foo::x
    0  undef
    DB<6> x $x
    0  2
    DB<7> x $main::x
    0  2



=head2 Possible uses

=over 4

=item *

The Perl debugger (and other Perl debuggers)

=item *

Interaction environments (e.g. C<perldl>)

=item * 

"Super" calculators

=item *

Perl shell


=back

=head1 IMPLEMENTATION

This would require considerable assistance from the parser, I think.
At the very least, it should be possible to feed Perl multi-line input
from the terminal.  Perl should read whole lines, and respond I<only>
when it has parsed a complete statement at the end of a line or when
it has read enough to identify a syntax error.

There are proposals to allow programmatic access to the Perl parser.
Such access might allow "interactive Perl" (C<iPerl>?) to be written
in Perl.

User input will need to be interpreted in a "continuously interrupted"
context of the Perl interpreter.  Use of C<eval> is insufficient, as
the second example show.  Being able to create, run and interrogate a
secondary Perl interpreter (from within Perl) could help.

As much as possible of these interaction environments should be
outside of the core, preferably written in Perl.

=head1 REFERENCES

perldebug 

zsh manuals (especially zshzle)

zsh itself for examples of how multi-line editing can make sense (things
worth stealing)

bash also lets you type multi-line commands, but flattens them for editing.

psh (Perl SHell) allows you to type multi-line perl statements, if you
make sure to have an unbalanced syntax element.  (It also does a lot
more, most of which is not relevant to this RFC).
http://sourceforge.net/projects/psh/

python1.5 For a useful interactive mode.  http://www.python.org/.  See also
chapter 2 of the tutorial
(http://www.python.org/doc/current/tut/node4.html) which discusses
this interactive mode.

Reply via email to