(none)

5 views
Skip to first unread message

g...@mitech.com

unread,
Aug 15, 1990, 1:49:42 PM8/15/90
to
I hope people may find some interesting technical details in the replies
herein.

>From: Alfred Kayser
>I've once tryed to port it to MSDOS or OS2 (compiler and cpu are the same)
>but it crashed enormously. The code was too unreadable to be debugged.
>Keep in mind that it was started from a 'joke'. SIOD stands for
>Scheme In One Defun. Thus a scheme interpreter in Lisp, which was ported to
>C somewhere between 1.0 and 2.4.

SIOD was never intended to be a joke. The fact that it was in one DEFUN
made it convenient to compile into MICROCODE on the LMI-LAMBDA lispmachine,
which had a PAGED microcode feature. Also, SIOD version 1.0 was in C,
(24-APR-1988), as is obvious from the comments in the source code.

Under the microsoft C compiler, small code and data model at least the 1.3
version of SIOD compiled and ran the first time I tried it.
Anybody who would want to utilize the large data model 80286 mode would
have to be an expert MSDOS/C programmer, I am told by someone who did
a port. The details were something I had a hard time grasping. Very strange
stuff along the lines of PADDING the "struct obj" structure so it would
be 16 bytes long instead of 10 bytes long. Be that as it may the fellow
was using SIOD in a commercial product and must have felt his port to be
too valuable to send back to me. Or perhaps he just didn't want to have
his name on it and have to put up with complaints from people.

>From: UUCP%"re...@parc.xerox.com" 14-AUG-1990 17:21

>> What is one requirement for living well with C? That if you
>> have a lisp-level call to a procedure like (equal (f x) (g y)) that
>> you must be able to call it at C-level as equal(f(x),g(y));

>This is a tall order; the only solution of which I'm aware is a
>conservative GC, and I didn't think siod had one of those (I deduce
>this from the presence in slib.c of a function called "gc_protect").

SIOD has both stop-and-copy and mark-and-sweep GC, the latter being
able to run in "conservative" mode. This can be deduced from the
discussion on garbage collection in SIOD.DOC.

>Or do you have some other way of dealing with the situation where
>assuming left-to-right argument evaluation in C)

> - the result of f is consed
> - the only pointer to this result while in g is on the C stack
> - invoking g triggers a GC
> - after the gc g does more allocation, thereby overwriting the
> result of the call to f?

A good way of describing the problem.

Interesting side-note: A company called Chesnut software was at AAAI
showing their LISP->C translator. It was interesting in that it
produced *readable* C code. For only $75000 with a free runtime license
it may have been the bargain of the show. (Many lisp vendors want $750
or more per copy runtime license). I played with it a little bit.
The disturbing thing was that it seemed to give BETTER performance
than native lisp implementations from the other 3rd-party lisp vendors.
Tells you something about the state of the art of lisp implementation
if such a crude but effective hack as idiomatic LISP->C can do better.

The other disturbing thing is that I swear I could DEBUG the compiled
LISP->C code better than I could debug the native compiled lisp code,
because the state of the art in C language debuggers is better than
the state of the art in LISP (compiled) language debuggers.
The Chesnut Software marketroid person did not seem to pick up on that
as a selling point. "We have a good relationship with the lisp vendors"
he said.

From: Andrew Ginter <samsung!uunet.uu.net!van-bc!ubc-cs!alberta!arcsun.arc.ab.ca!gintera>

>>This is a tall order; the only solution of which I'm aware is a
>>conservative GC...

>There's another solution to the problem - the one I believe GNU emacs
>uses. At the top of the command loop, emacs checks that there is a
>"fair" amount of memory left in the garbage collected heap (as I
>recall, "fair" = no more than about 90% full). If there's not enough
>room, the collector is called. At this point in time, there are no
>pointers to the heap anywhere on the stack. In the rare case that a
>lisp command consumes all of the remaining > 10% of the heap before
>returning to the top of the command loop, emacs simply allocates more
>memory for the heap.

Not accurate for GNU emacs which has explicit calls, in both the
S-expression and byte-code interpreters to macros which effectively
provide a linked list of pointers to GC-protected objects. This is a
good way of doing things. There is overhead in setting up all the GC
protection information, and you have to be very careful to never
RETURN from a function before calling GC-unprotect, but it is more
natural looking and probably as fast or faster than having a special
array to be used for all lisp objects. I would have done the same thing
in later versions of SIOD, except that doesn't allow you to
write things like f(g(),h()), and it slows things down.

There is a very explicit comment in the gnu emacs source, LISP.H about
this:

/* Structure for recording stack slots that need marking

This is a chain of structures, each of which points at a Lisp_Object
variable whose value should be marked in garbage collection. Normally
every link of the chain is an automatic variable of a function, and
its `val' points to some argument or local variable of the function.
On exit to the function, the chain is set back to the value it had on
entry. This way, no link remains in the chain when the stack frame
containing the link disappears.

Every function that can call Feval must protect in this fashion all
Lisp_Object variables whose contents will be used again.

*/

extern struct gcpro *gcprolist;

struct gcpro
{struct gcpro *next;
Lisp_Object *var; /* Address of first protected variable */
int nvars; /* Number of consecutive protected variables */
};

#define GCPRO1(varname) \
{gcpro1.next = gcprolist; gcpro1.var = &varname; gcpro1.nvars = 1; \
gcprolist = &gcpro1; }

#define GCPRO2(varname1, varname2) \
{gcpro1.next = gcprolist; gcpro1.var = &varname1; gcpro1.nvars = 1; \
gcpro2.next = &gcpro1; gcpro2.var = &varname2; gcpro2.nvars = 1; \
gcprolist = &gcpro2; }

/* Call staticpro (&var) to protect static variable `var'. */

void staticpro();

#define UNGCPRO (gcprolist = gcpro1.next)

James da Silva

unread,
Aug 16, 1990, 1:47:17 AM8/16/90
to
In article <900815174...@mailhost.samsung.com> g...@mitech.com writes:
>>From: Alfred Kayser
>>I've once tryed to port it to MSDOS or OS2 (compiler and cpu are the same)
>>but it crashed enormously. The code was too unreadable to be debugged.
>
>Under the microsoft C compiler, small code and data model at least the 1.3
>version of SIOD compiled and ran the first time I tried it.

I would guess that SIOD wants sizeof(pointer) == sizeof(int). This holds
for 8086 small model but not for large model, where sizeof(pointer) == 4.

>Anybody who would want to utilize the large data model 80286 mode would
>have to be an expert MSDOS/C programmer, I am told by someone who did
>a port. The details were something I had a hard time grasping. Very strange
>stuff along the lines of PADDING the "struct obj" structure so it would
>be 16 bytes long instead of 10 bytes long.

This is an old 8086 programmer's trick. On the 86 addresses are divided
into two 16-bit parts; the segment, and the offset. To get the physical
address, the hardware calculates `segment << 4 + offset'. Thus segment
numbers have 16 byte granularity. If all your objects are 16-byte aligned,
you can use just the segment number as the address (the offset is always 0),
thus you are back to sizeof(address) == sizeof(int).

Rather than using this 86-specific hack, it would be better to just make the
SIOD code portable to architectures where ints, pointers, and longs are
not interchangeable. I think making SIOD pass lint would be enough. Any
volunteers?

Jaime
...........................................................................
: domain: j...@cs.umd.edu James da Silva
: path: uunet!mimsy!jds Systems Design & Analysis Group

Al Thompson

unread,
Aug 16, 1990, 4:53:39 PM8/16/90
to

Mr. da Silva,

I am a senior undergraduate computer science student and intermediate
level (read experienced but still rather green) C programmer. You
mentioned that a requirement for making SIOD portable would be to get
it to go through lint without error. Is this possible on a MS C or
Turbo C 8086 config? Also do you know of any way to accomplish a
lint type checking of C source code on a NeXT computer? I have
relatively liberal access to both PC and NeXT machines, but I'm not
sure how to tackle a Portable SIOD project on either. I.e., I'm
volunteering but I'm not particularly sure how to start.


Warmest Wishes For A Happy New Year,
Your Friend and Good Buddy,

Alfred Thompson
Summer Intern (thom...@cebaf4.cebaf.gov)
CEBAF Computer Center
Work Phone: 249-7041

Bruce Krulwich

unread,
Aug 21, 1990, 10:16:20 AM8/21/90
to
In article <900815174...@mailhost.samsung.com>, gjc@mitech writes:
>Interesting side-note: A company called Chesnut software was at AAAI
>showing their LISP->C translator. It was interesting in that it
>produced *readable* C code.
...

>The disturbing thing was that it seemed to give BETTER performance
>than native lisp implementations from the other 3rd-party lisp vendors.
>Tells you something about the state of the art of lisp implementation
>if such a crude but effective hack as idiomatic LISP->C can do better.

I too saw this product and was intrigued. I asked the vendor (who actually
seemed to know the technical aspects of the system) why he got a speedup
over most LISP's, and his thought was that it was because most LISP systems
are written in a system-independant way, while most systems have a C
compiler that is heavily optimized in system-specific ways. In other words,
more work has gone into making sure the C compiler uses all the fastest
machine operations whenever possible, while LISP compiler writers have
presumably worried about other things like run-time environment and
portability.


Bruce Krulwich
krul...@ils.nwu.edu


Sin-Yaw Wang

unread,
Aug 21, 1990, 1:09:18 PM8/21/90
to
In article <14...@anaxagoras.ils.nwu.edu> krul...@ils.nwu.edu (Bruce Krulwich) writes:


To speed up your Lisp, or Scheme, code, there must be a way to measure its
performance and profile the code. Is there any tool for this purpose? Say
I've written a good-sized program, how do I find out where the program is
spending its time?

Patrick Logan

unread,
Aug 24, 1990, 12:54:04 PM8/24/90
to
Colin Plumb <ogicse!jarvis.csri.toronto.edu!colin%array%dciem%utzoo%utgpu> writes:
Less obviously,
(define (bar x) (cons x 1))
is not a function, since ... [confusing use of call/cc and bar]

It is a function. Every element in the domain is mapped to a unique element in
the codomain. The disturbing behavior Colin observed happens as a result of
playing with continuations. It has nothing to do with the function defined
above.

Scheme->C -- 23feb90jfb -- Copyright 1989 Digital Equipment Corporation
> (define (bar x) (cons x 1))
BAR
> (let ((y (call-with-current-continuation bar)))
(if (= (cdr y) 1)
((car y) (cons (car y) 2))
(cdr y)))
2

Atsushi Kanamori

unread,
Aug 25, 1990, 12:37:21 PM8/25/90
to
In article <900824165...@dad.MENTOR.COM> plo...@dad.mentor.COM (Patrick Logan) writes:
>Colin Plumb <ogicse!jarvis.csri.toronto.edu!colin%array%dciem%utzoo%utgpu> writes:
> Less obviously,
> (define (bar x) (cons x 1))
> is not a function, since ... [confusing use of call/cc and bar]
>
>It is a function. Every element in the domain is mapped to a unique element in
>the codomain.

For the record, it is not a function. Calling BAR twice with the same
argument gives you two distinct cons cells that happen to have the same
contents. You can distinguish the two using eq?, set-car! and set-cdr!.

In fact, BAR is a very good "gensym" function when you don't care
about the type of the gensym'd objects.

Alex Martelli

unread,
Sep 6, 1990, 11:22:47 AM9/6/90
to
krul...@ils.nwu.edu (Bruce Krulwich) writes:

I am NOT, repeat, NOT surprised at all: indeed I have measured the
SAME thing with, of all languages, FORTRAN!!! I have a Fortran
program that does 2d fft's on 256x256 complex arrays; running it
through the free f2c converter from ATT, and compiling the resulting
C, gave me TWICE the performance than just compiling the Fortran
source!!! That was on a Sparcstation with the penultimate generation
of Sun compilers (i.e., NOT the "Sparcompilers"). It seems to boil
down to: the groups doing C compilers (on workstations, at least) are
MUCH better at optimizers than all other compiler writers (if it holds
for two such languages as LISP and Fortran, it should hold all 'round,
shouldn't it now...?-).

I have sent the sources to several people who wanted to check, if
you want them too just send me E-mail (I don't regularly follow this
group). Others have gotten very similar results, though, on
(I imagine) completely different programs. Further discussion, if
any, to comp.compilers, I guess?

--
Alex Martelli - CAD.LAB s.p.a., v. Stalingrado 45, Bologna, Italia
Email: (work:) st...@cadlab.sublink.org, (home:) al...@am.sublink.org
Phone: (work:) ++39 (51) 371099, (home:) ++39 (51) 250434;
Fax: ++39 (51) 366964 (work only; any time of day or night).

lawrence.g.mayka

unread,
Sep 10, 1990, 7:13:20 PM9/10/90
to
> krul...@ils.nwu.edu (Bruce Krulwich) writes:
> >In article <900815174...@mailhost.samsung.com>, gjc@mitech writes:
> >>Interesting side-note: A company called Chesnut software was at AAAI
> >>showing their LISP->C translator. It was interesting in that it
> >>produced *readable* C code.
> >...
> >>The disturbing thing was that it seemed to give BETTER performance
> >>than native lisp implementations from the other 3rd-party lisp vendors.
> >>Tells you something about the state of the art of lisp implementation
> >>if such a crude but effective hack as idiomatic LISP->C can do better.
>
> >I too saw this product and was intrigued. I asked the vendor (who actually
> >seemed to know the technical aspects of the system) why he got a speedup
> >over most LISP's, and his thought was that it was because most LISP systems
> >are written in a system-independant way, while most systems have a C
> >compiler that is heavily optimized in system-specific ways. In other words,
> >more work has gone into making sure the C compiler uses all the fastest
> >machine operations whenever possible, while LISP compiler writers have
> >presumably worried about other things like run-time environment and
> >portability.

The literature I've seen indicates that Chestnut's Lisp-to-C
translator requires that the entire Common Lisp program be submitted
at one time. The translator essentially makes compile-time decisions
(e.g., as to the argument list expected by each function) that a
genuine Common Lisp implementation has no right to make. Chestnut's
product may be very useful in its own right, but I would not classify
it as a true Common Lisp system.

Kyoto Common Lisp and its progeny, on the other hand, are genuine
Common Lisp implementations that happen to use C as an intermediate
code representation, primarily for portability reasons. Some such
Lisp systems actually perform competitively, but not spectacularly.


Lawrence G. Mayka
AT&T Bell Laboratories
l...@iexist.att.com

Standard disclaimer.

Reply all
Reply to author
Forward
0 new messages