The recipe analogy is certainly very natural, but it does not extend as we get into things like assignments and references, which are a crucial part of Von Neumann languages (which is really the thing I am criticizing).
Tactic languages in theorem provers like Coq are stateful too: you have a proof state and you keep giving instructions for it to change. I wouldn't say that this is an unnatural way to think; for that subtask of the problem, we can view the proof as something with state without any problems.
"Mathematical modeling" sounds too sophisticated to be natural for humans. Let me illustrate what I meant; the kind of naturality I was talking about is this:
sorted(xs): a permutation xs' of xs such that, as we traverse xs' each element is greater than or equal to the previous one.
This is a perfectly fine sorting algorithm. It contains all the information we need to sort a list of comparable things, and it is very unlikely to contain an error; it is the _definition_ of sorting.
There are righteous performance concerns about this but ignoring all performance issues this is still more natural than listing out the steps needed to carry out the task of sorting. I don't think it is possible come up with a simpler recipe-like algorithm for this task.
There are recipe-like tasks in programming: ones that don't involve modeling the world; for those the functional paradigm would not be a good one. But these are rare if you are doing programming the right way.
You are confusing algorithms (Operational Semantics) with definitions (Denotational Semantics). One of the key difference between mathematics and computing is that mathematics is far less concerned with constructing results, and far more concerned with reasoning about the properties of objects. Mathematics sits at a level of abstraction unsuited to physical hardware.
In Haskell, this is evident in the complex and difficult to reason about graph-reduction engine that lays hidden in the runtime. Denotional semantics => Haskell Math yay. Operational Semantics => Haskell's downfall in real-world programmers.
I don't see how either operational or denotational semantics is relevant as I was not talking about semantics of any kind.
I don't think I am confusing anything, you are reacting exactly as I would expect from someone who does not get the point I'm making: we don't have to necessarily program with steps of instructions. If we have a good solver for our language, we can very efficiently execute definitions like my example. I agree that this presents the challenge of efficiently executing such high-level definitions, but this is irrelevant to my point.
> Mathematics sits at a level of abstraction unsuited to physical hardware.
Precisely what I am talking about. Mathematics sits at a level of abstraction convenient for humans not machines.
Have you ever programmed in Prolog? I strongly suggest you try it to get a feeling of why programs are not inherently lists of instructions and how computation can be viewed as deduction.
Tactic languages in theorem provers like Coq are stateful too: you have a proof state and you keep giving instructions for it to change. I wouldn't say that this is an unnatural way to think; for that subtask of the problem, we can view the proof as something with state without any problems.
"Mathematical modeling" sounds too sophisticated to be natural for humans. Let me illustrate what I meant; the kind of naturality I was talking about is this:
sorted(xs): a permutation xs' of xs such that, as we traverse xs' each element is greater than or equal to the previous one.
This is a perfectly fine sorting algorithm. It contains all the information we need to sort a list of comparable things, and it is very unlikely to contain an error; it is the _definition_ of sorting.
There are righteous performance concerns about this but ignoring all performance issues this is still more natural than listing out the steps needed to carry out the task of sorting. I don't think it is possible come up with a simpler recipe-like algorithm for this task.
There are recipe-like tasks in programming: ones that don't involve modeling the world; for those the functional paradigm would not be a good one. But these are rare if you are doing programming the right way.