Did you know ... | Search Documentation: |
Improving on the current situation |
Whether we see options as arguments or locally scoped environment variables, the most obvious way to improve on the current situation is to provide reflective support for options: discover that an argument is an option-list and find what options are supported. Reflective access to options can be used by the compiler and development environment as well as by the runtime system to warn or throw errors.
An obvious approach to deal with options is to define the different possible option values as a type and type the argument that processes the option as list(<option_type>), as illustrated below. Considering options as types fully covers the case where we consider options as additional parameters.
:- type open_option ---> type(stream_type) | alias(atom) | ... . :- pred open(source_sink, open_mode, stream, list(open_option)).
There are three reasons for considering a different approach:
From the above, we conclude that we require reflective access to find
out whether an option is supported and valid for a particular predicate.
Possible option values must be described by types. Due to lack of a type
system, we use library(error)
to describe allowed option
values. Predicate options are declared using predicate_options/3:
Below is an example that processes the option header(boolean)
and passes all options to open/4:
:- predicate_options(write_xml_file/3, 3, [ header(boolean), pass_to(open/4, 4) ]). write_xml_file(File, XMLTerm, Options) :- open(File, write, Out, Options), ( option(header(true), Options, true) -> write_xml_header(Out) ; true ), ...
This predicate may only be used as a directive and is processed by expand_term/2. Option processing can be specified at runtime using assert_predicate_options/3, which is intended to support program analysis.
false
, the predicate becomes semidet and
fails without modifications if modifications are required.The predicates below realise the support for compile and runtime checking for supported options.
?- current_predicate_option(open/4, 4, type(text)). true.
This predicate is intended to support conditional compilation using if/1 ... endif/0. The predicate current_predicate_options/3 can be used to access the full capabilities of a predicate.
existence_error(option, OptionName)
if the option is not
supported by PI. type_error(Type, Value)
if the option is supported but
the value does not match the option type. See must_be/2.The predicates below can be used in a development environment to inform the user about supported options. PceEmacs uses this for colouring option names and values.
The library can execute a complete check of your program using check_predicate_options/0:
The library offers predicates that may be used to create declarations for your application. These predicates are designed to cooperate with the module system.
library(option)
or passes options to other
predicates that are known to process options. The process is repeated
until no new declarations are retrieved.
current_output
stream.