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:
> I'm glad someone is working on this. Are you doing this specifically
> for Guile, or trying to be portable to any RnRS Scheme?

Right now I'm doing it in SCM, because Simlix supports just SCM and
Chez Scheme.  Of course, it should be quite easy to port to Guile, but
I haven't bothered working through those details (I just got the
partial evaluator to work on my code yesterday).  Mostly the module
stuff in Similix would need to be ported (to get at slib), and I don't
understand modules in SCM or Guile so I haven't tried yet.

It should be pretty easy to port to anything else -- Similix supports
a functional subset of Scheme, so I'm fairly restricted in what I do.
You can get at all the other stuff, but it's kept separate and defined
differently -- which makes it pretty clear what would need to be
ported.  Also it seems that using more exotic procedures (like (eval
(string->symbol...))) might keep the evaluator from working as well,
so it would be judicious for me to avoid them.  However, Simlix would
need to be ported for it to be very useful (as a straight interpreter
there are some wild inefficiencies put in to keep it functional --
these should disapear during the partial evaluation stage, but leave
the interpreter inefficient).

As it is, I've implemented a whole lot of little things which must
exist in other places already (like streaming over a string) but which 
may work differently with different implementations.  This should make 
it even more portable.  (I've reimplemented some things to do things
in a more functional fashion)

> There were Gdb patches available, as Jim mentioned a while ago, but I
> am not sure they are up to date.

Hmmmm... does anyone know of up-to-date archives of the list?  The
ones at www.red-bean.com only go up to early August.  I didn't notice
anything about gdb when I was browsing through them (though maybe I
missed it).

[code examples]
> ;; then insert in generated code:
> (access-string-variable "*some-variable*)
> ;; however, this expands at macro-expansion time, not runtime, which
> ;; is a shortcoming for some cases in Tcl.

Yeah, macros wouldn't work on a few levels.  Does the REPL loop use
plain evals?  (I suppose the "E" would stand for "eval", answering my
own questions... but I was thinking there might be some deeper
[structurally] manner of getting at that stuff)

> > How can I define a variable based on a string?  E.g., if the TCL
> > wishes to export some procedure, how can I put that procedure's name
> > in the global namespace?
> 
> Use the same hacks as above in combination with `define'.

So, if I do something like this:

(eval (cons (list 'define (string->symbol "mytclproc"))
	    (tcl-procedure->lambda tcl-context "mytclproc")))

It should work?  How can I get it defined in the global scope?

I'm not trying to merge any of the local TCL stuff with Scheme -- the
mixing of the languages at anything less that the global scope seems
unnecessary.

[tcl type problems]
> I don't think there is a better way. Note that you also need to
> specify the return type unless it is possible to magically convert to
> strings in a canonical way.

It should be possible to make a canonical form -- most Scheme data can
be converted into some sort of TCL string, and the Scheme types are
rich enough to figure out the method of conversion automatically.
Anything which can't be converted into a string is going to be
meaningless to a TCL program anyhow.  Oh.  Except if it passes that
same value off to another Scheme procedure.  Hmm... I'll have to think
about that.  There's also messy things like the fact that Scheme ports
aren't necessarily named, where TCL channels are always named.
Hmm... I guess it was worse than I thought.  Darn.

> > So far the translation seems like it's going fairly well -- I'm using
> > a TCL interpreter written in Scheme, then applying a partial evaluator
> > (Similix
> > http://www.diku.dk/research-groups/topps/activities/similix.html).  I
> > don't think there's really any other reasonable way to translate TCL,
> > it being so context sensitive. 
> 
> I don't know if this will precisely reproduce semantics. There is
> actually real Tcl code out there that depends on accessing a variable
> through a name determined by accessing another variable (though I can
> no longer remember the hairy syntax for this).

set a green
set x a
set $x blue
puts $a
  ==> blue

It actually isn't too hairy -- it falls right out of TCL syntax.  It's 
just like LOGO, really:

MAKE "a "green
MAKE "x "a
MAKE :x "blue
PRINT :a
  ==> blue

There's some validity to the way TCL does this, theoretically.
Assignment isn't a special form, much unlike most languages.

Now, expr is ugly (with it's double parsing), and lists are ugly too
(with their double scanning).  Those feel like kludges in TCL -- the
assignment thing is actually fairly elegant (IMHO).  OTOH, I haven't
actually ever chosen to program anything in TCL :-)  (Hmm... I guess
this means that necessity sometimes *isn't* the mother of invention?)

However, this stuff shouldn't be a problem.  While I still haven't
implemented much of TCL, this works fine already.

TCL is meant to be interpreted, which is fine, because I'm
interpreting it.  The magic is all in the partial evaluator (and it
isn't even all that magical -- just rigorous).  The partial evaluator
preserves semantics (for it to do anything else is a bug), so even
after translation this stuff should work.  *However*, some TCL code
could translate very poorly, leaving it essentially interpreted.  The
same goes for byte-code compiling (I imagine they use something
equivalent to partial evaluational, just not as rigorous).

For instance:

set input [read stdin 1]   # get user input
set block "puts \"you answered "
if {"$input" == "y"} {
    append block "yes\""  # paste 'yes"' onto the end of block
} else {
    append block "no\""
}
while {true} $block

(if you enter "y", it prints out "you answered yes" forever,
anything else prints "you answered no")

This is nearly uncompilable but is perfectly legal TCL.  Heck, maybe
people even write like this :-)  It's actually reminiscent of
first-class functions.  Nevertheless, it's why direct translation
doesn't seem like it could work.


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