Dana programs are structured as collections of
components. Each Dana source file represents one such component. Each component implements one or more instantiable
micro-components where each microcom is, in turn, a collection of one or more
interfaces. Microcoms can be thought of like “objects” in languages like Java, except that microcoms are instantiated by interface and the only requirement for compatability between two microcoms is that they share a common primary interface; they may have different secondary interfaces and different internal state. We generally use the more familiar term “object” throughout this documentation.
An interface type is a collection of one or more function prototypes (interface types cannot contain any “fields”). Objects therefore tend to represent behaviour in Dana programs while data tends to be represented by record types.
As well as implementing a collection of objects, each component declares a number of
required interfaces, representing other components on which the functionality of this component depends. These explicit required interfaces are the basis of Dana's core purpose: enabling unparalleled re-usability of code and supporting meta-software-reasoning. These capabilities stem from the principle that a component never resolves its own dependencies, but rather an external entity (a meta-program) is responsible for this. Meta-programs can examine and seamlessly re-wire dependencies to other components while software is running. Meta-programs are themselves composed of Dana components.
Dana programs typically therefore consist of a meta-program, which is generic behaviour responsible for configuring the components that implement a system's behaviour, and an application-specific program which represents the specialised logic for your particular problem – all the components of which are loaded and interconnected by the meta-program.