\section{Directed Hypergraphs and Generalized Lambda Calculus}
\p{\phantomsection\label{sOne}Historically, Lambda Calculus
represented the first formal model
of computation that was reasonably close to actual programming
languages, allowing correspondence between Lambda Calculus as a
mathematical theory and the design and implementation
of early programming languages.  Languages have evolved
considerably since then, becoming more complex both semantically
and syntactically.  Semantically, this has been reflected in
the proliferation of many variants of \mOldLambda{}-Calculus, analyzing
different features of modern programming languages \mdash{} Object
Orientation, Exceptions, call-by-name, call-by-reference,
side effects, polymorphic type systems, lazy evaluation, and
so forth.  Syntactically, code representations have evolved
which supplement Abstract Syntactic Trees \mdash{} essentially,
unreduced (beyond so-called \q{$\beta$-normal} form)
lambda expressions \mdash{} with more detailed
presentations of computer code, like Source Code Algebras and
Abstract Semantic Graphs.  This richer detail is
important not only for program execution, but also other
kinds of interaction with computer code, such as querying,
testing, scripting, and debugging.
}
\p{The classical Lambda Calculus is formulated in terms of
\q{Applicative Structures}, whose constituents are
\i{symbols} and \i{terms} \mdash{} symbols are terms, and more
complex terms are created by combining a term which
designates a \q{function} with one or more terms designating
\q{arguments}.  These arguments can be other terms, so terms
can be nested.  Applicative Structures are roughly equivalent
to mathematical formulae, or in the programming world
to simple languages in the \Lisp{} family, like \Scheme{}.
Certain symbols in Applicative Structures are subject
to \q{lambda abstraction}, which makes the Applicative
Structure into something like a programming \q{function},
where \q{calling} the function amounts to assigning values to
the abstracted symbols (which happens at runtime as a program is executed).
Upon un-abstracting all symbols an Applicative Structure can
then be \i{evaluated} \mdash{} the mathematical analogy
would be replacing symbols with
numbers in mathematical formulae.  This model of
computation describes functions which have one
list of \q{input} parameters and \q{return} one value.
}
\p{Many functions in modern computer code fit that simple profile,
but many others do not: modern languages
have multiple kinds of \q{channels}
through which \q{functions} (that is, blocks of code that can be
called from other code) can communicate with other code.  This
affects code syntax as well as semantics: to understand how one
function call interacts with its surrounding code, analyzers need to
consider more than just values explicitly passed to the function as arguments,
or bound to its return value.  For example, if the function throws an
exception, then we have to look for surrounding \try{} blocks to identify
how the exception will be handled.  We also have to consider side-effects
that may not be apparent from the function-call syntax itself.  Given
\yeqfxz{}, say, we can assume that the symbols \xSym{}, \ySym{}, and
\zSym{} are involved with the function call, but there may be other symbols
in earlier or later lines of code that are \i{also} affected by (or have an effect on)
\fFun{}.  These relations of influence are intrinsic to modern
programming language grammars.  They are
also intrinsic to Program Semantics, because to
estimate how programs will behave in different scenarios it is
necessary to consider every form of influence between
functions and values \mdash{} not just the argument-and-return semantics
of classical Lambda Calculus.
}
\p{Retrospectively, Computer Scientists see \mOldLambda{}-Calculus as a kind
of precursor to the modern theory of programming languages.  This attitude
probably distorts history to some extent \mdash{} partly because
programming languages themselves did not exist when \mOldLambda{}-Calculus
was formulated, but partly also because the original vision
for \mOldLambda{}-Calculus as a mathematical theory was less about blueprints
for calculating machines and more about \i{abstract} formulation of
calculational processes.  While there were no digital computers at the time,
there \i{was} a growing interest in mechanical computers that would soon
evolve into cryptographic machines important during the Second World War, and
then into electronic systems with designs that
that we would see as early \q{computers}.  So the
mathematicians of the time \i{could} have explored formal prototypes
for \q{computing machines}, as John von Neumann did eventually.
}
\p{It is, however, probably more accurate to describe the original
purpose of \mOldLambda{}-Calculus as a mathematical \i{simulation} of
computations, which is not the same as a mathematical \i{prototype}
for computations.  Mathematicians in the decades before WWII
investigated logical properties of computations, with particular
emphasis on what sort of problems could always be solved in
finite time, or what kind of procedures can be guaranteed to
terminate \mdash{} a \q{Computable Number}, for example, is a number
which can be approximated to any degree of precision by a terminating
function.  Similarly, a Computable Function is a function from
input values to output values that can be associated with an
always-terminating procedure which necessarily calculates the desired
outputs from a set of inputs.  The space of Computable Functions
and Computable Numbers are mathematical objects whose properties
can be studied through mathematical techniques \mdash{} for instance,
Computable Numbers are known to be a
countable field within the real numbers.
These mathematical properties are proven using a formal
description of \q{any computer whatsoever}, which has no
concern for the size and physical design of the \q{computers}
or the time required for its \q{programs}, so long
as they are finite.  Computational procedures in
this context are not actual implementations but rather
mathematical distillations that can stand in for
calculations for the purpose of mathematical analysis
(interesting and representative contemporary articles
continuing these perspectives include, e.g., \cite{MartinEscardo},
\cite{MasahitoHasegawa}, \cite{TuckerZucker}).
}
\p{This abstract perspective, however, stands at some remove
from actual code-writing.  Programs written with Object-Orientation
and Exceptions can always be \i{mathematically} replicated with
programs using only the simplest kind of language.  As a result, the
properties of more sophisticated programming languages \mdash{} in
particular, the topics formally studied within Software Language
Engineering \mdash{} lie outside the mathematical bounds of
early \mOldLambda{}-Calculus or related disciplines, such as Recursive
Function Theory (which is not to say that they cannot be mathematically
studied from other angles, such as Category Theory).  From a sufficiently
mathematized perspective \mdash{} one appropriate for, say, the
theory of Computable Numbers \mdash{} distinctions such as that
between \OO{} and
non-\OO{} procedural code disappear; the mathematical framework
is not formulated with theoretical posits that would bring these kinds
of practical \SLE{}-oriented distinctions into focus.
}
\p{However, the subsequent evolution of programming
languages \i{did} inspire the
emergence of an ever-widening circle of \mOldLambda{}-Calculus
variations, whose role was no longer to abstract away from
concrete computational implementations for the sake of
logico-mathematical investigations but
rather to provide formal specifications
for models of computation which actual programming languages
could then put into practice.  So a reasonable
history can say that \mOldLambda{}-Calculus mutated from being an
abstract model for studying Computability as a mathematical concept,
to being a paradigm for prototype-specifications of concretely
realized computing environments.
}
\p{Superficially, the earlier \mOldLambda{}-Calculus just codifies the basic practices of mathematics.  For example,
in a formula like \VolSphere{} the volume of a sphere is expressed in terms of its radius \rRad{}; but
the symbol \rRad{} is just a mnemonic which could be replaced with a different symbol without the formula
being different.  It can also be replaced by a more complex expression to yield a new formula: how much
bigger is a sphere than a cube?  Substitute the formula for a cube's half-diagonal \mdash{} \crVOverRTwo{}
where \vVol{} is its volume \mdash{} for \rRad{} in the first formula, to get \volSphCube{},
from which \vVol{} can be \mbox{subtracted or divided
(\cite{KennethAnderson}} has similar interesting examples in the context of code optimization).
}
\p{The formal review of basic mathematical notation practice
was interesting to 20th century
mathematicians at a time when general questions were first being asked about the logical
completeness and consistency of mathematical systems \mdash{} which led to mechanical
models of computing processes and eventually to computers as we know them.
The actual name of a symbol during computations is not
significant, only its structural role as an element of aggregate expressions;
so the symbol itself is \q{abstracted} \mdash{} in the above formulae, \rRad{}
has no formal meaning (the fact that it uses the first letter of
\q{radius} is incidental) and serves only as a place-holder
(the correct cube-sphere comparison depends on substituting
\crVOverRTwo{} \i{in the right place}).  Multiple computations are linked by
how names of values in one context are linked to names in another context;
\q{calling} a function essentially entails plugging names in the calling
context into names used in the called function's body.  So symbols are
\q{abstracted} in that their meaning lies only in the \mbox{chain
of name-to-name links enacted during a computation}.
}
\p{Practical programming languages, however, have many different ways of handing-off
values between function bodies.  The \q{inputs} to a function can be \q{message receivers}
as in Object-Oriented programming, or lexically scoped
values \q{captured} in an anonymous function that inherits
values from the lexical scope (loosely, the area of source code)
where its body is composed.  Functions can also \q{receive} data indirectly
from pipes, streams, sockets, network connections, database connections, or files.
All of these are potential \q{input channels} whereby a function implementation
may access a value that it needs.  In addition, functions can \q{return} values
not just by providing a final result but by throwing exceptions, writing
to files or pipes, and so forth.  To represent these myriad
\q{channels of communication} computer scientists have invented a menagerie
of extensions to \mOldLambda{}-Calculus \mdash{} \q{Sigma} calculus to model Object-Oriented
Programming; \mOldLambda{}-Calculus with exceptions, captures,
lazy evaluation, \mbox{or named parameters; etc}.
}
\p{Rather than study each system in isolation, we can
understand different extensions
or variations to \mOldLambda{}-Calculus to each model their own
\i{kind} of channel: a specific kind of \mbox{protocol} and semantics
for passing values to functions.
We can generically discuss \q{input} and
\q{output}, but programming languages have different specifications
for different genres of input/output, which we can model via
different channels.  For a particular channel, we can recognize
language-specific limitations on how values passed in to or
received from those channels are used, and how the symbols carrying those
values interact with other symbols both in function call-sites and bodies.
For example, functions can output values by throwing exceptions, but
exceptions are unusual values which have to be handled
in specific ways \mdash{} languages use exceptions to signal possible
programming errors, and they are engineered to interrupt
normal program flow until or unless exceptions are \q{caught}.
}
\p{Computer scientists have explored these more complex programming paradigms
in part by inventing new variations on \mOldLambda{}-calculi, as well as new
code representations which can take the place of
Applicative Structures.  Here I will develop one theory representing
code in terms of Directed Hypergraphs, which are subject to multiple kinds
of lambda abstraction \mdash{} in principle, replacing many disparate
\mOldLambda{}-Calculus extensions with one overarching framework.
This section will lay out the details of this form of Directed Hypergraph
and how \mOldLambda{}-calculi
can be defined on its foundation.  The following section will
discuss an expanded type theory which follows organically
from this approach, and the third section will situate
lambda calculi in terms  of \q{Channel Algebras}.
}
\p{Many concepts outlined here are reflected in the accompanying code set,
which includes a \Cpp{} Directed Hypergraph library and also
parsers and runtimes for an Interface Definition Language.
The design choices behind these components will be
suggested in the text, but hopefully the code will illustrate
how the ideas can be manifest in concrete implementations, which
in turn provide evidence that they are logically sound
at least to the level of properly-behaving application code.
}
\spsubsectiontwoline{Directed Hypergraphs and \q{Channel Abstractions}}
\p{A \i{hypergraph} is a graph whose edges (a.k.a. \q{hyperedges}) can span
more than two nodes (\cite[e.g. p. 24]{BenGoetzel},
\cite{HaishanLiu}, \cite{MarkMinas};
\cite{AlexandraPoulovassilis}, \cite{JohnStell}).
A \i{directed} hypergraph (\q{\DH{}}) is a hypergraph
where each edge has a \i{head set} and
\i{tail set} (both possibly empty).  Both of these are sets of nodes
which (when non-empty) are called \i{hypernodes}.  A hypernode can
also be thought of as a hyperedge whose tail-set
(or head-set) is empty.  Note that a typical hyperedge
connects two hypernodes (its head- and tail-sets), so if
we consider just hypernodes, a hypergraph potentially
reduces to a directed ordinary graph.  While
\q{edge} and \q{hyperedge} are formally equivalent,
I will use the former term when attending more to the
edge's representational role as linking two hypernodes,
and use the latter term when focusing more on its tuple
of spanned nodes irrespective of their partition into
\i{head} and \i{tail}. % (see Figure 1).
}
\p{I assume that hyperedges always span an \i{ordered} node-tuple
which induces an ordering in the head- and tail-sets: so a
hypernode is an \i{ordered list} of nodes, not just a
\i{set} of nodes.  I will say that
two hypernodes \i{overlap} if they
share at least one node; they are \i{identical}
if they share exactly the same nodes in the same order; and
\i{disjoint} if they do not overlap at all.  I call a
Directed Hypergraph
\q{reducible} if all hypernodes are either disjoint or
identical.  The information in reducible \DH{}s can be factored
into two \q{scales}, one a directed graph whose nodes are the
original hypernodes, and then a table of all nodes
contained in each hypernode.  Reducible \DH{}s allow
ordinary graph traversal algorithms when hypernodes
are treated as ordinary nodes on the coarser scale
(so that their internal information \mdash{} their list
of contained nodes \mdash{} is ignored).
}
\p{A weaker restriction on \DH{} nodes is that two
non-identical hypernodes \i{can} overlap, but
must preserve node-order: i.e., if the first
hypernode includes nodes \nodeNOne{}, and \nodeNTwo{}
immediately after, and the second hypernode
also includes \nodeNOne{}, then the second
hypernode must also include \nodeNTwo{} immediately
thereafter.  Overlapping hypernodes
can not \q{permute} nodes
\mdash{} cannot include them in different orders or in a way
that \q{skips} nodes.
I will call \DH{}s meeting this condition
\i{linear}, in the sense that any sequence of nodes
appearing within one hypernode will always appear in the
exact same order whenever they are included in other hypernodes.
Trivially, all reducible \DH{}s are linear.
}
\p{To avoid confusion, I will hereafter use the word \q{hyponode} in place
of \q{node}, to emphasize the container/contained relation between
hypernodes and hyponodes.  I will use \q{node} as an informal word
for comments applicable to both hyper- and hypo-nodes.  Some
Hypergraph theories and/or implementations
allow hypernodes to be nested: i.e., a hypernode can contain
another hypernode.  In these theories, in the general case any node
is potentially both a hypernode and a hyponode.  For this chapter,
I assume the converse: any \q{node} (as I am hereafter using the term) is
\i{either} hypo- or hyper-.  However, multi-scale Hypergraphs can be approximated
by using hyponodes whose values are proxies to hypernodes.
}
\p{Here I will focus on a class of \DH{}s which (for reasons to emerge)
I will call \q{Channelizable}. Channelizable Hypergraphs
(\CH{}s) have these properties:
\begin{enumerate}\item{}  They are linear.
\item{}  They have a Type System \TyS{} and all hyponodes and hypernodes are assigned
exactly one canonical type (they may also be considered instances of super- or subtypes
of that type).
\item{}  All hyponodes can have (or \q{express}) at most one value, an instance of its
canonical type, which I will call a \i{hypovertex}.  Hypernodes, similarly,
can have at most one \i{hypervertex}.  Like \q{node} being an informal
designation for hypo- and hyper-nodes, \q{vertex} will be a general term
for both hypo- and hyper-vertices.  Nodes which do have a vertex
are called \i{initialized}.  The hypovertices \q{of} a hypernode are those
of its hyponodes.
\item{}  Two hyponodes are \q{equatable} if they express the same value of the same
type.  Two (possibly non-identical) hypernodes are \q{equatable} if all of their
hyponodes, compared one-by-one in order, are equatable.  I will also say that values
are \q{equatable} (rather than just saying \q{equal}) to emphasize that
they are the respective values of equatable nodes.
\item{}  There may be a stronger relation, defined on equatable non-equivalent hypernodes,
whereby two hypernodes are \i{inferentially equivalent} if any inference justified via
edges incident to the first hypernode can be freely combined with inferences
justified via edges incident to the second hypernode.  Equatable nodes are not
necessarily inferentially equivalent.
\item{}  Hypernodes can be assumed to be unique in each graph, but it is
unwarranted to assume (without type-level semantics) that two equatable
hypernodes in different graphs are or are not inferentially equivalent.
Conversely, even if graphs are uniquely labeled \mdash{} which would
appear to enable a formal distinction between hypernodes in one
graph from those in another, \CH{}
semantics does not permit the assumption that this separation alone
justifies inferences presupposing that their hypernodes
\i{are not} inferentially equivalent.
\item{}  All hypo- and hypernodes have a \q{proxy}, meaning there is a type in
\TyS{} including, for each node, a unique identifier designating
that node, that can be expressed in other hyponodes.
\item{}  There are some types (including these proxies) which may only be expressed
in hyponodes.  There may be other types which may only be expressed
in hypernodes.  Types can then be classified as \q{hypotypes} and \q{hypertypes}.
The \TyS{} may stipulate that all types are \i{either} hypo or hyper.  In
this case, it is reasonable to assume that each hypotype maps to a unique
hypertype, similar to \q{boxing} in a language which recognizes \q{primitive}
types (in Object-Oriented languages, boxing allows non-class-type
values to be used as if they were objects).
\item{}  Types may be subject to the restriction that any hypernode which has that
type can only be a tail-set, not a head-set; call these \i{tail-only} types.
\item{}  Hyponodes may not appear in the graph outside of hypernodes.  However, a
hypernode is permitted to contain only one hyponode.
\item{}  Each edge, separate and apart from the \CH{}'s actual graph structure,
is associated with a distinct hypernode, called its \i{annotation}.  This
annotation cannot (except via a proxy) be associated with any other hypernode
(it cannot be a head- or tail-set in any hypernode).
The first hyponode in its annotation is
called a hyperedge's \i{classifier}.  The outgoing edge-set of a hypernode can
always be represented as an associative array indexed by the classifier's vertex.
\item{}  A hypernode's type may be subject to restrictions such that there is a
single number of hyponodes shared by all instances.  However, other types may be
expressed in hypernodes whose size may vary.  In this case the
hyponode types cannot be random; there must be some pattern linking
the distribution of hyponode types evident in hypernodes (with the same
hypernode types) of different sizes.  For example, the hypernodes
may be dividable into a fixed-size, possibly empty sequence of hyponodes,
followed by a chain of hyponode-sequences repeating the same type pattern.
The simplest manifestation of this structure is a hypernode all of whose
hyponodes are the same type.
\item{}  Call a \i{product-type transform} of a hypernode to be a different
hypernode whose hypovertices are tuples of values equatable to those from the first hypernode,
typed in terms of product types (i.e., tuples).  For example, consider two
different representations of semi-transparent colors: as a 4-vector
\vecrgbt{}, or as an \vecrgb{} three-vector paired with a transparency magnitude.
The second representation is a product-type transform of the first, because the first
three values are grouped into a three-valued tuple.  We can
assert the requirement in most contexts that \CH{}s whose hypernodes are
product-type transforms of each other contain \q{the same information}
and as sources of information are interchangeable.
\item{}  The Type System \TyS{} is \i{channelized}, i.e., closed under a
Channel Algebra, as will be discussed below.
\end{enumerate}
}
\p{These definitions allude to two strategies for computationally representing
\CH{}s.  One, already mentioned, is to reduce them to directed graphs
by treating hypernodes as integral units (ignoring their internal structure).
A second is to model hypernodes as a \q{table of associations} whose
keys are the values of the classifier hyponodes on each of their edges.
A \CH{} can also be transformed into an \i{undirected} hypergraph by
collapsing head- and tail- sets into an overarching tuple.  All of these
transformations may be useful in some analytic/representational contexts,
and \CH{}s are flexible in part by morphing naturally into these various
forms.\phantomsection\label{unplug}
}
\tcl{unplug}
\begingroup\captionof{figure}{\q{Unplugging} a Node}\endgroup
\vspace{1.5em}
\p{Notice that information present \i{within} a hypernode can also be expressed as
relations \i{between} hypernodes.  For example, consider the information that
I (Nathaniel), age 45, live in Brooklyn as a registered Democrat.  This may be
represented as a hypernode with hyponodes \NathFF{}, connected to a hypernode
with hyponodes \BrookDem{}, via a hyperedge whose classifier encodes the
concept \q{lives in} or \q{is a resident of}.  However, it may also be
encoded by \q{unplugging} the \q{age} attribute so the first hypernode becomes
just \Nath{} and it acquires a new edge, whose tail has a single
hyponode \ageFF{} and a classifier (encoding the concept) \q{age}
(see the comparison in Diagram \hyperref[unplug]{1}).
This construction can work in reverse:
information present in a hyperedge can be refactored so that it \q{plugs in}
to a single hypernode.
}
\p{These alternatives are not redundant.  Generally, representing information
via hyperedges connecting two hypernodes implies that this information is
somehow conceptually apart from the hypernodes themselves, whereas representing
information via hyponodes \i{inside} hypernodes implies that this information
is central and recurring (enforced by types), and that the data
thereby aggregated forms a recurring logical unit.  In a political survey,
people's names may \i{always} be joined to their age, and
likewise their district of
residence \i{always} joined to their political affiliation.  The left-hand side
representation of the info (seen as an undirected hyperedge) \NathFFBD{}
in Diagram \hyperref[unplug]{1} captures this semantics better because it describes
the name/age and \mbox{place/party} pairings as
\i{types} which require analogous
node-tuples when expressed by other hypernodes.  For example, any two
hypernodes with the same type as \NathFF{} will necessarily have
an \q{age} hypovertex
and so can predictably be compared along this one axis.  By contrast, the
right-hand (\q{unplugged}) version in Diagram \hyperref[unplug]{1}
implies no guarantees that the \q{age}
data point is present as part of a recurring pattern.
}
\p{In general, graph representations like \CH{} and \RDF{} serve two goals: first,
they are used to \i{serialize} data structures (so that
they may be shared between
different locations; such as, via the internet);
and, second, they provide
formal, machine-readable descriptions of information content, allowing for
analyses and transformations, to infer new information or produce new data
structures.  The design and rationale of representational paradigms is
influenced differently by these two goals, as I will review now with an eye
in part on drawing comparisons between \CH{} and \RDF{}.
}
\spsubsection{Serializing Data via Hypergraphs}
\p{The formal Channelized Hypergraph
specification I sketched earlier described both
\q{hypervertices} and \q{hypovertices} as values associated with
hyper- and hyponodes, respectively.  There is no
\i{mandated} relation between hyper- and hypovertex values,
but usually there should be a sensible transformation between them.
In a typical case, hypovertices are used primarily for
serialization, while hypervertices are used for analysis and
processing.  That is, a \CH{} graph as a \i{runtime} data
structure will hold most or all values in hypernodes.
When the graph is sent to a different location, the
hypervertex values are split into minimal units
(like individual strings, numbers, or node-proxies),
from which hyponodes are initialized.
\itcl{initializing-hypernodes}\nl\vspace{-1em}
\noindent
When the graph is later \i{deserialized}, the hypovertices
are then re-aggregated to re-construct the hypervertices,
which in turn initialize their corresponding hypernodes.
}
\p{Figure \ref{lst:initializing-hypernodes} shows an example of code from the
demo where the \CH{} graph builder is adding content to a
code-graph, within functions that are used from callbacks triggered by
rule-matches in the parser.  The methods labeled at the top of the
sample (like \OneOverlay{}) show the
graph builder creating nodes when provided with values (technically, hypervertices)
allocated elsewhere (they are wrapped in a special kind of pointer
used for values internal to the graph system).  By contrast,
\TwoOverlay{} shows similar logic but where the vertex and node
are created together, by the same function.  As this
illustrates, making nodes is a two-step process, where \i{first} the
vertex is allocated, \i{then} the node is likewise, perhaps in a different
code location (these comments apply
both to hypo- and hypervertices and nodes).
}
\p{The freshly created nodes are not yet inserted into a graph; this final
step can occur via code like at \ThreeOverlay{}, where new nodes are
joined to prior nodes via a specified hyperedge annotation/classifier,
called a \q{connector} in demo code.  The
demo library uses \Cpp{} operators to
modify graph structures, essentially creating a \q{query language} for
graph traversal and manipulation as an embedded \DSL{}
(Domain-Specific Language), both adding nodes and
(as at \FourOverlay{}) for
moving between nodes based on a desired connector
(modifying the graph structure can also be done with
method-calls, as at \FiveOverlay{}).  The main point
for the present context is that nodes serve as wrappers
for ordinary runtime data structures: the \CH{} graph
library does not examine or process vertex values
directly.  Instead, it allows applications to traverse
graphs until they find nodes which are of interest for
whatever their present purpose, and allows the
application to use the node's initialized value
however it sees fit (unpacking the vertex as an ordinary
\Cpp{} pointer).
}
%\vspace{1em}
\p{This illustrates one contrast between \CH{} and \RDF{}: \CH{} graphs can
be used in a way that fully decouples graph \i{structure} from
any notion of value-manipulation or semantics.  The demo
libraries, for instance, recognize only structural relations
between values; they do not have any means to
\q{look inside} or use values.  As sampled in \ref{lst:dominion-types},
each graph has a \q{dominion} which encompasses a set of types
that may be used as vertex values.  The demo Hypergraph library
assumes that all node-values belong to types identified at
compile-time, and on that basis enforces
some measure of compile-time type checking.
}
%\itcl{initializing-hypernodes}
%\vsftcl{h}{dominion-types}
%\vspace{1em}
\p{The node classes are equipped
with constructors that accept vertex pointers from
\q{dominion} types,
and have methods to extract pointers of those types (the actual
implementation of these functions is centered at \OneOverlay{} in
\ref{lst:dominion},
which is macro code that gets included while the node classes are
being compiled \mdash{} in general, the list of types asserted
in \typesH{} generates several different kinds of code
depending on which preprocessor macros are defined at the
point where the \typesH{} file is included).  Overall,
the node classes hold values (vertices) but do not
operate on then; each vertex is opaque to the \CH{} graph
engine, stored within a node for subsequent use elsewhere in the
application, but only actually used at the application level.
}
\itcl{dominion-types}
\itcl{dominion}
\p{This manner of separating content from structure is conceptually
and operationally different from \RDF{}: \RDF{}
structures capture relations on multiple scales at once
\mdash{} which also means that \RDF{} graphs are suitable for
both serialization and analysis.  By contrast, \CH{} graphs \mdash{} or at
least those constructed via code sampled here \mdash{} are not
directly serializable, because each node holds a value that is,
in its underlying form, a \Cpp{} pointer.  Serializing the
overall graph depends on serializing each vertex, which in turn
depends on algorithms varying based on vertex types.  Note that
\q{serializing vertices} makes no sense in the \RDF{} context, because
\RDF{} nodes by definition are either atomic literals or \URL{}s
pointing at web resources.  Nodes in \CH{}, in contrast to \RDF{},
have \q{values} which can be multi-part aggregates of any type
(whereas \RDF{} literals are constrained to a handful of basic types like
numbers and character strings).
}
\p{On the other hand,
\CH{} graphs can be \i{transformed} into serializable
structures by mapping hypervertices onto sets of hypovertices,
thereby appointing hypernodes with an array of hyponodes.
Enforcing constraints related to
linearity, types, and product-type transforms can result in \CH{}s whose hypernodes
exhibit the same structural properties as a program's runtime memory.
It is helpful to think of hypernodes as analogous to either \CStruct{}s or
\CArray{}s.  Varying the precise requirements on hypernodes allows
\CH{}s to mimic the memory conventions of different programming languages
(for example, prohibiting non-identical but overlapping hypernodes
mimics a language without pointer arithmetic, which as such has no mechanism
for creating a reference to a proper subset of the memory area allocated
for a typed value).  These specifications help ensure that
serialization algorithms are straightforward to design: for
example, code that serializes hypervertex types to binary buffers
(like \QDataStream{}) can with little change be adopted to map
hypernodes to hyponodes.  As such, \CH{} graphs can be used
via processing \i{hypervertices} as runtime data structures, and used
via processing \i{hypovertices} for data sharing and network transfers:
the hyponodes become a kind of \q{transport} layer whose main
role lies in moving graphs from place to place.
}
\p{The fact that \CH{} allows a stricter separation of \i{structure} and
\i{content} also has ramifications for semantics and analytic
capabilities, compared to \RDF{}, which I will discuss next.
}
%\vspace{-1em}
\spsubsection{Channelized Hypergraphs and \largeRDF{}}
\p{The Resource Description Framework (\RDF{}) models information
via directed graphs (\cite{AnglesGuttierez},
\cite{MadalinaCroitoru}, \cite{ErnestoDamiani}, and
\cite{YurickWilks} are good discussions of
Semantic Web technologies from a graph-theoretic perspective),
whose edges are labeled with concepts that,
in well-structured contexts, are drawn from published Ontologies
(these labels play a similar role to \q{classifiers} in \CH{}s).
In principle, all data expressed via \RDF{} graphs is defined
by unordered sets of labeled edges, also called \q{triples}
(\q{\SPO{}}, where the \q{Predicate} is the label).  In practice,
however, higher-level \RDF{} notation such as \TTL{} (\Turtle{} or
\q{Terse \RDF{} Triple Language}) and Notation3 (\NThree{})
deal with aggregate groups of data, such as \RDF{} containers and
collections.\phantomsection\label{lived}
}
\vspace{-.5em}
\tcl{lived}
\begingroup\captionof{figure}{CH vs. RDF Collections.}\endgroup
\vspace{.5em}
\p{For example, imagine a representation of the
fact \q{(A/The person named) Nathaniel, 45, has lived in Brooklyn,
Buffalo, and Montreal} (shown in Diagram \hyperref[lived]{2} as both
a \CH{} and in \RDF{}).  An \NThree{} graph of the sentence
might look like this: \NathLivedTTL{}  The final (\NThree{} proper)
expression, in particular,
actually seems structurally closer to the \CH{} model than
to the \RDF{}.  If we consider \Turtle{} or \NThree{} as \i{languages} and
not just \i{notations}, it would appear as if their semantics is built
around hyperedges rather than triples.  It would seem that these
languages encode many-to-many or one-to-many assertions, graphed as
edges having more than one subject and/or predicate.  Indeed,
Tim Berners-Lee himself suggests that
\q{Implementations may treat list as a data type rather than just
a ladder of rdf:first and rdf:rest properties} \cite[p. 6]{TimBernersLee}.
That is, the specification for
\RDF{} list-type data structures invites us to consider that
they \i{may} be regarded integral units rather than
just aggregates that get pulled apart in semantic interpretation.
}
\p{Technically, perhaps, this is an illusion.  Despite their higher-level
expressiveness, \RDF{} expression languages are, perhaps,
supposed to be deemed \q{syntactic sugar}
for a more primitive listing of triples: the \i{semantics} of
\Turtle{} and \NThree{} are conceived to be defined by translating
expressions down to the triple-sets that they logically imply
(see also \cite{YurickWilks}).
This intention accepts the paradigm that providing semantics
for a formal language is closely related to defining which
propositions are logically entailed by its statements.
}
\p{There is, however, a divergent tradition in formal semantics that is oriented to
type theory more than logic.  It is consistent with this alternative
approach to see a different semantics for a language like \Turtle{},
where larger-scale aggregates become \q{first class} values.
So, \NathFF{} can be seen as a (single, integral)
\i{value} whose \i{type} is a \nameAge{} pair.  Such a value has an
\q{internal structure} which subsumes multiple data-points.  The
\RDF{} version is organized, instead, around a \i{blank node} which
ties together disparate data points, such as my name and age.
This blank node is also connected to another blank node which
ties together place and party.  The blank nodes
play an organizational role, since nodes are grouped together
insofar as they connect to the same blank node.  But the
implied organization is less strictly entailed; one might
assume that the \BrookDem{} nodes could just as readily
be attached individually to the \q{name/age} blank
(i.e., I live in Brooklyn, \i{and} I vote Democratic).
}
\p{Why, that is, are Brooklyn and Democratic grouped together?
What concept does this fusion model?
There is a presumptive rationale for the name/age blank
(i.e., the fusing name/age by joining them to a blank
node rather than allowing them to take edges independently):
conceivably there are multiple 45-year-olds named Nathaniel,
so \i{that} blank node plays a key semantic role
(analogous to the quantifier in \q{\i{There is} a Nathaniel,
age 45...}); it provides an unambiguous nexus so that
further predicates can be attached to \i{one specific}
45-year-old Nathaniel rather than any old \NathFF{}.  But there is no
similarly suggested semantic role for the \q{place/party} grouping.  The name
cannot logically be teased apart from the name/age blank (because there
are multiple Nathaniels); but there seems to be no \i{logical}
significance to the \mbox{place/party} grouping.  Yet pairing
these values \i{can} be motivated by a modeling convention
\mdash{} reflecting that geographic and party affiliation data
are grouped together in a data set or data model.  The logical
semantics of \RDF{} make it harder to express these kinds of modeling
assumptions that are driven by convention more than logic
\mdash{} an abstracting from data's modeling environment that can be desirable
in some contexts but not in others.
}
\p{So, why does the Semantic Web community effectively insist on
a semantic interpretation of \Turtle{} and \NThree{} as \i{just} a
notational convenience for \NTrips{} rather than as higher-level
languages with a different higher-level semantics \mdash{} and despite
statements like the above Tim Berners-Lee quote insinuating that
an alternative interpretation has been contemplated even by
those at the heart of Semantic Web specifications?  To the degree
that this question has an answer, it probably has something to
do with reasoning engines: the tools that evaluate \SPARQL{} queries
operate on a triplestore basis.  So the \q{reductive} semantic
interpretation is arguably justified via the warrant that the
definitive criteria for Semantic Web representations are not their
conceptual elegance \visavis{} human judgments but their utility in
cross-Ontology and cross-context inferences.  As a counter-argument,
however, note that many inference engines in Constraint Solving,
Computer Vision, and so forth, rely on specialized algorithms
and cannot be reduced to a canonical query format.  Libraries such
as \GeCODE{} and \ITK{} are important because problem-solving
in many domains demands fine-tuned application-level engineering.
We can think of these libraries as supporting \i{special} or
domain-specific reasoning engines, often built for specific
projects, whereas \OWL{}-based reasoners like \FactPP{} are
\i{general} engines that work on general-purpose \RDF{} data
without further qualification.  In order to
apply \q{special} reasoners to \RDF{}, a contingent of nodes must
be selected which are consistent with reasoners' runtime requirements.
}
\p{Of course, special reasoners cannot be expected to run on the domain of
the entire Semantic Web, or even on \q{very large} data sets in general.
A typical analysis will subdivide its problem into smaller parts
that are each tractable to custom reasoners \mdash{} in radiology, say,
a diagnosis may proceed by first selecting a medical
image series and then performing
image-by-image segmentation.  Applied to \RDF{}, this
two-step process can be considered a combination of general and special
reasoners: a general language like \SPARQL{} filters many nodes down to a smaller
subset, which are then mapped/deserialized to domain-specific representations
(including runtime memory).  For example, \RDF{} can link a patient to a
diagnostic test, ordered on a particular date by a particular doctor, whose
results can be obtained as a suite of images \mdash{} thereby selecting the
particular series relevant for a diagnostic task.  General reasoners
can \i{find} the images of interest and then pass them to
special reasoners (such as segmentation algorithms)
to analyze.  Insofar as this architecture is in effect, Semantic Web
data is a site for many kinds of reasoning engines.  Some of these engines
need to operate by transforming \RDF{} data and resources to an optimized,
internal representation.  Moreover, the semantics of these representations
will typically be closer to a high-level \NThree{} semantics taken as
\suigeneris{}, rather than as interpreted reductively as a notational
convenience for lower-level formats like \NTrip{}.  This appears
to undermine the justification for reductive semantics in terms of
\OWL{} reasoners.
}
\p{Perhaps the most accurate paradigm is that Semantic Web data has two
different interpretations, differing in being consistent with
special and general semantics, respectively.  It makes sense to
label these the \q{special semantic interpretation} or
\q{semantic interpretation for special-purpose reasoners}
(\SSI{}, maybe) and the \q{general semantic interpretation}
(\GSI{}), respectively.  Both these interpretations should be deemed
to have a role in the \q{semantics} of the Semantic Web.
}
\p{Another order of considerations involve the
semantics of \RDF{} nodes and \CH{} hypernodes
particularly with respect to uniqueness.  Nodes in \RDF{} fall into three classes:
blank nodes; nodes with values from a small set of basic types like strings and
integers; and nodes with \URL{}s which are understood to be unique across the
entire World Wide Web.  There are no blank nodes in \CH{}; and intrinsically
no \URL{}s either, although one can certainly define a \URL{} \i{type}.
There is nothing in the semantics of \URL{}s
which guarantees that each \URL{} designates a distinct internet resource;
this is just a convention which essentially, \i{de facto},
fulfills itself because
it structures a web of commercial and legal practices, not just digital
ones; e.g. ownership is uniquely granted for each internet domain name.
In \CH{}, a data type may be structured to reflect institutional
practices which guarantee the uniqueness of values in some context:
books have unique \ISBN{} codes; places have distinct \GIS{} locations,
etc.  These uniqueness requirements, however, are not intrinsically
part of \CH{}, and need to be expressed with additional axioms.  In
general, a \CH{} hypernode is a tuple of relatively simple values
and any additional semantics are determined by type
\mbox{definitions} (recall the idea that \CH{} hypernodes are roughly analogous to
\CStruct{}s \mdash{} which have no \i{a priori} uniqueness mechanism).
}
\p{Also, \RDF{} types are less intrinsic to \RDF{} semantics than in \CH{}
(see \cite{HeikoPaulheim}).  The
foundational elements of \CH{} are value-tuples (via nodes expressing values,
whose tuples in turn are hypernodes).  Tuples are indexed by position, not by
labels: the tuple \NathFF{} does not in itself draw in the labels \q{name} or
\q{age}, which instead are defined at the type-level (insofar as type-definitions
may stipulate that the label \q{age} is an alias for the node in its
second position, etc.).  So there is no way to ascertain the semantic/conceptual
intent of hypernodes without considering both hyponode and hypernode types.  Conversely,
\RDF{} does not have actual tuples (though these can be represented as collections,
if desired); and nodes are always joined to other nodes via labeled connectors
\mdash{} there is no direct equivalent to the basis-level \CH{}
modeling unit of a hyponode being included in a hypernode
by position.
}
\p{At its core, then, \RDF{} semantics are built on the proposition that many
nodes can be declared globally unique by fiat.  This does not need to be
true of all nodes \mdash{} \RDF{} types like integers and floats are more
ethereal; the number 45 in one graph is indistinguishable from 45 in
another graph.  This can be formalized by saying that some nodes can be
\i{objects} but never \i{subjects}.  If such restrictions were not enforced,
then \RDF{} graphs could become in some sense overdetermined, implying
relationships by virtue of quantitative magnitudes devoid of semantic
content.  This would open the door to bizarre judgments like
\q{my age is non-prime} or \q{I am older than Mohamed Salah's goal totals}.
The way to block these inferences is to prevent nodes like
\q{the number 45} from being subjects as well as objects.
But nodes which are not primitive values \mdash{} ones, say, designating
Mohamed Salah himself rather than his goal totals \mdash{} are justifiably
globally unique, since we have compelling reasons to adopt a model
where there is exactly one thing which is \i{that} Mohamed Salah.
So \RDF{} semantics basically marries some primitive types which are
objects but never subjects with a web of globally unique but internally
unstructured values which can be either subject or object.
}
\p{In \CH{} the \q{primitive} types are effectively hypotypes; hyponodes
are (at least indirectly)
analogous to object-only \RDF{} nodes insofar as
they can only be represented via inclusion inside
hypernodes.  But \CH{} hypernodes are neither (in themselves) globally
unique nor lacking in internal structure.  In essence, an \RDF{}
semantics based on guaranteed uniqueness for atom-like
primitives is replaced by a semantics based on structured building-blocks
without guaranteed uniqueness.  This alternative may be considered in the
context of general versus special reasoners: since general reasoners
potentially take the entire Semantic Web as their domain, global
uniqueness is a more desired property than internal structure.
However, since special reasoners only run on specially selected data,
global uniqueness is less important than efficient mapping
to domain-specific representations.  It is not computationally
optimal to deserialize data by running \SPARQL{} queries.
}
\p{Finally, as a last point in the comparison between
\RDF{} and \CH{} semantics,
it is worth considering the distinction (introduced, notably,
in the \q{OpenCog} system)
between \q{declarative knowledge} and \q{procedural knowledge}
\cite[especially pages 182-197]{BenGoetzel}.  According
to this distinction, canonical \RDF{} data exemplifies \i{declarative} knowledge
because it asserts apparent facts without explicitly trying to interpret or
process them.  Declarative knowledge circulates among software in canonical,
reusable data formats, allowing individual components to use or make inferences from
data according to their own purposes.
}
\p{Counter to this paradigm, return to
hypothetical \USH{} examples as I discussed at the top of this chapter.  For
example, consider the conversion of Voltage data to acceleration data, which is a
prerequisite to accelerometers' readings being useful in most contexts.  Software
possessing capabilities to process accelerometers therefore reveals
what can be called \i{procedural} knowledge, because software
so characterized not only receives data
but also processes such data in standardized ways.
}
\p{The declarative/procedural distinction perhaps fails to capture how
procedural transformations may be understood as intrinsic to some semantic
domains \mdash{} so that even the information we perceive as
\q{declarative} has a procedural element.  For example, the
very fact that \q{accelerometers} are not
called \q{Voltmeters} (which are something else) suggests how the
Ubiquitous Computing community perceives voltage-to-acceleration
calculations as intrinsic to accelerometers' data.  But strictly speaking
the components which participate in \USH{} networks are not just
engaged in data sharing; they are functioning parts of the network because
they can perform several widely-recognized
computations which are understood to be central to the relevant
domain \mdash{} in other words, they have (and share with their
peers) a certain \q{procedural knowledge}.
}
\p{\RDF{} is structured as if static data sharing were the sole arbiter of
semantically informed interactions between different components,
which may have a variety of designs and rationales \mdash{} which
is to say, a
Semantic Web.  But a thorough account of formal communication semantics
has to reckon with how semantic models are informed by the implicit, sometimes
unconscious assumption that producers and/or consumers of data will
have certain operational capacities: the dynamic processes anticipated as
part of sharing data are hard to conceptually separate from the static
data which is literally transferred.  To continue the accelerometer
example, designers can
think of such instruments as \q{measuring acceleration} even though
\i{physically} this is not strictly true; their
output must be mathematically transformed for it to be interpreted in
these terms.  Whether represented via \RDF{} graphs or Directed Hypergraphs,
the semantics of shared data is incomplete unless the operations
which may accompany sending and receiving data are recognized as
preconditions for legitimate semantic alignment.
}
\p{While Ontologies are valuable for coordinating and integrating
disparate semantic models, the Semantic Web has perhaps influenced
engineers to conceive of semantically informed data sharing
as mostly a matter of presenting static data conformant to published
Ontologies (i.e., alignment of \q{declarative knowledge}).  In reality,
robust data sharing also needs an \q{alignment of \i{procedural}
knowledge}: in an ideal Semantic Network, procedural capabilities
are circled among components, promoting an emergent \q{collective
procedural knowledge} driven by transparency about code and libraries as
well as about data and formats.  The \CH{} model arguably supports this
possibility because it makes type assertions fundamental to semantics.
Rigorous typing both lays a foundation for procedural alignment
and mandates that procedural capabilities be factored in to assessments
of network components, because a type attribution has no meaning
without adequate libraries and code to construct and interpret
type-specific values.
}
\whdecoline{}
\p{Still, having just identified several notable differences between
\RDF{} and the Semantic Web, on the one hand, and Hypergraph-based frameworks,
on the other \mdash{} perhaps OpenCog and its \q{Atom Space} system, and
certainly the \CH{} model highlighted in this chapter \mdash{} I hope
not to overstate these differences; both belong to the overall
space of graph database and graph-oriented semantic models.
\RDF{} graphs are both a plausible serialization
of \CH{} graphs and a reasonable interpretation of \CH{} at least
in some contexts.  In particular, there are several Ontologies that
formally model computer source code.  This implies that code can been be
modeled by suitably typed \DH{}s as well.  A rigorous review of \DH{}
code models may be premature before I discuss \q{channels}, but assume
provisionally that such a model does exist.  So, for any given
program, assume that there is a corresponding \DH{} representation
which I will call the \i{implementation graph}; the code
thereby represented I'll call an \i{implementation body}
or just \q{body}.
}
\p{\phantomsection\label{detachedeval}Assume moreover that these
programs do not always run the same way: that
their behavior and results depend on \i{inputs} which are fixed before the
program begins, and produce \q{outputs} once it ends (by \q{program} I
mean an integral body of computation in general, such as the implementation
of one function; not just \q{computer programs} in the sense of particular
binary executables or \q{applications}).  This implies that some
hypernodes represent and/or express values that are \i{inputs} to a
body, and others represent and/or express its \i{outputs}.  These
hypernodes are \i{abstract} in the sense (as in Lambda Calculus) that they
do not have a specific assigned value within the body, \i{qua} formal
structure.  Instead, a \i{runtime manifestation} of a \DH{}
(or equivalently a \CH{}, once channelized types are introduced) populates
the abstract hypernodes with concrete values, which in turn allows
expressions described by the \CH{} to be evaluated.  Intrinsically,
the \i{order of evaluation} is indeterminate \mdash{} it is neither
(necessarily) eager nor lazy, and neither concurrent nor sequential,
but perhaps could be described as \q{detached}: each evaluation is
a detached computation unless some additional structure convolutes them.
Therefore, one requirement to \CH{} semantics is to describe how the
\q{detached} evaluation model translates to either lazy or eager paradigms.
}
\p{Values can input into and output out of bodies in different ways; so this
model of computation is very incomplete.  Most of the rest of this
chapter will focus on expanding it with greater detail.
}
%\subsection{Kinds of Abstraction}
\spsubsection{Type Systems' Architecture}
\p{\label{types}Parallel to the historical evolution where \mOldLambda{}-Calculus
progressively diversified and re-oriented toward concrete
programming languages, there has been an analogous (and
to some extent overlapping) history in Type Theory.
When there are multiple ways of passing input to a
function, there are at potentially multiple kinds
of function types.  For instance, Object-Orientation inspired
expanded \mOldLambda{}-calculi that distinguish function
inputs which are \q{method receivers} or \q{\this{} objects} from
ordinary (\q{lambda}) inputs.  Simultaneously, Object-Orientation also
distinguishes \q{class} from \q{value} types
and between function-types which are \q{methods} versus ordinary
functions.  So, to take one example, a function telling
us the size of a list can exhibit two different types, depending
on whether the list itself is passed in as a method-call target
(\listsize{} vs. \sizelist{}).
}
\p{One way to systematize the diversity of type systems
is to assume that, for any particular type system, there
is a category \tCat{} of types conformant to that system.  This requires
modeling important type-related concepts as \q{morphisms} or maps
between types.  Another useful concept is an \q{endofunctor}:
an \q{operator} which maps elements in a category
to other (or sometimes the same) elements.  In a \tCat{} an endofunctor
selects (or constructs) a type \tyTwo{} from a type \tyOne{} \mdash{} note how this is
different from a morphism which maps \i{values of} \tyOne{} to \tyTwo{}.
Some basic morphisms and endofunctors include the following:
\begin{enumerate}\eli{} \q{Selectors} for the first and second elements in a type-product \tOneTimesTTwo{}:
note how this is a way of saying that product-types exist, since they are the types for which
the \q{select second} endofunctor exists.
%\eli{} Given types \tyOne{} and \tyTwo{}, where \tyOne{} is a \q{tuple}, an endofunctor
%which appends \tyTwo{} to the end of \tyOne{}, yielding a new tuple type; thus arbitrary
%tuples can be built from a \tOneTimesTTwo{} pair.
\eli{} Given type \tyOne{}, an endofunctor yielding \tOneTimesTOne{} for
which both the \q{select first} and \q{select second} endofunctors
yield back \tyOne{}.  We can then define arbitrary-sized tuples
of \tyOne{} wherein a \q{select first} endofunctor yields \tyOne{}
and a \q{select rest} endofunctor yields another \tyOne{}-tuple.
\eli{} Given types \tyOne{} and \tyTwo{}, there is a type comprising
functions whose domain is \tyOne{} and codomain is \tyTwo{}
(\tCat{} is \q{Cartesian Closed}), so an endofunctor
\tOneTimesTTwoToTOneOntoTTwo{}.  This kind of type
can be generically called a \i{function-type}, though
I more often prefer looser terms such as \q{function-like} types
because the word \q{function} has multiple (interrelated but
importantly different) meanings.
\eli{} As a special case, let \unitTy{} be a type
holding one sole \unitVal{} value.  Then morphisms
\unitTyToty{} are equivalent to selecting a single
value that can instantiate \ty{}, motivating the
concept of a \q{set of values} spanned by \ty{}.
\eli{} Given types \tyOne{} and \tyTwo{}, where \tyTwo{} represents
a (finite) set of nonnegative integers, then a morphism \tyOneToTyTwo{}
\q{enumerates} the elements of \tyOne{}; so we can construct arbitrary
types with a finite set of symbols (having no particular meaning, at
least internal to the type system), as domains of an Enumeration.
\eli{} Given any type \ty{}, we can associate an enumeration \tyE{}
(so an endofunctor \tyTotyE{}) which represents
\q{states} that meaningfully partition the set of \tyValues{} into groups
with similar behaviors or properties; then morphism \tyToTyE{} maps
\q{elements} of \ty{} to their associated states.
\eli{} Given types \tyOne{} and \tyTwo{}, we can consider variations on \q{sum types}
(as endofunctors mapping from \tyOneTimesTyTwo{}), including the type whose
\i{values} can be either in \tyOne{} or \tyTwo{}, and a type whose
\q{typestate enumeration} unifies \tyE{} of \tyOne{} and \tyTwo{}.  In Haskell, for
example, the \Maybe{} endofunctor uses a special one-valued \q{Nothing} type
and augments any other type by adding this value, to represent
missing or \q{null} data; similar constructions yield zero-able pointers in
other languages.
\end{enumerate}
}
\vspace{-1em}
\p{Overall type systems are built up from a smaller set of \q{core} types via
operations like products, sums, enumerations, and \q{function-like} types.
We may think of the
\q{core} types for practical programming as number-based
(booleans, bytes, and larger integer types), with everything else built up by aggregation
or encodings (like \ascii{} and \unicode{}, allowing types to include text and alphabets).
In other contexts, however, non-mathematical core types may be appropriate: for example,
the grammar of natural languages can be modeled in terms of a type system whose core are
the two types \tyNoun{} and \tyProposition{} and which also includes
function types (maps) between pairs or tuples of types (verbs,
say, map \tyNoun{}s \mdash{} maybe multiple nouns, e.g. direct objects
\mdash{} to \tyProposition{}s).
Ultimately, a type system \tCat{} is characterized
(1) by which are its core types and
(2) by how aggregate types can be built from simpler ones
(which essentially involves endofunctors and/or products).
}
\p{In Category Theory, a Category \cCat{} is called \q{Cartesian Closed} if
for every pair of elements \eOne{} and \eTwo{} in \cCat{} there is an
element \eOneToeTwo{} representing (for some relevant notion of
\q{function}) all functions from \eOne{} to \eTwo{} \cite{RBrown}.  The stipulation that
a type system \TyS{} include function-like types is roughly equivalent, then,
to the requirement that \TyS{}, seen as a Category, is Cartesian-Closed.
The historical basis for this concept (suggested by the terminology)
is that the construction to form function-types is an \q{operator}, something that
creates new types out of old.  A type system
\TyS{} first needs to be \q{closed} under products:
if \tOne{} and \tTwo{} are in \TyS{} then \tOneTimesTTwo{} must be as well.
If \TyS{} is \i{also} closed under \q{functionalization} then the
\tOneTimesTTwo{} product can be mapped onto a function-like type
\tyOneTotyTwo{}.
}
\p{In general, then, more sophisticated type systems \TyS{} are described by
identifying new kinds of inter-type operators and studying those
type systems which are closed under these operators: if \tyOne{} and
\tyTwo{} are in \TyS{} then so is the combination of \tyOne{} and
\tyTwo{}, where the meaning of \q{combination} depends on the
operator being introduced.  Expanded \mOldLambda{}-calculi \mdash{} which
define new ways of creating functions \mdash{} are correlated with new
type systems, insofar as \q{new ways of creating functions}
also means \q{new ways of combining types into function-types}.
}
\p{Furthermore, \q{expanded} \mOldLambda{}-calculi generally involve
\q{new kinds of abstraction}: new ways that the building-blocks
of functional expressions, whether these be mathematical formulae
or bodies of computer code, can be \q{abstracted}, treated as
inputs or outputs rather than as fixed values.  In this chapter, I attempt to
make the notion of \q{abstraction} rigorous by analyzing it against
the background of \DH{}s that formally model computer code.
So, given the correlations I have just described between
\mOldLambda{}-calculi and type systems \mdash{} specifically, on
\TyS{}-closure stipulations \mdash{} there are parallel correlations
between type systems and \i{kinds of abstraction defined on
Channelized Hypergraphs}.  I will now discuss this further.
}
\spsubsection{Kinds of Abstraction}
\p{The \q{abstracted} nodes in a \CH{} can be loosely classified as
\q{input} and \q{output}, but in practice there are various paradigms
for passing values into and out of functions, each with their own semantics.
For example, a \q{\this{}} symbol in \Cpp{} is an abstracted, \q{input}
hypernode with special treatment in terms of overload resolution and access
controls.  Similarly, exiting a function via \return{} presents
different semantics than exiting via \throw{}.  As mentioned earlier,
some of this variation in semantics has been formally modeled
by different extensions to Lambda Calculus.
}
\p{So, different hypernodes in a \CH{} are subject to different kinds of abstraction.
Speaking rather informally, hypernodes can be grouped into \i{channels} based on
the semantics of their kind of abstraction.  More precisely,
channels are defined initially on \i{symbols}, which are associated with hypernodes:
in any \q{body} (i.e., an \q{implementation graph}) hypernodes can be grouped
together by sharing the same symbol, and correlatively sharing the
same value during a \q{runtime manifestation} of the \CH{}.  Therefore,
the \q{channels of abstraction} at work in a body can be identified
by providing a name representing the \i{kind} of channel and a list of
symbols affected by that kind of abstraction.  In the notation I adopt here,
conventional lambda-abstraction like \lXY{} would be written as \CHlXY{}.
}
\p{Separate and apart from notating channels \visavis{} one graph, we
also need a way to represent the semantics of different kinds of
channels; labels like \q{lambda} and \q{return} do not carry much
significance outside the primitive distinction of \q{input} and
\q{output}.  Here I will mention only simple examples of \q{formulae}
related to channels.  Let \rCh{} be the name of a channel kind,
such as the output of functions returning normally.  Let \chChSize{}
denote the size of \Ch{}; the formula \rChSizeleOne{} thereby asserts that
functions can return at most one value.  Let \xCh{} be the name of a
channel kind intending to represent thrown exceptions.  Since a
function cannot \i{both} return a value and throw an exception,
these two kinds of channels are interrelated.  In particular,
when modeling the semantics of a specific programming language, we
may observe that in any runtime manifestation the return and
exception channels cannot both be non-empty.
A programming environment may also stipulate that every
function must either return a value or throw an exception,
meaning that after a function returns
the \rCh{} and \xCh{} runtime channels cannot both be
empty, either.  So exactly one of the channels must be non-empty,
which can be notated like \rOneOrx{}.
}
\p{Formulae can also express how channels combine to
describe possible function signatures: if every function \i{must}
have \lambda{} and \return{} channels and \i{may} have an exception
channel, this could be notated like \lrxSimple{}.  Note that such
notation relates to function \i{signatures}, not runtimes: a
function signature may declare that it \i{can} throw exceptions, but
usually \i{not} do so, so the exception channel is usually empty.  Having
a runtime-empty kind of channel is different from not having
that kind of channel at all.  Function signature options
may be combined with formulae about channel sizes, yielding notation
like \lrxDetailed{}, asserting that an allowable function signature
\i{must} include \lambda{} and \return{}, \i{may} include exceptions,
where lambda channels can be of zero or greater size and
the other channels sized at most one.
}
\p{\phantomsection\label{retexc}Finally, adding an axiom about the restricted interrelationship between
\return{}s and \exception{}s yields a formula like \lrxTotal{}; the
initial \q{\lrx{}} asserting in effect \q{there exist} channels
satisfying these categories.  Collectively I will say that formulae
like these describing channel kinds, their restrictions, and
their interrelationships describe a \i{Channel Algebra}.  The
purpose of a Channel Algebra is, among other things, to describe
how formal languages (like programming languages) formulate functions and
the rules they put in place for inputs and outputs.  If \Chi{} is a
Channel Algebra, a language adequately described by its formulae
(with respect to functions and function-types) can be called a
\Chi{}-language.  The basic Lambda Calculus can be described as a
\Chi{}-language for the algebra \lr{}.
}
\p{This wording can also be extended to types.  A Channel Algebra describes
the channels that may (or must) be declared for a complete type signature.
Let \Chi{} be a Channel Algebra governed
by the \mbox{characterization} \lsrx{}
\mdash{} representing an Object-Oriented language where
\sCh{} is a \q{Sigma} channel as in \q{Sigma Calculus}
(written as \sigmaCalculus{}: see e.g. \cite{MartinAbadi},
\cite{EdwardZalta}, \cite{KathleenFisher}).
These channels are associated with function \q{signatures}, and
a function's signature determines its type.  So we can say that the
Type System \TyS{} manifest in the underlying Object-Oriented language is
a \q{\Chi{}-type-system} and is \q{closed} with respect to \Chi{}
in that valid signatures described using channel kinds in
\Chi{} correspond to types found in \TyS{}.  Types may be less granular than
signatures: as a case in point,
functions differing in signature only by whether they
throw exceptions may or may not be deemed the same type.  But a channel
construction on types in \TyS{} must also yield a type in \TyS{}.
}
\p{I say that a type system is \i{channelized} if it is
closed with respect to some Channel Algebra.
Channelized Hypergraphs are then \DH{}s whose type system is Channelized.
We can think of channel constructions as operators which combine
groups of types into new types (this operative dimensions helps
motivate describing channel logics and their formulae as \q{algebras}).
Once we assert that a \CH{} is Channelized, we know that there is a mechanism
for describing some Hypergraphs as \q{function
implementations} some of whose hypernodes are subject to
kinds of abstraction present in the relevant Channel Algebra.  The
terse notation for Channel formulae and signatures describes
logical norms which can also be expressed with more conventional
Ontologies.  So Channel Algebra can be seen as a generalization of
(\RDF{}-environment) Source Code Ontology
(of the kinds studied for example by
\cite{ImanKeivanloo}, \cite{WernerKlieber},
\cite{JohnathanLee}, \cite{TurnerEden},
\cite{ReneWitte}, \cite{PornpitWongthongtham}).  Given the relations between
\RDF{} and Directed Hypergraphs (despite differences I have discussed here),
Channel Algebras can also be seen as adding to Ontologies governing
Directed Hypergraphs.  Such is the perspective I will take
for the remainder of this chapter.
}
%\decoline{}
\p{For a Channel Algebra \Chi{} and a \Chi{}-closed type system
(written, say) \TySChi{}, \Chi{} extends \TyS{} because function-signatures
conforming to \Chi{} become types in \TyS{}.  At the same time,
\TyS{} also extends \Chi{}, because the elements that
populate channels in \Chi{} have types within \TyS{}.  Assume that for
any type system, there is a
partner \q{Type Expression Language} (\TXL{}) which governs how type
descriptions (especially for aggregate types that do not have a
single symbol name) can be composed consistent with the logic of
the system.  The \TXL{} for a type-system \TyS{} can be
notated as \TXLTyS{}.  If \TyS{} is channelized then its
\TXL{} is also channelized \mdash{} say, \TXLTySChi{} for some \Chi{}.
}
\p{Similarly, we can then develop for Channel Algebras a \i{Channel
Expression Language}, or \CXL{}, which can indeed be integrated with
appropriate \TXL{}s.  The notation
I adopted earlier for stating Channel Algebra axioms is one example
of a \CXL{}, though variant notations may be desired for actual
computer code (as in the code samples accompanying this chapter).
However, whereas the \CXL{} expressions I have written so far
describe the overall shape of channels
\mdash{} which channels exist in a given context and their sizes
\mdash{} \CXL{} expressions can also add details concerning the \i{types} of
values that can or do populate channels.
\CXL{} expressions with these extra specifications then become
function signatures, and therefore can be type-expressions in the
relevant \TXL{}.  A channelized \TXL{} is then a
superset of a \CXL{}, because it adds \mdash{} to \CXL{} expressions
for function-signatures \mdash{} the stipulation that a particular
signature does describe a \i{type}; so \CXL{} expressions
become \TXL{} expressions when supplemented with a proviso
that the stated \CXL{} construction describes a
function-type signature.  With such a proviso, descriptions of
channels used by a function qualifies as a type attribution,
connecting function symbol-names
to expressions recognized in the \TXL{} as describing a type.
}
\p{Some \TXL{} expressions
designate function-types, but not all, since there are many types
(like integers, etc.) which do not have channels at all.
While a \TXL{} lies \q{above} a \CXL{} by adding provisos that
yield type-definition semantics from \CXL{} expressions,
the \TXL{} simultaneously in a sense lies \q{beneath} the
\CXL{} in that it provides expressions for the non-functional
types which in the general case are the basis for \CXL{}
expressions of functional types,
since most function parameters \mdash{} the input/output values
that populate channels \mdash{} have non-functional types.
Section \sectsym{}\hyperref[sThree]{3} will discuss the elements that \q{populate}
\mbox{channels (which I will call \q{carriers}) in more detail}.
}
\p{Identifying \CH{} code-graphs with function-typed values \mdash{} values that
are instances of function-like types \mdash{} provides an elegant theoretical
foundation for exploring functional types and, potentially,
Functional Programming in general (among other things providing a
useful definition of \q{function types} in the first place, insofar
as these are types which need to be described via a \CXL{}, not
just the underlying \TXL{}).  One of the central tenets \mdash{} arguably
\i{the} central tenet \mdash{} of Functional Programming is that \q{functions
are values}; their \q{life cycle} as values constructed, used by and
potentially passed to other functions, and potentially then destructed,
should be seen as effectively the same as any other value.  It is interesting
that this understanding of function-typed values sometimes gets overlooked
in the context of discussions about \q{pure} functions.  Contra the
attention afforded to pure functions, there is no
reason to single out effect-free functions as particularly valuable
or paradigmatic function-typed values, at least none which seems
compelling on type-theoretic grounds.
}
\p{Function-typed values are not \q{mathematical} functions in the sense of
one-to-one or many-to-one mappings: functions \fOne{} and \fTwo{} may be
different (as function-typed values) even if \fOneTwoxeq{} for all
\xVar{}.  The definitive criteria for functions are their implementations,
which can be modeled as \CH{}-graphs; particularly since many \q{impure} functions
depend on external data outside their explicit inputs, so \fx{} may
yield different values at different times for the same \xSym{}.  As \q{normal}
values, functions implicitly have \q{constructors} like any other type; and
most of these constructors work by starting from a formal representation
of implementation source-code.  This picture, which I will analyze further
in the next section \mdash{} of function-typed values as values constructed from
code graphs, so constructing function-typed values reveals a mapping
(or even functor) from (suitably abstracted) implementation code graphs to
suitably channelized types \mdash{} provides a formal
theory of function types that avoids direct reference to
functions' input values and the specific
relations they construct between inputs and outputs.
}
\p{In the following sections I will sketch a
\q{Channel Algebra} that codifies the graph-based representation
of functions as procedures whose inputs and
outputs are related to other functions by variegated semantics
(semantics that can be catalogued in a Source Code
Ontology).  With this foundation, I will argue that Channel-Algebraic
type representations can usefully model higher-scale
code segments (like statements and code blocks)
within a type system, and also how type interpretations
can give a rigorous interpretation to modeling
constructs such as code specifications and
\q{gatekeeping} code.  I will start this
discussion, however, by expanding on the idea of
functions as \i{values constructed} from code-graphs.
}
\vspace{4em}