Парадигмы программирования: объекты или функции?

Боль­ше 10 лет про­дол­жа­ет­ся мое осо­зна­ное зна­ком­ст­во с Ocaml и око­ло 18 лет зна­ком (на уров­не лю­би­те­ля) с лиспом. Пожа­луй, се­йчас мож­но раз­ре­шить се­бе ска­зать пуб­лич­но: я счи­таю ООП лиш­ним в боль­шинст­ве за­дач. И се­йчас объ­яс­ню по­че­му.

Любое про­ек­ти­ро­ва­ние си­сте­мы на­чи­на­ет­ся на де­кла­ра­тив­ном язы­ке ин­тер­фей­сов. В тер­ми­нах это­го язы­ка про­ек­ти­ро­ва­ния мы де­кла­ри­ру­ем (опи­сы­ва­ем) за­да­чу, наш про­ект. И толь­ко по­том, на язы­ке ре­али­за­ции, мы рас­су­жда­ем о тер­ми­нах язы­ка ин­тер­фей­са.

В па­ра­диг­ме ООП на этом язы­ке ин­тер­фей­са удоб­но опи­сы­вать уст­ро­йст­во ми­ра, пря­мо как пи­шут в кни­жках: вот это класс всех об­ъек­тов, а эти име­ют ра­диус, и они кру­ги. А вот эти име­ют два ра­диу­са, по­то­му что эллип­сы. А ра­диус — то­же класс об­ъек­тов, «по­ло­жи­тель­ное чис­ло». То есть в рам­ках этой па­ра­диг­мы мы опи­сы­ва­ем ро­до­слов­ную об­ъек­тов, кто и ка­кие ка­кие ха­рак­те­рис­ти­ки (ге­ны) имеет. Даль­ше, им­ея вот эту из­дан­ную и за­ком­ми­чен­ную энцикло­пе­дию ви­дов, на язы­ке ре­али­за­ции на­чи­на­ет­ся им­пе­ра­тив­ное на­пи­са­ние ин­ст­рук­ций то­го, че­го же мы собст­вен­но хо­тим от об­ъек­тов это­го ми­ра. Пишем ин­ст­рук­ции для Listener ин­тер­фей­са, ко­то­рый бу­дет слать Events в фер­му Worker’ов, со­зда­ва­емых на Factory. Потом мы пи­шем ин­ст­рук­ции для Listerner что де­лать в слу­чае, ес­ли Worker по­сре­ди вы­пол­не­ния ин­ст­рук­ции «по­ст­ро­ить дом» по ка­кой-то при­чи­не ско­нчал­ся, не до­ст­ро­ив по­след­ний этаж.

В па­ра­диг­ме функ­ци­ональ­но­го про­грам­ми­ро­ва­ния в тер­ми­нах язы­ка ин­тер­фей­са мы опи­сы­ва­ем ко­неч­ную цель про­ек­та («са­мый по­след­ний знак чи­сла Пи», «веб-стра­ни­ца с ку­сом ва­лют»), а так­же спо­со­бы её до­сти­же­ния. Если мы мо­жем до­ка­зать су­щест­во­ва­ние хо­тя бы од­но­го спо­со­ба до­сти­же­ния це­ли (не­ко­го пре­об­ра­зо­ва­ния од­но­го ти­па в це­ле­вой) — зна­чит мы мо­жем вы­пол­нить про­ект. В свою оче­редь, ис­ход­ные ти­пы это­го спо­со­ба — это та­кие же под­це­ли, ко­то­рые точ­но так же ли­бо име­ют до­ка­за­тельст­ва, ли­бо нет. В моем прос­том при­ме­ре, су­щест­во­ва­ние ре­зуль­та­та (ти­па дан­ных) «са­мый по­след­ний знак чи­сла Пи» оче­вид­но не имеет до­ка­за­тельств (ре­ше­ний), по­то­му что нель­зя при­вес­ти ни од­но­го ти­па функ­ций, ко­то­рый бы при­бли­жал нас к ней.

Таким об­ра­зом, в функ­ци­ональ­ной па­ра­диг­ме уже на эт­апе про­ек­ти­ро­ва­ния мы опи­сы­ва­ем це­ли и граф пу­тей её до­сти­же­ния. Мне ка­жет­ся это бо­лее ес­тест­вен­ным спо­со­бом про­ек­ти­ро­ва­ния.

И здесь та­кая ин­дук­ция: ре­али­за­ция функ­ции (опи­са­ние кон­крет­но­го спо­со­ба пре­об­ра­зо­ва­ния из ти­па A в тип B) то­же есть цель, ко­то­рую точ­но так же не­об­хо­ди­мо вы­вес­ти, пу­тем по­ст­ро­ения ми­ни­маль­но­го до­ста­точ­но­го гра­фа спо­со­бов по­лу­че­ния B из A. То есть, язык ре­али­за­ции функ­ции в не­ко­то­ром смыс­ле ста­но­вит­ся язы­ком, о тер­ми­нах ко­то­ро­го бу­дут рас­су­ждать уже в свою оче­редь при на­пи­са­нии функ­ций под­це­лей этой функ­ции.

В ми­ре ООП есть тен­ден­ция к пе­ре­хо­ду от спо­со­ба рас­суж­де­ния в де­кла­ра­ци­ях ви­да «ме­тод m со­вмес­тим с об­ъек­та­ми клас­са B» к де­кла­ра­ци­ям ви­да «ме­тод m ждет лю­бой об­ъект со свойст­ва­ми P₁ + P₂». Ниче­го не хо­чу ска­зать, но во­об­ще-то это чис­тая функ­ци­ональ­щи­на :-)

У ООП есть своя от­лич­ная ни­ша. Это не те си­сте­мы, где не­об­хо­ди­мо вы­чис­лить ре­зуль­тат или сде­лать се­рию пре­об­ра­зо­ва­ний дан­ных, а си­сте­мы, где ос­нов­ной целью яв­ля­ет­ся опи­са­ние об­ъек­тов и их вз­аи­мо­дейст­вия — без га­ран­тий ин­терп­ре­та­ции ко­да в не­кий ожи­да­емый ре­зуль­тат. Игруш­ки, ин­тер­фей­сы.