24.05.2014 Views

Monadic Dynamical Systems in C++ with Concepts and in Haskell

Monadic Dynamical Systems in C++ with Concepts and in Haskell

Monadic Dynamical Systems in C++ with Concepts and in Haskell

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

<strong>Monadic</strong> <strong>Dynamical</strong> <strong>Systems</strong><br />

<strong>in</strong> <strong>C++</strong> <strong>with</strong> <strong>Concepts</strong> <strong>and</strong> <strong>in</strong> <strong>Haskell</strong><br />

Daniel L<strong>in</strong>cke 1,∗ , Patrik Jansson b , Marc<strong>in</strong> Zalewski c , Cezar Ionescu 1<br />

a Potsdam Institute for Climate Impact Research, Potsdam, Germany.<br />

b Chalmers University of Technology & University of Gothenburg, Gothenburg, Sweden.<br />

c Indiana University, Bloom<strong>in</strong>gton, USA.<br />

Abstract<br />

In scientific programm<strong>in</strong>g, the implementation of a computational model goes h<strong>and</strong> <strong>in</strong><br />

h<strong>and</strong> <strong>with</strong> a deep analysis of the underly<strong>in</strong>g doma<strong>in</strong>. Software developers <strong>and</strong> doma<strong>in</strong><br />

experts work together to develop a common underst<strong>and</strong><strong>in</strong>g <strong>and</strong> a (possibly executable)<br />

specification. Such a specification should be easy to underst<strong>and</strong> <strong>and</strong> serve as a sketch<br />

for an implementation <strong>in</strong> a high-performance language. In this paper, we describe<br />

a doma<strong>in</strong> us<strong>in</strong>g <strong>Haskell</strong> as a modell<strong>in</strong>g language <strong>and</strong> then we derive a generic implementation<br />

framework from the <strong>Haskell</strong> model. To achieve this, we transform functional<br />

<strong>Haskell</strong> constructs describ<strong>in</strong>g the doma<strong>in</strong> notions <strong>in</strong>to a hierarchy of concepts, generic<br />

algorithms, <strong>and</strong> generic constructors. Our approach is flexible: we can implement a library<br />

based on these concepts <strong>in</strong> every language which supports concept-based generic<br />

programm<strong>in</strong>g.<br />

In particular, we beg<strong>in</strong> <strong>with</strong> the doma<strong>in</strong> of vulnerability assessment. We start <strong>with</strong><br />

analysis of the doma<strong>in</strong>, <strong>and</strong> we provide a high-level executable model based on dynamical<br />

monadic systems. Then we systematically translate the model <strong>in</strong>to a generic<br />

concept-based library. Our approach is demonstrated by a translation <strong>in</strong>to <strong>C++</strong>, but also<br />

sketch how to reimplement our library <strong>in</strong> <strong>Haskell</strong> us<strong>in</strong>g the same pr<strong>in</strong>ciples.<br />

Keywords: generic programm<strong>in</strong>g, functional programm<strong>in</strong>g, vulnerability assessment<br />

1. Introduction<br />

The road from a doma<strong>in</strong> of scientific knowledge to an efficient implementation<br />

is long <strong>and</strong> perilous, often result<strong>in</strong>g <strong>in</strong> an implementation that bears little apparent<br />

resemblance to the doma<strong>in</strong>. Still, the practitioners of high-performance comput<strong>in</strong>g are<br />

will<strong>in</strong>g to pay the price of overwhelm<strong>in</strong>gly low-level implementations to guarantee<br />

performance. In the current day <strong>and</strong> age, however, it is possible to <strong>in</strong>crease the level of<br />

abstraction by apply<strong>in</strong>g generic programm<strong>in</strong>g techniques to provide a high-level library<br />

∗ Correspond<strong>in</strong>g author<br />

Email addresses: daniel.l<strong>in</strong>cke@pik-potsdam.de (Daniel L<strong>in</strong>cke), patrikj@chalmers.se (Patrik<br />

Jansson), zalewski@osl.iu.edu (Marc<strong>in</strong> Zalewski), ionescu@pik-potsdam.de (Cezar Ionescu)<br />

Prepr<strong>in</strong>t submitted to Science of Computer Programm<strong>in</strong>g March 1, 2011


for a doma<strong>in</strong> that allows structured use of exist<strong>in</strong>g, efficient code. In this paper, <strong>in</strong><br />

particular, we show how to first describe a doma<strong>in</strong> <strong>in</strong> a high-level functional style, close<br />

to mathematical notation but executable, <strong>and</strong>, then, transform this description <strong>in</strong>to a<br />

strongly generic library that corresponds closely to the <strong>in</strong>itial description. Specifically,<br />

we present the process by which we derived a generic <strong>C++</strong> (Stroustrup, 1997) library<br />

for vulnerability assessment (vulnerability <strong>in</strong> the context of environmental sciences).<br />

The concept of “vulnerability” plays an important role <strong>in</strong> many research fields, <strong>in</strong>clud<strong>in</strong>g<br />

climate change research (Adger, 2006). As we discuss <strong>in</strong> Sect. 2, there is no<br />

unique def<strong>in</strong>ition of this term. However, there is a simple common structure underly<strong>in</strong>g<br />

the def<strong>in</strong>itions <strong>in</strong> the usage of “vulnerability”, which can be shortly described as measur<strong>in</strong>g<br />

the possible harm for a given system. <strong>Systems</strong> may be of very different natures,<br />

but it turns out that the differences can be captured by the idea of monadic dynamical<br />

systems that hides the particulars of a system beh<strong>in</strong>d a curta<strong>in</strong> of abstraction.<br />

Our <strong>C++</strong> library for monadic systems is derived from the high-level description <strong>in</strong><br />

<strong>Haskell</strong> (Peyton Jones, 2003), given by Ionescu (2009) <strong>in</strong> his formalisation of vulnerability<br />

done at the Potsdam Institute for Climate Impact Research. Ionescu relies on<br />

functional features of <strong>Haskell</strong>, such as function types <strong>and</strong> type constructors, to represent<br />

the underly<strong>in</strong>g mathematical notions of, among others, functors, coalgebras, monads,<br />

<strong>and</strong>, crucially, of monadic dynamical systems, which we <strong>in</strong>troduce <strong>and</strong> expla<strong>in</strong> <strong>in</strong><br />

Sect. 2.3. While his description can be executed, its design is focused on exposition of<br />

ideas <strong>and</strong> not on efficiency. Furthermore, the description is not generic enough to be<br />

applied <strong>in</strong> a practical sett<strong>in</strong>g of exist<strong>in</strong>g implementations, tool sets, <strong>and</strong> so on.<br />

Our library ma<strong>in</strong>ta<strong>in</strong>s the abstract, high-level correspondence <strong>with</strong> the doma<strong>in</strong> notions<br />

<strong>in</strong>troduced by Ionescu but it makes efficient implementations possible by provid<strong>in</strong>g<br />

a generic <strong>in</strong>terface for use of high-performance components. We are able to achieve<br />

the abstraction by bas<strong>in</strong>g the libraries on concepts, a well known term <strong>in</strong> generic programm<strong>in</strong>g.<br />

A concept is an abstract specification of a set of (tuples of) types (Bernardy<br />

et al., 2010). While <strong>in</strong> <strong>Haskell</strong> concepts are provided by means of type classes (Wadler<br />

<strong>and</strong> Blott, 1989), <strong>in</strong> <strong>C++</strong> they are still an experimental language feature called <strong>C++</strong>concepts<br />

(Gregor et al., 2006, 2008c). We use concepts to specify three k<strong>in</strong>ds of components<br />

from our application doma<strong>in</strong>:<br />

• a conceptual framework specify<strong>in</strong>g concepts for functional constructs, like functions,<br />

functors, monads, <strong>and</strong> so on;<br />

• parameterised types, themselves “typed” by concepts, that represent doma<strong>in</strong> constructs<br />

<strong>and</strong> comb<strong>in</strong>ators;<br />

• <strong>and</strong>, f<strong>in</strong>ally, generic functions represent<strong>in</strong>g the algorithms applicable <strong>in</strong> a given<br />

doma<strong>in</strong>.<br />

These components provide a generic, algorithmic description of a doma<strong>in</strong>. The user<br />

of our library must then plug <strong>in</strong> his/her complex data structures, but that is done only<br />

once for each concept, rather than for any possible comb<strong>in</strong>ation required by every<br />

comb<strong>in</strong>ator or algorithm. As an alternative, we provide some simple data structures<br />

that are meant for <strong>Haskell</strong>-like prototyp<strong>in</strong>g rather than a full-blown implementation.<br />

2


Functions<br />

Function Fun ∼ a -> b : describes general unary function types<br />

Type Constructors<br />

ConstructorType T ∼ f :: *->* : the type T is a unary type constructor<br />

SameTypeConstructor<br />

T1 ∼ f :: *->*, T2 ∼ f :: *->* : two types represent the same<br />

type constructor<br />

Functors <strong>and</strong> Monads<br />

Functor<br />

the type T is a unary functor type<br />

: ConstructorType<br />

Monad<br />

the type T is a unary monad type<br />

: ConstructorType<br />

Figure 1: Overview of the core concepts of the functional <strong>C++</strong> concepts library. The full library also conta<strong>in</strong>s<br />

concepts like FunctionN <strong>and</strong> FunctorN (for small N) <strong>and</strong> related convenience functions.<br />

Constructors for <strong>Monadic</strong> system<br />

Discrete_<strong>Monadic</strong>_System<br />

Trans ∼ (x -> m x) : a discrete monadic system<br />

∼ Int -> (x -> m x)<br />

is constructed from a given transition function Trans<br />

<strong>Monadic</strong>_System_Input<br />

Trans ∼ i -> (x -> m x), Cont ∼ [i] : an MDS<br />

∼ [i] -> (x -> m x)<br />

<strong>with</strong> <strong>in</strong>put of type [i] is constructed from a given<br />

transition function Trans<br />

Comb<strong>in</strong>ators for <strong>Monadic</strong> system<br />

<strong>Monadic</strong>_<strong>Systems</strong>_Parallel<br />

∼ (i1, i2)-> ((x,y)-> PairM m n (x,y))<br />

Sys_Ser_Function<br />

∼ (i1, i2)-> x -> m x<br />

Sys1 ∼ i1 -> (x -> m x),<br />

Sys2 ∼ i2 -> (y -> n y): : Two monadic systems<br />

are comb<strong>in</strong>ed <strong>in</strong> parallel<br />

Sys1 ∼ i1 -> (x -> m x),<br />

Sys2 ∼ i2 -> (x -> m x) : two monadic systems<br />

<strong>with</strong> the same state space <strong>and</strong> the same monad are<br />

comb<strong>in</strong>ed <strong>in</strong>to a comb<strong>in</strong>ed transition function <strong>with</strong><br />

<strong>in</strong>put<br />

Figure 2: Overview of the ma<strong>in</strong> parametrised types <strong>in</strong> the library<br />

Special Function types<br />

Coalgebra Fun ∼ x -> f x : functions whose codoma<strong>in</strong> is a functor<br />

: Function<br />

application<br />

CoalgebraWithInput Fun ∼ i -> x -> f x : coalgebras <strong>with</strong> an additional<br />

: Function2<br />

<strong>in</strong>put<br />

<strong>Monadic</strong>Coalgebra Fun ∼ x -> m x : functions whose codoma<strong>in</strong> is a monad<br />

: Coalgebra<br />

application<br />

<strong>Monadic</strong>CoalgebraWithInput Fun ∼ i -> x -> m x : monadic coalgebras <strong>with</strong> an<br />

: CoalgebraWithInput additional <strong>in</strong>put<br />

<strong>Monadic</strong> system<br />

<strong>Monadic</strong>System<br />

: Function<br />

Sys ∼ i -> (x -> m x) : Sys is a monadic system<br />

Figure 3: Overview of the ma<strong>in</strong> concepts <strong>in</strong> the <strong>Monadic</strong> systems library<br />

The library for monadic dynamical systems presented <strong>in</strong> this paper consists of two<br />

parts. First, we capture the basic constructs of functional programm<strong>in</strong>g <strong>in</strong> a separate<br />

library called FCPPC (Functional <strong>C++</strong> <strong>with</strong> <strong>Concepts</strong>) (L<strong>in</strong>cke, 2010; L<strong>in</strong>cke <strong>and</strong><br />

Schupp, 2009). In contrast to other exist<strong>in</strong>g libraries for functional <strong>C++</strong> programm<strong>in</strong>g,<br />

like F<strong>C++</strong> (McNamara <strong>and</strong> Smaragdakis, 2004a), our <strong>in</strong>tention is not to provide the<br />

3


whole <strong>Haskell</strong> prelude <strong>in</strong> <strong>C++</strong>. We rather provide a framework of concepts which specifies<br />

types for functional constructs. This library is <strong>in</strong>dependent of the vulnerability<br />

doma<strong>in</strong>, <strong>and</strong> can, or even should, be reused when our approach is used <strong>in</strong> other doma<strong>in</strong>s.<br />

Next, us<strong>in</strong>g the FCPPC library as the base, we capture the constructs from the<br />

doma<strong>in</strong> of monadic dynamical systems. While our library is split <strong>in</strong>to two parts based<br />

on reusability of the components of each part, both parts are derived us<strong>in</strong>g the same<br />

approach <strong>and</strong> both parts consists of the three k<strong>in</strong>ds of components described before.<br />

In order to give an overview of our approach, the core concepts from FCPPC are<br />

outl<strong>in</strong>ed <strong>in</strong> Fig. 1 <strong>and</strong> the core concepts <strong>and</strong> constructors/comb<strong>in</strong>ators of the monadic<br />

systems library are presented <strong>in</strong> Fig. 3 <strong>and</strong> Fig. 2. In both figures the left column shows<br />

the signature of the concepts <strong>and</strong> functions as well as ref<strong>in</strong>ement relations, written <strong>in</strong><br />

<strong>C++</strong> syntax. The right column shows how the parameters of the concept match the<br />

<strong>Haskell</strong> signature (we write C ∼ t for “<strong>C++</strong> type C corresponds to <strong>Haskell</strong> type t”).<br />

Furthermore we give a brief explanation of what the concept or function is <strong>in</strong>tended<br />

to model. The concepts are divided <strong>in</strong>to groups for presentation reasons (the group<strong>in</strong>g<br />

does not imply any hierarchy). In Figs. 1 <strong>and</strong> 3 we do not <strong>in</strong>tend to give a detailed<br />

description of the concepts we use, therefore associated entities are not stated.<br />

A library like our monadic system library is much more complex <strong>and</strong> verbose than<br />

its high-level specification <strong>in</strong> <strong>Haskell</strong> but it is surpris<strong>in</strong>gly similar <strong>and</strong> nimble from<br />

the po<strong>in</strong>t of view of the user. For example, the computation of macro-trajectories (see<br />

Sect. 2.3) is cleanly specified <strong>in</strong> <strong>Haskell</strong> as a function of the follow<strong>in</strong>g type:<br />

1 macro_trj :: (Monad m) => (i -> x -> m x) -> x -> [i] -> [m x]<br />

In the <strong>C++</strong> library functional constructs are lifted to the concept level, <strong>and</strong> the type of<br />

the function has to be translated accord<strong>in</strong>gly (express<strong>in</strong>g sequences <strong>with</strong> <strong>C++</strong>’s iterator<br />

mechanism):<br />

1 template<br />

3 requires<br />

4 std::SameType,<br />

5 std::SameType<br />

6 void<br />

7 macro_trajectory(Mon_Sys sys,<br />

8 Inp_Iter controls_bg, Inp_Iter controls_end,<br />

9 Mon_Sys::Codoma<strong>in</strong>::Doma<strong>in</strong>1 x,<br />

10 Out_Iter& ret);<br />

In <strong>C++</strong>, the type of the <strong>Haskell</strong> macro_trj function must be expressed <strong>in</strong> terms of<br />

concepts. Besides the concept <strong>Monadic</strong>System that is taken form our library, we rely<br />

on concepts from the <strong>C++</strong> st<strong>and</strong>ard library (preceded by the std:: prefix). While a<br />

function like macro_trajectory clearly is more complex from the po<strong>in</strong>t of view of a<br />

library developer, the complexity is hidden when the function is used:<br />

1 macro_trajectory(my_sys, ctrl.beg<strong>in</strong>(), ctrl.end(), <strong>in</strong>it, ret);<br />

The user must declare the necessary modell<strong>in</strong>gs (called “concept maps” <strong>in</strong> <strong>C++</strong> <strong>and</strong><br />

“<strong>in</strong>stances” <strong>in</strong> <strong>Haskell</strong>) that describe how types model the necessary concepts. The decoupl<strong>in</strong>g<br />

of concepts <strong>and</strong> their modell<strong>in</strong>gs makes it possible to use the library <strong>with</strong> the<br />

exist<strong>in</strong>g high-performance implementations while keep<strong>in</strong>g the complexity manageable.<br />

4


This paper is based on an earlier conference paper (L<strong>in</strong>cke et al., 2009). We generalised<br />

the approach by separat<strong>in</strong>g the functional components out <strong>in</strong>to a separate library.<br />

Furthermore we made the approach more widely applicable by transform<strong>in</strong>g the functional<br />

constructs <strong>and</strong> the doma<strong>in</strong> notions <strong>in</strong>to concepts <strong>in</strong> general. With these general<br />

concepts it is possible to implement the result<strong>in</strong>g library <strong>in</strong> any language which provides<br />

an implementation of concepts. From the po<strong>in</strong>t of view from the library, we<br />

additionally explored questions of system comb<strong>in</strong>ation <strong>and</strong> present some useful comb<strong>in</strong>ators<br />

for monadic dynamical systems.<br />

In the rema<strong>in</strong>der of the paper, we outl<strong>in</strong>e the progression from the doma<strong>in</strong> to an<br />

efficient implementation by first express<strong>in</strong>g doma<strong>in</strong> notions <strong>in</strong> a functional form, <strong>and</strong><br />

then implement<strong>in</strong>g them us<strong>in</strong>g our library of functional concepts, This is illustrated by<br />

our particular path from the doma<strong>in</strong> of monadic systems <strong>in</strong> the context of vulnerability<br />

assessment to our <strong>C++</strong> library for monadic systems. In Sect. 2, we present the concept<br />

of vulnerability as used <strong>in</strong> the climate change community <strong>and</strong> its mathematical formalisation<br />

<strong>in</strong> <strong>Haskell</strong>. We show that different k<strong>in</strong>ds of dynamical systems are <strong>in</strong>volved <strong>in</strong><br />

vulnerability studies <strong>and</strong> expla<strong>in</strong> why monadic dynamical systems are an appropriate<br />

model for these systems. Sect. 3.1 shows how functional constructs like functions,<br />

functors <strong>and</strong> monads can be expressed by concepts <strong>and</strong> show a <strong>C++</strong> implementation of<br />

them. Sect. 3.2 describes how the doma<strong>in</strong> specific constructs (concepts, parametrised<br />

types <strong>and</strong> functions) of the monadic systems doma<strong>in</strong> are provided <strong>in</strong> <strong>C++</strong> <strong>and</strong> Sect. 3.3<br />

shows how the library can be used. Sect. 4 expla<strong>in</strong>s how the concepts can be implemented<br />

us<strong>in</strong>g type classes <strong>in</strong> <strong>Haskell</strong>. In Sect. 5 we survey related work <strong>and</strong> <strong>in</strong> Sect. 6<br />

we discuss our approach <strong>and</strong> present ideas how to further generalise it.<br />

1.1. Prelim<strong>in</strong>aries<br />

We use <strong>Haskell</strong> code for describ<strong>in</strong>g the mathematical model, concepts for describ<strong>in</strong>g<br />

the conceptual framework <strong>and</strong> <strong>C++</strong> code for describ<strong>in</strong>g the actual implementation.<br />

Here we give a very short description of some of the notation used. It is worth not<strong>in</strong>g<br />

already from the start that :: is used <strong>in</strong> two different ways: <strong>in</strong> <strong>Haskell</strong> it is the “has<br />

type” keyword, while <strong>in</strong> <strong>C++</strong> it is the “scope resolution” operator.<br />

1.1.1. Functional modell<strong>in</strong>g<br />

Any pure functional language <strong>with</strong> appropriate support of generic programm<strong>in</strong>g<br />

could be used for our mathematical modell<strong>in</strong>g of monadic dynamical systems. Such<br />

languages usually have clean syntax <strong>and</strong> stay close to the orig<strong>in</strong>al mathematical notation<br />

from which they borrow their expressive type systems <strong>and</strong> algebraic type classes.<br />

We picked <strong>Haskell</strong> (Peyton Jones, 2003), <strong>with</strong>out any of the language extensions, for<br />

specification of the mathematical model. As usual <strong>in</strong> <strong>Haskell</strong> we denote function application<br />

by juxtaposition: f a denotes the application of f to a, parentheses are not<br />

needed. Function composition is (.) :: (b ->c) -> (a -> b) -> (a -> c) <strong>and</strong> for<br />

Kleisli composition we use ( (a -> m b) -> (a -> m c)<br />

We use two recursion operators for lists—foldr <strong>and</strong> scanr—which are best <strong>in</strong>troduced<br />

by example. If we def<strong>in</strong>e sum = foldr (+) 0 <strong>and</strong> sums = scanr (+) 0 then<br />

sum [3,2,1] is 6 <strong>and</strong> sums [3,2,1] are the partial sums [6,3,1,0]. Follow<strong>in</strong>g a similar<br />

pattern we use foldr to compose lists of monadic actions:<br />

5


1 mcompose :: Monad m => [x -> m x] -> (x -> m x)<br />

2 mcompose = foldr ( [a] which creates a list by repetition<br />

of a given element. For test<strong>in</strong>g we write predicates (parametrised test cases) as<br />

normal <strong>Haskell</strong> functions run by QuickCheck (Claessen <strong>and</strong> Hughes, 2000). F<strong>in</strong>ally we<br />

use the type constructor SimpleProb for probability distributions <strong>with</strong> f<strong>in</strong>ite support.<br />

1 type Prob = Double<br />

2 newtype SimpleProb a = SP [(a, Prob)] deriv<strong>in</strong>g Show<br />

The <strong>Haskell</strong> type system is complex enough to have has its own type system: k<strong>in</strong>ds.<br />

Base types, like Bool, are of k<strong>in</strong>d * while a parametrised type like SimpleProb has k<strong>in</strong>d<br />

*->*.<br />

1.1.2. <strong>Concepts</strong><br />

For concepts we stick to the term<strong>in</strong>ology from (Bernardy et al., 2010; Garcia et al.,<br />

2007a). We use the term concept for an abstract specification of a set of (tuples of)<br />

types, where the arity of a concept is the size of the tuple (the number of type parameters).<br />

Semantically, a concept is a predicate over types. When a tuple of types satisfies<br />

this predicate, we say that it is a model for the concept. A concept has a number of<br />

associated entities (often called members): values, functions, or types. Def<strong>in</strong>itions for<br />

these entities are provided <strong>in</strong> the modell<strong>in</strong>gs (model declarations). In addition, a concept<br />

can state requirements for its types. Modell<strong>in</strong>gs are type-checked tak<strong>in</strong>g these<br />

requirements <strong>in</strong>to account. <strong>Concepts</strong> can ref<strong>in</strong>e each other. A concept C 1 ref<strong>in</strong>es another<br />

concept C 2 if C 1 implies C 2 , that means the associated entities of C 2 are available<br />

whenever the entities of C 1 are available. In this paper we describe concepts literally<br />

by list<strong>in</strong>g their associated entities.<br />

1.1.3. <strong>Concepts</strong> <strong>in</strong> <strong>C++</strong><br />

<strong>C++</strong> implements concepts by the experimental language feature <strong>C++</strong>-concepts<br />

(Gregor et al., 2006, 2008c). <strong>Concepts</strong> can be used to constra<strong>in</strong> the type parameters<br />

of templates us<strong>in</strong>g the requires keyword. Templates (basically pieces of code<br />

parametrised by types or values) are the generic programm<strong>in</strong>g technique of <strong>C++</strong>. Concept<br />

modell<strong>in</strong>g <strong>in</strong> <strong>C++</strong> is done by concept maps which are used to b<strong>in</strong>d names dependent<br />

on type parameters to the implementations provided by the user (Gregor et al., 2006,<br />

2008c).<br />

The follow<strong>in</strong>g snippet of code is a complete example of us<strong>in</strong>g concepts:<br />

1 concept Function {<br />

2 typename Doma<strong>in</strong>1;<br />

3 typename Codoma<strong>in</strong>;<br />

4<br />

5 Codoma<strong>in</strong> operator () (Fun, Doma<strong>in</strong>1);<br />

6 };<br />

7<br />

8 template<br />

9 requires<br />

10 Function,<br />

6


11 std::SameType<br />

12 Fun::Codoma<strong>in</strong> twice(Fun fun, Fun::Doma<strong>in</strong>1 x) {<br />

13 return fun(fun(x));<br />

14 }<br />

15<br />

16 struct Increment {<br />

17 typedef Int Doma<strong>in</strong>1;<br />

18 typedef Int Codoma<strong>in</strong>;<br />

19<br />

20 Codoma<strong>in</strong> operator()(Doma<strong>in</strong>1 x) { return x++; }<br />

21 };<br />

22<br />

23 concept_map Function {<br />

24 typedef Increment::Doma<strong>in</strong>1 Doma<strong>in</strong>1;<br />

25 typedef Increment::Codoma<strong>in</strong> Codoma<strong>in</strong>;<br />

26 }<br />

27<br />

28 Increment <strong>in</strong>c;<br />

29 <strong>in</strong>t x = twice(<strong>in</strong>c,0);<br />

The concept Function, def<strong>in</strong>ed from L<strong>in</strong>e 1, def<strong>in</strong>es a predicate on a s<strong>in</strong>gle type <strong>and</strong><br />

requires two associated type Doma<strong>in</strong>1 <strong>and</strong> Codoma<strong>in</strong> <strong>and</strong> an application operator ().<br />

Thus, the concept specifies function types. It is then used, on L<strong>in</strong>e 10, to constra<strong>in</strong> the<br />

sole type parameter of the twice function. The requirement ensures, that the parameter<br />

type is a function type. The second requirement (L<strong>in</strong>e 11) states that this function<br />

type is a homogeneous function, which makes it possible to apply the function two<br />

times. The user-def<strong>in</strong>ed type Increment, def<strong>in</strong>ed <strong>in</strong> L<strong>in</strong>es 16–21, is than declared to<br />

model Function, on L<strong>in</strong>e 23. In the model declaration the b<strong>in</strong>d<strong>in</strong>gs for the associated<br />

types are provided (L<strong>in</strong>es 24–25) while the def<strong>in</strong>ition of the associated operator is<br />

not given explicitly. In such situations, the compiler is required to attempt to f<strong>in</strong>d a<br />

match<strong>in</strong>g def<strong>in</strong>ition <strong>in</strong> the context, <strong>and</strong>, <strong>in</strong> this case, it f<strong>in</strong>ds the application operator<br />

of Increment. F<strong>in</strong>ally, the usage of concept-constra<strong>in</strong>ed twice is demonstrated on<br />

L<strong>in</strong>e 29: the application twice(<strong>in</strong>c,0) concept-checks, s<strong>in</strong>ce the required concept<br />

map has been def<strong>in</strong>ed.<br />

While <strong>in</strong> the above example, requirements on the twice function were all given<br />

<strong>in</strong> the requires clause, concepts can be also written “<strong>in</strong>l<strong>in</strong>e.” Thus, the Function<br />

requirement from could be also written as:<br />

template<br />

We use the <strong>in</strong>l<strong>in</strong>e notation frequently as it signifies the “types of types” role of concepts.<br />

As concepts are an experimental feature they are not supported by common compilers.<br />

To make the <strong>C++</strong> code compilable on st<strong>and</strong>ard compilers we use traits (Myers,<br />

1995) to simulate concepts. Traits are template classes which provide b<strong>in</strong>d<strong>in</strong>gs for associated<br />

entities by specialisations for particular types, <strong>with</strong>out be<strong>in</strong>g able to check the<br />

type correctness of templates.<br />

The <strong>C++</strong> code <strong>in</strong> this paper is tested <strong>with</strong> the gcc compiler 1 , version 4.3, <strong>and</strong> the<br />

1 http://gcc.gnu.org/<br />

7


concept code is partly tested <strong>with</strong> the ConceptGCC compiler 2 (version alpha 7). In<br />

<strong>C++</strong>, we name concepts <strong>in</strong> CamelCase, <strong>and</strong> for class names we use Camel_Case <strong>with</strong><br />

underscores. Furthermore, <strong>in</strong> the <strong>C++</strong> code we usually omit unnecessary details such as<br />

const qualifiers or reference (&) type modifiers—while these are important for performance<br />

they do not contribute to the exposition. F<strong>in</strong>ally, <strong>in</strong> template parameter lists, the<br />

keywords class <strong>and</strong> typename are freely exchangeable—the variations <strong>in</strong> the paper are<br />

motivated by space constra<strong>in</strong>ts.<br />

1.1.4. <strong>Haskell</strong> <strong>with</strong> concepts<br />

<strong>Concepts</strong> are implemented <strong>in</strong> <strong>Haskell</strong> by the means of type classes (Wadler <strong>and</strong><br />

Blott, 1989). Models of concepts are declared by the <strong>in</strong>stance declaration keyword,<br />

constra<strong>in</strong><strong>in</strong>g an algorithm <strong>with</strong> concept requirements is done <strong>with</strong> the => declaration.<br />

We make frequent use of the concepts Monad <strong>with</strong> members functions (>>=) (pronounced<br />

“b<strong>in</strong>d”) <strong>and</strong> return <strong>and</strong> the Functor concept <strong>with</strong> the member function fmap.<br />

1 class Functor f where<br />

2 fmap :: (a -> b) -> f a -> f b<br />

3<br />

4 class Monad m where<br />

5 (>>=) :: m a -> (a -> m b) -> m b<br />

6 return :: a -> m a<br />

Note that the parameters f <strong>and</strong> m are of k<strong>in</strong>d * ->*, so these concepts (type classes)<br />

constra<strong>in</strong> type constructors, not types. Type classes <strong>with</strong> parameter of other k<strong>in</strong>d than<br />

* are sometimes called constructor classes (Jones, 1993).<br />

The list type constructor [] is a model of both the Functor <strong>and</strong> the Monad concept:<br />

1 <strong>in</strong>stance Functor [] where<br />

2 fmap = map<br />

3<br />

4 <strong>in</strong>stance Monad [] where<br />

5 xs >>= f = concat (map f xs)<br />

6 return x = [x]<br />

Over the years <strong>Haskell</strong> has acquired a number of extensions (for multiple parameters,<br />

associated types, equality constra<strong>in</strong>ts, etc.) to the basic idea of type classes <strong>and</strong> <strong>in</strong><br />

Sect. 4 we use quite a few of those extensions to port the <strong>C++</strong> conceptual framework<br />

for monadic dynamical systems “back to <strong>Haskell</strong>”.<br />

2. Vulnerability Modell<strong>in</strong>g<br />

In the past decade, the concept of “vulnerability” has played an important role <strong>in</strong><br />

fields such as climate change, food security, <strong>and</strong> natural hazard studies. Vulnerability<br />

studies have been useful <strong>in</strong> alert<strong>in</strong>g policymakers to the possibility of precarious<br />

situations <strong>in</strong> the future.<br />

2 http://www.generic-programm<strong>in</strong>g.org/software/ConceptGCC/<br />

8


However, def<strong>in</strong>itions of vulnerability vary: there seem to be almost as many def<strong>in</strong>itions<br />

of vulnerability as case studies conducted. Wolf et al. (2008), for <strong>in</strong>stance,<br />

analyse the usage of 20 def<strong>in</strong>itions of vulnerability. An allegory frequently used to<br />

describe the term<strong>in</strong>ology is the Babylonian confusion, <strong>and</strong> the need for a common underst<strong>and</strong><strong>in</strong>g<br />

has repeatedly been expressed <strong>in</strong> the literature (Brooks, 2003; Janssen <strong>and</strong><br />

Ostrom, 2006).<br />

While def<strong>in</strong>itions of vulnerability are usually imprecise, Ionescu (2009) proposes<br />

a mathematically def<strong>in</strong>ed framework that underlies the def<strong>in</strong>itions <strong>and</strong> the usage of the<br />

term vulnerability. Ionescu’s framework applies to those studies that “project future<br />

conditions” by us<strong>in</strong>g computational tools <strong>and</strong> that can thus be designated as computational<br />

vulnerability assessment. This common framework for vulnerability assessment<br />

consists of three primitive concepts: an entity (which is subject to possible future<br />

harm), possible future evolutions (of the entity), <strong>and</strong> harm. Next, we briefly summarise<br />

Ionescu’s development. First, we discuss the primitive concepts <strong>and</strong>, then, their extension<br />

to monadic dynamical systems.<br />

2.1. A Simple Mathematical Model of Vulnerability<br />

An entity, its current situation, <strong>and</strong> its environment are described by a state. In<br />

vulnerability computations, the current state of an entity is only a start<strong>in</strong>g po<strong>in</strong>t; it is the<br />

evolution of the state over time that is the ma<strong>in</strong> focus of <strong>in</strong>terest. A s<strong>in</strong>gle evolution path<br />

of an entity is called a trajectory. In a first, simple vulnerability model, the evolution<br />

of an entity is computed <strong>in</strong> a s<strong>in</strong>gle step:<br />

1 possible :: State -> F Evolution<br />

The possible function maps a state <strong>in</strong>to an F-structure of future evolutions. Two<br />

types <strong>and</strong> one type constructor are <strong>in</strong>volved: State is the type of the state of an entity,<br />

Evolution is the type of the evolution of an entity, <strong>and</strong> F is the type constructor<br />

represent<strong>in</strong>g the structure of evolutions (e.g., a set). In this simple model we take<br />

Evolution = [State]: an evolution is a f<strong>in</strong>ite sequence of the states that an entity<br />

successively assumes over time. This notion is sufficient, as most vulnerability assessments<br />

are made for a given horizon, which is expressible as a f<strong>in</strong>ite evolution.<br />

The constructor F is a functor (see Sect. 1.1) that describes the nature of the future<br />

computation. For example, if the future of an entity is determ<strong>in</strong>istic, one would<br />

have F = Id, the identity functor, giv<strong>in</strong>g a s<strong>in</strong>gle evolution. Sometimes, a more sophisticated<br />

model may be necessary. For <strong>in</strong>stance, a stochastic model might be used,<br />

which computes probability distributions over trajectories; the stochastic functor <strong>in</strong>troduced<br />

<strong>in</strong> Sect. 1.1 captures such situations (F = SimpleProb). Some other models<br />

might produce just lists of trajectories, <strong>with</strong>out assign<strong>in</strong>g a specific probability to each<br />

possibility. For these models, the trajectories are enclosed <strong>in</strong> the list functor (F = []).<br />

The second <strong>in</strong>gredient of a vulnerability computation is a harm judgement function:<br />

1 harm :: Evolution -> Harm<br />

The harm function maps evolutions <strong>in</strong>to values of type Harm, which describes the nature<br />

of the harm assessment. One of the simplest harm assessments is a threshold measurement.<br />

Examples of thresholds that can be crossed <strong>in</strong>clude temperature that grows too<br />

9


high or a budget that is too low. Correspond<strong>in</strong>gly, threshold harm measurement judges<br />

two possibilities, namely “yes, there is harm for this evolution” or “no, there isn’t any<br />

harm when the entity evolves <strong>in</strong> this way.” In such cases, harm is simply a boolean<br />

value (Harm = Bool). In other models, the harm value for each trajectory may be measured<br />

as a real value (Harm = R). A more sophisticated model might measure multiple<br />

dimensions of harm, all expressed as real values, which would lead to Harm = R N .<br />

The harm function measures the harm of a s<strong>in</strong>gle evolution, but a model produces<br />

an F-structure of evolutions, given some implementation of the function possible. The<br />

harm function must then be mapped to the evolutions, us<strong>in</strong>g the fmap function of the<br />

functor F (see Sect. 1.1). A measure function takes the result<strong>in</strong>g F-structure of harm<br />

values <strong>and</strong> summarises them <strong>in</strong>to an overall measurement:<br />

1 measure :: F Harm -> V<br />

The codoma<strong>in</strong> of the measure function could be, for example, the real numbers (to get<br />

the result as a s<strong>in</strong>gle number, a way of expression policymakers prefer) or a multidimensional<br />

space (to express various dimensions of vulnerability <strong>in</strong>stead of collaps<strong>in</strong>g<br />

it <strong>in</strong>to a s<strong>in</strong>gle number). Common examples for the measure function are measure<br />

= maximum <strong>in</strong> the case of F = [] <strong>and</strong> Harm = Bool, or measure = expectation <strong>in</strong> the<br />

case of F = SimpleProb <strong>and</strong> Harm = R.<br />

Comb<strong>in</strong><strong>in</strong>g these three functions gives the vulnerability computation:<br />

1 vulnerability :: State -> V<br />

2 vulnerability = measure . fmap harm . possible<br />

This computation captures the idea beh<strong>in</strong>d many vulnerability def<strong>in</strong>itions: we measure<br />

the harm that might be possible. The follow<strong>in</strong>g example illustrates the use of the<br />

vulnerability computation framework:<br />

1 type Economy_State = (Double, Double, Double, ...)<br />

2 -- GDP, GDP-growth, Unemployment Rate, <strong>and</strong> so on ...<br />

3 type Economy_Evolution = [Economy_State]<br />

4<br />

5 possible_economy :: Economy_State -> [ Economy_Evolution ]<br />

6 possible_economy x = -- ... implement a model of an economy here<br />

7<br />

8 economic_harm :: Economy_Evolution -> Double<br />

9 economic_harm ec_ev = -- ... return -(biggest GDP-change)<br />

10<br />

11 economic_vulnerability :: Economy_State -> Double<br />

12 economic_vulnerability = maximum . fmap economic_harm . possible_economy<br />

The implementation of the economy evolution function is unspecified, but the type<br />

<strong>in</strong>dicates that it is performed non-determ<strong>in</strong>istically. Harm is def<strong>in</strong>ed as the greatest<br />

decrease <strong>in</strong> Gross Domestic Product (GDP) over a trajectory; the harm function returns<br />

zero if the GDP is always <strong>in</strong>creas<strong>in</strong>g. In the f<strong>in</strong>al vulnerability computation, the<br />

maximum function is used as measure, def<strong>in</strong><strong>in</strong>g vulnerability as the greatest economic<br />

loss over all possible evolutions of the economy from a given state.<br />

10


2.2. Vulnerability measures<br />

An important result of this analysis, go<strong>in</strong>g beyond the implementation of software<br />

components, is the <strong>in</strong>creased underst<strong>and</strong><strong>in</strong>g of vulnerability. This is often the case <strong>with</strong><br />

develop<strong>in</strong>g a Doma<strong>in</strong> Specific Language (DSL): the activity leads to a deeper underst<strong>and</strong><strong>in</strong>g<br />

of the doma<strong>in</strong>, not just for the computer scientist, but even for the doma<strong>in</strong><br />

expert. We give here a couple of examples.<br />

We were able to formulate precisely the natural condition of consistency between<br />

the impact evaluations <strong>and</strong> the vulnerability measure: if the harm <strong>in</strong> the structure <strong>in</strong>creases,<br />

then the vulnerability measure should not decrease. This can be formalised<br />

as follows: for any function f :: Harm -> Harm <strong>with</strong> h V <strong>and</strong> m2 :: F2 Harm -> V are<br />

said to be compatible <strong>with</strong> respect to tau if, for all hs1, hs2 :: F1 Harm we have<br />

that m1 hs1


2.3. <strong>Monadic</strong> <strong>Systems</strong> <strong>and</strong> Vulnerability<br />

The simple model of vulnerability presented <strong>in</strong> the previous section has two ma<strong>in</strong><br />

disadvantages. First, it is not very generic: as shown <strong>in</strong> the economy example we have<br />

to write a new function for every vulnerability computation. This can easily be fixed by<br />

mak<strong>in</strong>g possible, harm <strong>and</strong> measure <strong>in</strong>puts to the vulnerability computation. Second,<br />

the model is <strong>in</strong>flexible: the evolution function of the simple model only consumes the<br />

<strong>in</strong>itial state of a system as the <strong>in</strong>put. In practise, however, an evolution function often<br />

has more <strong>in</strong>puts. In particular, an evolution may depend on auxiliary control arguments<br />

that are not part of the <strong>in</strong>itial state of a system.<br />

Ionescu (2009) explores possible structures which might provide the required flexibility.<br />

On the one h<strong>and</strong> the multitude of systems which might be <strong>in</strong>volved has to be<br />

represented, on the other h<strong>and</strong> we want an easy way of comput<strong>in</strong>g iterations. It turns<br />

out that a functorial structure on the possible evolutions is not suitable for the trajectory<br />

computations <strong>and</strong> that the use of a monad <strong>in</strong>stead of a functor gives the possibility<br />

to iterate a system. Therefore, the notion of a monadic dynamical system (MDS) was<br />

<strong>in</strong>troduced. In contrast to the possible function, trajectories of a model def<strong>in</strong>ed by<br />

an MDS can be computed <strong>in</strong> multiple separate steps. For example, a trajectory of an<br />

MDS can be computed up to a certa<strong>in</strong> po<strong>in</strong>t, the result archived, <strong>and</strong> the computation<br />

cont<strong>in</strong>ued later <strong>with</strong> this <strong>in</strong>termediate result as a start<strong>in</strong>g po<strong>in</strong>t.<br />

An MDS is a mapp<strong>in</strong>g <strong>with</strong> the signature t -> (x -> m x), where m is a monad<br />

(see Sect. 1.1). An MDS takes a value of type t (e.g., t = Nat) to a (monadic) transition<br />

function of type x -> m x. Every MDS must fulfil some further conditions; for<br />

<strong>in</strong>stance, the type t has to form a monoid structure (<strong>with</strong> a zero z <strong>and</strong> an operation<br />

(+.)) <strong>and</strong> the MDS must preserve that structure (must be a monoid morphism). More<br />

precisely, the follow<strong>in</strong>g two laws (expressed as predicates) have to be satisfied (where<br />

(=.=) is po<strong>in</strong>twise equality for functions):<br />

1 sys_law_zero sys = sys z =.= return<br />

2 sys_law_plus sys t1 t2 = sys (t1 +. t2) =.= (sys t2 [Int]<br />

2 my_discrete_trans x = [x-1, x+1]<br />

We can construct an MDS from my_discrete_trans us<strong>in</strong>g discrete_sys:<br />

1 type Nat = Int<br />

2 discrete_sys :: (Monad m) => (x -> m x) -> (Nat -> x -> m x)<br />

3 discrete_sys f n = mcompose (replicate n f)<br />

Not all transitions of <strong>in</strong>terest are that simple. Often, a transition function does<br />

not only map a state <strong>in</strong>to an M-structure of states, but also takes an additional control<br />

parameter. This parameter describes some external <strong>in</strong>put which is not a part of the<br />

12


state. Such a function describes a family of transition functions, one for each control<br />

<strong>in</strong>put. Consider the follow<strong>in</strong>g example:<br />

1 type MyControl = Double<br />

2 type MyState = Double<br />

3 my_<strong>in</strong>put_trans :: MyControl -> (MyState -> SimpleProb MyState)<br />

4 my_<strong>in</strong>put_trans delta x = SP [(x + delta, 0.75),<br />

5 (x - delta, 0.25)]<br />

Here, every <strong>in</strong>put delta gives a different transition function. The function itself is not<br />

an MDS (because it fails to satisfy the MDS laws). But it can be used to construct a<br />

monadic system by us<strong>in</strong>g the follow<strong>in</strong>g constructor:<br />

1 <strong>in</strong>put_system :: (Monad m) => (i -> x -> m x) -> ([i] -> x -> m x)<br />

2 <strong>in</strong>put_system trans = mcompose . map trans<br />

Furthermore, given an MDS, two iteration functions can be def<strong>in</strong>ed: the macro<br />

trajectory function, macro_trj, computes the evolution of an M-structure of states, <strong>and</strong><br />

the micro trajectory, micro_trj, computes the M-structure of evolutions (sequences of<br />

states). Both computations start <strong>with</strong> a sequence of <strong>in</strong>puts of type i <strong>and</strong> an <strong>in</strong>itial state.<br />

The macro trajectory describes all possible states at each step of the computation, but<br />

does not connect them:<br />

1 macro_trj :: (Monad m) => (i -> (x -> m x)) -> [i] -> x -> [m x]<br />

2 macro_trj sys ts x = scanr (\i mx -> mx >>= sys i) (return x) ts<br />

The micro trajectory records the s<strong>in</strong>gle evolution paths <strong>in</strong>clud<strong>in</strong>g all <strong>in</strong>termediate states:<br />

1 micro_trj :: (Monad m) => (i -> (x -> m x)) -> [i] -> x -> m [x]<br />

2 micro_trj sys is x = mcompose (map (addHist . sys) is) [x]<br />

3<br />

4 addHist :: (Monad f) => (x -> f x) -> [x] -> f [x]<br />

5 addHist g (x : xs) = liftM (:(x : xs)) (g x)<br />

Comput<strong>in</strong>g the trajectories for the MDS constructed out of my_discrete_trans from<br />

the <strong>in</strong>itial state myx = 0 <strong>and</strong> the <strong>in</strong>put sequence myts = [1,1,1] yields:<br />

1 macro_trj (discrete_sys my_discrete_trans) myts myx ==<br />

2 [ [-3,-1,-1,1,-1,1,1,3],<br />

3 [-2,0,0,2],<br />

4 [-1,1],<br />

5 [0]]<br />

6<br />

7 micro_trj (discrete_sys my_discrete_trans) myts myx ==<br />

8 [ [-3,-2,-1, 0], [-1,-2,-1, 0], [-1, 0,-1, 0], [ 1, 0,-1, 0],<br />

9 [-1, 0, 1, 0], [ 1, 0, 1, 0], [ 1, 2, 1, 0], [ 3, 2, 1, 0]<br />

10 ]<br />

The example clarifies the nature of the two trajectory computations: The macro trajectory<br />

provides the <strong>in</strong>formation that the state of this system is 0 at the beg<strong>in</strong>n<strong>in</strong>g. After<br />

one step the state is either -1 or 1, after two steps it can be <strong>in</strong> state -2, 0 or 2 <strong>and</strong> so<br />

on. The micro trajectory function returns all the <strong>in</strong>dividual trajectories the system can<br />

take, from [-3,-2-1,0], where we always take the -1 path, to [3,2,1,0]. Macro <strong>and</strong><br />

micro trajectories are, as shown by Ionescu (2009), related by:<br />

13


1 fmap (!!n) (micro_trj sys ts x) == (macro_trj sys ts x !! n)<br />

It should be noted that while the trajectory computations work for any monadic coalgebra<br />

<strong>with</strong> <strong>in</strong>put, these laws are only valid for monadic dynamical systems (Ionescu,<br />

2009). Note furthermore, that the computed states are prepended to the list, lead<strong>in</strong>g to<br />

the un<strong>in</strong>tuitive order<strong>in</strong>g of states <strong>with</strong> the f<strong>in</strong>al state at the head of the list. The <strong>in</strong>put of<br />

myts are processed <strong>in</strong> the same order: start<strong>in</strong>g from the end of the list <strong>and</strong> proceed<strong>in</strong>g<br />

to the first element.<br />

Many computational models used <strong>in</strong> the climate change community already implicitly<br />

implement the structure of an MDS. For <strong>in</strong>stance, the climate model CLIMBER<br />

(Petoukhov et al., 2000) has an <strong>in</strong>ternal state which represents the current configuration<br />

of certa<strong>in</strong> physical parameters. In addition, CLIMBER takes as an <strong>in</strong>put the concentration<br />

of greenhouse gases. The CLIMBER model can be described as an MDS built from<br />

a family of transition functions <strong>with</strong> signature climber :: GHG -> (Climber_st -><br />

F Climber_st), where GHG is the type of values represent<strong>in</strong>g concentration of greenhouse<br />

gases, <strong>and</strong> F = Id is the identity monad, s<strong>in</strong>ce CLIMBER is determ<strong>in</strong>istic.<br />

To tie back to vulnerability assessment, the micro_trj computation for an MDS<br />

fits the signature of the possible function <strong>in</strong> a vulnerability computation. Thus, the<br />

possible can be computed as the structure of micro-trajectories of an MDS. Tak<strong>in</strong>g<br />

this <strong>in</strong>to account we can compute vulnerability as:<br />

1 vulnerability’ :: (Functor m, Monad m) =><br />

2 (i -> x -> m x) -> ([x] -> h) -><br />

3 (m h -> v) -> [i] -> x -> v<br />

4 vulnerability’ sys harm measure ts = measure . fmap harm . micro_trj sys ts<br />

Us<strong>in</strong>g the above def<strong>in</strong>itions, the examples of the possible functions from the previous<br />

section, <strong>with</strong> F = Id, F = [], or F = SimpleProb as the result<strong>in</strong>g structures, can all be<br />

easily translated to an MDS, s<strong>in</strong>ce all these functors are also monads.<br />

2.4. Comb<strong>in</strong><strong>in</strong>g monadic dynamical systems<br />

One monadic system is rarely used alone, at least <strong>in</strong> vulnerability assessment. It<br />

is, <strong>in</strong> fact, a common task to build a model of a complex system, such as the climate<br />

system, from build<strong>in</strong>g blocks: a model of the atmosphere, a model of the ocean, one<br />

for the ice-sheets at the poles, <strong>and</strong> so on. There are problems that are characteristic for<br />

the type of modell<strong>in</strong>g needed <strong>in</strong> vulnerability studies. In particular the build<strong>in</strong>g blocks<br />

are often represented <strong>in</strong> very different ways: physical systems might be described by<br />

determ<strong>in</strong>istic or stochastic systems, while the social systems are usually described as<br />

non-determ<strong>in</strong>istic or fuzzy. Even if all the systems operate on the same time scale,<br />

even if the geographical resolution is identical <strong>and</strong> all shared variables have uniform<br />

semantics, it is still not clear how to compute the trajectory of a comb<strong>in</strong>ation of, say,<br />

determ<strong>in</strong>istic <strong>and</strong> non-determ<strong>in</strong>istic systems.<br />

Unfortunately, there is no unique way of comb<strong>in</strong><strong>in</strong>g monads to yield monads (K<strong>in</strong>g<br />

<strong>and</strong> Wadler, 1992). The same two monads may be comb<strong>in</strong>ed differently, yield<strong>in</strong>g different<br />

results. Accord<strong>in</strong>gly, we present those comb<strong>in</strong>ations of systems which are most<br />

likely to be useful <strong>in</strong> the practice of computational vulnerability assessment.<br />

14


The simplest way of comb<strong>in</strong><strong>in</strong>g two systems is to put them <strong>in</strong> parallel. The trajectories<br />

of the two systems are computed <strong>in</strong>dependently, <strong>and</strong> are comb<strong>in</strong>ed by tupl<strong>in</strong>g.<br />

Thus, given two systems sys1 :: t1 -> x -> m x <strong>and</strong> sys2 :: t2 -> y -><br />

n y, putt<strong>in</strong>g them <strong>in</strong> parallel results <strong>in</strong> the system syspar (sys1, sys2) :: (t1, t2)<br />

-> (x, y) -> (m x, n y). It is trivial to check that syspar (sys1, sys2) is a monoid<br />

morphism (given that sys1 <strong>and</strong> sys2 are monoid morphisms).<br />

However, syspar (sys1, sys2) cannot be made a monadic dynamical system <strong>in</strong><br />

<strong>Haskell</strong>, because of the fact that there is no possibility to declare (M, N) to be a monad<br />

as the notion (M, N) does not even type check. In order to circumvent this problem<br />

we provide a technical workaround which starts <strong>with</strong> def<strong>in</strong><strong>in</strong>g the “pair<strong>in</strong>g” of two<br />

monads:<br />

1 newtype PairM m n a = PM (m a, n a)<br />

2 unwrapPM :: PairM m n a -> (m a, n a)<br />

3 unwrapPM (PM x) = x<br />

4<br />

5 <strong>in</strong>stance (Monad m, Monad n) => Monad (PairM m n) where<br />

6 return x = PM (return x , return x )<br />

7 (PM (mx, nx)) >>= f = PM (mx0, nx0)<br />

8 where<br />

9 mx0 = mx >>= (fst . unwrapPM . f )<br />

10 nx0 = nx >>= (snd . unwrapPM . f )<br />

11<br />

12 pr :: Functor f => (f a, b) -> f (a, b)<br />

13 pr (fa, b) = fmap (\a -> (a, b)) fa<br />

14<br />

15 pl :: Functor f => (b, f a) -> f (b, a)<br />

16 pl (b, fa) = fmap (\a -> (b, a)) fa<br />

17<br />

18 syspar :: (Functor m, Functor n) =><br />

19 (t1 -> x -> m x , t2 -> y -> n y) -><br />

20 (t1, t2) -> ((x, y) -> PairM m n (x, y))<br />

21 syspar (sys1, sys2) (t1, t2) (x, y) = PM (pr (sys1 t1 x, y),<br />

22 pl ( x, sys2 t2 y))<br />

Even if the def<strong>in</strong>ition of syspar only requires the functoriality of m <strong>and</strong> n, further conditions<br />

are needed for syspar (sys1, sys2) to also be a monoid morphism, therefore<br />

a monadic system. (More precisely, m <strong>and</strong> n need to be monads <strong>and</strong> sys1 <strong>and</strong> sys2<br />

monoid morphisms.)<br />

System comb<strong>in</strong>ation becomes more complicated when the <strong>in</strong>volved systems <strong>in</strong>teract<br />

(someth<strong>in</strong>g they cannot do when comb<strong>in</strong>ed <strong>in</strong> parallel). In the follow<strong>in</strong>g we only<br />

consider <strong>in</strong>teraction through shared state: the two systems are assumed to have the<br />

same state space X, although possibly different monoids <strong>and</strong> monads. This represents<br />

the follow<strong>in</strong>g situation: an <strong>in</strong>itial state (element of X) is modified by the first system<br />

accord<strong>in</strong>g to an <strong>in</strong>put from its own monoid, the result<strong>in</strong>g macro-state is then modified<br />

by the second system accord<strong>in</strong>g to an <strong>in</strong>put from its monoid, <strong>and</strong> so on. If both systems<br />

have the same monad, that is sys1 :: t1 -> x -> m x <strong>and</strong> sys2 :: t2 -> x -><br />

m x, one could expect the serial comb<strong>in</strong>ation to be def<strong>in</strong>ed as: comb (sys1, sys2)<br />

(t1, t2) = (sys2 t2)


Ionescu (2009) for explanation). Rather, we can def<strong>in</strong>e a system comb<strong>in</strong>ation sysser<br />

which uses pairs (t1, t2) as <strong>in</strong>puts:<br />

1 sysser :: (Monad m) => (t1 -> x -> m x,<br />

2 t2 -> x -> m x) -><br />

3 [(t1, t2)] -> x -> m x<br />

4 sysser (sys1, sys2) = <strong>in</strong>put_system f<br />

5 where f (t1, t2) = sys2 t2 (t1 -> x -> Id x,<br />

2 t2 -> x -> m x) -><br />

3 [(t1, t2)]-> x -> m x<br />

4 detserl (detsys, sys) = sysser (embedMDS detsys, sys)<br />

5<br />

6 detserr :: (Monad m) => (t1 -> x -> m x,<br />

7 t2 -> x -> Id x) -><br />

8 [(t1, t2)]-> x -> m x<br />

9 detserr (sys, detsys) = sysser (sys, embedMDS detsys)<br />

10<br />

11 embedMDS :: (Monad m) => (t -> a1 -> Id a) -> t -> a1 -> m a<br />

12 embedMDS detsys t = return . unwrapId . detsys t<br />

If there is no determ<strong>in</strong>istic system <strong>in</strong>volved, serial comb<strong>in</strong>ation becomes more difficult.<br />

This case is beyond the scope of this paper, we refer to Ionescu (2009) for discussion.<br />

3. Vulnerability Modell<strong>in</strong>g <strong>in</strong> <strong>C++</strong> <strong>with</strong> <strong>Concepts</strong><br />

In the previous section, we used <strong>Haskell</strong> to describe monadic systems <strong>and</strong> vulnerability<br />

assessment at high level, more <strong>in</strong> the mathematical specification style than as a<br />

practical computational library. Thanks to its laz<strong>in</strong>ess <strong>and</strong> its clean notation, <strong>Haskell</strong><br />

serves well as a modell<strong>in</strong>g <strong>and</strong> prototyp<strong>in</strong>g language that enables one to write operational<br />

def<strong>in</strong>itions that can be executed.<br />

However, an executable specification such as the one we have given <strong>in</strong> the previous<br />

section is not practical <strong>in</strong> real-life scientific programm<strong>in</strong>g. High-performance<br />

comput<strong>in</strong>g is usually performed <strong>in</strong> very specific <strong>and</strong> complex environments, <strong>and</strong> often<br />

there are many exist<strong>in</strong>g libraries <strong>and</strong> code bases that must be <strong>in</strong>tegrated. In this section<br />

we present a <strong>C++</strong> library for monadic dynamical systems that addresses the shortcom<strong>in</strong>gs<br />

of the high-level <strong>Haskell</strong> description while ma<strong>in</strong>ta<strong>in</strong><strong>in</strong>g much of the description’s<br />

clarity <strong>and</strong> structure. We choose <strong>C++</strong> because of its support of high-level generic programm<strong>in</strong>g,<br />

the ease <strong>with</strong> which exist<strong>in</strong>g components can be <strong>in</strong>tegrated, <strong>and</strong> because<br />

<strong>C++</strong> is well supported on high-performance platforms.<br />

Our choice of <strong>C++</strong> is not a crucial decision. By express<strong>in</strong>g the high-level structure of<br />

functional constructs <strong>in</strong> a generic manner by specify<strong>in</strong>g their requirements as concepts,<br />

16


our library is implementable <strong>in</strong> every language that provides support for generic programm<strong>in</strong>g<br />

<strong>with</strong> concepts. While we rely on the <strong>C++</strong> concepts (discussed <strong>in</strong> Sect. 1.1.3)<br />

to capture the notions of the doma<strong>in</strong>, a recent study by Garcia et al. shows that there are<br />

other languages <strong>with</strong> an appropriate generic programm<strong>in</strong>g support. In section Sect. 4<br />

we sketch how a similar concept-based library can be constructed <strong>in</strong> <strong>Haskell</strong>.<br />

Our methodology is to transform the <strong>Haskell</strong> description <strong>in</strong> a pr<strong>in</strong>cipled way to a<br />

correspond<strong>in</strong>g conceptual specification, <strong>and</strong> implement<strong>in</strong>g a <strong>C++</strong> framework based on<br />

that specification. In the nutshell, we reflect the <strong>Haskell</strong> types from the previous section<br />

us<strong>in</strong>g concepts so that, for example, function types <strong>and</strong> type constructors are expressed<br />

by concepts. This allows our library to freely glue exist<strong>in</strong>g code bases by plugg<strong>in</strong>g<br />

them <strong>in</strong>to well def<strong>in</strong>ed “slots” given by concepts. The algorithms <strong>and</strong> comb<strong>in</strong>ators are<br />

expressed as generic functions <strong>and</strong> types, respectively. We present our methodology <strong>in</strong><br />

more detail <strong>in</strong> the rema<strong>in</strong>der of this section, as we describe the particular elements of<br />

our library.<br />

The approach is split <strong>in</strong>to two libraries. The first one, discussed <strong>in</strong> Sect. 3.1, is the<br />

encod<strong>in</strong>g of basic functional-programm<strong>in</strong>g types <strong>and</strong> features. As such, this library is<br />

useful, or even strictly necessary, for any future development styled after our work. The<br />

second library (Sect. 3.2), build<strong>in</strong>g upon the first one, <strong>in</strong>troduces the notions necessary<br />

for monadic dynamical systems.<br />

3.1. A Functional <strong>Concepts</strong> Library<br />

The <strong>Haskell</strong> description of monadic dynamical systems, as shown <strong>in</strong> Sect. 2, uses<br />

the features of <strong>Haskell</strong> that make it a language so well suited for computable specifications.<br />

In particular, functions <strong>and</strong> categorial constructs such as monads or functors can<br />

be easily represented <strong>in</strong> the type system us<strong>in</strong>g first-class function types <strong>and</strong> type constructors.<br />

In this section, we encode these high-level features <strong>in</strong> a generic manner that<br />

makes it possible to reimplement them <strong>in</strong> non-functional languages <strong>and</strong> bridge them<br />

<strong>with</strong> exist<strong>in</strong>g code bases.<br />

We beg<strong>in</strong> <strong>with</strong> the most basic concept underly<strong>in</strong>g the specification of vulnerability:<br />

functions. In the <strong>Haskell</strong> description from Sect. 2, we use the built-<strong>in</strong> function type<br />

(->). This makes perfect sense <strong>in</strong> the sett<strong>in</strong>g where clarity is of topmost importance. In<br />

general, however, there are many programm<strong>in</strong>g languages that do not provide a built-<strong>in</strong><br />

function type. Function types are available <strong>in</strong> <strong>C++</strong>, but they are only useful for form<strong>in</strong>g<br />

function po<strong>in</strong>ters <strong>and</strong> meta-programm<strong>in</strong>g. As discussed by L<strong>in</strong>cke <strong>and</strong> Schupp (2009)<br />

there are multiple ways of implement<strong>in</strong>g mathematical functions <strong>in</strong> <strong>C++</strong>. L<strong>in</strong>cke <strong>and</strong><br />

Schupp consider mostly the efficiency of different implementations, but <strong>in</strong>tegration of<br />

legacy code is equally important, at least <strong>in</strong> our sett<strong>in</strong>g. A scientist wish<strong>in</strong>g to employ<br />

our vulnerability library may have an exist<strong>in</strong>g <strong>and</strong> potentially complex platformspecific<br />

implementation of particular functions. Therefore, <strong>in</strong>stead of us<strong>in</strong>g a particular<br />

type, we <strong>in</strong>troduce a Function concept that captures the basic requirements on a type<br />

implement<strong>in</strong>g functions. Every type which models unary functions has to provide the<br />

follow<strong>in</strong>g entities:<br />

• an associated doma<strong>in</strong> type (called Doma<strong>in</strong>1 3 ),<br />

3 We choose the name Doma<strong>in</strong>1 over just Doma<strong>in</strong> for consistency <strong>with</strong> higher-arity function concepts.<br />

17


• an associated codoma<strong>in</strong> type (called Codoma<strong>in</strong>),<br />

• <strong>and</strong> an application operator mapp<strong>in</strong>g elements of the doma<strong>in</strong> <strong>in</strong>to the codoma<strong>in</strong>.<br />

The function concept conta<strong>in</strong><strong>in</strong>g these associated entities is implemented directly:<br />

1 // Fun ~ a -> b<br />

2 concept Function {<br />

3 typename Doma<strong>in</strong>1;<br />

4 typename Codoma<strong>in</strong>;<br />

5<br />

6 Codoma<strong>in</strong> operator () (Fun, Doma<strong>in</strong>1);<br />

7 };<br />

Although the call operator, as written above, takes an object of type Fun as one of<br />

its arguments, the actual syntax of a function call on types modell<strong>in</strong>g the concept is<br />

f(x) where f is of type Fun <strong>and</strong> x is of type Doma<strong>in</strong>1.<br />

In general, crucial doma<strong>in</strong> notions from the <strong>Haskell</strong> description are translated <strong>in</strong>to<br />

concepts, class templates, or generic functions, depend<strong>in</strong>g on their role <strong>in</strong> the library.<br />

For example, our library provides a function composition operator, implemented as<br />

a class template “typed” <strong>with</strong> concepts, that given two functions as <strong>in</strong>put provides a<br />

composed function:<br />

1 // F ~ a -> b, G ~ b -> c<br />

2 template <br />

3 requires<br />

4 std::CopyConstructible, std::CopyConstructible,<br />

5 std::SameType<br />

6 class Composed_Function {<br />

7 public:<br />

8 typedef F::Doma<strong>in</strong>1 Doma<strong>in</strong>1;<br />

9 typedef G::Codoma<strong>in</strong> Codoma<strong>in</strong>;<br />

10<br />

11 // The constructor just stores f <strong>in</strong> my_f <strong>and</strong> g <strong>in</strong> my_g<br />

12 Composed_Function(F f, G g) : my_f(f), my_g(g) {}<br />

13<br />

14 Codoma<strong>in</strong> operator() (Doma<strong>in</strong>1 x) const { return my_g(my_f(x)); }<br />

15 private:<br />

16 F my_f;<br />

17 G my_g;<br />

18 };<br />

The Composed_Function comb<strong>in</strong>ator is implemented as a constra<strong>in</strong>ed class template.<br />

Its constra<strong>in</strong>ts correspond to the <strong>Haskell</strong> type signature (a->b)-> (b->c)-> (a->c)<br />

by stat<strong>in</strong>g that the two type parameters must each be models of the Function concept.<br />

Doma<strong>in</strong>s <strong>and</strong> codoma<strong>in</strong>s of the functions are left unspecified (type variables a, b, <strong>and</strong><br />

c <strong>in</strong> the <strong>Haskell</strong> type), mak<strong>in</strong>g Composed_Function polymorphic <strong>in</strong> the doma<strong>in</strong>s <strong>and</strong><br />

codoma<strong>in</strong>s of the composed functions. There is, however, a constra<strong>in</strong>t that the codoma<strong>in</strong><br />

of the first function must be the same as the doma<strong>in</strong> of the second function (the<br />

SameType requirement), correspond<strong>in</strong>g to reuse of the type variable b <strong>in</strong> the <strong>Haskell</strong><br />

type. The CopyConstructible requirements are a technical necessity <strong>in</strong> <strong>C++</strong>, s<strong>in</strong>ce ob-<br />

18


jects represent<strong>in</strong>g functions are copied <strong>and</strong> stored for later use via the <strong>in</strong>itialisation list 4<br />

<strong>in</strong> the Composed_Function constructor. The result type, (a->c) <strong>in</strong> <strong>Haskell</strong>, is not a part<br />

of the def<strong>in</strong>ition of the Composed_Function comb<strong>in</strong>ator. Instead, the result type must<br />

be provided by a concept map stat<strong>in</strong>g that any Composed_Function object is a function<br />

itself:<br />

1 template<br />

2 // requirements forwarded from Composed_Function<br />

3 concept_map Function {<br />

4 typedef F::Doma<strong>in</strong>1 Doma<strong>in</strong>1;<br />

5 typedef G::Codoma<strong>in</strong> Codoma<strong>in</strong>;<br />

6<br />

7 // the b<strong>in</strong>d<strong>in</strong>g for operator() is implicitly generated by the compiler<br />

8 }<br />

The above concept map states that all <strong>in</strong>stantiations of Composed_Function model the<br />

Function concept. The requirements on the F <strong>and</strong> G template arguments of the concept<br />

map are propagated from the def<strong>in</strong>ition of the Composed_Function comb<strong>in</strong>ator, so that<br />

they do not have to be copied <strong>and</strong> pasted. The associated types of the Function concept<br />

are stated explicitly, while the application operator is matched automatically (by name)<br />

to the appropriate def<strong>in</strong>ition <strong>in</strong> the Composed_Function template. The concept map<br />

just states that Composed_Function is a function, but the correspondence between the<br />

types of parameters <strong>and</strong> the type of the result<strong>in</strong>g composed function is encoded by the<br />

def<strong>in</strong>ition of Composed_Function <strong>and</strong> does not result from the concept map alone.<br />

While, by design, our Function concept is presented <strong>in</strong> <strong>C++</strong>, the methodology of<br />

the translation is, besides technicalities, language-<strong>in</strong>dependent:<br />

• for every generic function we have to provide a new (parameterised) type,<br />

• constra<strong>in</strong>ts are used to capture the <strong>in</strong>tended functional signature of this type,<br />

• if the codoma<strong>in</strong> of the function is itself a function type, we have to also <strong>in</strong>troduce<br />

a new type for the codoma<strong>in</strong> (<strong>and</strong> so on),<br />

• every new type which is <strong>in</strong>tended to model a function has to be declared as a<br />

model of the Function concept.<br />

In a similar manner, our library provides more function-related features. For convenience,<br />

we provide multiple argument function concepts such as Function2, Function3,<br />

<strong>and</strong> so on. In addition to the composition comb<strong>in</strong>ator, we provide function curry<strong>in</strong>g.<br />

Both composition <strong>and</strong> curry<strong>in</strong>g are extended to functions <strong>with</strong> multiple parameters.<br />

All comb<strong>in</strong>ators <strong>in</strong> our library come <strong>with</strong> convenience functions that make apply<strong>in</strong>g<br />

the comb<strong>in</strong>ators easier. For example, a compose function is provided for function composition:<br />

1 template <br />

2 requires<br />

3 std::CopyConstructible, std::CopyConstructible,<br />

4 Initialisation list appears after the colon follow<strong>in</strong>g the constructor.<br />

19


4 std::SameType<br />

5 Composed_Function compose(F f, G g) {<br />

6 Composed_Function ret(f, g);<br />

7 return ret;<br />

8 }<br />

Such a function is easier to apply than directly construct<strong>in</strong>g a Composed_Function<br />

object because <strong>C++</strong> automatically deduces template parameters from function call arguments.<br />

A full list of Function-related operations may be found <strong>in</strong> the library source<br />

code (L<strong>in</strong>cke, 2010).<br />

The description of vulnerability <strong>in</strong> Sect. 2 depended on type constructors to represent<br />

categorial notions such as monads or functors. As before, we do not rely on a<br />

particular type or language construct to represent type constructors, but, <strong>in</strong>stead, we<br />

represent type constructors as concepts so that various implementations of type constructors<br />

can be used.<br />

<strong>C++</strong> does not provide support for first-class type constructors. <strong>Concepts</strong> <strong>with</strong> template<br />

template parameters, that is, template parameters that themselves must be templates,<br />

are the most obvious encod<strong>in</strong>g for type constructors where template parameters<br />

represent type constructors. In practise, however, they are not well supported, <strong>and</strong> are<br />

rarely used by <strong>C++</strong> programmers. Also, such higher-order encod<strong>in</strong>g would force programmers<br />

to represent type constructors us<strong>in</strong>g a specific language mechanism (every<br />

constructor would be a template), a restriction we have specifically set out not to impose.<br />

Accord<strong>in</strong>gly, we represent type constructors (of the <strong>Haskell</strong> k<strong>in</strong>d * ->*) <strong>with</strong> a<br />

ConstructorType concept parametrised by a pla<strong>in</strong> template parameter. The concept<br />

provides three one associated entities: a template that represents type constructor application,<br />

an associated type which represents the type the constructor is applied to,<br />

<strong>and</strong> an associated requirement ensur<strong>in</strong>g the consistency of all the <strong>in</strong>gredients:<br />

1 // T ~ f :: *->*<br />

2 concept ConstructorType {<br />

3 template<br />

4 class Apply;<br />

5<br />

6 typename Inner;<br />

7<br />

8 // enforce a connection between T, Inner <strong>and</strong> Apply<br />

9 requires std::SameType;<br />

10 }<br />

A reader familiar <strong>with</strong> type constructors may be immediately baffled by Inner member<br />

<strong>and</strong> the SameType requirement. We <strong>in</strong>troduced the two to get around limitations of the<br />

<strong>C++</strong> type system. The problem is that, <strong>in</strong> general, application of two different constructor<br />

types may result <strong>in</strong> the same type caus<strong>in</strong>g <strong>in</strong>jectivity issues when pattern match<strong>in</strong>g<br />

on type constructor applications. To avoid <strong>in</strong>jectivity problems, our ConstructorType<br />

concept <strong>in</strong>troduces an artificial requirement that the constructor type tag T actually be<br />

an application of the constructor. The SameType requirement is used to establish a connection<br />

between the the constructor type T, the Apply operation, <strong>and</strong> the Inner type.<br />

If the constructor type T is applied to Inner, the result has to be T. Therefore it is not<br />

possible to declare an arbitrary type to be a type constructor. Our <strong>Haskell</strong> version of<br />

20


the ConstructorType concept <strong>in</strong> Sect. 4 is more ideal, rely<strong>in</strong>g on the feature of associated<br />

data types to prevent <strong>in</strong>jectivity errors. A similar technique could be used <strong>in</strong> <strong>C++</strong>,<br />

but s<strong>in</strong>ce there is no feature correspond<strong>in</strong>g directly to associated data types, it would<br />

have to be encoded severely complicat<strong>in</strong>g our library. We believe that <strong>in</strong> connection<br />

<strong>with</strong> template concept maps, our “trick” works out well. For <strong>in</strong>stance, the std::vector<br />

template from the STL is a type constructor:<br />

1 template<br />

2 concept_map ConstructorType {<br />

3 template<br />

4 us<strong>in</strong>g Apply = std::vector;<br />

5<br />

6 typedef T Inner;<br />

7 }<br />

The concept map states that any <strong>in</strong>stantiation of the std::vector template has an associated<br />

type constructor application, <strong>and</strong> it provides the application argument Inner<br />

for pattern match<strong>in</strong>g on particular applications.<br />

Furthermore, we provide a SameTypeConstructor concept that models equivalence<br />

between constructors similarly to how std::SameType concept models equivalence between<br />

types. In addition, as for functions, we provide concepts for type constructors of<br />

different arities.<br />

Us<strong>in</strong>g these simple concepts, we model more complex concepts. The Functor concept<br />

ref<strong>in</strong>es the notion of a type constructor. In <strong>Haskell</strong>, a functor is a type constructor<br />

<strong>with</strong> one additional (polymorphic) operation called fmap:<br />

1 class Functor f :: *->* where<br />

2 fmap :: (a -> b) -> f a -> f b<br />

Us<strong>in</strong>g the ConstructorType concept, we represent functors as follows:<br />

1 // F is a ConstructorType that is a Functor<br />

2 concept Functor : ConstructorType {<br />

3 template<br />

4 F::Apply fmap(Fun, F::Apply);<br />

5 }<br />

We first require that a functor type F be a type constructor by ref<strong>in</strong><strong>in</strong>g the concept<br />

ConstructorType, thus mak<strong>in</strong>g the Functor correspond to a <strong>Haskell</strong> type constructor<br />

class. Then, fmap is provided as an associated member, just as <strong>in</strong> <strong>Haskell</strong>, us<strong>in</strong>g the<br />

type constructor Apply template.<br />

Models for the Functor concept are provided by def<strong>in</strong><strong>in</strong>g the fmap function, as, for<br />

<strong>in</strong>stance, for the std::vector (tak<strong>in</strong>g <strong>in</strong>to account the previously def<strong>in</strong>ed concept map<br />

for the ConstructorType concept):<br />

1 template<br />

2 concept_map Functor {<br />

3 template<br />

4 ConstructorType::Apply<br />

5 fmap(Fun f, ConstructorType::Apply fx) {<br />

6 ConstructorType::Apply ret(fx.size());<br />

7 for (unsigned <strong>in</strong>t i=0; i


8 ret[i] = f(fx[i]);<br />

9 return ret;<br />

10 }<br />

11 }<br />

Monads are def<strong>in</strong>ed similarly to functors. The Monad concept also ref<strong>in</strong>es the<br />

ConstructorType concept. It provides two polymorphic member functions mb<strong>in</strong>d <strong>and</strong><br />

mreturn correspond<strong>in</strong>g to the follow<strong>in</strong>g <strong>Haskell</strong> signatures:<br />

1 class Monad (m :: *->*) where<br />

2 mb<strong>in</strong>d :: m x -> (x -> m y) -> m y<br />

3 mreturn :: x -> m x<br />

Us<strong>in</strong>g the previously def<strong>in</strong>ed concepts ConstructorType <strong>and</strong> Function, the signatures<br />

are translated <strong>in</strong>to the Monad concept:<br />

1 // M is a ConstructorType that is a Monad<br />

2 concept Monad : ConstructorType {<br />

3 template<br />

4 requires<br />

5 ConstructorType,<br />

6 std::SameType<br />

8 Fun::Codoma<strong>in</strong> mb<strong>in</strong>d(M::Apply, Fun);<br />

9<br />

10 template<br />

11 M::Apply mreturn(X);<br />

12 }<br />

3.2. <strong>C++</strong> Implementation of <strong>Monadic</strong> <strong>Dynamical</strong> <strong>Systems</strong><br />

In the previous section, we describe how to represent fundamental functional types.<br />

These basic build<strong>in</strong>g blocks are necessary for any library <strong>in</strong> the style we propose. In this<br />

section, we proceed to the notions specific to our doma<strong>in</strong> of vulnerability modell<strong>in</strong>g.<br />

3.2.1. The Concept Framework<br />

Us<strong>in</strong>g the concepts from the functional <strong>C++</strong> framework from the previous section,<br />

we can describe the <strong>in</strong>gredients of monadic systems. Coalgebras, which are functions<br />

of type x -> f x where f is a functor, play an important role <strong>in</strong> our framework. A<br />

general concept for a coalgebra ref<strong>in</strong>es the Function concept <strong>and</strong> adds the follow<strong>in</strong>g<br />

requirements:<br />

• the codoma<strong>in</strong> type has to be an application of a functor type (f x),<br />

• <strong>and</strong> the type the functor is applied to (x) has to be the doma<strong>in</strong> type.<br />

The Coalgebra concept expresses these requirements us<strong>in</strong>g the concepts Functor <strong>and</strong><br />

std::SameType:<br />

1 // Fun ~ x -> f x<br />

2 concept Coalgebra : Function {<br />

3 requires<br />

22


4 Functor,<br />

5 std::SameType;<br />

6 }<br />

Similarly, us<strong>in</strong>g the Monad concept, we def<strong>in</strong>e a concept for monadic coalgebras,<br />

which are functions x -> m x for a monad m. A monadic coalgebra ref<strong>in</strong>es the idea of<br />

a coalgebra <strong>with</strong> an addition of the requirement that the type constructor applied <strong>in</strong> the<br />

codoma<strong>in</strong> has to be a monad, not only a functor:<br />

1 // Fun ~ x -> m x<br />

2 concept <strong>Monadic</strong>Coalgebra : Coalgebra {<br />

3 requires Monad;<br />

4 };<br />

As seen <strong>in</strong> Sect. 2, functions of type f :: i -> x -> m x where m is a monad are<br />

of special <strong>in</strong>terest for monadic systems <strong>with</strong> an external control (realised as an <strong>in</strong>put<br />

to the system). We call such functions monadic coalgebras <strong>with</strong> <strong>in</strong>put, while functions<br />

where only a functor is required are called coalgebras <strong>with</strong> <strong>in</strong>put. The latter ref<strong>in</strong>es the<br />

concept Function2 (b<strong>in</strong>ary function) by add<strong>in</strong>g two requirements:<br />

• the codoma<strong>in</strong> type has to be a application of a functor type constructor,<br />

• <strong>and</strong> the argument <strong>in</strong> the application has to be the second doma<strong>in</strong> type.<br />

The concept <strong>Monadic</strong>CoalgebraWithInput ref<strong>in</strong>es the concept CoalgebraWithInput<br />

by stat<strong>in</strong>g that the codoma<strong>in</strong> type has to be a monad type:<br />

1 // Fun ~ (i,x) -> f x<br />

2 concept CoalgebraWithInput : Function2 {<br />

3 requires<br />

4 Functor,<br />

5 std::SameType;<br />

6 };<br />

7<br />

8 // Fun ~ (i,x) -> m x<br />

9 concept <strong>Monadic</strong>CoalgebraWithInput : CoalgebraWithInput {<br />

10 requires<br />

11 Monad;<br />

12 };<br />

Us<strong>in</strong>g that hierarchy of concepts, we specify the ma<strong>in</strong> concept of our library, the<br />

one for monadic systems:<br />

1 // Sys ~ ((t,x) -> m x)<br />

2 concept <strong>Monadic</strong>System : <strong>Monadic</strong>CoalgebraWithInput {<br />

3 typename MonoidOperation;<br />

4 requires<br />

5 Monoid,<br />

6 std::SameType;<br />

7<br />

8 // axioms (<strong>in</strong> pseudocode):<br />

9 // Sys(0) = return<br />

10 // Sys(t1 + t2) = (Sys t1


The <strong>Monadic</strong>System concept ref<strong>in</strong>es the concept for a monadic coalgebra <strong>with</strong> <strong>in</strong>put <strong>and</strong><br />

therefore <strong>in</strong>herits all requirements from there. There is just one associated entity: an<br />

associated type that represents a monoid operation on the doma<strong>in</strong> type of the monadic<br />

system. The Monoid requirement on L<strong>in</strong>e 5 implies a Function requirement, <strong>and</strong> the<br />

type identity requirement on L<strong>in</strong>e 6 ensures that the monoid element type is the same as<br />

the doma<strong>in</strong> type of the monadic system. F<strong>in</strong>ally, monadic system must obey two laws,<br />

which are expressed <strong>in</strong> comments. The first axiom states that the neutral element of the<br />

doma<strong>in</strong> monoid has to be mapped to monadic return, <strong>and</strong> the second axiom states that<br />

the b<strong>in</strong>ary operation of the monoid should be mapped to Kleisli composition.<br />

3.2.2. The Concept Framework as a Type System<br />

<strong>Concepts</strong>, such as the ones presented <strong>in</strong> this section, build the type system of our<br />

library. The doma<strong>in</strong> of vulnerability is now freed from particularity of types, <strong>and</strong> even<br />

such basic notions as functions are under the control of a user who may plug <strong>in</strong> implementations<br />

<strong>in</strong>to the <strong>in</strong>terface. Next, we give examples of generic constructors <strong>and</strong><br />

algorithms implemented <strong>in</strong> our library.<br />

In Sect. 2.3, we have <strong>in</strong>troduced a constructor for monadic systems <strong>with</strong> <strong>in</strong>put,<br />

called <strong>in</strong>put_system. Our <strong>C++</strong> library provides a similar constructor:<br />

1 // Trans ~ (i,x) -> m x; Cont ~ [i]<br />

2 template<br />

3 requires<br />

4 std::SameType<br />

5 class <strong>Monadic</strong>_System_With_Input {<br />

6 public:<br />

7 typedef Cont Doma<strong>in</strong>1;<br />

8 typedef Trans::Doma<strong>in</strong>2 Doma<strong>in</strong>2;<br />

9 typedef Trans::Codoma<strong>in</strong> Codoma<strong>in</strong>;<br />

10 typedef Concatenation Op1;<br />

11<br />

12 <strong>Monadic</strong>_System_With_Input(Trans const& trans) : my_trans(trans) {}<br />

13<br />

14 Codoma<strong>in</strong> operator()(Doma<strong>in</strong>1 const& l, Doma<strong>in</strong>2 const& x) const {<br />

15 Codoma<strong>in</strong> ret = mreturn (x);<br />

16 for (unsigned <strong>in</strong>t i=0; i


ators (operator()) must be provided as a class members though, s<strong>in</strong>ce they accesses<br />

private class variables.<br />

The monadic systems library conta<strong>in</strong>s generic functions which implement the algorithms<br />

developed <strong>in</strong> the formalisation. As an example, we discuss the macro_trj<br />

function from Sect. 2.3:<br />

1 macro_trj :: (Monad m) => (i -> (x -> m x)) -> [i] -> x -> [m x]<br />

2 macro_trj sys ts x = scanr (\i mx -> mx >>= sys i) (return x) ts<br />

The macro_trj is translated to the follow<strong>in</strong>g <strong>C++</strong> implementation:<br />

1 // Mon_Sys ~ (i,x) -> m x; Inp_Iter ~ [i]; Cont ~ [m x]<br />

2 template<br />

4 requires<br />

5 std::SameType,<br />

6 std::SameType<br />

7 Cont<br />

8 macro_trajectory(Mon_Sys const& sys,<br />

9 Inp_Iter controls_bg, Inp_Iter controls_end,<br />

10 Mon_Sys::Doma<strong>in</strong>2 x) {<br />

11 Cont macro_trj;<br />

12 std::<strong>in</strong>sert_iterator macro_trj_iter(macro_trj, macro_trj.beg<strong>in</strong>());<br />

13<br />

14 // Mon_Sys::Codoma<strong>in</strong> ~ (m x).<br />

15 *macro_trj_iter = mreturn (x);<br />

16<br />

17 Mon_Sys::Codoma<strong>in</strong>::Codoma<strong>in</strong> mx = *macro_trj.beg<strong>in</strong>();<br />

18 while(controls_bg != controls_end) {<br />

19 // Mon_Sys::Codoma<strong>in</strong> ~ (m x) is the monad type.<br />

20 // mb<strong>in</strong>d is called for that monad m.<br />

21 mx = mb<strong>in</strong>d(mx, curry(sys)(*controls_bg)); ++controls_bg;<br />

22 ++macro_trj_iter; *macro_trj_iter = mx;<br />

23 }<br />

24<br />

25 return macro_trj;<br />

26 }<br />

The two l<strong>in</strong>es <strong>in</strong> <strong>Haskell</strong> correspond to a much longer implementation <strong>in</strong> <strong>C++</strong>. Most<br />

of the verbosity is due to concept-based type signature. It should be noted that we use<br />

the <strong>C++</strong> iterator mechanism to implement a function which is even more generic than<br />

the equivalent <strong>Haskell</strong> version: <strong>in</strong> contrast to the <strong>Haskell</strong> function, where we h<strong>and</strong>le all<br />

sequences as <strong>Haskell</strong> lists, we do not have a fixed sequence type for the <strong>in</strong>put (nor for<br />

the output) <strong>in</strong> the <strong>C++</strong> version. On the other h<strong>and</strong>, we have not reimplemented <strong>Haskell</strong>’s<br />

scanr, which makes our implementation more verbose.<br />

In addition to the constructors <strong>and</strong> generic algorithms we shown here our library<br />

provides also comb<strong>in</strong>ators, <strong>in</strong> particular <strong>Monadic</strong>_<strong>Systems</strong>_Parallel <strong>and</strong><br />

Sys_Ser_Function. As a f<strong>in</strong>al example how our libraries can be used we<br />

present a vulnerability computation algorithm encoded <strong>with</strong> the concepts from our libraries<br />

<strong>in</strong> the next section.<br />

25


3.3. Application of the <strong>Monadic</strong> <strong>Systems</strong> Library <strong>in</strong> Vulnerability Assessment<br />

The framework of concepts, operation <strong>and</strong> comb<strong>in</strong>ators presented so far can be<br />

used to implement vulnerability computation as <strong>in</strong>troduced <strong>in</strong> Sect. 2.3. The signature<br />

of such computations, as for <strong>in</strong>stance<br />

1 vulnerability’ :: (Functor m, Monad m) =><br />

2 (i -> x -> m x) -> ([x] -> h) -><br />

3 (m h -> v) -> [i] -> x -> v<br />

4 vulnerability’ sys harm measure ts = measure . fmap harm . micro_trj sys ts<br />

has to be encoded <strong>with</strong> requirements. For functions types we use the Function concept,<br />

<strong>and</strong> type identities are expressed <strong>with</strong> std::SameType requirements:<br />

1 template<br />

3 requires<br />

4 ConstructorType, Monad,<br />

5 std::SameType,<br />

6 std::SameType,<br />

7 std::SameType<br />

8 Meas::Codoma<strong>in</strong><br />

9 vulnerability_sys(Sys sys, Harm harm, Meas measure, Crtl ts,<br />

10 Sys::Doma<strong>in</strong>2 x) {<br />

11 typedef<br />

12 Sys::Codoma<strong>in</strong>::Apply<br />

13 Micro_Trj_Type;<br />

14<br />

15 Micro_Trj_Type micro_trj;<br />

16<br />

17 micro_trajectories(sys, x, ts.beg<strong>in</strong>(), ts.end(), micro_trj);<br />

18 return measure(fmap (harm, micro_trj));<br />

19 }<br />

It should be noted that encod<strong>in</strong>g the function signature <strong>with</strong> concepts is more complex<br />

than the functional signature. Otherwise the implementation is not much different from<br />

the functional implementation because technical details such as the iterator mechanism<br />

are hidden <strong>in</strong> the computation of micro-trajectories.<br />

4. Reimplementation <strong>in</strong> concept-based <strong>Haskell</strong><br />

The general concepts presented <strong>in</strong> section Sect. 3.2 are not only implementable <strong>in</strong><br />

<strong>C++</strong> but also <strong>in</strong> any language which provides an appropriate support of generic programm<strong>in</strong>g<br />

<strong>with</strong> concepts. To illustrate what implementations <strong>in</strong> other languages could<br />

look like, we sketch a monadic systems library <strong>in</strong> concept-based <strong>Haskell</strong>.<br />

Recent additions of support for associated types to the GHC <strong>Haskell</strong> compiler<br />

(Chakravarty et al., 2005; Schrijvers et al., 2008) allows us to express the <strong>C++</strong> concept<br />

framework also <strong>in</strong> <strong>Haskell</strong> (<strong>with</strong> extensions). We have ported our <strong>C++</strong> implementation<br />

“back to <strong>Haskell</strong>” <strong>and</strong> <strong>in</strong>terest<strong>in</strong>g future work would be to make this port more complete<br />

<strong>and</strong> to compare the expressivity <strong>and</strong> efficiency of the generated code. Below is a<br />

sample of the <strong>Haskell</strong> version us<strong>in</strong>g associated types. The full <strong>Haskell</strong> development is<br />

26


available as an experimental Cabal package <strong>with</strong> 43 modules <strong>and</strong> 1700 LOC (<strong>in</strong>clud<strong>in</strong>g<br />

comments).<br />

We start <strong>with</strong> the Function concept as a <strong>Haskell</strong> type class <strong>with</strong> a st<strong>and</strong>ard modell<strong>in</strong>g<br />

(<strong>in</strong>stance) for the built-<strong>in</strong> function type. As <strong>Haskell</strong> does not allow overload<strong>in</strong>g<br />

the application operator, we use an <strong>in</strong>fix operator (!):<br />

1 class Function fun where<br />

2 type Doma<strong>in</strong> fun<br />

3 type Codoma<strong>in</strong> fun<br />

4 (!) :: fun -> (Doma<strong>in</strong> fun -> Codoma<strong>in</strong> fun)<br />

5<br />

6 <strong>in</strong>stance Function (a -> b) where<br />

7 type Doma<strong>in</strong> (a -> b) = a<br />

8 type Codoma<strong>in</strong> (a -> b) = b<br />

9 f ! x = f x<br />

Next, we move to the ConstructorType concept where we use GHC’s support for<br />

<strong>in</strong>fix type constructors to make later def<strong>in</strong>itions a bit more readable.<br />

1 class ConstructorType con where<br />

2 data (:@) con :: * -> *<br />

3 type Apply = (:@)<br />

The full code also <strong>in</strong>cludes three more associated entities.<br />

For the next example (monads) we need equality constra<strong>in</strong>ts: a ~ b is the <strong>Haskell</strong><br />

equivalent of SameType <strong>in</strong> <strong>C++</strong> <strong>with</strong> <strong>Concepts</strong>. We name the Function type variable<br />

a2mb (short for “a to m b”):<br />

1 class ConstructorType m => Monad m where<br />

2 mb<strong>in</strong>d :: (Function a2mb, Codoma<strong>in</strong> a2mb ~ (m :@ b)) =><br />

3 m :@ Doma<strong>in</strong> a2mb -> a2mb -> Codoma<strong>in</strong> a2mb<br />

4 mreturn :: a -> m:@a<br />

Note that the equality constra<strong>in</strong>t means that the same type can be expressed <strong>in</strong> different<br />

ways: <strong>in</strong> this example Codoma<strong>in</strong> a2mb can freely be replaced by m:@b. In general,<br />

not only can equals be substituted for equals, but we can also effectively add type<br />

subexpression aliases as <strong>in</strong> the follow<strong>in</strong>g example:<br />

1 mb<strong>in</strong>d’ :: ( Monad m, Function a2mb<br />

2 , a ~ Doma<strong>in</strong> a2mb<br />

3 , mb ~ Codoma<strong>in</strong> a2mb<br />

4 , ma ~ (m :@ a)<br />

5 , mb ~ (m :@ b)<br />

6 ) =><br />

7 ma -> a2mb -> mb<br />

8 mb<strong>in</strong>d’ = mb<strong>in</strong>d<br />

In fact, equality constra<strong>in</strong>ts are sufficiently powerful to take us to the limit of what<br />

GHC can h<strong>and</strong>le. When encod<strong>in</strong>g the Coalgebra concept we had to comment out the<br />

equality constra<strong>in</strong>t to avoid a compiler error 5 :<br />

5 Both GHC 6.12 <strong>and</strong> GHC 7.0.1 say “The current implementation of type families does not support<br />

equality constra<strong>in</strong>ts <strong>in</strong> superclass contexts. They are planned for a future release.”<br />

27


1 class ( Function a2fb<br />

2 , Functor (FunctorTag a2fb)<br />

3 -- , Codoma<strong>in</strong> a2fb ~ (FunctorTag a2fb :@ Doma<strong>in</strong> a2fb)<br />

4 ) => Coalgebra a2fb where<br />

5 type FunctorTag a2fb :: *<br />

Our f<strong>in</strong>al example (<strong>in</strong> Fig. 4) is the generic vulnerability calculation where we use<br />

equality constra<strong>in</strong>ts to document the type structure <strong>in</strong> detail (mak<strong>in</strong>g it just as verbose<br />

as the <strong>C++</strong> version).<br />

1 vulnerability_sys ::<br />

2 ( <strong>Monadic</strong>System sys , Function harm<br />

3 , i ~ Doma<strong>in</strong> sys , [x] ~ Doma<strong>in</strong> harm<br />

4 , x2mx ~ Codoma<strong>in</strong> sys , h ~ Codoma<strong>in</strong> harm<br />

5 , x ~ Doma<strong>in</strong> x2mx , Function meas<br />

6 , mx ~ Codoma<strong>in</strong> x2mx , mh ~ Doma<strong>in</strong> meas<br />

7 , m ~ FunctorTag x2mx , v ~ Codoma<strong>in</strong> meas<br />

8 , mx ~ (m:@x) , mh ~ (m :@ h)<br />

9 ) => sys -> harm -> meas -> [i] -> x -> v<br />

10 vulnerability_sys sys harm meas is x = v<br />

11 where mxs = micro_trj sys is x<br />

12 mh = fmap harm mxs<br />

13 v = meas ! mh<br />

Figure 4: The generic vulnerability calculation <strong>in</strong> <strong>Haskell</strong> <strong>with</strong> concepts.<br />

While port<strong>in</strong>g the concepts code from <strong>C++</strong> to <strong>Haskell</strong> we had to make a number<br />

of technical choices (associated types versus associated datatypes, type <strong>in</strong>ference versus<br />

explicit type application, etc.) where the languages differ. A detailed description<br />

would take as too far off topic but there is certa<strong>in</strong>ly some scope for future work <strong>in</strong> this<br />

direction.<br />

One issue that deserves attention, however, is our use of associated datatypes. An<br />

attentive reader may have noticed that the <strong>Haskell</strong> ConstructorType concept does not<br />

impose the same constra<strong>in</strong>ts on the tag as the <strong>C++</strong> version on page 20. <strong>Haskell</strong>’s associated<br />

datatype <strong>in</strong>troduces a wrapper, which is one of the solutions we discussed <strong>in</strong><br />

the discussion of the <strong>C++</strong> ConstructorType concept. Thanks to that wrapper, one can<br />

always map a constructor type application back to the appropriate <strong>in</strong>stance, avoid<strong>in</strong>g<br />

<strong>in</strong>jectivity errors 6 . Yet, the wrapper does not come <strong>with</strong>out a price. The programmer<br />

must now wrap <strong>and</strong> unwrap values where necessary, which is impossible to do<br />

generically. To avoid that issue, the actual ConstructorType class <strong>in</strong>troduces extra<br />

mach<strong>in</strong>ery:<br />

1 class ConstructorType con where<br />

2 data (:@) con :: * -> *<br />

3 type Applied con :: * -> *<br />

4 unapply :: con :@ a > Applied con a<br />

6 http://www.haskell.org/haskellwiki/GHC/Type_families<br />

28


Constructor type application produces a wrapped value, but we also provide generic<br />

apply <strong>and</strong> unapply functions that can move back <strong>and</strong> forth between wrapped <strong>and</strong> unwrapped<br />

values. The associated type Applied corresponds to the Apply template <strong>in</strong> the<br />

<strong>C++</strong> version of this concept.<br />

5. Related Work<br />

In the realm of generic programm<strong>in</strong>g, the use of concepts (or type classes) to abstract<br />

from representations of data or to capture certa<strong>in</strong> properties of types is a common<br />

practise. For example, the <strong>C++</strong> St<strong>and</strong>ard Template Library (STL) (Austern, 1998;<br />

Stepanov <strong>and</strong> Lee, 1994) <strong>in</strong>troduces a hierarchy of concepts for data conta<strong>in</strong>ers <strong>and</strong> for<br />

iterators used to generically traverse ranges of data, <strong>and</strong> the Boost Graph Library (Siek<br />

et al., 2002) <strong>in</strong>troduces concepts represent<strong>in</strong>g different k<strong>in</strong>ds of graphs. In the traditional<br />

approach, functional notions such as monadic system, for example, are either<br />

not represented explicitly at all (<strong>in</strong> <strong>C++</strong> libraries) or are represented by a particular type<br />

(as <strong>in</strong> <strong>Haskell</strong> libraries). In our generic library for vulnerability assessment, we take<br />

abstraction further <strong>in</strong> conceptually represent<strong>in</strong>g functions as well as data. In <strong>Haskell</strong>,<br />

almost all libraries are generic <strong>in</strong> the sense that they use <strong>and</strong> def<strong>in</strong>e type classes. Some<br />

more advanced examples are (Chakravarty et al., 2005; Claessen <strong>and</strong> Hughes, 2000;<br />

Jansson <strong>and</strong> Jeur<strong>in</strong>g, 2002; Oliveira et al., 2006)<br />

Recently, new concept applications have been enabled (<strong>and</strong> <strong>in</strong>spired) by the l<strong>in</strong>guistic<br />

support for concepts <strong>in</strong> <strong>C++</strong>0x (Gregor et al., 2006). For example, much of the st<strong>and</strong>ard<br />

library of <strong>C++</strong> (<strong>in</strong>clud<strong>in</strong>g the STL) has been conceptualised, that is, rewritten us<strong>in</strong>g<br />

the new concepts feature (for example, Gregor et al., 2008a,b). This body of code <strong>and</strong><br />

specifications provides a good example of how generic libraries will be written when<br />

concepts officially become a feature of <strong>C++</strong>. Our work goes further than STL concepts.<br />

The first difference is that we systematically tackle type constructor concepts; the only<br />

similar concept <strong>in</strong> STL is the Allocator concept (Halpern, 2008), which requires compiler<br />

support to verify constra<strong>in</strong>ts that are expressed us<strong>in</strong>g SameTypeConstructor concept<br />

<strong>in</strong> our framework. The other difference is <strong>in</strong> h<strong>and</strong>l<strong>in</strong>g of computations: <strong>in</strong> our<br />

framework a computation is represented by a self-conta<strong>in</strong>ed Function concept that<br />

knows its doma<strong>in</strong> <strong>and</strong> codoma<strong>in</strong> types, while <strong>in</strong> the conceptualised STL a computation<br />

is represented by a Callable family of concepts that require doma<strong>in</strong> types as concept<br />

arguments.<br />

One aspect of our work is implementation of functional programm<strong>in</strong>g constructs<br />

<strong>in</strong> <strong>C++</strong>. Related work has been done before, <strong>in</strong>clud<strong>in</strong>g the Boost Lambda library (Järvi<br />

et al., 2003), the F<strong>C++</strong> library (McNamara <strong>and</strong> Smaragdakis, 2004b), <strong>and</strong> the Boost<br />

Fusion library (de Guzman <strong>and</strong> Marsden, 2009). All the previous approaches rely<br />

heavily on template meta-programm<strong>in</strong>g, while we encode the types of functions on the<br />

level of concepts.<br />

A related project <strong>with</strong> similar goals as our work is the DUNE (Distributed <strong>and</strong> Unified<br />

Numerics Environment) project (Bastian et al., 2008). DUNE identifies an abstract<br />

specification of a parallel <strong>and</strong> adaptive hierarchical grid for scientific comput<strong>in</strong>g, but<br />

<strong>with</strong>out provid<strong>in</strong>g a functional prototype implementation. <strong>C++</strong> template programm<strong>in</strong>g<br />

is employed to achieve an efficient implementation of this specification which supports<br />

29


<strong>with</strong> reuse of exist<strong>in</strong>g f<strong>in</strong>ite element packages. <strong>Concepts</strong> are used implicitly to specific<br />

the type parameters of the templates.<br />

Botta <strong>and</strong> Ionescu develop a generic <strong>C++</strong> library for parallel comput<strong>in</strong>g us<strong>in</strong>g a<br />

<strong>Haskell</strong> prototype as a model <strong>and</strong> a specification. While concepts are not used explicitly<br />

there is a common idea between their work <strong>and</strong> the approach presented <strong>in</strong> this paper.<br />

This paper can also be seen as cont<strong>in</strong>u<strong>in</strong>g the l<strong>in</strong>e of work relat<strong>in</strong>g concepts <strong>in</strong><br />

<strong>Haskell</strong> <strong>and</strong> <strong>C++</strong>: (Bernardy et al., 2010, 2008; Garcia et al., 2007b; Zalewski et al.,<br />

2007).<br />

6. Discussion <strong>and</strong> Future Work<br />

We presented an approach to express doma<strong>in</strong> notions <strong>in</strong> a functional model <strong>and</strong> afterwards<br />

transform them <strong>in</strong>to generic concepts. This enables us to implement doma<strong>in</strong>specific<br />

high-performance libraries from functional models. We have illustrated our<br />

approach by implement<strong>in</strong>g a library for monadic dynamical systems, a useful model of<br />

systems <strong>in</strong>volved <strong>in</strong> vulnerability modell<strong>in</strong>g <strong>in</strong> the context of climate change. A functional<br />

description of monadic dynamical systems <strong>and</strong> algorithms is provided <strong>in</strong> the first<br />

part of this paper, <strong>in</strong> the second part we implement a concept-based generic <strong>C++</strong> library<br />

from this executable functional specification.<br />

Our approach is flexible, we don’t have to stick to <strong>C++</strong> <strong>and</strong> <strong>Haskell</strong>. The functional<br />

modell<strong>in</strong>g can be done <strong>in</strong> other functional languages or even <strong>in</strong> a more mathematical<br />

notion like the typed λ-calculus. As we have shown, the implementation of the f<strong>in</strong>al<br />

library can also be done <strong>in</strong> concept-enabled <strong>Haskell</strong>. But what language features are<br />

necessary to apply our approach? First of all, the language has to provide a mechanism<br />

to allow generic programm<strong>in</strong>g <strong>with</strong> concepts. This <strong>in</strong>clude a possibility to implement<br />

concepts, a notion for ref<strong>in</strong>ement, a mechanism for modell<strong>in</strong>g <strong>and</strong> support for<br />

constra<strong>in</strong><strong>in</strong>g generic algorithms. Besides, Bernardy et al. studies advanced language<br />

features for generic programm<strong>in</strong>g <strong>with</strong> concepts. Fig. 5 summarises language features<br />

which are necessary for implement<strong>in</strong>g a generic library <strong>with</strong> our approach. Only a few<br />

Feature<br />

Necessary for<br />

Multi-type concepts <strong>Concepts</strong> modell<strong>in</strong>g type identities as for <strong>in</strong>stance <strong>in</strong> std::SameType<br />

Multiple constra<strong>in</strong>ts Encod<strong>in</strong>g complex function signatures as <strong>in</strong> vulnerability_sys<br />

Parametric modell<strong>in</strong>g Declare models for our ConstructorType concept<br />

Associated type access Encod<strong>in</strong>g function signatures of member functions, for <strong>in</strong>stance mb<strong>in</strong>d <strong>in</strong><br />

Monad.<br />

Constra<strong>in</strong>ts on associated<br />

types<br />

Encod<strong>in</strong>g type relations between associated types <strong>and</strong> type parameters,<br />

for <strong>in</strong>stance <strong>in</strong> the ConstructorType concept.<br />

Type equality constra<strong>in</strong>ts Encod<strong>in</strong>g type equalities <strong>in</strong> complex function signatures as <strong>in</strong><br />

vulnerability_sys<br />

Figure 5: Language features (us<strong>in</strong>g term<strong>in</strong>ology from Bernardy et al.)<br />

concept-based generic library <strong>with</strong> our approach.<br />

that are necessary to develop a<br />

features are really essential, while some other features (like constra<strong>in</strong>t <strong>and</strong> type aliases)<br />

are useful for more convenient cod<strong>in</strong>g but not necessary for implement<strong>in</strong>g a library.<br />

The transformation of types from a functional style <strong>in</strong>to Function-concept style<br />

follows a well def<strong>in</strong>ed scheme <strong>and</strong> can therefore be automated. In a nutshell, a function<br />

30


type f :: X -> Y is flattened by replac<strong>in</strong>g higher order function types <strong>in</strong> the doma<strong>in</strong><br />

type <strong>and</strong> the codoma<strong>in</strong> type. Higher order function types <strong>in</strong> the doma<strong>in</strong> are replaced by<br />

type parameters <strong>and</strong> concepts are used to encode their signature. In the codoma<strong>in</strong> type,<br />

a new type is <strong>in</strong>troduced for every higher order function type <strong>and</strong> the orig<strong>in</strong>al higher<br />

order function type is replaced by it. We currently work<strong>in</strong>g on a compiler that does this<br />

transformation. 7<br />

Acknowledgements<br />

The authors would like to thank Jean-Philippe Bernardy, Nicola Botta, Andreas<br />

Priesnitz, Gustav Munkby <strong>and</strong> Sibylle Schupp for their <strong>in</strong>sightful comments <strong>and</strong> <strong>in</strong>terest<strong>in</strong>g<br />

discussions. The research <strong>in</strong> this paper was partly supported by a grant from the<br />

European Union research project ADAM under Contract number GOCE-018476 <strong>and</strong><br />

by a grant 0702717 from National Science Foundation.<br />

References<br />

Adger, W. N., 2006. Vulnerability. Global Environmental Change 16, 268–281.<br />

Austern, M. H., 1998. Generic Programm<strong>in</strong>g <strong>and</strong> the STL: Us<strong>in</strong>g <strong>and</strong> Extend<strong>in</strong>g the<br />

<strong>C++</strong> St<strong>and</strong>ard Template Library. Addison-Wesley.<br />

Bastian, P., Blatt, M., Dedner, A., Engwer, C., Klöfkorn, R., Kornhuber, R., Ohlberger,<br />

M., S<strong>and</strong>er, O., July 2008. A generic grid <strong>in</strong>terface for parallel <strong>and</strong> adaptive scientific<br />

comput<strong>in</strong>g. part ii: implementation <strong>and</strong> tests <strong>in</strong> dune. Comput<strong>in</strong>g 82, 121–138.<br />

Bernardy, J.-P., Jansson, P., Zalewski, M., Schupp, S., 2010. Generic programm<strong>in</strong>g<br />

<strong>with</strong> <strong>C++</strong> concepts <strong>and</strong> <strong>Haskell</strong> type classes—a comparison. J. Funct. Program.In<br />

press.<br />

Bernardy, J.-P., Jansson, P., Zalewski, M., Schupp, S., Priesnitz, A., 2008. A comparison<br />

of <strong>C++</strong> concepts <strong>and</strong> <strong>Haskell</strong> type classes. In: Proc. ACM SIGPLAN Workshop<br />

on Generic Programm<strong>in</strong>g. ACM, pp. 37–48.<br />

Botta, N., Ionescu, C., 2007. Relation-Based Computations <strong>in</strong> a <strong>Monadic</strong> BSP Model.<br />

Parallel Comput<strong>in</strong>g 33 (12), 795–821.<br />

Brooks, N., 2003. Vulnerability, risk <strong>and</strong> adaptation: A conceptual framework. Tyndall<br />

Center Work<strong>in</strong>g Paper 38.<br />

Chakravarty, M. M. T., Keller, G., Jones, S. P., 2005. Associated type synonyms. In:<br />

ICFP ’05: Proc. tenth ACM SIGPLAN <strong>in</strong>ternational conference on Functional programm<strong>in</strong>g.<br />

ACM, pp. 241–253.<br />

7 See the project page http://www.pik-potsdam.de/members/l<strong>in</strong>cke/haskc-generic-c-programm<strong>in</strong>g-fromhaskell-specification<br />

31


Claessen, K., Hughes, J., 2000. QuickCheck: A lightweight tool for r<strong>and</strong>om test<strong>in</strong>g of<br />

<strong>Haskell</strong> programs. In: ICFP’00: International Conference on Functional Programm<strong>in</strong>g.<br />

ACM, pp. 268–279.<br />

Garcia, R., Jarvi, J., Lumsda<strong>in</strong>e, A., Siek, J., Willcock, J., Mar. 2007a. An extended<br />

comparative study of language support for generic programm<strong>in</strong>g. J. Funct. Program.<br />

17 (2), 145–205.<br />

Garcia, R., Jarvi, J., Lumsda<strong>in</strong>e, A., Siek, J., Willcock, J., 2007b. An extended comparative<br />

study of language support for generic programm<strong>in</strong>g. J. Funct. Program. 17 (2),<br />

145–205.<br />

Gregor, D., Järvi, J., Siek, J., Stroustrup, B., Dos Reis, G., Lumsda<strong>in</strong>e, A., 2006.<br />

<strong>Concepts</strong>: L<strong>in</strong>guistic support for generic programm<strong>in</strong>g <strong>in</strong> <strong>C++</strong>. In: Proc. ACM SIG-<br />

PLAN Conf. on Object-Oriented Programm<strong>in</strong>g, <strong>Systems</strong>, Languages, <strong>and</strong> Applications<br />

(OOPSLA). ACM Press, pp. 291–310.<br />

Gregor, D., Marcus, M., Witt, T., Lumsda<strong>in</strong>e, A., 2008a. Foundational concepts<br />

for the <strong>C++</strong>0x st<strong>and</strong>ard library (rev. 4). Tech. Rep. N2737=08-0247, ISO/IEC<br />

JTC1/SC22/WG21 - <strong>C++</strong>.<br />

Gregor, D., Siek, J., Lumsda<strong>in</strong>e, A., 2008b. Iterator concepts for the <strong>C++</strong>0x st<strong>and</strong>ard<br />

library (rev. 4). Tech. Rep. N2739=08-0249, ISO/IEC JTC1/SC22/WG21 - <strong>C++</strong>.<br />

Gregor, D., Stroustrup, B., Widman, J., Siek, J., 2008c. Proposed word<strong>in</strong>g for concepts<br />

(rev. 8). Tech. Rep. N2741=08-0251, ISO/IEC JTC1/SC22/WG21 - <strong>C++</strong>.<br />

de Guzman, J., Marsden, D., 2009. Fusion library homepage. http://www.boost.org/<br />

libs/fusion.<br />

Halpern, P., 2008. Defects <strong>and</strong> proposed resolutions for allocator concepts. Tech. Rep.<br />

N2810=08-0320, ISO/IEC JTC1/SC22/WG21 - <strong>C++</strong>.<br />

Ionescu, C., 2009. Vulnerability modell<strong>in</strong>g <strong>and</strong> monadic dynamical systems. Ph.D.<br />

thesis, Freie Universität Berl<strong>in</strong>, available from http://www.diss.fu-berl<strong>in</strong>.de/<br />

diss/receive/FUDISS_thesis_000000008403.<br />

Janssen, M. A., Ostrom, E., 2006. Resilience, vulnerability <strong>and</strong> adaptation: A crosscutt<strong>in</strong>g<br />

theme of the <strong>in</strong>ternational human dimensions programme on global environmental<br />

change. Global Environmental Change 16 (3), 237–239, editorial.<br />

Jansson, P., Jeur<strong>in</strong>g, J., 2002. Polytypic data conversion programs. Science of Computer<br />

Programm<strong>in</strong>g 43 (1), 35–75.<br />

Järvi, J., Powell, G., Lumsda<strong>in</strong>e, A., 2003. The lambda library: Unnamed functions <strong>in</strong><br />

<strong>C++</strong>. Software: Practice <strong>and</strong> Experience 33 (3), 259–291.<br />

Jones, M. P., 1993. A system of constructor classes: overload<strong>in</strong>g <strong>and</strong> implicit higherorder<br />

polymorphism. In: Proc. Conference on Functional Programm<strong>in</strong>g Languages<br />

<strong>and</strong> Computer Architecture (FPCA). ACM, New York, NY, USA, pp. 52–61.<br />

32


K<strong>in</strong>g, D., Wadler, P., 1992. Comb<strong>in</strong><strong>in</strong>g monads. In: Launchbury, J., Sansom, P. M.<br />

(Eds.), Glasgow Workshop on Functional Programm<strong>in</strong>g. Spr<strong>in</strong>ger-Verlag, pp. 134–<br />

143.<br />

L<strong>in</strong>cke, D., 2010. Functional <strong>C++</strong> <strong>with</strong> concepts. Last checked: 2010-12-27.<br />

L<strong>in</strong>cke, D., Jansson, P., Zalewski, M., Ionescu, C., 2009. Generic libraries <strong>in</strong> <strong>C++</strong> <strong>with</strong><br />

concepts from high-level doma<strong>in</strong> descriptions <strong>in</strong> <strong>Haskell</strong>: A DSL for computational<br />

vulnerability assessment. In: IFIP Work<strong>in</strong>g Conf. on Doma<strong>in</strong> Specific Languages.<br />

Vol. 5658/2009 of LNCS. pp. 236–261.<br />

L<strong>in</strong>cke, D., Schupp, S., 2009. The function concept <strong>in</strong> <strong>C++</strong>- an empirical study. In:<br />

WGP ’09: Proc. ACM SIGPLAN workshop on Generic programm<strong>in</strong>g. ACM, pp.<br />

25–36.<br />

McNamara, B., Smaragdakis, Y., 2004a. Functional programm<strong>in</strong>g <strong>with</strong> the fc++ library.<br />

Journal of Functional Programm<strong>in</strong>g 14 (4), 429–472.<br />

McNamara, B., Smaragdakis, Y., 2004b. Functional programm<strong>in</strong>g <strong>with</strong> the F<strong>C++</strong> library.<br />

J. of Functional Programm<strong>in</strong>g 14 (4), 429–472.<br />

Myers, N., 1995. A new <strong>and</strong> useful template technique: “Traits”. <strong>C++</strong> Report 7 (5), 35,<br />

32.<br />

Oliveira, B. C. d. S., H<strong>in</strong>ze, R., Löh, A., 2006. Extensible <strong>and</strong> modular generics for the<br />

masses. In: Nilsson, H. (Ed.), Trends <strong>in</strong> Functional Programm<strong>in</strong>g. pp. 199–216.<br />

Petoukhov, V., Ganopolski, A., Brovk<strong>in</strong>, V., Claussen, M., Eliseev, A., Kubatzki, C.,<br />

Rahmstorf, S., 2000. CLIMBER-2 : a climate system model of <strong>in</strong>termediate complexity.<br />

Part I : model description <strong>and</strong> performance for present climate. Climate dynamics<br />

16, 1–17.<br />

Peyton Jones, S. (Ed.), 2003. <strong>Haskell</strong> 98 Language <strong>and</strong> Libraries: The Revised Report.<br />

Cambridge University Press.<br />

Schrijvers, T., Peyton Jones, S., Chakravarty, M., Sulzmann, M., 2008. Type check<strong>in</strong>g<br />

<strong>with</strong> open type functions. In: ICFP ’08: Proc. 13th ACM SIGPLAN <strong>in</strong>ternational<br />

conference on Functional programm<strong>in</strong>g. ACM, pp. 51–62.<br />

Siek, J. G., Lee, L. Q., Lumsda<strong>in</strong>e, A., 2002. The Boost Graph Library: User Guide<br />

<strong>and</strong> Reference Manual. Addison-Wesley.<br />

Stepanov, A. A., Lee, M., 1994. The St<strong>and</strong>ard Template Library. Tech. Rep. HPL-94-<br />

34, Hewlett-Packard Laboratories, revised <strong>in</strong> October 1995 as tech. rep. HPL-95-11.<br />

Stroustrup, B., 1997. The <strong>C++</strong> Programm<strong>in</strong>g Language, 3rd Edition. Addison-Wesley.<br />

Wadler, P., Blott, S., 1989. How to make ad-hoc polymorphism less ad hoc. In: Proc.<br />

16th ACM SIGPLAN-SIGACT Symp. on Pr<strong>in</strong>ciples of Programm<strong>in</strong>g Languages<br />

(POPL). ACM Press, pp. 60–76.<br />

33


Wolf, S., L<strong>in</strong>cke, D., H<strong>in</strong>kel, J., Ionescu, C., Bisaro, S., 2008. A formal framework<br />

of vulnerability. F<strong>in</strong>al deliverable to the ADAM project. FAVAIA work<strong>in</strong>g paper 8,<br />

Potsdam Institute for Climate Impact Research, Potsdam, Germany.<br />

Zalewski, M., Priesnitz, A. P., Ionescu, C., Botta, N., Schupp, S., 2007. Multi-<br />

Language library development: From <strong>Haskell</strong> type classes to <strong>C++</strong> concepts. In:<br />

Striegnitz, J. (Ed.), Proc. 6th Int. Workshop on Multiparadigm Programm<strong>in</strong>g With<br />

Object-Oriented Languages (MPOOL).<br />

34

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!