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]

They said it couldn't be done (Scheme style auto-resizing hashtable)


> 2. aesthetics: I don't want to store the user's function closures in the
> header; it would be ugly.  Also, if we did, then we couldn't
> "read"/"write" the dictionary to/from a file. 

I asked a while back about how to get (write) to show the (lambda)
expression for a procedure and was told to use (procedure-source).
Since then I have figured out the following pair of routines:


(define write-as-source
  (let ((proc/macro-writer (lambda (PROC PORT)
			   (let ((s (source PROC)))
			     (cond (s (write s) #t)
				   (else #f))))))
    (lambda () (print-options-interface
		(list 'closure-hook proc/macro-writer)))))

(define (write-as-normal) (print-options-interface '(closure-hook #f)))


The key elements to this are the use of the (source) procedure
that knows about both procedures and macros (defined in boot-9 probably..?)
and the use of (print-options-interface) to modify the behaviour of (write).

If you actually try to use these then you will find that the source
code output is strangely appended with a #<procedure> thingy. Looking
at the code from libguile ``print.c'':


	case scm_tcs_closures:
	  /* The user supplied print closure procedure must handle
	     macro closures as well. */
	  if (SCM_FALSEP (scm_procedure_p (SCM_PRINT_CLOSURE))
	      || SCM_FALSEP (scm_printer_apply (SCM_PRINT_CLOSURE,
						exp, port, pstate)));
	  {
	    SCM name, code, env;
	    if (SCM_TYP16 (exp) == scm_tc16_macro)
	      {
		/* Printing a macro. */
	      prinmacro:


You might detect a very suspect looking semicolon that gives
if(); { } rather than if() { } (i.e. the conditional behaviour
of if() is nulified). Removing the semicolon gives the expected
behaviour for the print option and you can go ahead and print
procedures as source code.

You may actually want to be even fancier and print procedures as
source code unless they are primitives in which case you print their
symbolic name, you may want to handle macros differently since this
method prints macros to look like procedures. The point is that
is can be done (with only one character modified in libguile :-)

	- Tel

PS: one subtle point, the items in the print options don't seem
to get marked for garbage collection so the strange way that I define
proc/macro-writer is actually necessary (and redefining write-as-source
while the print option is in place also risks failure). This is a bug
in garbage marking but not a particularly severe one <shrug>.