Macroes

The macro builds expression and calculates its value

  Often happens it is useful not to write out calculated expression manually, and to generate it by means of the program. This idea of automatic dynamic programming is especially well realised in a Lisp as the program in this language also is represented in the form of the list. Thus calculation of such expression or its part if necessary can be prevented locking ('), for example, for the purpose of expression conversion. For calculation of the generated expression the programmer always can call the interpreter (eval). The special ways of processing of arguments provided in a Lisp open possibility for a combination of various methods.
  The enumerated possibilities can be used in a Lisp and without special resources. However most naturally program creation of expressions is carried out by means of special macroes. Outwardly macroes are defined and used the same as functions, the way of their calculation differs only. Calculating macro call, at first from its arguments the form set by definition of a macro is under construction. As a result of call value of this form, instead of the form as would be at functions evaluation comes back. Thus, the macro is calculated as though in two stages.
  Macroes represent the abstract mechanism with which help it is possible to define creation and calculation of any (computable) form or the whole program.
  Macroes give the chance to expand syntax and semantics of a Lisp and to use new forms of sentences suiting for the solved task. Abstraction of such character name as abstraction of problem area, and the extension of language defined by them a Lisp - the built in language.
  Macroes are a powerful working tool of programming. They give the chance to write the compact programs oriented to the task which will automatically be transformed to more complex, but effective code closer to the computer. However the difficulties and dangers too are linked to their usage. Forms created in the course of calculations are often difficult for seeing directly from definition of a macro or from the form of its call.

The macro does not calculate arguments

  Syntax of definition of a macro looks the same as syntax used at definition of functions of the form defmethod:

  (class-name defmacro macro-name arguments-list body)

  Macro call coincides under the form with function call, but its calculation differs from function call calculation. The first difference consists that in a macro arguments are not calculated. The macro body is calculated with arguments in that sort as they are written. Methods always preliminary calculate the arguments and if there is a necessity that the argument was not calculated, such forms are defined by means of a macro.

The macro is calculated twice

  The second difference of a macro from function is linked to way of calculation of a body of a macro. Calculation of call of a macro consists of two by turns stages. At the first stage calculation of a body of definition with arguments from call in the same way, as well as for function is carried out. This stage name as a stage of the extension or macro disclosure as the arising form, as a rule, is more and more difficult the initial form of call. Often speak and about translation of macroes as at a stage of the extension the macrocall is assembled in some computable expression. At the second stage the opened form received from call which value comes back as value of all macrocall is calculated.
  Let's define, for example, a macro setqq which works like setq, but locks calculation and the second argument:

>(nil setq  list)
nil
>(nil defmacro  setqq (x  y)
  `(nil setq  ,x  ',y))
(macro  (x  y)  `(nil setq  ,x ',y))
>(nil setqq list  (a  b c)) ; setqq does not calculate the arguments
(a  b c)
>list
(a  b c)

  After a stage of the extension of macrocall value of a body of a macro was

  (nil setq list '(a b c))

  At the second stage this program created form is calculated by usual image and its value comes back as value of call of a macro. In this case the arisen form has a side effect.
  So, the macro is a form which during calculation replaces on new, usually more complex form which then is calculated by usual image.

Recursive macroes and proceeding calculations

  Arising during the macro extension new expression can contain again macrocall, probably recursive. Macrocalls containing in the extension lead at the second stage of calculations to new macrocalculations. By means of a recursive macro it is possible to carry out the extension dynamically depending on parametres, and proceeding macrocalculation. For example, copying of a top level of the list could be defined a following recursive macro:

>(nil defmacro  copy  ())
(macro  nil)
>('cons defmacro  copy  ()
  (nil  list  nil 'cons ; call  cons  as the extension
    `',(this  first)
    (nil  list  `',(this  rest) 'copy)))
(macro  nil (nil  list  nil 'cons `',(this  first)  (nil  list  `',(this  rest) 'copy)))
>('(a b c)  copy)
(a  b c)

  As the first extension the expression containing new macrocall is formed:

  (nil cons 'a ('(b c) copy))

  Thus, the extension at the second stage of calculations leads to recursive macrocall. The recursion is ended on call (nil copy) which value of the extension is nil.

Lambda-list and macro keywords

  As at definition and function call, in case of macroes in lambda-list it is possible to use same &rest.
  Parametre &rest it is used for instructions on in advance indefinite quantity of arguments. This mechanism is applied and to definition of the forms, not which all arguments need to be calculated or in which arguments are desirable for handling in the non-standard image. For example, in the usual form cond predicates are calculated only until the first value which is distinct from nil and false will be received. For definition of such forms of function don't suit.
  Let's set the simple form cond by means of a following recursive macro:

(nil  defmacro  cond  (&rest  branches)
  (nil  if  (nil  consp branches)
    (nil  let ((branch  (branches first)))
      (nil  if  (nil  eval  (branch first))
        (nil  list* nil 'progn  (branch rest))
        (nil  list* nil 'cond (branches rest))))))

Back blocking resolves intermediate calculations

  At macro disclosure the considerable quantity of the calls of functions enclosed each other cons, first, rest, list, + and others is usually used. Therefore at extension construction it is possible to be mistaken easily, and the macrodefinition becomes less transparent. For simplification of a writing of macroes in a Lisp the special mechanism of locking of calculations as which name as return locking is accepted and which is marked unlike usual locking (') (return) apostrophe inclined in another side ` (back quote).
  Inside back locked expression it is possible to cancel locally at will locking of calculations, differently in some subexpression again to carry out calculations. From here there is also a name of return locking. Locking cancellation is marked with a comma , before each subexpression intended for calculation. The comma gives possibility for a while to switch in a normal state of calculations. An example:

>'(is not calculated  (3  + 4)) ; ordinary ' it is not cancelled
(is not calculated  (3  + 4))
>`(is possible  to  calculate (3  + 4)) ; ` operates as usual locking
(is possible  to  calculate (3  + 4))
>`(is desirable to  calculate ,(3 + 4)) ; , before expression leads to its calculation
(is desirable to  calculate 7)

  In expanded expression at return locking of expression from an anticipating comma replacing on their values. It is possible to name usage of an anticipating comma as substituting cancellation of locking. Except a comma it is possible to use a comma together with @ (at-sign) sign of joining of the subexpression. Expression before which there is a joining tag ,@, is calculated by usual image, but the received expression joins finite expression in the same way as it is made by function +. So external brackets of list value will disappear, and units become units of the list of a top level. Such form of cancellation of locking name connecting. We will give an example:

>(nil setq  x '(new units))
nil
>`(to include ,x  in  the list) ; substituting cancellation
(to include (new  units)  in  the list)
>`(to include ,@x in  the list) ; connecting cancellation
(to include new units in  the list)

  Locking of calculations and cancellation signs are defined in a Lisp as reading macroes. To study ways of creation of expressions it is possible, setting the expression interpreter in which inside ' return locking contains. For example:

>'`(a (b  ,c))
`(a (b  ,c))

  As value the hierarchy of calls of the system functions which calculation of value is interfered by an apostrophe turns out.

The sample it is convenient to use for definition of macroes

  Back locking is a convenient resource of creation of a macro. With its help the macro can be defined in the form close to sort of its opened expression. For example, the macro list can be defined very simply:

(nil  defmacro  list  (&rest  args)
  (nil  if  (nil  consp args)
    `(nil cons  ,(args  first)
      ,(nil list* nil 'list (args rest)))))

  Back locking gives possibility to define the opened expression in the form of the sample in whom dynamically filled forms are marked by a comma. It helps to avoid a complex combination of calls of functions cons, list and others.
  Back locking is used not only in macrodefinitions. For example, construction of results for function writeln often leads to usage of calls cons, list and other functions. We come nearer again with return locking to definitive output sort:

>('stream defmethod add-and (x  y)
  (this writeln `(,x  and ,y)))
(lambda (x  y)  (this writeln `(,x  and ,y)))
>(cout  add-and 'Bonnie  'Clyde)
(bonnie and clyde)
STREAM:Stdout

  add-and would be possible to define and a following macro for which apostrophes before arguments are not necessary:

>('stream defmacro  add-and (x  y)
  `(,this writeln '(,x  and ,y)))
(macro  (x  y z)  `(,this writeln '(,x  ,y  and ,z)))
>(cout  add-and Bonnie  Clyde)
(bonnie and clyde)
STREAM:Stdout

Macroes with a side effect

  The interesting type of macroes is derivated by macroes with a side effect, or the macroes changing definition. As, changing, they simultaneously delete something, them still name structure-destroying as macroes.
  By means of a suitable side effect it is often possible to receive more effective solution both in macroes, and in operation with structure-destroying functions. However to use them it is necessary very attentively, differently the received effect becomes for the program destroying in literal sense of this word.
  Usually the Lisp interpreter expands macrocalls at each call anew, that in some situations can be too ineffective. Programming of such macro with engaging of a side effect can become alternative solution, which substitutes by means of pseudo-functions ( setfirst, setrest, etc.) macrocall on its extension. Such macroes are not present need to expand each time as by following call of a macro on a macrocall place there will be an extension received by the first call. For example:

>('cons defmacro  the-first ()
  `(',this  first))
(macro  nil `(',this  first))
>('(a b c)  the-first)
a
>('cons defmethod write-first ()
  (cout writeln (this the-first)))
(lambda nil (cout writeln (this the-first)))

  By these definitions at each function call write-first is made the macro extension the-first:

>('(a b c)  write-first)
a
STREAM:Stdout

  Let's transform now a macro the-first in structure-destroying a macro:

('cons  defmacro  the-first (&whole expression)
  ((expression  rest) setfirst  'first)
  expression)

  The macro extension happens now only at the first function call write-first, which as a side effect will transform the form (this the-first) in a body write-first to the form (this first). Calculations correspond to a situation in which write-first it would be from the very beginning defined in sort:

('cons  defmethod write-first ()
  (cout writeln (this first)))

Definition of methods by means of macroes

  Except syntactic definition of forms macroes are applied and to definition of new methods. We have already got acquainted with the main data types of a Lisp: numbers, symbols and lists. Further we as the elementary example of application of macroes for operation with data types will set a macro defaccess which defines intended for reading of property of the character the elementary function of the access which name is this property, and argument - the symbol. By means of such function of access it is possible to read property of the symbol in more simple form, than by means of the form get, namely

  (symbol property)

; Macro of definition of function of access
('symbol  defmacro  defaccess ()
  `('symbol defmethod ,this ()
    (this get ',this)))

  As a result of call of a macro we as a side effect will receive definition of a new method with the help defmethod.

>('apple  put 'color  'red) ; property assignment
red
>('color  defaccess)  ; definition by means of an access macro
(lambda nil (this get 'color))
>('apple  color)  ; property reading became easier now
red

  By means of macroes it is possible to write easily programs which form other programs and at once calculate them.