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]

translators



[Trying to catch up on very old mail...]

> The idea of a pure translator of one language into another, doesn't
> seem to fly for many languages.  TCL has stack concepts and scoping
> rules that violate Scheme's closure constructs.  TCL would end up
> more of an implememtation in Scheme than a translation.  Just like
> Guile is implemented in C.  The example I saw in TCL was being
> able to modify a variable on a callers stack, a violation in Scheme.
> Also would a TCL translation be able to call a Guile function, like
> call-with-current-continuation or string-ref?  For different translated
> languages to utilize each other's functionality they would have
> to do something like this.  An alternative, say for TCL, would
> be to provide a new TCL function like call_guile_proc.



Here's how I think about translation.

The most important thing is that the translation has to preserve the
semantics of the source language.  If I run a Tcl program and get some
output, my translator should produce some Scheme expression which
gives the same output.

If that's all you want, you can clearly do this for any language.  I
could translate C into Tcl if I wanted to.  I'd have a big array for
memory, indexed by addresses.  Something like "x++" would turn into

    set $memory(6048) [32bit_add $memory(6048) [32bit_const 1]]

Right?  You're damn sure you're preserving the semantics, but you're
also damn sure you don't want to read the resulting code, or try to
interface between them.

This is really unsatisfying, though, because we are much more
ambitious.  We not only want translation, but we want a *nice
correspondence* between the two languages' worlds.  We want a Tcl
function to be a Scheme function.  We want a Tcl list to be a Scheme
list.

The catch is, a perfect correspondence just isn't possible.  For
example, there's just no way to get set-cdr! to work perfectly in Tcl.
You just can't have Tcl lists share structure, because Tcl lists are
always (semantically, anyway) copied.  I'm not saying this precisely,
but you know what I mean.  You can't mutate Tcl lists in place.

So you find yourself in this very squishy middle ground, where you
want to do as much as possible, but you can't do it perfectly.
So it's kind of unsatisfying in some ways, but in a sense you have a
lot of freedom; you just have to do the best job you can, but you
don't have to do a perfect job.

Here's what I sent to Ian Bicking, which I guess I should have CC'd to
this list after all, to give a sense of how I think translators could
work:


----

The type problem, as you've noticed, is indeed going to come up with
just about every translator we do.  Basically, when it comes to
inter-language calling, there's a spectrum running from "predictable
but clumsy" to "almost always what you want, but hard to rely on".

Keep in mind that no Tcl script in existence requires any particular
Scheme function.  So whatever you invent, you're not going to break
anything.  You want to make Scheme/Tcl calls as convenient as
possible, but don't try to make it invisible, because it can't be done.

Don't introduce anything with difficult-to-predict semantics unless
you provide a solid way to get around it, when the user does know what
they want.

Here's what I'd suggest:

Keep the Tcl namespace and the Scheme namespace separate; don't assume
that every Scheme function is immediately visible to Tcl, and vice
versa.  Thus, the Scheme/Tcl interface becomes explicit, and you give
the user control.  

Provide one calling mechanism that lets the user explicitly specify
exactly how each argument to the Scheme function should be treated.

   # Parse $a and $b as lists, turn them into Scheme lists, and then
   # call Scheme's append function.
   call-scheme append {list list} $a $b
   
That's for maximum control, and it's your escape valve, but it's clumsy.

Provide a function that introduces Scheme functions into Tcl space in
a controlled way, and specifies what to do with the arguments.  For
example:

	import-scheme append {list ...}
	import-scheme sin {number}

This basically provides default conversions for some functions.  Then
you could say

	[append $a $b]

and you'd automatically get the same effect as the call-scheme call
above. 

Try to keep objects as Scheme objects for as long as possible.  Turn
them into strings only if the code's semantics require it.  Basically,
any time Tcl 8.0 would use its optimized internal representation, use
a Schemey representation in your system.