[Haskell] Extensible records: Static duck typing

Bulat Ziganshin bulat.ziganshin at gmail.com
Tue Feb 5 05:28:58 EST 2008


Hello haskell,

the principle of duck typing used in dynamic OOP languages such as
Ruby and Python, is simple: if some object supports Quack method, then
it can be passed to any routine that expects an object of some Duck type

this principle allows to build programs in quick and easy way: we just
add to objects implementations of all the methods required:

e = new Entry {label := "Hi",
               color := blue,
               getValue := getEntryValue,
               setValue := setEntryValue}

e.display      -- uses color/label properties
e.saveToFile   -- uses getValue property

of course, drawback of duck typing that when we forgot to setup some
field, this will be detected only at runtime - as usual for dynamic
typing


Haskell can provide benefits of both static and duck typing with type
inference by means of extensible records. type of 'e' in this case
will be {Entry | getValue::IO String, setValue::String->IO()}, i.e.
Entry record type extended with getValue/setValue fields.

serialization function may look like this:

saveToFile x = writeToFile "data" (show x.getValue)

and its implementation infers its type:

saveToFile :: {...| getValue::(Show a) => a->IO() } -> IO ()

where {...| getValue::a} means "any record type which includes getValue
field of type a".

type of our 'e' conforms to this type signature, so `e` can be passed
to saveToFile in safe manner and this is completely checked at compile
time without any explicitly written type signatures


this becomes even more important when we want to create objects
belonging to more than one object hierarchy. by requiring that each
possible property should be explicitly declared, we may ensure that
properties used in different modules can't be mixed up:

module A:  property getValue
module B:  property getValue
module C:  import A; import B -- conflict: from where getValue should be imported?


it may be interesting to compare extensible records with OOP and type
classes approaches - it seems that e.r. is just like type class instances
created "at the place" and linked to the concrete object rather than
whole type


so, implementation of extensible records in haskell compilers would
allow to

1) give us simple, natural way to make bindings to various OOP
libraries. i've seen bindings in gtk2hs/wxHaskell and now they use a
lot of type hackery

2) compete with dynamic OOP languages in the areas of scripting, fast
prototyping, web programming and even make possible to use the same
techniques in larger apps, again increasing programmers productivity


also, extensible records may be useful for merging haskell into jvm/.net
world - as a way to provide haskell access to their OOP libs


ps: there are many papers on adding extensible records to Haskell, in particular
you can read http://research.microsoft.com/Users/simonpj/Papers/recpro.ps.gz

-- 
Best regards,
 Bulat                          mailto:Bulat.Ziganshin at gmail.com



More information about the Haskell mailing list