2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу Пред.  1, 2, 3, 4, 5, 6
 
 
Сообщение23.03.2006, 21:22 
Заслуженный участник
Аватара пользователя


16/03/06
406
Moscow
Вот, кстати, чего по моему мнению не хватает Си++ (и Джаве), так это оператора with, как в бейсике.

 Профиль  
                  
 
 
Сообщение23.03.2006, 22:51 
Заслуженный участник
Аватара пользователя


17/10/05
3709
:evil:

1) о примере --

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

А теперь давайте сверим часы:
Код:
template<TR, TD>
TD find_root(TD a, TD b, TR(*f)(TD), TD eps)
{
  TR c = (a + b)/2;

  assert(f(a) < 0 && 0 < f(b));
  while ((b - a) > eps) {
    (f(c) < 0? a: b) = c;
    c = (a + b) /2;
  }
  return c;
}
Хорошо бы задать ограничения на TR, TD -- чтобы при инстанцизации шаблона получать внятное сообщение о том, что класс-параметр не удовлетворяет требованиям шаблона, а не нечто нечленораздельное. Но -- мой текст гораздо больше похож на исходный и гораздо легче читается. Более того, он применим и к встроенным типам, и к классу YourFloat, который я купил у Вас в составе библиотеки -- только вот Вы не знали о GenericFloat (а это мой промышленный секрет) и не использовали его в своей библиотеке. А если у меня еще и TheirFloat (от третьего поставщика)?

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

Это утверждение я не понял.

Ваша идея с SingleParameterFloatFunction тоже имеет определенные проблемы. Первая -- поскольку все -- методы, то как передать имя метода в функцию. Ну хорошо, я ищу не корень, а минимум. У меня есть класс -- ГеомТело, у него методы -- площадьПоверхности() и объем(). Что будем делать? Писать адаптеры на каждый метод? Причем именно писать, без template'ов-то. Другая проблема -- а что будем делать с уже существующими классами? Они-то не могут быть выведены из Ваших предков.

Что касается рассмотрения функций, отношений, et cetera как объектов, то это здравый подход при одном условии -- он поддерживается языком. То есть с точки зрения языка эти конструкты должны быть объектами. Тогда -- никаких проблем (как нет их в Python. P. обходиться без template). Но на уровне библиотеки это неприемлемо обычно по соображениям эффективности и читаемости результата. Вот если Вы делаете свою систему вычисления a la Maple -- то, да, конечно. Но там и свой язык.

А на вкус, на цвет товарища нет. Я считаю Java более современным языком, чем C++. И что Java реализует более современные трактовки программирования. Но я не вижу греха в отклонении от ОО.

2) О наследовании и членстве

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

Так что я готов рассматривать только "логические", концептуальные аргументы.

На концептуальном уровне -- объект обладает своими атрибутами. То есть -- нет объекта, нет атрибута. Связь же между классом и наследником -- это специализация. То есть, всякий наследник есть всегда подкласс предка. Добавление атрибутов -- всего лишь частный случай. Но соотношение здеь не по общности атрибутов, а по принадлежности к классу. Чтобы было понятно -- у меня есть класс Млекопитаюшее. У него есть атрибут -- ноги, в количестве четырех штук. У меня есть класс Стол. Будем выводить из Млекопитающего? Почему бы и нет... :D С другой стороны, мы можем вывести из млекопитающего человека, несмотря на анатомический недостаток (наличие только двух ног).

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

Что же касается Вашего примера с тензором, то я бы сказал так -- поскольку скаляр есть тензор нулевого ранга, то выводить можно. Но вот вектор длины один я бы выводить из скаляра не стал. Как видите, провожу линию, руководствясь провозглашенными принципами.

 Профиль  
                  
 
 
Сообщение24.03.2006, 02:06 


29/05/05
143
Dims писал(а):
И поэтому в похожем языке -- Джаве -- Вам кажутся писутствующими множество мелких недостатков. А на самом деле, это просто эффект привычки.


Но я ведь объясняю свои претензии! А не просто говорю, что это мне не нравится, потому что непривычно. Аналогичные камни можно кинуть и в C++. В этом языке нет, например, Final классов (или уже есть?). Мелочь, а неприятно. Это, конечно, можно реализовать, но, блин, решение не для слабонервных. Или вот из книги Элджер Д. — Библиотека программиста C++:
Цитата:
Если в производном классе создается функция с тем же именем, но с другой сигнатурой, она скрывает все сигнатуры базового класса для данной функции, но только в области действия производного класса. Понятно? Нет? Что ж, вы не одиноки.


Dims писал(а):
Не знаю, хотел ли он. Но он не мог: он был связан синтаксисом простого Си.


И каким образом синтаксис языка Си связывает в этой конкретной ситуации???

Dims писал(а):
Это способ избегать ошибок.


И каким образом требование принадлежности всякого метода некоторому классу позволяет избегать ошибок?

Dims писал(а):
Потому что интерфейсы нужны для другого.


Вот тут я ничего не понял...

Dims писал(а):
Ничё не понял.


А что непонятного? Согласны ли Вы с предложенным мной неравенством?

 Профиль  
                  
 
 
Сообщение24.03.2006, 02:38 


29/05/05
143
незванный гость писал(а):
Лично я склонен считать, что класс (модуль, компонента, библиотека), экпортирующий listener обязан экспортировать и базовый адаптер -- как правило хорошего тона. Аки мытье рук перед едой. Тогда его и искать особливо не надо.


Зачем в таких ситуациях вообще адаптер? Всё ведь из-за чистоты интерфейсов и принятой практики их использования (даёшь!;)). А тут бац и адаптеры прикручивать приходится. А всех адаптеров ведь для более-менее сложных классов не напишешь. Когда нужного нет - ваяем сами. К лишним телодвижениям ещё лишние телодвижения.

 Профиль  
                  
 
 
Сообщение24.03.2006, 03:01 
Заслуженный участник
Аватара пользователя


17/10/05
3709
:evil:
dikun писал(а):
Зачем в таких ситуациях вообще адаптер? Всё ведь из-за чистоты интерфейсов и принятой практики их использования (даёшь!;)).

Чтобы уменьшить работу по написанию своего слушателя. Требует от разработчика источника событий больше работы, так ведь -- обычно источник событий делается один раз, а вот слушателей -- много.

Если же Вы имеете в виду, что интерфейсы не нужны (поскольку базовый класс предоставляется источником), то тут я возражу, что без интрефейсов не обойтись, если мы хотим слушать более чем один источник событий.

 Профиль  
                  
 
 
Сообщение24.03.2006, 08:45 


01/01/06
35
Мне кажется (могу ошибаться), что для любого отклонения от ОО в ОО же языке, вполне можно сделать ОО обертку. Чистота концепции будет соблюдена, но улучшится ли читаемость, производительность и сопровождение, это еще вопрос. Для разных случаев ответ, видимо, будет разным.

 Профиль  
                  
 
 
Сообщение24.03.2006, 09:30 
Заслуженный участник
Аватара пользователя


16/03/06
406
Moscow
незванный гость писал(а):
Ну, во-первых, считать встроенные типы отклонением -- очень сильное заявление. Потому они и встраиваются в язык, что важны для практичекого применения.

Ну так правильно. Отклонение от ОО-модели, важное для практического применения.

Цитата:
Хорошо бы задать ограничения на TR, TD -- чтобы при инстанцизации шаблона получать внятное сообщение о том, что класс-параметр не удовлетворяет требованиям шаблона, а не нечто нечленораздельное.

Правильно, шаблоны этого не позволяют. А если позволят, то окончательно превратятся в ОО-идеологию.

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

Это утверждение я не понял.

Так положено в джаве. Сама фирма Сан часто пишет целые библиотеки на основе просто интерфейсов (интерфейс в понятиях си++ -- это класс, в котором все функции чисто виртуальные). А потом сторонние производители их "имплементят", то есть, пишут классы. В самих функциях, которые написаны Саном об этом даже не знают.

Цитата:
Ваша идея с SingleParameterFloatFunction тоже имеет определенные проблемы. Первая -- поскольку все -- методы, то как передать имя метода в функцию.

А зачем передавать имя метода в функцию? Как я понял, Ваш код ищет ноль математической функции. Так что не надо путать математическую функцию и функцию в языке программирования. В Ваш код должен быть передан объект типа функция.

Цитата:
Ну хорошо, я ищу не корень, а минимум. У меня есть класс -- ГеомТело, у него методы -- площадьПоверхности() и объем(). Что будем делать? Писать адаптеры на каждый метод?

Не понял. Минимум чего Вы хотите найти?

Цитата:
Причем именно писать, без template'ов-то. Другая проблема -- а что будем делать с уже существующими классами? Они-то не могут быть выведены из Ваших предков.

Просто задача абстрактная. В Си++ Вы, кстати, тоже не сможете передать в Вашу функцию адрес функции-члена -- тип не тот. То есть, Вам тоже придётся написать адаптор.

Цитата:
Но я не вижу греха в отклонении от ОО.

Я тоже не вижу в этом греха. Я его (отклонение) просто вижу. И говорю, что оно есть. Не более.

Цитата:
Приведу пример -- на процессорах с требованием выравнивания компилятор будет сортировать члены так, чтобы минимизировать потери памяти. То есть, все double -- в начало, все bool -- в конец. Но вот предок будет идти в начале, даже если он нарушает выравнивание.

Вы ше сами сказали, что реализация -- не аргумент. И тем не менее, я не понимаю, почему предка нельзя так же разложить, как и член?

Цитата:
На концептуальном уровне -- объект обладает своими атрибутами. То есть -- нет объекта, нет атрибута.

То есть, Вы хотите сказать, что если в объекте есть член типа "целое", то в отсутствии объекта понятие целого тоже исчезает?

Цитата:
Связь же между классом и наследником -- это специализация. То есть, всякий наследник есть всегда подкласс предка.

С членами тоже самое. Если членов несколько, то имеет место множественное наследование. Например, 3-вектор -- это просто наследник трёх экземпляров класса "вещественное число".

Цитата:
Что же касается Вашего примера с тензором, то я бы сказал так -- поскольку скаляр есть тензор нулевого ранга, то выводить можно. Но вот вектор длины один я бы выводить из скаляра не стал. Как видите, провожу линию, руководствясь провозглашенными принципами.

А я не понял.

Скажем так: член -- это просто именованный предок. А предок -- это просто безымянный член.

 Профиль  
                  
 
 
Сообщение24.03.2006, 20:03 
Заслуженный участник
Аватара пользователя


17/10/05
3709
:evil:
Я уже сказал все, что мог, и дополнительных аргументов по предмету дискурссии (а кстати, каков он? стандарт С++? что-то не похоже) не имею.

 Профиль  
                  
 
 
Сообщение24.03.2006, 20:43 


29/05/05
143
незванный гость писал(а):
Чтобы уменьшить работу по написанию своего слушателя. Требует от разработчика источника событий больше работы, так ведь -- обычно источник событий делается один раз, а вот слушателей -- много.

Если же Вы имеете в виду, что интерфейсы не нужны (поскольку базовый класс предоставляется источником), то тут я возражу, что без интрефейсов не обойтись, если мы хотим слушать более чем один источник событий.


Да понимаю я всё это... Блин... Ладно... Забьём на эти адаптеры, ОК?

 Профиль  
                  
 
 
Сообщение27.03.2006, 20:23 
Заслуженный участник
Аватара пользователя


12/10/05
478
Казань
По-моему, невзирая на то, что далеко отошли от темы, получился интересный разговор (обсуждение шаблонов).
Цитата:
И еще -- обратите внимание. Шаблоны появились после OO. Они добавлялись в ОО языки (в С++, в Java). Может ли это быть потому, что шаблоны -- пост-ОО концепция?

На мой взгляд, шаблоны - это не пост-ОО концепция, поскольку появились они раньше (извиняюсь, что опять вспоминаю Аду-83 - там они были). Дуаю, что не сильно ошибусь, если предположу что они были в Lisp-e еще раньше. Кстати, что касается проверки наличия соответствующего интерфейса у типа-параметра на этапе компиляции - это тоже присутствует в Ада-83. Так что все generic - это очень старая и хорошо забытая штука. Думаю, история повторится, но с некоторым изменением синтаксиса :)

 Профиль  
                  
 
 
Сообщение28.03.2006, 00:03 
Заслуженный участник
Аватара пользователя


17/10/05
3709
:evil:
По поводу Ады-83, (как, впрочем, и Ады-95), Вы, несомненно, абсолютно правы -- спасибо Вам. Что же касается Lisp'а, то я не вполне понимаю, о чем там речь. Lisp -- динамический язык, и динамических языках шаблоны обычно не нужны, поскольку тип/класс являются объектами, доступными программе (а связывание -- позднее). Я могу, однако, заблуждаться, исходя из сильно устаревшего описания Lisp'а.

 Профиль  
                  
 
 
Сообщение06.07.2006, 22:37 


29/05/05
143
Java и традиционные языки: производительность программиста

:)

[скабрезность]Вырезано![/скабрезность]

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 87 ]  На страницу Пред.  1, 2, 3, 4, 5, 6

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group