Mailing List Archive


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [tlug] recomendations for a functional language



On 2009-11-03 09:15 +0900 (Tue), Alan Busby wrote:

> On Tue, Nov 3, 2009 at 12:06 AM, Curt Sampson <cjs@example.com>wrote:
>
> > Don't underestimate this difference. Moving from duck typing to a
> > good H-M type system is a larger jump than moving from something like
> > Java's "static" type system to Ruby's "dynamic" type system.
> 
> I've heard this more than once, but I've yet to discover it myself
> unfortunately. How often are you saved from typing bugs by the
> compiler...

Saved from bugs by the type system? Constantly. It's my primary tool to
verify that what I'm writing makes sense.

I write about 1/5 the number of unit tests that I used to write, and
many of the ones now kicking around my biggest project I wrote for
comfort early on. Yet I still feel that I have better reliability than
in Ruby with five times the number of tests. I'll frequently do fairly
major refactorings on large and wide-ranging parts of code that have no
tests at all, relying entirely on the type system to make sure I make no
errors doing this.

And that's before we even get into the really sophisticated features of
the type system. It's basically like learning yet another programming
language.

> , and does it help with data driven bugs at all?

I'm not clear on exactly what you mean by "data driven bugs." 

It certainly does help, in concert with pattern matching, in terms of
things such as "am I handling all the possible cases of this value?"
When you have even a moderately sophisticated data type, such as:

    data Expr a		-- An expression of 'a's, where a is some type is
	= Fail String	-- a failure, with a string holding the error message,
	| IConst Int	-- a constant of type 'Int',
	| Const a	-- a constant of type a,
	| Sum (Expr a) (Expr a)
			-- or the sum of two (sub-) expressions of type a

making sure that you're handling all of the cases, and handling them
correctly, can be rather tricky in a language like Ruby, or even Java.

If you're talking about something like dependent types, Haskell doesn't
support those, though Agda does.

Basically, the long and short of it is, you can describe a *lot* of
stuff in a sophisticated type system. There are plenty of examples of
communications protocols described within type systems like this (and
even Haskell's type system, in particular) such that the type checker is
able to tell whether the client and server will be able to talk to each
other in all possible communications.

> > unrelated, yet quite important feature: pattern matching.
> 
> Clojure calls them "multi-methods", though they are a little different.

Multi-methods are entirely different, and correspond not to pattern
matching but to Haskell's type classes. I'm finding it hard to come up
with a good example, but perhaps we can fork off a thread here to find
one. Let's start with something like this:

    data Maybe a = Nothing | Just a     -- standard library definition
    data Pair    = Pair Int Int

    nonZeroValueOf :: Maybe Pair -> Maybe Int
    nonZeroValueOf x =
        case x of
             Nothing         -> Nothing
             Just (Pair 0 0) -> Nothing
             Just (Pair 0 m) -> Just m
             Just (Pair n _) -> Just n

How would you implement this in Clojure?

Note that type checking isn't required for pattern matching; Erlang
for example doesn't have compile-time type checking, yet has pattern
matching. However, I find that compile-time type checking, and notices
that you've missed a case in the pattern, to be exceedingly useful.

cjs
-- 
Curt Sampson       <cjs@example.com>        +81 90 7737 2974
           Functional programming in all senses of the word:
                   http://www.starling-software.com


Home | Main Index | Thread Index

Home Page Mailing List Linux and Japan TLUG Members Links