Programowanie symboliczne to paradygmat programowania, w którym program komputerowy może dokonywać zmian we własnych podstawowych elementach, np. wyrażeniach kodu źródłowego, w taki sam sposób, w jaki dokonuje się operacji na dowolnych danych. Jest to sposób programowania, w którym rozwiązując problemy obliczeniowe, nie tylko tworzymy nowe programy, lecz również dostosowujemy język do efektywnego wyrażania rozwiązań tych problemów. Takie podejście leży u podstaw techniki zwanej metaprogramowaniem.

W językach programowania obsługujących paradygmat symboliczny, takich jak Lisp czy Prolog, można decydować, które fragmenty kodu źródłowego zostaną poddane uruchamianiu w procesie obliczania wartości wyrażeń, a które zostaną potraktowane jak dane. W rezultacie możliwe jest modyfikowanie oryginalnego kodu źródłowego programu (a dokładniej jego pamięciowej reprezentacji) z użyciem odpowiednich konstrukcji (w Lispie będą to makra i formy specjalne) zanim wyrażenia będą przeliczane. Pozwala to na budowanie złożonych systemów obliczeniowych na podstawie przejrzystych, wyspecjalizowanych części realizujących poszczególne zadania. Mogą to być niewielkie udogodnienia rozszerzające możliwości języka (np.