Namespace funnyqt.polyfns

Polymorphic functions dispatching on types of model elements.

Other Namespaces

Bidirectional transformations (BX).
Co-Evolution transformations on TGraphs.
Printing/persisting and reading/loading query results and transformation traces as EDN.
Core functions for accessing and manipulating EMF models.
Specify models extensionally.
Generic protocols extended upon many different types, and generic functions.
In-place transformation stuff.
Rule-base out-place transformations similar to ATL or QVTo.
Graph Pattern Matching on arbitrary models.
Generic query functions like regular path expressions & quantified expressions.
EMF-specific query functions
TG-specific query functions
Relational Model Querying.
Core functions for accessing and manipulating TGraphs.
Generic utility functions, e.g., for signaling errors, debugging, and profiling,
Model visualization functions.
Convert XML to DOM-like TGraphs.
Index Page
Alphabetic Var Index

Public Vars

Usage Documentation

Polymorphic functions dispatching on types of model elements.

Every polyfn must be declared first, and then arbitrary many implementations
for several metamodel types may be provided.  A polyfn must have a model
element as first argument which is used to dispatch among implementations.

Every polyfn has to be declared once using `declare-polyfn`, and then
implementations for specific types map be provided using `defpolyfn`.  When a
polyfn is called, the most specific implementation for the model element type
is invoked.  In case of multiple inheritance, a class inheriting two different
implementations is an error.  It must provide an own implementation in order
to remove ambiguities.


Let's consider our metamodel has the types TypeA and TypeB, and a TypeC that
extends both TypeA and TypeB.  Furthermore, TypeD extends TypeC.  Lastly,
there's a TypeE with no inheritance relationships.

  ;; Declare a polyfn
  (declare-polyfn foo [elem ...]
    ;; Optional default behavior
    (str "Don't know how to handle " elem))

  ;; Define implementations for several types
  (defpolyfn foo TypeA [elem ...] ...)
  (defpolyfn foo TypeB [elem ...] ...)
  (defpolyfn foo TypeC [elem ...] ...)

Then, (foo objOfTypeA) invokes the first implementation, (foo objOfTypeB)
invokes the second implementation, both (foo objOfTypeC) and (foo objOfTypeD)
invoke the third implementation, and (foo objOfTypeE) invokes the default
behavior.  If no optional default behavior is specified, an exception is

An impl can also be defined for many types at once.  In that case, a list of
types is provided:

  (defpolyfn foo (TypeX TypeY TypeZ) [elem ...] ...)
Back to top

Details of Public Vars

Function: build-polyfn-dispatch-table


  (build-polyfn-dispatch-table polyfn-var cls)


  No docs attached.
Back to top View Source

Macro: declare-polyfn


  (declare-polyfn name doc-string? attr-map? [model-elem & more] & body)


  Decares a polymorphic function dispatching on a model element type.
  `name` is the name of the new polyfn, an optional `doc-string` may be
  provided.  The argument list's first element must be the model element on
  whose type the dispatch is done.  Polymorphic functions for several metamodel
  types are provided later using `defpolyfn`.  If an optional `body` is
  provided, this is executed if no implementation for `model-elem`s type was
  added using `defpolyfn`.  The default behavior in that case (i.e., `body`
  omitted) is to throw an exception.

  By default, when a polyfn is called for the very first time a dispatch table
  is computed which maps metamodel classes to the implementation for that type.
  If the metamodel changes afterwards, then the dispatch table might be wrong
  and needs to be recomputed which will happen if one reset!s
  the ::polyfn-dispatch-table metadata atom to nil.  One can also omit building
  a dispatch table by adding :no-dispatch-table metadata to the polyfn name or
  by setting it to true in the polyfn's `attr-map`.  In that case, the
  implementation is computed with each call and never cached.
Back to top View Source

Macro: defpolyfn


  (defpolyfn name type [model-elem & more] & body)
  (defpolyfn name (type1 type2 ...) [model-elem & more] & body)


  Defines an implementation of the polyfn `name` for objects of type `type`
  or objects of `type1`, `type2`, etc.
  The polyfn has to be already declared using `declare-polyfn`.  `type` is a
  fully qualified type name that is used to check if the polyfn implementation
  is matching the type of `model-elem`.  The arity of the argument vector has
  to match the one of the corresponding `declare-polyfn`.
Back to top View Source

Function: find-polyfn-impl


  (find-polyfn-impl polyfn-sym spec-map type)
  (find-polyfn-impl polyfn-sym spec-map orig-type type)


  No docs attached.
Back to top View Source