9.9 ML and Haskell: Summaries, Comparison, Applications, and Analysis

We are now ready to draw some comparisons between ML and Haskell.

9.9.1 ML Summary

ML is a statically scoped, programming language that supports primarily functional programming with a safe type system, type inference, an eager evaluation strategy, parametric polymorphism, algebraic data types, pattern matching, automatic memory management through garbage collection, a rich and expressive polymorphic type and module system, and some imperative features. ML integrates functional features from Lisp, rule-based programming (i.e., pattern matching) from Prolog, data abstraction from Smalltalk, and has a more readable syntax than Lisp. As a result, ML is a useful general-purpose programming language.

9.9.2 Haskell Summary

Haskell is a fully curried, statically scoped, (nearly) pure functional programming language with a lazy evaluation parameter-passing strategy, safe type system, type inference, parametric polymorphism, algebraic data types, pattern matching, automatic memory management through garbage collection, and a rich and expressive polymorphic type and class system.

9.9.3 Comparison of ML and Haskell

Table 9.7 compares the main concepts and features of ML and Haskell. The primary difference between these two languages is that ML uses eager evaluation (i.e., call-by-value) while Haskell uses lazy evaluation (i.e., call-by-name). Eager evaluation means that all subexpressions are always evaluated. These parameter-passing evaluation strategies are discussed in Chapter 12. Unlike Haskell, not all built-in functions in ML are curried. However, the higher-order functions map, foldl, and foldr, which are useful in creating new functions, are curried in ML. ML and Haskell share a similar syntax, though the syntax in Haskell is terser than that in ML. The other differences mentioned in Table 9.7 are mostly syntactic. Haskell is also (nearly) purely functional, in that it has no imperative features or provisions for side effects, even for I/O. Haskell uses the mathematical notion of a monad for conducting I/O while remaining faithful to functional purity. The following expressions succinctly summarize ML and Haskell in relation to each other and to Lisp:

Table 9.7 Comparison of the Main Concepts and Features of ML and Haskell

Concept

ML

Haskell

lists

homogeneous

homogeneous

cons

::

:

append

@

++

integer equality

=

==

integer inequality

<>

/=

strings

not a list of characters use explode

a list of Characters

renaming parameters

lst as (X::XS)

lst@(X:XS)

functional redefinition

permitted

not permitted

pattern-directed invocation

yes, with |

yes

parameter passing

call-by-value,
strict,
applicative-order evaluation

call-by-need,
non-strict,
normal-order evaluation

functional composition

o

.

infix to prefix

(op operator)

(operator)

sections

not supported

supported, use (operator)

prefix to infix

 

operator

user-defined functions

introduced with fun can be defined at the prompt or in a script

must be defined in a script

anonymous functions

(fn tuple => body)

( tuple -> body)

curried form

omit parentheses, commas

omit parentheses, commas

curried

partially

fully

type declaration

:

::

type definition

type

type

data type definition

datatype

data

type variables

prefaced with ’ written before data type name

not prefaced with ’ written after data type name

function type

optional, but if used, embedded within function definition

optional, but if used, precedes function definition

type inference/checking

Hindley-Milner

Hindley-Milner

function overloading

not supported

supported through qualified types and type classes

ADTs

module system (structures, signatures, and functors)

class system

A list of three expressions summarizing the relationships among M L, Haskell, and Lisp.
Description

9.9.4 Applications

The features of ML are ideally applied in language-processing systems, including compilers and theorem provers (Appel 2004). Haskell is also being increasingly used for application development in a commercial setting. Examples of applications developed in Haskell include a revision control system and a window manager for the X Window System. Galois is a software development and computer science research company that has used Haskell in multiple projects.6

ML and Haskell are also used for artificial intelligence (AI) applications. Traditionally, Prolog, which is presented in Chapter 14, has been recognized as a language for AI, particularly because it has a built-in theorem-proving algorithm called resolution and implements the associated techniques of unification and backtracking, which make resolution practical in a computer system. As a result, the semantics of Prolog are more complex than those of languages such as Scheme, C, and Java. A Prolog program consists of a set of facts and rules. An ML or Haskell program involving a series of function definitions using pattern-directed invocation has much the same appearance. (The built-in list data structures in Prolog and ML/Haskell are nearly identical.) Moreover, the pattern-directed invocation built into ML and Haskell is similar to the rule system in Prolog, albeit without the semantic complexity associated with unification and backtracking in Prolog.

However, ML and Haskell, unlike Prolog, include currying and curried functions and a powerful type and module system for creating abstract data types. As a result, ML and Haskell are used for AI in applications where Prolog (or Lisp) might have been the only programming language considered in the past. Curry, nearly a superset of Haskell, is an experimental programming language that seeks to marry the functional and logic programming in a single language. Similarly, miniKanren is a family of languages for relational programming. ML (and Prolog) were developed in the early 1970s; Haskell was developed in the early 1990s.

9.9.5 Analysis

Some beginner programmers find the constraints of the safe type system in ML and Haskell to be a source of frustration. Moreover, some find type classes to be a source of frustration in Haskell. However, once these concepts are understood properly, advanced ML and Haskell programmers appreciate the safe, algebraic type systems in ML and Haskell.

The subtle syntax and sophisticated type system of Haskell are a double edged sword—highly appreciated by experienced programmers but also a source of frustration among beginners, since the generality of Haskell often leads to cryptic error messages. (Heeren, Leijen, and van IJzendoorn 2003, p. 62)

An understanding of the branch of mathematics known as category theory is helpful for mastering the safe, algebraic type systems in ML and Haskell. Paul Graham (n.d.) has written:

Most hackers I know have been disappointed by the ML family. Languages with static typing would be more suitable if programs were something you thought of in advance, and then merely translated into code. But that’s not how programs get written. The inability to have lists of mixed types is a particularly crippling restriction. It gets in the way of exploratory programming (it’s convenient early on to represent everything as lists), . . . .

6. https://galois.com/about/haskell/

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.189.23