This is the mail archive of the guile@sourceware.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]

type-checking (was: Re: thanks)


Han-Wen Nienhuys <hanwen@cs.uu.nl> writes:

> [ words snipped ]
>
> In other words, I propose
> 
>       typedef struct {
> 
> 	      ...
> 
> 	     SCM (*func)(..);
> 	     SCM (*type_p)(SCM args);
> 	     char const *name;
>       } scm_subr_entry;
> 
>       SCM
>       call_c_procedure (scm_subr_entry * desc, SCM args)
>       {
> 	if (debug_types)
> 	   {
> 		SCM check = (*desc->type_p )(args);
> 		if(check != SCM_BOOL_T)
> 			 {
> 			 printf ("error in arg to function %s: ",
> 			       desc->name);
> 			 printf ("%s", gh_scm2newstr0 (check))
> 			 }
> 	   }
> 
> 	return (*desc->func)(args);
>       }
> 
> Would this be worth the effort?  It could possibly clean up some of
> the code, moving lots of SCM_ASSERT calls out of function bodies. It
> allows both speed and debuggability.  The big contra, is that
> including checks is extra expensive, since there is a lot of code
> looking like
> 
> 	SCM_ASSERT(SCM_INUMP(k), k, SCM_ARG2, s_list_ref);
> 	i = SCM_INUM(k);
> 	SCM_ASSERT(i >= 0, k, SCM_ARG2, s_list_ref);
> 
> (where the 2nd check uses an intermediate result I of the body).
> 
> Anyways, now that I am thinking longer about the subject, I realise
> that type checking/inferencing is a hairy subject (decidability comes
> around the corner, iirc), so anything more fancy than this probably
> isn't worth the effort.

I believe that even your proposal above is too hairy, for that matter.

<blah>
people need to realize that Guile's performance is limited by its
intimacy with the C world.  one reason is the stack-scanning GC.
another reason is the necessary hairiness of any fine-grained control
over invariant checking.  there probably are more reasons.
</blah>

now, Dirk's idea of providing non-checking variants of Guile
primitives seems to be a very good one, with one caveat: we need to
find some way to automate the duplication.

here is one not even half-baked idea: have the newly-proposed
soon-to-be-implemented GUILE_DEFINE (SCM_DEFINE?) macro do different
things according to whether the SCM_RECKLESS macro is defined.  if
SCM_RECKLESS is defined, then the C name has an 'f_' prefix prepended
to it, and the registration of the Scheme primitive is not performed.
if it's not defined, all is normal.

this way, we get Guile in which all the primitives check their
invariants, but each hash a f_* counterpart that doesn't, and can be
called by libguile clients that know what they are doing.

now, seeng how the above is obviously unworkable, let's see what we
are missing:

we need to evolve the snarfer to something more intelligent, that
can do some clever things with convention-following C code.  it would
need to know how to strip comments, how to extract whole function
bodies (those that begin with GUILE_DEFINE, obviously), how to detect
function calls (so that if you call scm_foo, it will substitute
scm_f_foo), etc.  this way the snarfer will, given foo.c, produce
cooked_foo.c, which then will be compiled.

"foo.c":

#include "needed.h"

static var;
SCM scm_var;

GUILE_DEFINE(blarg, "blarg", 1, 0, 0, (SCM arg),
             "argh! blarg the arg.")
{
   SCM_ASSERT(SCM_CONSP(arg), SCM_ARG1, s_blarg);
   return scm_cons(arg, SCM_EOL);
}

static void
init()
{
  <whatever>;
}

"cooked_foo.c":

#include "needed.h"

static var;
SCM scm_var;

static const char *s_blarg = "blarg";
SCM
scm_blarg(SCM arg)
{
   SCM_ASSERT(SCM_CONSP(arg), SCM_ARG1, s_blarg);
   return scm_cons(arg, SCM_EOL);
}
SCM
scm_f_blarg(SCM arg)
{
   return scm_f_cons(arg, SCM_EOL);
}

static void
init()
{
  <whatever>
}

void
init_foo()
{
  init();
  scm_register_proc(scm_blarg, s_blarg, 1, 0, 0, "argh! blarg the arg.");
}

here, enough rambling for now, I guess.

> Han-Wen Nienhuys, hanwen@cs.uu.nl ** GNU LilyPond - The Music Typesetter

--mike

-- 
Politics is non-euclidean.                           -- Robert Anton Wilson

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]