This is the mail archive of the 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:
> It's possible to get at slib pretty easily from Guile (although I
> don't think the latest version works).

If you could quick tell me how to do that, I'd be grateful.  I've

(define-module (ice-9 slib))
(use-modules (ice-9 slib))

but it doesn't seem to do anything, so I figure I'm not appreciating
some detail of it.  Should a procedure like pretty-print show up as
"pretty-print", "pp:pretty-print", "slib:pretty-print", or what?  Or
is there another statement I need to get at sub-modules?

> > 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)
> Hmm, Guile already has string ports (call-with-input-string,
> call-with-output-string), as do many other implementations, if that is
> what you mean.

Yes, but I wanted to have a stream that didn't involve mutation: i.e., 
I implement it as 

(define (make-stream string position)
  (cons string position))

(define (next stream)
  (cons (car stream) (+ 1 (cdr stream))))

[but fancier, of course]

This way I never change the stream, just pass around a new stream that 
is pointing at a new position.  This works better in the context I'm
in, since there's lots of stream manipulation that needs to be
functional (re-entrant, repeatable, or whatever it's called).

> The REPL loop evals, yes. The original intended Guile formalism was
> for translators to only replace `read', though, not the whole REPL -
> the translator's reader would return Scheme forms in list
> representation to be eval'd as appropriate by the REPL.

OK, that would work fine too.  Similix returns a list just like this.
I'm just trying to figure out the best way to work on top of Similix,
since it wants to see actual Scheme code, barring me from using any
fancy manipulation of the final code outside of the bounds of Scheme's 
actual introspective capabilities.  Or, maybe I'd really need to
modify Similix to make this work right... that would be unfortunate.

> > (eval (cons (list 'define (string->symbol "mytclproc"))
> > 	    (tcl-procedure->lambda tcl-context "mytclproc")))
> I'd just have something that would return 
> (list 'define (string->symbol "mytclproc")
> 	(tcl-procedure->lambda tcl-context "mytclproc"))
> Actually, I don't really understand the latter part - I'd expect
> something more like 
> `(define ,@(cons (tcl-string->symbol procname)
> 		 (map tcl-string->symbol (tcl-string->list arglist)))
>    ,@(tcl-string->code procbody))

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 am impressed with how much your translator manages to handle. Are
> you willing/able to post code somewhere? Maybe I can try some of my
> extra-hairy old tcl code from the bad old days and see how it does.

Well, I'm afraid the translator couldn't deal with much of any real
TCL code at the moment.  It's missing too many primitives, among other
things.  Like I said, these weird cases fall out of the syntax -- they
aren't weird add-ons to the language (a-la Perl :).  The interpreter,
as it currently stands, does most of the core syntax of tcl (I still
don't have arrays, channels, and a few other things) -- where it
doesn't it's a bug, not because I just chose not to follow tcl.  I'm
ultimately aiming to reproduce tcl exactly and completely.  OK, well,
maybe I won't get there but I won't make any compromises to get 90% of
the way there more easily.  Luckily, tcl is small so maybe I'll manage
it (this is why I chose tcl, really, not for any particular love of
the language).

So, my translater supports "set $x blue", but doesn't even have "expr"
yet (expr feels like a whole other completely unrelated
language... ugh).

I guess, to understand why "set $x blue" is easy you have to remember
I'm starting with interpretation.  It's easy in that case, because you 
just do the normal substitution ($x -> a) and run the expression 
"set a blue".  Only if you try to do straight translation will you
find this hard.

If you convert "set XXX YYY" directly to (define XXX YYY) you'll have
defined some variable called "$x", which was not your intention.  That
sort of direct translation will also die on something like 
"while {true} $block".  Your translator can't know ahead of time if
$block is going to be considered to be a lambda-like form (as it is in
the while statement) or just a simple string.  It can't even
necessarily predict what $block is going to be at runtime, and thus it
*must* interpret it (or translate it on the fly, which is almost the
same thing).

On a whim I tried to translate tcl this way (i.e. "set X Y" -> 
(define X Y)) the first time around (about six months ago).  That
didn't work.  So I've come back to this problem a couple times now,
and I think partial evaluation could really work nicely.  Basically
the partial evaluation allows you to make that direct conversion when
it's valid, and fall back on interpretation when it isn't.

Paul Snively was trying to do this sort of thing for Casbah, which is
where I got the ideas.  He decided to start out with perl, though, and 
unsurprisingly blew his mind.  He also tried to do it in a general
sense (thus making it easier to later translate Python or
what-have-you).  I'm hand-coding all the parsing stuff (i.e., without
a lexer), which makes me happy but probably isn't as helpful, and
certainly not as general.

> Another interesting problem is how to deal with the fact that arrays
> are not first-class in tcl.

>From what I can tell (I suppose I should read the tcl sources some
time) tcl kludges this.  So $x(10) is really some variable called
"x(10)", with a few parsing rules to make it a bit more useful.  If
tcl kludges it, I can kludge it too (since I'm only being imitative :)

< Ian Bicking                 |                >
< drawer #419 Earlham College | >
< Richmond, IN 47374          |  (765) 973-2824                     >