Στον προγραμματισμό, λέμε ότι μια συνάρτηση έχει **παρενέργειες** (*side effects*) αν, εκτός από την τιμή που επιστρέφει, τροποποιεί και διάφορα άλλα στοιχεία. Για παράδειγμα, μία συνάρτηση θα μπορούσε να τροποποιεί μία καθολική ή μία στατική μεταβλητή, να αλλάζει την τιμή μιας ή περισσοτέρων από τις παραμέτρους της, να γράφει δεδομένα σε ένα αρχείο για εμφάνιση, ή να διαβάζει κάποια δεδομένα από άλλες συναρτήσεις που επίσης έχουν παρενέργειες. Οι παρενέργειες συχνά κάνουν πιο δύσκολη την κατανόηση της συμπεριφοράς ενός προγράμματος. Οι προστακτικές γλώσσες είναι γνωστές για την στράτευση των παρενεργειών προκειμένου να υλοποιήσουν τις συναρτήσεις ενός προγράμματος. Αντίθετα, οι συναρτησιακές γλώσσες προγραμματισμού είναι γνωστές για την ελαχιστοποίηση ή εξάλειψη των παρενεργειών.

Διαφάνεια αναφοράς
------------------

Μία συνάρτηση που χρησιμοποιεί παρενέργειες την ονομάζουμε *αδιαφανή σε αναφορικότητα* (*referentially opaque*), ενώ αν δεν χρησιμοποιεί την ονομάζουμε *διαφανή σε αναφορικότητα* (*referentially transparent*). Για λόγους απλότητας, λέμε ότι μία διαφανής σε αναφορικότητα συνάρτηση είναι αυτή που, δοσμένων κάποιων παραμέτρων, πάντα θα επιστρέφει ένα και μόνο αποτέλεσμα. Ένας άλλος όρος αντί του διαφανής σε αναφορικότητα συνάρτηση είναι *ντετερμινιστική* συνάρτηση.

Μία συνάρτηση μπορεί να μην έχει καμία παρενέργεια αλλά να είναι αδιαφανής σε αναφορικότητα - κάθε συνάρτηση που μετρά τον εξωτερικό κόσμο είναι αδιαφανής σε αναφορικότητα. Μία συνάρτηση που διαβάζει την τρέχουσα ώρα από το ρολόι του υπολογιστή θα επιστρέφει διαφορετικά αποτελέσματα δοσμένων των ίδιων παραμέτρων, ακόμα και αν δεν αλλάξει κάποια καθολική κατάσταση, γιατί εξαρτάται κατά κάποιο τρόπο από μία καθολική μεταβλητή που αλλάζει, δηλαδή τον χρόνο.

Ένα παράδειγμα
--------------

Ως παράδειγμα, ας χρησιμοποιήσουμε δύο συναρτήσεις, μία από τις οποίες είναι διαφανής και μία που είναι αδιαφανής:

```
καθολικήΤιμή = 0;
integer συνάρτηση αδ(integer x)
Αρχή
  καθολικήΤιμή = καθολικήΤιμή + 1;
  Επίστρεψε (x + καθολικήΤιμή);
Τέλος
```

```
integer συνάρτηση δφ(integer x)
Αρχή
  Επίστρεψε (x + 1);
Τέλος
```

Η δφ είναι η διαφανής συνάρτηση, που σημαίνει ότι όταν α = β τότε πάντα δφ(α) = δφ(β). Για παράδειγμα, δφ(5) = δφ(6-1) = 6. Όμως, δεν μπορούμε να πούμε ότι κάτι τέτοιο συμβαίνει και με τη αδ, αφού χρησιμοποιεί την καθολική μεταβλητή την οποία και τροποποιεί.

Ο χειρισμός των αδιαφανών χρειάζεται αυξημένη προσοχή. Ας υποθέσουμε ότι θέλουμε να κάνουμε έναν υπολογισμό όπως τον παρακάτω:

```
 integer α = αδ(x) + αδ(y) * (αδ(x) - αδ(x));
```

Τώρα, κάποιος θα έμπαινε στον πειρασμό να τροποποιήσει τον παραπάνω κώδικα ως εξής:

```
integer p = αδ(x) + αδ(y) * (0) <=> 
integer p = αδ(x) + 0           <=> 
integer p = αδ(x);
```

Όμως, η απλοποίηση δεν πρέπει να γίνει με την αδ() αδιαφανή, αφού αδ(x) δεν ισούται με το αδ(y) ακόμα και όταν x = y. (Ενδιαφέρον! Θυμηθείτε ότι η επιστρεφόμενη τιμή της αδ() βασίζεται στην καθολική μεταβλητή η οποία μπορεί να μεταβληθεί από οποιοδήποτε σημείο του προγράμματος). Αυτό αντιτίθεται στον κανόνα της απλής αριθμητικής, όπου αν από οτιδήποτε αφαιρέσουμε τον εαυτό του προκύπτει ο αριθμός μηδέν.

Αντίθετα, η απλοποίηση θα μπορούσε να γίνει αν χρησιμοποιείτο η δφ(), που είναι μία διαφανής σε αναφορικότητα συνάρτηση.

Γενικά, καλό είναι να προτιμούνται μέθοδοι οι οποίες θα οδηγούν σε δυνατά και επαναχρησιμοποιήσιμα προγράμματα έναντι άλλων πιο εύκολων και προφανών λύσεων οι οποίες θα έφερναν σύγχυση σε όποιον προσπαθούσε να τις κατανοήσει.