* Creating recursive customization types / widgets @ 2003-11-29 16:38 Per Abrahamsen 2003-11-29 18:34 ` Per Abrahamsen ` (2 more replies) 0 siblings, 3 replies; 24+ messages in thread From: Per Abrahamsen @ 2003-11-29 16:38 UTC (permalink / raw) Creating new widgets from existing customization type specifications has something of a black magic feel to it, and creating widgets for recursive datastructures is next to impossible. Below is a new widget named "child", which should simplify both tasks a lot. Background: The predefined complex widgets, i.e. the widgets that is build from other widgets, has their types expanded at creation for speed. This obviously goes wrong for recursive types. This new "child" widget is a delayed action wrapper of an arbitrary widget, specified in its :type argument. The value of the :type argument will not be expanded before it is needed, which allow for recursive datastructures. Since the :type argument to this widget takes exactly the same values as the :type argument to defcustom, it will also be useful for people who want to "name" a type for custom use. If the datastructures is recursive, you need to gave a :match argument as well as :type. If not, it will simply match any values that the type specified for :type will match. Here is the code for the "child" widget, as well as an example of a recursive datastructure (a binary tree of strings). I suggest we add the "child" widget to wid-edit.el, and document it somewhere. (define-widget 'child 'default "Base widget for recursive datastructures. You need to set :type to the widget type for the datastructure you want to define, and set :match to a function that matches the datastructure. If the datastructure is not recursive, you don't have to set :match." :format "%v" ;; We don't convert :type because we want to allow recursive ;; datastructures. This is slow, so we should not create speed ;; critical widgets by deriving from this. :convert-widget 'widget-value-convert-widget :value-create 'widget-child-value-create :value-delete 'widget-children-value-delete :value-get 'widget-child-value-get :value-inline 'widget-child-value-inline :default-get 'widget-child-default-get :validate 'widget-child-validate) (defun widget-child-value-create (widget) "Create the child widget." (let ((value (widget-get widget :value)) (type (widget-get widget :type))) (widget-put widget :children (list (widget-create-child-value widget (widget-convert type) value))))) (defun widget-child-value-get (widget) ;; Get value of the child widget. (widget-value (car (widget-get widget :children)))) (defun widget-child-value-inline (widget) ;; Get value of the child widget. (widget-apply (car (widget-get widget :children)) :value-inline)) (defun widget-child-default-get (widget) ;; Get default for the child. (widget-default-get (car (widget-get widget :args)))) (defun widget-child-match (widget value) "Matches iff the child matches. You need to overwrite you want to match recursive datastructures." (widget-apply (widget-convert (widget-get widget :type)) :match value)) (defun widget-child-validate (widget) "Valid iff the child is valid." (widget-apply (car (widget-get widget :children)) :validate)) (define-widget 'binary-tree-of-string 'child "A binary tree made of cons-cells and strings." :offset 4 :match (lambda (widget value) (binary-tree-of-string-p value)) :type '(menu-choice (string :tag "Leaf" :value "") (cons :tag "Interior" :value ("" . "") binary-tree-of-string binary-tree-of-string))) (defun binary-tree-of-string-p (object) "Return t if OBJECT is a binary tree of strings." (or (stringp object) (and (consp object) (binary-tree-of-string-p (car object)) (binary-tree-of-string-p (cdr object))))) ;; Evaluate this to edit the buffer again. (lisp-interaction-mode) ;; Evaluate this to get the current value. (widget-value w) ;; Evaluate this to create and edit a test widget. (progn (setq w (widget-create 'binary-tree-of-string '("a" . (("b" . "c") . "d")))) (widget-setup) (widget-browse-mode)) ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Creating recursive customization types / widgets 2003-11-29 16:38 Creating recursive customization types / widgets Per Abrahamsen @ 2003-11-29 18:34 ` Per Abrahamsen 2003-11-30 20:05 ` Stefan Monnier 2003-12-01 1:45 ` Richard Stallman 2 siblings, 0 replies; 24+ messages in thread From: Per Abrahamsen @ 2003-11-29 18:34 UTC (permalink / raw) Per Abrahamsen <abraham@dina.kvl.dk> writes: > (define-widget 'child 'default > "Base widget for recursive datastructures. > > You need to set :type to the widget type for the datastructure you > want to define, and set :match to a function that matches the > datastructure. If the datastructure is not recursive, you don't have > to set :match." > :format "%v" This should be :format "%{%t%}: %v" to make it directly usable as a customization type. ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Creating recursive customization types / widgets 2003-11-29 16:38 Creating recursive customization types / widgets Per Abrahamsen 2003-11-29 18:34 ` Per Abrahamsen @ 2003-11-30 20:05 ` Stefan Monnier 2003-12-01 11:36 ` Per Abrahamsen ` (2 more replies) 2003-12-01 1:45 ` Richard Stallman 2 siblings, 3 replies; 24+ messages in thread From: Stefan Monnier @ 2003-11-30 20:05 UTC (permalink / raw) > Below is a new widget named "child", which should simplify both tasks > a lot. Neat. I have no idea why it's called `child' and the resulting use of `child' in (define-widget 'foo 'child ...) does not look particularly intuitive, but I can't think of anything better either. We should install this. > If the datastructures is recursive, you need to gave a :match argument > as well as :type. Why is that ? > If not, it will simply match any values that the > type specified for :type will match. Which seems like what we want. Are there cases where it doesn't work and if so, why not (i.e. can we fix it) ? Stefan ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Creating recursive customization types / widgets 2003-11-30 20:05 ` Stefan Monnier @ 2003-12-01 11:36 ` Per Abrahamsen 2003-12-01 16:35 ` Thien-Thi Nguyen 2003-12-01 17:08 ` Creating recursive customization types / widgets Per Abrahamsen 2003-12-01 13:36 ` Per Abrahamsen 2003-12-01 16:10 ` Ted Zlatanov 2 siblings, 2 replies; 24+ messages in thread From: Per Abrahamsen @ 2003-12-01 11:36 UTC (permalink / raw) Stefan Monnier <monnier@IRO.UMontreal.CA> writes: > Neat. I have no idea why it's called `child' and the resulting > use of `child' in (define-widget 'foo 'child ...) does not look > particularly intuitive, but I can't think of anything better either. Because it has a single child widget, and the new widget basically behave like the child, except for allowing recursion. I called it 'recursive' and 'delayed' under development. It is a common pattern in OOP. Having an object that wraps another object, delegates message to the other object, and thus acts like a proxy. So 'wrapper', delegator' or 'proxy' could be used as well. > We should install this. Yes. It answers the most common custom/widget programming question that I couldn't previously answer :-) >> If the datastructures is recursive, you need to gave a :match argument >> as well as :type. > > Why is that ? Good question. I was afraid of infinite recursion, but as long as the widget type "eat some tokens" of the value before the recursion starts, that doesn't happen. ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Creating recursive customization types / widgets 2003-12-01 11:36 ` Per Abrahamsen @ 2003-12-01 16:35 ` Thien-Thi Nguyen 2003-12-02 12:37 ` tapsellferrier.co.uk Host name lookup failure Robert J. Chassell 2003-12-01 17:08 ` Creating recursive customization types / widgets Per Abrahamsen 1 sibling, 1 reply; 24+ messages in thread From: Thien-Thi Nguyen @ 2003-12-01 16:35 UTC (permalink / raw) Per Abrahamsen <abraham@dina.kvl.dk> writes: 'recursive' and 'delayed' under development. hehe, "fecund-root". thi ^ permalink raw reply [flat|nested] 24+ messages in thread
* tapsellferrier.co.uk Host name lookup failure 2003-12-01 16:35 ` Thien-Thi Nguyen @ 2003-12-02 12:37 ` Robert J. Chassell 0 siblings, 0 replies; 24+ messages in thread From: Robert J. Chassell @ 2003-12-02 12:37 UTC (permalink / raw) Sorry to bother the rest of you -- but this is the best way I know to tell Nic Ferrier <nferrier@tapsellferrier.co.uk> the problem: Nic: over the past week I have sent several messages to you off-list and have got back bounces saying Xdefer: <nferrier@tapsellferrier.co.uk> reason: (ERR164) router inet_hosts: DNS error: Host name lookup failure: Connection refused Please do what you can. Thank you. -- Robert J. Chassell Rattlesnake Enterprises http://www.rattlesnake.com GnuPG Key ID: 004B4AC8 http://www.teak.cc bob@rattlesnake.com ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Creating recursive customization types / widgets 2003-12-01 11:36 ` Per Abrahamsen 2003-12-01 16:35 ` Thien-Thi Nguyen @ 2003-12-01 17:08 ` Per Abrahamsen 2003-12-02 0:31 ` Juri Linkov 1 sibling, 1 reply; 24+ messages in thread From: Per Abrahamsen @ 2003-12-01 17:08 UTC (permalink / raw) Per Abrahamsen <abraham@dina.kvl.dk> writes: > Stefan Monnier <monnier@IRO.UMontreal.CA> writes: > >> Neat. I have no idea why it's called `child' and the resulting >> use of `child' in (define-widget 'foo 'child ...) does not look >> particularly intuitive, but I can't think of anything better either. > > Because it has a single child widget, and the new widget basically > behave like the child, except for allowing recursion. Actually, now I remember. I though of it as a potential base class for all widgets with a single child. But it is not entirely appropriate for that. > I called it 'recursive' and 'delayed' under development. > > It is a common pattern in OOP. Having an object that wraps another > object, delegates message to the other object, and thus acts like a > proxy. So 'wrapper', delegator' or 'proxy' could be used as well. My current favorite name would be 'proxy', but I do not feel strongly about it. What do you think? ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Creating recursive customization types / widgets 2003-12-01 17:08 ` Creating recursive customization types / widgets Per Abrahamsen @ 2003-12-02 0:31 ` Juri Linkov 2003-12-02 10:19 ` Per Abrahamsen 2003-12-02 10:40 ` Per Abrahamsen 0 siblings, 2 replies; 24+ messages in thread From: Juri Linkov @ 2003-12-02 0:31 UTC (permalink / raw) Cc: emacs-devel Per Abrahamsen <abraham@dina.kvl.dk> writes: > Per Abrahamsen <abraham@dina.kvl.dk> writes: >> Stefan Monnier <monnier@IRO.UMontreal.CA> writes: >>> Neat. I have no idea why it's called `child' and the resulting >>> use of `child' in (define-widget 'foo 'child ...) does not look >>> particularly intuitive, but I can't think of anything better either. >> >> Because it has a single child widget, and the new widget basically >> behave like the child, except for allowing recursion. > > Actually, now I remember. I though of it as a potential base class > for all widgets with a single child. But it is not entirely > appropriate for that. The name "child" is not suitable in this case because it has a sense only in a "parent-child" relationship between two entities. So, let's consider some terminology to choose a better name: Tree - recursive data structure Node - item of a tree Root - initial node of a tree Leaf - terminal node of a tree Cell - data object in Lisp data structure ("cons cell", "pair") So depending on whether you perceive a new widget as a whole structure (such as e.g. displayed by the `widget-browse-mode' in a widget buffer) or only as one element of such structure, I suggest you to name it either "tree" or "node". >> I called it 'recursive' and 'delayed' under development. >> >> It is a common pattern in OOP. Having an object that wraps another >> object, delegates message to the other object, and thus acts like a >> proxy. So 'wrapper', delegator' or 'proxy' could be used as well. > > My current favorite name would be 'proxy', but I do not feel strongly > about it. What do you think? These names are too implementation-specific, but from user's point of view the name "node" is more clear. BTW, adding new nodes to a tree in this new widget is easy, but I can't find a way to delete a node. Is it possible? -- http://www.jurta.org/emacs/ ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Creating recursive customization types / widgets 2003-12-02 0:31 ` Juri Linkov @ 2003-12-02 10:19 ` Per Abrahamsen 2003-12-02 12:46 ` David Kastrup 2003-12-02 10:40 ` Per Abrahamsen 1 sibling, 1 reply; 24+ messages in thread From: Per Abrahamsen @ 2003-12-02 10:19 UTC (permalink / raw) Cc: emacs-devel Juri Linkov <juri@jurta.org> writes: > So depending on whether you perceive a new widget as a whole structure > (such as e.g. displayed by the `widget-browse-mode' in a widget > buffer) or only as one element of such structure, I suggest you > to name it either "tree" or "node". It is both. I'd like to reserve `tree' for a customize-browse ui widget, and node is rather non-descriptive. Non-recursive datastructures can have nodes as well. ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Creating recursive customization types / widgets 2003-12-02 10:19 ` Per Abrahamsen @ 2003-12-02 12:46 ` David Kastrup 2003-12-02 13:34 ` Per Abrahamsen 0 siblings, 1 reply; 24+ messages in thread From: David Kastrup @ 2003-12-02 12:46 UTC (permalink / raw) Cc: Juri Linkov, emacs-devel Per Abrahamsen <abraham@dina.kvl.dk> writes: > Juri Linkov <juri@jurta.org> writes: > > > So depending on whether you perceive a new widget as a whole structure > > (such as e.g. displayed by the `widget-browse-mode' in a widget > > buffer) or only as one element of such structure, I suggest you > > to name it either "tree" or "node". > > It is both. > > I'd like to reserve `tree' for a customize-browse ui widget, and node > is rather non-descriptive. Non-recursive datastructures can have > nodes as well. There is nothing in the widget as far as I can see that requires it to be used only for recursive data structures, even though that is its primary purpose. Its principal feature is that the type information is evaluated delayed or dynamically. It is conceivable, for example, that the exact type depends on the value of a different variable, or the availability of some feature at run-time. One could use that widget even in that case, and it would have nothing to do with recursion. So I think something like "lazy" or "dynamic" or "late" will be a better name than "recursive". Unless I am misunderstanding something here. -- David Kastrup, Kriemhildstr. 15, 44793 Bochum ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Creating recursive customization types / widgets 2003-12-02 12:46 ` David Kastrup @ 2003-12-02 13:34 ` Per Abrahamsen 0 siblings, 0 replies; 24+ messages in thread From: Per Abrahamsen @ 2003-12-02 13:34 UTC (permalink / raw) Cc: Juri Linkov, emacs-devel David Kastrup <dak@gnu.org> writes: > It is conceivable, for example, that the exact type depends on the > value of a different variable, or the availability of some feature > at run-time. One could use that widget even in that case, and it > would have nothing to do with recursion. I don't know if that would work. The :type value isn't evaluated like a Lisp expression, it is expanded in widget specific ways. ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Creating recursive customization types / widgets 2003-12-02 0:31 ` Juri Linkov 2003-12-02 10:19 ` Per Abrahamsen @ 2003-12-02 10:40 ` Per Abrahamsen 1 sibling, 0 replies; 24+ messages in thread From: Per Abrahamsen @ 2003-12-02 10:40 UTC (permalink / raw) Juri Linkov <juri@jurta.org> writes: > BTW, adding new nodes to a tree in this new widget is easy, > but I can't find a way to delete a node. Is it possible? I don't understand the question. Are you speaking of the 'child' widget, or the 'binary-tree-of-string' example? If the later, then you can't delete or add a single node in binary tree. If you do, the tree is no longer binary. Binary trees always have an odd number of nodes. You can add two nodes by converting a leaf node to an interior node, and you can delete two subtrees by converting an interior node to a leaf node. ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Creating recursive customization types / widgets 2003-11-30 20:05 ` Stefan Monnier 2003-12-01 11:36 ` Per Abrahamsen @ 2003-12-01 13:36 ` Per Abrahamsen 2003-12-01 16:10 ` Ted Zlatanov 2 siblings, 0 replies; 24+ messages in thread From: Per Abrahamsen @ 2003-12-01 13:36 UTC (permalink / raw) Stefan Monnier <monnier@IRO.UMontreal.CA> writes: >> If the datastructures is recursive, you need to gave a :match argument >> as well as :type. > > Why is that ? > >> If not, it will simply match any values that the >> type specified for :type will match. > > Which seems like what we want. Are there cases where it doesn't work > and if so, why not (i.e. can we fix it) ? You need :match 'widget-child-match in the definition of the 'child' widget, then it seems to work for the cases I have tried. ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Creating recursive customization types / widgets 2003-11-30 20:05 ` Stefan Monnier 2003-12-01 11:36 ` Per Abrahamsen 2003-12-01 13:36 ` Per Abrahamsen @ 2003-12-01 16:10 ` Ted Zlatanov 2003-12-01 19:24 ` Per Abrahamsen 2 siblings, 1 reply; 24+ messages in thread From: Ted Zlatanov @ 2003-12-01 16:10 UTC (permalink / raw) On 30 Nov 2003, monnier@iro.umontreal.ca wrote: >> Below is a new widget named "child", which should simplify both >> tasks a lot. > > Neat. I have no idea why it's called `child' and the resulting > use of `child' in (define-widget 'foo 'child ...) does not look > particularly intuitive, but I can't think of anything better either. I like the patch, and I'm OK with "child" but here's some alternate suggestions: recursive, inherited, derived, subtype, extending. Ted ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Creating recursive customization types / widgets 2003-12-01 16:10 ` Ted Zlatanov @ 2003-12-01 19:24 ` Per Abrahamsen 0 siblings, 0 replies; 24+ messages in thread From: Per Abrahamsen @ 2003-12-01 19:24 UTC (permalink / raw) Ted Zlatanov <tzz@lifelogs.com> writes: > I like the patch, and I'm OK with "child" but here's some alternate > suggestions: recursive, inherited, derived, subtype, extending. It is a bit weird to name a base class 'derived' or 'subtype' :-) extending and inherited are a bit non-specific. recursive is ok. ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Creating recursive customization types / widgets 2003-11-29 16:38 Creating recursive customization types / widgets Per Abrahamsen 2003-11-29 18:34 ` Per Abrahamsen 2003-11-30 20:05 ` Stefan Monnier @ 2003-12-01 1:45 ` Richard Stallman 2003-12-01 13:27 ` Per Abrahamsen 2 siblings, 1 reply; 24+ messages in thread From: Richard Stallman @ 2003-12-01 1:45 UTC (permalink / raw) Cc: emacs-devel (define-widget 'child 'default "Base widget for recursive datastructures. You need to set :type to the widget type for the datastructure you want to define, and set :match to a function that matches the datastructure. If the datastructure is not recursive, you don't have to set :match." It looks like a good feature, but I can't really understand that doc string, so it needs to be somewhat clearer. ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Creating recursive customization types / widgets 2003-12-01 1:45 ` Richard Stallman @ 2003-12-01 13:27 ` Per Abrahamsen 2003-12-02 4:17 ` Richard Stallman 0 siblings, 1 reply; 24+ messages in thread From: Per Abrahamsen @ 2003-12-01 13:27 UTC (permalink / raw) Cc: emacs-devel Richard Stallman <rms@gnu.org> writes: > (define-widget 'child 'default > "Base widget for recursive datastructures. > > You need to set :type to the widget type for the datastructure you > want to define, and set :match to a function that matches the > datastructure. If the datastructure is not recursive, you don't have > to set :match." > > It looks like a good feature, but I can't really understand > that doc string, so it needs to be somewhat clearer. Most widget doc strings are much worse, but that's no excuse. Is the following understandable? (define-widget 'child 'default "Base widget for recursive datastructures. The `child' widget will, when instantiated, contain a single inferior widget, of the widget type specified by the :type parameter. The value of the `child' widget is the same as the value of the inferior widget. When deriving a new widget from the 'child' widget, the :type parameter is allowed to refer to the widget currently being defined, thus allowing recursive datastructures to be described. The :type parameter takes the same arguments as the defcustom parameter with the same name. Background: Most composite widgets, i.e. widgets containing other widgets, does not allow recursion. That is, when you define a new widget type, none of the inferior widgets may be of the same type you are currently defining. In Lisp, however, it is custom to define datastructures in terms of themselves. A list, for example, is defined as either nil, or a cons cell whose cdr itself is a lisp. The obvious way to translate this into a widget type would be (define-widget 'my-list 'choice \"A list of sexps.\" :tag \"Sexp list\" :args '((const nil) (cons :value (nil) sexp my-list))) Here we attempt to define my-list as a choice of either the constant nil, or a cons-cell containing a sexp and my-lisp. This will not work because the `choice' widget does not allow recursion. Using the `child' widget you can overcome this problem, as in this example: (define-widget 'sexp-list 'child \"A list of sexps.\" :tag \"Sexp list\" :type '(choice (const nil) (cons :value (nil) sexp sexp-list)))" :format "%{%t%}: %v" ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Creating recursive customization types / widgets 2003-12-01 13:27 ` Per Abrahamsen @ 2003-12-02 4:17 ` Richard Stallman 2003-12-02 10:31 ` Per Abrahamsen 2003-12-02 11:24 ` David Kastrup 0 siblings, 2 replies; 24+ messages in thread From: Richard Stallman @ 2003-12-02 4:17 UTC (permalink / raw) Cc: emacs-devel The doc string for `child' is now clear, but it shows that `child' is not the right name for it. ISTR that there is a frequently used term for an object whose value will be computed only when you actually refer to it, but it has been so many years that I don't remember the term. Is it "lazy"? Maybe this type should be called `lazy'. `delayed' is ok too. ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Creating recursive customization types / widgets 2003-12-02 4:17 ` Richard Stallman @ 2003-12-02 10:31 ` Per Abrahamsen 2003-12-03 4:46 ` Richard Stallman 2003-12-02 11:24 ` David Kastrup 1 sibling, 1 reply; 24+ messages in thread From: Per Abrahamsen @ 2003-12-02 10:31 UTC (permalink / raw) Cc: emacs-devel Richard Stallman <rms@gnu.org> writes: > ISTR that there is a frequently used term for an object > whose value will be computed only when you actually refer to it, > but it has been so many years that I don't remember the term. > Is it "lazy"? Maybe this type should be called `lazy'. The word is lazy, as in lazy evaluation. > `delayed' is ok too. 'lazy' and 'delayed' are good because they describe how the widget accomplish its task. But I now believe 'recursive' is best, because it described what the task is. Also (define-widget 'binary-tree 'recursive ...) reads well: A binary tree is a recursive datastructure with the following attributes ... That lazy or delayed expansion is needed for recursive datastructures is an (admittedly important) implementation detail. May I commit the widget under the name `recursive'? ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Creating recursive customization types / widgets 2003-12-02 10:31 ` Per Abrahamsen @ 2003-12-03 4:46 ` Richard Stallman 2003-12-03 12:30 ` Per Abrahamsen ` (2 more replies) 0 siblings, 3 replies; 24+ messages in thread From: Richard Stallman @ 2003-12-03 4:46 UTC (permalink / raw) Cc: emacs-devel 'lazy' and 'delayed' are good because they describe how the widget accomplish its task. But I now believe 'recursive' is best, because it described what the task is. Also (define-widget 'binary-tree 'recursive ...) reads well: A binary tree is a recursive datastructure with the following attributes ... That use is recursive, but the widget doesn't require you to use recursion. Its essence is lazy or delayed evaluation. So I think that should be the name. ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Creating recursive customization types / widgets 2003-12-03 4:46 ` Richard Stallman @ 2003-12-03 12:30 ` Per Abrahamsen 2003-12-03 15:26 ` Per Abrahamsen 2003-12-03 19:05 ` Kevin Rodgers 2 siblings, 0 replies; 24+ messages in thread From: Per Abrahamsen @ 2003-12-03 12:30 UTC (permalink / raw) Richard Stallman <rms@gnu.org> writes: > That use is recursive, but the widget doesn't require you to use > recursion. Its essence is lazy or delayed evaluation. So I think > that should be the name. Ok, I'll call it lazy. ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Creating recursive customization types / widgets 2003-12-03 4:46 ` Richard Stallman 2003-12-03 12:30 ` Per Abrahamsen @ 2003-12-03 15:26 ` Per Abrahamsen 2003-12-03 19:05 ` Kevin Rodgers 2 siblings, 0 replies; 24+ messages in thread From: Per Abrahamsen @ 2003-12-03 15:26 UTC (permalink / raw) Cc: emacs-devel Here is documentation patch describing the use of the new widget. Is it ok to commit that, and the lazy widget code itself, to CVS? 2003-12-03 Per Abrahamsen <abraham@dina.kvl.dk> * customize.texi (Defining New Types): Document use of the `lazy' widget. *** customize.texi.~1.36.~ 2003-11-30 14:59:10.000000000 +0100 --- customize.texi 2003-12-03 16:18:56.000000000 +0100 *************** *** 1,6 **** @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. ! @c Copyright (C) 1997, 1998, 1999, 2000, 2002 Free Software Foundation, Inc. @c See the file elisp.texi for copying conditions. @setfilename ../info/customize @node Customization, Loading, Macros, Top --- 1,6 ---- @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. ! @c Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003 Free Software Foundation, Inc. @c See the file elisp.texi for copying conditions. @setfilename ../info/customize @node Customization, Loading, Macros, Top *************** *** 373,378 **** --- 373,379 ---- * Composite Types:: * Splicing into Lists:: * Type Keywords:: + * Defining New Types:: @end menu All customization types are implemented as widgets; see @ref{Top, , *************** *** 1056,1061 **** --- 1057,1123 ---- @end ignore @end table + @node Defining New Types + @subsection Defining New Types + + In the previous sections we have described how to construct elaborate + type specifications for @code{defcustom}. In some cases you may want to + give such a type specification a name. The obvious case is when you are + using the same type for many user options, rather than repeat the + specification for each option, you can give the type specification a + name once, and use that name each @code{defcustom}. The other case is + when a user option accept a recursive datastructure. To make it + possible for a datatype to refer to itself, it needs to have a name. + + Since custom types are implemented as widgets, the way to define a new + customize type is to define a new widget. We are not going to describe + the widget interface here in details, see @ref{Top, , Introduction, + widget, The Emacs Widget Library}, for that. Instead we are going to + demonstrate the minimal functionality needed for defining new customize + types by a simple example. + + @example + (define-widget 'binary-tree-of-string 'lazy + "A binary tree made of cons-cells and strings." + :offset 4 + :tag "Node" + :type '(choice (string :tag "Leaf" :value "") + (cons :tag "Interior" + :value ("" . "") + binary-tree-of-string + binary-tree-of-string))) + + (defcustom foo-bar "" + "Sample variable holding a binary tree of strings." + :type 'binary-tree-of-string) + @end example + + The function to define a new widget is name @code{define-widget}. The + first argument is the symbol we want to make a new widget type. The + second argument is a symbol representing an existing widget, the new + widget is going to be defined in terms of difference from the existing + widget. For the purpose of defining new customization types, the + @code{lazy} widget is perfect, because it accept a @code{:type} keyword + argument with the same syntax as the keyword argument to + @code{defcustom} with the same name. The third argument is a + documentation string for the new widget. You will be able to see that + string with the @kbd{M-x widget-browse @key{ret} binary-tree-of-string + @key{ret}} command. + + After these mandatory arguments follows the keyword arguments. The most + important is @code{:type}, which describes the datatype we want to match + with this widget. Here a @code{binary-tree-of-string} is described as + being either a string, or a cons-cell whose car and cdr are themselves + both @code{binary-tree-of-string}. Note the reference to the widget + type we are currently in the process of defining. The @code{:tag} + attribute is a string to name the widget in the user interface, and the + @code{:offset} argument are there to ensure that child nodes are + indented four spaces relatively to the parent node, making the tree + structure apparent in the customization buffer. + + The @code{defcustom} shows how the new widget can be used as an ordinary + customization type. + @ignore arch-tag: d1b8fad3-f48c-4ce4-a402-f73b5ef19bd2 @end ignore ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Creating recursive customization types / widgets 2003-12-03 4:46 ` Richard Stallman 2003-12-03 12:30 ` Per Abrahamsen 2003-12-03 15:26 ` Per Abrahamsen @ 2003-12-03 19:05 ` Kevin Rodgers 2 siblings, 0 replies; 24+ messages in thread From: Kevin Rodgers @ 2003-12-03 19:05 UTC (permalink / raw) Richard Stallman wrote: > 'lazy' and 'delayed' are good because they describe how the widget > accomplish its task. But I now believe 'recursive' is best, because > it described what the task is. Also > > (define-widget 'binary-tree 'recursive ...) > > reads well: A binary tree is a recursive datastructure with the > following attributes ... > > That use is recursive, but the widget doesn't require you to use > recursion. Its essence is lazy or delayed evaluation. So I think > that should be the name. Can widgets have aliases, like variables and functions? -- Kevin Rodgers ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Creating recursive customization types / widgets 2003-12-02 4:17 ` Richard Stallman 2003-12-02 10:31 ` Per Abrahamsen @ 2003-12-02 11:24 ` David Kastrup 1 sibling, 0 replies; 24+ messages in thread From: David Kastrup @ 2003-12-02 11:24 UTC (permalink / raw) Cc: Per Abrahamsen, emacs-devel Richard Stallman <rms@gnu.org> writes: > The doc string for `child' is now clear, but it shows > that `child' is not the right name for it. > > ISTR that there is a frequently used term for an object > whose value will be computed only when you actually refer to it, > but it has been so many years that I don't remember the term. > Is it "lazy"? Maybe this type should be called `lazy'. > > `delayed' is ok too. dynamic? -- David Kastrup, Kriemhildstr. 15, 44793 Bochum ^ permalink raw reply [flat|nested] 24+ messages in thread
end of thread, other threads:[~2003-12-03 19:05 UTC | newest] Thread overview: 24+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2003-11-29 16:38 Creating recursive customization types / widgets Per Abrahamsen 2003-11-29 18:34 ` Per Abrahamsen 2003-11-30 20:05 ` Stefan Monnier 2003-12-01 11:36 ` Per Abrahamsen 2003-12-01 16:35 ` Thien-Thi Nguyen 2003-12-02 12:37 ` tapsellferrier.co.uk Host name lookup failure Robert J. Chassell 2003-12-01 17:08 ` Creating recursive customization types / widgets Per Abrahamsen 2003-12-02 0:31 ` Juri Linkov 2003-12-02 10:19 ` Per Abrahamsen 2003-12-02 12:46 ` David Kastrup 2003-12-02 13:34 ` Per Abrahamsen 2003-12-02 10:40 ` Per Abrahamsen 2003-12-01 13:36 ` Per Abrahamsen 2003-12-01 16:10 ` Ted Zlatanov 2003-12-01 19:24 ` Per Abrahamsen 2003-12-01 1:45 ` Richard Stallman 2003-12-01 13:27 ` Per Abrahamsen 2003-12-02 4:17 ` Richard Stallman 2003-12-02 10:31 ` Per Abrahamsen 2003-12-03 4:46 ` Richard Stallman 2003-12-03 12:30 ` Per Abrahamsen 2003-12-03 15:26 ` Per Abrahamsen 2003-12-03 19:05 ` Kevin Rodgers 2003-12-02 11:24 ` David Kastrup
Code repositories for project(s) associated with this external index https://git.savannah.gnu.org/cgit/emacs.git https://git.savannah.gnu.org/cgit/emacs/org-mode.git This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.