user_guide:extend:polymorphic

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
user_guide:extend:polymorphic [2019/01/25 16:02] – ↷ Page moved from reference:polymorphic to user_guide:extend:polymorphic oroehriguser_guide:extend:polymorphic [2021/01/12 15:46] (current) – [Labels] gawrilow
Line 1: Line 1:
 ====== Polymorphic Functions ====== ====== Polymorphic Functions ======
  
-In the rulefiles you can define polymorphic functions and methods resembling, to some extent, the features of programming languages C++ or Java.  The general syntax is described [[reference:rulefiles#functions|among other rulefile elements]], here we discuss the definition and overload resolution in deeper details.+In the rulefiles you can define polymorphic functions and methods resembling, to some extent, the features of programming languages C++ or Java.  The general syntax is described [[rulefiles#functions|among other rulefile elements]], here we discuss the definition and overload resolution in deeper details.
  
 ===== Definition elements ===== ===== Definition elements =====
Line 8: Line 8:
 category label '':'' name ''<'' type parameters > ''['' typecheck ''] ('' signature '') : '' attributes category label '':'' name ''<'' type parameters > ''['' typecheck ''] ('' signature '') : '' attributes
  
-//category// can be ''method'', ''function'', etc., as described in the [[reference:rulefiles#functions|general syntax rules]].+//category// can be ''method'', ''function'', etc., as described in the [[rulefiles#functions|general syntax rules]].
  
 Name and signature are mandatory, while label, type parameters, and attributes are optional. Name and signature are mandatory, while label, type parameters, and attributes are optional.
  
 ===== Signature ===== ===== Signature =====
-The signature describes the number and types of arguments expected by an overloaded instance, as well as default values for optional arguments.  The syntax of the most primitive elements is borrowed from the standard perl //function prototypes//, enriched with further elements for [[reference:rulefiles#type_definitions|property types]] and "big" object types, [[reference:rulefiles#fuctions|option lists]] and other keyword arguments, etc.  The "standard" elements are encoded with one-symbol codes, they can be written in traditional style glued together, or in a more legible style with commas and white spaces in between.  Advanced elements must be separated with commas.+The signature describes the number and types of arguments expected by an overloaded instance, as well as default values for optional arguments.  The syntax of the most primitive elements is borrowed from the standard perl //function prototypes//, enriched with further elements for [[user_guide:extend:rulefiles#type_definitions|property types]] and "big" object types, [[user_guide:extend:rulefiles#fuctions|option lists]] and other keyword arguments, etc.  The "standard" elements are encoded with one-symbol codes, they can be written in traditional style glued together, or in a more legible style with commas and white spaces in between.  Advanced elements must be separated with commas.
  
 Signatures of pure perl functions and wrapped C++ functions share many common elements, but also have few differences.  Unless mentioned explicitly, the elements described below may be used in both cases.  C++ functions are recognized by the ''c++'' [[#attributes|attribute]]. Signatures of pure perl functions and wrapped C++ functions share many common elements, but also have few differences.  Unless mentioned explicitly, the elements described below may be used in both cases.  C++ functions are recognized by the ''c++'' [[#attributes|attribute]].
Line 34: Line 34:
   :: Denotes arbitrarily many (trailing) arguments of any types.  This element must be the last one among all arguments in the signature.  This is only allowed with functions implemented in perl.  For C++ functions, an appropriate container type (Array, Vector, etc.) must be used.   :: Denotes arbitrarily many (trailing) arguments of any types.  This element must be the last one among all arguments in the signature.  This is only allowed with functions implemented in perl.  For C++ functions, an appropriate container type (Array, Vector, etc.) must be used.
   ? ''%''option_list   ? ''%''option_list
-  :: Refers to an [[reference:rulefiles#functions|option list]] defined in the rulefiles before.  Trailing argument pairs of the form ''%%keyword => value%%'' with keywords matching the keys of the option list are collected together in an anonymous hash map, which is passed to the function body by reference.+  :: Refers to an [[rulefiles#functions|option list]] defined in the rulefiles before.  Trailing argument pairs of the form ''%%keyword => value%%'' with keywords matching the keys of the option list are collected together in an anonymous hash map, which is passed to the function body by reference.
   .. A signature may contain more than one option list reference.  The arguments passed to the function are reorganized to match the keys of each option list; each anonymous hash map is then passed to the function body per separate reference.  If the option lists share some keys, the keyword arguments matching several lists are copied in all corresponding hash maps.   .. A signature may contain more than one option list reference.  The arguments passed to the function are reorganized to match the keys of each option list; each anonymous hash map is then passed to the function body per separate reference.  If the option lists share some keys, the keyword arguments matching several lists are copied in all corresponding hash maps.
   .. If the argument list already contains a reference to a hash map at the position where keyword-value pairs are expected, this reference is passed unchanged and unchecked to the function body; this allows to gradually define families of polymorphic functions delegating work to each other without expensive re-checking and reordering of keyword arguments.   .. If the argument list already contains a reference to a hash map at the position where keyword-value pairs are expected, this reference is passed unchanged and unchecked to the function body; this allows to gradually define families of polymorphic functions delegating work to each other without expensive re-checking and reordering of keyword arguments.
Line 103: Line 103:
  
 ==== Typechecks ==== ==== Typechecks ====
-A type checking clause may be specified for functions with type parameters.  It can contain an expression performing arbitrary checks on the deduced or explicitly given type parameters, e.g. by calling a [[reference:rulefiles#typechecks|type checking function]].  Default values for type parameters, if applicable, are assigned prior to evaluation of the type checking expression.  The expression should return a boolean value signaling success or failure; it must not raise exceptions.  In the successful case, the function body is executed; otherwise, the function is discarded from candidates and the overload resolution continues.+A type checking clause may be specified for functions with type parameters.  It can contain an expression performing arbitrary checks on the deduced or explicitly given type parameters, e.g. by calling a [[user_guide:extend:rulefiles#typechecks|type checking function]].  Default values for type parameters, if applicable, are assigned prior to evaluation of the type checking expression.  The expression should return a boolean value signaling success or failure; it must not raise exceptions.  In the successful case, the function body is executed; otherwise, the function is discarded from candidates and the overload resolution continues.
  
 Besides performing pure checks, the type checking clause may upgrade the deduced parameter values by calling a meta-function ''type_upgrade<''T'','' other type''>'' This meta-function upgrades T to //other type// if it is allowed by upgrade relations and T has not been explicitly specified by the caller.  Even if the upgrade is not possible, this function succeeds and simply returns the unchanged type of T. Besides performing pure checks, the type checking clause may upgrade the deduced parameter values by calling a meta-function ''type_upgrade<''T'','' other type''>'' This meta-function upgrades T to //other type// if it is allowed by upgrade relations and T has not been explicitly specified by the caller.  Even if the upgrade is not possible, this function succeeds and simply returns the unchanged type of T.
Line 159: Line 159:
  
 ===== Labels ===== ===== Labels =====
-Labels allow to provide several alternative implementations for the same function or for a family of functions with compatible signatures.  The choice of the function to be called is governed by active preference lists (cf. user commands [[:general#preferences|prefer, prefer_now, show_preferences]]).  First, all candidates with the label of the highest rank are considered according to usual overload resolution rules.  If none has matched the argument list, the candidates with the label of the next lower rank are considered, and so on.+Labels allow to provide several alternative implementations for the same function or for a family of functions with compatible signatures.  The choice of the function to be called is governed by active preference lists (cf. user commands [[:user_guide:howto:shell_custom#preferences|prefer, prefer_now, show_preferences]]).  First, all candidates with the label of the highest rank are considered according to usual overload resolution rules.  If none has matched the argument list, the candidates with the label of the next lower rank are considered, and so on.
  
 Labels are mandatory for //global methods// The overload resolution for global methods runs slightly differently from other functions.  The application first calls ''$method=Overload::Global:://NAME//(//args//%%...%%)'' to obtain the code reference pointing to the currently preferred method matching the given list of arguments.  Then it creates an object of the corresponding class using something like ''%%$object=method_owner($method)->new(...);%%'' or retrieves a suitable object in whatever appropriate way, and finally calls the method, passing the obtained object as a leading argument: ''%%$method->($object, %%//args//%%...);%%'' Labels are mandatory for //global methods// The overload resolution for global methods runs slightly differently from other functions.  The application first calls ''$method=Overload::Global:://NAME//(//args//%%...%%)'' to obtain the code reference pointing to the currently preferred method matching the given list of arguments.  Then it creates an object of the corresponding class using something like ''%%$object=method_owner($method)->new(...);%%'' or retrieves a suitable object in whatever appropriate way, and finally calls the method, passing the obtained object as a leading argument: ''%%$method->($object, %%//args//%%...);%%''
  
 Alternatively, the application can request the full list of candidate methods from ''Overload::resolve_global(//NAME//, [ //args//%%...%% ])'' ,  the argument list must be passed by reference.  The result will be a reference to a list of method references, ordered according to the current label ranking. Alternatively, the application can request the full list of candidate methods from ''Overload::resolve_global(//NAME//, [ //args//%%...%% ])'' ,  the argument list must be passed by reference.  The result will be a reference to a list of method references, ordered according to the current label ranking.
 +
  • user_guide/extend/polymorphic.1548432144.txt.gz
  • Last modified: 2019/01/25 16:02
  • by oroehrig