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

Adelf

Administrator
Команда форума
Я просто не понимаю этот кусок кода, извини :)
Я думал о функциональщине и мне нравились нотки, которые оттуда шли. Чистые функции, иммутабельность. А ты говоришь пока о других вещах. Я вернусь к этой теме, когда на досуге освою чего-нибудь.
 

Lionishy

Новичок
Я просто не понимаю этот кусок кода, извини
Это я, действительно, промахнулся...

Если провести аналогию с PHP, то представим, что у нас есть некоторый тип Mybool, который может быть сконструирован двумя функциями T или F.
PHP:
interface Mybool {
};

class F implements Mybool {
}

class T implements Mybool {
}
Запишем также два выражения перегруженные по типу аргумента, если бы это было можно в PHP
PHP:
function if_then_else(T $bool, $true_actor, $false_actor)
{
    return $true_actor;
}

function if_then_else(F $bool, $true_actor, $false_actor)
{
    return $false_actor;
}
Теперь создаём какую-то переменную $mybool, и вызываем функцию If_then_else
PHP:
$mybool = new F();

function act(Mybool $mybool)
{
    echo if_then_else($mybool,"true","false");
}
Если бы компилятор мог проследить, что $mybool создана из F, то вызвал бы нужный вариант функции if_then_else.
То есть, мы не следим, что там за объект, а следим за тем, как он создан. А указание Mybool в параметре функции проверяет, что конструктор из набора Mybool.
В Java мы бы в рамках статической именованной системы не узнали бы как $mybool создано. Это F или это T? Пришлось бы проверить вручную через рефлексии и встроенный оператор сравнения.

Если прибавить к статической типизации немного параметризации типами, хотя бы как в C++, то повторить этот пируэт из Haskell возможно. Но гораздо более громоздкий получится код.
 

AmdY

Пью пиво
Команда форума
@Lionishy твои утверждения про проще и удобнее зыждятся на какой-то идеалогии, а не на фактах.
@Adelf, система не анализирует структуру класса A, а типовую метку Base. Это и есть именованная система типов.
Если бы можно было сделать так:
Код:
class A {
    public function hello($string);
}
class B {
    public function hello($string);
}
class C{}

function test(A $t){ $t->t(); }

test(new A()};
test(new B()};
test(new C()}; // а вот тут ошибка :)
тогда это была бы структурная система типов.
Здесь две ошибки. В третьем случае вная, так как нет метода t. А во вором неявная, потому что несмотря на то, что есть два метода с одинаковыми названиями это не значит что они делат одно и то же. Если животное серое у него большие уши и короткий хвост, то это может быть и слон, и заяц и не правильно расчитывать что от одной в морковки в день они не звохнут.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Да, неслабо глючит. Перегрузка функций на PHP, изменение принципа полиморфизма под функциональное программирование, сравнение типов в Java по содержимому.
Чувак, ты чем в жизни занимаешься-то - свой язык пишешь?

я понимаю о чем ты, а вот ты не хочешь подумать о том, что такое полиморфизм и почему в языках с областью видимости за пределами функции нужен контроль иерархии типов ;)
 
Последнее редактирование:

Lionishy

Новичок
В третьем случае явная, так как нет метода t
Да, ошибся, процитировал сообщение. Нужен верный вызов.

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

твои утверждения про проще и удобнее зыждятся на какой-то идеалогии, а не на фактах
Лично для меня большой секрет, почему функциональное программирование не поглотило Web.
Если мне не изменяет память то первое Web приложение было написано на Lisp: viaweb
И я убеждён, что проблемы, например, ORM -- это проблемы очень сложной системы данных. Это как строгая типизация без параметризации типами aka Pascal. Ничего не напишешь...

свой язык пишешь?
Нет. Но занимаюсь формальной верификацией кода. Точнее возможностями формальной верификации с помощью статической системы типов.
 

fixxxer

К.О.
Партнер клуба
Чото много умных слов. Давай на пальцах и без теорий категорий :)

Вот возьмем например go, там нет классов. Зато есть типы и интерфейсы. Языковой конструкции, подобной implements, нет - достаточно фактической полной реализации интерфейса.
https://gobyexample.com/interfaces

Ты про что-то такое, чтоли?
 

Adelf

Administrator
Команда форума
PHP:
function if_then_else(T $bool, $true_actor, $false_actor)
{
    return $true_actor;
}

function if_then_else(F $bool, $true_actor, $false_actor)
{
    return $false_actor;
}
И в Java и в C# это легко возможно. Именно такой же записью. Называется перегрузка методов.
 

Lionishy

Новичок
Ты про что-то такое, чтоли?
То о, чём я говорю гораздо шире. Но в частности, да.
Но не очень понятно, что делать с возможностью определить два одинаковых интерфейса, которые семантически различаются.

И в Java и в C# это легко возможно. Именно такой же записью. Называется перегрузка методов.
К сожалению, нет.
Как только мы выполним каст к Mybool, мы уже не можем произвести обратный каст к F или T явно.
Без обобщённого программирования не повторить никак.
 

Adelf

Administrator
Команда форума
Твоя правда. Но все равно не могу придумать, где это было бы полезно. Я к этому вопросу вернусь, когда освою что-нибудь функциональное. Чтобы понять надо гонять ;-)
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
>Лично для меня большой секрет, почему функциональное программирование не поглотило Web.
видимо, чтобы понять web dev, нужно делать веб
а для возможности формализации и верификации кода, конечно, нужна и другая типизация, и ограничения области видимости, и другие принципы ООП

в php с такой сферой интересов ловить нечего, для тебя здесь будут сплошные алогизмы,
да и в js и в go с питоном тоже
 

fixxxer

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

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

fixxxer

К.О.
Партнер клуба
Лично для меня большой секрет, почему функциональное программирование не поглотило Web
Потому что, если не брать узкую область клепания контентных говносайтов, веб-приложение ничем принципиально не отличается от просто приложения, а для описания бизнес-логики ничего лучше объектов не придумано.

проблемы, например, ORM -- это проблемы очень сложной системы данных
Проблема ORM - это проблема https://en.wikipedia.org/wiki/Object-relational_impedance_mismatch, дело не в сложности. Да и сам по себе impedance mismatch нерешаемой проблемой не является (за исключением ActiveRecord) - просто маппинг в ряде случаев необходимо писать вручную.
 

Lionishy

Новичок
При следующем оверлоаде и так все сработает
В Java c именованной системой работать не будет. А в Haskell всё будет работать на уровне статической проверки типов.

веб-приложение ничем принципиально не отличается от просто приложения
У Web приложения меньше императивности. Собственно само приложение не зависит от времени, потому может быть полностью функциональным, это следствие работы протокола обмена данными. Потому более простая форма объектного подхода, функциональная, казалось бы должна была бы Web поглотить.

для описания бизнес-логики ничего лучше объектов не придумано.
Крайне спорное утверждение.
 

Lionishy

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

fixxxer

К.О.
Партнер клуба
Так для этого есть либо generic-и, либо композиция. При попытке их заменить наследованием очевидно получается ерунда.
 

fixxxer

К.О.
Партнер клуба
Крайне спорное утверждение.
"Лучше" - это плохое слово, согласен - это субъективно. Скажу иначе - проще. По крайней мере, в бизнес-задачах: "перевод" с языка предметной области на язык объектов обычно намного более прямолинеен и очевиден.
 

AmdY

Пью пиво
Команда форума
Потому более простая форма объектного подхода, функциональная, казалось бы должна была бы Web поглотить.
Давай код, ты напишешь CRUD приложение для веба на функциональном языке в функциональном стиле, а я на php и сравним что должно поглотить веб.

Просто ты здесь уже не первый раз теоретизируешь и твои высказывания противоречивы, интересно что ты можешь на практике.
 
Сверху