deprecate primitive properties
authorAndy Wingo <wingo@pobox.com>
Thu, 10 Feb 2011 22:07:03 +0000 (23:07 +0100)
committerAndy Wingo <wingo@pobox.com>
Thu, 10 Feb 2011 22:16:52 +0000 (23:16 +0100)
* libguile.h:
* libguile/Makefile.am:
* libguile/deprecated.h:
* libguile/deprecated.c:
* libguile/init.c:
* libguile/properties.c:
* libguile/properties.h: Deprecate the "primitive properties"
  interface.  It was only used to implement object properties, and that
  is no longer the case.

* module/ice-9/boot-9.scm (make-object-property): Reimplement just in
  terms of weak hash tables, and make threadsafe.

* NEWS:
* doc/ref/api-utility.texi: Update.

NEWS
doc/ref/api-utility.texi
libguile.h
libguile/Makefile.am
libguile/deprecated.c
libguile/deprecated.h
libguile/init.c
libguile/properties.c [deleted file]
libguile/properties.h [deleted file]
module/ice-9/boot-9.scm

diff --git a/NEWS b/NEWS
index 7912259..3c65d98 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,14 @@ latest prerelease, and a full NEWS corresponding to 1.8 -> 2.0.
 
 Changes since the 1.9.15 prerelease:
 
+** Deprecated: primitive properties
+
+The `primitive-make-property', `primitive-property-set!',
+`primitive-property-ref', and `primitive-property-del!' procedures were
+crufty and only used to implement object properties, which has a new,
+threadsafe implementation.  Use object properties or weak hash tables
+instead.
+
 ** New syntax: define-once
 
 `define-once' is like Lisp's `defvar': it creates a toplevel binding,
index fb747ee..ba6139f 100644 (file)
@@ -1,6 +1,6 @@
 @c -*-texinfo-*-
 @c This is part of the GNU Guile Reference Manual.
-@c Copyright (C)  1996, 1997, 2000, 2001, 2002, 2003, 2004
+@c Copyright (C)  1996, 1997, 2000, 2001, 2002, 2003, 2004, 2011
 @c   Free Software Foundation, Inc.
 @c See the file guile.texi for copying conditions.
 
@@ -229,57 +229,10 @@ protected.  When the Scheme value is collected, its entry in the
 property table is removed and so the (ex-) property values are no longer
 protected by the table.
 
-@menu
-* Property Primitives::         Low level property implementation.
-* Old-fashioned Properties::    An older approach to properties.
-@end menu
-
-
-@node Property Primitives
-@subsubsection Low Level Property Implementation.
-
-@deffn {Scheme Procedure} primitive-make-property not-found-proc
-@deffnx {C Function} scm_primitive_make_property (not_found_proc)
-Create a @dfn{property token} that can be used with
-@code{primitive-property-ref} and @code{primitive-property-set!}.
-See @code{primitive-property-ref} for the significance of
-@var{not-found-proc}.
-@end deffn
-
-@deffn {Scheme Procedure} primitive-property-ref prop obj
-@deffnx {C Function} scm_primitive_property_ref (prop, obj)
-Return the property @var{prop} of @var{obj}.
-
-When no value has yet been associated with @var{prop} and @var{obj},
-the @var{not-found-proc} from @var{prop} is used.  A call
-@code{(@var{not-found-proc} @var{prop} @var{obj})} is made and the
-result set as the property value.  If @var{not-found-proc} is
-@code{#f} then @code{#f} is the property value.
-@end deffn
-
-@deffn {Scheme Procedure} primitive-property-set! prop obj val
-@deffnx {C Function} scm_primitive_property_set_x (prop, obj, val)
-Set the property @var{prop} of @var{obj} to @var{val}.
-@end deffn
-
-@deffn {Scheme Procedure} primitive-property-del! prop obj
-@deffnx {C Function} scm_primitive_property_del_x (prop, obj)
-Remove any value associated with @var{prop} and @var{obj}.
-@end deffn
-
-
-@node Old-fashioned Properties
-@subsubsection An Older Approach to Properties
-
-Traditionally, Lisp systems provide a different object property
-interface to that provided by @code{make-object-property}, in which the
-object property that is being set or retrieved is indicated by a symbol.
-
-Guile includes this older kind of interface as well, but it may well be
-removed in a future release, as it is less powerful than
-@code{make-object-property} and so increases the size of the Guile
-library for no benefit.  (And it is trivial to write a compatibility
-layer in Scheme.)
+Guile also implements a more traditional Lispy interface to properties,
+in which each object has an list of key-value pairs associated with it.
+Properties in that list are keyed by symbols.  This is a legacy
+interface; you should use weak hash tables or object properties instead.
 
 @deffn {Scheme Procedure} object-properties obj
 @deffnx {C Function} scm_object_properties (obj)
index 5e8c792..2c10d05 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef SCM_LIBGUILE_H
 #define SCM_LIBGUILE_H
 
-/* Copyright (C) 1995,1996,1997,1998,2000,2001, 2002, 2003, 2004, 2006, 2008, 2009, 2010 Free Software Foundation, Inc.
+/* Copyright (C) 1995,1996,1997,1998,2000,2001, 2002, 2003, 2004, 2006, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
  * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -82,7 +82,6 @@ extern "C" {
 #include "libguile/print.h"
 #include "libguile/procprop.h"
 #include "libguile/promises.h"
-#include "libguile/properties.h"
 #include "libguile/procs.h"
 #include "libguile/r6rs-ports.h"
 #include "libguile/random.h"
index dd797ea..79f886b 100644 (file)
@@ -1,6 +1,6 @@
 ## Process this file with Automake to create Makefile.in
 ##
-##     Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+##     Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
 ##
 ##   This file is part of GUILE.
 ##
@@ -177,7 +177,6 @@ libguile_@GUILE_EFFECTIVE_VERSION@_la_SOURCES =                             \
        procs.c                                 \
        programs.c                              \
        promises.c                              \
-       properties.c                            \
        r6rs-ports.c                            \
        random.c                                \
        rdelim.c                                \
@@ -274,7 +273,6 @@ DOT_X_FILES =                                       \
        procprop.x                              \
        procs.x                                 \
        promises.x                              \
-       properties.x                            \
        r6rs-ports.x                            \
        random.x                                \
        rdelim.x                                \
@@ -375,7 +373,6 @@ DOT_DOC_FILES =                             \
        procprop.doc                            \
        procs.doc                               \
        promises.doc                            \
-       properties.doc                          \
        r6rs-ports.doc                          \
        random.doc                              \
        rdelim.doc                              \
@@ -550,7 +547,6 @@ modinclude_HEADERS =                                \
        procs.h                                 \
        programs.h                              \
        promises.h                              \
-       properties.h                            \
        pthread-threads.h                       \
        r6rs-ports.h                            \
        random.h                                \
index 59ff341..fd23e2d 100644 (file)
@@ -2,7 +2,7 @@
    deprecate something, move it here when that is feasible.
 */
 
-/* Copyright (C) 2003, 2004, 2006, 2008, 2009, 2010 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2006, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -2390,9 +2390,120 @@ SCM_DEFINE (scm_cuserid, "cuserid", 0, 0, 0,
 
 \f
 
+/* {Properties}
+ */
+
+static SCM properties_whash;
+
+SCM_DEFINE (scm_primitive_make_property, "primitive-make-property", 1, 0, 0,
+           (SCM not_found_proc),
+           "Create a @dfn{property token} that can be used with\n"
+           "@code{primitive-property-ref} and @code{primitive-property-set!}.\n"
+           "See @code{primitive-property-ref} for the significance of\n"
+           "@var{not_found_proc}.")
+#define FUNC_NAME s_scm_primitive_make_property
+{
+  scm_c_issue_deprecation_warning
+    ("`primitive-make-property' is deprecated.  Use object properties.");
+
+  if (not_found_proc != SCM_BOOL_F)
+    SCM_VALIDATE_PROC (SCM_ARG1, not_found_proc);
+  return scm_cons (not_found_proc, SCM_EOL);
+}
+#undef FUNC_NAME
+
+
+SCM_DEFINE (scm_primitive_property_ref, "primitive-property-ref", 2, 0, 0,
+           (SCM prop, SCM obj),
+           "Return the property @var{prop} of @var{obj}.\n"
+           "\n"
+           "When no value has yet been associated with @var{prop} and\n"
+           "@var{obj}, the @var{not-found-proc} from @var{prop} is used.  A\n"
+           "call @code{(@var{not-found-proc} @var{prop} @var{obj})} is made\n"
+           "and the result set as the property value.  If\n"
+           "@var{not-found-proc} is @code{#f} then @code{#f} is the\n"
+           "property value.")
+#define FUNC_NAME s_scm_primitive_property_ref
+{
+  SCM h;
+
+  scm_c_issue_deprecation_warning
+    ("`primitive-property-ref' is deprecated.  Use object properties.");
+
+  SCM_VALIDATE_CONS (SCM_ARG1, prop);
+
+  h = scm_hashq_get_handle (properties_whash, obj);
+  if (scm_is_true (h))
+    {
+      SCM assoc = scm_assq (prop, SCM_CDR (h));
+      if (scm_is_true (assoc))
+       return SCM_CDR (assoc);
+    }
+
+  if (scm_is_false (SCM_CAR (prop)))
+    return SCM_BOOL_F;
+  else
+    {
+      SCM val = scm_call_2 (SCM_CAR (prop), prop, obj);
+      if (scm_is_false (h))
+       h = scm_hashq_create_handle_x (properties_whash, obj, SCM_EOL);
+      SCM_SETCDR (h, scm_acons (prop, val, SCM_CDR (h)));
+      return val;
+    }
+}
+#undef FUNC_NAME
+
+
+SCM_DEFINE (scm_primitive_property_set_x, "primitive-property-set!", 3, 0, 0,
+           (SCM prop, SCM obj, SCM val),
+           "Set the property @var{prop} of @var{obj} to @var{val}.")
+#define FUNC_NAME s_scm_primitive_property_set_x
+{
+  SCM h, assoc;
+
+  scm_c_issue_deprecation_warning
+    ("`primitive-property-set!' is deprecated.  Use object properties.");
+
+  SCM_VALIDATE_CONS (SCM_ARG1, prop);
+  h = scm_hashq_create_handle_x (properties_whash, obj, SCM_EOL);
+  assoc = scm_assq (prop, SCM_CDR (h));
+  if (SCM_NIMP (assoc))
+    SCM_SETCDR (assoc, val);
+  else
+    {
+      assoc = scm_acons (prop, val, SCM_CDR (h));
+      SCM_SETCDR (h, assoc);
+    }
+  return SCM_UNSPECIFIED;
+}
+#undef FUNC_NAME
+
+
+SCM_DEFINE (scm_primitive_property_del_x, "primitive-property-del!", 2, 0, 0,
+           (SCM prop, SCM obj),
+           "Remove any value associated with @var{prop} and @var{obj}.")
+#define FUNC_NAME s_scm_primitive_property_del_x
+{
+  SCM h;
+
+  scm_c_issue_deprecation_warning
+    ("`primitive-property-del!' is deprecated.  Use object properties.");
+
+  SCM_VALIDATE_CONS (SCM_ARG1, prop);
+  h = scm_hashq_get_handle (properties_whash, obj);
+  if (scm_is_true (h))
+    SCM_SETCDR (h, scm_assq_remove_x (SCM_CDR (h), prop));
+  return SCM_UNSPECIFIED;
+}
+#undef FUNC_NAME
+
+\f
+
+
 void
 scm_i_init_deprecated ()
 {
+  properties_whash = scm_make_weak_key_hash_table (SCM_UNDEFINED);
 #include "libguile/deprecated.x"
 }
 
index 84258fa..68aee63 100644 (file)
@@ -5,7 +5,7 @@
 #ifndef SCM_DEPRECATED_H
 #define SCM_DEPRECATED_H
 
-/* Copyright (C) 2003,2004, 2005, 2006, 2007, 2009, 2010 Free Software Foundation, Inc.
+/* Copyright (C) 2003,2004, 2005, 2006, 2007, 2009, 2010, 2011 Free Software Foundation, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -738,7 +738,16 @@ SCM_DEPRECATED int scm_internal_select (int fds,
 \f
 /* Deprecated because the cuserid call is deprecated.
  */
-SCM_API SCM scm_cuserid (void);
+SCM_DEPRECATED SCM scm_cuserid (void);
+
+\f
+
+/* Deprecated because it's yet another property interface.
+ */
+SCM_DEPRECATED SCM scm_primitive_make_property (SCM not_found_proc);
+SCM_DEPRECATED SCM scm_primitive_property_ref (SCM prop, SCM obj);
+SCM_DEPRECATED SCM scm_primitive_property_set_x (SCM prop, SCM obj, SCM val);
+SCM_DEPRECATED SCM scm_primitive_property_del_x (SCM prop, SCM obj);
 
 \f
 
index cf7447d..243e15e 100644 (file)
@@ -99,7 +99,6 @@
 #include "libguile/procs.h"
 #include "libguile/programs.h"
 #include "libguile/promises.h"
-#include "libguile/properties.h"
 #include "libguile/array-map.h"
 #include "libguile/random.h"
 #include "libguile/rdelim.h"
@@ -458,7 +457,6 @@ scm_i_init_guile (SCM_STACKITEM *base)
   scm_init_deprecation ();
   scm_init_objprop ();
   scm_init_promises ();         /* requires smob_prehistory */
-  scm_init_properties ();
   scm_init_hooks ();            /* Requires smob_prehistory */
   scm_init_gc ();              /* Requires hooks */
   scm_init_gc_protect_object ();  /* requires threads_prehistory */
diff --git a/libguile/properties.c b/libguile/properties.c
deleted file mode 100644 (file)
index 1f3c668..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-/* Copyright (C) 1995,1996,2000,2001, 2003, 2006, 2008, 2009 Free Software Foundation, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 3 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-
-\f
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "libguile/_scm.h"
-#include "libguile/hashtab.h"
-#include "libguile/alist.h"
-#include "libguile/root.h"
-#include "libguile/weaks.h"
-#include "libguile/validate.h"
-#include "libguile/eval.h"
-
-#include "libguile/properties.h"
-\f
-
-/* {Properties}
- */
-
-static SCM properties_whash;
-
-SCM_DEFINE (scm_primitive_make_property, "primitive-make-property", 1, 0, 0,
-           (SCM not_found_proc),
-           "Create a @dfn{property token} that can be used with\n"
-           "@code{primitive-property-ref} and @code{primitive-property-set!}.\n"
-           "See @code{primitive-property-ref} for the significance of\n"
-           "@var{not_found_proc}.")
-#define FUNC_NAME s_scm_primitive_make_property
-{
-  if (not_found_proc != SCM_BOOL_F)
-    SCM_VALIDATE_PROC (SCM_ARG1, not_found_proc);
-  return scm_cons (not_found_proc, SCM_EOL);
-}
-#undef FUNC_NAME
-
-
-SCM_DEFINE (scm_primitive_property_ref, "primitive-property-ref", 2, 0, 0,
-           (SCM prop, SCM obj),
-           "Return the property @var{prop} of @var{obj}.\n"
-           "\n"
-           "When no value has yet been associated with @var{prop} and\n"
-           "@var{obj}, the @var{not-found-proc} from @var{prop} is used.  A\n"
-           "call @code{(@var{not-found-proc} @var{prop} @var{obj})} is made\n"
-           "and the result set as the property value.  If\n"
-           "@var{not-found-proc} is @code{#f} then @code{#f} is the\n"
-           "property value.")
-#define FUNC_NAME s_scm_primitive_property_ref
-{
-  SCM h;
-
-  SCM_VALIDATE_CONS (SCM_ARG1, prop);
-
-  h = scm_hashq_get_handle (properties_whash, obj);
-  if (scm_is_true (h))
-    {
-      SCM assoc = scm_assq (prop, SCM_CDR (h));
-      if (scm_is_true (assoc))
-       return SCM_CDR (assoc);
-    }
-
-  if (scm_is_false (SCM_CAR (prop)))
-    return SCM_BOOL_F;
-  else
-    {
-      SCM val = scm_call_2 (SCM_CAR (prop), prop, obj);
-      if (scm_is_false (h))
-       h = scm_hashq_create_handle_x (properties_whash, obj, SCM_EOL);
-      SCM_SETCDR (h, scm_acons (prop, val, SCM_CDR (h)));
-      return val;
-    }
-}
-#undef FUNC_NAME
-
-
-SCM_DEFINE (scm_primitive_property_set_x, "primitive-property-set!", 3, 0, 0,
-           (SCM prop, SCM obj, SCM val),
-           "Set the property @var{prop} of @var{obj} to @var{val}.")
-#define FUNC_NAME s_scm_primitive_property_set_x
-{
-  SCM h, assoc;
-  SCM_VALIDATE_CONS (SCM_ARG1, prop);
-  h = scm_hashq_create_handle_x (properties_whash, obj, SCM_EOL);
-  assoc = scm_assq (prop, SCM_CDR (h));
-  if (SCM_NIMP (assoc))
-    SCM_SETCDR (assoc, val);
-  else
-    {
-      assoc = scm_acons (prop, val, SCM_CDR (h));
-      SCM_SETCDR (h, assoc);
-    }
-  return SCM_UNSPECIFIED;
-}
-#undef FUNC_NAME
-
-
-SCM_DEFINE (scm_primitive_property_del_x, "primitive-property-del!", 2, 0, 0,
-           (SCM prop, SCM obj),
-           "Remove any value associated with @var{prop} and @var{obj}.")
-#define FUNC_NAME s_scm_primitive_property_del_x
-{
-  SCM h;
-  SCM_VALIDATE_CONS (SCM_ARG1, prop);
-  h = scm_hashq_get_handle (properties_whash, obj);
-  if (scm_is_true (h))
-    SCM_SETCDR (h, scm_assq_remove_x (SCM_CDR (h), prop));
-  return SCM_UNSPECIFIED;
-}
-#undef FUNC_NAME
-
-
-void
-scm_init_properties ()
-{
-  properties_whash = scm_make_weak_key_hash_table (SCM_UNDEFINED);
-#include "libguile/properties.x"
-}
-
-
-/*
-  Local Variables:
-  c-file-style: "gnu"
-  End:
-*/
diff --git a/libguile/properties.h b/libguile/properties.h
deleted file mode 100644 (file)
index efeaf3a..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/* classes: h_files */
-
-#ifndef SCM_PROPERTIES_H
-#define SCM_PROPERTIES_H
-
-/* Copyright (C) 1995,1996,1998,2000, 2006, 2008 Free Software Foundation, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 3 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-\f
-
-#include "libguile/__scm.h"
-
-SCM_API SCM scm_primitive_make_property (SCM not_found_proc);
-SCM_API SCM scm_primitive_property_ref (SCM prop, SCM obj);
-SCM_API SCM scm_primitive_property_set_x (SCM prop, SCM obj, SCM val);
-SCM_API SCM scm_primitive_property_del_x (SCM prop, SCM obj);
-
-SCM_INTERNAL void scm_init_properties (void);
-
-#endif  /* SCM_PROPERTIES_H */
-
-/*
-  Local Variables:
-  c-file-style: "gnu"
-  End:
-*/
index f706a71..83b87fd 100644 (file)
@@ -587,10 +587,18 @@ VALUE."
 ;; properties within the object itself.
 
 (define (make-object-property)
-  (let ((prop (primitive-make-property #f)))
+  (define-syntax with-mutex
+    (syntax-rules ()
+      ((_ lock exp)
+       (dynamic-wind (lambda () (lock-mutex lock))
+                     (lambda () exp)
+                     (lambda () (unlock-mutex lock))))))
+  (let ((prop (make-weak-key-hash-table))
+        (lock (make-mutex)))
     (make-procedure-with-setter
-     (lambda (obj) (primitive-property-ref prop obj))
-     (lambda (obj val) (primitive-property-set! prop obj val)))))
+     (lambda (obj) (with-mutex lock (hashq-ref prop obj)))
+     (lambda (obj val) (with-mutex lock (hashq-set! prop obj val))))))
+
 
 \f