Re[49]: Быстро превратить интерпретатор в компилятор
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 01.02.10 22:31
Оценка: +1
Здравствуйте, Temoto, Вы писали:

T>Просто я давно не читал код с абстрактными классами и методами. Вот и забыл.


Ага, и при этом обвиняешь оппонентов, что у них глаза замылены

T>>>А если void *func, то это не полиморфизм

AVK>>Разница только в типизации. Принципиально ничего не меняется.

T>Да, ну вот я так для себя определился, что полиморфизм это с типизацией.


Ну, знаешь ... Ты для себя определения какие хочешь можешь придумывать, но уж если хочешь, чтобы тебя поняли, стоит использовать общепринятые.

T> А без типизации это машинный код — что хочешь куда хочешь


Да нет. Динамических языков хватает, но машинным кодом их не назовешь.
... << RSDN@Home 1.2.0 alpha 4 rev. 1421 on Windows 7 6.1.7600.0>>
AVK Blog
Re[46]: Быстро превратить интерпретатор в компилятор
От: Temoto  
Дата: 01.02.10 23:08
Оценка:
T>>Я подумал и получается, что нет, это не полиморфизм, потому что он неконтроллируемый (я ведь могу указатель на любую функцию сунуть в эту структуру).

ВВ>Объяви да засовывай только то, что нужно:


Отлично, значит в си он поддерживается.

T>>Мне не кажется, что дизайн языка должен быть из одной чистой парадигмы, поэтому я не считаю, что обсуждаемые плюшки в некоторых функциональных языках пришлое и чужое.


ВВ>Ну такая точка зрения тоже имеет место быть. Вот, к примеру, у твоего второго оппонента

ВВ>Да, языки с мульти-парадигмой, отлично.

ВВ>Но, погодите, ведь это означает, что язык *изначально проектировался* как "гибридный", а не как ФЯ? Т.е. о нем уже некорректно говорить как просто об ФЯ. Это гибридный язык. Поддерживающий ФП и ООП. Вот опять немерле в голову лезет.


Все гибридные, потому что во всех есть больше одной парадигмы. Следовательно, все проектировались как гибридные. Вообще, это логично. Язык из какой-нибудь одной чистой парадигмы полезен только для исследования этой самой парадигмы. (как-то непонятно, надо это обосновывать или нет)

ВВ>А лягут ли хорошо ООП "плюшки" в ФЯ язык (не буду употреблять слово "чистый", раз уж оно тебе не нравится), который все же изначально проектировался как ФЯ?


Не думаю, что есть такие языки, которые изначально проектировались под одну ФП, а потом в них добавили ООП. Может лягут, может нет. Это неважно, потому что на практике все изначально гибридные в любом случае.

ВВ>>>У нас есть универсальный механизм — указатель на функцию. В тех случаях, когда требуется колл-бек — передаем просто указатель. В тех, когда требуется описать полиморфную структуру — описываем ее как "словарь" указателей на функции. Абсолютно универсальное и удобное средство. Проверьте.

T>>Ну да, если убрать слово указатель, то это лямбда исчисление. Всё из функций, даже рыбы и медузы.

ВВ>Вот чем такая позиция отличается от вашей? ИМХО налицо определенное сходство.


Ну тем что я не стремлюсь в крайности. Я хочу и интерфейсы, и абстракции. Ещё хочу писать инварианты для типов и функций. В общем я не против сообщить компилятору максимум информации о своих намерениях. Он неподкупен и непоколебим, пущай проверяет мой код.

ВВ>>>Зачем требуется наследование, виртуальные функции, интерфейсы, делегаты, лямбды, бла-бла-бла?

T>>Это очень простой вопрос. Всё это нужно для проверки кода на корректность и для оптимизаций (в т.ч. компиляции в машинный код).

ВВ>Проверку кода на корректность можно делать и без этого.


Как?

ВВ> А по поводу оптимизаций — извините, что из перечисленного используется для *оптимизации*? Вы ничего не путаете? Скорее всего, наоборот. Подлинный сишник, например, скажет, что это все мега-зло и мешает ему писать заоптимизированные до смерти "большие системы". И в чем-то будет прав, кстати. Если речь идет, скажем, о ядре ОС.


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

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

ВВ>Ну насколько там F# от C# отстает

ВВ>А вообще нуна эту вашу табличку Это тест компиляторов по большей части. Добавьте туда "взрослый" промышленный компилятор C++ вроде VC или Intel CPP, и он порвет всех остальных как тузик грелку.

Да, было бы интересно поглядеть на результат интеловского. Но gcc тоже как бы не ребёнок.

T>>Про варианты это надо конкретные языки назвать?

ВВ>Другие варианты построения "больших систем". Без ОО. А так получается, что ОО вроде бы и нет, а вроде он и есть. Я разницы не вижу. В упор.

Ну вряд ли я в одном посте тут напишу большую систему, да? Но есть одна хорошая статейка, где рассказывают какой бывает вроде бы ОО, но не ОО. Мне очень жаль, что мой кругозор "других подходов" ограничивается, по большому счёту одним, который используется в хаскеле. Пожалуйста, не поймите как будто я предлагаю его как панацею.
http://www.haskell.org/haskellwiki/OOP_vs_type_classes

ВВ>Так ООП это ведь не одно средство, а скорее набор средств, аккуратно уложенных в коробочку, согласно некоторой "концепции". Ты (в лучшем случае) предлагаешь те же самые средства в другой коробочке. И зачем оно?


Во-первых, однозначно полезно для расширения кругозора. Можно сказать, что это самое главное.
Во-вторых, есть мнение (в статейке обосновано), что такая система более выразительна, чем те же средства в коробочке ООП. Тут я не могу как-то подтвердить или опровергнуть, потому что не достигал глубин ОО классов и объектов. Но этот вариант гибче, это сразу чувствуется. И эта гибкость приятна.

T>>- несогласен, нужны части, а не конкретное воплощение ... и поехало.


ВВ>Если речь идет о том, можно ли вообще, т.е. в принципе, писать большие системы на не-ОО языках, то да — можно. На Си же пишут. И даже не в ОО-стиле пишут.


Честно говоря, я всегда удивлялся как людям удаётся поддерживать несколько миллионов строк на си.

ВВ>А так, ну да, нужны части. А часто нужны все части. А часто еще нужно, чтобы все эти части хорошо вписывались в дизайн языка. И так далее. И если у вас все это есть — значит язык поддерживает ОО-парадигму. Разве нет?


Нет, потому что ООП это связь частей определённым образом (классы, интерфейсы и объекты, одни не имеют смысла без других). В хаскеле другим способом (интерфейсы, типы и функции, все отдельно), когда есть больше независимых компонентов, из можно слепить больше разных странных штуковин. Ну и серьёзных, полезных тоже.
Re[49]: Быстро превратить интерпретатор в компилятор
От: Воронков Василий Россия  
Дата: 01.02.10 23:09
Оценка: +1
Здравствуйте, Temoto, Вы писали:

T>>>Ну понятно, в общем, там в другом ответе я [для себя] сформулировал это так, что передача аргументов разных типов и при этом контроллируемая системой типов, а не if-ами программиста, это да, поддержка полиморфизма в языке.

T>>>А если void *func, то это не полиморфизм, а просто отсутствие ограничений. Вот думаю над разными примерами, пока что меня такое разделение устраивает.
ВВ>>Т.е. полиморфизм это или нет зависит от кривизны рук программиста? Да, не укажешь явно список параметров — проверки не будет. Так не делайте так. За объявление указателя на функцию в виде void* вообще-то бьют по рукам линейкой.

T>Не, я имел в виду, позволяет ли язык контролировать набор типов, который можно сунуть в функцию или нет. Вот Си позволяет, а лисп и питон — нет, вот о чём речь.


T>И FooStream.Read(10) нельзя, потому что int — не объект, да?


Почему же? Это вам не Си, где "общего" типа данных нет, только через указатель В дотнете System.Object это что угодно, и тип по значению, и тип по ссылке. int в понятиях дотнета — полноценный объект.

Сигнатура выше означает, проще говоря, что метод возвращает что угодно и принимает какое угодно количество параметров (от нуля до бесконечности), какого угодно типа.
Т.е. язык-то вообще типобезопасный, но учудить подобные выкрутасы можно легко. И все равно же это полиморфизм. Ведь, согласись, не зависит же это от того, насколько "красиво" и по правилам мы описываем функции? Поэтому я лично не уверен, что типобезопасность здесь является критерием. В Джаваскрипте вот есть полиморфизм? По-моему вполне

Короче, "полиморфизм на function pointers" — это плюшка или эмуляция?
А ответив на этот вопрос, можешь заодно подумать над такой проблемкой.

Вот был (ну впрочем и есть) язык Си. Старенький такой язык. Довольно простой причем, изучать легко. Все нужные ООП плюшки в этом языке есть. Тем не менее энное время назад мужики собрались, подумали и решили, что при проектировании "больших систем" (tm) Си не очень-то удобен. Думали, думали и придумали С++. Казалось бы, зачем? Какой смысл? Многие до сих пор кричат, что на Си можно спокойно писать в ОО-ключе, при этом код получается типа более быстрый и не такой заморченный как на С++. Создание С++ было ошибкой?

Другая история. Давным-давно были так называемый функциональные языки. И поддерживали эти языки такие отличные плюшки как "полиморфизм", "инкапсуляция"...
Re[47]: Быстро превратить интерпретатор в компилятор
От: Воронков Василий Россия  
Дата: 01.02.10 23:41
Оценка:
Здравствуйте, Temoto, Вы писали:

ВВ>>Но, погодите, ведь это означает, что язык *изначально проектировался* как "гибридный", а не как ФЯ? Т.е. о нем уже некорректно говорить как просто об ФЯ. Это гибридный язык. Поддерживающий ФП и ООП. Вот опять немерле в голову лезет.

T>Все гибридные, потому что во всех есть больше одной парадигмы. Следовательно, все проектировались как гибридные. Вообще, это логично. Язык из какой-нибудь одной чистой парадигмы полезен только для исследования этой самой парадигмы. (как-то непонятно, надо это обосновывать или нет)

Т.е. теперь новый тезис — все языки гибридные? А давайте не будем вводить новые термины и скажем проще:

Есть ООЯ, которые изначально проектировались без учета ФП (например, C# 1.0), а есть ФЯ, которые проектировались без учета ООП.

Так согласны?

ВВ>>А лягут ли хорошо ООП "плюшки" в ФЯ язык (не буду употреблять слово "чистый", раз уж оно тебе не нравится), который все же изначально проектировался как ФЯ?

T>Не думаю, что есть такие языки, которые изначально проектировались под одну ФП, а потом в них добавили ООП. Может лягут, может нет. Это неважно, потому что на практике все изначально гибридные в любом случае.

Да? Мне кажется, большинство ФЯ, хотя бы в силу возраста, проектировались без учета ООП. По причине отсутствия последнего как класс.

T>Ну тем что я не стремлюсь в крайности. Я хочу и интерфейсы, и абстракции. Ещё хочу писать инварианты для типов и функций. В общем я не против сообщить компилятору максимум информации о своих намерениях. Он неподкупен и непоколебим, пущай проверяет мой код.


Тебе не посещает искорка сомнения, что те самый ОО "плюшки" в ФЯ — это на самом деле прообразы современного ООП по сути. Просто плюшки развились в полноценную концепцию. Твои же аргументы ну абсолютно ничем не отличаются от аргументов Сишника "в защиту Си", которые предлагает людям, пишущим на С++, забыть о своих "привычках" и обратить свои взоры к "новому", а именно — к ОО "плюшкам" в Си.

Смешно, да? А я серьезно. Вот ты мне объясни, чем твоя позиция-то отличается. Я правда не вижу разницы.

ВВ>>>>Зачем требуется наследование, виртуальные функции, интерфейсы, делегаты, лямбды, бла-бла-бла?

T>>>Это очень простой вопрос. Всё это нужно для проверки кода на корректность и для оптимизаций (в т.ч. компиляции в машинный код).
ВВ>>Проверку кода на корректность можно делать и без этого.
T>Как?

Ну в Си-то как-то делают проверки без всего вышеперечисленного. И как бы никто не мешает на то же шарпе (или вообще на немерле) писать типобезопасный статически-типизированный код со всеми нужными "проверками" без всего вышеперечисленного опять же.
Скажи, какие тебе конкретно "проверки" нужны — рассудим.

ВВ>> А по поводу оптимизаций — извините, что из перечисленного используется для *оптимизации*? Вы ничего не путаете? Скорее всего, наоборот. Подлинный сишник, например, скажет, что это все мега-зло и мешает ему писать заоптимизированные до смерти "большие системы". И в чем-то будет прав, кстати. Если речь идет, скажем, о ядре ОС.

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

Гм, вообще те же виртуальные ф-ции скорее мешают оптимизатору. Вот в том же Шарпе мешают сильно (не инлайнятся гады). Навороченные вроде VC компиляторы С++ еще как-то справляются, да и то не все. Делегаты — вообще странная оптизимация. Наоборот перформанс хит. А вот указатели на функции в Си — никакого тебе перформанс хита, все просто. Так что, не очень понятно, честно говоря.

T>Что из этого.. ух, хороший вопрос, боюсь тут ошибиться, но пример будет такой, что интерфейсы позволяют во время компиляции вычислить адрес процедуры, которая обрабатывает именно эти типы аргументов. А без интерфейсов в питоне приходится во время каждого вызова это делать.


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

ВВ>>Ну насколько там F# от C# отстает

ВВ>>А вообще нуна эту вашу табличку Это тест компиляторов по большей части. Добавьте туда "взрослый" промышленный компилятор C++ вроде VC или Intel CPP, и он порвет всех остальных как тузик грелку.
T>Да, было бы интересно поглядеть на результат интеловского. Но gcc тоже как бы не ребёнок.

Тесты есть на сайте (еле нашел):

Раз: http://rsdn.ru/article/devtools/perftest.xml
Автор(ы): Владислав Чистяков

Два: http://rsdn.ru/article/devtools/perftest2.xml
Автор(ы): Владислав Чистяков

Три: http://rsdn.ru/article/devtools/perftest3.xml
Автор(ы): Владислав Чистяков


Что характерно, там реальные примеры с результами по этим примерам, а не сводная табличка.
В первом как раз есть VC, C#, gcc, Intel. И Шарп, что характерно, не так уж и бледно выглядит. Причем это еще старый 1.0 компилятор, а с тех пор орлы из МС много чего заооптимизировали.

К тому же все это Влад писал, так что можешь прям тут с ним и обсудить

T>>>Про варианты это надо конкретные языки назвать?

ВВ>>Другие варианты построения "больших систем". Без ОО. А так получается, что ОО вроде бы и нет, а вроде он и есть. Я разницы не вижу. В упор.

T>Ну вряд ли я в одном посте тут напишу большую систему, да? Но есть одна хорошая статейка, где рассказывают какой бывает вроде бы ОО, но не ОО. Мне очень жаль, что мой кругозор "других подходов" ограничивается, по большому счёту одним, который используется в хаскеле. Пожалуйста, не поймите как будто я предлагаю его как панацею.

T>http://www.haskell.org/haskellwiki/OOP_vs_type_classes

ВВ>>Так ООП это ведь не одно средство, а скорее набор средств, аккуратно уложенных в коробочку, согласно некоторой "концепции". Ты (в лучшем случае) предлагаешь те же самые средства в другой коробочке. И зачем оно?


T>Во-первых, однозначно полезно для расширения кругозора. Можно сказать, что это самое главное.

T>Во-вторых, есть мнение (в статейке обосновано), что такая система более выразительна, чем те же средства в коробочке ООП. Тут я не могу как-то подтвердить или опровергнуть, потому что не достигал глубин ОО классов и объектов. Но этот вариант гибче, это сразу чувствуется. И эта гибкость приятна.

Ну так надо достигнуть. "Мнение в статейке" это всегда не самый надежный источник информации. Тут на сайте столько статей со своими мнения, что можно мозги вывихнуть. А кругозор мы себе и так расширяем потихоньку. Ты думаешь у Влада, который сейчас чуть ли не единственный, кто немерле тянет, кругозора по ФЯ не хватает?

T>>>- несогласен, нужны части, а не конкретное воплощение ... и поехало.

ВВ>>Если речь идет о том, можно ли вообще, т.е. в принципе, писать большие системы на не-ОО языках, то да — можно. На Си же пишут. И даже не в ОО-стиле пишут.
T>Честно говоря, я всегда удивлялся как людям удаётся поддерживать несколько миллионов строк на си.

Ты про Линукс?
Много народу, много сил, много денег, жесткие порядки. Все можно, если есть люди и деньги.

ВВ>>А так, ну да, нужны части. А часто нужны все части. А часто еще нужно, чтобы все эти части хорошо вписывались в дизайн языка. И так далее. И если у вас все это есть — значит язык поддерживает ОО-парадигму. Разве нет?

T>Нет, потому что ООП это связь частей определённым образом (классы, интерфейсы и объекты, одни не имеют смысла без других). В хаскеле другим способом (интерфейсы, типы и функции, все отдельно), когда есть больше независимых компонентов, из можно слепить больше разных странных штуковин. Ну и серьёзных, полезных тоже.

Хочется, чтобы ты показал (желательно с учетом того, что тот же Хаскель тут могут знать далеко не все), что ОО система в этом языке это действительно развитие концепций ОО, а не прикрученный к бабе...
Re[47]: Быстро превратить интерпретатор в компилятор
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.02.10 23:52
Оценка:
Здравствуйте, Temoto, Вы писали:

T>Язык из какой-нибудь одной чистой парадигмы полезен только для исследования этой самой парадигмы. (как-то непонятно, надо это обосновывать или нет)


А как же С?

T>Не думаю, что есть такие языки, которые изначально проектировались под одну ФП, а потом в них добавили ООП. Может лягут, может нет. Это неважно, потому что на практике все изначально гибридные в любом случае.


ML -> Caml -> OCaml

T>Ну тем что я не стремлюсь в крайности. Я хочу и интерфейсы, и абстракции. Ещё хочу писать инварианты для типов и функций. В общем я не против сообщить компилятору максимум информации о своих намерениях. Он неподкупен и непоколебим, пущай проверяет мой код.


Ну, тогда остается сообщить ему что у тебя в мыслях есть объекты...

T>Ну вряд ли я в одном посте тут напишу большую систему, да? Но есть одна хорошая статейка, где рассказывают какой бывает вроде бы ОО, но не ОО. Мне очень жаль, что мой кругозор "других подходов" ограничивается, по большому счёту одним, который используется в хаскеле. Пожалуйста, не поймите как будто я предлагаю его как панацею.

T>http://www.haskell.org/haskellwiki/OOP_vs_type_classes

Спасибо за отличную статью демонстрирующую реальные примеры эмуляции. Особенно показательно выглядит раздел "5 Haskell emulation of OOP inheritance with record extension". Где для примитивного и совершенно понятного примера на С++:
    class A {
    public:
        String s;
        Int i;
 
        A(String s, Int i) s(s), i(i){}
 
        virtual void Display(){
            printf("A %s %d\n", s.c_str(), i);
        }
 
        virtual Int Reuse(){
            return i * 100;
        }
    };
 
 
    class B: public A{
    public:
        Char c;
 
        B(String s, Int i, Char c) : A(s, i), c(c){}
 
        virtual void Display(){
            printf("B %s %d %c", s.c_str(), i, c);
        }
 
        virtual void Extra(){
            printf("B Extra %d\n", Reuse());
        }
 
    };

Дается версия эмуляции его на Хаскеле:
data A = A
                { _A_s :: String
                , _A_i :: Int
                }
 
-- This could do arg checking etc
constructA :: String -> Int -> A
constructA = A
 
 
class ClassA a where
    getA :: a -> A
 
    display :: a -> IO ()
    display a = do
        let
            A{_A_s = s, _A_i = i} = getA a
        putStrLn $ "A " ++ s ++ show i
 
    reuse :: a -> Int
    reuse a = _A_i (getA a) * 100
 
 
data WrapA = forall a. ClassA a => WrapA a
 
instance ClassA WrapA where
    getA (WrapA a) = getA a
    display (WrapA a) = display a
    reuse (WrapA a) = reuse a
 
instance ClassA A where
    getA = id
 
 
data B = B { _B_A :: A, _B_c :: Char }
 
 
constructB :: String -> Int -> Char -> B
constructB s i c = B {_B_A = constructA s i, _B_c = c}
 
class ClassA b => ClassB b where
    getB :: b -> B
 
    extra :: b -> IO ()
    extra b = do
        putStrLn $ "B Extra " ++ show (reuse b)
 
data WrapB = forall b. ClassB b => WrapB b
 
instance ClassB WrapB where
    getB (WrapB b) = getB b
    extra (WrapB b) = extra b
 
instance ClassA WrapB where
    getA (WrapB b) = getA b
    display (WrapB b) = display b
    reuse (WrapB b) = reuse b
 
instance ClassB B where
    getB = id
 
instance ClassA B where
    getA = _B_A
 
    -- override the base class version
    display b = putStrLn $
                "B " ++ _A_s (getA b)
                ++ show (_A_i (getA b))
                ++ [_B_c (getB b)]


Если версия на хаскеле кому-то кажется понятнее и проще в разработке/поддержке, то я уже и не знаю что сказать.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[50]: Быстро превратить интерпретатор в компилятор
От: Temoto  
Дата: 02.02.10 13:10
Оценка:
T>>Не, я имел в виду, позволяет ли язык контролировать набор типов, который можно сунуть в функцию или нет. Вот Си позволяет, а лисп и питон — нет, вот о чём речь.

T>>И FooStream.Read(10) нельзя, потому что int — не объект, да?


ВВ>Почему же? Это вам не Си, где "общего" типа данных нет, только через указатель В дотнете System.Object это что угодно, и тип по значению, и тип по ссылке. int в понятиях дотнета — полноценный объект.


Может быть я путаю с Java, но, по-моему в C# 2 int тоже был скалярным типом, не объектом.

ВВ>Сигнатура выше означает, проще говоря, что метод возвращает что угодно и принимает какое угодно количество параметров (от нуля до бесконечности), какого угодно типа.

ВВ>Т.е. язык-то вообще типобезопасный, но учудить подобные выкрутасы можно легко. И все равно же это полиморфизм. Ведь, согласись, не зависит же это от того, насколько "красиво" и по правилам мы описываем функции? Поэтому я лично не уверен, что типобезопасность здесь является критерием. В Джаваскрипте вот есть полиморфизм? По-моему вполне

Да, можно написать плохую сигнатуру. Но можно и хорошую. А когда проверок нет, то хорошую написать невозможно, все будут как эта.

В динамических языках я не знаю как судить. Проверок вообще нет. Как тут может отсутствовать полиморфизм, если компилятор не проверяет типы аргументов? Может быть, можно сказать, что динамическая типизация подразумевает полиморфизм. Но это неконструктивно, потому что проверок-то нет. Не знаю. Может быть можно сказать, что говорить о полиморфизме не имеет смысла в рамках динамических языков, как не имеет смысла применить операцию деления к строке.

ВВ>Короче, "полиморфизм на function pointers" — это плюшка или эмуляция?


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

ВВ>А ответив на этот вопрос, можешь заодно подумать над такой проблемкой.

ВВ>Вот был (ну впрочем и есть) язык Си. Старенький такой язык. Довольно простой причем, изучать легко. Все нужные ООП плюшки в этом языке есть. Тем не менее энное время назад мужики собрались, подумали и решили, что при проектировании "больших систем" (tm) Си не очень-то удобен. Думали, думали и придумали С++. Казалось бы, зачем? Какой смысл? Многие до сих пор кричат, что на Си можно спокойно писать в ОО-ключе, при этом код получается типа более быстрый и не такой заморченный как на С++. Создание С++ было ошибкой?

Плюсы были ошибкой, да. Это довольно популярное мнение, кстати. Есть сторонники и противники. По-моему, более интересны проекты типа Amplify-C, SC, Vala, то есть некоторый мета-язык, из которого генерится код на си, с которым работает обычный сишный компилятор. Похоже на то что си по отношению к ассемблеру.

ВВ>Другая история. Давным-давно были так называемый функциональные языки. И поддерживали эти языки такие отличные плюшки как "полиморфизм", "инкапсуляция"...


И ничего не срослось, все используют сишарп вместо лиспа? Думаю, что тут для каждого языка, для каждого проекта своя правда. И инерция в человеческих умах очень важна, и менеджеры не пойдут на риски начинать проект на языке, который никто не знает. Не только и не столько сами языки, их качество и плюшки, влияют на их популярность.
Re[51]: Быстро превратить интерпретатор в компилятор
От: Воронков Василий Россия  
Дата: 02.02.10 13:37
Оценка:
Здравствуйте, Temoto, Вы писали:

ВВ>>Почему же? Это вам не Си, где "общего" типа данных нет, только через указатель В дотнете System.Object это что угодно, и тип по значению, и тип по ссылке. int в понятиях дотнета — полноценный объект.

T>Может быть я путаю с Java, но, по-моему в C# 2 int тоже был скалярным типом, не объектом.

И в джава, и в С# начиная с самой первой версии int — это скалярный тип, который так же является объектом. Епт, мужик, это ООП, все есть объект, что тебя удивляет?

T>Да, можно написать плохую сигнатуру. Но можно и хорошую. А когда проверок нет, то хорошую написать невозможно, все будут как эта.

T>В динамических языках я не знаю как судить. Проверок вообще нет. Как тут может отсутствовать полиморфизм, если компилятор не проверяет типы аргументов? Может быть, можно сказать, что динамическая типизация подразумевает полиморфизм. Но это неконструктивно, потому что проверок-то нет. Не знаю. Может быть можно сказать, что говорить о полиморфизме не имеет смысла в рамках динамических языков, как не имеет смысла применить операцию деления к строке.

Нет, можно сказать, что если в динамических языках есть специальные средства (какие, к примеру, есть в Джава-скрипте) с помощью которых можно добиваться полиморфизма, то полиморфизм в них есть. А примешивать сюда типобезопасность мне кажется излишним. Блин, да тот же лисп — это динамический язык.
В общем ты рискуешь придумать определение, с которым никто, кроме тебя, не согласен.

ВВ>>Короче, "полиморфизм на function pointers" — это плюшка или эмуляция?

T>Я думаю, что тут как с лиспом. Встроенных в язык плюшек нет. Но он достаточно гибкий, чтобы эмулировать эти плюшки в рамках самого языка, *без костылей* — это очень важный момент.

ВВ>>А ответив на этот вопрос, можешь заодно подумать над такой проблемкой.

ВВ>>Вот был (ну впрочем и есть) язык Си. Старенький такой язык. Довольно простой причем, изучать легко. Все нужные ООП плюшки в этом языке есть. Тем не менее энное время назад мужики собрались, подумали и решили, что при проектировании "больших систем" (tm) Си не очень-то удобен. Думали, думали и придумали С++. Казалось бы, зачем? Какой смысл? Многие до сих пор кричат, что на Си можно спокойно писать в ОО-ключе, при этом код получается типа более быстрый и не такой заморченный как на С++. Создание С++ было ошибкой?

T>Плюсы были ошибкой, да. Это довольно популярное мнение, кстати. Есть сторонники и противники. По-моему, более интересны проекты типа Amplify-C, SC, Vala, то есть некоторый мета-язык, из которого генерится код на си, с которым работает обычный сишный компилятор. Похоже на то что си по отношению к ассемблеру.


То, что есть много популярных мнений разного толка я не спорю. Ты просто изначально определись, к какому лагерю ты относишься. С++ — это деградация по отношению к Си? Или это язык, испорченный обратной совместимостью и нужен еще более высокоуровневый и более ОО язык? Или что-то третье?
Что такое SC и Vala я не знаю, а причем Amplifying C мне непонятно. Это проект прикручивающий к С *текстовые* макросы с более навороченным синтаксисом. Текстовые, понимаешь? Офигенный прогресс.

Хоть бы Objective-C в противовес привел, я бы понял

ВВ>>Другая история. Давным-давно были так называемый функциональные языки. И поддерживали эти языки такие отличные плюшки как "полиморфизм", "инкапсуляция"...


T>И ничего не срослось, все используют сишарп вместо лиспа?


Ну в принципе так и есть. Но дело тут не в том, что все используют, а в том, что те самые "плюшки", которые ты видишь в ФП, развились в полноценную парадигму, которая называется ООП. Поэтому как раз C# — это прогресс в ОО по отношению к Хаскелю, а не Хаскель "границы сознания" расширяет.

А ты, повторюсь, говоришь как тот фанатик, который пытается всех убедить, что на С удобнее писать ОО-код, чем на С++. "Довольно популярное мнение, кстати". Только подумай — ты реально хочешь выступать в роли клоуна? Может быть, не стоит?

T>Думаю, что тут для каждого языка, для каждого проекта своя правда. И инерция в человеческих умах очень важна, и менеджеры не пойдут на риски начинать проект на языке, который никто не знает. Не только и не столько сами языки, их качество и плюшки, влияют на их популярность.


Причем тут инерция в умах? Ты тут всех обвиняешь в закоснелости взглядов и инерции, при этом, извини, но по твоим постам складывается впечатление, что с ОО-языками ты знаком, вообще говоря, слабо. Может быть, правда стоит расширить кругозор? Посмотреть, что люди придумали после Хаскеля?

Я в ФП никаких средств, хотя бы приближающихся к ОО для проектирования не нашел. При этом подходил к вопросу с большим лимитом доверия, ибо есть к ОО некоторые претензии. А ты сам-то способен объективно сравнить имитацию (simulation, термин из твоей статейки) ОО из ФЯ и полноценный ОО в том же C#?
Re[52]: Быстро превратить интерпретатор в компилятор
От: Temoto  
Дата: 02.02.10 14:45
Оценка:
ВВ>В общем ты рискуешь придумать определение, с которым никто, кроме тебя, не согласен.

Верно, пора мне прекратить придумывать определение полиморфизма, всё равно от этого ничего не зависит.

T>>Плюсы были ошибкой, да. Это довольно популярное мнение, кстати. Есть сторонники и противники. По-моему, более интересны проекты типа Amplify-C, SC, Vala, то есть некоторый мета-язык, из которого генерится код на си, с которым работает обычный сишный компилятор. Похоже на то что си по отношению к ассемблеру.


ВВ>То, что есть много популярных мнений разного толка я не спорю. Ты просто изначально определись, к какому лагерю ты относишься. С++ — это деградация по отношению к Си? Или это язык, испорченный обратной совместимостью и нужен еще более высокоуровневый и более ОО язык? Или что-то третье?


Как проект, это развитие, однозначно. Просто сделано ужасно. Когда в нотации шаблонов надо разделять угловые скобки, потому что они совпадают с оператором, не знаю кому как, для меня это просто очевидный баг в парсере. А сообщения об ошибках от шаблонов в сотни килобайт и увеличение времени компиляции на порядки это вот "сделано ужасно". Тем не менее, простые ОО вещи, которые на си выглядят более уродливо, в плюсах вполне хороши. Можно так сформулировать: я считаю, что Objective-C это плюсы, сделанные правильно. (с obj-c знаком очень поверхностно, могу ошибаться)

ВВ>Что такое SC и Vala я не знаю, а причем Amplifying C мне непонятно. Это проект прикручивающий к С *текстовые* макросы с более навороченным синтаксисом. Текстовые, понимаешь? Офигенный прогресс.


Vala это гномский проект. В двух словах, они добавили в си ООП. Может быть, я что-то неправильно понял про Amplify-C, но по описанию макросы не текстовые, а AST, как в лиспе, синтаксис которого в нём и используется. Может быть мы про разные проекты говорим.

ВВ>Хоть бы Objective-C в противовес привел, я бы понял


Насколько я знаю, это отдельный язык, с отдельным компилятором. Как плюсы сегодня. А я говорил именно о трансляторе в си.

ВВ>>>Другая история. Давным-давно были так называемый функциональные языки. И поддерживали эти языки такие отличные плюшки как "полиморфизм", "инкапсуляция"...


T>>И ничего не срослось, все используют сишарп вместо лиспа?


ВВ>Ну в принципе так и есть. Но дело тут не в том, что все используют, а в том, что те самые "плюшки", которые ты видишь в ФП, развились в полноценную парадигму, которая называется ООП. Поэтому как раз C# — это прогресс в ОО по отношению к Хаскелю, а не Хаскель "границы сознания" расширяет.

ВВ>А ты, повторюсь, говоришь как тот фанатик, который пытается всех убедить, что на С удобнее писать ОО-код, чем на С++. "Довольно популярное мнение, кстати". Только подумай — ты реально хочешь выступать в роли клоуна? Может быть, не стоит?

А я повторюсь, что я не фанатик, никого не убеждаю писать на хаскеле. Две вещи, в чём я пытаюсь убедить:
1. не стоит замыкаться на достигнутом знании (ООП), стоит быть открытым для новых. Думаю, что примерно так же
2. классы и объекты — это не единственный способ проектировать большие системы.

Здесь нигде не написано слово "хаскель". И я уже говорил, что, к моему огромному сожалению, я знаю только один подход, который не менее выразителен и при этом действительно отличается от ОО с объектами.

Надеюсь, что в этих двух посылах и вы тоже не видите клоунады.

T>>Думаю, что тут для каждого языка, для каждого проекта своя правда. И инерция в человеческих умах очень важна, и менеджеры не пойдут на риски начинать проект на языке, который никто не знает. Не только и не столько сами языки, их качество и плюшки, влияют на их популярность.


ВВ>Причем тут инерция в умах? Ты тут всех обвиняешь в закоснелости взглядов и инерции, при этом, извини, но по твоим постам складывается впечатление, что с ОО-языками ты знаком, вообще говоря, слабо. Может быть, правда стоит расширить кругозор? Посмотреть, что люди придумали после Хаскеля?


Я не обвиняю, не всех и не тут. Речь была про нераспространённость.. наверное, лиспа и ML, потому что вы сказали
Да не, я просто забыл их. Раньше писал на делфи, немного на плюсах и на шарпе. А сейчас, в основном, на питоне, классы пишу ну очень редко.

Пытаюсь смотреть что придумали после хаскеля, но это очень жесткая научная литература, часто не хватает образования чтобы понимать.

ВВ>Я в ФП никаких средств, хотя бы приближающихся к ОО для проектирования не нашел. При этом подходил к вопросу с большим лимитом доверия, ибо есть к ОО некоторые претензии. А ты сам-то способен объективно сравнить имитацию (simulation, термин из твоей статейки) ОО из ФЯ и полноценный ОО в том же C#?


Симуляция ОО в хаскеле — унылое говно (так же, как симуляция лямбд в Java, enum-ов в питоне, и пр. симуляции). В статье она показана как аргумент в споре. Один мужик сказал, что нельзя переопределить реализацию в отнаследованном "классе", а другой доказал что можно, через неверооятный гемор. Вы приводили подобный пример с эмуляцией полиморфизма в Си через структуру и набор функций в ней, только он не настолько ужасен как тут. Но иллюстрирует то же самое. Си и хаскель не поддерживают ООП (с объектами).

Есть такая отличная пословица: в чужой монастырь со своим уставом не лезут. Хаскельные классы типов это другое средство, к нему не подходит ОО мышление. И к ним *очень сложно* приспособиться после ОО опыта. Я серьёзно, требуется либо сломать себе мозг, либо забыть всё, что знал.

А ваши претензии к ОО, кстати, не заключаются ли как раз в наследовании реализаций методов, которые в наследнике зачастую не имеют смысла?
Re[53]: Быстро превратить интерпретатор в компилятор
От: Воронков Василий Россия  
Дата: 02.02.10 15:14
Оценка: +1
Здравствуйте, Temoto, Вы писали:

ВВ>>В общем ты рискуешь придумать определение, с которым никто, кроме тебя, не согласен.

T>Верно, пора мне прекратить придумывать определение полиморфизма, всё равно от этого ничего не зависит.

Ну как же. Мы ведь пытаемся разобраться, если ты не забыл, не является ли то самое "ОО без объектов" примерно теми же яйцами, которые есть в Си. Тебе бы по хорошему именно эту позицию обосновать, а не пытаться доказать, что "полиморфизм" есть и без ОО с классами, и без классов тоже можно писать.
Ну можно. Ок. Раньше писали. И сейчас пишут. Дальше что?

T>Как проект, это развитие, однозначно. Просто сделано ужасно. Когда в нотации шаблонов надо разделять угловые скобки, потому что они совпадают с оператором, не знаю кому как, для меня это просто очевидный баг в парсере. А сообщения об ошибках от шаблонов в сотни килобайт и увеличение времени компиляции на порядки это вот "сделано ужасно".


А причем тут шаблоны?

T>Тем не менее, простые ОО вещи, которые на си выглядят более уродливо, в плюсах вполне хороши. Можно так сформулировать: я считаю, что Objective-C это плюсы, сделанные правильно. (с obj-c знаком очень поверхностно, могу ошибаться)


"Простые" ОО вещи — это какие? А сложные как выглядят? (Ты, кстати, ведь понимаешь, что шаблоны к ОО никаким боком).

T>Vala это гномский проект. В двух словах, они добавили в си ООП. Может быть, я что-то неправильно понял про Amplify-C, но по описанию макросы не текстовые, а AST, как в лиспе, синтаксис которого в нём и используется. Может быть мы про разные проекты говорим.


Речь об этом? http://voodoo-slide.blogspot.com/2010/01/amplifying-c.html
Я там не вижу подтверждений того, что этот самый aplify-c строит дерево исходников на Си именно. Проблема дефайнов не в том, что там синтаксис лиспа не используется, а в том, что они совершают по сути текстовую подстановку. Очевидно, что здесь происходит то же самое, раз речь не идет о создании нового компилятора Си. Но вот насколько это подстановка "умная" — хз.

ВВ>>Ну в принципе так и есть. Но дело тут не в том, что все используют, а в том, что те самые "плюшки", которые ты видишь в ФП, развились в полноценную парадигму, которая называется ООП. Поэтому как раз C# — это прогресс в ОО по отношению к Хаскелю, а не Хаскель "границы сознания" расширяет.

ВВ>>А ты, повторюсь, говоришь как тот фанатик, который пытается всех убедить, что на С удобнее писать ОО-код, чем на С++. "Довольно популярное мнение, кстати". Только подумай — ты реально хочешь выступать в роли клоуна? Может быть, не стоит?

T>А я повторюсь, что я не фанатик, никого не убеждаю писать на хаскеле. Две вещи, в чём я пытаюсь убедить:

T>1. не стоит замыкаться на достигнутом знании (ООП), стоит быть открытым для новых. Думаю, что примерно так же

Кто сказал, что здесь кто-то замыкается на каком-то знании? И ты сам-то следуешь этому "убеждению"?

T>2. классы и объекты — это не единственный способ проектировать большие системы.


Тогда, наверное, стоит говорить не о полиморфизме, а описать альтернативные способы, так сказать, кирпичики с помощью которых можно проектировать большие системы и показать в чем их преимущество.

T>Здесь нигде не написано слово "хаскель". И я уже говорил, что, к моему огромному сожалению, я знаю только один подход, который не менее выразителен и при этом действительно отличается от ОО с объектами.

T>Надеюсь, что в этих двух посылах и вы тоже не видите клоунады.

Собственно, кроме "посылов" я вообще ничего не вижу.

ВВ>>Причем тут инерция в умах? Ты тут всех обвиняешь в закоснелости взглядов и инерции, при этом, извини, но по твоим постам складывается впечатление, что с ОО-языками ты знаком, вообще говоря, слабо. Может быть, правда стоит расширить кругозор? Посмотреть, что люди придумали после Хаскеля?

T>Я не обвиняю, не всех и не тут. Речь была про нераспространённость.. наверное, лиспа и ML, потому что вы сказали
T>Да не, я просто забыл их. Раньше писал на делфи, немного на плюсах и на шарпе. А сейчас, в основном, на питоне, классы пишу ну очень редко.
T>Пытаюсь смотреть что придумали после хаскеля, но это очень жесткая научная литература, часто не хватает образования чтобы понимать.

Учебник по C# или Джаве — это "очень жесткая научная литература"?

ВВ>>Я в ФП никаких средств, хотя бы приближающихся к ОО для проектирования не нашел. При этом подходил к вопросу с большим лимитом доверия, ибо есть к ОО некоторые претензии. А ты сам-то способен объективно сравнить имитацию (simulation, термин из твоей статейки) ОО из ФЯ и полноценный ОО в том же C#?


T>Симуляция ОО в хаскеле — унылое говно (так же, как симуляция лямбд в Java, enum-ов в питоне, и пр. симуляции). В статье она показана как аргумент в споре.


Зачем тогда ссылку на эту статью приводил? Ведь приводилась она с пафосом — вот смотрите, как еще можно без ваших шарпов сделать. Неудачный пример, значит.

T>А ваши претензии к ОО, кстати, не заключаются ли как раз в наследовании реализаций методов, которые в наследнике зачастую не имеют смысла?


Претензии заключаются в том, что ОО очень тяжелый механизм, его последовательная реализация в ряде случаев приводит к серьезному оверхеду, а в каких-то сценариях и вовсе слабо применима (например, распределенные приложения). Но я не вижу, чем тут конкретно ФП может помочь. Тут просто местами начинает рулить старая добрая процедурная парадигма, в которую в плане дизайна ФП ничего не вносит.

А если вносит — то, что, скажите мне? Вот мне надо дизайн системы сделать, на бумажке нарисовать — какие термины мне использовать?
Re[54]: Быстро превратить интерпретатор в компилятор
От: Temoto  
Дата: 02.02.10 16:50
Оценка:
ВВ>>>В общем ты рискуешь придумать определение, с которым никто, кроме тебя, не согласен.
T>>Верно, пора мне прекратить придумывать определение полиморфизма, всё равно от этого ничего не зависит.

ВВ>Ну как же. Мы ведь пытаемся разобраться, если ты не забыл, не является ли то самое "ОО без объектов" примерно теми же яйцами, которые есть в Си. Тебе бы по хорошему именно эту позицию обосновать, а не пытаться доказать, что "полиморфизм" есть и без ОО с классами, и без классов тоже можно писать.


А я именно второе и говорил. И плюс к этому, что "без классов можно писать столь же удобно". В си неудобно.

ВВ>Ну можно. Ок. Раньше писали. И сейчас пишут. Дальше что?


Да в общем-то согласие в этом пункте уже бы не породило всего этого огромного обсуждения.

T>>Как проект, это развитие, однозначно. Просто сделано ужасно. Когда в нотации шаблонов надо разделять угловые скобки, потому что они совпадают с оператором, не знаю кому как, для меня это просто очевидный баг в парсере. А сообщения об ошибках от шаблонов в сотни килобайт и увеличение времени компиляции на порядки это вот "сделано ужасно".


ВВ>А причем тут шаблоны?


Пример того, что в плюсах сделано ужасно. Понимаю, что к ОО никаким боком, да.

T>>Тем не менее, простые ОО вещи, которые на си выглядят более уродливо, в плюсах вполне хороши. Можно так сформулировать: я считаю, что Objective-C это плюсы, сделанные правильно. (с obj-c знаком очень поверхностно, могу ошибаться)


ВВ>"Простые" ОО вещи — это какие? А сложные как выглядят? (Ты, кстати, ведь понимаешь, что шаблоны к ОО никаким боком).


Простые это то, что с успехом эмулируют в си, хоть и неудобно. Заводят структуру и руками пихают её первым аргументом в набор функций с одинаковым префиксом в имени.
А сложные это то, что в си выглядит как в хаскеле наследование реализации, виртуальные методы, оверлоадинг по числу параметров и т.п.

T>>Vala это гномский проект. В двух словах, они добавили в си ООП. Может быть, я что-то неправильно понял про Amplify-C, но по описанию макросы не текстовые, а AST, как в лиспе, синтаксис которого в нём и используется. Может быть мы про разные проекты говорим.


ВВ>Речь об этом? http://voodoo-slide.blogspot.com/2010/01/amplifying-c.html


Да, речь об этом.

ВВ>Я там не вижу подтверждений того, что этот самый aplify-c строит дерево исходников на Си именно. Проблема дефайнов не в том, что там синтаксис лиспа не используется, а в том, что они совершают по сути текстовую подстановку. Очевидно, что здесь происходит то же самое, раз речь не идет о создании нового компилятора Си. Но вот насколько это подстановка "умная" — хз.


Как я понимаю, там не строится дерево исходников на си. Строится дерево Amplify-C (лиспа), а оно уже тупо конкатится в строку. Но все манипуляции происходят как в обычной лисповой программе: с деревом, не со строками.

T>>А я повторюсь, что я не фанатик, никого не убеждаю писать на хаскеле. Две вещи, в чём я пытаюсь убедить:

T>>1. не стоит замыкаться на достигнутом знании (ООП), стоит быть открытым для новых. Думаю, что примерно так же

ВВ>Кто сказал, что здесь кто-то замыкается на каком-то знании? И ты сам-то следуешь этому "убеждению"?


Уважаемый LaPerouse сказал, что ООП необходим для проектирования больших систем.
Я следую, да.

T>>2. классы и объекты — это не единственный способ проектировать большие системы.


ВВ>Тогда, наверное, стоит говорить не о полиморфизме, а описать альтернативные способы, так сказать, кирпичики с помощью которых можно проектировать большие системы и показать в чем их преимущество.


Да, верно. (для этого, кстати я и дал ссылку на сравнение классов типов с ООП)
Обешаю выкроить время и нарисовать решение какой-нибудь задачи этим "альтернативным" способом.

T>>Здесь нигде не написано слово "хаскель". И я уже говорил, что, к моему огромному сожалению, я знаю только один подход, который не менее выразителен и при этом действительно отличается от ОО с объектами.

T>>Надеюсь, что в этих двух посылах и вы тоже не видите клоунады.

ВВ>Собственно, кроме "посылов" я вообще ничего не вижу.


Моя вина, да; голословен.

T>>Я не обвиняю, не всех и не тут. Речь была про нераспространённость.. наверное, лиспа и ML, потому что вы сказали

T>>Да не, я просто забыл их. Раньше писал на делфи, немного на плюсах и на шарпе. А сейчас, в основном, на питоне, классы пишу ну очень редко.
T>>Пытаюсь смотреть что придумали после хаскеля, но это очень жесткая научная литература, часто не хватает образования чтобы понимать.

ВВ>Учебник по C# или Джаве — это "очень жесткая научная литература"?


Нет, я же говорю — после хаскеля. мы тут немного расходимся о порядке событий.

T>>Симуляция ОО в хаскеле — унылое говно (так же, как симуляция лямбд в Java, enum-ов в питоне, и пр. симуляции). В статье она показана как аргумент в споре.


ВВ>Зачем тогда ссылку на эту статью приводил? Ведь приводилась она с пафосом — вот смотрите, как еще можно без ваших шарпов сделать. Неудачный пример, значит.


Там это рассказано! Но вы спросили только о последней главе, про симуляцию. Я ответил про симуляцию. А теперь как будто вся статья только из этого и состояла.

ВВ>Тут просто местами начинает рулить старая добрая процедурная парадигма, в которую в плане дизайна ФП ничего не вносит. А если вносит — то, что, скажите мне? Вот мне надо дизайн системы сделать, на бумажке нарисовать — какие термины мне использовать?


Согласен, в проектирование функциональная парадигма ничего не вносит; я тоже вижу разницу только на уровне одного исходника.
Re[55]: Быстро превратить интерпретатор в компилятор
От: Воронков Василий Россия  
Дата: 02.02.10 17:02
Оценка:
Здравствуйте, Temoto, Вы писали:

ВВ>>Ну как же. Мы ведь пытаемся разобраться, если ты не забыл, не является ли то самое "ОО без объектов" примерно теми же яйцами, которые есть в Си. Тебе бы по хорошему именно эту позицию обосновать, а не пытаться доказать, что "полиморфизм" есть и без ОО с классами, и без классов тоже можно писать.

T>А я именно второе и говорил. И плюс к этому, что "без классов можно писать столь же удобно". В си неудобно.

А почему вот в Си неудобно? Можешь обосновать?

T>Простые это то, что с успехом эмулируют в си, хоть и неудобно. Заводят структуру и руками пихают её первым аргументом в набор функций с одинаковым префиксом в имени.

T>А сложные это то, что в си выглядит как в хаскеле наследование реализации, виртуальные методы, оверлоадинг по числу параметров и т.п.

А зачем нужно наследование реализации?
Да и вообще в Си в этом проблем никаких нет — инклюд и вперед.
Виртуальные методы суть механизм, через которые полиморфизм и реализуется. И они спокойно эмулируются через указатели.

T>Как я понимаю, там не строится дерево исходников на си. Строится дерево Amplify-C (лиспа), а оно уже тупо конкатится в строку. Но все манипуляции происходят как в обычной лисповой программе: с деревом, не со строками.


Проблема макросов, повторюсь, не в том, что сам макрос не представлен в виде лисп-дерева или чего-то там еще, а в том, что макрос работает с кодом как с *текстом*. Настоящий "правильный" макрос работает с кодом как с AST. Как в том же Лиспе. Я могу ошибаться, но в Amplify-C я такого не вижу. Ибо для этого нужно строить таки дерево исходников на Си.
А раз этого нет, то такие макросы — лишь дефайн с сиськами.

ВВ>>Кто сказал, что здесь кто-то замыкается на каком-то знании? И ты сам-то следуешь этому "убеждению"?

T>Уважаемый LaPerouse сказал, что ООП необходим для проектирования больших систем.

И ты то же самое повторил ниже.

T>Да, верно. (для этого, кстати я и дал ссылку на сравнение классов типов с ООП)

T>Обешаю выкроить время и нарисовать решение какой-нибудь задачи этим "альтернативным" способом.

Ну что ж, посмотрим.

ВВ>>Учебник по C# или Джаве — это "очень жесткая научная литература"?

T>Нет, я же говорю — после хаскеля. мы тут немного расходимся о порядке событий.

А что, C# появился до Хаскеля?

T>Согласен, в проектирование функциональная парадигма ничего не вносит; я тоже вижу разницу только на уровне одного исходника.


Э, тебе не кажется, что ты сам себе противоречишь? Речь была об ООП именно для проектирования больших систем. *Писать* большие системы можно одновременно на 10 языках, половина из которых функциональные. Здесь многие вообще использует ФЯ в работе.
Но речь-то о проектировании. И если тут по-прежнему то же, что и в ООП... Где "новые горизонты"?
Re[51]: Быстро превратить интерпретатор в компилятор
От: VladD2 Российская Империя www.nemerle.org
Дата: 02.02.10 17:58
Оценка:
Здравствуйте, Temoto, Вы писали:

T>В динамических языках я не знаю как судить. Проверок вообще нет. Как тут может отсутствовать полиморфизм, если компилятор не проверяет типы аргументов? Может быть, можно сказать, что динамическая типизация подразумевает полиморфизм. Но это неконструктивно, потому что проверок-то нет. Не знаю. Может быть можно сказать, что говорить о полиморфизме не имеет смысла в рамках динамических языков, как не имеет смысла применить операцию деления к строке.


В динамических языках все проверки в рантайме. А полиморфными являются все без исключения функции.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[53]: Быстро превратить интерпретатор в компилятор
От: VladD2 Российская Империя www.nemerle.org
Дата: 02.02.10 18:51
Оценка:
Здравствуйте, Temoto, Вы писали:

T>Верно, пора мне прекратить придумывать определение полиморфизма, всё равно от этого ничего не зависит.


+1

Тем более, что оно уже дано в википедии.
Хаскелевский вид полиморфизма там причислен к эд-кок-полиморфизму, что примерно соответствует перегрузке в С-подобных языках или частичной специализации (в С++).
На мой взгляд спорное мнение, но имеющее под собой некоторые основания.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[54]: Быстро превратить интерпретатор в компилятор
От: Курилка Россия http://kirya.narod.ru/
Дата: 02.02.10 19:19
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Тем более, что оно уже дано в википедии.

VD>Хаскелевский вид полиморфизма там причислен к эд-кок-полиморфизму, что примерно соответствует перегрузке в С-подобных языках или частичной специализации (в С++).
VD>На мой взгляд спорное мнение, но имеющее под собой некоторые основания.

Как-то ты, Влад, читаешь по диагонали, параметрический полиморфизм там ты не заметил или игнорируешь?
Re[56]: Быстро превратить интерпретатор в компилятор
От: Temoto  
Дата: 02.02.10 20:01
Оценка:
ВВ>>>Ну как же. Мы ведь пытаемся разобраться, если ты не забыл, не является ли то самое "ОО без объектов" примерно теми же яйцами, которые есть в Си. Тебе бы по хорошему именно эту позицию обосновать, а не пытаться доказать, что "полиморфизм" есть и без ОО с классами, и без классов тоже можно писать.
T>>А я именно второе и говорил. И плюс к этому, что "без классов можно писать столь же удобно". В си неудобно.

ВВ>А почему вот в Си неудобно? Можешь обосновать?


Вы сомневаетесь и просите пример или спрашиваете как я понимаю причины неудобства? Если пример, то вот:

http_parser *parser = malloc(sizeof(http_parser));
if (NULL == parser) {...}
http_parser__init(parser);
http_parser__parse(parser, data);
// работаем
free(parser);


против тех же плюсов

std::auto_ptr< HttpParser > parser = new HttpParser();
parser->parse(data);
// работаем


T>>Простые это то, что с успехом эмулируют в си, хоть и неудобно. Заводят структуру и руками пихают её первым аргументом в набор функций с одинаковым префиксом в имени.

T>>А сложные это то, что в си выглядит как в хаскеле наследование реализации, виртуальные методы, оверлоадинг по числу параметров и т.п.

ВВ>А зачем нужно наследование реализации?


Это вы у меня спрашиваете зачем нужна такая-то фича ООП? Наверное, чтобы руками не вызывать родительский метод.

ВВ>Да и вообще в Си в этом проблем никаких нет — инклюд и вперед.

ВВ>Виртуальные методы суть механизм, через которые полиморфизм и реализуется. И они спокойно эмулируются через указатели.

Хорошо, вам было удобно работать с ОО в Си. Тут, наверное, тоже субъективная оценка играет большую роль.

T>>Как я понимаю, там не строится дерево исходников на си. Строится дерево Amplify-C (лиспа), а оно уже тупо конкатится в строку. Но все манипуляции происходят как в обычной лисповой программе: с деревом, не со строками.


ВВ>Проблема макросов, повторюсь, не в том, что сам макрос не представлен в виде лисп-дерева или чего-то там еще, а в том, что макрос работает с кодом как с *текстом*. Настоящий "правильный" макрос работает с кодом как с AST. Как в том же Лиспе. Я могу ошибаться, но в Amplify-C я такого не вижу. Ибо для этого нужно строить таки дерево исходников на Си.

ВВ>А раз этого нет, то такие макросы — лишь дефайн с сиськами.

Согласен про правильный макрос. Если в обратную сторону конвертить, тогда надо строить дерево Си. А если только Amplify -> C, то не надо.
В общем, мы предполагаем, что в этом проекте используются разные подходы. Есть способ проверить, но лично у меня нет желания.

ВВ>>>Учебник по C# или Джаве — это "очень жесткая научная литература"?

T>>Нет, я же говорю — после хаскеля. мы тут немного расходимся о порядке событий.
ВВ>А что, C# появился до Хаскеля?

В шарпе нет ничего, что придумано после хаскеля. Вот о каком порядке речь. Обратное, кстати, тоже верно. Потому что всякие интересные идеи приходят в настоящие, не исследовательские языки с большим запозданием. Ну это и нормально.

T>>Согласен, в проектирование функциональная парадигма ничего не вносит; я тоже вижу разницу только на уровне одного исходника.


ВВ>Э, тебе не кажется, что ты сам себе противоречишь? Речь была об ООП именно для проектирования больших систем.

ВВ>*Писать* большие системы можно одновременно на 10 языках, половина из которых функциональные. Здесь многие вообще использует ФЯ в работе.
ВВ>Но речь-то о проектировании. И если тут по-прежнему то же, что и в ООП... Где "новые горизонты"?

И получится гнутый молоток, потому что один из этих языков не поддерживает ООП? Представим вырожденный случай, когда это единственный язык в реализации системы, например, Cи/(диалект-лиспа-без-defclass)/Go. Это всё ещё ООП?
Разбивать проект на отдельные подсистемы, модули и процессы (в смысле OS process) это естественно и полезно. Без классов и объектов (то есть вообще ещё до кода не дошло дело) это уже ООП?

А то, может и правда мы тут спорим о том, в чём согласны. Может я совсем не понимаю термин ОО проектирование.

Горизонты в гибкости композиции кода, в повторном использовании. Не на уровне подсистем, а на уровне управления потоком выполнения, обработки определённых типов данных. Но это опять голословно и надо показывать.

P.S.: попутно я вспомнил ещё один язык с альтернативным подходом к привязыванию операций к типам данных: Go
http://golang.org/doc/effective_go.html#interfaces_and_types
Подход похожий на классы типов в хаскеле. В целом получилось намного менее выразительно, но это не потому что чего-то не смогли, а просто они там от многих плюшек сознательно отказались в пользу скорости. В каком-то смысле, они сделали статический duck typing.
Re[57]: Быстро превратить интерпретатор в компилятор
От: Воронков Василий Россия  
Дата: 02.02.10 20:26
Оценка:
Здравствуйте, Temoto, Вы писали:

T>Вы сомневаетесь и просите пример или спрашиваете как я понимаю причины неудобства? Если пример, то вот:


T>
T>http_parser *parser = malloc(sizeof(http_parser));
T>if (NULL == parser) {...}
T>http_parser__init(parser);
T>http_parser__parse(parser, data);
T>// работаем
T>free(parser);
T>


T>против тех же плюсов


T>
T>std::auto_ptr< HttpParser > parser = new HttpParser();
T>parser->parse(data);
T>// работаем
T>


Не, ну мы же говорим про ОО. И причем тут, казалось бы, RAII? Да и С++, впрочем тоже
Вопрос был, повторюсь, почему без классов в Си писать неудобно?

На какую часть вопроса отвечает твой пример?

ВВ>>А зачем нужно наследование реализации?

T>Это вы у меня спрашиваете зачем нужна такая-то фича ООП? Наверное, чтобы руками не вызывать родительский метод.

В ОО? Это такая необходимая плюшка, чтобы писать было удобно? По-моему это не фича, а просто побочный эффект наследования.
И причем тут "руками не вызывать родительский метод"? А чем его вызывать-то? Ногами?

ВВ>>Да и вообще в Си в этом проблем никаких нет — инклюд и вперед.

ВВ>>Виртуальные методы суть механизм, через которые полиморфизм и реализуется. И они спокойно эмулируются через указатели.
T>Хорошо, вам было удобно работать с ОО в Си. Тут, наверное, тоже субъективная оценка играет большую роль.

Причем тут субьективная оценка? Я вообще ненавижу Си. Я жду, что ты покажешь, что вот в Си без классов неудобно по таким-то причинам, а в каком-нибудь твоем любимом ФЯ — удобно. С примерами кода. Чтобы сразу было видно.
А пока — по-прежнему голословные заявления.

T>Согласен про правильный макрос. Если в обратную сторону конвертить, тогда надо строить дерево Си. А если только Amplify -> C, то не надо.

T>В общем, мы предполагаем, что в этом проекте используются разные подходы. Есть способ проверить, но лично у меня нет желания.

Да в принципе у меня тоже
Хотя как можно работать с AST кода по типу —
макрос

with {
//C code
}

при этом не разбирать в дерево то, что там у нас вместо C code содержится, я не понимаю.

T>В шарпе нет ничего, что придумано после хаскеля. Вот о каком порядке речь. Обратное, кстати, тоже верно. Потому что всякие интересные идеи приходят в настоящие, не исследовательские языки с большим запозданием. Ну это и нормально.


Мужик, короче. Я тебе предлагаю поближе ознакомиться с ООП так же, как ты предлагаешь нам ФП.
ООП в наиболее распространенной его форме сейчас (в стиле С++). Те языки, в которых его проще всего смотреть — шарп, джава и пр.

T>И получится гнутый молоток, потому что один из этих языков не поддерживает ООП? Представим вырожденный случай, когда это единственный язык в реализации системы, например, Cи/(диалект-лиспа-без-defclass)/Go. Это всё ещё ООП?

T>Разбивать проект на отдельные подсистемы, модули и процессы (в смысле OS process) это естественно и полезно. Без классов и объектов (то есть вообще ещё до кода не дошло дело) это уже ООП?

Этот абзац я вообще не понял, честно говоря.

T>А то, может и правда мы тут спорим о том, в чём согласны. Может я совсем не понимаю термин ОО проектирование.


Выделение абстракций высокого уровня, описание системы на языке этих абстракций. Вот у нас есть задача — приложение должно работать с файлами под юниксом и вин. Надо создать виртуальную файловую систему. Сначала продумать дизайн. Мы знаем, что есть файлы, директории, атрибуты у тех и других, операции, состояния и проч.

В ООП я знаю, как спроектировать такую систему, используя те строительные блоки, которые дает само ООП. А что дает ФП?

T>Горизонты в гибкости композиции кода, в повторном использовании. Не на уровне подсистем, а на уровне управления потоком выполнения, обработки определённых типов данных. Но это опять голословно и надо показывать.


Это даже показывать не надо. Как и доказывать, чем хороши ФЯ. Мы в курсе. Речь вообще никогда не шла о том, что ФП не нужны или что они ничего не дают на уровне "кода функций".
Re[58]: Быстро превратить интерпретатор в компилятор
От: Temoto  
Дата: 02.02.10 21:14
Оценка:
ВВ>Не, ну мы же говорим про ОО. И причем тут, казалось бы, RAII? Да и С++, впрочем тоже
ВВ>Вопрос был, повторюсь, почему без классов в Си писать неудобно?

Я отвечал на вопрос "почему писать ООП в Си неудобно". Ну Си подразумевает отсутствие классов.
Потому что boilerplate в таскании состояния в каждую функцию, нет сахара на конструкторы и деструкторы. Такой ответ устраивает?

ВВ>>>А зачем нужно наследование реализации?

T>>Это вы у меня спрашиваете зачем нужна такая-то фича ООП? Наверное, чтобы руками не вызывать родительский метод.
ВВ>В ОО? Это такая необходимая плюшка, чтобы писать было удобно? По-моему это не фича, а просто побочный эффект наследования.
ВВ>И причем тут "руками не вызывать родительский метод"? А чем его вызывать-то? Ногами?

Если б наследование реализации отсутствовало, то в наследнике, который не переопределил у себя родительский метод, этого метода бы просто не было. Таким образом, пришлось бы явно его описывать и явно вызывать родительский. (руками=явно)

ВВ>Причем тут субьективная оценка? Я вообще ненавижу Си. Я жду, что ты покажешь, что вот в Си без классов неудобно по таким-то причинам, а в каком-нибудь твоем любимом ФЯ — удобно. С примерами кода. Чтобы сразу было видно.

ВВ>А пока — по-прежнему голословные заявления.

Я говорил не о том, что в Си без классов неудобно в принципе. Я говорил, что писать ОО в Си неудобно. Ну банально потому, что язык не поддерживает классы.
А в каком-нибудь моём любимом ФЯ писать ОО так же неудобно. Это не доказывает ничего, кроме того, что не надо ОО изображать в тех языках, где он не поддерживается на уровне языка. Пример кода был с http_parser.

Очевидно Си менее выразителен, чем "какой-нибудь мой любимый ФЯ" и менее выразителен чем любой ОО язык. Потому что и второй и последний дают набор плюшек, которых в си нет. (можно эмулировать, как например структуры с указателями на функции, но неудобно, долго писать). Но это опять голословщина. Надо, наверное, ждать пример кода с классами типов, как они упрощают жизнь по сравнению с ОО и по сравнению с Си. Хотя последнее, на мой взгляд это уже перебор.

T>>А то, может и правда мы тут спорим о том, в чём согласны. Может я совсем не понимаю термин ОО проектирование.


ВВ>Выделение абстракций высокого уровня, описание системы на языке этих абстракций. Вот у нас есть задача — приложение должно работать с файлами под юниксом и вин. Надо создать виртуальную файловую систему. Сначала продумать дизайн. Мы знаем, что есть файлы, директории, атрибуты у тех и других, операции, состояния и проч.


Согласен. Но это абстракции и они точно так же не "принадлежат ОО", как и полиморфизм. Эндемичным для ОО в проектировании, наверное, было бы разбиение системы на "объекты"? (но если так, то мы придём к очень интересному)

ВВ>В ООП я знаю, как спроектировать такую систему, используя те строительные блоки, которые дает само ООП. А что дает ФП?


Может быть, это неудачный пример, но в результате должна получиться библиотека с функциями (грубо говоря, без всяких аттрибутов) open,read,write,close, которые будут принимать и возвращать одинаковые типы данных, независимо от ОС, на которой они запущены. В такой формулировке не используется ООП, не используется ФП. Просто абстракции и выразительности Си вполне достаточно для решения этой задачи.

T>>Горизонты в гибкости композиции кода, в повторном использовании. Не на уровне подсистем, а на уровне управления потоком выполнения, обработки определённых типов данных. Но это опять голословно и надо показывать.

ВВ>Это даже показывать не надо. Как и доказывать, чем хороши ФЯ. Мы в курсе. Речь вообще никогда не шла о том, что ФП не нужны или что они ничего не дают на уровне "кода функций".

Я не говорил о функциональных языках в целом. Я говорил о довольно конкретном способе привязывания типов к операциям, которые можно делать с этими типами. ООП предлагает один способ: классы с методами и т.п. Я говорил о другом, который в хаскеле: классы(как группы) типов. Чтобы заиметь такую систему типов язык не обязан быть функциональным и Go тому подтверждение.
Re[59]: Быстро превратить интерпретатор в компилятор
От: Воронков Василий Россия  
Дата: 02.02.10 21:42
Оценка:
Здравствуйте, Temoto, Вы писали:

ВВ>>Не, ну мы же говорим про ОО. И причем тут, казалось бы, RAII? Да и С++, впрочем тоже

ВВ>>Вопрос был, повторюсь, почему без классов в Си писать неудобно?
T>Я отвечал на вопрос "почему писать ООП в Си неудобно". Ну Си подразумевает отсутствие классов.
T>Потому что boilerplate в таскании состояния в каждую функцию, нет сахара на конструкторы и деструкторы. Такой ответ устраивает?

Это ответ на какой-то другой вопрос, причем достаточно очевидный. Я же не спрашиваю тебя, почему в ФЯ в ООП стиле писать неудобно? Интересует другой момент — почему неудобно использовать концепции ОО и не тащить при этом весь груз ООП-ных классов с наследованиями.

Мы же с тобой определились, что в Си все нужные плюшки есть.
В ФЯ (подставь любое название) тоже есть.
Какие же преимущества при использовании этих плюшек есть в ФЯ?

ВВ>>>>А зачем нужно наследование реализации?

T>>>Это вы у меня спрашиваете зачем нужна такая-то фича ООП? Наверное, чтобы руками не вызывать родительский метод.
ВВ>>В ОО? Это такая необходимая плюшка, чтобы писать было удобно? По-моему это не фича, а просто побочный эффект наследования.
ВВ>>И причем тут "руками не вызывать родительский метод"? А чем его вызывать-то? Ногами?
T>Если б наследование реализации отсутствовало, то в наследнике, который не переопределил у себя родительский метод, этого метода бы просто не было. Таким образом, пришлось бы явно его описывать и явно вызывать родительский. (руками=явно)

Метод достаточно описать в интерфейсе.
Где бы он там ни был описан вызывать его все равно надо явно (явно=руками).
Подключение реализации, которое получается при наследовании реализации, к ООП имеет весьма слабое отношение.

T>Очевидно Си менее выразителен, чем "какой-нибудь мой любимый ФЯ" и менее выразителен чем любой ОО язык. Потому что и второй и последний дают набор плюшек, которых в си нет. (можно эмулировать, как например структуры с указателями на функции, но неудобно, долго писать). Но это опять голословщина. Надо, наверное, ждать пример кода с классами типов, как они упрощают жизнь по сравнению с ОО и по сравнению с Си. Хотя последнее, на мой взгляд это уже перебор.


T>>>А то, может и правда мы тут спорим о том, в чём согласны. Может я совсем не понимаю термин ОО проектирование.

ВВ>>Выделение абстракций высокого уровня, описание системы на языке этих абстракций. Вот у нас есть задача — приложение должно работать с файлами под юниксом и вин. Надо создать виртуальную файловую систему. Сначала продумать дизайн. Мы знаем, что есть файлы, директории, атрибуты у тех и других, операции, состояния и проч.
T>Согласен. Но это абстракции и они точно так же не "принадлежат ОО", как и полиморфизм. Эндемичным для ОО в проектировании, наверное, было бы разбиение системы на "объекты"? (но если так, то мы придём к очень интересному)

Никто не говорит, что абстракции "принадлежат ООП". Абстракции принадлежат тому, кто их придумал.
И что значит "разбиение системы на объекты"? Как ты себе это представляешь? Я уже привел все нужные "термины", именно в таких ООП приложение и разрабатывается, они напрямую мапятся на сущности в ООП.

ВВ>>В ООП я знаю, как спроектировать такую систему, используя те строительные блоки, которые дает само ООП. А что дает ФП?


T>Может быть, это неудачный пример, но в результате должна получиться библиотека с функциями (грубо говоря, без всяких аттрибутов) open,read,write,close, которые будут принимать и возвращать одинаковые типы данных, независимо от ОС, на которой они запущены. В такой формулировке не используется ООП, не используется ФП. Просто абстракции и выразительности Си вполне достаточно для решения этой задачи.


Речь же не о том, что любую задачу можно решить в процедурном стиле.
Вот я ввел ряд абстракций — файл, директория и пр., обладающих определенным поведением, имеющих состояние и пр. Все это, как ты правильно, "не принадлежит" ООП, это, собственно, предметная область. В ООП у меня прямой путь от этих абстракций к коду. А в ФП?

T>Я не говорил о функциональных языках в целом. Я говорил о довольно конкретном способе привязывания типов к операциям, которые можно делать с этими типами. ООП предлагает один способ: классы с методами и т.п. Я говорил о другом, который в хаскеле: классы(как группы) типов. Чтобы заиметь такую систему типов язык не обязан быть функциональным и Go тому подтверждение.


Теперь осталось показать, зачем нужна такая система типов и какие преимущества при проектировании она дает по сравнению с системой типов в том же дотнете.
Re[55]: Быстро превратить интерпретатор в компилятор
От: VladD2 Российская Империя www.nemerle.org
Дата: 02.02.10 21:49
Оценка:
Здравствуйте, Курилка, Вы писали:

К>Как-то ты, Влад, читаешь по диагонали, параметрический полиморфизм там ты не заметил или игнорируешь?


Ну, это само собой и не обсуждается даже. Но к ООП он ни каким боком не относится. Это аналог дженериков. Без него язык называться современным просто не может, по-моему.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[21]: Быстро превратить интерпретатор в компилятор
От: FR  
Дата: 03.02.10 04:25
Оценка:
Здравствуйте, Воронков Василий, Вы писали:

FR>>Извини Влад, но ты в этом не разбираешься


ВВ>Так расскажи, в чем специфика. Мне вот тоже интересно стало


Специфики особой нет, обычное системное приложение, очень много кода сплошые вызовы Win и Native API.

ВВ>Подозреваю, что может быть много интеропа, в таком случае писать код исключительно на том же C# достаточно геморойно. Но на C++\CLI или даже на C++\CLI + C# вполне. Уж по крайней мере ГУЙ писать, который у таких утилиток как правило весьма "нарядный".


Давай приходи, перепиши нам бесплатно несколько человеко — лет кода с C++ Buildera на C# мы дальше продолжим
Кроме того я вообще не вижу никаких преимуществ шарпа при написании подобных приложений,
надежности от управляемого кода мы не получим на такой смеси, мощность языка тоже не особо востребована, так
как кодирование очень небольшая часть работы (несколько сотен строк кода в неделю вполне нормально).
Если бы я писал с нуля подобное выбрал бы (позабыв свою любовь к питону и окамлу) тот же C++, но не C++ Builder,
а VC + wxWidfets (или Qt).
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.