ArgumentModes.ArgumentModesModule
module ArgumentModes

The module provides type Mode which could be seen as an extension of Val. Mode is indended to be used as a type for a function method argument. A specialization of Mode type contains a list of accepted symbols (flags). The dispatch would choose the method only if the argument value (a Mode instance) containes only symbols from the list of accepted symbols as declared in the type of the argument.

Presumed uses of Mode:

  1. Replacement of using ordinary Symbol as a function argument as a flag parameter. Here Mode allows to explicitly declare a function argument as a set of symbols (flags) with a distinct list of accepted symbols for each of a function's methods. The dispatch process then chooses a method with respect to those lists. That way it also indirectly performs the typo control. For example, open(f, Mode(:read)), open(f, Mode(:write)), open(f, Mode(:write, :sync)) might correspond (depending on the design) to 3 different methods.

  2. The way to explicitly show in which meaning a value to a function argument is provided. This might be useful when it is not possible to distinct the meaning of an argument only by the type.

    For example, suppose a function f processes array-typed objects with arbitrary dimensions number. We might want to declare methods for both processing a single object and an iteratable collection of objects. It would be difficult to distinct the methods using only the type of the argument since f([x,y]) could both mean to process a single object [x,y] or to process two objects x and y. However, using Mode in the declaration of method for a collection, the user would be allowed to explicitly indicate what is passed in the call: f([x,y]) for a single object and f(Mode(:collection)=> [x, y]) for a collection of objects.

Series of tests showed that the current implementation of Mode fully compiles out when it used for function arguments and method dispatch, so it seems that there is no runtime overhead for using it (at least for the use cases considered in the tests).

Types

  • Mode: similar to a set of symbols (possibly, with parameters) with ability for dispatch process to choose the function method based on a value of a Mode instance.

Type constructors

  • Mode[ s₁ [=> t₁] [, s₂ [=> t₂]]... ]: declare a type specialization which would accept the symbols s₁, s₂, …. Intended to be used in a function method declaration as a type of an argument.

Instance constructors

  • Mode( s₁[=> v₁] [, v₂ [=> v₂]]... ): create an instance with symbols s₁, s₂, … and corresponding values v₁, v₂, … in it. Intended to be used in a function call as an argument value.

Operations on a Mode instance

  • m => v given m::Mode[s => Nothing]: return a new instance with single symbol in it.
  • m₁ ~ m₂: join m₁ and m₂.
  • keys(m), values(m), pairs(m): return symbols / values / pairs of symbols and values.
  • m[s₁ [, s₂]... ]: return the value of s₁ / the tuple of values of s₁, s₂, ....
  • m[]: if m contains only one value, return it; throw an ArgumentError otherwise.
  • checkmode(m, ...): check if m is a Mode and contains the prescribed symbols, and, possibly, do an action.