LINUX.ORG.RU

Typeclasses в Haskell

 ,


0

1

Часто можно услышать их сравнение с «интерфейсами в java» или что-то в таком духе. На мой взгляд, это плохая аналогия. Тайпклассы больше напоминают свободные шаблонные функции с неопределённой для общего типа реализацией (ну или [взаимно]определенные через другие функции, но это уже детали), которые надо явно инстанциировать для своего типа.

★★★

Последнее исправление: utf8nowhere (всего исправлений: 1)
Ответ на: комментарий от Miguel

Опции оптимизации у Rust есть? Если да — то они обязаны влиять на компиляцию этого AST.

Оптимизация выполняется следующим проходом.

Ну, представь, что вышла новая версия библиотеки

А. То есть критерий полноценности параметрического полиморфизма - двоичная совместимость библиотек? Так можно далеко зайти. До самого JIT.

Тебе достаточно линковки или нужно перекомпилировать клиент полностью?

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

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

Оптимизация выполняется следующим проходом.

Ну вот.

То есть критерий полноценности параметрического полиморфизма - двоичная совместимость библиотек?

Стоп-стоп-стоп. Мы говорили про полноценность раздельной компиляции.

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

«Конечно же», пока у вас Rust или C++.

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

Опции оптимизации у Rust есть? Если да — то они обязаны влиять на компиляцию этого AST.

Оптимизация выполняется следующим проходом.

Ну вот.

Оптимизация выполняется следующим проходом после генерации AST, и не влияет на AST.

Мы говорили про полноценность раздельной компиляции.

А потом ты заговорил о перелинковке. Если подразумевать традиционный линковщик, то его недостаточно. Однако, если подразумевать что-то вроде древнего Ultra C (в котором линковщик понимал промежуточное представление), он справился бы. Я же говорю, мы далеко зайдем, если примешаем технологию компиляции в рассмотрение полиморфизма.

«Конечно же», пока у вас Rust или C++.

Или Ada. Или MLton. Или еще что-то эффективное^Wс мономорфизацией.

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

Оптимизация выполняется следующим проходом после генерации AST

Именно.

Я же говорю, мы далеко зайдем, если примешаем технологию компиляции в рассмотрение полиморфизма.

Речь не о технологии, а о наличии.

Или Ada. Или MLton. Или еще что-то эффективное^Wс мономорфизацией.

GHC делает частичную мономорфизацию, как уже говорилось. Но при этом генерирует и generic-версию, используемую, когда ему не удаётся предугадать тип, или когда это какой-то новый тип, ранее неизвестный.

Насчёт MLton не знаю, не интересовался.

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

Речь не о технологии, а о наличии.

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

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

Полиморфизм в наличии, потому что это понятие, относящееся только к компиляции.

Вопрос о наличии КОМПИЛЯЦИИ.

твоя точка зрения общепринятой не является

Из всего, что я сказал, «точкой зрения» является ТОЛЬКО разграничение понятий «шаблон» и «дженерик». Я попросил тебя привести другой вариант, и ты привёл такой, который, в зависимости от понимания, либо согласуется с моим, либо же делает дженериками то, что в плюсах. Попробуешь ещё раз?

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

И все. GHC, например, мимо.

Нет, не мимо. Вот вызовешь ты fold (+) над тем же FingerTree Rational, так код fold'а вызовется из одного объектника, а код (+) из другого.

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

Вопрос о наличии КОМПИЛЯЦИИ.

Раскрой тему, если хочешь. Мне надоело у тебя выпытывать, что ты на этот раз имел в виду.

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

Проблема не в монорфизации. Еще раз, GHC ее тоже _делает_. И это не мешает велосипедить finger trees на хаскеле.

Проблема в том, что ты путаешь обязательную мономорфизацию с опциональной. GHC её делает опционально, где и когда это делать — указано специальными правилами. И да, в таком случае эта фишка является чисто оптимизацией. Например, помогает при преобразовании из Word в Int избежать промежуточного Integer (см. fromIntegral).

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

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

Раскрой тему, если хочешь. Мне надоело у тебя выпытывать, что ты на этот раз имел в виду.

А мне надоело ходить по кругу. В комментах выше всё есть.

Нет, преобразование Source->AST — нифига не компиляция. И нет, линковка — тоже не компиляция. А если в линкер вставлен кусок компилятора, значит, это нифига не линкер.

И да, я понимаю, что можно наскрести промежуточных примеров. Но из того, что существуют субстанции, которые невозможно уверенно отнести ни к жидким, ни к твёрдым, не следует, что жидкое и твёрдое вообще не отличаются.

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

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

Разве это не детали реализации? Если они в новой версии уберут мономорфизацию, разве перестанет работать какой-то корректный код?

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

Если уберут обязательную мономорфизацию, то старый код работать не перестанет. Ну, не должен, по крайней мере :) Зато заработает новый код, открывающий новые границы для веселья с типами.

Кстати, да, вполне возможно, что авторы оставили этот момент в закладках на будущее.

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

Да тем самым. Преобразование Source->AST — это микроскопическая часть компиляции.

Скажи, а каким образом, по-твоему, GHC генерирует инстансы для конкретных типов? ТЫ знаешь какой-то другой способ, кроме как из того или иного представления АСТ?

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

«Конечно же», пока у вас Rust или C++.

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

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

GHC делает частичную мономорфизацию, как уже говорилось. Но при этом генерирует и generic-версию, используемую, когда ему не удаётся предугадать тип, или когда это какой-то новый тип, ранее неизвестный.

Ты, видимо, не в курсе, как работает ghc. В случае того, о чем ты говоришь (раздельной компиляции) все будет как в этих ваших сишкак - то есть мономорфизация вызовов с перекомпиляцией всего, что требуется. Генерик-варинт функции используется только в случае high-rank полиморфизма (т.к. в этом случае инстанс неопределенный by design).

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

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

Java, C#(да и весь .NET потенциально).

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

Нет, преобразование Source->AST — нифига не компиляция. И нет, линковка — тоже не компиляция. А если в линкер вставлен кусок компилятора, значит, это нифига не линкер.

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

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

Нет, не мимо. Вот вызовешь ты fold (+) над тем же FingerTree Rational, так код fold'а вызовется из одного объектника, а код (+) из другого.

Так фолд - это не ф-я тайпкласса, с-но он аргумент тайпкласса и не получает.

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

Проблема в том, что ты путаешь обязательную мономорфизацию с опциональной. GHC её делает опционально

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

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

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

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

Нет, преобразование Source->AST — нифига не компиляция. И нет, линковка — тоже не компиляция. А если в линкер вставлен кусок компилятора, значит, это нифига не линкер.

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

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

Зато заработает новый код, открывающий новые границы для веселья с типами.

Не заработает, для этого надо будет сильно править систему типов, то етсь семантику языка

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

Java, C#(да и весь .NET потенциально).

Да но, дуднет хранит представление АСТ генерика (можно даже к нему обращаться в рантайме и переписывать), а потом из него в нужный момент _в рантайме_ компилит нужные инстансы, по-этому он обязан за собой тянуть компилятор. В джаве нету мономорфизации, что обходится значительными ограничениями для этих самых генериков и опять же оптимизируется это дело за счет агрессивного джита (снова компиляция инстансов в рантайме, по факту). Магии нет, без дополнительной компиляции инстансов не обойтись, либо же ты получаешь тормоза.

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

по-этому

поэто-му

не благодари

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

Ты предлагаешь теперь всё это месево обмана и просто вызывающе неверной информации долго и нудно опровергать по пунктам?

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

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

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

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

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

Ага. То есть, уверенно идём в сторону шаблонов.

Пусть так, но согласиться с «худшим из двух миров» я не могу. В наличии нормальные сообщения об ошибках и специализация - весьма неплохо.

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

При наличии специализации — согласен.

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