Code360 powered by Coding Ninjas X Naukri.com. Code360 powered by Coding Ninjas X Naukri.com
Table of contents
1.
Introduction
2.
What is Polymorphism?
2.1.
What is Compile Time Polymorphism?
2.2.
What is Run Time Polymorphism?
3.
What is a Polymorphic Function?
3.1.
Types of Polymorphic Functions in Compiler Design
3.1.1.
1. Ad-hoc Polymorphism:
3.1.2.
2. Parametric Polymorphism:
4.
How to Implement Polymorphic Functions in Different Languages?
5.
Frequently asked question
5.1.
Can a function act as both ad-hoc and parametric Polymorphic?
5.2.
How does Polymorphism improve code reusability?
5.3.
What are the uses of the keyword ‘super’ in Java?
5.4.
Write all the ways to achieve overloading a method.
6.
Conclusion
Last Updated: Mar 27, 2024

Polymorphic Functions in Compiler Design

Author Sourabh
1 upvote
Master Python: Predicting weather forecasts
Speaker
Ashwin Goyal
Product Manager @

Introduction

In today’s world, the life of a developer would be difficult without Polymorphism. It allows us to treat items from different instructions as though they belong to a shared superclass. To implement Polymorphism, we use Polymorphic functions.

Polymorphic Functions in Compiler Design

Now we will learn about polymorphic functions in compiler design. We will also learn how to implement them, what their types are, and their advantages.

What is Polymorphism?

Polymorphism is a Greek word. It comprises two words, where Poly means "many" and morphism means "forms". It is the ability of an object to take on many forms. Polymorphism allows you to “program in general” rather than “program in specific."  It is the capability of a method to do different things based on the object.

There are two types of Polymorphism:

  1. Compile Time Polymorphism.
     
  2. Run Time Polymorphism.
     
Types of Polymorphism

What is Compile Time Polymorphism?

Compile time Polymorphism refers to a behavior that is resolved when your class is compiled. Example: -  Method overloading.
Method Overloading: This is a feature that we can use to allow a class to have more than one method with the same name, but their argument lists should be different from each other. Compile time is also known as "static binding" or "early binding."

What is Run Time Polymorphism?

It is a feature that allows a child class or subclass to provide a certain implementation of a method that is already provided by one of its parent classes or superclasses.
Example: -  Method Overriding. Run time is also known as Dynamic binding or Late binding.

Get the tech career you deserve, faster!
Connect with our expert counsellors to understand how to hack your way to success
User rating 4.7/5
1:1 doubt support
95% placement record
Akash Pal
Senior Software Engineer
326% Hike After Job Bootcamp
Himanshu Gusain
Programmer Analyst
32 LPA After Job Bootcamp
After Job
Bootcamp

What is a Polymorphic Function?

A function is said to be a Polymorphic function if it can work with multiple types of data or objects. We can also describe it as a function that can be used to perform the same type of operation on different types of input.

Types of Polymorphic Functions in Compiler Design

There are two types of polymorphic functions that are used in compiler design.

1. Ad-hoc Polymorphism:

It is also known as “Overloading Ad-hoc Polymorphism”, which allows functions that have the same name to act differently for different data types. For example, The plus operator will add two numbers but perform a concatenation operation on two strings.

#include <iostream>
using namespace std;

int add(int x, int y)
{
	int z = x + y;
	return z;
}

string add(const char* x, const char* y)
{
	string addition(x);
	addition += y;
	return addition;
}

int main()
{
	cout << add(71, 72)
		<< " is  Integer addition Output\n";
	cout << add("Coding", " Ninjas")
		<< " is  String Concatenation Output\n";
}


Output:

143 is Integer addition Output
Coding Ninjas is String Concatenation Output


So, we are calling two different functions (which differ in the type of arguments), and both of them have the same name to execute multiple operations. We have successfully achieved Ad-hoc Polymorphism.

Advantages of Ad-hoc Polymorphism:

  • It allows the functions to be more versatile and handle different data types and different ways.
     
  • It provides a simpler Interface to the programmer.
     
  • It will group all the related functions under a single name. And this will improve the readability. 
     

2. Parametric Polymorphism:

 It is also known as "Early Binding Parametric Polymorphism.” It opens a way to use the same code for different data types. It is implemented by using Templates. For example: To develop an understanding of this sort of Polymorphism, let us execute a program to find the greater of two Integers or two Strings.

#include <iostream>
#include <string>
using namespace std;

template <class temp>
temp greater(temp a, temp b)
{
	if (a > b)
		return a;
	else
		return b;
}

int main()
{
	cout <<:: greater(96, 69) << endl;
	string str1("Coding"), str2("Ninja");
	cout <<:: greater(str1, str2) << endl;
}


 Output:

96
Ninja


Using Templates, the same function can be parameterized with different types of data, but this needs to be decided at compile-time itself, and hence, this Polymorphism is named so. If we wish to achieve such Polymorphism for pointers, it turns into Ad-hoc Polymorphism.

Advantages of parametric Polymorphism

  • It helps developers in reducing code duplication. And it also increases the code maintainability.
     
  • It also enables more data abstraction in the code design.
     
  • By allowing the compiler to optimize the code for some specific data types, it will improve the performance of the system.

How to Implement Polymorphic Functions in Different Languages?

Example 1:
In the first example, We will see how we can implement or use Polymorphic functions in C++ language.

#include <iostream> 
Using namespace std: 

class A {  
   public: 
   void show() {    
      cout << "A class method is called/n"; 
   } 
}; 

class B: public A { 
   public: 
   void show() {   
      cout << "B class method is called/n"; 
   } 
};  

int main() {   
   A x;        // Base class object 
   B y;        // Derived class object 
   x.show();   // A class method is called 
   y.show();   // B class method is called 
   return 0; 
} 


There are two classes present in the code "A" AND "B". And we are using "A" to derive "B".
And both of these classes have a member function known as "show()". But "B" will override the implementation of functions "show()" in "A".
Then show function will be called on "A" and "B". The appropriate implementation of "show()" function will be called depending on the type of object, demonstrating Polymorphism.

Output:

A class method is called 
B class method is called


Example 2:
In the second example, we will see how we can use a Polymorphic function in Python language.

class A(object): 
   def show(self): 
      print "A class method is called." 
  
class B(A): 
   def show(self): 
      print "B class method is called." 
  
def whichmethod(clasmethod): 
   which.show()  

AObj = A() 
BObj = B() 
  
whichmethod(AObj) 
whichmethod(BObj) 


There are two classes present in the code "A" AND "B". And "B" inherits from  "A". And both of these classes have a member function known as "show()". A function “whichmethod” is defined which takes an argument “classmethod” and calls the show method on the object passed as the argument. Two objects AObj and BObj, are created, one of each class. Then, “whichmethod” is called twice with AObj and BObj as the arguments, respectively.
When “whichmethod” is called with AObj, it calls A's show method, which prints "A class method is called". When it is called with BObj, it calls B's show method, which prints "B class method is called".
Overall, this code snippet demonstrates that a subclass can override a method defined in its superclass with its own implementation.

Output:

A class method is called.
B class method is called.

 

Example 3:
In the third example, we will see how we can use the Polymorphic function in C#.

class Animal  // Base class (parent) 
{
  public void animalSound() 
  {
    Console.WriteLine("The animal is making a sound.");
  }
}

class Lion: Animal  // Derived class (child) 
{
  public void animalSound() 
  {
    Console.WriteLine("The Lion says: Roar Roar");
  }
}

class Element : Animal  // Derived class (child) 
{
  public void animalSound() 
  {
    Console.WriteLine("The Elephant says: oog oog");
  }
}

class Program 
{
  static void Main(string[] args) 
  {
    Animal myAnimal = new Animal();  // Creating an Animal object
    Animal myLion = new Lion();  // Creating a Lion object
    Animal myLion = new Lion();  // Creating an Elephant object

    myAnimal.animalSound();
    myLion.animalSound();
    myElephant.animalSound();
  }
}


This code defines three classes: Animal, Lion, and Element. Lion and Element are derived classes that inherit from the Animal class. The Animal class has a method called animalSound(), while the Lion and Element classes override this method to write specific messages to the console. In the Main method, objects of each class are created, and their animalSound() methods are called, resulting in different messages being printed to the console depending on the type of object.


Output:

The animal is making a sound.
The animal is making a sound.
The animal is making a sound.

 

Also check out - Phases of Compiler and  cousins of compiler

Frequently asked question

Can a function act as both ad-hoc and parametric Polymorphic?

Yes, It is possible that a function can act as both. And we can achieve this through the use of generic functions that are overloaded with different parameter types and numbers.

How does Polymorphism improve code reusability?

Polymorphism permits one function to operate on multiple types of values. Due to this, we do not have to write extra code for different data types. Due to this, the code reusability improves.

What are the uses of the keyword ‘super’ in Java?

It can be used to invoke the method for the immediate parent class. It can be used to call the constructor of the immediate parent class. It can also be used to refer to the instance variable for the immediate parent class.

Write all the ways to achieve overloading a method.

If you want to overload a method, then you should make sure that the argument lists of the methods should differ in either of these cases: A sequence of Data types of parameters, the number of parameters and the data type of parameters.

Conclusion

Polymorphic functions in compiler design allow functions to work on multiple data types or objects. They make the code more flexible and reusable. On the plus side, it can improve code reusability and type safety. But on the bad side, it also brings some challenges, but careful testing can help ensure the high reliability of these functions.

You can refer to our article if you want to learn more about Polymorphism.
You can refer to our article if you want to learn about code generation.
You can refer to our article if you want to learn about intermediate code for procedure.

For more information, refer to our Guided Path on Coding Ninjas Studio to upskill yourself in PythonData Structures and AlgorithmsCompetitive ProgrammingSystem Design, and many more! Head over to our practice platform, Coding Ninjas Studio, to practice top problems, attempt mock tests, read interview experiences and interview bundles, follow guided paths for placement preparations, and much more! Nevertheless, consider our paid courses to give your career an edge over others!

Do upvote our blogs if you find them helpful and engaging!

Happy Learning!

Live masterclass