unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* 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).