Spreadsheets are a dataflow programming language where all expressions are displayed visually on the screen. They share a lot in common with functional programming languages. Cells are expressed as functions of other cells, where the functions do not have side effects, and in most simple sheets, any given cell is immutable barring new I/O in the form of keyboard input (cells which are not will show an error instead of a value).
They have three limitations that make arbitrary programming difficult:
- They only have two dimensions: rows and colums. In many programs, you have at least three dimensions: "time" in the form of an instruction pointer or recursion stack, multiple variables, and vector valued variables. If you use one of the spreadsheet axes for time, you are either limited to scalar values or are forced to serialize list and more complicated data types into strings.
- They have a limited number of cells. While an imperative program can run an event loop forever, if you map "time" into one of the spreadsheet axes, you can run out of memory if the "program" needs to run forever.
- They are slow because they aren't designed to be used as a general purpose programming language.
However, it is possible to solve all sorts of programming problems using spreadsheets. I have done a few, taken from "ninety-nine prolog/lisp/haskell problems" here.