This is the mail archive of the guile@cygnus.com mailing list for the guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: TCL->Scheme


Maciej Stachowiak writes:
> But you still need to `require' the appropriate slib package, in your
> case I guess, (require 'pp). Of course, slib also needs to be
> installed somewhere that Guile can find it.

Aha!  I knew there was some detail that was escaping me.

[snipsnip]
> > I don't know just what the syntax would be (it's sort of
> > psuedo-psuedo-code, I guess :) But the point of the "eval" is that I'm
> > actually writing an interpreter.  This later gets changed into a
> > translator, but the translator is completely equivalent to the
> > interpreter.  That's why I want to figure out how to do it without
> > jumping out the the interpreter-paradigm.
> 
> I specifically wanted to think in terms of a translator rather than an
> interpreter, becuase it was much clearer to express the translator
> calling itself recursively to translate the procedure body than to
> express an evaluator calling only its translation half.

Hmmm... neither of those was very clear to me, I'm afraid.  

> The other clarification I was trying to make is that I expect whatever
> is translating proc to have access to the arguments of the proc call,
> namely the proc name, proc argument list, and proc body, rather than
> the name of the proc and a magical way to glean those facts from its
> name.

Oh, that's what the tcl-context was about.  A proc is (in my current
implementation) just a list of variables/arguments consed with the
proc body.  If I'm going to split the proc off from the rest of the
tcl program, I'll also have to consider bindings (i.e., the exported
proc should be able to call other procs that were binded earlier but
not exported).

tcl-proc->lambda would, hopefully, deal with this stuff.  Maybe it
would also convert all arguments into strings and other fancy stuff.

> Of course, if the proc body is not a constant, it would get
> substituted by a variable reference or whatever other kind of
> expression instead of a constant value. I guess that means the
> backquote there is not sufficient, or at least that the unquting is in
> the wrong place, but I am having a hard time thinking of how to
> represent it properly without a double backquote or something.

If the proc body is not constant the lambda call will, in essence and
by necessity, be a call to the interpreter.  Again, this is a place
where I want the partial evaluator to do the work of deciding whether
it must be interpreted or if it can be translated before runtime.

> The hairy examples I would like to try are not especially dependent on
> particular builtins, they just fall out of the oddities of the
> syntax. set $foo "bar" is one example, but how about
> 
> % set foo puts
> puts
> % $foo xyz
> xyz
> 
> Or worse yet:
> 
> % set bar put
> put
> % "${bar}s" xyz
> xyz

These would not currently work.  Only recently I realized you could do
this in tcl -- in an earlier incantation of the program the parsing
did work like this but (from what I'm realizing is a not-so-accurate
man page) I thought that tcl didn't allow this and I seperated
command-name parsing from normal argument parsing.

It'll probably simplify the code some when I change it back.

> I suppose if you are just doing a straight interpreter with no real
> interface to Scheme, this will not be nearly as evil as for a
> translator. I am starting to understand now how the partial evaluator
> approach cleverly optimizes the complicated semantically correct
> translation to somethign simple whenever possible. Zowie. That's
> slick.

Isn't it, though?  One of the first tests I did of the partial
evaluation was:

set i hello
set i "$i world"
puts $i

which translated to:

(display "hello world") (display #\nl)

That's the kind of translation that makes me happy.  OTOH, I think the 
functional way I do variable definition is probably too optimistic,
and while it allows for highly optimized code (like this) it might
become horrible inefficient at the first sign of unoptimizable code.
In general I'm going to have to rethink some of the binding stuff, I'm 
afraid.

> In any case, I'd really like to see your code. Maybe I can even help
> you get it to work with Guile (once my company signs those papers,
> grumble grumble).

I'll put it up after the next round of code-rewriting -- I'm putting
expr in right now (I realized double-parsing is more important than I
thought -- while loops, in particular).  I'll have to re-factor the
code for that.  I hope to get a lot of this work done over the long
weekend I have coming up.

My interpreter works fine with guile, but Similix doesn't.  I've
actually run the interpreter under scm, guile, scheme48, rscheme, and
DrScheme at various times, trying to look for a decent debugging
environment.  Gdb would be a huge step up from any of the others, but
without it scheme48's inspector is very helpful (while looking fairly
simple to implement... hmmm...)

> It is in a way, but internally an array is a namespace implemented as
> a hash table. It would make for really poor performance if you really
> tried to create a fresh variable for each array slot.

Hmmm... that's a good way to look at it (in terms of elegant code).
I'll try setting it up like that.

> Of course, the second-classness of arrays in Tcl leads people to do
> things like pass them by name a lot...
> 
> Another semi-evil thing I thought of: traces. You can't effectively
> trace Scheme variables in most schemes, frustrating attempts to
> translate global sets into defines.

Hmmm.. that does look difficult.  It might not be a problem though, as 
long as internal tcl variables are managed seperately from scheme
variables.

There are a couple things that won't work right in the context of
translation.  "history" and "info", for instance.  While it may be
possible to implement them they would render nearly the entire program
untranslatable if they were used (hence, it's probably best to just
leave them out).  OTOH, figuring out a way to implement them
reasonably efficiently may be the same as trying to figure out a way
to allow debugging of translated programs (like guile hanging onto
source code line numbers when you get an error).

In terms of trace, as I think about it, it's probably best to only
allow procedures to be exported from tcl.  It's easy enough to wrap a
variable in a couple of procedures if you want to do that, and all the 
assignments would be done in the tcl context where trace could be made 
to work.  You also don't have to worry about someone assigning a list
to a tcl variable, or some other thing that would make tcl die
(painfully and without warning).

> Also, tcl has separate function and variable namespaces I think.

yup, I caught that one.

> Just pointing out more annoying problems I have thought of in the
> past.

That's good -- I'd hate to be suprised by some weird tcl thing when
I'm too far into the interpreter.


<------------------------------------------------------------------->
< Ian Bicking                 |  bickiia@earlham.edu                >
< drawer #419 Earlham College |  http://www.cs.earlham.edu/~bickiia >
< Richmond, IN 47374          |  (765) 973-2824                     >
<------------------------------------------------------------------->