[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Patch for better multiple values support
From: |
Matthias Koeppe |
Subject: |
Patch for better multiple values support |
Date: |
10 May 2001 11:24:16 +0200 |
User-agent: |
Gnus/5.0808 (Gnus v5.8.8) Emacs/20.6 |
In this article I propose to change the multiple values support of the
current CVS Guile in order to make it cleaner. A patch is included at
the end of the article.
Guile uses a special struct type for passing multiple values to
multiple-value continuations. Ideally,
1) such an intermediate object should never be exposed to the user,
2) it should be an error to pass the object to ordinary (single-value)
continuations.
However, let us look how Guile deals with these objects.
guile> (version)
"1.5.0"
guile> (use-modules (ice-9 history))
guile> (define x (values 3 4)) ; should signal error
guile> x
$2 = 3
4
guile>
The `define' should signal an error because it is passed two values
where it expects one. Instead, Guile binds the intermediate values
object to `x'. The fancy write representation of intermediate values
objects makes it hard to see what kind of objects are dealt with. It
is only a kludgy solution for the repl but it already breaks when the
history module is used.
The patch shown below does the following:
A) It replaces the fancy write representation of values with a
sharp-angle representation like this: #<values (3 4)>. This is the
right thing to do because of reason 1) and because the intermediate
values objects do not have a read representation.
B) It changes the read-eval-print loop in order to explicitly deal
with multiple values, rather than relying on Guile's "ability" to
pass multiple values to single-value continuations.
boot-9.scm (error-catching-repl): The P ("printer") argument to
error-catching-repl is now a procedure taking one argument, the
list of all returned values; error-catching-repl calls the E
("eval'er") procedure via call-with-values.
(scm-style-repl): The `-print' procedure calls `maybe-print' and
the before/after-print-hook for every element of the list of values
it receives.
Here is an example how this effects the repl when (ice-9 history) is used.
guile> (values 3 4)
$2 = 3
$3 = 4
guile> $2
$4 = 3
That is, one can properly refer to the multiple return values using
the $NUMBER identifiers.
This patch does NOT make Guile signal an error when multiple values
are passed to ordinary (single-value) continuations. I don't know how
to do this; probably the evaluator needs to be changed. Maybe someone
with a deeper understanding of the evaluator can help here.
Matthias
Index: ice-9/boot-9.scm
===================================================================
RCS file: /cvs/guile/guile-core/ice-9/boot-9.scm,v
retrieving revision 1.240
diff -u -r1.240 boot-9.scm
--- ice-9/boot-9.scm 2001/05/05 13:41:59 1.240
+++ ice-9/boot-9.scm 2001/05/10 08:26:51
@@ -2329,7 +2329,10 @@
;; (display "No backtrace available.\n")))
(define (error-catching-repl r e p)
- (error-catching-loop (lambda () (p (e (r))))))
+ (error-catching-loop
+ (lambda ()
+ (call-with-values (lambda () (e (r)))
+ (lambda the-values (p the-values))))))
(define (gc-run-time)
(cdr (assq 'gc-time-taken (gc-stats))))
@@ -2434,15 +2437,20 @@
(begin
(write result)
(newline))))))
- (lambda (result)
+ (lambda (results)
(if (not scm-repl-silent)
(begin
- (run-hook before-print-hook result)
- (maybe-print result)
- (run-hook after-print-hook result)
- (if scm-repl-verbose
- (repl-report))
- (force-output))))))
+ (let loop ((results results))
+ (cond ((null? results)
+ (if scm-repl-verbose
+ (repl-report))
+ (force-output))
+ (else
+ (let ((result (car results)))
+ (run-hook before-print-hook result)
+ (maybe-print result)
+ (run-hook after-print-hook result))
+ (loop (cdr results))))))))))
(-quit (lambda (args)
(if scm-repl-verbose
Index: libguile/values.c
===================================================================
RCS file: /cvs/guile/guile-core/libguile/values.c,v
retrieving revision 1.3
diff -u -r1.3 values.c
--- libguile/values.c 2001/03/26 22:43:23 1.3
+++ libguile/values.c 2001/05/10 08:26:51
@@ -61,13 +61,10 @@
SCM port = SCM_PORT_WITH_PS_PORT (pwps);
scm_print_state *ps = SCM_PRINT_STATE (SCM_PORT_WITH_PS_PS (pwps));
- while (SCM_CONSP (values))
- {
- scm_iprin1 (SCM_CAR (values), port, ps);
- values = SCM_CDR (values);
- if (SCM_CONSP (values))
- scm_newline (port);
- }
+ scm_puts ("#<values ", port);
+ scm_iprin1 (values, port, ps);
+ scm_puts (">", port);
+
return SCM_UNSPECIFIED;
}
--
Matthias Köppe -- http://www.math.uni-magdeburg.de/~mkoeppe
- Patch for better multiple values support,
Matthias Koeppe <=