Напишу еще немного.

Во первых, я хочу сказать, что несмотря на бурную дискуссию с ARV я согласен с почти всеми его высказываниями. Различие я вижу лишь в том, что считать 'естественным, логичным и интуитивно понятным', а что таковым не является.
Disclamer: Все нижеслдующее никоим образом не связанно ни с какими участниками этой дискуссииЧто же такое 'естественое и огичное'? Давайте споросим у бубульки возле подъезда - нужно ли разделять логические и арифметические операции? Как думаете, что она вам ответит?

Ладно, согласен - не та целевая аудитория. Давайте спросим у программиста, но тут есть загвоздка - у какого именно? Не бывает 'сферического программиста в ваккуме'. Каждый язык програмирования построен вокруг некоторого набора принципов и правил, и наборы эти разные. И не надо аппелировать к математической логике - она напрямую не применима к языкам програмирования, т.к. они строились не для доказательства математических теорем, а для написания программ.
Как вы думаете, эти коды согласуются с 'здравым смыслом и математической логикой'?
Код
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
Код
select: aBlock
| newCollection |
newCollection := self species new.
self do: [:each |
(aBlock value: each)
ifTrue: [newCollection add: each]].
^newCollection
Код
gcd2(A, 0, A).
gcd2(A, B, G) :- A>0, B>0, N is mod(A, B), gcd2(B, N, G).
gcdn(A, [], A).
gcdn(A, [B|Bs], G) :- gcd2(A, B, N), gcdn(N, Bs, G).
gcdn([A|As], G) :- gcdn(A, As, G).
:- initialization(main).
str2int([], []).
str2int([S|St], [N|Nt]) :- number_atom(N, S), str2int(St, Nt).
main :-
argument_list(Args),
str2int(Args, Numbers),
gcdn(Numbers, G),
write(G), nl.
Код
(~R∊R∘.×R)/R←1↓⍳R
На возможный ответ 'что это за бред' сразу отвечу - вполне законные куски программ на разных языках, а именно - Haskel, Smalltalk, Prolog, APL
Давайте возмем более близкие языки - С и Pascal. Несмотря на их внешнюю схожесть (по сравнению с вышеизложенными кусками кода), они очень разные. И как это пародоксально не звучит, С более простой язык. В С уменьшено количество сущностей языка и практически убраны какие либо ограничения на использование
конкретных конструкций в конкретных местах. Все описывается именно на уровне сущностей.
Например - в Pascal'е операция сравнения, присваивание и арифметика это разные сущности и используются они в разных, строго определенных контекстах. В С это все
выражения, и использоваться они могут везде, где ожидается выражение. В Pascal'е все очень строго оговорено и определено. Шаг влево, шаг вправо - расстрел

Поэтому запись на С
Код
int a=b==c;
вызывает у Pascal'иста взрыв мозга - как так, тут же сравнение, значит должен быть if!
И не надо аппелировать к логике и здравому смыслу - у програмистов на С и Pascal'е они будут
разными. Более того, они
и должны быть разными - языки же разные!
Так же становится понятными жалобы со стороны Pascal'истов на сложность С. На самом деле они жалуются не на сложность, а на то, что способы применения вроде бы понятных и тривиальных конструкций порой оказываются совершенно другими. Так же понятно, почему с Pascal'я неохотно переходят на С - не хочется вылезать из песочницы, там все так просто и безопасно

И понятно, почему все же перейдя на С обратно уже не возвращаются - мир интереснее, чем песочница.
На самом деле есть гораздо более опасная связка - переход с С на С++. Несмотря на их внешнюю практически идентичность, эти языки отличаются горадо больше, чем С и Pascal. А если неофиту еще скажут, что в настоящей ООП программе все должно быть в виде классов, то получаются жуткие классовые монстры, такие, что не в сказке сказать не вслух произнести