Структурные и Именованные типы. Поведение или Представление?

Adelf

Administrator
Команда форума
@Redjik, Ну насколько я понял у него оно runtime определяет какой метод вызвать.
А у нас, обычных языков, во время компиляции. В этом разница. Но зачем это все - мне так и не понятно.
 

fixxxer

К.О.
Партнер клуба
Ну у нас, в обычном похапе, все происходит в рантайме. И что?

Параметрический оверлоад (хотя бы в виде кодогенерации правильно упорядоченных if instanceof) и Generic-и в PHP можно легко себе представить умозрительно.
 

Lionishy

Новичок
Так для этого есть либо generic-и, либо композиция.
Это и не Generics и не агрегация.
Точного аналога такой конструкции в Java просто нет.
Самое близкое: это интерфейс и пара реализаций. Я попытался на этом примере объяснить, что можно сделать, если использовать анализ структуры типа, вместо сравнения имён типов.

В случае с функцией act логический анализ выглядел бы так: функция принимает тип T, который есть сумма из трёх типов G | C | F. Если в функцию act поступает тип P, то мы получим ошибку компиляции. Если в функцию поступает тип C, то набор альтернатив, определённых в функции act, заменяется на конкретную альтернативу для метки C.
 

fixxxer

К.О.
Партнер клуба
PHP:
interface G {}
interface C {}
interface F {}
interface T extends G, C, F{} // тут, кстати, и не понадобится

class Actor {
   public function act(G x) { ... }
   public function act(C x) { ... }
   public function act(F x) { ... }
}
В чем разница с тем, о чем ты говоришь?
 

Lionishy

Новичок
@fixxxer,
В отсутствии абстракции T.
Можно создать классы
PHP:
class CorruptedActor_P {
   public function act(G x) { ... }
   public function act(C x) { ... }
   public function act(F x) { ... }
   public function act(P x) { ... }
}

class CorruptedActor_G {
   public function act(C x) { ... }
   public function act(F x) { ... }
}
Именно наличие метки T позволяет нам отсечь бессмысленные, с точки зрения нашего мета языка T G C F P, высказывания.

P.S. Чтобы не было поползновений. Не поможет и попытка объявить какую-то абстракцию ActorT.
Предупреждая вопрос: "А зачем нам писать такие классы, когда нам нужно не так?"
Ответ: "Это может быть непреднамеренной ошибкой".

P.P.S. В рамках принятой в Java системы типов повторить это просто невозможно. Это как пытаться пересилить постулат о параллельных прямых.
Не исключаю, что с применением метапрограммирвоания на шаблонах C++ подобный оборот, всё же, можно повторить. Тем не менее, это будет устроено в разы сложнее, чем в Haskell.
 
Последнее редактирование:

grigori

( ͡° ͜ʖ ͡°)
Команда форума
@Lionishy, много догм, ни одного обоснования. Похоже на проповедь, а мы инженеры, работаем с воспроизводимыми фактами.

последние догмы: "бессмысленные высказывания" (как определяются критерии осмысленности?), "Это может быть непреднамеренной ошибкой" (любое событие может быть непреднамеренной ошибкой), "повторить это невозможно" (да неужели?), "это будет в разы сложнее" (кто и как считал?)

тут эмоции не прокатывают, или обосновывай - или иди на хабр
 
Последнее редактирование:

Lionishy

Новичок
@grigori
Бессмысленное высказывание такое, которое невозможно редуцировать согласно формальной операционной или детонационной семантики нашего языка.
Например, если мы определим правило редукции
if T then t1 else t2 -> t1 | if F then t1 else t2 -> t2
То выражение if P then t1 else t2 -- бессмысленно.

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

Сложнее, значит нам придётся руками создавать абстракции со сложной поведенческой семантикой, привлекая аппарат метапрограммирования.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
хорошо, а что в твоем примере означает оператор -> ? какую общеизвестную семантику ты используешь в своих фразах? можно ссылку на rfc/ietf/wiki/etc?

какая у тебя семантика работы с типами? какой алгоритм определения набора реализаций по сумме типов? дай ссылку на wiki, например

какие критерии оценки сложности поведенческой семантики?

parole, parole, parole, encore des paroles que tu sèmes au vent (C)
 
Последнее редактирование:

Lionishy

Новичок
а что в твоем примере означает оператор ->
Стрелка, обозначающая "следовательно". Редактора формул нет, я пишу тем, что есть.

какая у тебя семантика работы с типами?
В Java именованная семантика, в Haskell -- структурная.

какой алгоритм определения набора реализаций по сумме типов?
Не понятно, что Вы имеете в виду.
Может быть так: возьмём некоторое конечной множество типов G и определим новую типовую метку T, которая присваивается всем объектам, имеющим тип из G.

какие критерии оценки сложности поведенческой семантики?
Сложность -- это субъективно. Я не возражаю. Но то, что в Haskell записывает в строчку, в C++ придётся городить несколькими классами, да ещё в своём коде организовывать наследование. И всё равно, точного совпадения с абстракцией не будет.

Хорошим пособием, например, является книга Бенджамина Пирса https://www.cis.upenn.edu/~bcpierce/tapl/
 

fixxxer

К.О.
Партнер клуба
Падажди.

PHP:
interface T {}
class G implements T {}
class C implements T {}
class F implements T {}

interface TActorInterface {
    public function act(T x);
}
    
class Actor implements TActorInterface {
    public function act(T x) {
        return this._act(x);
    }
    private function _act(G x) { ... }
    private function _act(C x) { ... }
    private function _act(F x) { ... }
}
Тут что не так?
 

AmdY

Пью пиво
Команда форума
Человек же не хочешь интерфейсы явно прописывать, он хочет сравнивать структуры. если у объекта Foo есть атрибут baz и у объекта Bar есть атрибут baz, то оба эти объекта подходят. Типичный костыль для языков без интерфейсов, вот только почему-то кто-то считает его конкурентным преимуществом.
 

Вурдалак

Продвинутый новичок
Я очень скептически отношусь к duck typing. Если два объекта имеют одинаковые с точки зрения сигнатуры методы, то это вовсе не означает, что семантически эти методы эквиваленты и, стало быть, взаимозаменяемы. Что резволвит метод resolve(string $name) : string? Путь к шаблону? IP по хосту? Нормально ли, если вместо «/home/bar/www/templates/foo.tpl» вернется «73.32.4.209»? На мой взгляд, это только добавляет неявности и, как следствие, это усложняет код.
 

Lionishy

Новичок
Я очень скептически отношусь к duck typing.
Я просто напомню.
Здесь речь не о duck typing.
Всё происходит в статике.
То есть, если в одном пространстве имён есть два интерфейса с разными именами, но содержащие одинаковые имена функций, выпадет ошибка компиляции. А если пространства имён разные, то и имена функций разные.

P.S. PHP так не умеет, и Java не умеет. Я однажды попадал с PHP в подобную ситуацию. Приходилось договариваться о именовании методов вручную.
 

Lionishy

Новичок
Нет. С PHP4 я работал, но без ООП.
А с интерфейсами вышло, примерно так: я создал интерфейс в своём пространстве имён, разумеется, а в другом пространстве имён независимо появился другой интерфейс. В интерфейсах имя одного метода совпало. При создании класса-реализации оказалось, что PHP не различает методы из разных интерфейсов, т.е. не использует полностью квалифицированные имена. Пришлось специально договариваться об именовании методов. А имя у метода было как раз типа resolve или render. В общем "очень обыденное". Казалось, что имя интерфейса говорящее. В итоге давали более чёткие имена методам.
Потом ещё был реинжениринг -- вообще всю статическую типизацию убрали, только комментарии оставили. Нам подкатили кодоанализатор, который по PHPDoc проводил более интересный анализ, чем встроенные проверки. Что-то вроде java type checkers, только для PHP.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Стрелка, обозначающая "следовательно". Редактора формул нет, я пишу тем, что есть.
хорошо, запишем по-русски:
Если T то t1 иначе t2 следовательно t1 ИЛИ если F то t1 иначе t2 следовательно t2
Значит, выражение "Если P то t1 иначе t2" -- бессмысленно.

Алгоритм сформулировать не можешь, код привести не можешь. Пишешь, что расширение списка допустимых входных параметров конечного автомата без реализации функций переходов и соответствующих внутренних состояний приводит к исключению. Спасибо, кэп. Только это связано нифига не с типизацией, а с математической теорией конечных автоматов. В ООП и функциональных языках КА идентичны. Если ты не знаешь что это такое - ссылка в тексте.

Сплошные гипотезы ad-hoc, ссылка на британских ученых случайностью не кажется. Говоря по-русски, ты просто пишешь от балды, типа, за умного сойдет.

Короче, астрологи объявили неделю очередного Пейсателя. Спасибо, что сразу в офтопике.
 
Последнее редактирование:

Вурдалак

Продвинутый новичок
Нет. С PHP4 я работал, но без ООП.
А с интерфейсами вышло, примерно так: я создал интерфейс в своём пространстве имён, разумеется, а в другом пространстве имён независимо появился другой интерфейс. В интерфейсах имя одного метода совпало. При создании класса-реализации оказалось, что PHP не различает методы из разных интерфейсов, т.е. не использует полностью квалифицированные имена. Пришлось специально договариваться об именовании методов. А имя у метода было как раз типа resolve или render.
А, ты уже тут писал про это на форуме. Ты знаешь много слов, но SRP так и осилил.
 

fixxxer

К.О.
Партнер клуба
У Вас выпадет ошибка статической проверки.
И правильно сделает.
Так ты того и хотел, по постановке задачи.

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