Programmation fonctionnelle - Guide rapide

Les langages de programmation fonctionnels sont spécialement conçus pour gérer les applications de calcul symbolique et de traitement de liste. La programmation fonctionnelle est basée sur des fonctions mathématiques. Certains des langages de programmation fonctionnelle populaires incluent: Lisp, Python, Erlang, Haskell, Clojure, etc.

Les langages de programmation fonctionnels sont classés en deux groupes, à savoir -

  • Pure Functional Languages- Ces types de langages fonctionnels ne prennent en charge que les paradigmes fonctionnels. Par exemple - Haskell.

  • Impure Functional Languages- Ces types de langages fonctionnels prennent en charge les paradigmes fonctionnels et la programmation de style impératif. Par exemple - LISP.

Programmation fonctionnelle - Caractéristiques

Les caractéristiques les plus importantes de la programmation fonctionnelle sont les suivantes:

  • Les langages de programmation fonctionnels sont conçus sur le concept de fonctions mathématiques qui utilisent des expressions conditionnelles et la récursivité pour effectuer des calculs.

  • Supports de programmation fonctionnelle higher-order functions et lazy evaluation fonctionnalités.

  • Les langages de programmation fonctionnels ne prennent pas en charge les contrôles de flux comme les instructions de boucle et les instructions conditionnelles telles que les instructions If-Else et Switch. Ils utilisent directement les fonctions et les appels fonctionnels.

  • Comme la POO, les langages de programmation fonctionnels prennent en charge des concepts courants tels que l'abstraction, l'encapsulation, l'héritage et le polymorphisme.

Programmation fonctionnelle - Avantages

La programmation fonctionnelle offre les avantages suivants -

  • Bugs-Free Code - La programmation fonctionnelle ne prend pas en charge state, il n'y a donc pas de résultats d'effets secondaires et nous pouvons écrire des codes sans erreur.

  • Efficient Parallel Programming- Les langages de programmation fonctionnels n'ont aucun état mutable, il n'y a donc pas de problèmes de changement d'état. On peut programmer des "Fonctions" pour qu'elles fonctionnent en parallèle comme des "instructions". Ces codes facilitent la réutilisabilité et la testabilité.

  • Efficiency- Les programmes fonctionnels sont constitués d'unités indépendantes qui peuvent s'exécuter simultanément. En conséquence, ces programmes sont plus efficaces.

  • Supports Nested Functions - La programmation fonctionnelle prend en charge les fonctions imbriquées.

  • Lazy Evaluation - La programmation fonctionnelle prend en charge les constructions fonctionnelles paresseuses telles que les listes paresseuses, les cartes paresseuses, etc.

Par contre, la programmation fonctionnelle nécessite un grand espace mémoire. Comme il n'a pas d'état, vous devez créer de nouveaux objets à chaque fois pour effectuer des actions.

La programmation fonctionnelle est utilisée dans des situations où nous devons effectuer de nombreuses opérations différentes sur le même ensemble de données.

  • Lisp est utilisé pour les applications d'intelligence artificielle telles que l'apprentissage automatique, le traitement du langage, la modélisation de la parole et de la vision, etc.

  • Les interpréteurs Lisp intégrés ajoutent de la programmabilité à certains systèmes comme Emacs.

Programmation fonctionnelle vs programmation orientée objet

Le tableau suivant met en évidence les principales différences entre la programmation fonctionnelle et la programmation orientée objet -

Programmation fonctionnelle POO
Utilise des données immuables. Utilise les données Mutable.
Suit le modèle de programmation déclarative. Suit le modèle de programmation impératif.
L'accent est mis sur: «Ce que vous faites» L'accent est mis sur «comment tu vas»
Prend en charge la programmation parallèle Ne convient pas à la programmation parallèle
Ses fonctions n'ont aucun effet secondaire Ses méthodes peuvent produire des effets secondaires graves.
Le contrôle de flux est effectué à l'aide d'appels de fonction et d'appels de fonction avec récursivité Le contrôle de flux est effectué à l'aide de boucles et d'instructions conditionnelles.
Il utilise le concept de «récursion» pour itérer les données de collecte. Il utilise le concept de «boucle» pour itérer les données de collecte. Par exemple: boucle For-each en Java
L'ordre d'exécution des déclarations n'est pas si important. L'ordre d'exécution des déclarations est très important.
Prend en charge à la fois «l'abstraction sur les données» et «l'abstraction sur le comportement». Prend en charge uniquement "Abstraction sur les données".

Efficacité d'un code de programme

L'efficacité d'un code de programmation est directement proportionnelle à l'efficacité algorithmique et à la vitesse d'exécution. Une bonne efficacité garantit des performances plus élevées.

Les facteurs qui affectent l'efficacité d'un programme comprennent:

  • La vitesse de la machine
  • Vitesse du compilateur
  • Système opérateur
  • Choisir le bon langage de programmation
  • Le chemin des données dans un programme est organisé
  • Algorithme utilisé pour résoudre le problème

L'efficacité d'un langage de programmation peut être améliorée en effectuant les tâches suivantes -

  • En supprimant le code inutile ou le code qui va au traitement redondant.

  • En utilisant une mémoire optimale et un stockage non volatile

  • En utilisant des composants réutilisables le cas échéant.

  • En utilisant la gestion des erreurs et des exceptions à toutes les couches du programme.

  • En créant un code de programmation qui garantit l'intégrité et la cohérence des données.

  • En développant le code de programme conforme à la logique et au flux de conception.

Un code de programmation efficace peut réduire autant que possible la consommation de ressources et le temps d'exécution avec un risque minimal pour l'environnement d'exploitation.

En termes de programmation, un functionest un bloc d'instructions qui effectue une tâche spécifique. Les fonctions acceptent les données, les traitent et renvoient un résultat. Les fonctions sont écrites principalement pour prendre en charge le concept de réutilisabilité. Une fois qu'une fonction est écrite, elle peut être appelée facilement, sans avoir à écrire encore et encore le même code.

Différents langages fonctionnels utilisent une syntaxe différente pour écrire une fonction.

Prérequis pour écrire une fonction

Avant d'écrire une fonction, un programmeur doit connaître les points suivants -

  • Le but de la fonction doit être connu du programmeur.

  • L'algorithme de la fonction doit être connu du programmeur.

  • Les variables de données des fonctions et leur objectif doivent être connus du programmeur.

  • Les données de la fonction doivent être connues du programmeur appelé par l'utilisateur.

Contrôle de flux d'une fonction

Lorsqu'une fonction est "appelée", le programme "transfère" le contrôle pour exécuter la fonction et son "flux de contrôle" est comme ci-dessous -

  • Le programme atteint l'instruction contenant un "appel de fonction".

  • La première ligne à l'intérieur de la fonction est exécutée.

  • Toutes les instructions à l'intérieur de la fonction sont exécutées de haut en bas.

  • Lorsque la fonction est exécutée avec succès, le contrôle revient à l'instruction d'où il a commencé.

  • Toutes les données calculées et renvoyées par la fonction sont utilisées à la place de la fonction dans la ligne de code d'origine.

Syntaxe d'une fonction

La syntaxe générale d'une fonction se présente comme suit -

returnType functionName(type1 argument1, type2 argument2, . . . ) {     
   // function body 
}

Définition d'une fonction en C ++

Prenons un exemple pour comprendre comment une fonction peut être définie en C ++ qui est un langage de programmation orienté objet. Le code suivant a une fonction qui ajoute deux nombres et fournit son résultat comme sortie.

#include <stdio.h> 

int addNum(int a, int b);     // function prototype  

int main() {    
   int sum; 
   sum = addNum(5,6);         // function call 
   printf("sum = %d",sum); 
   return 0; 
}  
int addNum (int a,int b) {    // function definition      
   int result; 
   result = a + b; 
   return result;             // return statement 
}

Il produira la sortie suivante -

Sum = 11

Définition d'une fonction dans Erlang

Voyons comment la même fonction peut être définie dans Erlang, qui est un langage de programmation fonctionnel.

-module(helloworld).  
-export([add/2,start/0]).   

add(A,B) ->
   C = A + B,  
   io:fwrite("~w~n",[C]).  
start() ->  
   add(5,6).

Il produira la sortie suivante -

11

Prototype de fonction

Un prototype de fonction est une déclaration de la fonction qui inclut le type de retour, le nom de la fonction et la liste des arguments. C'est similaire à la définition de fonction sans corps de fonction.

For Example - Certains langages de programmation prennent en charge le prototypage de fonctions et certains ne le sont pas.

En C ++, nous pouvons créer un prototype de fonction de la fonction 'somme' comme ceci -

int sum(int a, int b)

Note - Les langages de programmation comme Python, Erlang, etc. ne prennent pas en charge le prototypage de fonction, nous devons déclarer la fonction complète.

À quoi sert le prototype de fonction?

Le prototype de fonction est utilisé par le compilateur lorsque la fonction est appelée. Le compilateur l'utilise pour s'assurer que le type de retour est correct, que la liste d'arguments appropriée est transmise et que leur type de retour est correct.

Signature de fonction

Une signature de fonction est similaire à un prototype de fonction dans lequel le nombre de paramètres, le type de données des paramètres et l'ordre d'apparition doivent être dans un ordre similaire. Par exemple -

void Sum(int a, int b, int c);         // function 1  
void Sum(float a, float b, float c);   // function 2  
void Sum(float a, float b, float c);   // function 3

Function1 et Function2 ont des signatures différentes. Function2 et Function3 ont les mêmes signatures.

Note - La surcharge de fonction et le remplacement de fonction dont nous parlerons dans les chapitres suivants sont basés sur le concept de signatures de fonction.

  • La surcharge de fonctions est possible lorsqu'une classe a plusieurs fonctions avec le même nom mais des signatures différentes.

  • Le remplacement de fonction est possible lorsqu'une fonction de classe dérivée a le même nom et la même signature que sa classe de base.

Les fonctions sont de deux types -

  • Fonctions prédéfinies
  • Fonctions définies par l'utilisateur

Dans ce chapitre, nous discuterons en détail des fonctions.

Fonctions prédéfinies

Ce sont les fonctions qui sont intégrées à Language pour effectuer des opérations et qui sont stockées dans la bibliothèque de fonctions standard.

For Example - 'Strcat' en C ++ et 'concat' en Haskell sont utilisés pour ajouter les deux chaînes, 'strlen' en C ++ et 'len' en Python sont utilisés pour calculer la longueur de la chaîne.

Programme pour imprimer la longueur de la chaîne en C ++

Le programme suivant montre comment vous pouvez imprimer la longueur d'une chaîne en utilisant C ++ -

#include <iostream> 
#include <string.h> 
#include <stdio.h> 
using namespace std;  

int main() {     
   char str[20] = "Hello World"; 
   int len; 
   len = strlen(str); 
   cout<<"String length is: "<<len; 
   return 0; 
}

Il produira la sortie suivante -

String length is: 11

Programme pour imprimer la longueur de la chaîne en Python

Le programme suivant montre comment imprimer la longueur d'une chaîne en utilisant Python, qui est un langage de programmation fonctionnel -

str = "Hello World"; 
print("String length is: ", len(str))

Il produira la sortie suivante -

('String length is: ', 11)

Fonctions définies par l'utilisateur

Les fonctions définies par l'utilisateur sont définies par l'utilisateur pour effectuer des tâches spécifiques. Il existe quatre modèles différents pour définir une fonction -

  • Fonctions sans argument et sans valeur de retour
  • Fonctions sans argument mais avec une valeur de retour
  • Fonctions avec argument mais sans valeur de retour
  • Fonctions avec argument et valeur de retour

Fonctions sans argument et sans valeur de retour

Le programme suivant montre comment définir une fonction sans argument et sans valeur de retour dans C++ -

#include <iostream> 
using namespace std; 

void function1() { 
   cout <<"Hello World"; 
}  
int main() { 
   function1(); 
   return 0; 
}

Il produira la sortie suivante -

Hello World

Le programme suivant montre comment définir une fonction similaire (sans argument ni valeur de retour) dans Python -

def function1():    
   print ("Hello World") 
    
function1()

Il produira la sortie suivante -

Hello World

Fonctions sans argument mais avec une valeur de retour

Le programme suivant montre comment définir une fonction sans argument mais avec une valeur de retour dans C++ -

#include <iostream> 
using namespace std; 
string function1() { 
   return("Hello World"); 
}  

int main() { 
   cout<<function1(); 
   return 0; 
}

Il produira la sortie suivante -

Hello World

Le programme suivant montre comment définir une fonction similaire (sans argument mais avec une valeur de retour) dans Python -

def function1(): 
   return "Hello World" 
res = function1() 
print(res)

Il produira la sortie suivante -

Hello World

Fonctions avec argument mais sans valeur de retour

Le programme suivant montre comment définir une fonction avec un argument mais pas de valeur de retour dans C++ -

#include <iostream> 
using namespace std; 
void function1(int x, int y) {    
   int c; 
   c = x+y;  
   cout<<"Sum is: "<<c; 
}  

int main() { 
   function1(4,5); 
   return 0; 
}

Il produira la sortie suivante -

Sum is: 9

Le programme suivant montre comment définir une fonction similaire dans Python -

def function1(x,y): 
   c = x + y 
   print("Sum is:",c) 
function1(4,5)

Il produira la sortie suivante -

('Sum is:', 9)

Fonctions avec argument et valeur de retour

Le programme suivant montre comment définir une fonction en C ++ sans argument mais avec une valeur de retour -

#include <iostream> 
using namespace std; 
int function1(int x, int y) {    
   int c; 
   c = x + y;  
   return c;    
} 

int main() {  
   int res; 
   res = function1(4,5); 
   cout<<"Sum is: "<<res; 
   return 0; 
}

Il produira la sortie suivante -

Sum is: 9

Le programme suivant montre comment définir une fonction similaire (avec un argument et une valeur de retour) dans Python -

def function1(x,y): 
   c = x + y 
   return c  

res = function1(4,5) 
print("Sum is ",res)

Il produira la sortie suivante -

('Sum is ', 9)

Après avoir défini une fonction, nous devons y passer des arguments pour obtenir la sortie souhaitée. La plupart des langages de programmation prennent en chargecall by value et call by reference méthodes pour passer des arguments dans des fonctions.

Dans ce chapitre, nous apprendrons les travaux d '«appel par valeur» dans un langage de programmation orienté objet comme C ++ et un langage de programmation fonctionnel comme Python.

Dans la méthode Call by Value, le original value cannot be changed. Lorsque nous passons un argument à une fonction, il est stocké localement par le paramètre de fonction dans la mémoire de la pile. Par conséquent, les valeurs sont modifiées uniquement à l'intérieur de la fonction et cela n'aura aucun effet en dehors de la fonction.

Appel par valeur en C ++

Le programme suivant montre comment l'appel par valeur fonctionne en C ++ -

#include <iostream> 
using namespace std; 

void swap(int a, int b) {    
   int temp; 
   temp = a; 
   a = b; 
   b = temp; 
   cout<<"\n"<<"value of a inside the function: "<<a; 
   cout<<"\n"<<"value of b inside the function: "<<b; 
}  
int main() {     
   int a = 50, b = 70;   
   cout<<"value of a before sending to function: "<<a; 
   cout<<"\n"<<"value of b before sending to function: "<<b; 
   swap(a, b);  // passing value to function 
   cout<<"\n"<<"value of a after sending to function: "<<a; 
   cout<<"\n"<<"value of b after sending to function: "<<b; 
   return 0;   
}

Il produira la sortie suivante -

value of a before sending to function:  50 
value of b before sending to function:  70 
value of a inside the function:  70 
value of b inside the function:  50 
value of a after sending to function:  50 
value of b after sending to function:  70

Appel par valeur en Python

Le programme suivant montre comment fonctionne Call by Value en Python -

def swap(a,b): 
   t = a; 
   a = b; 
   b = t; 
   print "value of a inside the function: :",a 
   print "value of b inside the function: ",b 

# Now we can call the swap function 
a = 50 
b = 75 
print "value of a before sending to function: ",a 
print "value of b before sending to function: ",b 
swap(a,b) 
print "value of a after sending to function: ", a 
print "value of b after sending to function: ",b

Il produira la sortie suivante -

value of a before sending to function:  50 
value of b before sending to function:  75 
value of a inside the function: : 75 
value of b inside the function:  50 
value of a after sending to function:  50 
value of b after sending to function:  75

Dans Call by Reference, le original value is changedcar nous passons l'adresse de référence des arguments. Les arguments réels et formels partagent le même espace d'adressage, de sorte que tout changement de valeur à l'intérieur de la fonction est reflété à l'intérieur comme à l'extérieur de la fonction.

Appel par référence en C ++

Le programme suivant montre comment l'appel par valeur fonctionne en C ++ -

#include <iostream> 
using namespace std; 

void swap(int *a, int *b) {    
   int temp; 
   temp = *a; 
   *a = *b; 
   *b = temp; 
   cout<<"\n"<<"value of a inside the function: "<<*a; 
   cout<<"\n"<<"value of b inside the function: "<<*b; 
}  
int main() {     
   int a = 50, b = 75;   
   cout<<"\n"<<"value of a before sending to function: "<<a; 
   cout<<"\n"<<"value of b before sending to function: "<<b; 
   swap(&a, &b);  // passing value to function 
   cout<<"\n"<<"value of a after sending to function: "<<a; 
   cout<<"\n"<<"value of b after sending to function: "<<b; 
   return 0;   
}

Il produira la sortie suivante -

value of a before sending to function:  50 
value of b before sending to function:  75 
value of a inside the function:  75 
value of b inside the function: 50 
value of a after sending to function:  75 
value of b after sending to function:  50

Appel par référence en Python

Le programme suivant montre comment fonctionne Call by Value en Python -

def swap(a,b): 
   t = a; 
   a = b; 
   b = t; 
   print "value of a inside the function: :",a 
   print "value of b inside the function: ",b 
   return(a,b) 
    
# Now we can call swap function 
a = 50 
b =75 
print "value of a before sending to function: ",a 
print "value of b before sending to function: ",b 
x = swap(a,b) 
print "value of a after sending to function: ", x[0] 
print "value of b after sending to function: ",x[1]

Il produira la sortie suivante -

value of a before sending to function:  50 
value of b before sending to function:  75 
value of a inside the function:  75 
value of b inside the function:  50 
value of a after sending to function:  75 
value of b after sending to function:  50

Lorsque nous avons plusieurs fonctions avec le même nom mais des paramètres différents, on dit alors qu'elles sont surchargées. Cette technique est utilisée pour améliorer la lisibilité du programme.

Il existe deux façons de surcharger une fonction, c'est-à-dire -

  • Avoir un nombre d'arguments différent
  • Avoir différents types d'arguments

La surcharge de fonction est normalement effectuée lorsque nous devons effectuer une seule opération avec un nombre ou des types d'arguments différents.

Surcharge de fonction en C ++

L'exemple suivant montre comment la surcharge de fonctions est effectuée en C ++, qui est un langage de programmation orienté objet -

#include <iostream> 
using namespace std;  
void addnum(int,int); 
void addnum(int,int,int); 

int main() {     
   addnum (5,5); 
   addnum (5,2,8); 
   return 0; 
} 

void addnum (int x, int y) {     
   cout<<"Integer number: "<<x+y<<endl; 
} 

void addnum (int x, int y, int z) {     
   cout<<"Float number: "<<x+y+z<<endl; 
}

Il produira la sortie suivante -

Integer number: 10 
Float number: 15

Surcharge de fonction à Erlang

L'exemple suivant montre comment effectuer une surcharge de fonction dans Erlang, qui est un langage de programmation fonctionnel -

-module(helloworld).  
-export([addnum/2,addnum/3,start/0]).   

addnum(X,Y) ->  
   Z = X+Y,  
   io:fwrite("~w~n",[Z]).  
    
addnum(X,Y,Z) ->  
   A = X+Y+Z,  
   io:fwrite("~w~n",[A]).  
  
start() ->
   addnum(5,5),     addnum(5,2,8).

Il produira la sortie suivante -

10 
15

Lorsque la classe de base et la classe dérivée ont des fonctions membres avec exactement le même nom, le même type de retour et la même liste d'arguments, on dit alors qu'il s'agit d'un remplacement de fonction.

Remplacement de fonction à l'aide de C ++

L'exemple suivant montre comment le remplacement de fonction est effectué en C ++, qui est un langage de programmation orienté objet -

#include <iostream> 
using namespace std;  

class A {  
   public: 
   void display() {   
      cout<<"Base class"; 
   } 
}; 

class B:public A {  
   public: 
   void display() {   
      cout<<"Derived Class"; 
   } 
}; 

int main() {  
   B obj; 
   obj.display(); 
   return 0;  
}

Il produira la sortie suivante

Derived Class

Remplacement de fonction à l'aide de Python

L'exemple suivant montre comment effectuer un remplacement de fonction en Python, qui est un langage de programmation fonctionnel -

class A(object): 
   def disp(self): 
      print "Base Class"  
class B(A): 
   def disp(self): 
      print "Derived Class"  
x = A() 
y = B()  
x.disp() 
y.disp()

Il produira la sortie suivante -

Base Class 
Derived Class

Une fonction qui s'appelle elle-même est appelée fonction récursive et cette technique est appelée récursivité. Une instruction de récursivité continue jusqu'à ce qu'une autre instruction l'empêche.

Récursivité en C ++

L'exemple suivant montre comment la récursivité fonctionne en C ++, qui est un langage de programmation orienté objet -

#include <stdio.h> 
long int fact(int n);  

int main() { 
   int n; 
   printf("Enter a positive integer: "); 
   scanf("%d", &n); 
   printf("Factorial of %d = %ld", n, fact(n)); 
   return 0; 
} 
long int fact(int n) { 
   if (n >= 1) 
      return n*fact(n-1); 
   else 
      return 1; 
}

Il produira la sortie suivante

Enter a positive integer: 5 
Factorial of 5 = 120

Récursivité en Python

L'exemple suivant montre comment fonctionne la récursivité en Python, qui est un langage de programmation fonctionnel -

def fact(n): 
   if n == 1: 
      return n 
   else: 
      return n* fact (n-1)  

# accepts input from user 
num = int(input("Enter a number: "))  
# check whether number is positive or not 

if num < 0: 
   print("Sorry, factorial does not exist for negative numbers") 
else: 
   print("The factorial of " + str(num) +  " is " + str(fact(num)))

Il produira la sortie suivante -

Enter a number: 6
The factorial of 6 is 720

Une fonction d'ordre supérieur (HOF) est une fonction qui suit au moins l'une des conditions suivantes -

  • Prend une ou plusieurs fonctions comme argument
  • Renvoie une fonction comme résultat

HOF en PHP

L'exemple suivant montre comment écrire une fonction d'ordre supérieur en PHP, qui est un langage de programmation orienté objet -

<?php  
$twice = function($f, $v) { return $f($f($v)); 
};  

$f = function($v) { 
   return $v + 3; }; echo($twice($f, 7));

Il produira la sortie suivante -

13

HOF en Python

L'exemple suivant montre comment écrire une fonction d'ordre supérieur en Python, qui est un langage de programmation orienté objet -

def twice(function): 
   return lambda x: function(function(x))  
def f(x): 
   return x + 3 
g = twice(f)
print g(7)

Il produira la sortie suivante -

13

Un type de données définit le type de valeur qu'un objet peut avoir et les opérations qui peuvent y être effectuées. Un type de données doit être déclaré avant d'être utilisé. Différents langages de programmation prennent en charge différents types de données. Par exemple,

  • C prend en charge char, int, float, long, etc.
  • Python prend en charge String, List, Tuple, etc.

Au sens large, il existe trois types de types de données -

  • Fundamental data types- Ce sont les types de données prédéfinis qui sont utilisés directement par le programmeur pour stocker une seule valeur selon l'exigence, c'est-à-dire le type entier, le type caractère ou le type flottant. Par exemple - int, char, float, etc.

  • Derived data types- Ces types de données sont dérivés à l'aide d'un type de données intégré conçu par le programmeur pour stocker plusieurs valeurs du même type selon leurs besoins. Par exemple: tableau, pointeur, fonction, liste, etc.

  • User-defined data types- Ces types de données sont dérivés à l'aide de types de données intégrés qui sont enveloppés dans un seul type de données pour stocker plusieurs valeurs du même type ou d'un type différent ou les deux selon l'exigence. Par exemple - Classe, Structure, etc.

Types de données pris en charge par C ++

Le tableau suivant répertorie les types de données pris en charge par C ++ -

Type de données Taille Intervalle
carboniser 1 octet -128 à 127 ou 0 à 255
caractère non signé 1 octet 0 à 255
char signé 1 octet -128 à 127
int 4 octets -2147483648 à 2147483647
int non signé 4 octets 0 à 4294967295
signé int 4 octets -2147483648 à 2147483647
int court 2 octets -32768 à 32767
int court non signé 2 octets 0 à 65 535
signé court int 2 octets -32768 à 32767
long int 4 octets -2 147 483 648 à 2 147 483 647
signé long int 4 octets -2 147 483 648 à 2 147 483 647
entier long non signé 4 octets 0 à 4 294 967 295
flotte 4 octets +/- 3,4e +/- 38 (~ 7 chiffres)
double 8 octets +/- 1,7e +/- 308 (~ 15 chiffres)
long double 8 octets +/- 1,7e +/- 308 (~ 15 chiffres)

Types de données pris en charge par Java

Les types de données suivants sont pris en charge par Java -

Type de données Taille Intervalle
octet 1 octet -128 à 127
carboniser 2 octets 0 à 65 536
court 2 octets -32.7688 à 32.767
int 4 octets -2 147 483 648 à 2 147 483 647
longue 8 octets -9,223,372,036,854,775,808 à 9,223,372,036,854,775,807
flotte 4 octets -2147483648 à 2147483647
double 8 octets + 9,223 * 1018
Booléen 1 bit Vrai ou faux

Types de données pris en charge par Erlang

Dans cette section, nous discuterons des types de données pris en charge par Erlang, qui est un langage de programmation fonctionnel.

Nombre

Erlang prend en charge deux types de littéraux numériques, à savoir integer et float. Jetez un œil à l'exemple suivant qui montre comment ajouter deux valeurs entières -

-module(helloworld).
-export([start/0]). 
start() -> 
   io:fwrite("~w",[5+4]).

Il produira la sortie suivante -

9

Atome

Un atomest une chaîne dont la valeur ne peut pas être modifiée. Il doit commencer par une lettre minuscule et peut contenir des caractères alphanumériques et des caractères spéciaux. Lorsqu'un atome contient des caractères spéciaux, il doit être placé entre guillemets simples ('). Jetez un œil à l'exemple suivant pour mieux comprendre.

-module(helloworld). 
-export([start/0]). 

start()-> 
   io:fwrite(monday).

Il produira la sortie suivante -

monday

Note- Essayez de changer l'atome en "Lundi" avec un "M" majuscule. Le programme produira une erreur.

Booléen

Ce type de données est utilisé pour afficher le résultat soit true ou false. Jetez un œil à l'exemple suivant. Il montre comment comparer deux entiers.

-module(helloworld). 
-export([start/0]). 

start() -> 
   io:fwrite(5 =< 9).

Il produira la sortie suivante -

true

Chaîne de bits

Une chaîne de bits est utilisée pour stocker une zone de mémoire non typée. Jetez un œil à l'exemple suivant. Il montre comment convertir 2 bits d'une chaîne de bits en une liste.

-module(helloworld). 
-export([start/0]). 

start() -> 
   Bin2 = <<15,25>>, 
   P = binary_to_list(Bin2), 
   io:fwrite("~w",[P]).

Il produira la sortie suivante -

[15,25]

Tuple

Un tuple est un type de données composé ayant un nombre fixe de termes. Chaque terme d'un tuple est appeléelement. Le nombre d'éléments correspond à la taille du tuple. L'exemple suivant montre comment définir un tuple de 5 termes et imprime sa taille.

-module(helloworld).  
-export([start/0]).  

start() ->  
   K = {abc,50,pqr,60,{xyz,75}} ,  
   io:fwrite("~w",[tuple_size(K)]).

Il produira la sortie suivante -

5

Carte

Une carte est un type de données composé avec un nombre variable d'associations clé-valeur. Chaque association clé-valeur de la carte est appeléeassociation-pair. lekey et value les parties de la paire sont appelées elements. On dit que le nombre de paires d'associations est la taille de la carte. L'exemple suivant montre comment définir une carte de 3 mappages et imprimer sa taille.

-module(helloworld).  
-export([start/0]).  
 
start() ->  
   Map1 = #{name => 'abc',age => 40, gender => 'M'},  
   io:fwrite("~w",[map_size(Map1)]).

Il produira la sortie suivante -

3

liste

Une liste est un type de données composé ayant un nombre variable de termes. Chaque terme de la liste est appelé un élément. On dit que le nombre d'éléments est la longueur de la liste. L'exemple suivant montre comment définir une liste de 5 éléments et imprimer sa taille.

-module(helloworld).  
-export([start/0]).  

start() ->  
   List1 = [10,15,20,25,30] ,  
   io:fwrite("~w",[length(List1)]).

Il produira la sortie suivante -

5

Note - Le type de données 'String' n'est pas défini dans Erlang.

Le polymorphisme, en termes de programmation, signifie réutiliser plusieurs fois un même code. Plus précisément, c'est la capacité d'un programme à traiter les objets différemment selon leur type de données ou leur classe.

Le polymorphisme est de deux types -

  • Compile-time Polymorphism - Ce type de polymorphisme peut être réalisé en utilisant la surcharge de méthode.

  • Run-time Polymorphism - Ce type de polymorphisme peut être obtenu en utilisant la substitution de méthode et des fonctions virtuelles.

Avantages du polymorphisme

Le polymorphisme offre les avantages suivants -

  • Il aide le programmeur à réutiliser les codes, c'est-à-dire que les classes une fois écrites, testées et implémentées peuvent être réutilisées selon les besoins. Gain de temps.

  • Une seule variable peut être utilisée pour stocker plusieurs types de données.

  • Facile à déboguer les codes.

Types de données polymorphes

Les types de données polymorphes peuvent être implémentés à l'aide de pointeurs génériques qui stockent une adresse d'octet uniquement, sans le type de données stockées à cette adresse mémoire. Par exemple,

function1(void *p, void *q)

p et q sont des pointeurs génériques qui peuvent contenir int, float (ou toute autre) valeur comme argument.

Fonction polymorphe en C ++

Le programme suivant montre comment utiliser les fonctions polymorphes en C ++, qui est un langage de programmation orienté objet.

#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; 
}

Il produira la sortie suivante -

A class method is called 
B class method is called

Fonction polymorphe en Python

Le programme suivant montre comment utiliser les fonctions polymorphes en Python, qui est un langage de programmation fonctionnel.

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 checkmethod(clasmethod): 
   clasmethod.show()  

AObj = A() 
BObj = B() 
  
checkmethod(AObj) 
checkmethod(BObj)

Il produira la sortie suivante -

A class method is called 
B class method is called

UNE stringest un groupe de caractères comprenant des espaces. Nous pouvons dire que c'est un tableau unidimensionnel de caractères qui se termine par un caractère NULL ('\ 0'). Une chaîne peut également être considérée comme une classe prédéfinie qui est prise en charge par la plupart des langages de programmation tels que C, C ++, Java, PHP, Erlang, Haskell, Lisp, etc.

L'image suivante montre à quoi ressemblera la chaîne "Tutorial" dans la mémoire.

Créer une chaîne en C ++

Le programme suivant est un exemple qui montre comment créer une chaîne en C ++, qui est un langage de programmation orienté objet.

#include <iostream> 
using namespace std; 

int main () {    
   char greeting[20] = {'H', 'o', 'l', 'i', 'd', 'a', 'y', '\0'}; 
   cout << "Today is: "; 
   cout << greeting << endl; 
   return 0; 
}

Il produira la sortie suivante -

Today is: Holiday

Chaîne à Erlang

Le programme suivant est un exemple qui montre comment créer une chaîne dans Erlang, qui est un langage de programmation fonctionnel.

-module(helloworld).  
-export([start/0]).   
start() -> 
   Str = "Today is: Holiday",  
   io:fwrite("~p~n",[Str]).

Il produira la sortie suivante -

"Today is: Holiday"

Opérations de chaîne en C ++

Différents langages de programmation prennent en charge différentes méthodes sur les chaînes. Le tableau suivant présente quelques méthodes de chaîne prédéfinies prises en charge par C ++.

S.No. Méthode et description
1

Strcpy(s1,s2)

Il copie la chaîne s2 dans la chaîne s1

2

Strcat(s1,s2)

Il ajoute la chaîne s2 à la fin de s1

3

Strlen(s1)

Il fournit la longueur de la chaîne s1

4

Strcmp(s1,s2)

Il renvoie 0 lorsque les chaînes s1 et s2 sont identiques

5

Strchr(s1,ch)

Il renvoie un pointeur vers la première occurrence du caractère ch dans la chaîne s1

6

Strstr(s1,s2)

Il renvoie un pointeur vers la première occurrence de la chaîne s2 dans la chaîne s1

Le programme suivant montre comment les méthodes ci-dessus peuvent être utilisées en C ++ -

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

int main () {   
   char str1[20] = "Today is "; 
   char str2[20] = "Monday"; 
   char str3[20]; 
   int  len ;  
   strcpy( str3, str1); // copy str1 into str3 
   cout << "strcpy( str3, str1) : " << str3 << endl;  

   strcat( str1, str2); // concatenates str1 and str2 
   cout << "strcat( str1, str2): " << str1 << endl;  

   len = strlen(str1);  // String length after concatenation 
   cout << "strlen(str1) : " << len << endl; 
   return 0; 
}

Il produira la sortie suivante -

strcpy(str3, str1)   :  Today is 
strcat(str1, str2)   :  Today is Monday 
strlen(str1)         :  15

Opérations de chaîne à Erlang

Le tableau suivant présente une liste des méthodes de chaîne prédéfinies prises en charge par Erlang.

S.No. Méthode et description
1

len(s1)

Renvoie le nombre de caractères dans la chaîne donnée.

2

equal(s1,s2)

Il renvoie true lorsque les chaînes s1 et s2 sont égales sinon retournent false

3

concat(s1,s2)

Il ajoute la chaîne s2 à la fin de la chaîne s1

4

str(s1,ch)

Il renvoie la position d'index du caractère ch dans la chaîne s1

5

str (s1,s2)

Il renvoie la position d'index de s2 dans la chaîne s1

6

substr(s1,s2,num)

Cette méthode renvoie la chaîne s2 à partir de la chaîne s1 en fonction de la position de départ et du nombre de caractères à partir de la position de départ

sept

to_lower(s1)

Cette méthode renvoie la chaîne en minuscules

Le programme suivant montre comment les méthodes ci-dessus peuvent être utilisées dans Erlang.

-module(helloworld).  
-import(string,[concat/2]).  
-export([start/0]).  
   start() ->  
   S1 = "Today is ",  
   S2 = "Monday",  
   S3 = concat(S1,S2),  
   io:fwrite("~p~n",[S3]).

Il produira la sortie suivante -

"Today is Monday"

Listest le type de données le plus polyvalent disponible dans les langages de programmation fonctionnelle utilisés pour stocker une collection d'éléments de données similaires. Le concept est similaire aux tableaux dans la programmation orientée objet. Les éléments de liste peuvent être écrits entre crochets séparés par des virgules. La manière d'écrire des données dans une liste varie d'une langue à l'autre.

Programme pour créer une liste de nombres en Java

List n'est pas un type de données en Java / C / C ++, mais nous avons d'autres moyens de créer une liste en Java, c'est-à-dire en utilisant ArrayList et LinkedList.

L'exemple suivant montre comment créer une liste en Java. Ici, nous utilisons une méthode de liste liée pour créer une liste de nombres.

import java.util.*; 
import java.lang.*; 
import java.io.*;  

/* Name of the class has to be "Main" only if the class is public. */ 

public class HelloWorld { 
   public static void main (String[] args) throws java.lang.Exception { 
      List<String> listStrings = new LinkedList<String>(); 
      listStrings.add("1"); 
      listStrings.add("2"); 
      listStrings.add("3"); 
      listStrings.add("4"); 
      listStrings.add("5"); 
  
      System.out.println(listStrings); 
   } 
}

Il produira la sortie suivante -

[1, 2, 3, 4, 5]

Programme pour créer une liste de nombres à Erlang

-module(helloworld).  
-export([start/0]).   

start() ->  
   Lst = [1,2,3,4,5],  
   io:fwrite("~w~n",[Lst]).

Il produira la sortie suivante -

[1 2 3 4 5]

Lister les opérations en Java

Dans cette section, nous discuterons de certaines opérations qui peuvent être effectuées sur des listes en Java.

Ajout d'éléments dans une liste

Les méthodes add (Object), add (index, Object), addAll () sont utilisées pour ajouter des éléments dans une liste. Par exemple,

ListStrings.add(3, “three”)

Suppression d'éléments d'une liste

Les méthodes remove (index) ou removeobject () sont utilisées pour supprimer des éléments d'une liste. Par exemple,

ListStrings.remove(3,”three”)

Note - Pour supprimer tous les éléments de la liste, la méthode clear () est utilisée.

Récupérer des éléments d'une liste

La méthode get () est utilisée pour récupérer des éléments d'une liste à un emplacement spécifié. Les méthodes getfirst () et getlast () peuvent être utilisées dans la classe LinkedList. Par exemple,

String str = ListStrings.get(2)

Mettre à jour des éléments dans une liste

La méthode set (index, element) est utilisée pour mettre à jour un élément à un index spécifié avec un élément spécifié. Par exemple,

listStrings.set(2,”to”)

Tri des éléments dans une liste

Les méthodes collection.sort () et collection.reverse () sont utilisées pour trier une liste par ordre croissant ou décroissant. Par exemple,

Collection.sort(listStrings)

Recherche d'éléments dans une liste

Les trois méthodes suivantes sont utilisées conformément à l'exigence -

Boolean contains(Object) retour de la méthode true si la liste contient l'élément spécifié, sinon elle retourne false.

int indexOf(Object) La méthode retourne l'index de la première occurrence d'un élément spécifié dans une liste, sinon elle retourne -1 lorsque l'élément n'est pas trouvé.

int lastIndexOf(Object) renvoie l'index de la dernière occurrence d'un élément spécifié dans une liste, sinon il retourne -1 lorsque l'élément n'est pas trouvé.

Liste des opérations à Erlang

Dans cette section, nous discuterons de certaines opérations qui peuvent être effectuées sur des listes dans Erlang.

Ajout de deux listes

La méthode append (listfirst, listsecond) est utilisée pour créer une nouvelle liste en ajoutant deux listes. Par exemple,

append(list1,list2)

Supprimer un élément

La méthode delete (element, listname) est utilisée pour supprimer l'élément spécifié de la liste et elle renvoie la nouvelle liste. Par exemple,

delete(5,list1)

Supprimer le dernier élément de la liste

La méthode droplast (listname) est utilisée pour supprimer le dernier élément d'une liste et renvoyer une nouvelle liste. Par exemple,

droplast(list1)

Recherche d'un élément

La méthode member (element, listname) est utilisée pour rechercher l'élément dans la liste, si elle est trouvée, elle retourne true sinon elle retourne false. Par exemple,

member(5,list1)

Obtenir la valeur maximale et minimale

Les méthodes max (listname) et min (listname) sont utilisées pour trouver les valeurs maximum et minimum dans une liste. Par exemple,

max(list1)

Tri des éléments de la liste

Les méthodes sort (listname) et reverse (listname) sont utilisées pour trier une liste par ordre croissant ou décroissant. Par exemple,

sort(list1)

Ajout d'éléments de liste

La méthode sum (listname) est utilisée pour ajouter tous les éléments d'une liste et retourner leur somme. Par exemple,

sum(list1)

Trier une liste par ordre croissant et décroissant à l'aide de Java

Le programme suivant montre comment trier une liste par ordre croissant et décroissant à l'aide de Java -

import java.util.*; 
import java.lang.*; 
import java.io.*;  

public class SortList { 
   public static void main (String[] args) throws java.lang.Exception { 
      List<String> list1 = new ArrayList<String>(); 
      list1.add("5"); 
      list1.add("3"); 
      list1.add("1"); 
      list1.add("4"); 
      list1.add("2"); 
  
      System.out.println("list before sorting: " + list1); 
  
      Collections.sort(list1); 
  
      System.out.println("list in ascending order: " + list1); 
      Collections.reverse(list1); 
  
      System.out.println("list in dsending order: " + list1); 
   } 
}

Il produira la sortie suivante -

list before sorting     : [5, 3, 1, 4, 2] 
list in ascending order : [1, 2, 3, 4, 5] 
list in dsending order  : [5, 4, 3, 2, 1]

Trier une liste par ordre croissant en utilisant Erlang

Le programme suivant montre comment trier une liste par ordre croissant et décroissant en utilisant Erlang, qui est un langage de programmation fonctionnel -

-module(helloworld).  
-import(lists,[sort/1]).  
-export([start/0]).   

start() ->  
   List1 = [5,3,4,2,1],  
   io:fwrite("~p~n",[sort(List1)]),

Il produira la sortie suivante -

[1,2,3,4,5]

Un tuple est un type de données composé ayant un nombre fixe de termes. Chaque terme d'un tuple est appeléelement. Le nombre d'éléments correspond à la taille du tuple.

Programme pour définir un tuple en C #

Le programme suivant montre comment définir un tuple de quatre termes et les imprimer en utilisant C #, qui est un langage de programmation orienté objet.

using System; 
public class Test { 
   public static void Main() { 
      var t1 = Tuple.Create(1, 2, 3, new Tuple<int, int>(4, 5));   
      Console.WriteLine("Tuple:" + t1);    
   } 
}

Il produira la sortie suivante -

Tuple :(1, 2, 3, (4, 5))

Programme pour définir un tuple dans Erlang

Le programme suivant montre comment définir un tuple de quatre termes et les imprimer à l'aide d'Erlang, qui est un langage de programmation fonctionnel.

-module(helloworld).  
-export([start/0]).   

start() -> 
   P = {1,2,3,{4,5}} ,  
   io:fwrite("~w",[P]).

Il produira la sortie suivante -

{1, 2, 3, {4, 5}}

Avantages de Tuple

Les tuples offrent les avantages suivants -

  • Les tuples sont par nature de taille fine, c'est-à-dire que nous ne pouvons pas ajouter / supprimer des éléments à / d'un tuple.

  • Nous pouvons rechercher n'importe quel élément dans un tuple.

  • Les tuples sont plus rapides que les listes, car ils ont un ensemble constant de valeurs.

  • Les tuples peuvent être utilisés comme clés de dictionnaire, car ils contiennent des valeurs immuables telles que des chaînes, des nombres, etc.

Tuples vs listes

Tuple liste
Les tuples sont immutable, c'est-à-dire que nous ne pouvons pas mettre à jour ses données. Liste sont mutable, c'est-à-dire que nous pouvons mettre à jour ses données.
Les éléments d'un tuple peuvent être de type différent. Tous les éléments d'une liste sont du même type.
Les tuples sont indiqués par des parenthèses rondes autour des éléments. Les listes sont indiquées par des crochets autour des éléments.

Opérations sur les tuples

Dans cette section, nous allons discuter de quelques opérations qui peuvent être effectuées sur un tuple.

Vérifiez si une valeur insérée est un Tuple ou non

La méthode is_tuple(tuplevalues)est utilisé pour déterminer si une valeur insérée est un tuple ou non. Il retournetrue lorsqu'une valeur insérée est un tuple, sinon elle retourne false. Par exemple,

-module(helloworld).  
-export([start/0]).  

start() ->  
   K = {abc,50,pqr,60,{xyz,75}} , io:fwrite("~w",[is_tuple(K)]).

Il produira la sortie suivante -

True

Conversion d'une liste en tuple

La méthode list_to_tuple(listvalues)convertit une liste en un tuple. Par exemple,

-module(helloworld).  
-export([start/0]).  

start() ->  
   io:fwrite("~w",[list_to_tuple([1,2,3,4,5])]).

Il produira la sortie suivante -

{1, 2, 3, 4, 5}

Conversion d'un tuple en liste

La méthode tuple_to_list(tuplevalues)convertit un tuple spécifié au format de liste. Par exemple,

-module(helloworld).  
-export([start/0]).  

start() ->  
   io:fwrite("~w",[tuple_to_list({1,2,3,4,5})]).

Il produira la sortie suivante -

[1, 2, 3, 4, 5]

Vérifier la taille du tuple

La méthode tuple_size(tuplename)renvoie la taille d'un tuple. Par exemple,

-module(helloworld).  
-export([start/0]).  

start() ->  
   K = {abc,50,pqr,60,{xyz,75}} ,  
   io:fwrite("~w",[tuple_size(K)]).

Il produira la sortie suivante -

5

Un enregistrement est une structure de données permettant de stocker un nombre fixe d'éléments. C'est similaire à une structure en langage C. Au moment de la compilation, ses expressions sont traduites en expressions de tuple.

Comment créer un enregistrement?

Le mot-clé «enregistrement» est utilisé pour créer des enregistrements spécifiés avec le nom de l'enregistrement et ses champs. Sa syntaxe est la suivante -

record(recodname, {field1, field2, . . fieldn})

La syntaxe pour insérer des valeurs dans l'enregistrement est -

#recordname {fieldName1 = value1, fieldName2 = value2 .. fieldNamen = valuen}

Programme pour créer des enregistrements en utilisant Erlang

Dans l'exemple suivant, nous avons créé un enregistrement de nom student ayant deux champs, à savoir, sname et sid.

-module(helloworld).  
-export([start/0]).  
-record(student, {sname = "", sid}).   

start() ->  
   S = #student{sname = "Sachin",sid = 5}.

Programme pour créer des enregistrements en C ++

L'exemple suivant montre comment créer des enregistrements à l'aide de C ++, qui est un langage de programmation orienté objet -

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

class student {
   public: 
   string sname; 
   int sid; 
   15 
}; 

int main() {    
   student S;  
   S.sname = "Sachin"; 
   S.sid = 5; 
   return 0;  
}

Programme pour accéder aux valeurs d'enregistrement en utilisant Erlang

Le programme suivant montre comment accéder aux valeurs d'enregistrement en utilisant Erlang, qui est un langage de programmation fonctionnel -

-module(helloworld).  
-export([start/0]).  
-record(student, {sname = "", sid}).   

start() ->  
   S = #student{sname = "Sachin",sid = 5},  
   io:fwrite("~p~n",[S#student.sid]),  
   io:fwrite("~p~n",[S#student.sname]).

Il produira la sortie suivante -

5 
"Sachin"

Programme pour accéder aux valeurs d'enregistrement en utilisant C ++

Le programme suivant montre comment accéder aux valeurs d'enregistrement à l'aide de C ++ -

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

class student {     
   public: 
   string sname; 
   int sid; 
}; 

int main() {     
   student S;  
   S.sname = "Sachin"; 
   S.sid = 5; 
   cout<<S.sid<<"\n"<<S.sname;  
   return 0; 
}

Il produira la sortie suivante -

5 
Sachin

Les valeurs d'enregistrement peuvent être mises à jour en modifiant la valeur dans un champ particulier, puis en affectant cet enregistrement à un nouveau nom de variable. Jetez un œil aux deux exemples suivants pour comprendre comment cela est fait à l'aide de langages de programmation orientés objet et fonctionnels.

Programme pour mettre à jour les valeurs d'enregistrement en utilisant Erlang

Le programme suivant montre comment mettre à jour les valeurs d'enregistrement à l'aide d'Erlang -

-module(helloworld).  
-export([start/0]).  
-record(student, {sname = "", sid}).   

start() ->  
   S = #student{sname = "Sachin",sid = 5},  
   S1 = S#student{sname = "Jonny"},  
   io:fwrite("~p~n",[S1#student.sid]),  
   io:fwrite("~p~n",[S1#student.sname]).

Il produira la sortie suivante -

5
"Jonny"

Programme pour mettre à jour les valeurs d'enregistrement en utilisant C ++

Le programme suivant montre comment mettre à jour les valeurs d'enregistrement à l'aide de C ++ -

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

class student {    
   public: 
   string sname; 
   int sid; 
};  

int main() {     
   student S;  
   S.sname = "Jonny"; 
   S.sid = 5; 
   cout<<S.sname<<"\n"<<S.sid; 
   cout<<"\n"<< "value after updating"<<"\n"; 
   S.sid = 10; 
   cout<<S.sname<<"\n"<<S.sid; 
   return 0; 
}

Il produira la sortie suivante -

Jonny 
5 
value after updating 
Jonny 
10

Le calcul lambda est un cadre développé par Alonzo Church dans les années 1930 pour étudier les calculs avec des fonctions.

  • Function creation - L'Église a introduit la notation λx.Epour désigner une fonction dans laquelle «x» est un argument formel et «E» est le corps fonctionnel. Ces fonctions peuvent être sans noms et sans arguments.

  • Function application - Church a utilisé la notation E1.E2 pour désigner l'application de la fonction E1 à l'argument réel E2. Et toutes les fonctions sont sur un seul argument.

Syntaxe de Lambda Calculus

Le calcul Lamdba comprend trois types d'expressions différents, à savoir,

E :: = x (variables)

| E 1 E 2 (application de fonction)

| λx.E (création de fonction)

λx.E est appelée abstraction Lambda et E est appelée expressions λ.

Évaluation du calcul Lambda

Le calcul lambda pur n'a pas de fonctions intégrées. Évaluons l'expression suivante -

(+ (* 5 6) (* 8 3))

Ici, on ne peut pas commencer par «+» car il ne fonctionne que sur les nombres. Il existe deux expressions réductibles: (* 5 6) et (* 8 3).

Nous pouvons d'abord réduire l'un ou l'autre. Par exemple -

(+ (* 5 6) (* 8 3)) 
(+ 30 (* 8 3)) 
(+ 30 24) 
= 54

Règle de β-réduction

Nous avons besoin d'une règle de réduction pour gérer les λs

(λx . * 2 x) 4 
(* 2 4) 
= 8

C'est ce qu'on appelle la β-réduction.

Le paramètre formel peut être utilisé plusieurs fois -

(λx . + x x) 4 
(+ 4 4) 
= 8

Lorsqu'il y a plusieurs termes, nous pouvons les gérer comme suit -

(λx . (λx . + (− x 1)) x 3) 9

L'intérieur x appartient à l'intérieur λ et le x extérieur appartient au x extérieur.

(λx . + (− x 1)) 9 3 
+ (− 9 1) 3 
+ 8 3 
= 11

Variables libres et liées

Dans une expression, chaque apparence d'une variable est soit "libre" (à λ), soit "liée" (à un λ).

β-réduction de (λx . E) y remplace chaque x qui se produit gratuitement dans E avec y. Par exemple -

Réduction alpha

La réduction alpha est très simple et peut être effectuée sans changer la signification d'une expression lambda.

λx . (λx . x) (+ 1 x) ↔ α λx . (λy . y) (+ 1 x)

Par exemple -

(λx . (λx . + (− x 1)) x 3) 9 
(λx . (λy . + (− y 1)) x 3) 9 
(λy . + (− y 1)) 9 3 
+ (− 9 1) 3 
+ 8 3 
11

Théorème de Church-Rosser

Le théorème de Church-Rosser déclare ce qui suit:

  • Si E1 ↔ E2, alors il existe un E tel que E1 → E et E2 → E. «Une réduction de quelque manière que ce soit peut finalement produire le même résultat.»

  • Si E1 → E2, et E2 est de forme normale, alors il y a une réduction d'ordre normal de E1 en E2. "La réduction d'ordre normal produira toujours une forme normale, s'il en existe une."

L'évaluation paresseuse est une stratégie d'évaluation qui contient l'évaluation d'une expression jusqu'à ce que sa valeur soit nécessaire. Cela évite les évaluations répétées.Haskell est un bon exemple d'un tel langage de programmation fonctionnel dont les fondamentaux sont basés sur Lazy Evaluation.

L'évaluation paresseuse est utilisée dans les fonctions de carte Unix pour améliorer leurs performances en ne chargeant que les pages requises à partir du disque. Aucune mémoire ne sera allouée pour les pages restantes.

Évaluation paresseuse - Avantages

  • Il permet au moteur d'exécution du langage de supprimer les sous-expressions qui ne sont pas directement liées au résultat final de l'expression.

  • Il réduit la complexité temporelle d'un algorithme en supprimant les calculs temporaires et les conditions.

  • Il permet au programmeur d'accéder aux composants des structures de données dans le désordre après leur initialisation, à condition qu'ils soient libres de toute dépendance circulaire.

  • Il est le mieux adapté pour charger des données qui seront rarement consultées.

Évaluation paresseuse - inconvénients

  • Il force le moteur d'exécution du langage à tenir l'évaluation des sous-expressions jusqu'à ce qu'il soit requis dans le résultat final en créant thunks (objets retardés).

  • Parfois, cela augmente la complexité spatiale d'un algorithme.

  • Il est très difficile de trouver ses performances car il contient des bruits d'expressions avant leur exécution.

Évaluation paresseuse à l'aide de Python

le rangeLa méthode en Python suit le concept de l'évaluation paresseuse. Cela permet d'économiser du temps d'exécution pour des plages plus grandes et nous n'avons jamais besoin de toutes les valeurs à la fois, donc cela économise également la consommation de mémoire. Jetez un œil à l'exemple suivant.

r = range(10) 
print(r) 
range(0, 10) 
print(r[3])

Il produira la sortie suivante -

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
3

Nous avons besoin de fichiers pour stocker la sortie d'un programme lorsque le programme se termine. À l'aide de fichiers, nous pouvons accéder aux informations associées à l'aide de diverses commandes dans différentes langues.

Voici une liste de quelques opérations qui peuvent être effectuées sur un fichier -

  • Créer un nouveau fichier
  • Ouvrir un fichier existant
  • Lire le contenu du fichier
  • Recherche de données sur un fichier
  • Ecrire dans un nouveau fichier
  • Mettre à jour le contenu d'un fichier existant
  • Supprimer un fichier
  • Fermer un dossier

Écrire dans un fichier

Pour écrire le contenu dans un fichier, nous devons d'abord ouvrir le fichier requis. Si le fichier spécifié n'existe pas, un nouveau fichier sera créé.

Voyons comment écrire du contenu dans un fichier en utilisant C ++.

Exemple

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

int main () {   
   ofstream myfile; 
   myfile.open ("Tempfile.txt", ios::out); 
   myfile << "Writing Contents to file.\n"; 
   cout << "Data inserted into file"; 
   myfile.close(); 
   return 0; 
}

Note -

  • fstream est la classe de flux utilisée pour contrôler les opérations de lecture / écriture de fichiers.

  • ofstream est la classe de flux utilisée pour écrire le contenu dans un fichier.

Voyons comment écrire du contenu dans un fichier en utilisant Erlang, qui est un langage de programmation fonctionnel.

-module(helloworld).  
-export([start/0]).   

start() ->
   {ok, File1} = file:open("Tempfile.txt", [write]),  
   file:write(File1,"Writting contents to file"), 
   io:fwrite("Data inserted into file\n").

Note -

  • Pour ouvrir un fichier, nous devons utiliser, open(filename,mode).

  • Syntaxe pour écrire le contenu dans le fichier: write(filemode,file_content).

Output - Lorsque nous exécutons ce code "Ecrire le contenu dans un fichier" sera écrit dans le fichier Tempfile.txt. Si le fichier a un contenu existant, il sera écrasé.

Lecture à partir d'un fichier

Pour lire un fichier, nous devons d'abord ouvrir le fichier spécifié dans reading mode. Si le fichier n'existe pas, sa méthode respective renvoie NULL.

Le programme suivant montre comment lire le contenu d'un fichier dans C++ -

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

int main () {
   string readfile; 
   ifstream myfile ("Tempfile.txt",ios::in); 
   
   if (myfile.is_open()) {     
      while ( getline (myfile,readfile) ) {       
         cout << readfile << '\n'; 
      } 
      myfile.close(); 
   } else  
      cout << "file doesn't exist";  
   return 0; 
}

Il produira la sortie suivante -

Writing contents to file

Note- Dans ce programme, nous avons ouvert un fichier texte en mode lecture en utilisant «ios :: in», puis nous avons imprimé son contenu à l'écran. Nous avons utiliséwhile loop pour lire le contenu du fichier ligne par ligne en utilisant la méthode «getline».

Le programme suivant montre comment effectuer la même opération en utilisant Erlang. Ici, nous utiliserons leread_file(filename) méthode pour lire tout le contenu du fichier spécifié.

-module(helloworld).  
-export([start/0]).   

start() ->  
   rdfile = file:read_file("Tempfile.txt"),  
   io:fwrite("~p~n",[rdfile]).

Il produira la sortie suivante -

ok, Writing contents to file

Supprimer un fichier existant

Nous pouvons supprimer un fichier existant à l'aide d'opérations sur les fichiers. Le programme suivant montre comment supprimer un fichier existantusing C++ -

#include <stdio.h> 

int main () {   
   if(remove( "Tempfile.txt" ) != 0 ) 
      perror( "File doesn’t exist, can’t delete" ); 
   else 
      puts( "file deleted successfully " ); 
   return 0; 
}

Il produira la sortie suivante -

file deleted successfully

Le programme suivant montre comment vous pouvez effectuer la même opération dans Erlang. Ici, nous utiliserons la méthodedelete(filename) pour supprimer un fichier existant.

-module(helloworld).  
-export([start/0]).   

start() ->  
   file:delete("Tempfile.txt").

Output - Si le fichier «Tempfile.txt» existe, il sera supprimé.

Déterminer la taille d'un fichier

Le programme suivant montre comment vous pouvez déterminer la taille d'un fichier à l'aide de C ++. Ici, la fonctionfseek définit l'indicateur de position associé au flux sur une nouvelle position, tandis que ftell renvoie la position actuelle dans le flux.

#include <stdio.h> 

int main () {  
   FILE * checkfile; 
   long size; 
   checkfile = fopen ("Tempfile.txt","rb"); 
   
   if (checkfile == NULL)  
      perror ("file can’t open"); 
   else {   
      fseek (checkfile, 0, SEEK_END);    // non-portable 
      size = ftell (checkfile); 
      fclose (checkfile); 
      printf ("Size of Tempfile.txt: %ld bytes.\n",size); 
   } 
   return 0; 
}

Output - Si le fichier «Tempfile.txt» existe, il affichera sa taille en octets.

Le programme suivant montre comment vous pouvez effectuer la même opération dans Erlang. Ici, nous utiliserons la méthodefile_size(filename) pour déterminer la taille du fichier.

-module(helloworld).  
-export([start/0]).   

start() ->  
   io:fwrite("~w~n",[filelib:file_size("Tempfile.txt")]).

Output- Si le fichier «Tempfile.txt» existe, il affichera sa taille en octets. Sinon, il affichera «0».