mirror of https://github.com/texmacs/doc.git
Reorganization of contextual overloading system, part I
This commit is contained in:
parent
ea66b07bac
commit
0f698d9a42
|
@ -1,4 +1,4 @@
|
|||
<TeXmacs|1.0.7.11>
|
||||
<TeXmacs|1.0.7.14>
|
||||
|
||||
<style|tmdoc>
|
||||
|
||||
|
@ -30,99 +30,52 @@
|
|||
<\scm-code>
|
||||
(tm-define (hello) (insert "Hello"))
|
||||
|
||||
(tm-define (hello) (:mode in-math?) (insert-go-to "hello()" '(6)))
|
||||
(tm-define (hello) (:require (in-math?)) (insert-go-to "hello()" '(6)))
|
||||
</scm-code>
|
||||
|
||||
Here we recall that the two definitions may be put inside different
|
||||
modules. Notice also that the contextual overloading system considers the
|
||||
implementation of <scm|hello> inside math mode to be more <em|particular>
|
||||
than the default implementation. In case when several implementations match
|
||||
their respective conditions, the most particular implementation will be
|
||||
chosen.
|
||||
|
||||
Currently, <TeXmacs> supports two major types of conditions:
|
||||
|
||||
<\description>
|
||||
<item*|Conditions on the mode>
|
||||
|
||||
A <em|<TeXmacs> mode> corresponds to a simple predicate without
|
||||
arguments, together with a finite number of other, less particular, modes
|
||||
which are implied by it. New modes can be defined using the instruction
|
||||
|
||||
<\scm-code>
|
||||
(texmacs-modes <em|mode>% <em|cond> <em|submode-1> ... <em|submode-n>)
|
||||
</scm-code>
|
||||
|
||||
For instance, we might define a new mode <scm|inside-theorem?> as follows
|
||||
|
||||
<\scm-code>
|
||||
(texmacs-modes inside-theorem% (inside? 'theorem) in-text%)
|
||||
</scm-code>
|
||||
|
||||
Some standard modes are <scm|always?>, <scm|in-source?>, <scm|in-text?>,
|
||||
<scm|in-math?>, <scm|in-prog?>. There is also a special mode
|
||||
<scm|prevail?> which is always satisfied, but nevertheless considered as
|
||||
more particular than all other modes.
|
||||
|
||||
<\remark>
|
||||
Currently, modes necessarily terminate by the <verbatim|?> character.
|
||||
However, in the <scm|texmacs-modes> instruction, the <verbatim|?> has
|
||||
to be replaced by a <verbatim|%>. This may change in a future version
|
||||
of <TeXmacs>.
|
||||
</remark>
|
||||
|
||||
<item*|Conditions on the arguments of the function>
|
||||
|
||||
This type of contextual overloading is closest to the more classical
|
||||
concept of overloading used by languages like <name|C++>. Although one
|
||||
may overload on the types of the arguments, it is also possible to impose
|
||||
more general conditions on the arguments. For instance, one may sometimes
|
||||
wish to write the following kind of code:
|
||||
|
||||
<\scm-code>
|
||||
(tm-define (my-replace what by)
|
||||
|
||||
\ \ <em|default-implementation>)
|
||||
|
||||
\;
|
||||
|
||||
(tm-define (my-replace what by)
|
||||
|
||||
\ \ (:require (== what by))
|
||||
|
||||
\ \ (noop))
|
||||
</scm-code>
|
||||
</description>
|
||||
|
||||
\;
|
||||
|
||||
In cases of conflict, we notice that the contextual overloading system
|
||||
first dispatches on mode and then on the arguments on the function. For
|
||||
instance, consider a routine <scm|foo> defined<nbsp>by
|
||||
The order in which routines are overloaded is important. <TeXmacs> first
|
||||
tries the latest (re)definition. If this definition does not satisfy the
|
||||
requirements (<scm|(in-math?)>, in our case), then it tries the before last
|
||||
(re)definition, and so on until an implementation is found which matches
|
||||
the requirements. For example, if we invert the two declarations in the
|
||||
above example, then the general unconditional definition of <scm|hello>
|
||||
will always prevail. If the two declarations are made inside different
|
||||
modules, then it is up to the user to ensure that the modules are loaded in
|
||||
an appropriate order.
|
||||
|
||||
Inside a redefinition, it is also possible to access the former definition
|
||||
using the keyword <scm|former>. In particular, the code
|
||||
|
||||
<\scm-code>
|
||||
(tm-define (foo t) (:mode in-math?) <em|implementation-1>)
|
||||
(tm-define (hello)
|
||||
|
||||
(tm-define (foo t) (:require (tree-is? t 'frac)) <em|implementation-2>)
|
||||
\ \ (if (in-math?) (insert-go-to "hello()" '(6)) (former)))
|
||||
</scm-code>
|
||||
|
||||
Then the first implementation will be used when <scm|foo> is called for a
|
||||
fraction in math mode. In cases of conflict when no implementation is
|
||||
preferrable <em|a priori>, the last implementation prevails. For instance,
|
||||
consider a predicate <scm|(gnu? t)> which implies another predicate
|
||||
<scm|(hairy? t)>, and assume that we want to overload a function <scm|(foo
|
||||
t)> for both predicates. Then we may use something such as
|
||||
is equivalent to the second declaration in our example.
|
||||
|
||||
Contextual overloading generalizes more classical overloading on the types
|
||||
of the arguments, such as <name|C++> style polymorphism. Although one may
|
||||
overload on the types of the arguments, it is also possible to impose more
|
||||
general conditions on the arguments. For instance, one may sometimes wish
|
||||
to write the following kind of code:
|
||||
|
||||
<\scm-code>
|
||||
(tm-define (foo t) (:require (hairy? t) <em|implementation-1>)
|
||||
(tm-define (my-replace what by)
|
||||
|
||||
(tm-define (foo t) (:require (gnu? t)) <em|implementation-2>)
|
||||
\ \ <em|default-implementation>)
|
||||
|
||||
\;
|
||||
|
||||
(tm-define (my-replace what by)
|
||||
|
||||
\ \ (:require (== what by))
|
||||
|
||||
\ \ (noop))
|
||||
</scm-code>
|
||||
|
||||
Indeed, the most particular implementation should be declared last. In the
|
||||
case when both implementations are in different files, the file with the
|
||||
definition when <scm|(gnu? t)> should include the other<nbsp>one.
|
||||
|
||||
Besides <scm|tm-define>, several other added language primitives support
|
||||
the contextual overloading mechanism. For instance, <scm|kbd-map> and
|
||||
<scm|menu-bind> support overloading on mode. The <scm|tm-define-macro> and
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
<\scm-code>
|
||||
(menu-bind insert-menu
|
||||
|
||||
\ \ (next)
|
||||
\ \ (former)
|
||||
|
||||
\ \ ---
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<TeXmacs|1.0.7.7>
|
||||
<TeXmacs|1.0.7.14>
|
||||
|
||||
<style|tmdoc>
|
||||
|
||||
|
@ -31,37 +31,9 @@
|
|||
|
||||
<paragraph*|Contextual overloading>
|
||||
|
||||
We will first describe the various options for overloading. If several
|
||||
definitions are given for the same function (or macro) <scm|foo> and
|
||||
several definitions satisfy the corresponding overloading conditions, when
|
||||
applying <scm|foo> to some arguments, then the <em|most particular>
|
||||
definition will prevail. For any of the overloading options, we will
|
||||
therefore have to specify what we mean my ``most particular''. When trying
|
||||
to find out the most particular set of options, we first sort on mode, next
|
||||
on context and finally on function arguments. Notice that sorting on
|
||||
function arguments is not yet fully implemented, so we will not discuss
|
||||
this yet.
|
||||
|
||||
<\explain>
|
||||
<scm|(:mode <scm-arg|mode>)><explain-synopsis|mode-based overloading>
|
||||
<|explain>
|
||||
This option specifies that the definition is only valid when we are in a
|
||||
given <scm-arg|mode>. New modes are defined using <scm|texmacs-modes> and
|
||||
modes can inherit from other modes. A mode <math|m<rsub|1>> is understood
|
||||
to be more particular than another mode <math|m<rsub|2>> if
|
||||
<math|m<rsub|1>> inherits from <math|m<rsub|2>>.
|
||||
</explain>
|
||||
|
||||
<\explain>
|
||||
<scm|(:match <scm-arg|pattern>)><explain-synopsis|argument based
|
||||
overloading>
|
||||
<|explain>
|
||||
This option specifies that one necessary condition for the declaration to
|
||||
be valid valid is that the arguments match the specified pattern
|
||||
according to the primitive <scm|match?>. We have not yet implemented a
|
||||
function to test whether a pattern is a restriction of another pattern,
|
||||
so ambiguous overloads cannot be resolved.
|
||||
</explain>
|
||||
We will first describe the most important <scm|:require> option for
|
||||
contextual overloading, which was already discussed
|
||||
<hlink|before|../overview/overview-overloading.en.tm>.
|
||||
|
||||
<\explain>
|
||||
<scm|(:require <scm-arg|cond>)><explain-synopsis|argument based
|
||||
|
@ -69,12 +41,11 @@
|
|||
<|explain>
|
||||
This option specifies that one necessary condition for the declaration to
|
||||
be valid is that the condition <scm-arg|cond> is met. This condition may
|
||||
involve the arguments of the function. Again, ambiguous overloads cannot
|
||||
be resolved.
|
||||
involve the arguments of the function.
|
||||
|
||||
As an example, let us consider the following definitions:
|
||||
|
||||
<\scm-fragment>
|
||||
<\scm-code>
|
||||
(tm-define (special t)
|
||||
|
||||
\ \ (and-with p (tree-outer t)
|
||||
|
@ -96,7 +67,7 @@
|
|||
\ \ (:require (tree-is? t 'rsub))
|
||||
|
||||
\ \ (tree-set! t `(rsup ,(tree-ref t 0))))
|
||||
</scm-fragment>
|
||||
</scm-code>
|
||||
|
||||
The default implementation of <scm|special> is to apply <scm|special> to
|
||||
the parent <scm|p> of <scm|t> as long as <scm|t> is not the entire
|
||||
|
@ -107,29 +78,20 @@
|
|||
calling <scm|special> will swap the numerator and the denominator. On the
|
||||
other hand, if your cursor is inside a subscript inside a fraction, then
|
||||
calling <scm|special> will change the subscript into a superscript.
|
||||
</explain>
|
||||
|
||||
<\explain>
|
||||
<scm|(:case <scm-arg|label-1> ... <scm-arg|label-n>)><explain-synopsis|argument
|
||||
based dispatching>
|
||||
<|explain>
|
||||
This is a very special case of the <scm|:match> option, where we require
|
||||
the first argument to be a compound hybrid tree whose root label is
|
||||
amongst <scm-arg|label-1> until <scm-arg|label-n>. Besides a simplified
|
||||
syntax, the implementation of <scm|:case> is done using a dispatch via a
|
||||
hash table. When appropriate, you should therefore priviledge <scm|:case>
|
||||
over the general form of <scm|:match>. A typical situation when
|
||||
<scm|:case> is useful is when writing a converter <scm|tm-\<gtr\>foo> of
|
||||
<TeXmacs> trees into your own foormat: specific converters for given tags
|
||||
can be added using
|
||||
When the conditions of several (re)declarations are met, then the last
|
||||
redeclaration will be used. Inside a redeclaration, one may also use the
|
||||
<scm|former> keyword in order to explicitly access the former value of
|
||||
the redefined symbol.
|
||||
|
||||
<\scm-fragment>
|
||||
(tm-define (tm-\<gtr\>foo t)
|
||||
|
||||
\ \ (:case frac)
|
||||
|
||||
\ \ <with|prog-font-shape|italic|tm-to-foo-converter-for-frac>)
|
||||
</scm-fragment>
|
||||
<\explain>
|
||||
<scm|(:mode <scm-arg|mode>)><explain-synopsis|mode-based overloading>
|
||||
<|explain>
|
||||
This option is equivalent to <scm|(:require (<scm-arg|mode>))> and
|
||||
specifies that the definition is only valid when we are in a given
|
||||
<scm-arg|mode>. New modes are defined using <scm|texmacs-modes> and
|
||||
modes can inherit from other modes.
|
||||
</explain>
|
||||
</explain>
|
||||
|
||||
<paragraph*|Other options for function and macro declarations>
|
||||
|
@ -149,13 +111,13 @@
|
|||
expressions may be encoded inside this string by using the
|
||||
<verbatim|@>-prefix. For instance:
|
||||
|
||||
<\scm-fragment>
|
||||
<\scm-code>
|
||||
(tm-define (list-square l)
|
||||
|
||||
\ \ (:synopsis "Appends the list @l to itself")
|
||||
|
||||
\ \ (append l l))
|
||||
</scm-fragment>
|
||||
</scm-code>
|
||||
|
||||
The synopsis of a function is used for instance in order to provide a
|
||||
short help string for the function. In the future, we might also use it
|
||||
|
|
Loading…
Reference in New Issue