Web Images Videos Maps News Shopping Gmail more »
Recently Visited Groups | Help | Sign in
Google Groups Home
Message from discussion There has got to be a better way...
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Kent M Pitman  
View profile  
 More options Apr 30 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: Kent M Pitman <pit...@world.std.com>
Date: 1999/04/30
Subject: Re: There has got to be a better way...

Duane Rettig <du...@franz.com> writes:
> Kent is right; keywords offer great flexibility at definitely non-trivial
> time cost, though not in consing.  Keywords are stored in a table on
> the stack, and an out-of-line primitive call is made to sort out the
> argument specification and fill in the table.  It is fairly fast, but
> definitely not function-entry speed.

It doesn't have to work this way, btw.  You could arrange for there to
be multiple entry points for a keyword call, relating to how they were
called.  Consider:

 (defun foo (&key x y) ...)

could be compiled as:

 (defun foo (&rest args) ;hopefully rarely called, so ok to be slow
   (destructuring-bind (&key x y) args
     (internal-foo x y)))
 (defun internal-foo (x y) ...)

with additional bookkeeping so that

 This...                    Compiles to...
 (foo :x (f))               (internal-foo!x-* (f))
 (foo :x (f) :x (g))        (internal-foo!x-x (f) (g))
 (foo :x (f) :y (g))        (internal-foo!x-y (f) (g))
 (foo :y (g) :x (f))        (internal-foo!y-x (g) (f))

where you then made sure the appropriate positional stubs were
present at load time, and where all each stub did was shuffle the
args and call the central entry point.  You could punt to the
general purpose entry point if you were exceeding a stub limit or
if apply had been used.

It would be nice if there was a simple way to request this stuff of
the compiler.  I've ended up writing stuff like this for special
purpose use from time to time, but I lament that most compilers aren't
committed to doing it for me.  Yes, it involves a proliferation of
symbols, but for heavily used interfaces, it's what you need.

It's pretty similar to the way "number calling" used to work (for
functions in Maclisp that were declared to take or return fixnums or
flonums).  The public entry point did not assume special stuff, but
people who had special knowledge of what was going on knew the secret
way to enter the function bypassing the general prolog.

(Really far afield: The trick was in Maclisp that the general purpose
function entry point had a "pushj" to another function as the first
instruction that would unpack the gneral purpose args into number args
and add an additional return frame to the stack so that on the way
out, the number-called internal function would have its args re-packed
into a general purpose call form that the caller expected.  so
number-called functions always blindly entered at the second
instruction, bypassing both the unpacking and the prep for the later
re-packing.  This sometimes led to "fun" cases where people
number-declared functions that weren't number functions and the wrong
thing happened, so you have to be careful.  Once I heard of it
happening deliberately: I remember some bug report from George
Carrette with the subject line "crowbar in head" where he'd finally
tracked down a case of brain damage where someone trying to get past
an error checking instruction ("skipe *rset", in pdp10-ese, if I
recall) by declaring the function a number function.  But the function
code changed and that was no longer the first instruction.  The joys
of cheating.  Life was interesting back then.)

> If you don't want to back all the way off to required arguments only,
> you can still use optionals.  This takes some flexibility away, but
> allows the options, and testing for the presence of optionals are
> only an instruction or two for each optional.  In fact, for n arguments
> of which at least n-k are optionals, if the compiled code decides that
> the kth argument is not present, it can go ahead and assign the default
> values to the kth through nth arguments.

You mean thecompiler works by calling the function with the full
complement of args and skipping (or minimizing) the optional code setup
work?

    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.

Create a group - Google Groups - Google Home - Terms of Service - Privacy Policy
©2009 Google