Здравствуйте, deniok, Вы писали:
D>Я несколько месяцев назад пытался искать, начиная отсюда, но в документации по GHC очень это довольно скупо описано.
Вообще не стоит забывать, что полный strictness analysis — это по сути проблема останова. Поэтому GHC не может форсировать всё, что будет требоваться. Однако некоторые случаи он распознаёт.
Как работает простой strictness analysis в GHC интуитивно, думаю, понятно (см. описание demand analysis на википедии).
Тем не менее, насколько я помню (не могу сейчас найти подтверждение) в GHC strictness analysis работает вместе с несколькими другими оптимизациями — unboxing, constructor specialization. Хотя здесь и пишут, что unboxing всего лишь возможен. хз.
Но я думаю, что там не простой demand analysis, который как указывают на вики "can only model strictness within product types". По крайней мере foldl он трансформирует в strict — попробуй -O2.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[12]: Функция как первоклассная сущность для рантайма
Здравствуйте, deniok, Вы писали:
L>> По крайней мере foldl он трансформирует в strict — попробуй -O2.
D>О как! А я как раз над этим сижу, размышляю — почему бы не
Он давно мог, кстати. 6.4 точно.
Потому что помню, что foldl' я использовал для GHCi, чтобы сэмулировать foldl при -O2
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[16]: Функция как первоклассная сущность для рантайма
Здравствуйте, Курилка, Вы писали:
К>Т.е. "снаружи" я это использовать не могу и если есть "затыки" в моём коде, то только лишь я во всём виноват?
Ну, как говорил мой учитель, машина не ошибается, ищи ошибки у себя
К>Блин, а я-то надеялся, что можно хоть какие-нибудь примитивные ворнинги получить. Типа: "вот здесь всё строго-строго, а вот тут чот непонятное, вы уверены, что это не _|_?".
Какие ворнинги? Вроде как для компилятора всё понятно: семантика нарушаться не должна, как только _|_ в аргументе может не влиять на результат, то просто не форсируем. Единственное, что при таких рассуждениях не учитывается — это размер памяти (да и вообще — в лямбда исчислении не ограничено кол-во термов, а в машине Тьюринга — длина ленты). Т.е. лениво ли что то или энергично — результат должен быть один. В реальном мире это не так, вот мы и получаем для одного и того же выражения в случае интерпретации ошибку, а в случае компиляции — нормальный результат. С другой стороны, оптимизации в компиляторах всегда обладали небольшими сайд-эффектами
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[16]: Функция как первоклассная сущность для рантайма
Здравствуйте, Курилка, Вы писали:
К>Здравствуйте, deniok, Вы писали:
D>>А что ты увидеть хочешь? Это — деталь реализации компилятора, полностью прозрачная для пользователя. По идее это может улучшить пространственную сложность некоторых алгоритмов, но, я думаю, только в отношении постоянного коэффициента
К>Т.е. "снаружи" я это использовать не могу и если есть "затыки" в моём коде, то только лишь я во всём виноват? К>Блин, а я-то надеялся, что можно хоть какие-нибудь примитивные ворнинги получить. Типа: "вот здесь всё строго-строго, а вот тут чот непонятное, вы уверены, что это не _|_?".
Так наоборот, если f — строгая по своему аргументу, то f _|_ = _|_. Это, собственно, определение:
f - строгая, если из x = _|_ следует f x = _|_
А если f нестрогая, то f _|_ может проканать. Строгость/нестрогость полезны для анализа _|_-консьюминга, а в деле _|_-продьюсинга играет роль тотальность
f - тотальная, если из f x = _|_ следует x = _|_
или, что то же самое
f - тотальная, если из x # _|_ следует f x # _|_
Re: Функция как первоклассная сущность для рантайма
Здравствуйте, deniok, Вы писали:
D>Открою маленькую тайну: в чисто функциональных языках первоклассная сущность функций сохраняется вплоть до рантайма: указатели на данные и на код вычисляющий эти данные эквивалентны и вообще неразличимы Это реализуется, например, G-машиной (STG в случае компилятора GHC языка Haskell). Поэтому на дотнете возможна только эмуляция такой "глубокой" чистой функциональности — той или иной степени успешности. В свете этого я думаю, что C# — наиболее перспективный "функциональный" (на синтаксическом уровне) язык
Открою больший сикрет. Сущность или первокласна, или сохраняется до чего-то там. А ФЯ — это язык где функцией можно манипулировать как любым бдругим значением. C# сильно продвинулся в этом направлении, но пока что все же сильно уступает языкам перечисленным в теме.
Что до чистоты Хаскеля, то это замечательное свойство этого языка как раз и делает его никчемной игрушкой. В прочем не оно (оно мнимое), а те жертвы на которые прихдится идти создателям компиляторов.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Функция как первоклассная сущность для рантайма
Здравствуйте, deniok, Вы писали:
D>Механизм вызова виртуальных функций в C++ тоже зависит от реализации и не документирован в стандарте Но все применяют единственную реализацию (естественную для стандартной архитектуры рантайма).
Это не так. Насклько я знаю в компиляторах Сана по соляркой используется свой вариант.
EC>>Вот левая и правая свёртки списка по разному используют память. Это артефакт реализации и от семантики никак не зависит?
D>Это прямо следует из нормального порядка редукций и ленивости.
Ленивость не является определяющим фактором для того чтобы признать язык ФЯ.
ФЯ — это язык на котором удобно писать программы в функциональном стиле. А чистый ФЯ — это ЯП на котором неудобно писать программы в стилях отличных от ФП. Все остальное бред и фанатство.
Так что кончай эти войны, ни то по твоей логике Лисп и МЛ окажутся не ФЯ, только потмоу, что они не похожи на Хаскель.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Функция как первоклассная сущность для рантайма
D>>Механизм вызова виртуальных функций в C++ тоже зависит от реализации и не документирован в стандарте Но все применяют единственную реализацию (естественную для стандартной архитектуры рантайма). VD>Это не так. Насклько я знаю в компиляторах Сана по соляркой используется свой вариант.
А как под соляркой реализованы виртуальные функции?
... << RSDN@Home 1.2.0 alpha rev. 717>>
Re[2]: Функция как первоклассная сущность для рантайма
Здравствуйте, VladD2, Вы писали:
VD>Что до чистоты Хаскеля, то это замечательное свойство этого языка как раз и делает его никчемной игрушкой. В прочем не оно (оно мнимое), а те жертвы на которые прихдится идти создателям компиляторов.
Если что его и делает никчемной игрушкой (в плане промышленного использования), то это не столько свойства языка (ну не всем же быть C-подобными), а сообщество разработчиков, для которых основной целью является добавление фич и эксперименты с системой типов, а не доведение компилятора до ума. В итоге — поддержка динамической линковки только под MacOS (вроде бы), интероперабельность с другими языками в зачаточном состоянии, поддержка Win64 — нет и неизвестно (Булат недавно пытался их уговорить — вежливо послали на "сделай сам"; кстати, интересно, куда он после этого запропал — может уже делает?). Или вот недавно наступил на грабли — невозможность выделить память приводит не к исключению, а к завершению процесса с ошибкой. Причем эта тема периодически обсуждается с 2000 года, а воз и ныне там.
А в остальном — самый его существенный недостаток — то, что на начальном этапе нужно слегка сломать мышление. В некотором роде это даже полезно — позволяет посмотреть на решаемые задачи под другим углом.
Re[3]: Функция как первоклассная сущность для рантайма
S>Если что его и делает никчемной игрушкой (в плане промышленного использования), то это не столько свойства языка (ну не всем же быть C-подобными), а сообщество разработчиков, для которых основной целью является добавление фич и эксперименты с системой типов, а не доведение компилятора до ума.
Этот компилятор невозможно довести до ума. Да и компилятором то его сделать невозможно. И виной всему ленивость по умолчанию. Чтобы сделать эффективный компилятор для Хаскеля нужен ИИ. Вот только когда он появится, нужды в Хаскеле уже не будет.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Функция как первоклассная сущность для рантайма
Здравствуйте, VladD2, Вы писали:
VD>Этот компилятор невозможно довести до ума. Да и компилятором то его сделать невозможно. И виной всему ленивость по умолчанию. Чтобы сделать эффективный компилятор для Хаскеля нужен ИИ. Вот только когда он появится, нужды в Хаскеле уже не будет.
Да не все так плохо с ленивостью по умолчанию. Эта такая известная грабля — space leak, когда вместо вычисления реального значения плодятся невычисленные thunk'и. Решается поставленной в нужном месте strictness annotation — в случае с GHC это просто один лишний восклицательный знак. Грабля? Да грабля, но ничем не лучше и не хуже, чем, скажем, тонкости поведения конструкторов/деструкторов в C++ или детерминированное освобождение unmanaged-ресурсов в дотнетовских языках. Просто ее надо учитывать. Ты же не станешь спорить, что по незнанию в C# можно наворотить тормозов на ровном месте?
Re[5]: Функция как первоклассная сущность для рантайма
Здравствуйте, Schade, Вы писали:
S>Да не все так плохо с ленивостью по умолчанию. Эта такая известная грабля — space leak, когда вместо вычисления реального значения плодятся невычисленные thunk'и. Решается поставленной в нужном месте strictness annotation — в случае с GHC это просто один лишний восклицательный знак. Грабля? Да грабля, но ничем не лучше и не хуже, чем, скажем, тонкости поведения конструкторов/деструкторов в C++ или детерминированное освобождение unmanaged-ресурсов в дотнетовских языках. Просто ее надо учитывать. Ты же не станешь спорить, что по незнанию в C# можно наворотить тормозов на ровном месте?
Польза функциональных языков состоит в том, что они позволяют сосредоточиться непосредственно на задаче, а не инфраструктуре вокруг нее, т.е. повышают уровень абстракции. Как простейший пример — знаменитый for (i=1;i<N;i++) {} против map. Изначально (в книгах) ленивость приводят как пример еще большего упрощения программ за счет рекурсивных данных, недовычленных выражений и т.п. Но все эти преимущества так и остаются в книгах, поскольку на практике мы сталкиваемся а) с убогим вводом-выводом через монады и всеми замечательными последствиями этого типа отсутствия нормальных исключений (см. память) и отладчика и б) мемори ликами в самых неожиданных местах. Это страшный геморой, когда для того, чтобы вывести отладочную информацию, приходится либо применять дедуктивные методы, либо искать способ, как подвести монаду к нужному месту. Еще хуже мемори лики — то ли везде ставить !, то ли опять же заниматься мощной дедукцией, пытаясь догадаться нужен ли ! в этом месте или нет.
Re[6]: Функция как первоклассная сущность для рантайма
Здравствуйте, Quintanar, Вы писали:
Q>Польза функциональных языков состоит в том, что они позволяют сосредоточиться непосредственно на задаче, а не инфраструктуре вокруг нее, т.е. повышают уровень абстракции. Как простейший пример — знаменитый for (i=1;i<N;i++) {} против map. Изначально (в книгах) ленивость приводят как пример еще большего упрощения программ за счет рекурсивных данных, недовычленных выражений и т.п. Но все эти преимущества так и остаются в книгах,
Ну, я вообще-то не настаиваю на том что ленивость — единственный и верный путь. А вот масштаб проблем, пожалуй, преувеличен. Q>поскольку на практике мы сталкиваемся а) с убогим вводом-выводом через монады
Насчет убогости такого IO — очень спорный вопрос. Особенно в свете того, что IO actions сами по себе являются значениями, которыми можно манипулировать посредством функций.
Q>и всеми замечательными последствиями этого типа отсутствия нормальных исключений
Нормальные исключения таки есть — единственное ограничение — отлавливаются они только в пределах IO монады, а бросать можно откуда хочется. Q>(см. память)
Это да, это болезненная грабля. Тут, наверное, вылазит боком тот факт, что GHC team, судя по всему, может себе позволить ранжировать задачи по разработке компилятора по шкале "прикольно-не прикольно" (как и с поддержкой Win64 — "тут работы на пару недель, но Win64 таакая-прааативная, что это будут очень безрадостные 2 недели" (c) Simon Marlow) Вот и с памятью, бедолага, уж 8 лет мучительно думает, откуда взять еще немножно пямяти для обработки исключения, если причина исключения — нехватка памяти
Однако ж к ленивости и самому по себе механизму исключений это, пожалуй, отношения не имеет. Кстати, прям-таки интересно, что случится раньше — решение этой проблемы в Haskell или появление многопоточного рантайма в OCaml
Q>и отладчика и б) мемори ликами в самых неожиданных местах. Это страшный геморой, когда для того, чтобы вывести отладочную информацию, приходится либо применять дедуктивные методы, либо искать способ, как подвести монаду к нужному месту. Еще хуже мемори лики — то ли везде ставить !, то ли опять же заниматься мощной дедукцией, пытаясь догадаться нужен ли !
в этом месте или нет.
Debug.Trace.trace таки есть. Не то что бы фантастически удобно, но, пожалуй, это не такая высокая цена за существенно меньшую потребность в отладчике.
Мемори лики (термин, кстати, не слишком правильный) — в своем коде обычно ясно, где воткнуть !. Если ликует код чужой/библиотечный — тогда да, трабл.
А, так вот, о чем это я, в двух словах — грабля — не приговор.