W programowaniu języki można podzielić na niskopoziomowe i wysokopoziomowe. Te pierwsze oddają działanie komputera, a te drugie są zbieżne z tokiem naszego myślenia, a co za tym idzie, ułatwiają myślenie o problemie.
Styczność z wieloma językami, pozwala dostrzec w nich różnicę, jeśli chodzi o poziom ekspresji przy operowaniu wyrażeniami.

Przykładowo:

  • asembler - nie ma żadnych wyrażeń - wszystkie działania sprowadzają się do użycia odpowiednich instrukcji;
  • COBOL - wspiera wyrażenia, ale wywołanie funkcji to osobna instrukcja, która nie może stanowić części wyrażenia;
  • C - obsługuje wyrażenia na typach prostych, ale również umożliwia wywołanie funkcji w wyrażeniu oraz pozwala na włączenie warunków dzięki ternary operator;
  • Python - obsługuje w wyrażeniach typy złożone, kolekcje, generatory, a także wspiera if jako wyrażenie oraz listy składane;
  • Lisp - w tym języku wszystko jest wyrażeniem.

Wymienione wyżej przykłady obrazują, że im bardziej wysokopoziomowy język tym jego większa ekspresja w zapisie wyrażeń.

Warto tutaj postawić pytanie: Jaką rolę odgrywa ekspresja?

Z jednej strony ekspresja pozwala uchwycić więcej w swoim zapisie, skupia uwagę w jednym miejscu i przez to kod staje się czytelniejszy w odróżnieniu od tworzenia odrębnej funkcji, o czym pisałem tutaj.

Z drugiej strony chciałbym zwrócić uwagę na to, że większa ekspresja otwiera więcej opcji podczas wydzielania kodu.

Dla przykładu przeanalizujmy funkcję y_ordered_widgets, która weryfikuje czy widgety są kolejno ułożone wg współrzędnej y.

def y_ordered_widgets(widgets):
    for i in range(len(widgets) - 1):
        if widgets[i].y > widgets[i+1].y:
            return False
    return True

Z kodu powyżej, można wyodrębnić pomocniczą funkcję generatora:

def pairwise(xs):
    for i in range(len(xs) - 1):
        yield xs[i], xs[i+1]

by następnie użyć ją w ten sposób:

def y_ordered_widgets(widgets):
    for a, b in pairwise(widgets):
        if a.y > b.y:
            return False
    return True

Zmodyfikowana funkcja y_ordered_widgets ma tę korzyść, że nie musi już bezpośrednio operować indeksami, ponieważ ta część została wyodrębniona. Dzięki temu łatwiej jest przetwarzać pary.