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