പോളിമോർഫിസം (കമ്പ്യൂട്ടർ ശാസ്ത്രം)

പ്രോഗ്രാമിങ് ഭാഷകളിലും ടൈപ്പ് തിയറിയിലും പല ടൈപ്പുകൾക്ക് ഒരേ ഇന്റർഫേസ് നൽകാനുള്ള കഴിവിനെയാണ് **പോളിമോർഫിസം** എന്നു പറയുന്നത്. ഒരു ടൈപ്പിന്റെ ഓപ്പറേഷൻസ് മറ്റൊരു ടൈപ്പിലും ഉപയോഗിയ്ക്കാൻ പറ്റുമെങ്കിൽ അതിനെ **പോളിമോർഫിക് ടൈപ്പ്** എന്നു വിളിയ്ക്കുന്നു. പല തരത്തിലുള്ള പോളിമോർഫിസങ്ങൾ ഉണ്ട്:

* *ആഡ് ഹോക്ക് പോളിമോർഫിസം*: ഒരേ ഫങ്ക്ഷന് അതിലേയ്ക്ക് പാസ് ചെയ്യാവുന്ന ഡാറ്റയുടെ ടൈപ്പുകളുടെ കോമ്പിനേഷനുകൾ വ്യത്യാസപ്പെടുത്തി കിട്ടുന്ന വ്യത്യസ്ത ഇമ്പ്ലെമെന്റഷനുകൾ ഉണ്ടെങ്കിൽ അത് ആഡ് ഹോക്ക് പോളിമോർഫിസം ആണ്. വ്യത്യസ്ത കമ്പ്യൂട്ടർ ഭാഷകൾ ഫങ്ക്ഷൻ ഓവർലോഡിങ് എന്ന സംവിധാനം വഴി ഇതിനു കളമൊരുക്കുന്നു.
* *പാരാമെട്രിക് പോളിമോർഫിസം*: ഒരു പ്രത്യേക ടൈപ്പിനെ മാത്രം ഉന്നം വെയ്ക്കാതെ ഏതു ടൈപ്പിലുള്ള ഡാറ്റാ ടൈപ്പും ഉപയോഗിയ്ക്കാവുന്ന രീതിയിൽ കോഡ് എഴുതുമ്പോൾ അതിനെ പാരാമെട്രിക് പോളിമോർഫിസം എന്ന് വിശേഷിപ്പിയ്ക്കുന്നു. ഒബ്ജക്റ്റ് ഓറിയന്റഡ് പ്രോഗ്രാമിങ് സമൂഹത്തിൽ ഇത് ജനറിക് പ്രോഗ്രാമിങ് എന്നും ഫങ്ക്ഷണൽ പ്രോഗ്രാമിങ് സമൂഹത്തിൽ ഇത് വെറുതെ പോളിമോർഫിസം എന്നും അറിയപ്പെടുന്നു.
* *സബ്ടൈപ്പിംഗ്* ഒരു ടൈപ്പിന്റെ പേര് ഒരേ ക്ലാസ്സിൽ നിന്നും ഡിറൈവ് ചെയ്യപ്പെട്ട പല സബ്-ക്ലാസ്സുകളെ പ്രതിനിധീകരിയ്ക്കുമ്പോൾ. 

## ചരിത്രം
ആഡ് ഹോക്ക് പോളിമോർഫിസവും പാരാമെട്രിക് പോളിമോർഫിസവും 1967 ൽ ബ്രിട്ടീഷ് കമ്പ്യൂട്ടർ ശാസ്ത്രജ്ഞൻ ക്രിസ്റ്റഫർ സ്ട്രാച്ചി എഴുതിയ ഫണ്ടമെന്റൽ കോൺസെപ്റ്സ് ഇൻ പ്രോഗ്രാമിങ് ലാംഗ്വേജസ് എന്ന പുസ്തത്തിൽ വിവരിയ്ക്കപ്പെട്ടിരുന്നു. 1985 ൽ എഴുതപ്പെട്ട ഒരു പേപ്പറിൽ പീറ്റർ വാഗ്‌നേറും ലൂക്ക കാർഡെല്ലിയും ഇൻക്ലഷൻ പോളിമോർഫിസം എന്ന വാക്ക് സബ് ടൈപ്പുകളെയും ഇൻഹെറിറ്റൻസ്'നെയും വിവരിയ്ക്കാൻ ഉപയോഗിച്ചിരുന്നു. എന്നാൽ ഇൻക്ലഷൻ പോളിമോർഫിസം എന്ന വാക്ക് നിലവിൽ വരുന്നതിനു മുൻപ് തന്നെ ഇത് ഇമ്പ്ലെമെന്റ് ചെയ്യാൻ ഉപയോഗിയ്ക്കുന്ന സബ് ടൈപ്പിംഗ്, ഇൻഹെറിറ്റൻസ് തുടങ്ങിയ ആശയങ്ങൾ 1967 ൽത്തന്നെ സിമുല എന്ന പ്രോഗ്രാമിങ് ഭാഷയിൽ ഉപയോഗിയ്ക്കപ്പെട്ടിരുന്നു.

## വിവിധ തരം പോളിമോർഫിസങ്ങൾ

### ആഡ് ഹോക്ക് പോളിമോർഫിസം
ഒരേ ഫങ്ക്ഷൻ അതിലേയ്ക്ക് പാസ് ചെയ്യപ്പെടുന്ന ഡാറ്റയുടെ ടൈപ്പുകളനുസരിച്ച് ഫങ്ക്ഷൻ വ്യത്യസ്ത സ്വഭാവം ആർജിയ്ക്കും എന്നുള്ളതാണ് ആഡ് ഹോക്ക് പോളിമോർഫിസത്തിന്റെ പ്രത്യേകത. ഇതിനെ മിയ്ക്ക പ്രോഗ്രാമിങ് ഭാഷകളിലും ഫങ്ക്ഷൻ ഓവർലോഡിങ് (ഓപ്പറേറ്ററുകളുടെ സ്വഭാവമാണ് ഇത്തരത്തിൽ മാറ്റുന്നതെങ്കിൽ ഓപ്പറേറ്റർ ഓവർലോഡിങ്) എന്നു വിളിയ്ക്കുന്നു. ഇതിനെ ആഡ് ഹോക്ക് പോളിമോർഫിസം എന്ന് ആദ്യമായി വിളിയ്ക്കുന്നത് ക്രിസ്റ്റഫർ സ്ട്രാച്ചി ആണ്. ഉദാഹരണത്തിന് താഴെ കൊടുത്തിരിയ്ക്കുന്ന പാസ്കൽ പ്രോഗ്രാമിൽ Add എന്ന ഫങ്ക്ഷൻ വ്യത്യസ്ത ടൈപ്പുകൾക്കനുസരിച് വ്യത്യസ്തമായി പ്രവർത്തിയ്ക്കുന്നുണ്ടെങ്കിലും അത് സി++'ലേതു പോലെ ഓവർലോഡഡ് ഫങ്ക്ഷൻ ആയല്ല കമ്പൈലർ കണക്കാക്കുന്നത്. പകരം രണ്ടും വ്യത്യസ്ത ഫങ്ക്ഷനുകൾ ആയാണ്:
```pascal
program Adhoc;

function Add(x, y : Integer) : Integer;
begin
    Add := x + y
end;

function Add(s, t : String) : String;
begin
    Add := Concat(s, t)
end;

begin
    Writeln(Add(1, 2));                   (* Prints "3"             *)
    Writeln(Add('Hello, ', 'World!'));    (* Prints "Hello, World!" *)
end.
```

അതുപോലെ ഡയനാമിക്കലി ടൈപ്ഡ് (ഡാറ്റയുടെ ടൈപ്പുകൾ പ്രോഗ്രാം ഓടുന്ന സമയത്തുമാത്രം ഊഹിച്ചെടുക്കുന്ന / കണക്കു കൂട്ടി എടുക്കുന്ന രീതി) പ്രോഗ്രാമിങ് ഭാഷകളിൽ ഇത് ഇനിയും സങ്കീർണമാണ്. ഇവിടെ കമ്പൈലർ ഒരു ഫങ്ക്ഷനിലേയ്ക്ക് ഇന്പുട് ആയി വരുന്ന എല്ലാ ഡേറ്റയുടെയും ടൈപ്പുകൾ കാണുന്നില്ല. എന്നിട്ടും ഓവർലോഡിങ്'ന്റെ പ്രഭാവം പ്രോഗ്രാം ഓടുന്ന സമയത്തു കാണാം. ഈ കാരണങ്ങൾ കൊണ്ടാണ് ഇത്തരം പോളിമോർഫിസം പ്രോഗ്രാമിങ് ഭാഷയുടെ അടിസ്ഥാന സ്വഭാവം അല്ലാതിരിയ്ക്കുന്നത്.

അതുപോലെ ചില ഭാഷകളിൽ പ്രോഗ്രാമർ പ്രത്യേകിച്ച് ഒന്നും സൂചിപ്പിച്ചില്ലെങ്കിലും കമ്പൈലർ ഒരു ഫങ്ക്ഷനിലേയ്ക്ക് ഇടുന്ന ഡാറ്റയുടെ ടൈപ്പ് സ്വന്തമായി ഊഹിച്ചു മാറ്റാറുണ്ട്. ഇതിനെ ഇംപ്ലിസിറ്റ് ടൈപ്പ് കോൺവെർഷൻ എന്നാണ് വിളിയ്ക്കുന്നത്. ഇതും ഒരു തരം ആഡ് ഹോക്ക് പോളിമോർഫിസം ആണ്.

### പാരാമെട്രിക് പോളിമോർഫിസം
മുകളിൽ പറഞ്ഞ ടൈപ്പ് മാറ്റങ്ങൾ നേടിയെടുക്കാൻ പൊതുവെ കമ്പൈലറുകൾ സ്വന്തമായി ചിലത് ഊഹിച്ചെടുക്കണം എന്നു കണ്ടല്ലോ. ഇത് പൊതുവെ അത്ര സുരക്ഷിതമല്ല. കാരണം പലപ്പോഴും പ്രോഗ്രാമർ അറിയാതെ തന്നെ വരുത്തുന്ന ചില തെറ്റുകൾ മൂലം അയാൾ ഉദ്ദേശിയ്ക്കുന്ന ഫങ്ക്ഷനുകൾ അല്ല വിളിയ്ക്കപ്പെടുക. എന്നാൽ ഇത്തരം തെറ്റായ സ്വഭാവങ്ങൾ കണ്ടെത്താൻ പ്രോഗ്രാം ഓടുന്നതു വരെ കാത്തിരിയ്ക്കണം. അതായത് ഇത്തരം തെറ്റുകൾ കണ്ടെത്താൻ കമ്പൈലറിന്റെ ഒരു സഹായവും കിട്ടില്ല എന്നർത്ഥം (ഏതാണ്ട് കമ്പൈലറിനെ പറ്റിച്ചാണല്ലോ പോളിമോർഫിസം നേടിയെടുക്കുന്നത് തന്നെ!). ഇത് കൂടുതൽ ടൈപ്പ്-സേഫ് ആയി നേടിയെടുക്കാൻ സഹായിയ്ക്കുന്ന വിദ്യയാണ് പാരാമെട്രിക് പോളിമോർഫിസം അഥവാ ജനറിക് പ്രോഗ്രാമിങ്. ഇവിടെ പൊതുവായി എഴുതപ്പെട്ട ഒരു ഫങ്ക്ഷനേ കാണൂ. ഇതിലേക്കുള്ള ഡാറ്റ ഒരു പൊതു ടൈപ്പ് ആയി പാസ്സ് ചെയ്യുന്നു. എന്നാൽ ഈ ടൈപ്പിനെ വേണ്ടവിധത്തിൽ ഭേദഗതി വരുത്തി നമുക്കാവശ്യമുള്ള പെരുമാറ്റം നേടിയെടുക്കാവുന്നതാണ്. ഇത്തരം മാറ്റങ്ങൾ കമ്പൈൽ ചെയ്യപ്പെടുന്ന വേളയിൽത്തന്നെ കമ്പൈലർ ഒത്തുനോക്കി ഉപയോഗിയ്ക്കുന്നതുകൊണ്ട് ഇതിന്റെ ടൈപ്പ് സുരക്ഷ വളരെ കൂടുതൽ ആണ്. 

ലിസ്റ്റ് എന്നത് ഇതിന് ഒരുദാഹരണമാണ്. ലിസ്റ്റിൽ ഇടുന്ന ഡാറ്റാ പല തരത്തിൽ പെട്ടതാകാം. അതായത് ലിസ്റ്റിലേക്ക് ഇടുന്ന ഡാറ്റ പല തരത്തിൽ വിവരിയ്ക്കാൻ പറ്റുന്ന ഒരു ടൈപ്പ് ആയിരിയ്ക്കും. എന്നാൽ ലിസ്റ്റിനെ പ്രോഗ്രാം ചെയ്തിരിയ്ക്കുന്നത് ഒരേ തരത്തിലായിരിയ്ക്കും.(പല ടൈപ്പിന് പലതരം ഫങ്ക്ഷനുകൾ ഇല്ല എന്നർത്ഥം. ആഡ് ഹോക്ക് പോളിമോർഫിസം ആണെങ്കിൽ ഓരോ ടൈപ്പിനും ഓവർലോഡ് ചെയ്യപ്പെട്ട ഓരോ ഫങ്ക്ഷൻ കാണും.)

ഫങ്ക്ഷണൽ പ്രോഗ്രാമിങിൽ ഇത് വെറുതെ പോളിമോർഫിസം എന്ന പേരിൽ അറിയപ്പെടുന്നു. താഴെ കൊടുത്തിരിയ്ക്കുന്ന ഹാസ്‌ക്കൽ കോഡ് ഒരു ലിസ്റ്റിനെ പൊതുവായി പ്രോഗ്രാം ചെയ്തിരിയ്ക്കുന്നത് കാണിയ്ക്കുന്നു.:
```haskell
data List a = Nil | Cons a (List a)

length :: List a -> Integer
length Nil         = 0
length (Cons x xs) = 1 + length xs

map :: (a -> b) -> List a -> List b
map f Nil         = Nil
map f (Cons x xs) = Cons (f x) (map f xs)
```

ഒബ്ജക്റ്റ് ഓറിയന്റഡ് പ്രോഗ്രാമിങ് ഭാഷകളിലും ഇത് വ്യാപകമായി കാണുന്നു. സി++'ൽ ഇത് ടെമ്പ്ലേറ്റ് (template) എന്നറിയപ്പെടുന്നു. സി#'ലും ജാവ'യിലും ജനറിക്സ് (generics) എന്നും:
```csharp
class List<T> {
    class Node<T> {
        T elem;
        Node<T> next;
    }
    Node<T> head;
    int length() { ... }
}

List<B> map(Func<A, B> f, List<A> xs) {
    ...
}
```

ഈ ആശയം വ്യാപകമായി ഉപയോഗിച്ച് ഡിസൈൻ ചെയ്യപ്പെട്ടിട്ടുള്ള ഒരു ലൈബ്രറിയാണ് സി++'ലെ സ്റ്റാൻഡേർഡ് ടെമ്പ്ലേറ്റ് ലൈബ്രറി.

### സബ്ടൈപ്പിംഗ്
ചില പ്രോഗ്രാമിങ് ഭാഷകളിൽ ഒരു ടൈപ്പ് സ്വീകരിയ്ക്കപ്പെടുന്ന ഫങ്ക്ഷനുകളിൽ ആ ടൈപ്പിന്റെ സബ്-ടൈപ്പ് (ഡിറൈവ് ചെയ്യപ്പെട്ട മറ്റൊരു ടൈപ്പ്, ഉദാ : 'ബസ്' എന്ന ടൈപ്പ് സ്വീകരിയ്ക്കുന്ന ഫങ്ക്ഷനിൽ 'സ്കൂൾബസ്' എന്ന് കൊടുത്താൽ) കൊടുത്താലും അത് പഴയ പോലെ തന്നെ പ്രവർത്തിയ്ക്കും. അതായത് `T` എന്ന ടൈപ്പ് സ്വീകരിയ്ക്കുന്ന ഫങ്ക്ഷൻ `S` എന്ന `T` യുടെ സബ്-ടൈപ്പ് കൊടുത്താലും പഴയപോലെ തന്നെ പ്രവർത്തിയ്ക്കും. ഇവിടെ `T`'യെ `S`'ന്റെ സൂപ്പർ ടൈപ്പ് എന്നു വിളിയ്ക്കുന്നു. ഇങ്ങനെ ഒരു ഫങ്ക്ഷന്റെ ടൈപ്പ് മാറ്റാൻ സാധിയ്ക്കുമെങ്കിൽ ആ ഫങ്ക്ഷൻ ലിസ്‌കോവ് സബ്സ്റ്റിട്യൂഷൻ നിയമം (Liskov substitution principle) പാലിയ്ക്കുന്നു എന്നു പറയുന്നു. ഇത്തരത്തിൽ ടൈപ്പ് മാറ്റിയ വിവരം സാധാരണ പ്രോഗ്രാമുകൾ റൺടൈമിൽ ആണ് അറിയുക.

താഴെ കൊടുത്തിരിയ്ക്കുന്ന ഉദാഹരണത്തിൽ `letsHear()` എന്ന ഫങ്ക്ഷൻ ഒരു `Animal` ഒബ്ജെക്റ്റിനെയാണ് പ്രതീക്ഷിയ്ക്കുന്നത്. എന്നാൽ `Cat, Dog` എന്നീ ക്ലാസുകൾ `Animal` ക്ലാസ്സിന്റെ സബ്-ടൈപ്പുകൾ ആയതുകൊണ്ട് `letsHear()` ഫങ്ക്ഷനിലേയ്ക്ക് `Cat, Dog` എന്നീ ക്ലാസ്സുകളുടെ ഒബ്ജക്റ്റുകൾ പാസ് ചെയ്താലും അത് ഉദ്ദേശിച്ച പോലെ പ്രവർത്തിയ്ക്കും:
```java
abstract class Animal {
    abstract String talk();
}

class Cat extends Animal {
    String talk() {
        return "Meow!";
    }
}

class Dog extends Animal {
    String talk() {
        return "Woof!";
    }
}

static void letsHear(final Animal a) {
    println(a.talk());
}

static void main(String[] args) {
    letsHear(new Cat());
    letsHear(new Dog());
}
```
ഒബ്ജക്റ്റ് ഓറിയന്റഡ് പ്രോഗ്രാമിങ് ഭാഷകളിൽ ഇത് സാധാരണ ഇൻഹെറിറ്റൻസ് എന്ന ആശയം വഴിയാണ് സാധിയ്ക്കുന്നത്.

## പോളിമോർഫിസം എങ്ങനെ ഉണ്ടാക്കിയെടുക്കുന്നു എന്നത്

### സ്റ്റാറ്റിക് ആൻഡ് ഡൈനാമിക് പോളിമോർഫിസം
മുകളിലെ വിവരണങ്ങളിൽ ചില പോളിമോർഫിസം വിദ്യകൾ കമ്പൈൽ സമയത്തും ചിലവ റൺ ടൈമിലും ആണ് പ്രവർത്തിയ്ക്കുന്നത് എന്ന് കണ്ടല്ലോ. കമ്പൈൽ സമയത്തു പ്രവർത്തിയ്ക്കുന്ന പോളിമോർഫിസത്തെ സ്റ്റാറ്റിക് പോളിമോർഫിസം എന്നും റൺടൈമിൽ പ്രവർത്തിയ്ക്കുന്ന പോളിമോർഫിസത്തെ ഡൈനാമിക് പോളിമോർഫിസം എന്നും വിളിയ്ക്കുന്നു. കമ്പൈൽ സമയത്തു തന്നെ എല്ലാം തീർപ്പാക്കുന്നതിനാൽ സ്റ്റാറ്റിക് പോളിമോർഫിസം താരതമ്യേന വേഗത്തിൽ പ്രവർത്തിയ്ക്കുന്നു. അത് കൂടാതെ, കോഡ് തന്നെ വായിച്ചു നോക്കി തെറ്റുകൾ കണ്ടെത്തുന്ന പ്രോഗ്രാമുകൾ (സ്റ്റാറ്റിക് പ്രോഗ്രാം അനാലിസിസ്, static code analysis) ഉപയോഗിച്ച് (കമ്പൈലർ സഹായം വേറെ) ഇതിലെ തെറ്റുകൾ തിരുത്താൻ താരതമ്യേന എളുപ്പമാണ്. അത് കൂടാതെ കമ്പൈലറുകൾക്കു ഉണ്ടാക്കുന്ന മെഷീൻ കോഡിൽ ആവശ്യത്തിന് വേഗക്കൂടുതൽ വിദ്യകളും (പ്രോഗ്രാം അഭീഷ്ടീകരണം, code optimization) കൊണ്ടുവരാൻ സഹായിയ്ക്കും. എന്നാൽ ഡൈനാമിക് പോളിമോർഫിസം ഉപയോഗിച്ച് കൂടുതൽ സങ്കീർണമായ ആവശ്യങ്ങൾ നേടിയെടുക്കാം.

## ഇവ കൂടി കാണുക

* സ്റ്റാൻഡേർഡ് ടെമ്പ്ലേറ്റ് ലൈബ്രറി (സി++)

## അവലംബം

## പുറംകണ്ണികൾ
* C++ examples of polymorphism
* Objects and Polymorphism (Visual Prolog) 

വർഗ്ഗം:പ്രോഗ്രാമിങ് ഭാഷകൾ
വർഗ്ഗം:കമ്പ്യൂട്ടർ പ്രോഗ്രാമിങ്ങ്
വർഗ്ഗം:സോഫ്റ്റ്‌വെയർ സാങ്കേതികവിദ്യ