• No se han encontrado resultados

5. PROPUESTA DE INTERVENCIÓN

5.9 Desarrollo de las sesiones

One of our main motivations in using Arrows was to capture the observation an agent makes using theArrowAgentclass (§6.1). This is a similar problem faced byLi and Zdancewic(2010) who want to restrict the information available to a computation in a security setting: both settings require thatallinformation sources for a particular Arrow are accounted for. They differ in that we also allow agents to make passive observations, such as the sensor readings made by our running example of the autonomous robot (Chapter2).

Russo, Claessen, and Hughes(2008) showed that Monads can be used to a similar end, essentially by requiring that all relevant information comes from a Monadic action which tags the returned value, and testing that data being consumed has an appropriate tag. Our approach has the advantage that information producers can be oblivious to the needs ofArrowAgent, and we do not incur the extra overhead of testing tags at runtime. As Arrows naturally handle sharing, we also avoid the problem of identifying external inputs that the agent consumes several times, which simplifies the computation of agents’ observations (§6.1). Moreover agents can make passive observations naturally by simply ignoring inputs provided by their environment.

We leave further investigation of this approach, and also the possibility of using observable sharing (§4.2.5), to future work.

7.1.5 Concluding remarks

Our approach leans heavily on the expressive types of modern Haskell systems, and it is difficult to imagine combinator programming without such a safety net. However the particular combi- nators that constitute Arrows have some limitations that suggest further research is worthwhile.

We note that the Arrow combinator graphs have a peculiar hybrid structure due to thearr

operation, which effectively embeds the entire function space of the host language into the object language represented by the Arrows. This operation serves two roles: firstly, to interface

the object language with Haskell’s datatype mechanisms (case analysis, construction, etc.), and secondly to construct a limited set of pure Arrows that pipe data around, as we saw in §5.1. The generality of this mechanism makes it impossible to completely analyse Arrow graphs as we cannot divine the behaviour of a pure Arrow without executing it. Thearrmethod is precisely the “polymorphic lift” thatCarette et al.(2009) so scrupulously avoid.

This failure of the graph to completely represent the structure of the computation prevents us from generically transforming our circuits represented as Arrows. For instance we would like to implement a generic constant-folding Arrow transformer but are stymied by the impossibility of knowing what a pure Arrow does to our values. We could of course write such a transformation for each interpretation separately, but we would hope to do it once-and-for-all in a similar manner to the optimisations ofHughes (2004), which act structurally on the Arrow graph without reference to the semantics of what is passed between the combinators.

Another motivation for abstracting the pure Arrows used for routing is that some systems are better modelled with environments represented as sums rather than products; for instance Carlsson1experimented with an Arrow interface for his asynchronous fudget stream processors. This approach also requires thefirstmethod to be suitably renovated, and still allows the machinery of the host language for datatypes to be used in the embedded language.

A more general approach is being pursued byMegacz(2010,2011) with his “Generalised Arrows”, which isolate the host and object languages by only requiring the latter to support a particular (abstract) set of pure routing Arrows. This means that the object language does not need to support the datatypes of the host language, which is precisely what we want for our synchronous circuit Arrows; these do not have a natural encoding of arbitrary sum types, for example (§5.2.2). It occupies another point in the space of “box and arrow” description techniques (§4.3.4), requiring a novel modal type system and a notation distinct from the one used here.

Following our discussion of circuit semantics in §4.3.5, one may wonder if Arrows are useful when reasoning about circuits formally, using a proof assistant. We observe that it is difficult to deeply embed the Arrow language in a simply-typed logic such as Isabelle/HOL (Nipkow et al. 2002) as we cannot give them sufficiently polymorphic types. (We could model them using a closed universe of types and so forth, but this might entail formalising a sufficiently expressive type system as well.Hughes(2004) had similar difficulty in Haskell prior to the advent

ofgeneralised algebraic data types(GADTs) (Schrijvers, Jones, Sulzmann, and Vytiniotis 2009).)

Note also that Arrows suffer from the same sort of over-specification as do Monads (§4.2.4), viz that they encode the order that gates are defined in, and hence are not fully abstract; we need to further assume that the bind operator (>>>) is suitably commutative.

More tellingly we followTullsen(2002) in observing that we almost certainly want to take an extensional view of our circuits, at least when verifying their functional properties, and showing that a transformation preserves correctness. In other words, we would like the freedom to ignore sharing provided by a direct semantics based on the domain theory mechanised byHuffman

(2012) (et al), which can model combinational cycles if we need them. Type theorists may prefer to show that their circuits yield productive coinductive definitions in Coq or Agda (§4.3.5).

This does not contradict our motivation for using Arrows within Haskell, as sharing there is a critical issue (§7.1.3). We acknowledge the temptation to abandon purity and adopt observable sharing (§4.2.5) if we are only going to reason informally about our circuit generators expressed in the host language.

Documento similar