* How could this be implemented?
@ 2007-01-14 22:50 Jon Wilson
2007-01-15 0:04 ` Per Bothner
2007-01-15 10:13 ` Andy Wingo
0 siblings, 2 replies; 11+ messages in thread
From: Jon Wilson @ 2007-01-14 22:50 UTC (permalink / raw)
Hi,
I've been toying with an odd little idea for a bit. It would add a
whole slew of symbols to guile's toplevel, but might well make it much
more useful as a shell or as a system administration scripting
language. Suppose that we could run executable files found in the $PATH
as if we were just calling a function? So, to change our current
working directory, we would just do:
(cd /)
Or, for instance, we might do:
(ls -a /home/fooguy/.gnome*)
The return value of such an expression would be a read-write port
connected to stdin and stdout for the program running. When eval found
a symbol in the first spot of a list that it didn't know, it would
convert the symbol to a string and search the $PATH just like, say, bash
does. If it found an executable there with a name matching the string,
then it would execute that file. The arguments would be handled thusly:
If the argument is a symbol, and it is bound to some value that we can
see, then convert that value to a string and use the resulting string as
the executable's argument.
If the argument is a symbol, but it is not bound to anything that we can
see, then convert that symbol directly to a string and use for the
executable.
If the argument is a list, try to execute that list as a function call,
convert the result to a string, and use that.
If trying to execute the list results in executing another program from
the $PATH, then pack up all the output (stdout) from the program into a
string (or maybe tokenize it like the shell would... not sure here) and
use that string.
If the argument is any other primitive data type, convert it to a string
and use that.
I suppose it would make things easiest if we used the existing command
interpreter (a la the system function, rather than the system*
function). Then we could just concatenate all the strings (with spaces
in between) and pass them to (system all-our-strings) without worrying
about how they should actually be broken up.
So, anyway, my primary question is: how could something like this be
implemented? It would involve a change, I suppose, to the evaluator.
Could it be made as an extension to eval which is added when you load a
module? Perhaps more pertinent: Could it be written in guile scheme, or
would it require messing with guile itself in C? If it can't be written
in guile scheme, should it be able to be written in guile scheme and how
difficult would it be to add something like that (eval-extension) to
guile? Is this sort of thing what the evaluator-traps thingy is for?
Regards,
Jon
_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: How could this be implemented?
2007-01-14 22:50 How could this be implemented? Jon Wilson
@ 2007-01-15 0:04 ` Per Bothner
2007-01-15 1:37 ` Jon Wilson
2007-01-15 10:13 ` Andy Wingo
1 sibling, 1 reply; 11+ messages in thread
From: Per Bothner @ 2007-01-15 0:04 UTC (permalink / raw)
Cc: Guile Users
Jon Wilson wrote:
> Or, for instance, we might do:
>
> (ls -a /home/fooguy/.gnome*)
>
> The return value of such an expression would be a read-write port
> connected to stdin and stdout for the program running. When eval found
> a symbol in the first spot of a list that it didn't know,
You really have to treat ls as a macro, which is resolved at
compile-time. Otherwise, it becomes near-impossible to
compile name-lookup efficiently. And if you can't compile
it, it's a toy. See:
http://per.bothner.com/papers/beyond-scripting/
> ... and it is bound to some value that we can see ...
This is the hard part: what does "that we can see" mean?
You might fix this interesting:
http://per.bothner.com/software/#Q
and specifically:
http://per.bothner.com/software/Q/Qshell.html
http://home.pacbell.net/bothner/Qman.html#SEC64
--
--Per Bothner
per@bothner.com http://per.bothner.com/
_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: How could this be implemented?
2007-01-15 0:04 ` Per Bothner
@ 2007-01-15 1:37 ` Jon Wilson
2007-01-15 2:44 ` Jon Wilson
` (2 more replies)
0 siblings, 3 replies; 11+ messages in thread
From: Jon Wilson @ 2007-01-15 1:37 UTC (permalink / raw)
Cc: Guile Users
Hi Per,
Per Bothner wrote:
> You really have to treat ls as a macro, which is resolved at
> compile-time. Otherwise, it becomes near-impossible to
> compile name-lookup efficiently. And if you can't compile
> it, it's a toy.
Bash script is not compiled, but it is quite useful. Not a toy at all.
> > ... and it is bound to some value that we can see ...
>
> This is the hard part: what does "that we can see" mean?
Perhaps I'm missing something, because this does not seem at all
difficult. Suppose I am running some guile code. I type something like:
guile>(+ 2 5)
Eval looks up the + symbol and sees that it is bound to a primitive
function. So, what "that we can see" means is anything which eval is
already and normally able to resolve to some value. Perhaps the best
way to implement this would be as an error handler for the Unbound
variable error.
guile>(ls)
Backtrace:
In current input:
2: 0* (ls)
<unnamed port>:2:1: In expression (ls):
<unnamed port>:2:1: Unbound variable: ls
ABORT: (unbound-variable)
Instead of dying when a variable in the function spot is not bound, we
would do a quick $PATH lookup, and if we found something then, we'd
execute it. Otherwise, we'd just go ahead with the Unbound variable
error as normal.
Regards,
Jon
_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: How could this be implemented?
2007-01-15 1:37 ` Jon Wilson
@ 2007-01-15 2:44 ` Jon Wilson
2007-01-15 2:50 ` Per Bothner
[not found] ` <932b2f1f0701141859q4633322raf9b6370f7480396@mail.gmail.com>
2 siblings, 0 replies; 11+ messages in thread
From: Jon Wilson @ 2007-01-15 2:44 UTC (permalink / raw)
Hi,
Jon Wilson wrote:
> Perhaps the best way to implement this would be as an error handler
> for the Unbound variable error.
Except the more I think about it, the more I suspect that this would in
fact require restarts a la common lisp. Why doesn't scheme (except MIT
scheme) have restarts, anyway? They are the prettiest error handling
mechanism I've ever heard of.
Regards,
Jon
PS: just found R5.91RS, which does seem to have a sort of a minimal
restart feature. That does look better.
_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: How could this be implemented?
2007-01-15 1:37 ` Jon Wilson
2007-01-15 2:44 ` Jon Wilson
@ 2007-01-15 2:50 ` Per Bothner
2007-01-15 3:34 ` Jon Wilson
[not found] ` <932b2f1f0701141859q4633322raf9b6370f7480396@mail.gmail.com>
2 siblings, 1 reply; 11+ messages in thread
From: Per Bothner @ 2007-01-15 2:50 UTC (permalink / raw)
Cc: Guile Users
Jon Wilson wrote:
> Per Bothner wrote:
>> You really have to treat ls as a macro, which is resolved at
>> compile-time. Otherwise, it becomes near-impossible to
>> compile name-lookup efficiently. And if you can't compile
>> it, it's a toy.
> Bash script is not compiled, but it is quite useful. Not a toy at all.
You really don't want to do non-trivial programming in bash ...
Also, remember it's a different niche. If you try to combine bash
and scheme, you might get something that sort-of-works but has
terrible performance, debugability, etc.
> So, what "that we can see" means is anything which eval is
> already and normally able to resolve to some value.
The problem is you're killing lexical scoping. You can no
longer tell statically if an identifier reference resolves to
a lexical binding. This means the compiler has to be extra
conservative. It makes harder for people to reason about the
program. And it makes it harder for a compiler to issue useful
error messages.
These are features not to be easily given up.
--
--Per Bothner
per@bothner.com http://per.bothner.com/
_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: How could this be implemented?
[not found] ` <932b2f1f0701141859q4633322raf9b6370f7480396@mail.gmail.com>
@ 2007-01-15 3:08 ` Jon Wilson
2007-01-15 19:31 ` Alan Bram
0 siblings, 1 reply; 11+ messages in thread
From: Jon Wilson @ 2007-01-15 3:08 UTC (permalink / raw)
Cc: Robby Findler
Hi Robby,
> Just in case you haven't already heard about it, you might check out
> scsh.
I've looked at scsh. The whole (run (ls)) thing is just too much noise
for me. It is slightly better than (system "ls"), but I still don't
quite like it well enough.
Regards,
Jon
_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: How could this be implemented?
2007-01-15 2:50 ` Per Bothner
@ 2007-01-15 3:34 ` Jon Wilson
0 siblings, 0 replies; 11+ messages in thread
From: Jon Wilson @ 2007-01-15 3:34 UTC (permalink / raw)
Cc: Guile Users
Hi Per,
Per Bothner wrote:
> You really don't want to do non-trivial programming in bash ...
>
> Also, remember it's a different niche. If you try to combine bash
> and scheme, you might get something that sort-of-works but has
> terrible performance, debugability, etc.
But this is precisely what I'm aiming at. Something that is like bash,
but with scheme syntax and other language features. It would be very
useful to combine the power and elegance of scheme with bash's easy
access to programs that others have written. However, of course you
wouldn't want to do non-trivial programming with it. I'm not proposing
to do so. But not wanting to do non-trivial programming in bash hasn't
kept it from being one of the most useful and most used languages on a
GNU box.
I doubt that the performance will be that bad (for scripting). The
debugability might be more of an issue, but no more so really than with
bash itself.
>
>> So, what "that we can see" means is anything which eval is already
>> and normally able to resolve to some value.
>
> The problem is you're killing lexical scoping. You can no
> longer tell statically if an identifier reference resolves to
> a lexical binding. This means the compiler has to be extra
> conservative. It makes harder for people to reason about the
> program. And it makes it harder for a compiler to issue useful
> error messages.
>
> These are features not to be easily given up.
I'm certainly not proposing to add this to guile scheme as an integral
part of the language. It would be a module, an add-on, to be used when
you want to use it, and devoutly to be ignored otherwise. Besides,
IIRC, guile is not a compiling scheme in any case! Anyway, I'm not sure
how what I am proposing would be noticeably different from adding
bindings for the symbols ls, cd, etc, etc, etc at the toplevel. You
first look in the innermost lexical environment. Do we have a binding
for this symbol here? No? Then look one lexical environment up. No
binding there? Eventually get to the top level. Is there a binding for
this symbol here? No? Well then, look at the filesystem and see if
there is an executable in path with this name. It would not be any
different from having another lexical environment which is one level
higher than what we call toplevel, really, except that the actual symbol
lookup mechanism for this lexical environment is slightly more messy.
But really, I suppose the same effect could be achieved by running, in
.guile I suppose, a bit of code which bound, to the result of
string->symbol on every executable in the path, a function (perhaps
macro) which executed that program with the semantics for the arguments
that I described earlier. Of course, that would take an enormous amount
of time, and you run the risk of stepping on the toes of other things
that are defined already when guile starts up. However, if this were
what was done, then I don't see how it would possible screw up scoping
in the slightest. At any rate, it would certainly not screw up scoping
any more than any other top level define of a procedure (or perhaps macro).
Regards,
Jon
_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: How could this be implemented?
2007-01-14 22:50 How could this be implemented? Jon Wilson
2007-01-15 0:04 ` Per Bothner
@ 2007-01-15 10:13 ` Andy Wingo
2007-01-16 21:37 ` Jon Wilson
1 sibling, 1 reply; 11+ messages in thread
From: Andy Wingo @ 2007-01-15 10:13 UTC (permalink / raw)
Hi Jon,
I think your idea is silly. However you might implement it via module
binder procs. See http://article.gmane.org/gmane.lisp.guile.user/3321
for an idea of how this can be done.
Regards,
Wingo.
--
http://wingolog.org/
_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: How could this be implemented?
2007-01-15 3:08 ` Jon Wilson
@ 2007-01-15 19:31 ` Alan Bram
0 siblings, 0 replies; 11+ messages in thread
From: Alan Bram @ 2007-01-15 19:31 UTC (permalink / raw)
Cc: guile-user, robby.findler
> > Just in case you haven't already heard about it, you might check out
> > scsh.
> I've looked at scsh. The whole (run (ls)) thing is just too much noise
> for me. It is slightly better than (system "ls"), but I still don't
> quite like it well enough.
Then you might prefer Tcl. What you've described is how they do it.
http://www.scsh.net/mail-archive/scsh-users/1996-01/msg00049.html
http://www.cs.indiana.edu/pub/scheme-repository/imp/scsh-paper.ps
(See section 5, "The Tao of Scheme and Unix")
Cheers,
- arb
_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: How could this be implemented?
2007-01-15 10:13 ` Andy Wingo
@ 2007-01-16 21:37 ` Jon Wilson
2007-01-17 8:30 ` Ludovic Courtès
0 siblings, 1 reply; 11+ messages in thread
From: Jon Wilson @ 2007-01-16 21:37 UTC (permalink / raw)
Hi Andy,
I (clearly) don't think it is silly, but I don't think that the guile
developers should think it is silly either, as one of guile's original
goals was to be able to emulate other languages. Bash is a quite common
and useful language, so why shouldn't we try to emulate it? My idea
would perhaps put us one step closer to being able to emulate a whole
class of languages which have the capability of running executables like
bash does (tcsh, bash, tcl ...).
Thanks for the pointer. Do you know of any documentation on module
binder procs? I've looked in the manual and, (as usual) it doesn't
really say much of anything about them.
Regards,
Jon
Andy Wingo wrote:
> Hi Jon,
>
> I think your idea is silly. However you might implement it via module
> binder procs. See http://article.gmane.org/gmane.lisp.guile.user/3321
> for an idea of how this can be done.
>
> Regards,
>
> Wingo.
>
_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: How could this be implemented?
2007-01-16 21:37 ` Jon Wilson
@ 2007-01-17 8:30 ` Ludovic Courtès
0 siblings, 0 replies; 11+ messages in thread
From: Ludovic Courtès @ 2007-01-17 8:30 UTC (permalink / raw)
Cc: guile-user
Hi,
Jon Wilson <j85wilson@fastmail.fm> writes:
> Thanks for the pointer. Do you know of any documentation on module
> binder procs? I've looked in the manual and, (as usual) it doesn't
> really say much of anything about them.
First, I think the "as usual" is a bit unfair. ;-)
Second, if you use undocumented stuff, keep in mind that they may change
without prior notice.
Third, you may want to look at `boot-9.scm' for examples of binder
procedures. Basically, each module can define a binder procedure (using
`set-module-binder!' or as an argument to `module-constructor') that is
called whenever a symbol lookup is not satisfied by the module's symbol
table (its "obarray"). When invoked, that binder is passed three
arguments: the module, the symbol being looked up, and a boolean
indicating whether that symbol is to be defined or just looked up. See,
for instance, `make-autoload-interface' (in 1.8) for an example (or
Andy's link).
Hope this helps,
Ludovic.
PS: FWIW, I'm also not convinced that this is the right approach to
implementing shell-like constructs in Guile.
_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2007-01-17 8:30 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-01-14 22:50 How could this be implemented? Jon Wilson
2007-01-15 0:04 ` Per Bothner
2007-01-15 1:37 ` Jon Wilson
2007-01-15 2:44 ` Jon Wilson
2007-01-15 2:50 ` Per Bothner
2007-01-15 3:34 ` Jon Wilson
[not found] ` <932b2f1f0701141859q4633322raf9b6370f7480396@mail.gmail.com>
2007-01-15 3:08 ` Jon Wilson
2007-01-15 19:31 ` Alan Bram
2007-01-15 10:13 ` Andy Wingo
2007-01-16 21:37 ` Jon Wilson
2007-01-17 8:30 ` Ludovic Courtès
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).