overloaded functions and incremental programming

Giuseppe Castagna Giuseppe.Castagna at ens.fr
Sun Jul 27 15:58:50 CEST 2003



> 
>>Are they simply a matter of convenience, or is there
>>something specific about the way XML types are expressed/extended that
>>requires overloading (and extensible overloading -- section 3.5
>>"incremental programming"). Thanks,
> 
> 
> I let Beppe answer this part.
> 

Ok, so let me add my two cents worth. This is an old idea, that is to use dynamic 
overloading to mimic object orientation. The rough idea is that code specialization 
can be obtained by incremental definition of overloaded functions. The act of adding 
  a new method for a message msg, corresponds to add a new code to (i.e. a new arrow 
in the interface of) the overloaded function msg.

To exemplify let us consider the split function of our example. Imagine that we 
define a subtype of person in that contains also a nationality attribute:

  type Citizen = FCitizen | MCitizen
  type FCitizen = <person gender = "F" nat = String>[ Name Children ]
  type MCitizen = <person gender = "M" nat = String>[ Name Children ]

note that the Children are still persons so no nationality is recorded. Imagine now 
that we want to specialize the behavior of  split. As it is split works also with 
Citizens but it completely loose the information about nationality. To make things 
harder imagine that instead split has to register the nationality in the result type 
and propagate it to children as well, that is.

type CMan = <man name=String nat=String>[ <sons>[CMan*] <daughters>[CWoman*] ]
type CWoman = <woman name=String nat=String>[ <sons>[CMan*] <daughters>[CWoman*] ]

Of course we can redefine split from scratch but by stating binding the new behavior 
will be available only to the new functions. If instead we implement specialization
with dynimic binding then also the "old" calls to split will enjoy the specialized 
behavior.

so if split were define in the module SomeModule we could write (in a yet not 
existing syntax)

addmethod SomeModule.split (FCitizen -> CWoman; MCitizen -> CMan)
  <person gender=g nat=nn>[ <name>n <children>[(mc::MPerson | fc::FPerson)*] ] ->
    let tag = match g with "F" -> `woman | "M" -> `man in
    let s = map mc with <person (atr)> elms -> split <person (atr+{nat=nn})> elms in
    let d = map fc with <person (atr)> elms -> split <person (atr+{nat=nn})> elms in
      <(tag) name=n nat=nn>[ <sons>s  <daughters>d ]

[we add the nat attribute in the arguments of the recursive calls and in the result]

This would roughly correspond to transform all the existin call to split to a call to 
the following function:


let split (MPerson -> Man ; FPerson -> Woman ; FCitizen -> CWoman ; MCitizen -> CMan)
| <person gender=g nat=nn>[ <name>n <children>[(mc::MPerson | fc::FPerson)*] ] ->
    let tag = match g with "F" -> `woman | "M" -> `man in
    let s = map mc with <person (atr)> elms -> split <person (atr+{nat=nn})> elms in
    let d = map fc with <person (atr)> elms -> split <person (atr+{nat=nn})> elms in
      <(tag) name=n nat=nn>[ <sons>s  <daughters>d ]
| <person gender=g>[ <name>n <children>[(mc::MPerson | fc::FPerson)*] ] ->
    let tag = match g with "F" -> `woman | "M" -> `man in
    let s = map mc with x -> split x in
    let d = map fc with x -> split x in
      <(tag) name=n>[ <sons>s  <daughters>d ]


Of course there still is a long way to go, first we need a real module system.

---Beppe---







More information about the Cduce-users mailing list