LINUX.ORG.RU

[haskell] есть ли что-то типа reflection? (недемократизм языка?)

 


0

0

Обычная фраза: deriving (Read, Show, Eq, Ord)

Компилятор умеет выводить инстансы этих typeclass-ов. А что делать, если хочется их выводить чуть-чуть по-другому или добавить еще один, который автоматически бы выводился? (Для этого, возможно, подошло что-то похожее на reflection, патчить компилятор не предлагайте)

__________________________________________________

Недемократизм языка в моем понимании -- это

1. Частичная реализация некой фичи и одновременно отстутствие инструмента для расширения реализации этой фичи. Например в яве оператор + для сложения целых, вещественных, строк и все: комплексные, кватернионы, вектора, матрицы... складывай уже через add.

2. Невозможность смены конкретной реализации фичи (зачастую связано с п.1). Например, невозможность создать в рамках с++ свой virtual dispatch (для того, что сделать множественный virtual dispatch, т.е. п.1). В принципе, п.2 до некоторой степени неизбежен, так как иногда намного проще сделать фичу, чем API для написания фич).

__________________________________________________

Более глобальный вопрос -- а насколько хаскель демократичен? (для обеспечения демократизма разрешается использовать ключи компилятора, template haskell, ...)

Ответ на: комментарий от anonymous

>ты часто в математике передаешь universe в качестве аргумента, только честно

по праздникам :)

>Кто-то утверждал, что лисп дает +10 к интеллекту?

это негласное мнение, витающее в воздухе. непосредственно к тебе не относится

jtootf ★★★★★
()
Ответ на: комментарий от anonymous

> У вас же (в хаскелле) типы вышего порядка по большому счету используются для полиморфизма (или еще для чего-то?), и зачем они в динамике?

Покажи мне там полиморфизм ТАКОГО уровня.

Miguel ★★★★★
()
Ответ на: комментарий от anonymous

>ты прекрасно понимаешь, что я говорию про деструктивное присваивание, а не про связывание имени со значением.

понимаю. и комментирую в смысле, что это самое деструктивное присваивание в этом самом программировании нужно далеко не всегда

jtootf ★★★★★
()
Ответ на: комментарий от anonymous

Однако на деле - мемоизить все подряд - себе дороже выходит

Да, но руками мемоизация делается не просто, а очень просто. В частности, благодаря иммутабельности.

Немемоизованное:

f 0 = 1
f 1 = 1
f n = f (n-1) + f (n-2)

Мемоизованное:

f n = fvals !! n where
  fvals = map f' [1..]
  f' 0 = 1
  f' 1 = 1
  f' n = f (n-1) + f (n-2)

Miguel ★★★★★
()
Ответ на: комментарий от Miguel

> Покажи мне там полиморфизм ТАКОГО уровня.

Пример можешь дать, чтобы я знал, про какой уровень идет речь :)

anonymous
()
Ответ на: комментарий от jtootf

> понимаю. и комментирую в смысле, что это самое деструктивное присваивание в этом самом программировании нужно далеко не всегда

Да. но имхо, иногда оно все-таки надо.

anonymous
()
Ответ на: комментарий от anonymous

Упс, отправил ответ раньше, чем дописал.

> параллелить все подряд - еще дороже

Однако опять же, ручная параллелизация при помощи par и pseq делается очень просто - опять же, благодаря иммутабельности.

Miguel ★★★★★
()
Ответ на: комментарий от Miguel

> Да, но руками мемоизация делается не просто, а очень просто.

Да никто не говорил, что руками сложно. Руками и в лиспе легко :)

anonymous
()
Ответ на: комментарий от anonymous

> Можно пример такой ошибки?

Нулевой указатель, например.

> тот анонимус, наверное, про то, что чтобы вернуть значение не нужно заворачивать его в списки или какой другой контейнер, и, поэтому, например, связка values и multiple-values-bind работает быстрее, чем list и destructuring-bind.

А, ну да. Узнаю брата Колю: ему так в лом ставить лишние скобочки, он же лиспер.

Miguel ★★★★★
()
Ответ на: комментарий от anonymous

> Так блин, он может проверять _вообще все_ в рантайме - ты только скажи, а может и не проверять.

Так вот я и хочу понять: он может ВООБЩЕ ВСЁ проверять в компайл-тайме? Если нет, то ему придётся делать проверки в ран-тайме. Иначе рано или поздно, но там будет ошибка типизации.

> Ну дык в хаскелле тоже не особо положишься

На проверку типов? Вполне.

Miguel ★★★★★
()
Ответ на: комментарий от anonymous

>Да. но имхо, иногда оно все-таки надо.

ну вот для этого "иногда" и можно отойти от математического представления, воспользовавшись unsafe* (равно как и волшебной монадой IO)

другое дело, когда модель требует приближения к железу - тогда уже идёт C и FFI, и мутабельность переносится на другой уровень абстракции (что, в общем-то, тоже неплохо)

jtootf ★★★★★
()
Ответ на: комментарий от anonymous

>А, ну да мы же в аргументы передавали еще и universe :) ты часто в математике передаешь universe в качестве аргумента, только честно.

Если не считать программирование, то последний раз - вчера, лол =)

Waterlaz ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

>Запись в файл например и чтение из него

Нифига не понимаю. Причем тут файлы? Причем тут любой тип? Байки о том, что любой объект мы можем сериализовать?

Обычно всегда известно объекты каких типов будут в списке, или не знаю, там, в базе храниться. Ну дык и обертываем их в полиморфный тип, а потом через паттерн матчинг...

Причем вышеперечсленный дизайн как раз очень хоршо сочетается с методологией программа = программа на DSL.

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

В данной задаче языки с динамической типизацией рулят по той простой причине, что для языков со статической типизацией придется воспроизводить не очень приятную штуковину под названием "стирание типов", а потом как-то "стертую" информацию восстанавливать. Причем, приведенные примеры показывают как просто это делается в хаскеле :)

Macil ★★★★★
()
Ответ на: комментарий от Miguel

Нулевой указатель, например.

В контексте спора динамизм против статики - это, наверное, плохой пример - как-то я не припомню ни одного динамического языка с указателями.

А, ну да. Узнаю брата Колю: ему так в лом ставить лишние скобочки, он же лиспер.

Ну как бы это очень удобно (а скобок тут получается больше), если хочешь сообщить вместе с основным результатом, какие-то дополнительные сведения. Простейший пример - функция целочисленного деления floor. Она возвращает 2 значения - собственно результат и остаток.

[25]> (floor 42 15)
2 ;
12

Если мы хотим _только_ частное, то просто пишем (setf x (floor 42 15)). Если хотим еще и остаток, то пользуемся multiple-value-bind. Это намного удобней, чем парсить возвращаемый лист _каждый раз_, кроме того список - это не то, что мы хотим от функции целочисленного деления - а от нее мы хотим число.

anonymous
()
Ответ на: комментарий от Waterlaz

> Если не считать программирование, то последний раз - вчера, лол =)

Опять теорию категорий на ночь читал, негодник? :)

anonymous
()
Ответ на: комментарий от Miguel

> Не настолько. Хотя бы потому, что сразу будет мешаться мутабельность.

Для чистых функций не будет. Мемоизить не чистую функцию - это же полный бред.

anonymous
()
Ответ на: комментарий от Miguel

> Однако опять же, ручная параллелизация при помощи par и pseq делается очень просто - опять же, благодаря иммутабельности.

В лиспе есть аналоги (прям один в один). Опять же я жалуюсь на невозможность нормальной _автоматической_ параллелизации.

anonymous
()
Ответ на: комментарий от anonymous

>Опять теорию категорий на ночь читал, негодник? :)

гм. и где там universe? разве что universe of discourse могу придумать, в комментариях

jtootf ★★★★★
()
Ответ на: комментарий от Miguel

>Охрененная разница.

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

про практические недостатки этого способа уже сказали.

>Не понял. При чём тут упорядоченные множества?

f(1,2) и f(2,1) могут иметь разные значения. поэтому необходимо упорядочивать множество аргументов, кстати являющихся тоже множествами, возможно и неупорядоченными, это всем очевидно, кроме "не будем пальцем показывать" кого именно.

aninamous
()
Ответ на: комментарий от Macil

> Байки о том, что любой объект мы можем сериализовать? Обычно всегда известно объекты каких типов будут в списке, или не знаю, там, в базе храниться. Ну дык и обертываем их в полиморфный тип, а потом через паттерн матчинг...

А потом в программе появится десяток новых типов, и твой паттерн матчинг придется переписать. Не говоря о том, что это boilerplate code по сути.

Но если "паттерн матчинг" заменить на virtual dispatch то идея становится правильной.

Интересно, кстати, как в хаскеле сделан "расширяемый паттерн матчинг".

> что для языков со статической типизацией придется воспроизводить не очень приятную штуковину под названием "стирание типов", а потом как-то "стертую" информацию восстанавливать.

имхо это бесперспективно, есть вариант лучше.

www_linux_org_ru ★★★★★
() автор топика
Ответ на: комментарий от Miguel

>Программирование - это такой раздел математики.
Здрасьте.
Это когда вдруг стало опять?
Ну, то есть, в сраной рашке, где люди с деревьев вчера слезли, понятно, отличить одно от другого не могут, но вот в цивилизованных странах CS, вообще, и математика - вещи далеко разные.

anonymous
()
Ответ на: комментарий от anonymous

>в цивилизованных странах CS, вообще, и математика - вещи далеко разные

насколько далеко? мне в километрах, если можно

>Это когда вдруг стало опять?

то есть когда-то так всё-таки было, да?

jtootf ★★★★★
()
Ответ на: комментарий от Miguel

> Анонимус прав. В плюсах есть статическая типизация, но в ней такое количество дырок и обходных путей, что, по сути, типизации почти и нет вообще.

У тебя достаточно мозгов, чтобы наехать на плюсы по сути дела (да, я про тот пример с virtual template, который, вероятно, красиво в плюсы не ляжет), а ты тут вспоминаешь аргументы из детского сада. Не стыдно?

Ну и по сути ты не прав: в самом начале TAPL чертится табличка в координатах статика/динамика и опасный/безопасный языки. Посмотри, где там С++, прежде чем поддерживать альтернативно одаренных.

> Haskell, ML - да, там обходные пути тоже, конечно, есть (unsafeCoerce, например), но они чётко изолированы

за хаскель не скажу, но в плюсах я бы хотел более четкую изоляцию

> и вся идеология языка строится так, чтобы избегать их всегда, кроме как когда уж совсем никуда.

Где ты видишь противоположные примеры в плюсах?

www_linux_org_ru ★★★★★
() автор топика
Ответ на: комментарий от aninamous

>f(1,2) и f(2,1) могут иметь разные значения. поэтому необходимо упорядочивать множество аргументов, кстати являющихся тоже множествами, возможно и неупорядоченными, это всем очевидно, кроме "не будем пальцем показывать" кого именно.

Откровенно не понял, о чем ты. f принимает на вход кортеж, и понятно, что кортежи (1, 2) и (2, 1) не равны. При этом устанавливать полную упорядоченность не надо.

Waterlaz ★★★★★
()
Ответ на: комментарий от anonymous

> Смотрим выведенный "тип". (VALUES (OR (SIMPLE-ARRAY CHARACTER (5)) (INTEGER 1 1)) &OPTIONAL)

Сначала минусы.

Есть рассказ о том, как к чуваку попал талисман, исполняющий желания, он заказал 1 000 000 баксов. Далее звонит телефон и страховой агент сообщает о смерти сына от несчастного случая и выплате страховки в 1 000 000 баксов.

Это я про умный вывод типов в сложной программе. А что? Ведь задание выполнено!

Хиндли-М. как-то научно обоснован, но все равно приходится аннотировать. А что там в *твоем самобытном* лиспе понакрутили?

Теперь плюсы.

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

auto f(int i) { return x!=0 ? "non-zero" : 0 }

или как минимум (в случае лиспа) один символ.

Кстати, *где* такое нужно? У тебя есть реальный список примеров?

Тут юзается общий принцип "ненарушения потока кода, отсутствия дублирования и определения AlgDT на ходу", что на самом деле весьма удобно.

Хотя я бы даже предпочел еще более избыточную запись ("??" означает заполнение списка параметров компилятором)

Variant<??> f(int i) { return x!=0 ? "non-zero" : 0 }

По аналогии тут вспоминаются ADT в лиспе для (очень) бедных. Я про них обещал рассказать.

www_linux_org_ru ★★★★★
() автор топика
Ответ на: комментарий от www_linux_org_ru

Тут юзается общий принцип "ненарушения потока кода, отсутствия дублирования и определения X на ходу", что на самом деле весьма удобно. (в инкарнации X=AlgDT)

// FIXED.

www_linux_org_ru ★★★★★
() автор топика
Ответ на: комментарий от www_linux_org_ru

Variant<??> f(int i) { return i!=0 ? "non-zero" : 0; }

// и остальные так же пофиксить

www_linux_org_ru ★★★★★
() автор топика
Ответ на: комментарий от www_linux_org_ru

> Хиндли-М. как-то научно обоснован, но все равно приходится

Тут нет никаких типоклассов, тут ничего по идее не надо аннотировать - он сам может и должен вывести. Почему я должен делать аннотации, если у меня нет никаких ошибок - компилятор умнее меня? Если не хочешь, чтобы оно молча выводил такие типы в лиспе, пишешь declaim с указанием желаемого типа, и он будет ругаться. По-моему все логично.

> Хотя я бы даже предпочел еще более избыточную запись ("??" означает заполнение списка параметров компилятором)

* , он сам заполнит. Просто пишешь (declaim (ftype (function (fixnum) *) f)). Также он может использоваться для создания "вариантов" типов. Например, есть тип вектор - обозначается он обычно примерно так (vector double-float 100) - это вектор, содержащий 100 элементов типа double-float. Но ты можешь указать например тип (vector * 100) - вектор содержит 100 элементов неизвестного типа, или (vector integer *) - вектор с незестным количеством элементов типа integer, или (vector * *) - вектор с неизвестным количеством элементов неизвестного типа. Можно (vector t *) - это вектор элементов общего типа.

> По аналогии тут вспоминаются ADT в лиспе для (очень) бедных. Я про них обещал рассказать.

Для CL, в Qi секвенциальные типы данных - они вроде как мощнее ADT, хотя типизация динамическая.

anonymous
()
Ответ на: комментарий от aninamous

> поскольку в языке существуют функции с несколькими аргументами

Нет. Это такое распространённое заблуждение.

> поэтому необходимо упорядочивать множество аргументов

Тьфу ты, блин. Я сразу про посеты подумал.

Miguel ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

> А потом в программе появится десяток новых типов, и твой паттерн матчинг придется переписать.

Почему я, собственно, и говорю, что паттерн-матчинг - штука не первой надобности.

Правда, тут дело не в новых типах. В принципе, никто не мешает писать, например, [code] data Container where Container :: GoodType a => a -> Container [/code] и просто объявлять новые инстансы класса GoodType. В Hugs-е это не заработает, но можно сделать несколько менее удобный аналог.

Miguel ★★★★★
()
Ответ на: комментарий от anonymous

Математика и Comuter Science(а тем более, программирование) это совершенно разные области. Они на разные вопросы отвечают, грубо говоря. Математика отвечает на вопрос "что?", а CS - на вопрос "как?".

anonymous
()
Ответ на: комментарий от www_linux_org_ru

> Посмотри, где там С++

Я, в общем, и так представляю, где он. О какой типизации речь, если пойнтеры на разные вещи элементарно кастятся друг к другу?

Сам же говоришь:

> в плюсах я бы хотел более четкую изоляцию

> Где ты видишь противоположные примеры в плюсах?

На каждом шагу, увы.

Miguel ★★★★★
()
Ответ на: комментарий от anonymous

> Почему я должен делать аннотации, если у меня нет никаких ошибок - компилятор умнее меня?

Не обязательно (хотя весьма вероятно). Но зачем отвергать его помощь?

Miguel ★★★★★
()
Ответ на: комментарий от anonymous

> Математика отвечает на вопрос "что?"

Что-что?

Miguel ★★★★★
()
Ответ на: комментарий от Miguel

> Не обязательно (хотя весьма вероятно). Но зачем отвергать его помощь?

Но он не просто выдает варнинг (я был бы не против этого),- он выдает ошибку, хотя это на самом деле не ошибка. Я был бы совершенно не против этого, если бы я попытался использовать эту функцию в выражении наподобие этого - 1 + (f 1) - ведь понятно, что я тогда _гарантированно_ ошибюсь.

anonymous
()
Ответ на: комментарий от anonymous

>Только в сраной рашке и прочих зимбабве, где информатика как наука не развита совсем.

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

Waterlaz ★★★★★
()
Ответ на: комментарий от Waterlaz

Да изучал, как раз.
Это не математика уже лет 60, если не больше.

А то точно так же можно утверждать что физика это философия.

anonymous
()
Ответ на: комментарий от anonymous

> Это не математика уже лет 60, если не больше.

Это раздел математики. Очень прикладной, правда.

Miguel ★★★★★
()
Ответ на: комментарий от anonymous

Ну.. инфортматика то как раз слишком широкое понятие и ИМХО глупое.

Waterlaz ★★★★★
()
Ответ на: комментарий от Miguel

> Я, в общем, и так представляю, где он. О какой типизации речь, если пойнтеры на разные вещи элементарно кастятся друг к другу?

Иди поспорь с Benjamin C. Pierce. и заставь его переписать TAPL, альтернативно одаренный ты наш.

www_linux_org_ru ★★★★★
() автор топика
Ответ на: комментарий от www_linux_org_ru

> Иди поспорь с Benjamin C. Pierce. и заставь его переписать TAPL, альтернативно одаренный ты наш.

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

Miguel ★★★★★
()
Ответ на: комментарий от anonymous

> (vector integer *) - вектор с незестным количеством элементов типа integer

с неизвестным постоянным или с неизвестным переменным?

www_linux_org_ru ★★★★★
() автор топика
Ответ на: комментарий от Miguel

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

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

www_linux_org_ru ★★★★★
() автор топика
Ответ на: комментарий от Miguel

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

Образование вообще и математика в частности не имеют к этому отношения. Это особенность харктера или диагноз.

P.S. нельзя ли вернуться к конструктивному флейму? А то рассуждения о высоких теоретических материях (типа является ли программирование математикой) навевают скуку.

tailgunner ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.