emacs-diffs
[Top][All Lists]
Advanced

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

scratch/fcr 2a34e414a1: FCR: Rename to OClosure


From: Stefan Monnier
Subject: scratch/fcr 2a34e414a1: FCR: Rename to OClosure
Date: Fri, 31 Dec 2021 15:40:33 -0500 (EST)

branch: scratch/fcr
commit 2a34e414a17ae2787e0ac9d98777cf6a9c523df6
Author: Stefan Monnier <monnier@iro.umontreal.ca>
Commit: Stefan Monnier <monnier@iro.umontreal.ca>

    FCR: Rename to OClosure
---
 lisp/emacs-lisp/cconv.el                |   4 +-
 lisp/emacs-lisp/cl-generic.el           |  44 +++---
 lisp/emacs-lisp/cl-print.el             |   4 +-
 lisp/emacs-lisp/nadvice.el              |  26 ++--
 lisp/emacs-lisp/{fcr.el => oclosure.el} | 230 ++++++++++++++++----------------
 lisp/kmacro.el                          |   4 +-
 lisp/loadup.el                          |   2 +-
 lisp/simple.el                          |   2 +-
 test/lisp/emacs-lisp/fcr-tests.el       | 124 -----------------
 test/lisp/emacs-lisp/oclosure-tests.el  | 124 +++++++++++++++++
 10 files changed, 282 insertions(+), 282 deletions(-)

diff --git a/lisp/emacs-lisp/cconv.el b/lisp/emacs-lisp/cconv.el
index 679d8136ad..90d2157847 100644
--- a/lisp/emacs-lisp/cconv.el
+++ b/lisp/emacs-lisp/cconv.el
@@ -201,7 +201,7 @@ Returns a form where all lambdas don't have any free 
variables."
          (i 0)
          (new-env ()))
     ;; Build the "formal and actual envs" for the closure-converted function.
-    ;; Hack for FCR: `nreverse' here intends to put the captured vars
+    ;; Hack for OClosure: `nreverse' here intends to put the captured vars
     ;; in the closure such that the first one is the one that is bound
     ;; most closely.
     (dolist (fv (nreverse fvs))
@@ -604,7 +604,7 @@ places where they originally did not directly appear."
 
     (`(declare . ,_) form)              ;The args don't contain code.
 
-    (`(fcr--fix-type (ignore . ,vars) ,exp)
+    (`(oclosure--fix-type (ignore . ,vars) ,exp)
      (dolist (var vars)
        (let ((x (assq var env)))
          (pcase (cdr x)
diff --git a/lisp/emacs-lisp/cl-generic.el b/lisp/emacs-lisp/cl-generic.el
index 2700df37de..36d6276cb1 100644
--- a/lisp/emacs-lisp/cl-generic.el
+++ b/lisp/emacs-lisp/cl-generic.el
@@ -724,7 +724,7 @@ for all those different tags in the method-cache.")
                   (list (cl--generic-name generic)))
         f))))
 
-(fcr-defstruct cl--generic-nnm
+(oclosure-define cl--generic-nnm
   "Special type for `call-next-method's that just call `no-next-method'.")
 
 (defun cl-generic-call-method (generic method &optional fun)
@@ -744,7 +744,7 @@ FUN is the function that should be called when METHOD calls
                (if fun
                    (lambda (&rest cnm-args)
                      (apply fun (or cnm-args args)))
-                 (fcr-lambda (cl--generic-nnm) (&rest cnm-args)
+                 (oclosure-lambda (cl--generic-nnm) (&rest cnm-args)
                    (apply #'cl-no-next-method generic method
                           (or cnm-args args))))
                args)))))
@@ -915,7 +915,7 @@ those methods.")
 
 (defun cl--generic-isnot-nnm-p (cnm)
   "Return non-nil if CNM is the function that calls `cl-no-next-method'."
-  (not (eq (fcr-type cnm) 'cl--generic-nnm)))
+  (not (eq (oclosure-type cnm) 'cl--generic-nnm)))
 
 ;;; Define some pre-defined generic functions, used internally.
 
@@ -1279,41 +1279,41 @@ Used internally for the (major-mode MODE) context 
specializers."
                     (progn (cl-assert (null modes)) mode)
                   `(derived-mode ,mode . ,modes))))
 
-;;; Dispatch on FCR type
+;;; Dispatch on OClosure type
 
-;; It would make sense to put this into `fcr.el' except that when
-;; `fcr.el' is loaded `cl-defmethod' is not available yet.
+;; It would make sense to put this into `oclosure.el' except that when
+;; `oclosure.el' is loaded `cl-defmethod' is not available yet.
 
-(defun cl--generic-fcr-tag (name &rest _)
-  `(fcr-type ,name))
+(defun cl--generic-oclosure-tag (name &rest _)
+  `(oclosure-type ,name))
 
-(defun cl-generic--fcr-specializers (tag &rest _)
+(defun cl-generic--oclosure-specializers (tag &rest _)
   (and (symbolp tag)
        (let ((class (cl--find-class tag)))
-         (when (cl-typep class 'fcr--class)
+         (when (cl-typep class 'oclosure--class)
            (cl--class-allparents class)))))
 
-(cl-generic-define-generalizer cl-generic--fcr-generalizer
+(cl-generic-define-generalizer cl-generic--oclosure-generalizer
   ;; Give slightly higher priority than the struct specializer, so that
-  ;; for a generic function with methods dispatching structs and on FCRs,
-  ;; we first try `fcr-type' before `type-of' since `type-of' will return
-  ;; non-nil for an FCR as well.
-  51 #'cl--generic-fcr-tag
-  #'cl-generic--fcr-specializers)
-
-(cl-defmethod cl-generic-generalizers :extra "fcr-struct" (type)
-  "Support for dispatch on types defined by `fcr-defstruct'."
+  ;; for a generic function with methods dispatching structs and on OClosures,
+  ;; we first try `oclosure-type' before `type-of' since `type-of' will return
+  ;; non-nil for an OClosure as well.
+  51 #'cl--generic-oclosure-tag
+  #'cl-generic--oclosure-specializers)
+
+(cl-defmethod cl-generic-generalizers :extra "oclosure-struct" (type)
+  "Support for dispatch on types defined by `oclosure-define'."
   (or
    (when (symbolp type)
      ;; Use the "cl--struct-class*" (inlinable) functions/macros rather than
      ;; the "cl-struct-*" variants which aren't inlined, so that dispatch can
      ;; take place without requiring cl-lib.
      (let ((class (cl--find-class type)))
-       (and (cl-typep class 'fcr--class)
-            (list cl-generic--fcr-generalizer))))
+       (and (cl-typep class 'oclosure--class)
+            (list cl-generic--oclosure-generalizer))))
    (cl-call-next-method)))
 
-(cl--generic-prefill-dispatchers 0 fcr-object)
+(cl--generic-prefill-dispatchers 0 oclosure-object)
 
 ;;; Support for unloading.
 
diff --git a/lisp/emacs-lisp/cl-print.el b/lisp/emacs-lisp/cl-print.el
index 83af57fd9b..0131913a06 100644
--- a/lisp/emacs-lisp/cl-print.el
+++ b/lisp/emacs-lisp/cl-print.el
@@ -221,11 +221,11 @@ into a button whose action shows the function's 
disassembly.")
                             'byte-code-function object)))))
   (princ ")" stream))
 
-;; This belongs in fcr.el, of course, but some load-ordering issues make it
+;; This belongs in oclosure.el, of course, but some load-ordering issues make 
it
 ;; complicated.
 (cl-defmethod cl-print-object ((object accessor) stream)
   ;; FIXME: η-reduce!
-  (fcr--accessor-cl-print object stream))
+  (oclosure--accessor-cl-print object stream))
 
 (cl-defmethod cl-print-object ((object cl-structure-object) stream)
   (if (and cl-print--depth (natnump print-level)
diff --git a/lisp/emacs-lisp/nadvice.el b/lisp/emacs-lisp/nadvice.el
index 4aeb41d4f2..789431cb35 100644
--- a/lisp/emacs-lisp/nadvice.el
+++ b/lisp/emacs-lisp/nadvice.el
@@ -42,39 +42,39 @@
 ;; as this one), so we have to do it by hand!
 (push (purecopy '(nadvice 1 0)) package--builtin-versions)
 
-(fcr-defstruct (advice
+(oclosure-define (advice
                 (:copier advice--cons (cdr))
                 (:copier advice--copy (car cdr where props)))
   car cdr where props)
 
 ;;;; Lightweight advice/hook
 (defvar advice--where-alist
-  `((:around ,(fcr-lambda (advice (where :around)) (&rest args)
+  `((:around ,(oclosure-lambda (advice (where :around)) (&rest args)
                 (apply car cdr args)))
-    (:before ,(fcr-lambda (advice (where :before)) (&rest args)
+    (:before ,(oclosure-lambda (advice (where :before)) (&rest args)
                 (apply car args) (apply cdr args)))
-    (:after ,(fcr-lambda (advice (where :after)) (&rest args)
+    (:after ,(oclosure-lambda (advice (where :after)) (&rest args)
                (apply cdr args) (apply car args)))
-    (:override ,(fcr-lambda (advice (where :override)) (&rest args)
+    (:override ,(oclosure-lambda (advice (where :override)) (&rest args)
                   (apply car args)))
-    (:after-until ,(fcr-lambda (advice (where :after-until)) (&rest args)
+    (:after-until ,(oclosure-lambda (advice (where :after-until)) (&rest args)
                      (or (apply cdr args) (apply car args))))
-    (:after-while ,(fcr-lambda (advice (where :after-while)) (&rest args)
+    (:after-while ,(oclosure-lambda (advice (where :after-while)) (&rest args)
                      (and (apply cdr args) (apply car args))))
-    (:before-until ,(fcr-lambda (advice (where :before-until)) (&rest args)
+    (:before-until ,(oclosure-lambda (advice (where :before-until)) (&rest 
args)
                      (or (apply car args) (apply cdr args))))
-    (:before-while ,(fcr-lambda (advice (where :before-while)) (&rest args)
+    (:before-while ,(oclosure-lambda (advice (where :before-while)) (&rest 
args)
                      (and (apply car args) (apply cdr args))))
-    (:filter-args ,(fcr-lambda (advice (where :filter-args)) (&rest args)
+    (:filter-args ,(oclosure-lambda (advice (where :filter-args)) (&rest args)
                      (apply cdr (funcall car args))))
-    (:filter-return ,(fcr-lambda (advice (where :filter-return)) (&rest args)
+    (:filter-return ,(oclosure-lambda (advice (where :filter-return)) (&rest 
args)
                        (funcall car (apply cdr args)))))
   "List of descriptions of how to add a function.
-Each element has the form (WHERE FCR) where FCR is a \"prototype\"
+Each element has the form (WHERE OCL) where OCL is a \"prototype\"
 function of type `advice'.")
 
 (defun advice--p (object)
-  ;; (eq (fcr-type object) 'advice)
+  ;; (eq (oclosure-type object) 'advice)
   (cl-typep object 'advice))
 
 (defun advice--cd*r (f)
diff --git a/lisp/emacs-lisp/fcr.el b/lisp/emacs-lisp/oclosure.el
similarity index 74%
rename from lisp/emacs-lisp/fcr.el
rename to lisp/emacs-lisp/oclosure.el
index f4be4fcc10..8fde69a2b0 100644
--- a/lisp/emacs-lisp/fcr.el
+++ b/lisp/emacs-lisp/oclosure.el
@@ -1,4 +1,4 @@
-;;; fcr.el --- FunCallableRecords       -*- lexical-binding: t; -*-
+;;; oclosure.el --- Open Closures       -*- lexical-binding: t; -*-
 
 ;; Copyright (C) 2015, 2021  Stefan Monnier
 
@@ -20,19 +20,19 @@
 
 ;;; Commentary:
 
-;; A FunCallableRecord is an object that combines the properties of records
+;; A OClosure is an object that combines the properties of records
 ;; with those of a function.  More specifically it is a function extended
 ;; with a notion of type (e.g. for defmethod dispatch) as well as the
 ;; ability to have some fields that are accessible from the outside.
 
-;; Here are some cases of "callable objects" where FCRs are used:
+;; Here are some cases of "callable objects" where OClosures are used:
 ;; - nadvice.el
 ;; - kmacros (for cl-print and for `kmacro-extract-lambda')
 ;; - cl-generic: turn `cl--generic-isnot-nnm-p' into a mere type test
 ;;   (by putting the no-next-methods into their own class).
-;; - FCR accessor functions, where the type-dispatch is used to
+;; - OClosure accessor functions, where the type-dispatch is used to
 ;;   dynamically compute the docstring, and also to pretty them.
-;; Here are other cases of "callable objects" where FCRs could be used:
+;; Here are other cases of "callable objects" where OClosures could be used:
 ;; - iterators (generator.el), thunks (thunk.el), streams (stream.el).
 ;; - PEG rules: they're currently just functions, but they should carry
 ;;   their original (macro-expanded) definition (and should be printed
@@ -52,29 +52,29 @@
 ;;   (negate f) generally returns (lambda (x) (not (f x)))
 ;;   but it can optimize (negate (negate f)) to f and (negate #'<) to
 ;;   #'>=.
-;; - Autoloads (tho currently our bytecode functions (and hence FCRs)
+;; - Autoloads (tho currently our bytecode functions (and hence OClosures)
 ;;   are too fat for that).
 
 ;; Related constructs:
 ;; - `funcallable-standard-object' (FSO) in Common-Lisp.  These are different
-;;   from FCRs in that they involve an additional indirection to get
+;;   from OClosures in that they involve an additional indirection to get
 ;;   to the actual code, and that they offer the possibility of
 ;;   changing (via mutation) the code associated with
 ;;   an FSO.  Also the FSO's function can't directly access the FSO's
-;;   other fields, contrary to the case with FCRs where those are directly
+;;   other fields, contrary to the case with OClosures where those are directly
 ;;   available as local variables.
 ;; - Function objects in Javascript.
 ;; - Function objects in Python.
 ;; - Callable/Applicable classes in OO languages, i.e. classes with
 ;;   a single method called `apply' or `call'.  The most obvious
-;;   difference with FCRs (beside the fact that Callable can be
+;;   difference with OClosures (beside the fact that Callable can be
 ;;   extended with additional methods) is that all instances of
 ;;   a given Callable class have to use the same method, whereas every
-;;   FCR object comes with its own code, so two FCR objects of the
+;;   OClosure object comes with its own code, so two OClosure objects of the
 ;;   same type can have different code.  Of course, you can get the
-;;   same result by turning every `fcr-lambda' into its own class
+;;   same result by turning every `oclosure-lambda' into its own class
 ;;   declaration creating an ad-hoc subclass of the specified type.
-;;   In this sense, FCRs are just a generalization of `lambda' which brings
+;;   In this sense, OClosures are just a generalization of `lambda' which 
brings
 ;;   some of the extra feature of Callable objects.
 ;; - Apply hooks and "entities" in MIT Scheme
 ;;   
https://www.gnu.org/software/mit-scheme/documentation/stable/mit-scheme-ref/Application-Hooks.html
@@ -82,14 +82,14 @@
 ;;   are a variant of it where the inner function gets the FSO itself as
 ;;   additional argument (a kind of "self" arg), thus making it easier
 ;;   for the code to get data from the object's extra info, tho still
-;;   not as easy as with FCRs.
+;;   not as easy as with OClosures.
 ;; - "entities" in Lisp Machine Lisp (LML)
 ;;   https://hanshuebner.github.io/lmman/fd-clo.xml
-;;   These are arguably identical to FCRs, modulo the fact that LML doesn't
+;;   These are arguably identical to OClosures, modulo the fact that LML 
doesn't
 ;;   have lexically-scoped closures and uses a form of closures based on
 ;;   capturing (and reinstating) dynamically scoped bindings instead.
 
-;; Naming: to replace "FCR" we could go with
+;; Naming: to replace "OClosure" we could go with
 ;; - open closures
 ;; - disclosures
 ;; - opening
@@ -107,39 +107,39 @@
 ;;   to perform store-conversion on the variable, so we'd either have
 ;;   to prevent cconv from doing it (which might require a new bytecode op
 ;;   to update the in-closure variable), or we'd have to keep track of which
-;;   slots have been store-converted so `fcr--get' can access their value
+;;   slots have been store-converted so `oclosure--get' can access their value
 ;;   correctly.
 ;; - If the mutated variable/slot is captured by another (nested) closure
 ;;   store-conversion is indispensable, so if we want to avoid store-conversion
 ;;   we'd have to disallow such capture.
 
 ;; TODO:
-;; - `fcr-cl-defun', `fcr-cl-defsubst', `fcr-defsubst', `fcr-define-inline'?
+;; - `oclosure-cl-defun', `oclosure-cl-defsubst', `oclosure-defsubst', 
`oclosure-define-inline'?
 ;; - Use accessor in cl-defstruct
-;; - Add pcase patterns for FCRs.
+;; - Add pcase patterns for OClosures.
 
 (eval-when-compile (require 'cl-lib))
 (eval-when-compile (require 'subr-x))   ;For `named-let'.
 
-(cl-defstruct (fcr--class
+(cl-defstruct (oclosure--class
                (:constructor nil)
-               (:constructor fcr--class-make ( name docstring slots parents
+               (:constructor oclosure--class-make ( name docstring slots 
parents
                                                allparents))
                (:include cl--class)
                (:copier nil))
-  "Metaclass for FunCallableRecord classes."
+  "Metaclass for OClosure classes."
   (allparents nil :read-only t :type (list-of symbol)))
 
-(setf (cl--find-class 'fcr-object)
-      (fcr--class-make 'fcr-object "The root parent of all FCR classes"
-                       nil nil '(fcr-object)))
-(defun fcr--object-p (fcr)
-  (let ((type (fcr-type fcr)))
+(setf (cl--find-class 'oclosure-object)
+      (oclosure--class-make 'oclosure-object "The root parent of all OClosure 
classes"
+                       nil nil '(oclosure-object)))
+(defun oclosure--object-p (oclosure)
+  (let ((type (oclosure-type oclosure)))
     (when type
-      (memq 'fcr-object (fcr--class-allparents (cl--find-class type))))))
-(cl-deftype fcr-object () '(satisfies fcr--object-p))
+      (memq 'oclosure-object (oclosure--class-allparents (cl--find-class 
type))))))
+(cl-deftype oclosure-object () '(satisfies oclosure--object-p))
 
-(defun fcr--defstruct-make-copiers (copiers slotdescs name)
+(defun oclosure--defstruct-make-copiers (copiers slotdescs name)
   (require 'cl-macs)            ;`cl--arglist-args' is not autoloaded.
   (let* ((mutables '())
          (slots (mapcar
@@ -175,7 +175,7 @@
              (lambda (slot)
                (setq index (1+ index))
                (let* ((mutable (memq slot mutables))
-                      (get `(fcr--get ,obj ,index ,(not (not mutable)))))
+                      (get `(oclosure--get ,obj ,index ,(not (not mutable)))))
                  (push mutable mutlist)
                  (cond
                   ((not (memq slot anames)) get)
@@ -188,11 +188,11 @@
         `(cl-defun ,cname (&cl-defs (',absent) ,obj ,@args)
             ,doc
             (declare (side-effect-free t))
-            (fcr--copy ,obj ',(if (remq nil mutlist) (nreverse mutlist))
+            (oclosure--copy ,obj ',(if (remq nil mutlist) (nreverse mutlist))
                        ,@argvals))))
      copiers)))
 
-(defmacro fcr-defstruct (name &optional docstring &rest slots)
+(defmacro oclosure-define (name &optional docstring &rest slots)
   (declare (doc-string 2) (indent 1))
   (unless (stringp docstring)
     (push docstring slots)
@@ -215,7 +215,7 @@
 
          (parent-names (or (or (funcall get-opt :parent)
                                (funcall get-opt :include))
-                           '(fcr-object)))
+                           '(oclosure-object)))
          (copiers (funcall get-opt :copier 'all))
 
          (parent-slots '())
@@ -266,7 +266,7 @@
                    slots)))
          (allparents (apply #'append (mapcar #'cl--class-allparents
                                              parents)))
-         (class (fcr--class-make name docstring slotdescs parents
+         (class (oclosure--class-make name docstring slotdescs parents
                                  (delete-dups
                                   (cons name allparents))))
          (it (make-hash-table :test #'eq)))
@@ -276,11 +276,11 @@
                        (format "Ignored options: %S" options)
                        nil))
        (eval-and-compile
-         (fcr--define ',class
-                      (lambda (fcr)
-                        (let ((type (fcr-type fcr)))
+         (oclosure--define ',class
+                      (lambda (oclosure)
+                        (let ((type (oclosure-type oclosure)))
                           (when type
-                            (memq ',name (fcr--class-allparents
+                            (memq ',name (oclosure--class-allparents
                                           (cl--find-class type))))))))
        ,@(let ((i -1))
            (mapcar (lambda (desc)
@@ -297,40 +297,40 @@
                        (setf (gethash slot it) i)
                        (if (not mutable)
                            `(defalias ',name
-                              ;; We use `fcr--copy' instead of
-                              ;; `fcr--accessor-copy' here to circumvent
+                              ;; We use `oclosure--copy' instead of
+                              ;; `oclosure--accessor-copy' here to circumvent
                               ;; bootstrapping problems.
-                              (fcr--copy fcr--accessor-prototype nil
+                              (oclosure--copy oclosure--accessor-prototype nil
                                          ',name ',slot ,i))
                          `(progn
                             (defalias ',name
-                              (fcr--accessor-copy
-                               fcr--mut-getter-prototype
+                              (oclosure--accessor-copy
+                               oclosure--mut-getter-prototype
                                ',name ',slot ,i))
                             (defalias ',(gv-setter name)
-                              (fcr--accessor-copy
-                               fcr--mut-setter-prototype
+                              (oclosure--accessor-copy
+                               oclosure--mut-setter-prototype
                                ',name ',slot ,i))))))
                    slotdescs))
-       ,@(fcr--defstruct-make-copiers
+       ,@(oclosure--defstruct-make-copiers
           copiers slotdescs name))))
 
-(defun fcr--define (class pred)
+(defun oclosure--define (class pred)
   (let* ((name (cl--class-name class))
-         (predname (intern (format "fcr--%s-p" name))))
+         (predname (intern (format "oclosure--%s-p" name))))
     (setf (cl--find-class name) class)
     (defalias predname pred)
     (put name 'cl-deftype-satisfies predname)))
 
-(defmacro fcr--lambda (type bindings mutables args &rest body)
-  "Low level construction of an FCR object.
-TYPE is expected to be a symbol that is (or will be) defined as an FCR type.
+(defmacro oclosure--lambda (type bindings mutables args &rest body)
+  "Low level construction of an OClosure object.
+TYPE is expected to be a symbol that is (or will be) defined as an OClosure 
type.
 BINDINGS should list all the slots expected by this type, in the proper order.
 MUTABLE is a list of symbols indicating which of the BINDINGS
 should be mutable.
 No checking is performed,"
   (declare (indent 3) (debug (sexp (&rest (sexp form)) sexp def-body)))
-  ;; FIXME: Fundamentally `fcr-lambda' should be a special form.
+  ;; FIXME: Fundamentally `oclosure-lambda' should be a special form.
   ;; We define it here as a macro which expands to something that
   ;; looks like "normal code" in order to avoid backward compatibility
   ;; issues with third party macros that do "code walks" and would
@@ -339,7 +339,7 @@ No checking is performed,"
   (pcase-let*
       ;; FIXME: Since we use the docstring internally to store the
       ;; type we can't handle actual docstrings.  We could fix this by adding
-      ;; a docstring slot to FCRs.
+      ;; a docstring slot to OClosures.
       ((`(,prebody . ,body) (macroexp-parse-body body))
        (rovars (mapcar #'car bindings)))
     (dolist (mutable mutables)
@@ -354,8 +354,8 @@ No checking is performed,"
        ;; FIXME: Make sure the slotbinds whose value is duplicable aren't
        ;; just value/variable-propagated by the optimizer (tho I think our
        ;; optimizer is too naive to be a problem currently).
-       (fcr--fix-type
-        ;; This `fcr--fix-type' + `ignore' call is used by the compiler (in
+       (oclosure--fix-type
+        ;; This `oclosure--fix-type' + `ignore' call is used by the compiler 
(in
         ;; `cconv.el') to detect and signal an error in case of
         ;; store-conversion (i.e. if a variable/slot is mutated).
         (ignore ,@rovars)
@@ -367,20 +367,20 @@ No checking is performed,"
           (if t nil ,@rovars ,@(mapcar (lambda (m) `(setq ,m ,m)) mutables))
           ,@body)))))
 
-(defmacro fcr-lambda (type-and-slots args &rest body)
-  "Define anonymous FCR function.
+(defmacro oclosure-lambda (type-and-slots args &rest body)
+  "Define anonymous OClosure function.
 TYPE-AND-SLOTS should be of the form (TYPE . SLOTS)
-where TYPE is an FCR type name and
+where TYPE is an OClosure type name and
 SLOTS is a let-style list of bindings for the various slots of TYPE.
 ARGS and BODY are the same as for `lambda'."
   (declare (indent 2) (debug ((sexp &rest (sexp form)) sexp def-body)))
-  ;; FIXME: Should `fcr-defstruct' distinguish "optional" from
+  ;; FIXME: Should `oclosure-define' distinguish "optional" from
   ;; "mandatory" slots, and/or provide default values for slots missing
   ;; from `fields'?
   (pcase-let*
       ((`(,type . ,fields) type-and-slots)
        (class (cl--find-class type))
-       (slots (fcr--class-slots class))
+       (slots (oclosure--class-slots class))
        (mutables '())
        (slotbinds (mapcar (lambda (slot)
                             (let ((name (cl--slot-descriptor-name slot))
@@ -405,35 +405,35 @@ ARGS and BODY are the same as for `lambda'."
                    fields)))
     ;; FIXME: Optimize temps away when they're provided in the right order?
     `(let ,tempbinds
-       (fcr--lambda ,type ,slotbinds ,mutables ,args ,@body))))
+       (oclosure--lambda ,type ,slotbinds ,mutables ,args ,@body))))
 
-(defun fcr--fix-type (_ignore fcr)
-  (if (byte-code-function-p fcr)
+(defun oclosure--fix-type (_ignore oclosure)
+  (if (byte-code-function-p oclosure)
       ;; Actually, this should never happen since the `cconv.el' should have
       ;; optimized away the call to this function.
-      fcr
+      oclosure
     ;; For byte-coded functions, we store the type as a symbol in the docstring
     ;; slot.  For interpreted functions, there's no specific docstring slot
     ;; so `Ffunction' turns the symbol into a string.
     ;; We thus have convert it back into a symbol (via `intern') and then
     ;; stuff it into the environment part of the closure with a special
     ;; marker so we can distinguish this entry from actual variables.
-    (cl-assert (eq 'closure (car-safe fcr)))
-    (let ((typename (nth 3 fcr))) ;; The "docstring".
+    (cl-assert (eq 'closure (car-safe oclosure)))
+    (let ((typename (nth 3 oclosure))) ;; The "docstring".
       (cl-assert (stringp typename))
       (push (cons :type (intern typename))
-            (cadr fcr))
-      fcr)))
+            (cadr oclosure))
+      oclosure)))
 
-(defun fcr--copy (fcr mutlist &rest args)
-  (if (byte-code-function-p fcr)
-      (apply #'make-closure fcr
+(defun oclosure--copy (oclosure mutlist &rest args)
+  (if (byte-code-function-p oclosure)
+      (apply #'make-closure oclosure
              (if (null mutlist)
                  args
                (mapcar (lambda (arg) (if (pop mutlist) (list arg) arg)) args)))
-    (cl-assert (eq 'closure (car-safe fcr)))
-    (cl-assert (eq :type (caar (cadr fcr))))
-    (let ((env (cadr fcr)))
+    (cl-assert (eq 'closure (car-safe oclosure)))
+    (cl-assert (eq :type (caar (cadr oclosure))))
+    (let ((env (cadr oclosure)))
       `(closure
            (,(car env)
             ,@(named-let loop ((env (cdr env)) (args args))
@@ -441,74 +441,74 @@ ARGS and BODY are the same as for `lambda'."
                   (cons (cons (caar env) (car args))
                         (loop (cdr env) (cdr args)))))
             ,@(nthcdr (1+ (length args)) env))
-           ,@(nthcdr 2 fcr)))))
+           ,@(nthcdr 2 oclosure)))))
 
-(defun fcr--get (fcr index mutable)
-  (if (byte-code-function-p fcr)
-      (let* ((csts (aref fcr 2))
+(defun oclosure--get (oclosure index mutable)
+  (if (byte-code-function-p oclosure)
+      (let* ((csts (aref oclosure 2))
              (v (aref csts index)))
         (if mutable (car v) v))
-    (cl-assert (eq 'closure (car-safe fcr)))
-    (cl-assert (eq :type (caar (cadr fcr))))
-    (cdr (nth (1+ index) (cadr fcr)))))
+    (cl-assert (eq 'closure (car-safe oclosure)))
+    (cl-assert (eq :type (caar (cadr oclosure))))
+    (cdr (nth (1+ index) (cadr oclosure)))))
 
-(defun fcr--set (v fcr index)
-  (if (byte-code-function-p fcr)
-      (let* ((csts (aref fcr 2))
+(defun oclosure--set (v oclosure index)
+  (if (byte-code-function-p oclosure)
+      (let* ((csts (aref oclosure 2))
              (cell (aref csts index)))
         (setcar cell v))
-    (cl-assert (eq 'closure (car-safe fcr)))
-    (cl-assert (eq :type (caar (cadr fcr))))
-    (setcdr (nth (1+ index) (cadr fcr)) v)))
-
-(defun fcr-type (fcr)
-  "Return the type of FCR, or nil if the arg is not a FunCallableRecord."
-  (if (byte-code-function-p fcr)
-      (let ((type (and (> (length fcr) 4) (aref fcr 4))))
+    (cl-assert (eq 'closure (car-safe oclosure)))
+    (cl-assert (eq :type (caar (cadr oclosure))))
+    (setcdr (nth (1+ index) (cadr oclosure)) v)))
+
+(defun oclosure-type (oclosure)
+  "Return the type of OCLOSURE, or nil if the arg is not a OClosure."
+  (if (byte-code-function-p oclosure)
+      (let ((type (and (> (length oclosure) 4) (aref oclosure 4))))
         (if (symbolp type) type))
-    (and (eq 'closure (car-safe fcr))
-         (let* ((env (car-safe (cdr fcr)))
+    (and (eq 'closure (car-safe oclosure))
+         (let* ((env (car-safe (cdr oclosure)))
                 (first-var (car-safe env)))
            (and (eq :type (car-safe first-var))
                 (cdr first-var))))))
 
-(defconst fcr--accessor-prototype
-  ;; Use `fcr--lambda' to circumvent a bootstrapping problem:
-  ;; `fcr-accessor' is not yet defined at this point but
-  ;; `fcr--accessor-prototype' is needed when defining `fcr-accessor'.
-  (fcr--lambda fcr-accessor ((type) (slot) (index)) nil
-    (fcr) (fcr--get fcr index nil)))
+(defconst oclosure--accessor-prototype
+  ;; Use `oclosure--lambda' to circumvent a bootstrapping problem:
+  ;; `oclosure-accessor' is not yet defined at this point but
+  ;; `oclosure--accessor-prototype' is needed when defining 
`oclosure-accessor'.
+  (oclosure--lambda oclosure-accessor ((type) (slot) (index)) nil
+    (oclosure) (oclosure--get oclosure index nil)))
 
-(fcr-defstruct accessor
-  "FCR function to access a specific slot of an object."
+(oclosure-define accessor
+  "OClosure function to access a specific slot of an object."
   type slot)
 
-(defun fcr--accessor-cl-print (object stream)
+(defun oclosure--accessor-cl-print (object stream)
   (princ "#f(accessor " stream)
   (prin1 (accessor--type object) stream)
   (princ "." stream)
   (prin1 (accessor--slot object) stream)
   (princ ")" stream))
 
-(defun fcr--accessor-docstring (f)
+(defun oclosure--accessor-docstring (f)
   (format "Access slot \"%S\" of OBJ of type `%S'.
 
 \(fn OBJ)"
           (accessor--slot f) (accessor--type f)))
 
-(fcr-defstruct (fcr-accessor
+(oclosure-define (oclosure-accessor
                 (:parent accessor)
-                (:copier fcr--accessor-copy (type slot index)))
-  "FCR function to access a specific slot of an FCR function."
+                (:copier oclosure--accessor-copy (type slot index)))
+  "OClosure function to access a specific slot of an OClosure function."
   index)
 
-(defconst fcr--mut-getter-prototype
-  (fcr-lambda (fcr-accessor (type) (slot) (index)) (fcr)
-    (fcr--get fcr index t)))
-(defconst fcr--mut-setter-prototype
+(defconst oclosure--mut-getter-prototype
+  (oclosure-lambda (oclosure-accessor (type) (slot) (index)) (oclosure)
+    (oclosure--get oclosure index t)))
+(defconst oclosure--mut-setter-prototype
   ;; FIXME: The generated docstring is wrong.
-  (fcr-lambda (fcr-accessor (type) (slot) (index)) (val fcr)
-    (fcr--set val fcr index)))
+  (oclosure-lambda (oclosure-accessor (type) (slot) (index)) (val oclosure)
+    (oclosure--set val oclosure index)))
 
-(provide 'fcr)
-;;; fcr.el ends here
+(provide 'oclosure)
+;;; oclosure.el ends here
diff --git a/lisp/kmacro.el b/lisp/kmacro.el
index 8311c43404..54ad779d4a 100644
--- a/lisp/kmacro.el
+++ b/lisp/kmacro.el
@@ -362,7 +362,7 @@ information."
 
 ;;; Keyboard macro ring
 
-(fcr-defstruct kmacro
+(oclosure-define kmacro
   "Keyboard macro."
   keys (counter :mutable t) format)
 
@@ -815,7 +815,7 @@ If kbd macro currently being defined end it before 
activating it."
 ;;;###autoload
 (defun kmacro (keys &optional counter format)
   "Create a `kmacro' for macro bound to symbol or key."
-  (fcr-lambda (kmacro (keys (if (stringp keys) (key-parse keys) keys))
+  (oclosure-lambda (kmacro (keys (if (stringp keys) (key-parse keys) keys))
                       (counter (or counter 0))
                       (format (or format "%d")))
       (&optional arg)
diff --git a/lisp/loadup.el b/lisp/loadup.el
index f02dcd6788..154f831ead 100644
--- a/lisp/loadup.el
+++ b/lisp/loadup.el
@@ -196,7 +196,7 @@
 
 (load "button")                  ;After loaddefs, because of define-minor-mode!
 (load "emacs-lisp/cl-preloaded")
-(load "emacs-lisp/fcr")          ;Used by cl-generic and nadvice
+(load "emacs-lisp/oclosure")          ;Used by cl-generic and nadvice
 (load "obarray")        ;abbrev.el is implemented in terms of obarrays.
 (load "abbrev")         ;lisp-mode.el and simple.el use define-abbrev-table.
 (load "help")
diff --git a/lisp/simple.el b/lisp/simple.el
index f8d963fd01..d7576a7c03 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -2350,7 +2350,7 @@ FUNCTION is expected to be a function value rather than, 
say, a mere symbol."
 
 (cl-defmethod function-docstring ((function accessor))
   ;; FIXME: η-reduce!
-  (fcr--accessor-docstring function))
+  (oclosure--accessor-docstring function))
 
 (cl-defgeneric interactive-form (cmd &optional original-name)
   "Return the interactive form of CMD or nil if none.
diff --git a/test/lisp/emacs-lisp/fcr-tests.el 
b/test/lisp/emacs-lisp/fcr-tests.el
deleted file mode 100644
index 19aba3329d..0000000000
--- a/test/lisp/emacs-lisp/fcr-tests.el
+++ /dev/null
@@ -1,124 +0,0 @@
-;;; fcr-tests.e; --- Tests for FunCallableRecords  -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2021 Free Software Foundation, Inc.
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs 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 General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
-
-;;; Code:
-
-(require 'ert)
-(require 'fcr)
-(require 'cl-lib)
-
-(fcr-defstruct (fcr-test
-                (:copier fcr-test-copy)
-                (:copier fcr-test-copy1 (fst)))
-  "Simple FCR."
-  fst snd name)
-
-(cl-defmethod fcr-test-gen ((_x compiled-function)) "#<bytecode>")
-
-(cl-defmethod fcr-test-gen ((_x cons)) "#<cons>")
-
-(cl-defmethod fcr-test-gen ((_x fcr-object))
-  (format "#<fcr:%s>" (cl-call-next-method)))
-
-(cl-defmethod fcr-test-gen ((_x fcr-test))
-  (format "#<fcr-test:%s>" (cl-call-next-method)))
-
-(ert-deftest fcr-tests ()
-  (let* ((i 42)
-         (fcr1 (fcr-lambda (fcr-test (fst 1) (snd 2) (name "hi"))
-                   ()
-                 (list fst snd i)))
-         (fcr2 (fcr-lambda (fcr-test (name (cl-incf i)) (fst (cl-incf i)))
-                   ()
-                 (list fst snd 152 i))))
-    (should (equal (list (fcr-test--fst fcr1)
-                         (fcr-test--snd fcr1)
-                         (fcr-test--name fcr1))
-                   '(1 2 "hi")))
-    (should (equal (list (fcr-test--fst fcr2)
-                         (fcr-test--snd fcr2)
-                         (fcr-test--name fcr2))
-                   '(44 nil 43)))
-    (should (equal (funcall fcr1) '(1 2 44)))
-    (should (equal (funcall fcr2) '(44 nil 152 44)))
-    (should (equal (funcall (fcr-test-copy fcr1 :fst 7)) '(7 2 44)))
-    (should (equal (funcall (fcr-test-copy1 fcr1 9)) '(9 2 44)))
-    (should (cl-typep fcr1 'fcr-test))
-    (should (cl-typep fcr1 'fcr-object))
-    (should (member (fcr-test-gen fcr1)
-                    '("#<fcr-test:#<fcr:#<cons>>>"
-                      "#<fcr-test:#<fcr:#<bytecode>>>")))
-    ))
-
-(ert-deftest fcr-tests--limits ()
-  (should
-   (condition-case err
-       (let ((lexical-binding t)
-             (byte-compile-debug t))
-         (byte-compile '(lambda ()
-                          (let ((inc-where nil))
-                            (fcr-lambda (advice (where 'foo)) ()
-                              (setq inc-where (lambda () (setq where (1+ 
where))))
-                              where))))
-         nil)
-     (error
-      (and (eq 'error (car err))
-           (string-match "where.*mutated" (cadr err))))))
-  (should
-   (condition-case err
-       (progn (macroexpand '(fcr-defstruct fcr--foo a a))
-              nil)
-     (error
-      (and (eq 'error (car err))
-           (string-match "Duplicate slot name: a$" (cadr err))))))
-  (should
-   (condition-case err
-       (progn (macroexpand '(fcr-defstruct (fcr--foo (:parent advice)) where))
-              nil)
-     (error
-      (and (eq 'error (car err))
-           (string-match "Duplicate slot name: where$" (cadr err))))))
-  (should
-   (condition-case err
-       (progn (macroexpand '(fcr-lambda (advice (where 1) (where 2)) () where))
-              nil)
-     (error
-      (and (eq 'error (car err))
-           (string-match "Duplicate slot: where$" (cadr err)))))))
-
-(fcr-defstruct (fcr-test-mut
-                (:parent fcr-test)
-                (:copier fcr-test-mut-copy))
-  "Simple FCR with a mutable field."
-  (mut :mutable t))
-
-(ert-deftest fcr-test--mutate ()
-  (let* ((f (fcr-lambda (fcr-test-mut (fst 0) (mut 3))
-                (x)
-              (+ x fst mut)))
-         (f2 (fcr-test-mut-copy f :fst 50)))
-    (should (equal (fcr-test-mut--mut f) 3))
-    (should (equal (funcall f 5) 8))
-    (should (equal (funcall f2 5) 58))
-    (cl-incf (fcr-test-mut--mut f) 7)
-    (should (equal (fcr-test-mut--mut f) 10))
-    (should (equal (funcall f 5) 15))
-    (should (equal (funcall f2 15) 68))))
-
-;;; fcr-tests.el ends here.
diff --git a/test/lisp/emacs-lisp/oclosure-tests.el 
b/test/lisp/emacs-lisp/oclosure-tests.el
new file mode 100644
index 0000000000..0a256a5baa
--- /dev/null
+++ b/test/lisp/emacs-lisp/oclosure-tests.el
@@ -0,0 +1,124 @@
+;;; oclosure-tests.e; --- Tests for Open Closures  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs 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 General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'ert)
+(require 'oclosure)
+(require 'cl-lib)
+
+(oclosure-define (oclosure-test
+                (:copier oclosure-test-copy)
+                (:copier oclosure-test-copy1 (fst)))
+  "Simple OClosure."
+  fst snd name)
+
+(cl-defmethod oclosure-test-gen ((_x compiled-function)) "#<bytecode>")
+
+(cl-defmethod oclosure-test-gen ((_x cons)) "#<cons>")
+
+(cl-defmethod oclosure-test-gen ((_x oclosure-object))
+  (format "#<oclosure:%s>" (cl-call-next-method)))
+
+(cl-defmethod oclosure-test-gen ((_x oclosure-test))
+  (format "#<oclosure-test:%s>" (cl-call-next-method)))
+
+(ert-deftest oclosure-tests ()
+  (let* ((i 42)
+         (ocl1 (oclosure-lambda (oclosure-test (fst 1) (snd 2) (name "hi"))
+                   ()
+                 (list fst snd i)))
+         (ocl2 (oclosure-lambda (oclosure-test (name (cl-incf i)) (fst 
(cl-incf i)))
+                   ()
+                 (list fst snd 152 i))))
+    (should (equal (list (oclosure-test--fst ocl1)
+                         (oclosure-test--snd ocl1)
+                         (oclosure-test--name ocl1))
+                   '(1 2 "hi")))
+    (should (equal (list (oclosure-test--fst ocl2)
+                         (oclosure-test--snd ocl2)
+                         (oclosure-test--name ocl2))
+                   '(44 nil 43)))
+    (should (equal (funcall ocl1) '(1 2 44)))
+    (should (equal (funcall ocl2) '(44 nil 152 44)))
+    (should (equal (funcall (oclosure-test-copy ocl1 :fst 7)) '(7 2 44)))
+    (should (equal (funcall (oclosure-test-copy1 ocl1 9)) '(9 2 44)))
+    (should (cl-typep ocl1 'oclosure-test))
+    (should (cl-typep ocl1 'oclosure-object))
+    (should (member (oclosure-test-gen ocl1)
+                    '("#<oclosure-test:#<oclosure:#<cons>>>"
+                      "#<oclosure-test:#<oclosure:#<bytecode>>>")))
+    ))
+
+(ert-deftest oclosure-tests--limits ()
+  (should
+   (condition-case err
+       (let ((lexical-binding t)
+             (byte-compile-debug t))
+         (byte-compile '(lambda ()
+                          (let ((inc-where nil))
+                            (oclosure-lambda (advice (where 'foo)) ()
+                              (setq inc-where (lambda () (setq where (1+ 
where))))
+                              where))))
+         nil)
+     (error
+      (and (eq 'error (car err))
+           (string-match "where.*mutated" (cadr err))))))
+  (should
+   (condition-case err
+       (progn (macroexpand '(oclosure-define oclosure--foo a a))
+              nil)
+     (error
+      (and (eq 'error (car err))
+           (string-match "Duplicate slot name: a$" (cadr err))))))
+  (should
+   (condition-case err
+       (progn (macroexpand '(oclosure-define (oclosure--foo (:parent advice)) 
where))
+              nil)
+     (error
+      (and (eq 'error (car err))
+           (string-match "Duplicate slot name: where$" (cadr err))))))
+  (should
+   (condition-case err
+       (progn (macroexpand '(oclosure-lambda (advice (where 1) (where 2)) () 
where))
+              nil)
+     (error
+      (and (eq 'error (car err))
+           (string-match "Duplicate slot: where$" (cadr err)))))))
+
+(oclosure-define (oclosure-test-mut
+                (:parent oclosure-test)
+                (:copier oclosure-test-mut-copy))
+  "Simple OClosure with a mutable field."
+  (mut :mutable t))
+
+(ert-deftest oclosure-test--mutate ()
+  (let* ((f (oclosure-lambda (oclosure-test-mut (fst 0) (mut 3))
+                (x)
+              (+ x fst mut)))
+         (f2 (oclosure-test-mut-copy f :fst 50)))
+    (should (equal (oclosure-test-mut--mut f) 3))
+    (should (equal (funcall f 5) 8))
+    (should (equal (funcall f2 5) 58))
+    (cl-incf (oclosure-test-mut--mut f) 7)
+    (should (equal (oclosure-test-mut--mut f) 10))
+    (should (equal (funcall f 5) 15))
+    (should (equal (funcall f2 15) 68))))
+
+;;; oclosure-tests.el ends here.



reply via email to

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