Как стать автором
Обновить

Комментарии 6

В кратце — без обид, но каша какая-то, например тема «чего же стоит синтаксический сахар» не раскрыта совсем.
Если развёрнутее и по тексту:
Вот вы вводите своё описание объектной модели, и называете всё что сверху «хаком», гм, допустим.
Первый же хак который вы называете — литеральное создание объектов?
Значит тот теоритический язык с вашей объектной моделью — не чисто объектный, в нём допустимы терминалы не являющиеся объектами, это не плохо само по себе, но совершенно непонятно как выполняется создание объекта. Да, можно вызвать Class.new(), но тогда Class это не объект.
Можно сказать что объявлением мы создаём глобальный объект, но об этом вы уже сами написали. Вы пишете пункты 6 и 7, но при этом называете это хаком? И всё было бы даже не плохо, если бы был какой нибудь new Class который просто создаёт «сущность» с полями по умолчанию, но совсем не то, что вы написали в пунктах 6,7. Кстати, тема инкапсуляции совершенно не раскрыта.
Далее вы называете замыкания хаком. Тут я ОЧЕНЬ удивился, ведь замыкания не являются частью объектной модели. Да, есть языки в которых замыкание превращается в объект, но это сделано чтобы не вводить специальный синтаксис для работы с замыканием, а не расширить объекную модель. Можно конечно поспорить что мол замыкание имеет доступ к this итд, мой аргумент следующий: объект это работа с данными, замыкание — это работа с потоком команд, относительно потока команд this это константная переменная, не более.
Хаки над хаками — не хочу защищать C#, тем более что я его толком и не знаю, однако истории некоторых из этих хаков уже расказанны в статьях на хабре. Касательно невиртуальных методов — очевидно что с С++ вы не знакомы (кстати Objective-C отпочковался от С, а не С++, и вообще сравнение Obj-C и C++ это интересная тема раскрывающая разные подходы к реализацию сферической объектной модели в вакууме на конкретном железе, которое как ни странно умудряется работать с ограниченной скоростью).
В заключении вы делаете совершенно несуразный вывод о том, что сахар не даёт больших возможностей в реализации логики и что ваша «простая» модель приводит к плохо читаемому и плохо структурированному коду. Хотелось бы заметить, что такие относительно простые вещи как «вызов метода объекта, имя которого переданно как строка» может превратиться в вашей сферической модели в УГ. Я пожалуй даже не буду разгоняться на тему зачем нужен синтаксический сахар и почему нам без него хуже, я просто скажу что языки сохраняющие кажущуюся «простоту и вседостаточность» теряют популярность не из за каких-то массонских заговоров, а из за низкой скорости разработки на них и отсутствия преимуществ перед другими языками.
В заключение скажу что все эти «хаки» имеют под собой ряд вполне обоснованных причин на существование.
P.S.
А знает ли автор о yeild? но это я так, просто спросил.
Попробую ответить на некоторые ваши вопросы.

1. Я знаком с C++ как и ещё полутра десяткой языков и с его невиртуальными методами тоже. Я о нём просто не написал.

2. В моём «сферическом языке» Class.new() выполняется для создания новых объектов и Class — это объект. Так есть, например, в Smalltalk, где класс Object содержит всё необходимое, чтобы делать новые объекты, но сам он является объектом. В Smalltalk, как и в Self, нет синтаксической конструкции для наследования классов — подкласс создаётся путём отправки сообщения subclass классу-объекту, от которого производится наследование.

3. Мой язык не такой уж и «сферический», я описал его, используя, в частности, знание Smalltalk и Self, где нет лексических конструкций для определения наследования, инкапсуляции, конструкторов и классов.

4. В таких языках как C#, Python, Smalltalk замыкание не что иное как объект (замыкание преобразуется в настоящий объект компилятором/интерпретатором).

5. В некоторых ранних версиях Objective-C представлял собой препроцессор над C++, поэтому и был чистым расширением не C, а C++. Впрочем и сейчас есть сборки, позволяющие использовать C++ в Objective-С, например, вот и вот.

6. Я делаю вывод, что чистая объектная модель не приводит к плохо структурированному коду, что видно при внимательном прочтении.

7. Я знаком с yield как в Python, так и в C#. Например, в C# конструкция yield преобразуется не во что иное как в объект IEnumerable. То, как это происходит, хорошо описано здесь.
То есть вы описываете прототипо-базированный язык? И противопоставляете его класс-ориентированному?
А вам не кажется что это некорректно? Это очень разные подходы которые в первую очередь требуют различного типа компиляторов. Прототипо-базированный язык вынужден иметь интерпретатор или JIT компилятор, в то время как класс-ориентированный может быть скомпилирован в машинный код. Это кстати и повлияло на непопулярность различных Self и Smalltalk — они появились гораздо раньше эффективных JIT компиляторов. Тем более есть классический набор «преимуществ и недостатков» одного подхода перед другим. Лично я не могу выбрать какой-то один подход, т.к. использую оба, и я бы не сказал, что какой-то из них приводит меня к плохому коду. Если конечно в JS не разводить ООП в стиле С++ или наоборот.
4 — то, что замыкание хранится объект ещё ни о чём не говорит. вообщем то замыкания можно точно так же ввести и в вашу модель — пускай это будет литеральный способ создания объекта и допустим введём перегрузку оператора (), или же как в Self — activation record и вуаля, мы имеем объект ни коем образом не тревожащий объектную модель. более того — смотрите на JS, где замыкание замещает собой понятие функции и стоит вне объектной модели
5 — Objective-C является расширением С и первая версия быле действительно препроцессором перед С компилятором, интеграция с С++ появилась позже в Objective-C++
6 — извините, описался, но на основании чего вы делаете такой вывод? Почему объектная модель внезапно стала серебряной пулей против кривых рук программистов? Или вы не видели дурацкого JS кода?
Вообще разговор о преимуществах одного языка над другим в контексте как его используют программисты это очень спорная вещь. Любую возможность языка можно использовать как для написания простого и понятного, так и для написания запутанного и сложного кода, вопрос в умении писателя а не в возможностях языка.
Логично пишите, я могу согласиться с вами и по части того, что сравнивать prototype-based и class-based подходы не корректно, и по части того, что ничто не застрахует программистов от «кривых рук». Даже, чего скрывать, я полностью с вами согласен. Но всё же есть «но». Я сам уже вижу, что недостаточно чётко раскрыл главную тему статьи. Моя цель заключалась вовсе не в том, чтобы вызвать сравнение прототипо-ориентированных языков с класс-ориентированными, и даже не в том, чтобы задеть за живое функциональщиков. Да, я имею представление о функциональном программировании, сам писал реальные приложения на Lisp и знаю, что ФП мощная вещь и не нуждается в объектной подстилке.
А в статье главное, что я хотел подчеркнуть, это то что многие возможности современных языков программирования, в том числе замыкания, управляемый полиморфизм (как в C#), и даже генераторы (которые не были рассмотрены в статье, но упомянуты позже в комментарии) не дают столь больших возможностей, как многие это считают. Я хотел рассмотреть язык с минимальной сложностью синтаксиса, но состояние реального положения дел таково, что минимальной сложностью обладает прототипо-ориентированный язык. Поэтому я и заострил внимание на этом подходе. Замыкания, карринг, обёртки функций в чистом виде нужны именно в ФП-языках и именно так, как вы описали в первом комментарии. Но в ООП-языках так или иначе они имеют меньше возможностей, чем вариант на базе явного решения в виде явного создания объекта. В ФП языках (это одна из характерных черт) нет состояния, все функции чисты в том смысле, что извне они обладают ровно пустым состоянием, то есть преобразуют «вход» в «выход» без памяти о том, что было сделано в прежних вызовах. Но в этом и сила ФП-программирования. Сила же ООП-программирования как раз в «программирование с состояниями». Теперь я хочу привести даже не моё мнение, а чисто факты:

1. Вынесение логики в виде замыкания в ООП-языках преобразуется в объект строго определённого типа, который может замыкаться на внешний контекст и хранить состояние только во внешним контексте, но в собственном.

2. Вынесение логики в явно определённый объект позволяет этому объекту сохранять состояние не во внешнем контексте, на который он замыкается, а внутри себя.

3. Объект, полученный при явном определении (п. 2), может иметь любой тип, наследовать любой класс, реализовывать любые интерфейсы (протоколы, трейты). В частном случае, он может нести ровно ту же самую нагрузку, что и неявно созданный с помощью синтаксического замыкания объект, описанный в п. 1.

4. Из пп 1-3 следует, что функциональность явно определённого объекта больше либо равна функциональности объекта, созданного через замыкание.

Кстати, в подтверждение этого заключения я в статье и привёл два примера на C#.

Почти то же самое можно сказать и о генераторах. А чтобы использовать решения на базе явного определения объектов достаточно языка с очень простым синтаксисом как, например, Smalltalk. Я не говорю, что замыкания на уровне синтаксиса — это плохо, наоборот они очень даже хорошо смотрятся и, главное, нужно писать меньше. Я хотел сказать, что они более ограничены. Вообще, я хотел сказать, что все хаки более ограничены, чем явное определение объектов.

Вообще, я уже почувствовал, что написание общетеоретических статей — совершенно проигрышное дело. Спасибо, что не забанили статью. В будущем буду писать статьи только с конкретикой.
Прошу прощение, опечатка: «хранить состояние только во внешним контексте, но не в собственном».
Кстати, хотел высказать ещё одну точку зрения в подкрепление основной мысли своей статьи. По C# я привёл достаточно примеров, но мало рассказал о Java, а ведь как раз Java развивается совершенно иначе, нежели C#. Многие говорили, и на хабре в частности, что C# развивается быстрее, чем Java. Но на мой взгляд, C# обрастает разного рода «хаками», в то время как в Java объектная модель остаётся более консервативной. Можно ли сказать, что Java от этого в убытке? Не думаю, да и внешне это никак не видно, рейтинг по версии TIOBE — второе место. Казалось бы, в Java синтаксис в разы проще, чем в C#, но язык от этого не слабее. Да, в Java нет таких сомнительных хаков, в частности над объектной моделью, как типы-значения (исключая примитивы, которые полностью за рамками объектной модели), структуры, невиртуальные функции. Да и от того, что в Java нет замыканий и генераторов, проигрыша от этого тоже нет. В Java есть нестатические внутренние классы, в том числе и анонимные, а это стоит больше, чем разного рода замыкания и больше соответствует «нормальной» объектной модели. В Java перечисления — действительно объекты, которые могут удовлетворять заданным интерфейсам, чего не скажешь о перечислениях в C#. А то, что в Java 7 всё же не включили замыкания — не велика потеря. Так что меня полностью устраивает, как развивается Java, и ей, в частности, были навеяны идеи, которые я изложил в статье.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории