Google
 
Webnews.only-4-geeks.com
Interesting places
news.only-4-geeks.com Forum Index » ProgrammingGoto page 1, 2  Next

Edit commands in Command Line Interpreters

 
Jump to:  
 
Richard Harter
PostPosted: Fri Aug 15, 2008 4:50 am    Post subject: Edit commands in Command Line Interpreters
       
In most programming languages source code is in a file or files.
The file(s) are either fed to a compiler or an interpreter; the
user does not alter the source code during execution.

In some languages, e.g., command line interpreters and shell
programs, the user can also enter code interactively. There are
some extra features that useful for interactive mode. Thus:

(a) It is useful to be able to silently enter blocks of code,
i.e., the interpreter does not execute the lines until an entire
block has been entered.

(b) It is useful to be able to edit code on the fly, i.e., edit
blocks of code as they are being entered.

(c) It is useful to be able to edit code that has already been
entered and executed.

One way to do this is to run the interpreter within an editor,
e.g., emacs. An alternative is to include editing commands
directly within the language. Does anyone have opinions about or
experience with the latter option?


Richard Harter, cri@tiac.net
LINK LINK
Save the Earth now!!
It's the only planet with chocolate.
 

 
Pascal J. Bourguignon
PostPosted: Fri Aug 15, 2008 9:02 am    Post subject: Re: Edit commands in Command Line Interpreters
       
cri@tiac.net (Richard Harter) writes:

Quote:
In most programming languages source code is in a file or files.
The file(s) are either fed to a compiler or an interpreter; the
user does not alter the source code during execution.

In some languages, e.g., command line interpreters and shell
programs, the user can also enter code interactively. There are
some extra features that useful for interactive mode. Thus:

(a) It is useful to be able to silently enter blocks of code,
i.e., the interpreter does not execute the lines until an entire
block has been entered.

(b) It is useful to be able to edit code on the fly, i.e., edit
blocks of code as they are being entered.

(c) It is useful to be able to edit code that has already been
entered and executed.

One way to do this is to run the interpreter within an editor,
e.g., emacs. An alternative is to include editing commands
directly within the language. Does anyone have opinions about or
experience with the latter option?

You have to see it in terms of virtual machine.

Virtual machines are implemented over virtual machines.

(Some virtual machines are implemented over silicium, but we
programmers don't get to see them usually: it's only Intel's engineers
who program the ix86 virtual machine in microcode over their silicium
who see it). Yes, the ix86 in current process is actually a virtual
machine, that gets compiled Just In Time by the processor.

Ok so you have this ix86 virtual machine, and over it is implemented
another virtual machine, the OS virtual machine. Let's say the unix
virtual machine to be concrete.

On this unix virtual machine, you have some other virtual machines,
like the emacs editor (which itself contains at least two virtual
machines: the lisp VM, and the editor itself). And of course, you
have virtual machines such as REPL environments.

A compiler is not really a virtual machine, it translates files
intended for one virtual machine to files intended for another virtual
machine. If you consider a compiler embedded in an IDE, you could say
that you have a C virtual machine (instead of a pure unix virtual
machine, characterized by the part of the underlying virtual machine
it exports and its syscalls).


What I call REPL environments, are those virtual machines that have a
Read-Eval-Print-Loop that allows you to modify very easily the program
loaded in the virtual machine. It can use either an interpreter or a
compiler (or both) to translate the text you type in into a program
executable by the virtual machine it implements.


Ok, so now the important question is where persistence occurs.

At the ix86 level, there is no persistance (there may be some
persistent PRAM, or you could consider the BIOS EEPROM as some
persistent storage, but it is not usually used as thus for user
programs).

Persistence is implemented at the OS level, by the use of persistente
storage memory such as hard disks, and the implementation of a file
system. Some OS implement persistence of user objects without a file
system (cf. EROS LINK).

Above a unix OS, all persistence is implemented using the unix file
system. Another important characteristic is that processes ARE NOT
persistent in unix. (They may be made persistent, and even migrable
(in clusters), but this is hard and rare). Because of the
characteristics of the unix virtual machine (basically the
characteristics you can see in a C virtual machine: no memory
protection from one block of memory to the other, etc), programs on
the unix virtual machine often have bugs and crash. Not having
persistent process is a "protection" unix OS offers against its own
defects. Your program crashes, the OS cleans up the process, and you
can restart. As long as the program bug didn't erase or modify
persistent data in the file system, you're OK. (And for the case of
persistent data damage, you can always get back to your backups, you
do have backups don't you).

Note another interesting characteristic of unix systems: when it runs
out of memory (both RAM and swap), it starts to kill innocent
processes 'at random'. Well sometimes, it choose rather a process
with a big memory footprint, to kill the smallest number of processes.


Let's consider now a REPL virtual machine implemented over a unix
virtual machine. When you modify the state of the REPL virtual
machine, you modify the REPL virtual machine "image", that is, the
memory the REPL virtual memory process uses. From within the REPL
virtual machine, this change is persistent, but since it is actually
stored inside the unix process memory, it is persistent only as long
as the REPL virtual machine process runs. Since it can be killed
easily just because of a bug in the implementation (rare when it's not
implemented in C), or just because the unix virtual machines wants
because it runs out of memory because of the other processes, and this
REPL virtual machine process uses a lot of memory (as is often the
case, since it has a whole world loaded, including compiler,
interpreter, editor, and other tools in addition to the user
programs), you can lose all that you stored in the REPL virtual memory
image at random points (or just when you shut down the REPL virtual
machine).

In this situation, it is worthwhile to rather edit the sources in an
editor external to the virtual machine, and have it save the files in
the unix virtual machine persistent store. (eg. a Common Lisp
implementation with emacs, and possibly slime to have a direct
communication between emacs and the CL implementation, in addition to
the underlying virtual machine persistent storage).

Now of course, if the REPL virtual machine implements primitives to
load and store files in the underlying virtual machine persistent
store, you can also implement an editor inside the REPL virtual
machine, and just load and save files from there, instead of from the
emacs lisp virtual machine. (Examples are the Climacs or Hemlock
editors running in a Common Lisp virtual machine).

However, when the REPL virtual machine has good introspective
features, even this edit/save-file/load-file-in-REPL cycle becomes
tedious. We want to go at the code that is stored inside the REPL
virtual machine, and directly edit it in place. A prototypal example
of this would be the Smalltalk browser. In this case, we modify
directly the REPL virtual machine memory, and it is not persistent. We
live dangerously! Happily often these REPL virtual machines can save
their "image" to a file in the underlying virtual machine persistent
storage, and when you boot one of these REPL virtual machines, you can
specify what "image" file to load, in place of the default "image"
file. This is wholesale persistence.

(Sometimes, the code entered is not kept in source form in the REPL
virtual machine image. But usually it's easy to add the needed
book-keeping. See for example for CL:
LINK
)


In the end, and given that emacs, either with its bare "inferior-lisp"
mode plus some easily implemented commands, or with the full featured
Slime package, can give the illusion of working within the Common Lisp
image, (and more or less similarly for some other REPL virtual
machines, if with perhaps less features), the question is whether you
prefer to work with the powerful tools offered within emacs, or if you
are satisfied by the editor in your REPL virtual machine. Personnaly,
I never could use the Smalltalk editor. I would have had to implement
an emacs in the Smalltalk image first.

--
__Pascal Bourguignon__ LINK

PLEASE NOTE: Some quantum physics theories suggest that when the
consumer is not directly observing this product, it may cease to
exist or will exist only in a vague and undetermined state.
 

 
James Harris
PostPosted: Fri Aug 15, 2008 7:17 pm    Post subject: Re: Edit commands in Command Line Interpreters
       
On 15 Aug, 07:50, c...@tiac.net (Richard Harter) wrote:
Quote:
In most programming languages source code is in a file or files.
The file(s) are either fed to a compiler or an interpreter; the
user does not alter the source code during execution.

In some languages, e.g., command line interpreters and shell
programs, the user can also enter code interactively. There are
some extra features that useful for interactive mode. Thus:

(a) It is useful to be able to silently enter blocks of code,
i.e., the interpreter does not execute the lines until an entire
block has been entered.

(b) It is useful to be able to edit code on the fly, i.e., edit
blocks of code as they are being entered
(c) It is useful to be able to edit code that has already been
entered and executed.

One way to do this is to run the interpreter within an editor,
e.g., emacs. An alternative is to include editing commands
directly within the language. Does anyone have opinions about or
experience with the latter option?

I used to work with PL1022 which is basically a database access
language. It was fairly standard for us to write code that would write
and execute other PL1022 code. After a while this way of working
became quite familiar and not as confusing as might be expected.
However, IIRC, we had to work that way largely because the language
did not readily permit us to do what we wished to do directly.

I thus tend to think that

a) generating code from within code is associated with poor languages,
b) even if the user enters the code on the fly the whole process
sounds prone to lead to confusion.

So I cannot comment on the options you mention. Maybe if you could
give a concrete example or two of where this all would be advisable it
would be easier to see why the facility would be desirable....?

On the other hand are you thinking of something like Basic where
interaction with the interpreter is via a command line?

--
James
 

 
Richard Harter
PostPosted: Mon Aug 18, 2008 1:55 pm    Post subject: Re: Edit commands in Command Line Interpreters
       
On Fri, 15 Aug 2008 12:17:00 -0700 (PDT), James Harris
<james.harris.1@googlemail.com> wrote:

Quote:
On 15 Aug, 07:50, c...@tiac.net (Richard Harter) wrote:
In most programming languages source code is in a file or files.
The file(s) are either fed to a compiler or an interpreter; the
user does not alter the source code during execution.

In some languages, e.g., command line interpreters and shell
programs, the user can also enter code interactively. There are
some extra features that useful for interactive mode. Thus:

(a) It is useful to be able to silently enter blocks of code,
i.e., the interpreter does not execute the lines until an entire
block has been entered.

(b) It is useful to be able to edit code on the fly, i.e., edit
blocks of code as they are being entered
(c) It is useful to be able to edit code that has already been
entered and executed.

One way to do this is to run the interpreter within an editor,
e.g., emacs. An alternative is to include editing commands
directly within the language. Does anyone have opinions about or
experience with the latter option?

I used to work with PL1022 which is basically a database access
language. It was fairly standard for us to write code that would write
and execute other PL1022 code. After a while this way of working
became quite familiar and not as confusing as might be expected.
However, IIRC, we had to work that way largely because the language
did not readily permit us to do what we wished to do directly.

I thus tend to think that

a) generating code from within code is associated with poor languages,
b) even if the user enters the code on the fly the whole process
sounds prone to lead to confusion.

So I cannot comment on the options you mention. Maybe if you could
give a concrete example or two of where this all would be advisable it
would be easier to see why the facility would be desirable....?

On the other hand are you thinking of something like Basic where
interaction with the interpreter is via a command line?

More the latter. I'm thinking in terms of languages that can be
used as an interactive shell, as a scripting language with
executable script files, and as compilable source.

In the REPL (read-eval-print-loop) model you can enter code on
the fly. The problem is that sometimes I wish to change the code
that I have entered. This implies there is an editing capability
associated with my interactive shell. The issue, then, is what
kind of editor do we want, and what is the relationship between
the editor and the shell.

Thus there is the emacs model, in which the editor is boss, and
you go into code execution mode from the editor. The trouble
with this is it enslaves the interpreter to the editor. Maybe
people don't like the chosen editor. Of course one could have an
API so that the shell could be hooked up to any chosen editor,
but I don't think much of that.

A general method is to write out buffers to a temp file, edit the
temp file with an editor of choice, and read the temp file back
into the interpreter. This sounds cumbersome but the cruft can
all be automated.

One thought that has occurred to me, is to incorporate a
primitive line editor, e.g., an ed clone, directly into the
language. The idea is that the "editor" is, in effect, a
preprocessor. Given that, one could have edit commands in source
files. Whether this is a good idea is another matter.

USW. In short, I looking for ways to think about the problem and
ways of thinking about it that I haven't thought of.


Richard Harter, cri@tiac.net
LINK LINK
Save the Earth now!!
It's the only planet with chocolate.
 

 
Richard Harter
PostPosted: Mon Aug 18, 2008 3:39 pm    Post subject: Re: Edit commands in Command Line Interpreters
       
On Fri, 15 Aug 2008 13:02:24 +0200, pjb@informatimago.com (Pascal
J. Bourguignon) wrote:

Quote:
cri@tiac.net (Richard Harter) writes:

[Snip interesting comments]

I hadn't quite thought of the issue in terms of persistence.


Richard Harter, cri@tiac.net
LINK LINK
Save the Earth now!!
It's the only planet with chocolate.
 

 
Pascal J. Bourguignon
PostPosted: Mon Aug 18, 2008 6:49 pm    Post subject: Re: Edit commands in Command Line Interpreters
       
cri@tiac.net (Richard Harter) writes:
Quote:
In the REPL (read-eval-print-loop) model you can enter code on
the fly. The problem is that sometimes I wish to change the code
that I have entered. This implies there is an editing capability
associated with my interactive shell. The issue, then, is what
kind of editor do we want, and what is the relationship between
the editor and the shell.

I fail to see the problem.


Quote:
Thus there is the emacs model, in which the editor is boss, and
you go into code execution mode from the editor. The trouble
with this is it enslaves the interpreter to the editor.

I don't understand. Do you say slave because emacs is usually used to
fork the lisp (or ruby or whatever) child process? This would be
silly, we can use, for example, slime in emacs, to _connect_ to
preexisting processes, in normal client/server fashion, there's no
slave here.


Quote:
Maybe
people don't like the chosen editor. Of course one could have an
API so that the shell could be hooked up to any chosen editor,
but I don't think much of that.

Why not? It works very well, it's in the spirit of unix, and even of
X (you could embed an editor X window inside any other application X
window). If you don't like the editor, you can easily change it on
the run:

C/USER[3]> (defun fact (x) (if (< x 0) 1 (* x (fact (1- x)))))
FACT
C/USER[4]> (ed 'fact)
Waiting for Emacs... <-- Pff! I corrected the bug
FACT <-- but I didn't liked the editor?
FACT
C/USER[5]> (fact 10)
3628800
C/USER[6]> (setf (ext:getenv "EDITOR") "/bin/ed")
"/bin/ed"
C/USER[7]> (ed 'fact)
54 <-- Yay! This time let's go for
1,$p <-- the STANDARD editor! Smile
(DEFUN FACT (X) (IF (<= X 0) 1 (* X (FACT (1- X)))))

1,$s/X/N/g
1,$p
(DEFUN FACT (N) (IF (<= N 0) 1 (* N (FACT (1- N)))))

wq
54
FACT
FACT
C/USER[8]> (fact 10)
3628800


Quote:
A general method is to write out buffers to a temp file, edit the
temp file with an editor of choice, and read the temp file back
into the interpreter. This sounds cumbersome but the cruft can
all be automated.

Yes, that is, it's not cumbersome at all it's already implemented
every where in unix tools that require edition services from external
editors. Notice that it is so standard that there are these EDITOR
and VISUAl and other unix environment variables.


Quote:
One thought that has occurred to me, is to incorporate a
primitive line editor, e.g., an ed clone, directly into the
language. The idea is that the "editor" is, in effect, a
preprocessor. Given that, one could have edit commands in source
files. Whether this is a good idea is another matter.

Of course it's a good idea, no need to fork off yet another process,
and since you've got the source of the editor inside your image, you
can correct any bug, or extend the editor easily. (In the case of
emacs, it's actually not an editor, but a lisp virtual machine, and
the editor grew over time by debugging and adding feature in
lisp. (well, almost Wink)


C/USER[9]> (com.informatimago.common-lisp.ed:ed 'fact)
1,$p
(DEFUN FACT (N) (DECLARE (SYSTEM::IN-DEFUN FACT))
(BLOCK FACT (IF (<= N 0) 1 (* N (FACT (1- N))))))
w
q
C/USER[10]>


Quote:
USW. In short, I looking for ways to think about the problem and
ways of thinking about it that I haven't thought of.

I would say you need to understand better what an emacs is, and what a
virtual machine is.

Try: The Craft of Text Editing LINK
and of course, use and learn as much as you can of GNU emacs,
and have a look at HEMLOCK and Climacs

And for virtual machines, learn some Smalltalk and give some time to
Squeak (http://www.squeak.org but I'd try a squeak version 2-something
perhaps, rather than the laters that are too much graphics oriented).

Also you could of course spend some time with some Common Lisp
implementation, either standalone in a terminal (try clisp then, since
it incorporates readline), or with emacs thru slime.

You could also try to use Movitz. It's a Common Lisp implementation
on the bare metal, so you don't have an underlying unix virtual
machine. You will have to use an embedded editor, or send your
sources over the network to another virtual machine with emacs ;-)



The point is that you have (virtual) machines that have stored
programs, where the programs are stored in the same memory as data,
and therefore where programs ARE data, and therefore where you can
modify the program as easily as any other data. When you have that,
it doesn't matter if you split sub-virtual-machines, some specialised
for editing some specialised for something else (that's what unix
does, each process being its own specialised virtual machine. But
thanks to the easily modifiable set of commands in a unix system
persistent storage, when you're not happy with a program, you can
easily modify and change it. (Unix is not a batch OS). In the same
way, inside a REPL virtual machine, if you can write an embedded
editor, so good, if you can use an external editor thru a red of
sockets or pipes or underlying persistent storage mechanisms, so good
too! Perhaps better even if this allows you to use a better editor.



--
__Pascal Bourguignon__ LINK

NEW GRAND UNIFIED THEORY DISCLAIMER: The manufacturer may
technically be entitled to claim that this product is
ten-dimensional. However, the consumer is reminded that this
confers no legal rights above and beyond those applicable to
three-dimensional objects, since the seven new dimensions are
"rolled up" into such a small "area" that they cannot be
detected.
 

 
Reinder Verlinde
PostPosted: Mon Aug 18, 2008 8:09 pm    Post subject: Re: Edit commands in Command Line Interpreters
       
In article
<d5095e94-f688-444f-8ca0-06cbe01e848a@l64g2000hse.googlegroups.com>,
James Harris <james.harris.1@googlemail.com> wrote:

Quote:
In the mental model I have, the reason source files exist is to allow
functions to be coded.

There are options for allowing functions without having source files
(examples: Forth, Lisp, Smalltalk)

Quote:
if I use a common command-line interface
I need to distinguish between commands which are to be executed
immediately and commands which are being typed as part of creating
another function. This is a bit like the old Basic interpreter scheme
and one possibility is use of numbers to precede stored program
lines.... Hmm. I'll list some options. See what you think. Can you see
any mileage within any of these?

Option 1. Numbered lines
* All stored lines are numbered
* Numbers are NOT allowed targets for gotos
* The numbers used are insignificant but are in order
* First line of source for a given function is line number 1
* To replace a line type <N>r (where N is the line number)
* To delete a line type <N>d
* To enter new lines before an existing line type <N>b
* To enter new lines after an existing line type <N>a
* To exit line entry mode (which these last two invoke)
do ...<something>...

'Numbered' is not a necessity. It could just be a special character, a
limited set of 'start of line' commands, or an editor that knows the
language grammar.

Quote:
Option 2. Switch into editing mode
* Type "edit <function name>"
* To return to command mode type ...<something>...

Option 3. Multiple editing windows
* Type "edit <function name>" to spawn an editor
* CLI continues to run
[...]
And there is still the need to distinguish between commands and edits.
Maybe some control key combination could be used???

That is option 4: use a special key combination for 'execute this'. This
is what Apple's MPW Shell used. It had Return = insert a newline, Enter
or option-Return = execute current selection/line as a command (Return
and Enter (on the numeric keypad) are different keys on a Mac).

Reinder
 

 
Richard Harter
PostPosted: Mon Aug 18, 2008 8:31 pm    Post subject: Re: Edit commands in Command Line Interpreters
       
On Mon, 18 Aug 2008 22:49:58 +0200, pjb@informatimago.com (Pascal
J. Bourguignon) wrote:

Quote:
cri@tiac.net (Richard Harter) writes:
In the REPL (read-eval-print-loop) model you can enter code on
the fly. The problem is that sometimes I wish to change the code
that I have entered. This implies there is an editing capability
associated with my interactive shell. The issue, then, is what
kind of editor do we want, and what is the relationship between
the editor and the shell.

I fail to see the problem.

Would your difficulty be that you've drunk too much kool-aid from
that jug labeled emacs?

Quote:


Thus there is the emacs model, in which the editor is boss, and
you go into code execution mode from the editor. The trouble
with this is it enslaves the interpreter to the editor.

I don't understand. Do you say slave because emacs is usually used to
fork the lisp (or ruby or whatever) child process? This would be
silly, we can use, for example, slime in emacs, to _connect_ to
preexisting processes, in normal client/server fashion, there's no
slave here.

Enslaves is too strong a word; try subordinates.
Quote:


Maybe
people don't like the chosen editor. Of course one could have an
API so that the shell could be hooked up to any chosen editor,
but I don't think much of that.

Why not? It works very well, it's in the spirit of unix, and even of
X (you could embed an editor X window inside any other application X
window). If you don't like the editor, you can easily change it on
the run:


Quote:

C/USER[3]> (defun fact (x) (if (< x 0) 1 (* x (fact (1- x)))))
FACT
C/USER[4]> (ed 'fact)
Waiting for Emacs... <-- Pff! I corrected the bug
FACT <-- but I didn't liked the editor?
FACT
C/USER[5]> (fact 10)
3628800
C/USER[6]> (setf (ext:getenv "EDITOR") "/bin/ed")
"/bin/ed"
C/USER[7]> (ed 'fact)
54 <-- Yay! This time let's go for
1,$p <-- the STANDARD editor! Smile
(DEFUN FACT (X) (IF (<= X 0) 1 (* X (FACT (1- X)))))

1,$s/X/N/g
1,$p
(DEFUN FACT (N) (IF (<= N 0) 1 (* N (FACT (1- N)))))

wq
54
FACT
FACT
C/USER[8]> (fact 10)
3628800

I like your example - geek to the core.
Quote:


A general method is to write out buffers to a temp file, edit the
temp file with an editor of choice, and read the temp file back
into the interpreter. This sounds cumbersome but the cruft can
all be automated.

Yes, that is, it's not cumbersome at all it's already implemented
every where in unix tools that require edition services from external
editors. Notice that it is so standard that there are these EDITOR
and VISUAl and other unix environment variables.

Unix is not the entirety of the world, you know, nor do all
editors work in the UNIX way (TM).
Quote:


One thought that has occurred to me, is to incorporate a
primitive line editor, e.g., an ed clone, directly into the
language. The idea is that the "editor" is, in effect, a
preprocessor. Given that, one could have edit commands in source
files. Whether this is a good idea is another matter.

Of course it's a good idea, no need to fork off yet another process,
and since you've got the source of the editor inside your image, you
can correct any bug, or extend the editor easily. (In the case of
emacs, it's actually not an editor, but a lisp virtual machine, and
the editor grew over time by debugging and adding feature in
lisp. (well, almost Wink)

Oh, now I've got the source of the emacs editor in my
interpreter, have I. My, my, what an utterly appalling idea.

The point is that one can put together a very simple line editor
inside the interpreter. The question is whether that would be a
good idea, not whether adding a powerhouse editor editor would be
a good idea. Adding emacs an equivalent piece of cruft would, in
my humble opinion, be a bad idea. YMMV.


Quote:


C/USER[9]> (com.informatimago.common-lisp.ed:ed 'fact)
1,$p
(DEFUN FACT (N) (DECLARE (SYSTEM::IN-DEFUN FACT))
(BLOCK FACT (IF (<= N 0) 1 (* N (FACT (1- N))))))
w
q
C/USER[10]


USW. In short, I looking for ways to think about the problem and
ways of thinking about it that I haven't thought of.

I would say you need to understand better what an emacs is, and what a
virtual machine is.

You might very well say that. It seems to be the sort of thing
that you say. Snort.

Quote:

Try: The Craft of Text Editing LINK
and of course, use and learn as much as you can of GNU emacs,
and have a look at HEMLOCK and Climacs

Thanks for the reference.
Quote:

And for virtual machines, learn some Smalltalk and give some time to
Squeak (http://www.squeak.org but I'd try a squeak version 2-something
perhaps, rather than the laters that are too much graphics oriented).

Also you could of course spend some time with some Common Lisp
implementation, either standalone in a terminal (try clisp then, since
it incorporates readline), or with emacs thru slime.

You could also try to use Movitz. It's a Common Lisp implementation
on the bare metal, so you don't have an underlying unix virtual
machine. You will have to use an embedded editor, or send your
sources over the network to another virtual machine with emacs Wink

I do thank you for your suggestion.

Quote:
The point is that you have (virtual) machines that have stored
programs, where the programs are stored in the same memory as data,
and therefore where programs ARE data, and therefore where you can
modify the program as easily as any other data. When you have that,
it doesn't matter if you split sub-virtual-machines, some specialised
for editing some specialised for something else (that's what unix
does, each process being its own specialised virtual machine. But
thanks to the easily modifiable set of commands in a unix system
persistent storage, when you're not happy with a program, you can
easily modify and change it. (Unix is not a batch OS). In the same
way, inside a REPL virtual machine, if you can write an embedded
editor, so good, if you can use an external editor thru a red of
sockets or pipes or underlying persistent storage mechanisms, so good
too! Perhaps better even if this allows you to use a better editor.

I suspect that we have different notions about what constitutes a
better editor.

Thank you for the comments about the virtues of virtual machines,
such as they are. I am so delighted to learn that UNIX is not a
batch OS. Fancy that, I always thought it was an MVS clone.


Richard Harter, cri@tiac.net
LINK LINK
Save the Earth now!!
It's the only planet with chocolate.
 

 
Pascal J. Bourguignon
PostPosted: Mon Aug 18, 2008 9:20 pm    Post subject: Re: Edit commands in Command Line Interpreters
       
James Harris <james.harris.1@googlemail.com> writes:

Quote:
On 18 Aug, 16:55, c...@tiac.net (Richard Harter) wrote:
On Fri, 15 Aug 2008 12:17:00 -0700 (PDT), James Harris



james.harri...@googlemail.com> wrote:
On 15 Aug, 07:50, c...@tiac.net (Richard Harter) wrote:
In most programming languages source code is in a file or files.
The file(s) are either fed to a compiler or an interpreter; the
user does not alter the source code during execution.

In some languages, e.g., command line interpreters and shell
programs, the user can also enter code interactively. There are
some extra features that useful for interactive mode. Thus:

(a) It is useful to be able to silently enter blocks of code,
i.e., the interpreter does not execute the lines until an entire
block has been entered.

(b) It is useful to be able to edit code on the fly, i.e., edit
blocks of code as they are being entered
(c) It is useful to be able to edit code that has already been
entered and executed.

One way to do this is to run the interpreter within an editor,
e.g., emacs. An alternative is to include editing commands
directly within the language. Does anyone have opinions about or
experience with the latter option?

I used to work with PL1022 which is basically a database access
language. It was fairly standard for us to write code that would write
and execute other PL1022 code. After a while this way of working
became quite familiar and not as confusing as might be expected.
However, IIRC, we had to work that way largely because the language
did not readily permit us to do what we wished to do directly.

I thus tend to think that

a) generating code from within code is associated with poor languages,
b) even if the user enters the code on the fly the whole process
sounds prone to lead to confusion.

So I cannot comment on the options you mention. Maybe if you could
give a concrete example or two of where this all would be advisable it
would be easier to see why the facility would be desirable....?

On the other hand are you thinking of something like Basic where
interaction with the interpreter is via a command line?

More the latter. I'm thinking in terms of languages that can be
used as an interactive shell, as a scripting language with
executable script files, and as compilable source.

In the REPL (read-eval-print-loop) model you can enter code on
the fly. The problem is that sometimes I wish to change the code
that I have entered. This implies there is an editing capability
associated with my interactive shell. The issue, then, is what
kind of editor do we want, and what is the relationship between
the editor and the shell.

This sounds like something I have been thinking about as well. I don't
have any complete answers. Maybe between us we can come up with some
options.

In the mental model I have, the reason source files exist is to allow
functions to be coded. Each function is like a command, there tends to
be a one-to-one relationship between source file and function, and
each new function becomes a new command. I could, therefore, ignore
the existence of files and simply code different functions.

You just need to have the REPL environment keep the functions in an
editable form. Old BASIC-like environment used to "compile" the
source, actually encode the parse tree in some compact byte-coded
format, and the LIST command would just unparse this tree to show the
"source". You got "pretty-printing" for the same price.


Current REPL environment don't do that. They rely on the editor, or on
readline and its history feature.

For example, I routinely enter and edit big, multiline commands or
functions in bash, without going thru an editor. Just put set
editmode=emacs in you ~/.bashrc, and use the history (C-p, C-n). But
this is indeed similar to using an external editor. There is no way
(AFAIK), knowing the name of a bash function, to recover the text of
its source.

Similarly, most Common Lisp implementation just compile the code you
give it at the REPL, and therefore cannot return the source (there's a
standard function, CL:FUNCTION-LAMBDA-EXPRESSION, but it is allowed to
return NIL instead of the source form of the function defined).
However, as I already indicated, it's rather easy to add the
bookkeeping needed in the REPL environment to store the source and
retrieve it when you want to edit the function.



Quote:
Like you, if I use a common command-line interface
I need to distinguish between commands which are to be executed
immediately and commands which are being typed as part of creating
another function.

What's wrong with you people, don't you know emacs?

Quote:
I'm not at all familiar with Emacs.

Ah ok. Well, you should.

Quote:
FWIW I think that an editor should
avoid switching between edit and command modes as they always annoy
me.

Check. You'll love emacs, you'll hate vi.


Quote:
I know not all terminals support things like the Alt key but the
control key is fairly ubiquitous.

Actually, all terminals since the era of ASCII support the ESCape key,
and this is what is transmited and what is expected by emacs for a
Meta- key. So if your terminal or terminal emulator cannot map some
Alt-X to ESC X, you can just type ESC X yourself.


Quote:
How about all keys typed go straight
into the document and Control key combinations perform functions or
bring up menus. That way the user is always in edit mode. IIRC the
Wordstar word processor worked something like that.

Yes. Guess where Wordstar took the idea from?



Quote:
And there is still the need to distinguish between commands and edits.
Maybe some control key combination could be used???

What command? What edit? Don't you realize it's always the SAME!

In emacs, there is a function that adds to number (+ 1 2), and there
is a function that transpose two characters at the point
(transpose-chars). There is no difference between these two
functions. If you want to bind a key to a command that sums two
numbers or a command that transpose the characters, to a key, you can
do it equally well. With the same kind of function:

(local-set-key (kbd "<f5>") (lambda () (interactive) (transpose-chars)))
(local-set-key (kbd "<f6>") (lambda () (interactive) (+ 1 2)))

and now when you type F5, the two characters at the point are
transposed (exchanged), and when you type F5, the number 1 and 2 are
added (and the result discarded, but it's up to you to send it
someplace where it can be seen if you so desire).



Similarly, when you have the source of a function in some data
structure, what difference can you make between an expression that
will modify that data structure and another that would modify another
data structure? It's exactly the same! And notice how there is
absolutely no difference between code and data: of course code can be
sent to the evaluator to be "executed", but the data can also be sent
to the evaluator to be "executed" (as long as you provide the "language"
to interpret that data):


C/USER[1]> (defparameter *funs* (make-hash-table))
*FUNS*
C/USER[2]> (setf (gethash 'fact *funs*) '(defun fact (x) (if (< x 0) 1 (* x (fact x)))))
(DEFUN FACT (X) (IF (< X 0) 1 (* X (FACT X))))
C/USER[3]> (eval (gethash 'fact *funs*))
FACT
C/USER[4]> (setf (gethash 'fact *funs*) (subst '<= '< (gethash 'fact *funs*)))
(DEFUN FACT (X) (IF (<= X 0) 1 (* X (FACT X))))
C/USER[5]> (setf (gethash 'fact *funs*) (subst '(fact (1- x)) '(fact x) (gethash 'fact *funs*) :test (function equal)))
(DEFUN FACT (X) (IF (<= X 0) 1 (* X (FACT (1- X)))))
C/USER[6]> (eval (gethash 'fact *funs*))
FACT
C/USER[7]> (fact 10)
3628800
C/USER[8]> (defparameter *pers* (make-hash-table))
*PERS*
C/USER[9]> (setf (gethash 'john *pers*) '(john (mother mary) (father job) (age 10)))
(JOHN (MOTHER MARY) (FATHER JOB) (AGE 10))
C/USER[10]> (setf (gethash 'john *pers*) (subst '(age 12) '(age 10) (gethash 'john *pers*) :test (function equal)))
(JOHN (MOTHER MARY) (FATHER JOB) (AGE 12))
C/USER[11]> (push 'person (gethash 'john *pers*))
(PERSON JOHN (MOTHER MARY) (FATHER JOB) (AGE 12))
C/USER[12]> (defmacro person (name &rest attributes) `(make-alive :name ',name :attributes ',attributes))
PERSON
C/USER[13]> (defun make-alive (&key name attributes) (print `(,name is alive)))
MAKE-ALIVE
C/USER[14]> (eval (gethash 'john *pers*))

(JOHN IS ALIVE)
(JOHN IS ALIVE)
C/USER[15]>




All this is trivial and has been known for more than 50 years now...

--
__Pascal Bourguignon__ LINK

ATTENTION: Despite any other listing of product contents found
herein, the consumer is advised that, in actuality, this product
consists of 99.9999999999% empty space.
 

 
James Harris
PostPosted: Mon Aug 18, 2008 9:26 pm    Post subject: Re: Edit commands in Command Line Interpreters
       
On 18 Aug, 16:55, c...@tiac.net (Richard Harter) wrote:
Quote:
On Fri, 15 Aug 2008 12:17:00 -0700 (PDT), James Harris



james.harri...@googlemail.com> wrote:
On 15 Aug, 07:50, c...@tiac.net (Richard Harter) wrote:
In most programming languages source code is in a file or files.
The file(s) are either fed to a compiler or an interpreter; the
user does not alter the source code during execution.

In some languages, e.g., command line interpreters and shell
programs, the user can also enter code interactively. There are
some extra features that useful for interactive mode. Thus:

(a) It is useful to be able to silently enter blocks of code,
i.e., the interpreter does not execute the lines until an entire
block has been entered.

(b) It is useful to be able to edit code on the fly, i.e., edit
blocks of code as they are being entered
(c) It is useful to be able to edit code that has already been
entered and executed.

One way to do this is to run the interpreter within an editor,
e.g., emacs. An alternative is to include editing commands
directly within the language. Does anyone have opinions about or
experience with the latter option?

I used to work with PL1022 which is basically a database access
language. It was fairly standard for us to write code that would write
and execute other PL1022 code. After a while this way of working
became quite familiar and not as confusing as might be expected.
However, IIRC, we had to work that way largely because the language
did not readily permit us to do what we wished to do directly.

I thus tend to think that

a) generating code from within code is associated with poor languages,
b) even if the user enters the code on the fly the whole process
sounds prone to lead to confusion.

So I cannot comment on the options you mention. Maybe if you could
give a concrete example or two of where this all would be advisable it
would be easier to see why the facility would be desirable....?

On the other hand are you thinking of something like Basic where
interaction with the interpreter is via a command line?

More the latter. I'm thinking in terms of languages that can be
used as an interactive shell, as a scripting language with
executable script files, and as compilable source.

In the REPL (read-eval-print-loop) model you can enter code on
the fly. The problem is that sometimes I wish to change the code
that I have entered. This implies there is an editing capability
associated with my interactive shell. The issue, then, is what
kind of editor do we want, and what is the relationship between
the editor and the shell.

This sounds like something I have been thinking about as well. I don't
have any complete answers. Maybe between us we can come up with some
options.

In the mental model I have, the reason source files exist is to allow
functions to be coded. Each function is like a command, there tends to
be a one-to-one relationship between source file and function, and
each new function becomes a new command. I could, therefore, ignore
the existence of files and simply code different functions.

Going back to your post, the same functions can be called from the
shell as from other functions. For example, function X could be
invoked as

X parm1 parm2

or

X.(parm, parm2)

where the first is command format and the second is function
invocation format. Like you, if I use a common command-line interface
I need to distinguish between commands which are to be executed
immediately and commands which are being typed as part of creating
another function. This is a bit like the old Basic interpreter scheme
and one possibility is use of numbers to precede stored program
lines.... Hmm. I'll list some options. See what you think. Can you see
any mileage within any of these?

Option 1. Numbered lines
* All stored lines are numbered
* Numbers are NOT allowed targets for gotos
* The numbers used are insignificant but are in order
* First line of source for a given function is line number 1
* To replace a line type <N>r (where N is the line number)
* To delete a line type <N>d
* To enter new lines before an existing line type <N>b
* To enter new lines after an existing line type <N>a
* To exit line entry mode (which these last two invoke)
do ...<something>...

Option 2. Switch into editing mode
* Type "edit <function name>"
* To return to command mode type ...<something>...

Option 3. Multiple editing windows
* Type "edit <function name>" to spawn an editor
* CLI continues to run

This one is rather similar to existing windowed environments if an
existing editor is used - e.g. Notepad on Windows and vi on Unix, say.
As a difference we could say that changes made in the editor are
immediately current without being saved, if that helps.

The above suggests that to invoke a function X, rather than typing
"run" as with Basic the user needs to type "X" along with any
parameters.

Maybe the CLI could compile functions on the fly as needed.

I guess you are thinking of allowing the user to write blocks of code
at the command prompt so

for a in 1 .. 10
<do something>
<do something else>
end for

The problem being what to do if the user wants to edit the block
before completing it. Not sure. How about

Option A. Prohibit use of blocks at the CLI
Option B. Give each new CLI block a default name

Just some thoughts.


Quote:
Thus there is the emacs model, in which the editor is boss, and
you go into code execution mode from the editor. The trouble
with this is it enslaves the interpreter to the editor. Maybe
people don't like the chosen editor. Of course one could have an
API so that the shell could be hooked up to any chosen editor,
but I don't think much of that.

I'm not at all familiar with Emacs. FWIW I think that an editor should
avoid switching between edit and command modes as they always annoy
me. I know not all terminals support things like the Alt key but the
control key is fairly ubiquitous. How about all keys typed go straight
into the document and Control key combinations perform functions or
bring up menus. That way the user is always in edit mode. IIRC the
Wordstar word processor worked something like that.

Quote:
A general method is to write out buffers to a temp file, edit the
temp file with an editor of choice, and read the temp file back
into the interpreter. This sounds cumbersome but the cruft can
all be automated.

One thought that has occurred to me, is to incorporate a
primitive line editor, e.g., an ed clone, directly into the
language. The idea is that the "editor" is, in effect, a
preprocessor. Given that, one could have edit commands in source
files. Whether this is a good idea is another matter.

And there is still the need to distinguish between commands and edits.
Maybe some control key combination could be used???

Quote:
USW. In short, I looking for ways to think about the problem and
ways of thinking about it that I haven't thought of.

Me too. Any thoughts on the above?

--
James
 

Page 1 of 2 .:. Goto page 1, 2  Next

Google
 
Webnews.only-4-geeks.com

Windows Update | C++ | C | PHP | JavaScript | Photoshop | Programming | Windows 2000 | Python | Windows XP | Object | Flash | Flash - ActionScript | Paint Shop Pro | Excel | PowerPoint | Access | Word | Windows 98 | Internet Explorer 6.0 | CorelDraw12 | Java | XML | asm x86 | Linux Mandrake | Linux RedHat | Outlook |  | news from newsgroups |_ | s

Web Templates

Awesome Website Templates ©

Diety zakłady bukmacherskie kasyno online hardwood floors Los Angeles nls