guile-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Guile-commits] 01/01: Deprecate user asyncs


From: Andy Wingo
Subject: [Guile-commits] 01/01: Deprecate user asyncs
Date: Mon, 17 Oct 2016 20:00:38 +0000 (UTC)

wingo pushed a commit to branch master
in repository guile.

commit 59f09d185b143326fb5c4d47bbd66eebe2b28d87
Author: Andy Wingo <address@hidden>
Date:   Mon Oct 17 21:58:08 2016 +0200

    Deprecate user asyncs
    
    * libguile/async.c:
    * libguile/async.h:
    * libguile/deprecated.c:
    * libguile/deprecated.h (scm_async, scm_async_mark, scm_run_asyncs):
      Deprecate these functions, which comprise the "users asyncs" facility.
    * module/oop/goops.scm: Adapt to <async> deprecation.
    * doc/ref/api-scheduling.texi:
    * doc/ref/libguile-concepts.texi:
    * doc/ref/libguile-foreign-objects.texi:
    * doc/ref/posix.texi: Remove documentation on user asyncs, and replace
      references to "system asyncs" to be just "asyncs".
---
 doc/ref/api-scheduling.texi           |  128 +++++++++++----------------------
 doc/ref/libguile-concepts.texi        |    2 +-
 doc/ref/libguile-foreign-objects.texi |    8 +--
 doc/ref/posix.texi                    |   10 +--
 libguile/async.c                      |   86 ++--------------------
 libguile/async.h                      |    3 -
 libguile/deprecated.c                 |   63 ++++++++++++++++
 libguile/deprecated.h                 |    6 ++
 module/oop/goops.scm                  |    6 +-
 9 files changed, 130 insertions(+), 182 deletions(-)

diff --git a/doc/ref/api-scheduling.texi b/doc/ref/api-scheduling.texi
index de07637..6048776 100644
--- a/doc/ref/api-scheduling.texi
+++ b/doc/ref/api-scheduling.texi
@@ -25,45 +25,28 @@
 @subsection Asyncs
 
 @cindex asyncs
address@hidden user asyncs
address@hidden system asyncs
 
 Asyncs are a means of deferring the execution of Scheme code until it is
 safe to do so.
 
-Guile provides two kinds of asyncs that share the basic concept but are
-otherwise quite different: system asyncs and user asyncs.  System asyncs
-are integrated into the core of Guile and are executed automatically
-when the system is in a state to allow the execution of Scheme code.
-For example, it is not possible to execute Scheme code in a POSIX signal
-handler, but such a signal handler can queue a system async to be
-executed in the near future, when it is safe to do so.
+Asyncs are integrated into the core of Guile.  A running Guile program
+will periodically check if there are asyncs to run, invoking them as
+needed.  For example, it is not possible to execute Scheme code in a
+POSIX signal handler, but in Guile a signal handler can enqueue a system
+async to be executed in the near future, when it is safe to do so.
 
-System asyncs can also be queued for threads other than the current one.
-This way, you can cause threads to asynchronously execute arbitrary
-code.
-
-User asyncs offer a convenient means of queuing procedures for future
-execution and triggering this execution.  They will not be executed
-automatically.
-
address@hidden
-* System asyncs::
-* User asyncs::
address@hidden menu
-
address@hidden System asyncs
address@hidden System asyncs
+Asyncs can also be queued for threads other than the current one.  This
+way, you can cause threads to asynchronously execute arbitrary code.
 
 To cause the future asynchronous execution of a procedure in a given
 thread, use @code{system-async-mark}.
 
-Automatic invocation of system asyncs can be temporarily disabled by
-calling @code{call-with-blocked-asyncs}.  This function works by
-temporarily increasing the @emph{async blocking level} of the current
-thread while a given procedure is running.  The blocking level starts
-out at zero, and whenever a safe point is reached, a blocking level
-greater than zero will prevent the execution of queued asyncs.
+Automatic invocation of asyncs can be temporarily disabled by calling
address@hidden  This function works by temporarily
+increasing the @emph{async blocking level} of the current thread while a
+given procedure is running.  The blocking level starts out at zero, and
+whenever a safe point is reached, a blocking level greater than zero
+will prevent the execution of queued asyncs.
 
 Analogously, the procedure @code{call-with-unblocked-asyncs} will
 temporarily decrease the blocking level of the current thread.  You
@@ -74,7 +57,7 @@ In addition to the C versions of 
@code{call-with-blocked-asyncs} and
 @code{call-with-unblocked-asyncs}, C code can use
 @code{scm_dynwind_block_asyncs} and @code{scm_dynwind_unblock_asyncs}
 inside a @dfn{dynamic context} (@pxref{Dynamic Wind}) to block or
-unblock system asyncs temporarily.
+unblock asyncs temporarily.
 
 @deffn {Scheme Procedure} system-async-mark proc [thread]
 @deffnx {C Function} scm_system_async_mark (proc)
@@ -85,16 +68,18 @@ in @var{thread}.  When @var{proc} has already been marked 
for
 When @var{thread} is omitted, the thread that called
 @code{system-async-mark} is used.
 
-This procedure is not safe to be called from signal handlers.  Use
+As we mentioned above, Scheme signal handlers are already called within
+an async and so can run any Scheme code.  However, note that the C
+function is not safe to be called from C signal handlers.  Use
 @code{scm_sigaction} or @code{scm_sigaction_for_thread} to install
 signal handlers.
 @end deffn
 
 @deffn {Scheme Procedure} call-with-blocked-asyncs proc
 @deffnx {C Function} scm_call_with_blocked_asyncs (proc)
-Call @var{proc} and block the execution of system asyncs by one level
-for the current thread while it is running.  Return the value returned
-by @var{proc}.  For the first two variants, call @var{proc} with no
+Call @var{proc} and block the execution of asyncs by one level for the
+current thread while it is running.  Return the value returned by
address@hidden  For the first two variants, call @var{proc} with no
 arguments; for the third, call it with @var{data}.
 @end deffn
 
@@ -104,10 +89,10 @@ The same but with a C function @var{proc} instead of a 
Scheme thunk.
 
 @deffn {Scheme Procedure} call-with-unblocked-asyncs proc
 @deffnx {C Function} scm_call_with_unblocked_asyncs (proc)
-Call @var{proc} and unblock the execution of system asyncs by one
-level for the current thread while it is running.  Return the value
-returned by @var{proc}.  For the first two variants, call @var{proc}
-with no arguments; for the third, call it with @var{data}.
+Call @var{proc} and unblock the execution of asyncs by one level for the
+current thread while it is running.  Return the value returned by
address@hidden  For the first two variants, call @var{proc} with no
+arguments; for the third, call it with @var{data}.
 @end deffn
 
 @deftypefn {C Function} {void *} scm_c_call_with_unblocked_asyncs (void 
*(*proc) (void *data), void *data)
@@ -128,32 +113,6 @@ one level.  This function must be used inside a pair of 
calls to
 Wind}).
 @end deftypefn
 
address@hidden User asyncs
address@hidden User asyncs
-
-A user async is a pair of a thunk (a parameterless procedure) and a
-mark.  Setting the mark on a user async will cause the thunk to be
-executed when the user async is passed to @code{run-asyncs}.  Setting
-the mark more than once is satisfied by one execution of the thunk.
-
-User asyncs are created with @code{async}.  They are marked with
address@hidden
-
address@hidden {Scheme Procedure} async thunk
address@hidden {C Function} scm_async (thunk)
-Create a new user async for the procedure @var{thunk}.
address@hidden deffn
-
address@hidden {Scheme Procedure} async-mark a
address@hidden {C Function} scm_async_mark (a)
-Mark the user async @var{a} for future execution.
address@hidden deffn
-
address@hidden {Scheme Procedure} run-asyncs list_of_a
address@hidden {C Function} scm_run_asyncs (list_of_a)
-Execute all thunks from the marked asyncs of the list @var{list_of_a}.
address@hidden deffn
-
 @node Atomics
 @subsection Atomics
 
@@ -443,9 +402,9 @@ If @var{mutex} was locked by a thread that exited before 
unlocking it,
 the next attempt to lock @var{mutex} will succeed, but
 @code{abandoned-mutex-error} will be signalled.
 
-When a system async (@pxref{System asyncs}) is activated for a thread
-blocked in @code{lock-mutex}, the wait is interrupted and the async is
-executed.  When the async returns, the wait resumes.
+When an async (@pxref{Asyncs}) is activated for a thread blocked in
address@hidden, the wait is interrupted and the async is executed.
+When the async returns, the wait resumes.
 @end deffn
 
 @deftypefn {C Function} void scm_dynwind_lock_mutex (SCM mutex)
@@ -526,12 +485,11 @@ as returned by @code{gettimeofday}.  When the waiting is 
aborted,
 signalled, @code{#t} is returned.  The mutex is re-locked in any case
 before @code{wait-condition-variable} returns.
 
-When a system async is activated for a thread that is blocked in a
-call to @code{wait-condition-variable}, the waiting is interrupted,
-the mutex is locked, and the async is executed.  When the async
-returns, the mutex is unlocked again and the waiting is resumed.  When
-the thread block while re-acquiring the mutex, execution of asyncs is
-blocked.
+When an async is activated for a thread that is blocked in a call to
address@hidden, the waiting is interrupted, the mutex is
+locked, and the async is executed.  When the async returns, the mutex is
+unlocked again and the waiting is resumed.  When the thread block while
+re-acquiring the mutex, execution of asyncs is blocked.
 @end deffn
 
 @deffn {Scheme Procedure} signal-condition-variable condvar
@@ -625,18 +583,18 @@ leaves guile mode while waiting for the condition 
variable.
 
 @deftypefn {C Function} int scm_std_select (int nfds, fd_set *readfds, fd_set 
*writefds, fd_set *exceptfds, struct timeval *timeout)
 Like @code{select} but leaves guile mode while waiting.  Also, the
-delivery of a system async causes this function to be interrupted with
-error code @code{EINTR}.
+delivery of an async causes this function to be interrupted with error
+code @code{EINTR}.
 @end deftypefn
 
 @deftypefn {C Function} {unsigned int} scm_std_sleep ({unsigned int} seconds)
 Like @code{sleep}, but leaves guile mode while sleeping.  Also, the
-delivery of a system async causes this function to be interrupted.
+delivery of an async causes this function to be interrupted.
 @end deftypefn
 
 @deftypefn {C Function} {unsigned long} scm_std_usleep ({unsigned long} usecs)
 Like @code{usleep}, but leaves guile mode while sleeping.  Also, the
-delivery of a system async causes this function to be interrupted.
+delivery of an async causes this function to be interrupted.
 @end deftypefn
 
 
@@ -649,14 +607,14 @@ These two macros can be used to delimit a critical 
section.
 Syntactically, they are both statements and need to be followed
 immediately by a semicolon.
 
-Executing @code{SCM_CRITICAL_SECTION_START} will lock a recursive
-mutex and block the executing of system asyncs.  Executing
+Executing @code{SCM_CRITICAL_SECTION_START} will lock a recursive mutex
+and block the executing of asyncs.  Executing
 @code{SCM_CRITICAL_SECTION_END} will unblock the execution of system
-asyncs and unlock the mutex.  Thus, the code that executes between
-these two macros can only be executed in one thread at any one time
-and no system asyncs will run.  However, because the mutex is a
-recursive one, the code might still be reentered by the same thread.
-You must either allow for this or avoid it, both by careful coding.
+asyncs and unlock the mutex.  Thus, the code that executes between these
+two macros can only be executed in one thread at any one time and no
+asyncs will run.  However, because the mutex is a recursive one, the
+code might still be reentered by the same thread.  You must either allow
+for this or avoid it, both by careful coding.
 
 On the other hand, critical sections delimited with these macros can
 be nested since the mutex is recursive.
diff --git a/doc/ref/libguile-concepts.texi b/doc/ref/libguile-concepts.texi
index e93d987..34010ee 100644
--- a/doc/ref/libguile-concepts.texi
+++ b/doc/ref/libguile-concepts.texi
@@ -418,7 +418,7 @@ do such a thing on its own.
 
 If you do not want to allow the running of asynchronous signal handlers,
 you can block them temporarily with @code{scm_dynwind_block_asyncs}, for
-example.  See @xref{System asyncs}.
+example.  @xref{Asyncs}.
 
 Since signal handling in Guile relies on safe points, you need to make
 sure that your functions do offer enough of them.  Normally, calling
diff --git a/doc/ref/libguile-foreign-objects.texi 
b/doc/ref/libguile-foreign-objects.texi
index 11941d5..29e1f86 100644
--- a/doc/ref/libguile-foreign-objects.texi
+++ b/doc/ref/libguile-foreign-objects.texi
@@ -279,10 +279,10 @@ Note that the finalizer may be invoked in ways and at 
times you might
 not expect.  In particular, if the user's Guile is built with support
 for threads, the finalizer may be called from any thread that is running
 Guile.  In Guile 2.0, finalizers are invoked via ``asyncs'', which
-interleaves them with running Scheme code; @pxref{System asyncs}.  In
-Guile 2.2 there will be a dedicated finalization thread, to ensure that
-the finalization doesn't run within the critical section of any other
-thread known to Guile.
+interleaves them with running Scheme code; @pxref{Asyncs}.  In Guile 2.2
+there will be a dedicated finalization thread, to ensure that the
+finalization doesn't run within the critical section of any other thread
+known to Guile.
 
 In either case, finalizers run concurrently with the main program, and
 so they need to be async-safe and thread-safe.  If for some reason this
diff --git a/doc/ref/posix.texi b/doc/ref/posix.texi
index a78617d..1c2c1f3 100644
--- a/doc/ref/posix.texi
+++ b/doc/ref/posix.texi
@@ -2007,11 +2007,11 @@ information.
 
 The following procedures raise, handle and wait for signals.
 
-Scheme code signal handlers are run via a system async (@pxref{System
-asyncs}), so they're called in the handler's thread at the next safe
-opportunity.  Generally this is after any currently executing
-primitive procedure finishes (which could be a long time for
-primitives that wait for an external event).
+Scheme code signal handlers are run via an async (@pxref{Asyncs}), so
+they're called in the handler's thread at the next safe opportunity.
+Generally this is after any currently executing primitive procedure
+finishes (which could be a long time for primitives that wait for an
+external event).
 
 @deffn {Scheme Procedure} kill pid sig
 @deffnx {C Function} scm_kill (pid, sig)
diff --git a/libguile/async.c b/libguile/async.c
index 1e5bc30..1cf1058 100644
--- a/libguile/async.c
+++ b/libguile/async.c
@@ -44,93 +44,19 @@
 
 /* {Asynchronous Events}
  *
- * There are two kinds of asyncs: system asyncs and user asyncs.  The
- * two kinds have some concepts in commen but work slightly
- * differently and are not interchangeable.
- *
- * System asyncs are used to run arbitrary code at the next safe point
- * in a specified thread.  You can use them to trigger execution of
- * Scheme code from signal handlers or to interrupt a thread, for
- * example.
+ * Asyncs are used to run arbitrary code at the next safe point in a
+ * specified thread.  You can use them to trigger execution of Scheme
+ * code from signal handlers or to interrupt a thread, for example.
  *
  * Each thread has a list of 'activated asyncs', which is a normal
  * Scheme list of procedures with zero arguments.  When a thread
- * executes a SCM_ASYNC_TICK statement (which is included in
- * SCM_TICK), it will call all procedures on this list.
- *
- * Also, a thread will wake up when a procedure is added to its list
- * of active asyncs and call them.  After that, it will go to sleep
- * again.  (Not implemented yet.)
- *
- *
- * User asyncs are a little data structure that consists of a
- * procedure of zero arguments and a mark.  There are functions for
- * setting the mark of a user async and for calling all procedures of
- * marked asyncs in a given list.  Nothing you couldn't quickly
- * implement yourself.
+ * executes a SCM_ASYNC_TICK statement (which is included in SCM_TICK),
+ * it will call all procedures on this list.
  */
 
 
 
 
-/* User asyncs. */
-
-static scm_t_bits tc16_async;
-
-/* cmm: this has SCM_ prefix because SCM_MAKE_VALIDATE expects it.
-   this is ugly.  */
-#define SCM_ASYNCP(X)          SCM_TYP16_PREDICATE (tc16_async, X)
-#define VALIDATE_ASYNC(pos, a) SCM_MAKE_VALIDATE_MSG(pos, a, ASYNCP, "user 
async")
-
-#define ASYNC_GOT_IT(X)        (SCM_SMOB_FLAGS (X))
-#define SET_ASYNC_GOT_IT(X, V) (SCM_SET_SMOB_FLAGS ((X), ((V))))
-#define ASYNC_THUNK(X)         SCM_SMOB_OBJECT_1 (X)
-
-
-SCM_DEFINE (scm_async, "async", 1, 0, 0,
-           (SCM thunk),
-           "Create a new async for the procedure @var{thunk}.")
-#define FUNC_NAME s_scm_async
-{
-  SCM_RETURN_NEWSMOB (tc16_async, SCM_UNPACK (thunk));
-}
-#undef FUNC_NAME
-
-SCM_DEFINE (scm_async_mark, "async-mark", 1, 0, 0,
-            (SCM a),
-           "Mark the async @var{a} for future execution.")
-#define FUNC_NAME s_scm_async_mark
-{
-  VALIDATE_ASYNC (1, a);
-  SET_ASYNC_GOT_IT (a, 1);
-  return SCM_UNSPECIFIED;
-}
-#undef FUNC_NAME
-
-SCM_DEFINE (scm_run_asyncs, "run-asyncs", 1, 0, 0,
-           (SCM list_of_a),
-           "Execute all thunks from the asyncs of the list @var{list_of_a}.")
-#define FUNC_NAME s_scm_run_asyncs
-{
-  while (! SCM_NULL_OR_NIL_P (list_of_a))
-    {
-      SCM a;
-      SCM_VALIDATE_CONS (1, list_of_a);
-      a = SCM_CAR (list_of_a);
-      VALIDATE_ASYNC (SCM_ARG1, a);
-      if (ASYNC_GOT_IT (a))
-       {
-         SET_ASYNC_GOT_IT (a, 0);
-         scm_call_0 (ASYNC_THUNK (a));
-       }
-      list_of_a = SCM_CDR (list_of_a);
-    }
-  return SCM_BOOL_T;
-}
-#undef FUNC_NAME
-
-
-
 static scm_i_pthread_mutex_t async_mutex = SCM_I_PTHREAD_MUTEX_INITIALIZER;
 
 /* System asyncs. */
@@ -448,8 +374,6 @@ scm_critical_section_end (void)
 void
 scm_init_async ()
 {
-  tc16_async = scm_make_smob_type ("async", 0);
-
 #include "libguile/async.x"
 }
 
diff --git a/libguile/async.h b/libguile/async.h
index 00b7914..1e9760a 100644
--- a/libguile/async.h
+++ b/libguile/async.h
@@ -32,8 +32,6 @@
 
 SCM_API void scm_async_tick (void);
 SCM_API void scm_switch (void);
-SCM_API SCM scm_async (SCM thunk);
-SCM_API SCM scm_async_mark (SCM a);
 SCM_API SCM scm_system_async_mark (SCM a);
 SCM_API SCM scm_system_async_mark_for_thread (SCM a, SCM thread);
 SCM_INTERNAL void scm_i_queue_async_cell (SCM cell, scm_i_thread *);
@@ -41,7 +39,6 @@ SCM_INTERNAL int scm_i_setup_sleep (scm_i_thread *,
                                    SCM obj, scm_i_pthread_mutex_t *m,
                                    int fd);
 SCM_INTERNAL void scm_i_reset_sleep (scm_i_thread *);
-SCM_API SCM scm_run_asyncs (SCM list_of_a);
 SCM_API SCM scm_noop (SCM args);
 SCM_API SCM scm_call_with_blocked_asyncs (SCM proc);
 SCM_API SCM scm_call_with_unblocked_asyncs (SCM proc);
diff --git a/libguile/deprecated.c b/libguile/deprecated.c
index bae4ed4..228c5d8 100644
--- a/libguile/deprecated.c
+++ b/libguile/deprecated.c
@@ -580,11 +580,74 @@ SCM_DEFINE (scm_release_arbiter, "release-arbiter", 1, 0, 
0,
 
 
 
+/* User asyncs. */
+
+static scm_t_bits tc16_async;
+
+/* cmm: this has SCM_ prefix because SCM_MAKE_VALIDATE expects it.
+   this is ugly.  */
+#define SCM_ASYNCP(X)          SCM_TYP16_PREDICATE (tc16_async, X)
+#define VALIDATE_ASYNC(pos, a) SCM_MAKE_VALIDATE_MSG(pos, a, ASYNCP, "user 
async")
+
+#define ASYNC_GOT_IT(X)        (SCM_SMOB_FLAGS (X))
+#define SET_ASYNC_GOT_IT(X, V) (SCM_SET_SMOB_FLAGS ((X), ((V))))
+#define ASYNC_THUNK(X)         SCM_SMOB_OBJECT_1 (X)
+
+
+SCM_DEFINE (scm_async, "async", 1, 0, 0,
+           (SCM thunk),
+           "Create a new async for the procedure @var{thunk}.")
+#define FUNC_NAME s_scm_async
+{
+  scm_c_issue_deprecation_warning
+    ("\"User asyncs\" are deprecated.  Use closures instead.");
+
+  SCM_RETURN_NEWSMOB (tc16_async, SCM_UNPACK (thunk));
+}
+#undef FUNC_NAME
+
+SCM_DEFINE (scm_async_mark, "async-mark", 1, 0, 0,
+            (SCM a),
+           "Mark the async @var{a} for future execution.")
+#define FUNC_NAME s_scm_async_mark
+{
+  VALIDATE_ASYNC (1, a);
+  SET_ASYNC_GOT_IT (a, 1);
+  return SCM_UNSPECIFIED;
+}
+#undef FUNC_NAME
+
+SCM_DEFINE (scm_run_asyncs, "run-asyncs", 1, 0, 0,
+           (SCM list_of_a),
+           "Execute all thunks from the asyncs of the list @var{list_of_a}.")
+#define FUNC_NAME s_scm_run_asyncs
+{
+  while (! SCM_NULL_OR_NIL_P (list_of_a))
+    {
+      SCM a;
+      SCM_VALIDATE_CONS (1, list_of_a);
+      a = SCM_CAR (list_of_a);
+      VALIDATE_ASYNC (SCM_ARG1, a);
+      if (ASYNC_GOT_IT (a))
+       {
+         SET_ASYNC_GOT_IT (a, 0);
+         scm_call_0 (ASYNC_THUNK (a));
+       }
+      list_of_a = SCM_CDR (list_of_a);
+    }
+  return SCM_BOOL_T;
+}
+#undef FUNC_NAME
+
+
+
+
 void
 scm_i_init_deprecated ()
 {
   scm_tc16_arbiter = scm_make_smob_type ("arbiter", 0);
   scm_set_smob_print (scm_tc16_arbiter, arbiter_print);
+  tc16_async = scm_make_smob_type ("async", 0);
 #include "libguile/deprecated.x"
 }
 
diff --git a/libguile/deprecated.h b/libguile/deprecated.h
index 5e8e8f8..7eb7ee4 100644
--- a/libguile/deprecated.h
+++ b/libguile/deprecated.h
@@ -223,6 +223,12 @@ SCM_DEPRECATED SCM scm_release_arbiter (SCM arb);
 
 
 
+SCM_DEPRECATED SCM scm_async (SCM thunk);
+SCM_DEPRECATED SCM scm_async_mark (SCM a);
+SCM_DEPRECATED SCM scm_run_asyncs (SCM list_of_a);
+
+
+
 void scm_i_init_deprecated (void);
 
 #endif
diff --git a/module/oop/goops.scm b/module/oop/goops.scm
index 1d56cc7..e4f5160 100644
--- a/module/oop/goops.scm
+++ b/module/oop/goops.scm
@@ -75,7 +75,7 @@
             ;; once you have an instance.  Perhaps FIXME to provide a
             ;; smob-type-name->class procedure.
             <promise> <thread> <mutex> <condition-variable>
-            <regexp> <hook> <bitvector> <random-state> <async>
+            <regexp> <hook> <bitvector> <random-state>
             <directory> <array> <character-set>
             <dynamic-object> <guardian> <macro>
 
@@ -3097,7 +3097,8 @@ var{initargs}."
 ;;;
 
 (begin-deprecated
- (define-public <arbiter> (find-subclass <top> '<arbiter>)))
+ (define-public <arbiter> (find-subclass <top> '<arbiter>))
+ (define-public <async> (find-subclass <top> '<async>)))
 
 (define <promise> (find-subclass <top> '<promise>))
 (define <thread> (find-subclass <top> '<thread>))
@@ -3107,7 +3108,6 @@ var{initargs}."
 (define <hook> (find-subclass <top> '<hook>))
 (define <bitvector> (find-subclass <top> '<bitvector>))
 (define <random-state> (find-subclass <top> '<random-state>))
-(define <async> (find-subclass <top> '<async>))
 (define <directory> (find-subclass <top> '<directory>))
 (define <array> (find-subclass <top> '<array>))
 (define <character-set> (find-subclass <top> '<character-set>))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]