На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела:
1. Название темы - краткое описание кто/что против кого/чего
2. В первом сообщении - список параметров, по которым идет сравнение.
3. Старайтесь аргументировать свои высказывания. Фразы типа "Венда/Слюникс - ацтой" считаются флудом.
4. Давайте жить дружно и не доводить обсуждение до маразма и личных оскорблений.
Модераторы: Модераторы, Комодераторы
Страницы: (495) « Первая ... 341 342 [343] 344 345 ...  494 495  ( Перейти к последнему сообщению )  
> Delphi vs C++ vs C# , ну и Java немножко, где-то ближе к старшему байту номеров страниц
    Цитата D_KEY @
    А чего ты хотел? Перегрузка функций теоретически действительно скорее трындец, чем что-то хорошее, хотя бы потому, что вводит два "объекта" с одинаковыми именами но разными типами, а это вообще-то противоречит остальной части системы типов большинства языков.

    Я думаю, что это проблема "остальных языков", а вовсе не перегрузки функций :)
    Цитата D_KEY @
    Ну и кроме того перегрузка очень удобная штука

    Именно :)
    Ах, да, D_KEY, надо было SFINAE показать и включение/выключение функций с помощью enable_if :D
    Сообщение отредактировано: MyNameIsIgor -
      ExpandedWrap disabled
        interface NumC<A> {
            A add(A y);
            A mul(A y);
            A sub(A y);
        }
         
        interface FractionalC<A> extends NumC<A> {
            A div(A y);
        }
         
        class Probability implements FractionalC<Probability> {
            public final double value;
         
            public Probability(double val) {
                value = (val < 0.0) ? 0.0 : (val > 1.0) ? 1.0 : val;
            }
         
            public Probability add(Probability y) {
                return new Probability(value + y.value);
            }
         
            public Probability mul(Probability y) {
                return new Probability(value * y.value);
            }
         
            public Probability sub(Probability y) {
                return new Probability(value - y.value);
            }
         
            public Probability div(Probability y) {
                return new Probability(value / y.value);
            }
        }

      ExpandedWrap disabled
        class NumC a where
            add :: a -> a -> a
            mul :: a -> a -> a
            sub :: a -> a -> a
         
        class NumC a => FractionalC a where
            div :: a -> a -> a
         
        data Probability = Probability {
            value :: Double
        } deriving (Show, Read, Eq)
         
        newProbability val
            | val < 0.0 = Probability 0.0
            | val > 1.0 = Probability 1.0
            | otherwise = Probability val
         
        instance NumC Probability where
            add x y = newProbability $ value x + value y
            mul x y = newProbability $ value x * value y
            sub x y = newProbability $ value x - value y
         
        instance FractionalC Probability where
            div x y = newProbability $ value x / value y

      отличия сугубо синтаксические.
        Цитата MyNameIsIgor @
        D_KEY, надо было SFINAE показать и включение/выключение функций с помощью enable_if :D

        Рано :)
          Цитата MyNameIsIgor @
          Вы, похоже, выделяете какой-то "главный шаблон с именем A". А такого не существует. Все специализации в общем-то равноправны.

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

          Цитата MyNameIsIgor @
          Оригинально...

          почему же? наоборот, это распространенное мнение. ничего оригинального =)
            korvin, здесь ты скорее показываешь эмуляцию тайпкастов в Java через интерфейсы и дженерики, чем наоборот :)

            Добавлено
            Цитата korvin @
            я выделяю шаблон как осязаемую сущность включенную в систему типов, как что-то строгое.

            Это средство создания типов и функций.

            Цитата
            в C++ по крайней мере.

            Где-то еще есть шаблоны?

            Цитата
            наоборот, это распространенное мнение. ничего оригинального =)

            Какие причины для запрета перегрузки функций в языке, где функции не являются объектами?
              Цитата D_KEY @
              korvin, здесь ты скорее показываешь эмуляцию тайпкастов в Java через интерфейсы и дженерики, чем наоборот :)

              эм... нет. вполне обычное, распространенное использование дженериков. и так же вполне обыденное использование тайпклассов. как две капли воды.
              если в жабе убрать наследование классов, то будет вообще хаскелл-like =)

              Добавлено
              Цитата D_KEY @
              Это средство создания типов и функций.
              Где-то еще есть шаблоны?

              в некотором смысле можно взять макросы (не сишные =)). кстати надо попробовать макросы в Typed Racket =)
                Цитата korvin @
                эм... нет. вполне обычное, распространенное использование дженериков. и так же вполне обыденное использование тайпклассов. как две капли воды.

                Тут скорее показана работа интерфейсов, чем дженериков :)

                Добавлено
                Цитата korvin @
                в некотором смысле можно взять макросы (не сишные =)).

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

                  D же :)
                    Цитата MyNameIsIgor @
                    Цитата D_KEY @
                    Где-то еще есть шаблоны?

                    D же :)

                    Кстати, как он решает обсуждаемые вопросы?
                      Цитата D_KEY @
                      Кстати, как он решает обсуждаемые вопросы?

                      Эммм?... А что здесь решать? :)
                      Вообще, на сколько я знакомился с докой, там плюсовые шаблоны.
                        Цитата D_KEY @
                        Тут скорее показана работа интерфейсов, чем дженериков :)

                        да ну? не хватает ключевого слова "generic"? ну так можно NumC и FractionalC переименовать в GenericNum и GenericFractional соответственно

                        Добавлено
                        Цитата D_KEY @
                        Нельзя, ибо как я уже говорил, обработка шаблонов не выделяется в отдельную стадию даже на концептуальном уровне - это все происходит во время компиляции

                        а какая разница? впрочем макросы CL тоже обрабатываются во время компиляции, никаких отдельных стадий =)

                        Добавлено
                        Цитата korvin @
                        кстати надо попробовать макросы в Typed Racket =)

                        гыгы
                        ExpandedWrap disabled
                          (define-syntax template
                            (syntax-rules (struct)
                              ((_ name (typevar ...)
                                  (struct
                                    (typev field)
                                    ...))
                               (define-syntax name
                                 (syntax-rules ()
                                   ((_ struct-name typevar ...)
                                    (struct: struct-name ((field : typev) ...))))))))
                           
                           
                          (template tfoo (T S)
                            (struct
                              (T x)
                              (S y)))
                           
                          (tfoo foo Integer Float)
                           
                          (define f (foo 1 2.0))

                        ExpandedWrap disabled
                          > f
                          - : foo
                          #<foo>
                          > foo
                          - : (Integer Float -> foo)
                          #<procedure:foo>
                          >
                          Эх, что-то вас не в ту степь понесло.
                          korvin, шаблоны - это не(пробел)законченный тип. Законченным он получается только после подстановки всех параметров в точке использования. В этом-то и драма отношений между библиотеками и их пользователями - авторам нужно предоставить возможность пользователям доопределеять свойства и аттрибуты шаблона, но при этом обезопаситься от случайностей сайд-эффектов.
                          Шаблонные сущности не оперируют типами и/или значениями, вместо этого они оперируют свойствами и аттрибутами типов и/или значений. Шаблону пофиг на тип объектов x и y; если ему нужно их сравнить, он может просто сделать x<y, т.е. он полагается на тот факт, что x и y умеют сравниваться оператором <. Если это не так, то этот тип не подходит, вот и всё; и ошибка компиляции тут будет закономерной. (Эх, ещё б концепты сюда :yummy: ). А пользователь, увидев эту ошибку, может просто перегрузить operator<() (хотя было бы лучше, конечно, если б он заранее прочёл требования, предъявляемые к типу x и y в документации) и повторить попытку, теперь она будет успешной.
                          С другой стороны, завышенные требования нежелательны, ибо сужают множество подходящих кандидатур. Неподходящие часто можно сделать таковыми, но это дополнительная работа для пользователя шаблона. И особенно обидная, если эта дополнительная работа так и не будет восстребована, а будет нужна только для компилябельности. Типичный пример - шаблон смарт-поинтеров, которые имеют у себя не только перегруженный operator* для разыменования указателя на объект, но и operator-> для разыменования указателя на классовый элемент (элемент структуры, если угодно). Когда смарт-поинтер юзается для класса, этот оператор полезен, но если шаблонным параметром в смарт-поинтер идёт не структурный тип, а к примеру массив, operator-> для него не просто не нужен, он невозможен, иначе будет семантическая ошибка, ибо для массивов он не определён грамматикой. Что делать? Правильно - определить в шаблоне смарт-поинтера "на всякий случай", но не использовать в программе. Последнее несложно - пользователь шаблона, в отличе от автора шаблона, знает его параметры, а значит и знает, какие операции могут над ним применяться, какие нет. Естественно, если читает мануалы.
                          korvin, рассматривай "опциональные" методы интерфейса шаблонного класса как статический эквивалент абстрактных методов из динамического полиморфизма. Чистые методы всегда реализованы (не всегда програмистом, конечно), но пока не вызваны, программа корректна. Тут то же самое. Я не обязан реализовывать для типа объетов x и y оператор <, если не буду использовать часть шаблонной сущности, которой требуется их сравнивать. Но это я знаю и я учитываю, потому что я (а не автор шаблона) знаю конкретные свойства типа, который передаю параметром в используюмую шаблонную сущность, и я знаю, что из его интерфейса я собираюсь использовать, а что нет. В примере D_KEY-я, который он выше цитировал из книжки, не пользователю шаблона "повезло", что он не вызвал нереализованный элемент стратегии. Он её намерено не вызвал ввиду ненадобности, а шаблон и язык ему такую возможность дали, не обязывая реализовывать невосстребованные интерфейсы параметрического типа. В динамике ты обязан реализывать методы абстрактных классов просто тупо для того, чтобы скомпилилось. Будет ли перекрытое восстребовано, никого не интересует.
                          Сообщение отредактировано: Qraizer -
                            Цитата Qraizer @
                            В примере D_KEY-я, который он выше цитировал из книжки, не пользователю шаблона "повезло", что он не вызвал нереализованный элемент стратегии. Он её намерено не вызвал ввиду ненадобности, а шаблон и язык ему такую возможность дали, не обязывая реализовывать невосстребованные интерфейсы параметрического типа.

                            да с автором класса все понятно, но что делать сторонним пользователям? писать наследников/обертки?

                            Добавлено
                            Цитата Qraizer @
                            В динамике ты обязан реализывать методы абстрактных классов просто тупо для того, чтобы скомпилилось. Будет ли перекрытое восстребовано, никого не интересует.

                            да при чем тут динамика? я могу и в динамике сделать необязательность реализации, а в статичном хаскелле требуется _полностью_ инстанциировать тайпкласс для типа. иначе не скомпилится
                              Цитата korvin @
                              да с автором класса все понятно, но что делать сторонним пользователям? писать наследников/обертки?

                              Зачем? Для чего? Какие обёртки?
                                Цитата MyNameIsIgor @
                                Зачем? Для чего? Какие обёртки?

                                затем, что пользователь может хотеть пользоваться вашим классом как C<?>, а не как C<T>
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (495) « Первая ... 341 342 [343] 344 345 ...  494 495


                                Рейтинг@Mail.ru
                                [ Script execution time: 0.4649 ]   [ 15 queries used ]   [ Generated: 31.07.26, 09:50 GMT ]