All Manuals > CLIM 2.0 User Guide > 7 Defining a New Presentation Type

7.2 CLIM Operators for Defining New Presentation Types

define-presentation-type Macro

define-presentation-type name parameters &key options inherit-from description history parameters-are-types

Summary: Defines a presentation type whose name is the symbol or class name and whose parameters are specified by the lambda-list parameters. These parameters are visible within inherit-from and within the methods created with define-presentation-method. For example, the parameters are used by presentation-typep and presentation-subtypep methods to refine their tests for type inclusion.

options is a list of option specifiers. It defaults to nil. An option specifier is either a symbol or a list of the form (symbol &optional default supplied-p presentation-type accept-options), where symbol, default, and supplied-p are as in a normal lambda-list. If presentation-type and accept-options are present, they specify how to accept a new value for this option from the user. symbol can also be specified in the (keyword variable) form allowed for Common Lisp lambda lists. symbol is a variable that is visible within inherit-from and within most of the methods created with define-presentation-method. The keyword corresponding to symbol can be used as an option in the third form of a presentation type specifier. An option specifier for the standard option :description is automatically added to options if an option with that keyword is not present; however, it does not produce a visible variable binding.

Unsupplied optional or keyword parameters default to * (as in deftype) if no default is specified in parameters. Unsupplied options default to nil if no default is specified in options.

inherit-from is a form that evaluates to a presentation type specifier for another type from which the new type inherits. inherit-from can access the parameter variables bound by the parameters lambda list and the option variables specified by options. If name is or names a CLOS class (other than a built-in-class), then inherit-from must specify the class's direct superclasses (using and to specify multiple inheritance). It is useful to do this when you want to parameterize previously defined CLOS classes.

If inherit-from is unsupplied, the default behavior is that if name is or names a CLOS class, then the type inherits from the presentation type corresponding to the direct superclasses of that CLOS class (using and to specify multiple inheritance). Otherwise, the type named by name inherits from standard-class.

description is a string or nil. This should be the term for an instance for the type being defined. If it is nil or unsupplied, a description is automatically generated; it will be a "prettied up" version of the type name, for example, small-integer would become "small integer". You can also write a describe-presentation-type presentation method. description is implemented by the default describe-presentation-type method, so description only works in presentation types where that default method is not shadowed.

history can be t (the default), meaning that this type has its own history of previous inputs; nil, meaning that this type keeps no history; or the name of another presentation type whose history is shared by this type. More complex histories can be specified by writing a presentation-type-history presentation method.

If the boolean parameters-are-types is t, this means that the parameters to the presentation type are themselves presentation types. If they are not presentation types, parameters-are-types should be supplied as nil. Types such as and, or, and sequence will specify this as t.

Every presentation type must define or inherit presentation methods for accept and present if the type is going to be used for input and output. For presentation types that are only going to be used for input via the pointer, the accept need not be defined.

If a presentation type has parameters, it must define presentation methods for presentation-typep and presentation-subtypep that handle the parameters, or inherit appropriate presentation methods. In many cases it should also define presentation methods for describe-presentation-type and presentation-type-specifier-p.

There are certain restrictions on the inherit-from form, to allow it to be analyzed at compile time. The form must be a simple substitution of parameters and options into positions in a fixed framework. It cannot involve conditionals or computations that depend on valid values for the parameters or options; for example, it cannot require parameter values to be numbers. It cannot depend on the dynamic or lexical environment. The form will be evaluated at compile time with uninterned symbols used as dummy values for the parameters and options. In the type specifier produced by evaluating the form, the type name must be a constant that names a type, the type parameters cannot derive from options of the type being defined, and the type options cannot derive from parameters of the type being defined. All presentation types mentioned must be already defined. and can be used for multiple inheritance, but or, not, and satisfies cannot be used.

None of the arguments, except inherit-from, are evaluated.

7.2.1 Presentation Methods in CLIM

Use define-presentation-method to define presentation methods.

define-presentation-method Macro

define-presentation-method name qualifiers* specialized-lambda-list &body body

Summary: Defines a presentation method for the function named name on the presentation type named in specialized-lambda-list.

specialized-lambda-list is a CLOS specialized lambda list for the method, and its contents vary depending on what name is. qualifiers* is zero or more of the usual CLOS method qualifier symbols. define-presentation-method supports standard method combination (the :before, :after, and :around method qualifiers).

body defines the body of the method. body may have zero or more declarations as its first forms.

All presentation methods have an argument named type that must be specialized with the name of a presentation type. The value of type is a presentation type specifier, which can be for a subtype that inherited the method.

All presentation methods except those for presentation-subtypep have lexical access to the parameters from the presentation type specifier. Presentation methods for the functions accept, present, describe-presentation-type, presentation-type-specifier-p, and accept-present-default also have lexical access to the options from the presentation type specifier.

Presentation methods inherit and combine in the same way as ordinary CLOS methods. However, they do not resemble ordinary CLOS methods with respect to the type argument. The parameter specializer for type is handled in a special way, and presentation method inheritance arranges the type parameters and options seen by each method.

For example, consider three types int, rrat, and num defined as follows:

(define-presentation-type int (low high) 
  :inherit-from `(rrat ,high ,low)) 
 
(define-presentation-method presentation-typep :around (object (type int))
  (and (call-next-method) 
       (integerp object) 
       (<= low object high))) 
 
(define-presentation-type rrat (high low) 
  :inherit-from `num) 
 
(define-presentation-method presentation-typep :around (object 
                                                        (type rrat))
  (and (call-next-method) 
       (rationalp object) 
       (<= low object high))) 
 
(define-presentation-type num ()) 
 
(define-presentation-method presentation-typep (object (type num))
  (numberp object)) 

If the user were to evaluate the form (presentation-typep x '(int 1 5)), then the type parameters will be (1 5) in the presentation-typep method for int, (5 1) in the method for rrat, and nil in the method for num. The value for type will be ((int 1 5)) in each of the methods.

Following are the names of the various presentation methods defined by define-presentation-method, along with the lambda-list for each method. For all of the presentation methods, the type will always be specialized. Where appropriate, view may be specialized as well. The other arguments are not usually specialized.

accept Presentation

accept type stream view &key default default-type

Summary: This presentation method is responsible for "parsing" the representation of type for a particular view view on the stream stream.The accept method returns a single value (the object that was "parsed"), or two values, the object and its type (a presentation type specifier). The method's caller takes care of establishing the input context, defaulting, prompting, and input editing.

The accept method can specialize on the view argument in order to define more than one input view for the data.

Note that accept presentation methods can call the function accept recursively. In this case, the programmer should be careful to specify nil for :prompt and :display-default unless recursive prompting is really desired.

present Presentation

present object type stream view &key acceptably for-context-type

Summary: This presentation method is responsible for displaying the representation of object having type type for a particular view view; see the function accept.

The present method can specialize on the view argument in order to define more than one view of the data. For example, a spreadsheet program might define a presentation type for revenue, which can be displayed either as a number or a bar of a certain length in a bar graph. Typically, at least one canonical view should be defined for a presentation type.

describe-presentation-type Presentation

describe-presentation-type type stream plural-count

Summary: This presentation method is responsible for textually describing the type type. stream is a stream, and will not be nil as it can be for the describe-presentation-type function.

presentation-type-specifier-p Presentation

presentation-type-specifier-p type

Summary: This presentation method is responsible for checking the validity of the parameters and options for the presentation type type. The default method returns t.

presentation-typep Presentation

presentation-typep object type

Summary: This presentation method is called when the presentation-typep function requires type-specific knowledge. If the type name in the presentation type type is or names a CLOS class, the method is called only if object is a member of the class and type contains parameters. The method simply tests whether object is a member of the subtype specified by the parameters. For non-class types, the method is always called.

For example, the type method will not get called in (presentation-typep 1.0 `(integer 10)) because 1.0 is not an integer. The method will get called by (presentation-typep 10 `(integer 0 5)).

presentation-subtypep Presentation

presentation-subtypep type putative-supertype

Summary: This presentation method is called when the presentation-subtypep function requires type-specific knowledge.

presentation-subtypep walks the type lattice (using map-over-presentation-supertypes) to determine whether or not the presentation type type is a subtype of the presentation type putative-supertype, without looking at the type parameters. When a supertype of type has been found whose name is the same as the name of putative-supertype, then the subtypep method for that type is called in order to resolve the question by looking at the type parameters (that is, if the subtypep method is called, type and putative-supertype are guaranteed to be the same type, differing only in their parameters). If putative-supertype is never found during the type walk, then presentation-subtypep will never call the presentation-subtypep presentation method for putative-supertype.

Unlike all other presentation methods, presentation-subtypep receives a type argument that has been translated to the presentation type for which the method is specialized; type is never a subtype. The method is only called if putative-supertype has parameters and the two presentation type specifiers do not have equal parameters. The method must return the two values that presentation-subtypep returns.

Since presentation-subtypep takes two type arguments, the parameters are not lexically available as variables in the body of a presentation method.

map-over-presentation-type-supertypes Presentation

map-over-presentation-type-supertypes function type

Summary: This method is called in order to apply function to the superclasses of the presentation type type.

accept-present-default Presentation

accept-present-default type stream view default default-supplied-p present-p query-identifier

Summary: This method specializes the kind of default that is to be presented to the user. It is called when accept turns into present inside accepting-values. The default method calls present or describe-presentation-type, depending on whether default-supplied-p is t or nil, respectively.

The boolean default-supplied-p will be t only in the case when the :default option was explicitly supplied in the call to accept that invoked accept-present-default.

present-p and query-identifier are arguments that are called internally by the accept-values mechanism that this method needs to handle. The form of present-p as it is handed down (internally) from accepting-values is a list of the presentation type of the accepting-values query (accept-values-choice) and the query object itself, e.g., (list 'accept-values-choice av-query-object). The value of query-identifier is an internal accept-values query identifier object.

presentation-type-history Presentation

presentation-type-history type

Summary: This method returns a history object for the presentation type type, or nil if there is none.

presentation-refined-position-test Presentation

presentation-refined-position-test (record presentation-type x y)

Summary: This method is supplied when the user wants a more precise test of whether the supplied coordinate arguments (x and y) are "contained" by the record argument. Without this test, whether or not a position is within a record is determined by simply by seeing if the position is inside the bounding-rectangle of that record.

highlight-presentation Presentation

highlight-presentation type record stream state

Summary: This method is responsible for drawing a highlighting box around the presentation record on the output recording stream stream. state will be either :highlight or :unhighlight.

See 7.4 Advanced Topics for more in-depth material relating to defining presentation methods.

7.2.2 CLIM Operators for Defining Presentation Type Abbreviations

You can define an abbreviation for a presentation type for the purpose of naming a commonly used cliche. The abbreviation is simply another name for a presentation type specifier.

Exported functions that call expand-presentation-type-abbreviation allow abbreviations.

define-presentation-type-abbreviation Macro

define-presentation-type-abbreviation name parameters equivalent-type &key options

Summary: Defines a presentation type that is an abbreviation for the presentation type specifier that is the value of equivalent-type.

Where presentation type abbreviations are allowed, equivalent-type and abbreviations are exactly equivalent and can be used interchangeably.

name must be a symbol and must not be the name of a CLOS class.

The equivalent-type form might be evaluated at compile time if presentation type abbreviations are expanded by compiler optimizers. Unlike inherit-from, equivalent-type can perform arbitrary computations and is not called with dummy parameter and option values. The type specifier produced by evaluating equivalent-type can be a real presentation type or another abbreviation. If the type specifier does not include the standard option :description, the option is automatically copied from the abbreviation to its expansion.

Note that you cannot define any presentation methods on a presentation type abbreviation. If you need methods, use define-presentation-type instead.

define-presentation-type-abbreviation is used to name a commonly used cliche. For example, a presentation type to read an octal integer might be defined as:

(define-presentation-type-abbreviation octal-integer 
  (&optional low high)
  `((integer ,low ,high) :base 8 
    :description "octal integer")) 

None of the arguments, except equivalent-type, is evaluated.

When writing presentation type abbreviations, it is sometimes useful to let CLIM include or exclude defaults for parameters and options. In some cases, you may also find it necessary to "expand" a presentation type abbreviation. The following three functions are useful in these circumstances.

expand-presentation-type-abbreviation-1 Function

expand-presentation-type-abbreviation-1 type &optional environment

Summary: If the presentation type specifier type is a presentation type abbreviation, or is an and, or, sequence, or sequence-enumerated that contains a presentation type abbreviation, then expand-presentation-type-abbreviation-1 expands the type abbreviation once and returns two values, the expansion and t. If type is not a presentation type abbreviation, then the values type and nil are returned. env is a macro-expansion environment, as in macroexpand.

expand-presentation-type-abbreviation Function

expand-presentation-type-abbreviation type &optional environment

Summary: expand-presentation-type-abbreviation is like expand-presentation-type-abbreviation-1, except that type is repeatedly expanded until all presentation type abbreviations have been removed.

make-presentation-type-specifier Function

make-presentation-type-specifier type-name-and-parameters &rest options

Summary: A convenient way to make a presentation type specifier including only non-default options. This is only useful for abbreviation expanders, not for the :inherit-from clause of define-presentation-type. type-name-and-parameters is a presentation type specifier that must be in the form of:

(type-name parameters\…)

options is a list of alternating keywords and values that are added as options to the specifier. If a value is equal to type-name's default, that option is omitted, producing a more concise presentation type specifier.


CLIM 2.0 User Guide - 01 Dec 2021 19:38:57