Results 1  10
of
22
Functional Programming with Graphs
 2ND ACM SIGPLAN INT. CONF. ON FUNCTIONAL PROGRAMMING
, 1997
"... Graph algorithms expressed in functional languages often suffer from their inherited imperative, statebased style. In particular, this impedes formal program manipulation. We show how to model persistent graphs in functional languages by graph constructors. This provides a decompositional view of g ..."
Abstract

Cited by 35 (12 self)
 Add to MetaCart
Graph algorithms expressed in functional languages often suffer from their inherited imperative, statebased style. In particular, this impedes formal program manipulation. We show how to model persistent graphs in functional languages by graph constructors. This provides a decompositional view of graphs which is very close to that of data types and leads to a "more functional" formulation of graph algorithms. Graph constructors enable the definition of general fold operations for graphs. We present a promotion theorem for one of these folds that allows program fusion and the elimination of intermediate results. Fusion is not restricted to the elimination of treelike structures, and we prove another theorem that facilitates the elimination of intermediate graphs. We describe an MLimplementation of persistent graphs which efficiently supports the presented fold operators. For example, depthfirstsearch expressed by a fold over a functional graph has the same complexity as the corresp...
Sourcebased trace exploration
 IMPLEMENTATION AND APPLICATION OF FUNCTIONAL LANGUAGES, 16TH INTERNATIONAL WORKSHOP, IFL 2004, LNCS 3474
, 2005
"... Tracing a computation is a key method for program comprehension and debugging. Hat is a tracing system for Haskell 98 programs. During a computation a trace is recorded in a file; then the user studies the trace with a collection of viewing tools. Different views are complementary and can producti ..."
Abstract

Cited by 11 (2 self)
 Add to MetaCart
Tracing a computation is a key method for program comprehension and debugging. Hat is a tracing system for Haskell 98 programs. During a computation a trace is recorded in a file; then the user studies the trace with a collection of viewing tools. Different views are complementary and can productively be used together. Experience shows that users of the viewing tools find it hard to keep orientation and navigate to a point of interest in the trace. Hence this paper describes a new viewing tool where navigation through the trace is based on the program source. The tool combines ideas from algorithmic debugging, traditional stepping debuggers and dynamic program slicing.
A Sharing Analysis for SAFE
"... We present a sharing analysis for the functional language Safe. This is a firstorder eager language with facilities for programmercontrolled destruction and copying of data structures. It provides also regions, i.e. disjoint parts of the heap where the programmer may allocate data structures. The ..."
Abstract

Cited by 11 (6 self)
 Add to MetaCart
(Show Context)
We present a sharing analysis for the functional language Safe. This is a firstorder eager language with facilities for programmercontrolled destruction and copying of data structures. It provides also regions, i.e. disjoint parts of the heap where the programmer may allocate data structures. The language and its associated type system guaranteeing that destruction facilities and region management are done in a safe way were presented in a previous paper [6]. That type system uses two functions, called sharerec and shareall, which are supposed to give upper approximations to the set of variables respectively sharing a recursive substructure, or any substructure, of a given variable. In this paper we present the formal definition of such functions. In order to have a modular and efficient analysis, we provide signatures for functions, which summarize their sharing behaviour. The paper ends up describing the implementation of the analysis and some examples. 1
The constrainedmonad problem
 In Proceedings of the 18th ACM SIGPLAN international conference on Functional programming. ACM
, 2013
"... In Haskell, there are many data types that would form monads were it not for the presence of typeclass constraints on the operations on that data type. This is a frustrating problem in practice, because there is a considerable amount of support and infrastructure for monads that these data types ca ..."
Abstract

Cited by 8 (1 self)
 Add to MetaCart
(Show Context)
In Haskell, there are many data types that would form monads were it not for the presence of typeclass constraints on the operations on that data type. This is a frustrating problem in practice, because there is a considerable amount of support and infrastructure for monads that these data types cannot use. Using several examples, we show that a monadic computation can be restructured into a normal form such that the standard monad class can be used. The technique is not specific to monads, and we show how it can also be applied to other structures, such as applicative functors. One significant use case for this technique is domainspecific languages, where it is often desirable to compile a deep embedding of a computation to some other language, which requires restricting the types that can appear in that computation.
Hatdelta — One Right Does Make a Wrong
"... Abstract. We outline two heuristics for improving the localisation of bugs in a program. This is done by comparing computations of the same program with different input. At least one of these computations must produce a correct result, while exactly one must exhibit some erroneous behavior. First, r ..."
Abstract

Cited by 6 (0 self)
 Add to MetaCart
(Show Context)
Abstract. We outline two heuristics for improving the localisation of bugs in a program. This is done by comparing computations of the same program with different input. At least one of these computations must produce a correct result, while exactly one must exhibit some erroneous behavior. First, reductions that are thought highly likely to be correct are eliminated from the search for the bug. Second, a program slicing technique is used to identify areas of code that are likely to be correct. These techniques are used in combination with algorithmic debugging to create a debugger that quickly and accurately locates bugs. The implementation of a prototype system is now complete. 1
Automated Benchmarking of Functional Data Structures
 In Practical Aspects of Declarative Languages
, 1999
"... . Despite a lot of recent interest in purely functional data structures, for example [Ada93, Oka95, BO96, Oka96, OB97, Erw97], few have been benchmarked. Of these, even fewer have their performance qualified by how they are used. But how a data structure is used can significantly affect performa ..."
Abstract

Cited by 5 (2 self)
 Add to MetaCart
(Show Context)
. Despite a lot of recent interest in purely functional data structures, for example [Ada93, Oka95, BO96, Oka96, OB97, Erw97], few have been benchmarked. Of these, even fewer have their performance qualified by how they are used. But how a data structure is used can significantly affect performance. This paper makes three original contributions. (1) We present an algorithm for generating a benchmark according to a given use of data structure. (2) We compare use of an automated tool based on this algorithm, with the traditional technique of handpicked benchmarks, by benchmarking six implementations of randomaccess list using both methods. (3) We use the results of this benchmarking to present a decision tree for the choice of randomaccess list implementation, according to how the list will be used. 1 Motivation Recent years have seen renewed interest in purely functional data structures: sets [Ada93], randomaccess lists [Oka95], priority queues [BO96], arrays [OB97], gr...
Denotational design with type class morphisms (extended version
"... Type classes provide a mechanism for varied implementations of standard interfaces. Many of these interfaces are founded in mathematical tradition and so have regularity not only of types but also of properties (laws) that must hold. Types and properties give strong guidance to the library implemen ..."
Abstract

Cited by 5 (0 self)
 Add to MetaCart
(Show Context)
Type classes provide a mechanism for varied implementations of standard interfaces. Many of these interfaces are founded in mathematical tradition and so have regularity not only of types but also of properties (laws) that must hold. Types and properties give strong guidance to the library implementor, while leaving freedom as well. Some of this remaining freedom is in how the implementation works, and some is in what it accomplishes. To give additional guidance to the what, without impinging on the how, this paper proposes a principle of type class morphisms (TCMs), which further refines the compositional style of denotational semantics. The TCM idea is simply that the instance’s meaning follows the meaning’s instance. This principle determines the meaning of each type class instance, and hence defines correctness of implementation. It also serves to transfer laws about a type’s semantic model, such as the class laws, to hold for the type itself. In some cases, it provides a systematic guide to implementation, and in some cases, valuable design feedback. The paper is illustrated with several examples of types, meanings, and morphisms. 1.
From higherorder logic to Haskell: there and back again
 In the ACM SIGPLAN Workshop on Partial Evaluation and Program Manipulation, PEPM’10
, 2010
"... We present two tools which together allow reasoning about (a substantial subset of) Haskell programs. One is the code generator of the proof assistant Isabelle, which turns specifications formulated in Isabelle’s higherorder logic into executable Haskell source text; the other is Haskabelle, a to ..."
Abstract

Cited by 5 (0 self)
 Add to MetaCart
(Show Context)
We present two tools which together allow reasoning about (a substantial subset of) Haskell programs. One is the code generator of the proof assistant Isabelle, which turns specifications formulated in Isabelle’s higherorder logic into executable Haskell source text; the other is Haskabelle, a tool to translate programs written in Haskell into Isabelle specifications. The translation from Isabelle to Haskell directly benefits from the rigorous correctness approach of a proof assistant: generated Haskell programs are always partially correct w.r.t. to the specification from which they are generated.
Fully Persistent Graphs  Which One To Choose?
 9th Int. Workshop on Implementation of Functional Languages. LNCS 1467
, 1997
"... . Functional programs, by nature, operate on functional, or persistent, data structures. Therefore, persistent graphs are a prerequisite to express functional graph algorithms. In this paper we describe two implementations of persistent graphs and compare their running times on different graph probl ..."
Abstract

Cited by 3 (2 self)
 Add to MetaCart
(Show Context)
. Functional programs, by nature, operate on functional, or persistent, data structures. Therefore, persistent graphs are a prerequisite to express functional graph algorithms. In this paper we describe two implementations of persistent graphs and compare their running times on different graph problems. Both data structures essentially represent graphs as adjacency lists. The first uses the version tree implementation of functional arrays to make adjacency lists persistent. An array cache of the newest graph version together with a time stamping technique for speeding up deletions makes it asymptotically optimal for a class of graph algorithms that use graphs in a singlethreaded way. The second approach uses balanced search trees to store adjacency lists. For both structures we also consider several variations, for example, ignoring edge labels or predecessor information. 1 Introduction A data structure is called persistent if it is possible to access old versions after updates. It ...
Benchmarking Purely Functional Data Structures
 Journal of Functional Programming
, 1999
"... When someone designs a new data structure, they want to know how well it performs. Previously, the only way to do this involves finding, coding and testing some applications to act as benchmarks. This can be tedious and timeconsuming. Worse, how a benchmark uses a data structure may considerably af ..."
Abstract

Cited by 2 (0 self)
 Add to MetaCart
(Show Context)
When someone designs a new data structure, they want to know how well it performs. Previously, the only way to do this involves finding, coding and testing some applications to act as benchmarks. This can be tedious and timeconsuming. Worse, how a benchmark uses a data structure may considerably affect the efficiency of the data structure. Thus, the choice of benchmarks may bias the results. For these reasons, new data structures developed for functional languages often pay little attention to empirical performance. We solve these problems by developing a benchmarking tool, Auburn, that can generate benchmarks across a fair distribution of uses. We precisely define "the use of a data structure", upon which we build the core algorithms of Auburn: how to generate a benchmark from a description of use, and how to extract a description of use from an application. We consider how best to use these algorithms to benchmark competing data structures. Finally, we test Auburn by benchmarking ...