LINUX.ORG.RU

GHC 8.8.1

 , ,


5

9

Тихо и незаметно, вышла новая версия известного компилятора языка программирования Haskell.

Среди изменений:

  • Поддержка профилирования на 64-битных системах с Windows.
  • GHC теперь требует LLVM версии 7.
  • Метод fail окончательно вынесен из класса Monad, теперь он находится в классе MonadFail (финальная часть MonadFail Proposal).
  • Явное применение типа (type application) теперь работает и для самих типов, а не только для значений.
  • forall теперь является ключевым словом вне зависимости от контекста, что позволяет использовать его в type families и rewrite rules.
  • Улучшен алгоритм компоновки кода для x86.
  • Множество других изменений.

>>> Полный список изменений

>>> Гайд по миграции кода на новую версию

>>> Скачать

★★★★★

Проверено: jollheef ()
Последнее исправление: Virtuos86 (всего исправлений: 4)
Ответ на: комментарий от monk

Хотя нет, вру, возможно дальнейшее упрощение

=>
(defun whileM (p m)
  (lambda ()
    (if (funcall p) 
        null
        (progn (funcall m) (funcall (whileM p m))))))
И (funcall (whileM p m)) упрощается до
(if (funcall p) 
    null
    (progn (funcall m) (funcall (whileM p m))))))
то есть конечно-хвостовой становится конструкция (funcall (whileM p m)). При желании можно научить компилятор такие структуры отлавливать.

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

вызов (whileM p m) не является хвостовым, если >> является функцией.

В том и посыл, что вызов «whileM p m» является хвостовым, причем, это случай косвенной рекурсии. Есть еще прямая.

Ладно. Мне чего-то надоело уже.

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

В том и посыл, что вызов «whileM p m» является хвостовым, причем, это случай косвенной рекурсии. Есть еще прямая.

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

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

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

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

IO просто так посреди кода не воткнете - во всех зависимостях придется это явно отразить

Так можно и все языки со статической типизацией критиковать: просто так целое на вещественное не поменять, придётся в всех зависимостях типы поменять.

Никто не мешает писать на хаскеле целиком в IO, если предполагается произвольное действие в любом месте.

в своей нише он феерит (например, где надо преобразовать из чего-то заранее заданного во что-то другое и завершить выполнение), но есть масса вещей, где его модель вообще не подходит

Хаскель очень хорошо сочетается с TDD.

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

Ты конечно прав, но не расслабляйся, аргумент с целыми и вещественными не подходит из-за раковой природы монад, тогда как с числами можно типы приводить взад-назад. unsafePerformIO не считается:)

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

аргумент с целыми и вещественными не подходит из-за раковой природы монад

В чём разница? Любой тип имеет раковую природу. Что там придётся все аргументы у всех функций перебивать, что здесь всюду IO добавлять или убирать. Александреску свой паттерн «стратегия» не от хорошей жизни придумал.

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

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

Распишу для F#. Для простоты изложения будем использовать явную монадическую связку, раз ленивость запутывает и уводит от сути:

let whileAsync p m = 
    if p () then
       async.Bind(m, fun () -> whileAsync p m)
    else
       async.Zero()

Так стало понятнее?

Вызов хвостовой. Поскольку в Bind тоже вызовы все хвостовые (см. код F#), то созданы все условия для работы оптимизатора хвостового вызова.

Кстати, бесконечный цикл while true для async в F# в обычном .NET не сжирает всю память именно по этой причине!

dave ★★★★★
()
Последнее исправление: dave (всего исправлений: 4)
Ответ на: комментарий от monk

И стек тоже не сжирает. А вот совершенно аналогичный код, над которым работала команда Одерского для плагина продолжений, съедала стек JVM, поскольку в JVM нет TCO, тогда как во многих версиях CLR есть (только хвостовой вызов надо явно обозначить в байт-коде).

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

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

Вызов хвостовой. Поскольку в Bind тоже вызовы все хвостовые (см. код F#), то созданы все условия для работы оптимизатора хвостового вызова.

Я примерно это и расписал: GHC 8.8.1 (комментарий)

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

Вот для SBCL:

* (disassemble 'whileM)

; disassembly for WHILEM
; Size: 91 bytes. Origin: #xAA29465
; 65:       8B0D3494A20A     MOV ECX, [#xAA29434]             ; no-arg-parsing entry point
                                                              ; #<FUNCTION (LAMBDA
                                                              ;                # ..)>
; 6B:       64892D1C000000   MOV FS:[#x1C], EBP
; 72:       BB10000000       MOV EBX, 16
; 77:       64031D0C000000   ADD EBX, FS:[#xC]
; 7E:       643B1D10000000   CMP EBX, FS:[#x10]
; 85:       7607             JBE L0
; 87:       E8B4B064FD       CALL #x8074540                   ; alloc_overflow_ebx
; 8C:       EB0A             JMP L1
; 8E: L0:   64891D0C000000   MOV FS:[#xC], EBX
; 95:       83EB10           SUB EBX, 16
; 98: L1:   8D5B05           LEA EBX, [EBX+5]
; 9B:       C743FB2E030000   MOV DWORD PTR [EBX-5], 814
; A2:       8D5113           LEA EDX, [ECX+19]
; A5:       8953FF           MOV [EBX-1], EDX
; A8:       64312D1C000000   XOR FS:[#x1C], EBP
; AF:       7402             JEQ L2
; B1:       CC09             BREAK 9                          ; pending interrupt trap
; B3: L2:   897B03           MOV [EBX+3], EDI
; B6:       894307           MOV [EBX+7], EAX
; B9:       8BD3             MOV EDX, EBX
; BB:       8BE5             MOV ESP, EBP
; BD:       F8               CLC
; BE:       5D               POP EBP
; BF:       C3               RET

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

совершенно аналогичный код, над которым работала команда Одерского для плагина продолжений, съедала стек JVM, поскольку в JVM нет TCO

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

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

Я понял твою точку зрения.

И кстати, SBCL часто умеет делать TCO, в отличие от LispWorks и CCL. Но у тебя такого примера для SBCL я пока не заметил.

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

И кстати, SBCL часто умеет делать TCO, в отличие от LispWorks и CCL. Но у тебя такого примера для SBCL я пока не заметил.

Так я же привёл пример с WHILEM. Он транслируется в ассемблер без использования CALL, потому что TCO.

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

совершенно аналогичный код, над которым работала команда Одерского для плагина продолжений, съедала стек JVM, поскольку в JVM нет TCO

Совершенно аналогичный код на SISC стек JVM не съедает, потому что разработчики SISC сделали нормальный компилятор, а не прямую трансляцию вызовов функций Scheme в вызовы функций JVM.

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

Кстати, в контексте нашего спора и Хаскеля: кто что хорошее или плохое может сказать про хаскель на JVM? То есть Eta.

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

просто так целое на вещественное не поменять, придётся в всех зависимостях типы поменять

Так в ML/Haskell как раз не придется, если весь код полиморфный. Даже в C++ так можно, хотя выглядеть будет страшновато (в C++20 лучше).

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

2019 год на дворе. На ЛОРе уже давно не спорят конструктивно о языках. Интересующиеся давно сбежали в телегу, да простит меня РКН.

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

Авторы пишут, что да:

Is Eta ready to use?

Yes! You can compile the vast majority of programs that GHC Haskell 7.10.3 can along with some additional extensions and interoperate with Java, Scala, and Clojure with ease.

....

Eta will be a language with commercial support, backed by TypeLead. Therefore, our foremost priority is making the language stable, fast, and building a wide user base. This may conflict with the primary goal of GHC - to be a research platform for cutting-edge CS research. We believe that GHC being able to realize its goal and survive for decades is commendable and we have an amazing language as a result of its of labor.

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

Без таких ненужно сидели бы до сих пор в автокоде и фортране (в лучшем случае).

Анонимус, ты бредишь. Какое отношение имеет Хацкель к твоему сидению в фортране?

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

Что оно дает, кроме возможности лихо писать ХВ в 10 строчек? Выглядит очень стильно-модно-молодежно. Короче, хочется поскорее закрыть вкладку.

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

2019 год на дворе. На ЛОРе уже давно не спорят конструктивно о языках. Интересующиеся давно сбежали в телегу, да простит меня РКН.

Да ты рофлишь. Когда на ЛОР обсуждали хоть что-то конструктивно? Если только в обсуждении не участвуют непрошибаемые интеллигенты вроде Квазимото, невозмутимо выкатывающие экраны текста про монады и кластеры метапарадигм.

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

Когда на ЛОР обсуждали хоть что-то конструктивно?

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

Вот только почти все способные ушли, остались одни цари. Даже про кресты один порожняк, куда там хаскелю. Иногда перечитываю старые треды в /dev и плачу.

непрошибаемые интеллигенты вроде Квазимото, невозмутимо выкатывающие экраны текста про монады и кластеры метапарадигм

Ну вот monk, только понимает его те же несколько человек. Но спасибо ему, да.

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

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

Эх... спасибо Антихристу/Луговскому. Столько полезной информации выкладывал. Хотя и нецензурно местами....

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

Ну да, наверно ему ЛОР обязан тем своим уровнем. И наверно закономерно оно затухает со временем.

А я застал уже следующее поколение. Absurd, r, tailgunner, lester, mv, ip1981, lovesan, ...

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

Что оно дает, кроме возможности лихо писать ХВ в 10 строчек?

Полный Haskell + все библиотеки Java.

Я бы поменял местами, если по-честному. Потому что Хацкель уже есть, и Ета не нужна без джавовских либ. Еще интересно, как это отлаживать. Я бы изучил опыт других ЯП на JVM, чтобы примерно понимать, какие проблемы огребешь.

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

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

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

Ну вроде как котлин умеет неплохо трансформировать код, когда помечаешь его tailrec или async. Как считаешь, его движка достаточно для того, чтоб не переписывать код полностью руками в тех случаях, когда необходимо (и возможно) провести TCO?

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

про хаскель на JVM

Я не противник JVM. Мне просто не нравится скрещивать ежей с ужами. Если сидишь на JVM - бери котлин. Он написан конкретно под JVM и раскрывает её потенциал минимальными усилиями. Единственное исключение - JS ибо TypeScript не настолько крут, чтобы отказаться от идеи поискать другие языки. Ну есть еще coffeescript, но то на любителя.

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

Еще интересно, как это отлаживать.

А разве для отладки Хаскеля есть что-то кроме trace? Ведь gdb ничего вразумительного не покажет. Или я неправ?

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

Я вообще не в курсе, как с отладкой обстоит дело в Хацкеле :) Всего лишь пытаюсь искать аналогии в существующем опыте, чтобы не вставать на уже использованные грабли. Логично прежде всего поискать ответы на самые насущные вопросы, отладка несомненно один из них.

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

SISC

А оно, вообще, живое?

В вики написано, что Stable release 1.16.6 / February 27, 2007.

На официальном сайте нет (я не нашёл, по крайней мере) ссылок ни на исходники, ни на бинарники, ни кнопки «купить».

И что насчёт гораздо более свежей Kawa?

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

А оно, вообще, живое?

Также как и TeX достигло совершенства. R5RS реализован полностью, среди таковых реализаций одна из самых быстрых.

На официальном сайте нет (я не нашёл, по крайней мере) ссылок ни на исходники, ни на бинарники, ни кнопки «купить».

У меня официальный сайт РосКомНадзор блокирует. Есть всё на https://sourceforge.net/projects/sisc/files/

И что насчёт гораздо более свежей Kawa?

Call/cc не умеет (умеет только выходить из блока, но не возвращаться в него). TCO не по стандарту (примерно как в SBCL). За счёт этого чуть быстрее, чем SISC. Но с таким подходом лучше бы они Common Lisp ваяли.

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

Я вообще не в курсе, как с отладкой обстоит дело в Хацкеле

Вот поэтому «полный Haskell + все библиотеки Java» именно в таком порядке. Если просто нужны библиотеки, если Java и Kotlin, если нужна функциональщина на JVM, есть Scala. А вот если нужен именно Haskell с хорошими библиотеками, то только Eta.

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

Ты не находишь, что юзкейс _очень_ специфичный? Промышленные хаскеллисты или как назвать его потенциальную очень малочисленную аудиторию?)

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

Ну Racket так же начинал. Промышленные схемеры, однако. Сейчас чуть ли не самый распространённый диалект.

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

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

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

Использую. Для того, что предназначено исключительно для Линукса. На оффтопике он слишком сложно устанавливается. Для разработки ещё сойдёт, а вот дистрибутив скомпилированной программы для пользователя так и не понял как делать.

И в этом смысле задумался про Eta. Java проще ставится и чаще уже есть у потенциального пользователя.

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

Кста на счет ракеты, хотел вот спросить, обычная схема сильно отстаёт от ракеты в плане макросов?

Именно в плане макросов R5RS и R7RS small отстаёт сильно. R6RS и R7RS large также как и Racket имеет syntax-case, что позволяет почти все макросы реализовать.

В обычной схеме нет синтаксических параметров (есть в STFI-139), нету подъёма синтаксических объектов (например, на Racket я могу сделать, чтобы при вызове создавались новые функции верхнего уровня, как в шаблонах Си++, а в стандартной схеме — нет).

я смогу там повторить все фокусы из ракеты с узерскими языками?

Языки в ракете создаются не за счёт макросов, а за счёт обработки конструкции #lang (там привязывается парсер). В схеме только написав собственный аналогичный механизм, тогда в Racket

#lang bf
Greatest language ever!
++++++++[>++++++++<-]>.
а в Scheme что-то вроде
(lang bf "++++++++[>++++++++<-]>.")

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

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

Оказывается, бывает и наоборот.

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

Хацкель стал настолько ненужно, что в чатике вяло спорят монк и дэйв. Мда

Это просто уровень погромистов ЛОРа (да и Ваш). Низковат.

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