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] |
ian@bickiia.earlhall.earlham.edu writes:
> 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's possible to get at slib pretty easily from Guile (although I
don't think the latest version works).
> 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)
>
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.
> > 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).
>
They seem to not have updated since then. Jim?
> [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)
>
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.
> > > 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")))
>
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))
Where tcl-string->symbol is just string->symbol, assuming Tcl strings
are implemented as Scheme strings, tcl-string->list uses tcl's list
conversion rules and returns a list of strings, and tcl-string->code
recursively does the same string ==> scheme s-expression conversion as
your translator as a whole, recursively on the given string taken as a
list. Maybe a more accurate expression for this idea would be
(map tcl-statement->s-expression (tcl-string->list procbody))
which better expresses the idea that you treat the body of a tcl
"proc" as a list of statements,
which expresses the idea of treating the body as a list of statements,
each of which is recursively turned into an s-expression.
> It should work? How can I get it defined in the global scope?
>
I think you should just write a replacement for `read' and leave it up
to the repl to put things 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.
Probably true.
>
> [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.
There's also the fact that a Scheme list has to be recursively
subconverted or whatever.
>
> > > 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).
>
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.
Another interesting problem is how to deal with the fact that arrays
are not first-class in tcl.
> 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.
>
Yes, there always needs to be an interpretive fallback for really
hairy cases, I imagine.
- Maciej Stachowiak