Оп-хуй. В прошлом треде прикрепил Нэша, теперь Перельмана. От себя посоветую книгу Christopher Allen, Julie Moronuki Haskell Programming from first principles Она мне больше Real World Haskell понравилась
>>970711 Чё сразу секта? Тред не очень активен, но в нём пишут. Другое дело, что много постов типа : "Зачем этот ваш хаскелль нужен?", "В чём суть ФП?", "ООП говно", "ФП говно".
я единственный на всей доске кто забыл хашкель щас используем эфсярп на продакшоне, хещкель не трогал уже года 2, как универ закончил что там новенького? наследование мандадки от аппликатива уже завезли?
>>970872 изучая эти понятия ты одновременно изучаешь все реальные обьекты которые обладают свойствами заданными в определениях например если твоя мамка удовлетворяет свойствам функтора то к ней применимы все теоремы о функторах
Надеюсь Вы мне сможете помочь. Я написал прогу, которая считает функцию Неймана, в качестве аргумента она принимает комплексное число, суть вопроса: как передать в качестве аргумента, список чисел от 0.0+1i до 14.0 + 1i, как вы видите, мнимая часть всегда равна 1. Конструкция данного вида: mapM_ print([(bessY 0 z 100) | z <- [0.1,0.2..14.0]]) Здесь 0 - порядок, z - аргумент, она выводила значение ф-ии Неймана для аргументов от 0.1 до 14. Она работала, но в таком случае аргумент был вещественным числом, а надо, чтобы был комлпексным.
>>969781 Буду накатывать эту книгу в свободное время. Мне хуёвенько и все надоело, хочу прикоснуться к прекрасному. А нихуя остальные его учат, интересно?
>>973541 Хз, мне жаба не стала меньше нравится, уж если говорить о человеческом фп, где не нужно изворачиваться, то это скала, хочешь пиши на джаве с синтаксическим сахаром, хочешь упарывай монады и функторы, а хаскель - язык для каких-то фп фанатиков, не все вещи удобно и нужно делать в функциональном стиле так-то.
Поясните, во что разворачивается эта хуйня: fibs = 1 : scanl (+) 1 fibs
Не сам результат, а как происходит вычисление. Я всю голову сломал. То есть, 1 :, потом идет scanl, но он вызывает fibs, где снова идет 1:. Как это работает?
>>975409 А нет чего-то такого эдак однородного? Вот в лиспе мало всяких странных символов и все однородное, а что-то подобное но отвечающее нормам 21 века (монадки, функторы, зависимые типы) нельзя сделать?
>>976428 Так от бэкрграунда зависит. Кто ты, непонятно - школие или тырпрайз макака или вкатыватель какой. Кроме того, 10часовое задрачивание ни в чем пользу не принесёт, важно чередавать активную и фоновую работу мозга, максимально интенсивно загрузить его и отвлечься на другие задачи, чтобы он скрипел в фоновом режиме. У Пуанкаре об этом где-то здорово написано.
Делай что должен и будь что будет.
Кстати, можешь попробовать в repl выполнить :set prompt "" - помню из-за бажной реализации очистки экрана, меня бесило что ввод ломался. Может поможет и тебе. Загруженных модулей конечно не увидишь, если это важно.
>>976497 Лол. До твоего ответа думал, что у него саблайм пытается влезть в REPL и обработать её как .hs-файл. Оказывается это просто скопипащенный REPL.
Чем код редактируете? Писать без IDE в статически типизированом языке - себя не уважать, собирать своими руками парашу из emacs/vim не хочу. Для однострочников текстовый редактор пока подходит, но на будущее интересно. В https://wiki.haskell.org/IDEs одна параша - эклипс тормозное говно и не нужен, сублимы-атомы хуита. Что можете сказать про жидею с плагином и Leksah?
>>977793 Жидея - кал. Я под атомом и скажу, что не хуже жидеи будет, даже стилистические улучшения предлагает. Но есть один НЬЮАНС. Из-за эпичного проеба в ghc-mod память течёт эпично. Тому в соседней сонсоли у меня запущен watch -n 15 'pkill ghc-mod'
Я перестал испытывать какой-либо интерес к программированию, когда осознал всю независимость формы и результата. Я люблю области, где форма = результат. В программировании, форма = код. Ты можешь сколько угодно менять структуру своего кода и ксс, можешь хоть обфусцировать и минифицировать его тыщу раз, а результат в браузере от этого никак не изменится. Ценность формы здесь чисто менеджмент-уровня, майнтабельность все дела. Причём, к сожалению, я не могу сказать, что "красивое функциональное решение" выстраданное на хаскеле за неделю всегда майнтабельнее, чем делающий абсолютно то же самое, написанный на коленке за полчаса скрипт на ноде, в котором всё просто и банально... Да и сама майнтабельность это чисто прикладная ценность, нет в ней ничего фундаментального и вечного.
>>979014 >Причём, к сожалению, я не могу сказать, что "красивое функциональное решение" выстраданное на хаскеле за неделю всегда майнтабельнее, чем делающий абсолютно то же самое, написанный на коленке за полчаса скрипт на ноде, в котором всё просто и банально Кому ты пиздишь Ты никогда ничего не писал на хаскеле, съеби
Прошу вибачення за вопрос по софту, но: Atom или VSCode?
Я не особо в восторге от сих хипстерских редакторов и кроме как для Хаскеля Atom не использую; Atom мне нравится интеграцией с ghc-mod, показывает типы. Не нравится странным REPL. Файл в него загружать/перезагружать нужно явно, дополнение там идиотское.
>>978746 Так и до деанона недалеко. Смотри тематические сообщества. Еще есть годная "конфа", там можно задать вопросы и найти иногда работу. Одно время записывались радио выпуски о хаскелле, разговоры на всякие темы, интервью, обзор новостей и прочее, но сейчас перестали.
>>980087 Чтобы индуцировать у человека аутизм/шизофрению, а потом при помощи NLP сделать из него послушного вьябывальщика, полного энтузиазма, который будет пахать не просто фултайм, но ещё и после работы, перед работой, по дороге на работу, и на выходных. Сниматься в рекламе своих технологий и своей компании с искренней улыбкой полной счастья. Потому что люди без серьёзных психических отклонений и незагипнотизированные на успех в 21-то веке работать, вообще, мягко говоря, не любят, и в такую ноулайферскую парашу как программирование их затянуть нереально, хотя в быту они вполне могут писать скрипты, более сложные алгоритмически, чем все ваши ёбаные интерпрайзы.
>>980227 >>980228 >>980237 Нет, это всё рабочий код. В хаскеле монойд так не получится юзнуть, линзы так не работают, я много чё пробовал, даже тред создавал, максимум в биндинг вынести со строкой на вход типа f "track" <|> f "playlist", причём там тип надо будет указать. В жс мне не нужны эти проверки которые ты дописал, мне нужно исключение, если вдруг в пейлоаде чего-то не оказалось, потому что это исключительная ситуация, ожидаемое поведение - что там всегда будут эти поля.
>>977680 Не совсем так. Функциональщики - это в первую очередь фанатики, социоблядками-хипстерами они являются не так часто, большинство вообще не ходит на конференции. Какой-то профит в плане типобезопасности у них действительно есть и с десятилетиями нарастает, просто в практическом отношении он гораздо менее значимый, чем им кажется, а главное, увеличеная сложность программ зачастую с перевесом нивелирует эти профиты, когда дело доходит до реальной майнтабельности. Динамические петушки вроде лисперов - это такие же фанатики, только с другими ценностями, с реальностью их ценности пересекаются не лучше.
Ребят, а как можно запустить в терминале программу на хаскелле, чтобы она как скрипт работала? ну то есть выдала output и всё, прекратила работать. чтоб как на питуне лол
>>980619 нет чистоты? временем компиляции? скоростью работы? отсталостью средств разработки? синтаксисом наконец? с хаскелем хоть понятно что это борщехлебство, а скала с претензией. И блядь синтаксис уродский еще.
>>980813 хаскель тоже используют в проде. Скала конечно популярнее, но тоже маргинальная. > А идее нормальная поддержка В идее? Ну вроде норм, только тормозит, хотя это не с идеей связано. Но я вообще-то говорил про ебанутый сбт. > Вкусовщина Вспомнил, поблевал. > ни критично ясно
>>980494 Да, сработало, я видимо пытался только с (<|>). Но всё равно сложновато, для такой элементарной вещи. В хаскеле вечно приходится думать, напрягать мозги, учить новые инструменты, комбинаторы, для всех тех же задач, которые в обычных яп решаются встроенными конструкциями типа точечки, индексирования, var/let, for/while. Лучше один раз выучить хештаблички, массивы, переменные, ветвления и циклы, и потом уметь выразить на этом любую программу, чем на каждый частный случай придумывать новые комбинаторы и даже парадигмы типа линз и тд. Хаскель позволяет тебе оставаться вечным студентом, ты никогда не можешь его выучить, и за счёт этого он будет удерживать твой интерес, если ты не догадаешься немного абстрагироваться, и подумать, а зачем это всё нужно.
>>981012 >вечно приходится думать, напрягать мозги, учить новые инструменты, комбинаторы сложна-сложна-нипанятна
>для всех тех же задач, которые в обычных яп решаются встроенными конструкциями типа точечки это до тех пор пока ты делаешь какую-нибудь примитивную тупую хуйню. чуть усложню твой пример. попробуй сделать это на говноскрипте: t ^? key "collection" . nth 0 . ((key "track" . key "trackId") <> (key "playlist" . nth 0 . key "track" . key "trackId"")) . _Integer или t ^? key "collection" . nth 0 . (key "track" <> key "playlist") . (key "id" <> key "name") . _Integer
>переменные, ветвления и циклы, и потом уметь выразить на этом любую программу вырази простейшую комбинацию map и filter Haskell: map g . filter p . map f
Императивное говно: let result = []; foreach (x in xs) { if (p(x)) result.push(g(x)) }
ой, понадобился еще один фильтр и отображение: Haskell: map h . filter q . map g . filter p . map f
Императивное говно: let result = []; foreach (x in xs) { if (p(x)) { let y = g(x) if (q(y)) { result.push(h(y)) } } }
и так далее
>чем на каждый частный случай придумывать новые комбинаторы и даже парадигмы типа линз (.) и (<>) нихуя не новые комбинаторы, это просто композиция функций и операция полугруппы, им по двести лет.
>>981047 > t ^? key "collection" . nth 0 . ((key "track" . key "trackId") <> (key "playlist" . nth 0 . key "track" . key "trackId"")) . _Integer let firstItem = res.collection[0]; if (firstItem.track): return firstItem.track.trackId; else: return firstItem.playlist[0].trackId; Оформил в ширину чисто ради большего comedy value. А вообще, я не предлагаю отказываться от map и filter. Если какой-то комбинатор приводит к более компактному и понятному коду и нужен настолько часто, что ты не успеваешь о нём забыть, и тебе не надо его каждый раз гуглить, выгода в его использовании очевидна. Вот если взять fold/reduce, кроме случая когда они используются для расстановки уже задефайненого бинарного оператора между элементами коллекции, они практически всегда приводят к более сложному или даже громоздкому коду, чем цикл с переменными. А частные случаи свёрток кроме map и filter быстро забываются. > до тех пор пока ты делаешь какую-нибудь примитивную тупую хуйню. Любая сложная хуйня раскладывается на примитивную тупую хуйню.
бинарное дерево:data Tree a = Leaf | Node (Tree a) a (Tree
a) Напишите следующие функции:Iвычисление суммы элементов дерева treeSum :: Tree Integer -> IntegertreeSum = undefined
б) вычисление максимальной высоты дерева treeHeight :: Tree a -> InttreeHeight = undefined
Я его выполнил, но пришлось добавить поддержку Eq для сравнения, как можно было сделать это иначе, может я какой-то простой способ пропустил, прохожу недавно, последняя тема - алгебраические типы данных, вот мой код. Учу для себя. (не лаба)
>>981434 Если вместо сравнений (==), (/=) везде использовать паттерн-матчинг, то Eq не понадобится. Код при этом может стать более сложным и громоздким.
>>981566 Scala - вакансий много и не сказать бы что на ней часто пишут в функциональном стиле, хотя есть такие проекты. Elixir/Erlang - работа есть, начну с этого, хотя её куда меньше чем на Scala и требования тоже не хилые. Haskell - работы ещё меньше чем в верхних двух, надо быть реально фанатиков, что сдаться и долго искать работу.
>>981656 Учти, что работа - это в любом случае хуйня, не то что свои проектики в кайф кодить. С прикладной точки зрения, разницы на чём пишешь на работе, особо и нет, потому что ты будешь и так и сяк работать 8+ часов в день, даже если решаешь задачи быстрее за счёт крутого яп. Правильнее выбирать то, на чём много вакансий и заеботые зарплаты.
>>981659 Да я вообще вкатываюсь в js, это я на будущее думаю, куда перекатываться, не очень js и фронт нравится, но это довольно просто и времени на изучение этого много не нужно + куча вакансий. Для себя начал учить haskell и понял, что хочется в будущем работать на чем-то подобном.
Двачую >Haskell Programming from first principles , но с одним важным замечанием.
Эту книгу стоит пилить в ОП-пост вместе Learn you a Haskell. Она даёт хорошее энтри-лэвэл понимание как все работает в отличии от, где просто поверхностное описание, и после чего ты вроде и книгу прочёл, а как пользоваться не понял. Переоценивать, впрочем, и ее не стоит, но то, что первая глава посвящена лямбда калкулусу, символизирует.
Real World Haskell стоит оставить в качестве практического семинара после прочтения Аллена.
спрашиваю здесь, так как ФП треда нет Сравните плз. по хардкору F# и Scala, те, кто разбирается. Что более труЪ ФП? Делаю эпохальный для себя выбор: .NET vs JVM, но в функциональном духе. Короче, что брать?
>>981994 Он про то, что вакансий на чистых scala/F# нет, везде это идут, как доп языки. А по твоему вопросу ближе к haskell F# стоит, так как корни у языков одни - ML
>>982024 Ну ёпрст Ты говоришь о том, что и так всем очевидно. Чтобы избежать таких ответов я специально задал конкретный вопрос. По языкам-то что? Кто-нибудь знает?
>>982168 У меня есть полная, но нимагу, прости. Самому подогнал человек, купивший её, под обещание больше никому не давать даже мамке. Более того, у меня есть подозрение, что дистрибьютор впиливает туде цифровые метки, которые могут указать на него, когда она с двачей перекатится во все торрент трекеры. А таки перекатится, потому что кроме устаревшей копии в сети ничего нет.
>>982206 Да ничего, братунь. Я уже и авторам написал, попросил скидку для российских нищебродов, но если ничего не ответят в течение 2-3 дней, то куплю видимо за полную цену.
>>982282 Я перекатился главы где-то с седьмой, и по диагонали сравнил пройденный материал (по диагонали, потому что попробуй-ка нормально сравнить овер 200 страниц).
Подредактировано стилистически, кое-где определаний добавили, в одной главе ответы добавили, новые подглавы, подредактировано чисто визуально. Не перечитывая, и не читая параллельно довольно сложно оценить отличия.
Но они есть - если сравнивать только по утекшему в сеть материалу - овер 100 страниц. Пикрилейтед.
Алсо, в новой тоже заметно, что пара глав еще до конца редактуру не прошли, и еще будут меняться.
>>983816 Integral - это тайпкласс, а не тип. Нет такого типа. Есть Int и Integer. В сигнатуре то, что перед "=>" называется class constraint. В нем ты указываешь тайпклассы, к которым может принадлежать типы инпута/аутпута. А дальше, после "=>" следуют типы данных которые принимает и возвращает функция (а вообще все функции в хаскелле принимают только один аргумент). т.к. ты указал, что тип а принадлежит интеграл, то принимает эта функция число. я сам ток учу, так что могу ошибаться. поправьте если что
>>983853 всё правильно проще говоря, тип, принимаемый ф-ей lucky, может быть любым типом, реализующим класс Integral (Int, Integer, ещё вроде какие-то специфичные есть)
>>983816 Вот этот >>983853 правильно сказал, но стоит добавить почему именно нотация выглядит именно так, почему тайпкласс нельзя вписать Integral -> String
Потому, что тайпклассов в констрейнте может быть много, например (Bounded a, Ord a) => a -> a -> Bool
Я, конечно, капитанствую, но для совсем ньюфагом лучше лишний раз явно сказать.
>>984135 Будь ласка. Ты пока упарывай доступную версию, ты и без главы посвящённой сугубо IO закончишь материал монадическим титаном на самом деле ніт, но знаний будет достаточно, чтобы начать что-то пилить.
Monoid. Прочитал, попробовал, пописал инстансы. Всё понятно. Functor. Прочитал, попробовал, пописал инстансы. Всё понятно. Applicative. Прочитал, попробовал, пописал инстансы. Всё понятно. Monad. Прочитал, попробовал, пописал инстансы. Всё понятно. Foldable. Прочитал, попробовал, пописал инстансы. Всё понятно. Traversable. Кровь, кишки, распидорасило, Залго. Как вообще в это въехать?
>>987739 Я спутал с функцией sequenceA, traverse просто мапит функцию из какого-то значения в контейнер и упаковывает в другой контейнер при этом тип значения может быть функцией изменен
Внешнюю сторону я чисто интуитивно разглядел, с трюками типа traverse id [[1], [2]] = [[1,2]] traverse id [[1, 2]] = [[1],[2]] Еще увидел как что-то типа цепочки IO вычислений перепаковать в одну IO цепочки, выглядит удобно. Но вот только интуитивно разглядел, а понять не могу совсем.
Все предыдущие тайпкласы я, вроде бы, понял. По крайней мере нет ни проблем с написанием инстансов, ни проблем с пониманием законов каждого из тайпкласов.
А с Traversable пиздец. Чувствую себя довеном. С написанием нетривиальных инстансов тоже проблемы.
А ещё прочитал, что Traversable вкатили относительно недавно, раньше не было. Но потом кто-то решил принести больше абстракции богу абстракции, что не всем в интернетах понравилось.
Нашёл вот туториал, о котором говорят, что простой, попробую покурить.
>>987751 >цепочки IO вычислений перепаковать в одну IO цепочки Плохо выразился, довен же. Скорее имел в виду не перепаковку, а альтернативу функтору, применив который можно получить структуру IO-результатов, а альтернатива даёт структуру результатов внутри IO а внутре неонка.
>>987759 Ну, то есть, перепаковать вывернуть наизнанку тоже можно, протраверсив применив id, но такой способ не выглядит нужным, если можешь сразу траверсить.
>>987752 Вначале главы, посвящённой Traversable автор предлагает вместе с ним определить инстанс для списка.
Тут-то я и подумал, что неплохо бы в последний раз попытаться написать самостоятельно, тем более на самом интуитивно понятном-то типе. Пусть типы и тайпчекер меня выведут.
Выбросил Prelude, минут 10 подумал и поколдовал внутри where импортируя по пути нужные функции и ... тадам, результат пикрилейтед.
>>987937 Раз я уже начал по литературе, так и продолжу.
Слабо представляю, как перекатиться на степик, бросив то, что начал штоле? А курс Москвина сначала, или с момента, куда я по литературе дошёл? https://www.youtube.com/watch?v=S9Nkfi_NLXI
Думаю, закончу то, что есть, а там посмотрим, мне ведь ничто не мешает ещё и курс Москвина поверх накатить. Тем более, те вещи, в которых разобрался с трудом, но сам, они лучше усваиваются. Хотя с курсом непонятно. Там же, наверное, видео-лекции, а не бумажные. Как вообще на ютюбе учиться? Я только по книжкам умею.
Не является функцией инстанса необходимой для определения. Я её в общем видел, но над вопросами реализации не задумывался.
А вот при изучении тайпкласса нужно же понять как он работает, чтобы уметь без проблем запилить его инстанс. Со всеми предыдущими тайплассами проблем не было вообще, а вот тут я завис, слишком дофига намешано. Но уже разобрался сам, и этим самим понял как там всё устроено.
Хотя, конечно, упростил я со списком. Foldable констрейнт в моей имплементации не нужен. Я так понимаю, можна запилить дженерик-реализацию через фолдинг. Когда-нибудь я попробую и это говно. Наверное, завтра. Чувствую жопой что, если получится, это будет вообще эзотерический readonly код.
>>987945 >дженерик-реализацию через фолдинг. Когда-нибудь я попробую и это говно.
Какой же я всё-таки дурак. Ко-ко-ко, дженерик реализацию стыдно-то как Сел пилить, и тут же понял, что мне чего-то, билять, не хватает. Моноида как минимум. Попробую придумать generic версию с дополнительными констрейнтами, но хуй у меня что выйдет.
>>988052>>988053 Так и знал, что можно запилить, добавив констрейнты Моноидальности и Аппликативности самого предполагаемого дженерик инстанса. Невозбранно впилил использование дженерик функции в инстансе списка аппликатив и моноид же
Теперь, кажется, понял как работает Traversable. Вроде бы.
>>988079 А теперь проверь на соответствие monad laws. Подозреваю, где-то ты их нарушил, ибо traversable должен сохранять структуру при traverse, а monoid подразумевает свертку структуры в единичный итем.
>>988558 По крайней мере соблюдается для тех моноидов, что я тестировал. Думаю, можно и разъебать. Но это не то чтобы серъезная функция, просто типоёбство, чтобы развить интуитивное понимание, в также я закрепил понимание Traversable.
>>988721 Ну императивщину полностью не вычеркнуть, даже в Haskell, если речь идёт по последовательных вычислениях, юзают do-нотацию, потому что так читать проще. А вот ООП действительно засирает мозги, и люди потом не могут понять как структурировать программы другими способами, пусть даже более выразительными.
>>988730 Ну с таким же успехом let-нотацию и where- можно императивными назвать. Но спорить не стоит, в том, что это слегка напоминает императивный код, я согласен.
>>992646 Извини за тупость и дерзость, но не мог бы ты помочь мне написать лямбда-нотации к следующим вещам или хотя бы на примере одной на пальцах объяснить принцип перевода в \-нотацию:
isPeriodic :: Library -> Bool
isPeriodic (Newspaper _ _ _ _) = True
getByMonths :: [Library] -> [Int] -> Int -> [Library]
findEq (x:xs) y = if x/=y then x:findEq xs y else x:xs
>>992766 вернее a определяется как абстракция: a = λ x₁ ... xₙ . b [x₁, ..., xₙ] (но только в случае, когда x₁ ... xₙ - переменные и других клозов нет)
>>996495 Ну, или если хочется совсем красиво, то в итоге получится вот такой легкочитаемый, легкорасширяемый и легкодополняемый ad-hoc-полиморфный код c экзистенциальными типами:
{-# LANGUAGE ExistentialQuantification #-}
class FirstNameable' a where getFirstName :: a -> FirstName
type FirstName = String type Age = Double newtype Person = Person {getPersonFirstName :: FirstName} data Seld' = Seld' {getSeld'FirstName :: FirstName, getSeld'Age :: Age} data FirstNameable = forall a . FirstNameable' a => FirstNameable a
firstName (FirstNameable x) = getFirstName x
instance FirstNameable' Person where getFirstName = getPersonFirstName
instance FirstNameable' Seld' where getFirstName = getSeld'FirstName
gospodin = Person "Huirandomniy" gospozha = Seld' "Pelotka" 40
main = mapM_ (print . firstName) [FirstNameable gospodin, FirstNameable gospozha]
какое отношение у хаскелистов к idris? думаю вкатиться со скалы в хаскель или идрис я правильно понимаю что идрис = хаскель + зав типы? можно ли сразу начинать с идриса?
>>997051 В общих чертах ознакомился с языком, посмотрел пару примеров на гитхабе, сделал кой чего сам и все. Работаю и продолжаю изучать. Взяли как раз из-за того что мало спецов на рынке. >>997054 На житье-бытье хватает.
>>981987 Нормальное ФП только в Хаскелле (из живых языков). Но если выбирать из F# и Скалы, я бы выбрал Скалу. F# сильно косит под ФП, поскольку спиздил синтаксис из Окамла, но по сути проект проприетарный с полудохлым комьюнити. Я не знаю на F# каких-нибудь продуктов уровня Спарка или Кафки, я вообще не знаю, нахуй F# нужен. Ну разве что какую-нибудь хуитку писать, убедив начальника, что C# - это не тру, а F# - тру, хотя разница между ними весьма небольшая (не такая, как между Скалой и Джавой, поэтому не представляю какие аргументы ты сможешь привести).
Скала, конечно, сделана с большим упором на ООП, но там более серьезная система типов, чем в F#, а вообще нормальная система типов - это одна из главных фич, ради которой ФП существует в принципе. На ней пилятся серьезные проекты, в которые вкладывается дофига бабла, на ней проще найти хорошую работу. Там в комьюнити полно настоящих ФП-шников, которые пришли туда из Хаскеля, с корорыми есть о чем поговорить и у которых есть чему поучиться.
Изучаешь х-ль/п-т @ не понимаешь очередную йобу и чувствуешь себя тупым @ достигаешь просветления и чувствуешь себя продуктивным @ натыкаешься на очередную непонятную йобу.
Похоже, этот цикл никогда не закончится. На этот раз я застопорился на cmap. forall a b. (b -> a) -> f a -> f b Как это добро использовать? Откуда я знаю, какой функцией получить a из b?
data Item = Item { value :: Int, weight :: Int } deriving (Eq, Show) data Problem = Knapsack Int [Item] deriving (Eq, Show) data Solution = KnapsackSolution Int [Item] deriving (Eq, Show)
и решение задачи о рюкзаке с набором без ограничений в виде
dpKnapsackUB :: Problem -> Int dpKnapsackUB (Knapsack capacity items) = trace (show table) (table ! capacity) where table = array (0, capacity) [(w, opt w) | w <- [0..capacity]] opt 0 = 0 opt w = maximum $ 0:[value i + table ! (w - weight i) | i <- items, weight i <= w]
Не то чтобы это было нормальное решение, но когда решил ещё возвращать список элементов попавших в рюкзак, становится трудно остановиться. Единственное, что вызывало у меня опасение - это монады и Trace / State / whatever. Я знал, что рано или поздно мы перейдем и на эту дрянь.
Анон, подскажи, у меня есть шанс отрефакторить функцию в dpKnapsackUB' :: Problem -> Solution?
Этот тип хранит функцию, которая позволяет преобразовывать потоки значений. Определите функцию применения:
ap :: St a b -> [a] ->
Она принимает ленту входящих значений и возвращает ленту выходов.
Что тут надо сделать? Вроде речь про потоки, которые мы сами до этого делали, но тут ap принимает и выдает просто списки. Ну да ладно, они могут быть бесконечными. Я вроде сделал ap и функцию изменеия списков для теста, которая берет поток и прибавляет 1 к каждому значения в новом потоке.
ap::St a b -> [a] -> ap (St f) (x:xs) = fst (f x) : ap (St f) xs
myf::Int -> (Int, St Int Int) myf a = (a + 1, St myf)
Но нахуя эту функцию оборачивать в St a b. Я тут поразмышлял и понял, что она выдает в результате кортеж, с самой собой. Ок, без St функия не может иметь в результате саму себя, наверное. Но об этом тут никакой речи нет. И приходиться из кортежа вытаскивать первое значение, а возврат самой себя нафиг не нужен. Я чего-то не понимаю точно.
>>1007487 Ты почти постиг дзен. Теперь осталось ответить на один простой вопрос - зачем? Зачем все это? Как это приближает тебя к решению конкретной задачи?
>>1007543 Упражнение в книжке. Приближает к возможности практического применения инструмента. >>1007547 Никак. Просто пришел на двачи поныть о том что сложна.
>Единственное, что вызывало у меня опасение - это монады
А зря. Кто умеет в монады, тот длинные list comprehensions в одну строку не пишет.
>Анон, подскажи, у меня есть шанс отрефакторить функцию в >dpKnapsackUB' :: Problem -> Solution?
Внезапно да. Например вот так:
--import Control.Monad (guard)
data Item = Item { value :: Int, weight :: Int } deriving (Eq, Ord, Show) data Problem = Knapsack Int [Item] deriving (Eq, Show) data Solution = KnapsackSolution Int [Item] deriving (Eq, Ord, Show)
dpKnapsackUB' :: Problem -> Solution dpKnapsackUB' (Knapsack capacity items) = table ! capacity where table = array (0, capacity) [(w, opt w) | w <- [0..capacity]] empty = KnapsackSolution 0 [] opt 0 = empty opt w = maximum . (empty :) $ do --i <- items --guard $ weight i <= w i <- filter ((<= w) . weight) items let KnapsackSolution optVal optItems = table ! (w - weight i) return $ KnapsackSolution (value i + optVal) (i : optItems)
Выведенный Ord на типах позволяет не писать maximumBy с разбором кортежей или похожую хуйню. Про guard можешь прочитать в доках к Control.Monad. Я сначала написал с ним, но потом подумал, что лучше не добавлять лишних модулей просто так.
>Но нахуя эту функцию оборачивать в St a b Чтоб задать тип, в котором он же сам и используется, очевидно же.
>а возврат самой себя нафиг не нужен Тащемта нужен. Тебе там предлагают написать integral :: Num a => St a a, который выдаёт "ленту" частичных сумм. А для этого надо помнить предыдущую частичную сумму, ведь к ней надо будет прибавлять текущий элемент. Так вот, для этого функция внутри St должна уметь изменять не только свой аргумент, но и саму себя. Именно новую версию самой себя, которую надо будет применить к следующему элементу, она и возвращает вторым элементом кортежа, который ты выкидываешь.
Функцию f :: St a b, которой не нужно себя изменять (применяемую поэлементно, подобно map g :: [a] -> для списков) при этом можно будет получить как f = lift f' для некоторой f' :: a -> b. Попробуй написать lift :: (a -> b) -> St a b, который это делает — с ним можно будет "поднимать" обычные функции до функций над потоками, легко написать const :: a -> St b a и проверить тот же ap :: St a b -> [a] -> на конкретных примерах.
>>1008188 Вот спасибо, кажется начинаю понимать. Но жаль что сам не мог допереть до понимния. Или все таки слишком недостаточное описание в упражнениях.
>>1008702 В принципе у меня примерно так же получилось, только конструкции не такие локаничные, я нуб. За исключением id в инстансе для Category St. Я не врубаюсь в него никак и не могу понять почему он реализуется так в данном случае (я сделал что-то другое и оно не работает как надо). Кажется, что все просто, он просто берет что-то и возвращается то же самое. В данном случае это экземпляр для St и он должен принимать St, хотя он не принимает никаких аргументов, а является константой, это я тоже не очень четко понимаю.
В твоих тестах следующее ap (integral . id) [0,1,2] Как оно работает? Ведь в ap эта композиция принимает элементы листа? То есть сначала берется 0 и к нему применяется id, который должен брать/быть что-то типа St, то есть функцию.
>>1008830 Я так начинаю понимать, что id сам является функцией типа St, которая работает как обычный id для элементов листа. А если применить id к чему-то с типом St, то что будет. Или оно так не должно применяться..
>>1008830 >и он должен принимать St Сам по себе он ничего не принимает (элементы в него суёт ap), он является как бы "обёрткой", для которой ты можешь определять классы типов. Когда нужна функция - "распаковываешь" (сопоставлением по образцу) и работаешь с ней. Для таких случаев ещё newtype есть и record syntax, чтобы "распаковывать" можно было и специальной функцией, и образцами. Например:
newtype St a b = St { getSt :: a -> (b, St a b) }
getSt "распаковывает", St "запаковывает". В стандартной библиотеке есть несколько примеров вроде ZipList из Control.Applicative. Это "обёртка" над списком, которая позволяет задать ещё одну реализацию класса Applicative, не конфликтуя с реализацией Applicative из Prelude.
>Как оно работает? Если ты про (.), то там та же идея, что и для функций, только с учётом второго элемента (новой St, которую надо применять к следующему элементу). Текущий пропускается сначала через (распакованную) g, потом через (распакованную) f, а в качестве новой St для результата композиции будет взята (наша) композиция новой St для f (обозначенной через f1) и новой St для g (обозначенной через g1).
>>1008837 >А если применить id к чему-то с типом St, то что будет. Или оно так не должно применяться.. То же самое и будет, к чему применил. id задан в классе типов, т.е. реализация его выбирается в зависимости от требуемого типа. Ты его применяешь => тебе нужна функция => выбирается реализация для функций. Если не импортировать Control.Category, то будет id из Prelude, который всегда является функцией.
Я не понимаю с точки зрения теории категорий. С ней знаком поверхностно. С этой точки зрения St образует категорию, в которой объектами являются еще и сами морфизмы, но возможно ли такое - не знаю.
Мое глупое понимание сводится к "коробочкам". St - это конверт с инструкцией, в которой указано что надо сделать с исходным объектом, чтобы получить новый объект и новую инструкцию для работы со следующим объектом. Т.к. St является конвертом, значит напрямую он не может ничего делать. Поэтому нужен внешний исполнитель, коим и является ap, умеющий читать инструкции.
id с этой точки зрения работает так. В инструкции написано: верни сам объект, в следующий раз используй эту же инструкцию. Исполнитель ap это и делает.
>Как оно работает? Ведь в ap эта композиция принимает элементы листа?
В тех же терминах, композиция инструкций - это просто новая инструкция для исполнителя, которая объясняет как пользоваться двумя инструкциями одновременно. Композиция инструкций тоже ничего принимать не может.
>>1008943 Так же получилось, как в закомментированной строчке.
>>1009970 Главное препятствие - runtime system, реализующая семантику аппликативных вычислений на тьюринг-архитектуре. Самый разумный способ - взять C/C++ вместо хаскеля.
>>987751 Тоже нихуя не понятно. > :t traverse traverse :: (Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b) > :t id id :: a -> a И внезапно >:t traverse id traverse id :: (Traversable t, Applicative f) => t (f b) -> f (t b)
Как id можно запихать в traverse, оно же по типу не подходит?
Спросим, нафиг тебе функция, принимающая Traversable и ни на что не влияющий аргумент и заменяющая каждый элемент на const "shit". Или это пример, когда у тебя в итоге получается (Traversable t, Applicative f) => t (f a), на котором сработает traverse id?
Недавно имел незащищенный контакт с вебдевелопоментом в редукасе-реакте. Теперь хочу функционироваться. Стоит ли изучать Кашель? Кто использует в продакшене? Что есть в Кашеле чего нет в Йобаскрипте2015-2017?
>>1017066 Монада - это моноид в категории эндофункторов. Системы эффектов - вычислители, производящие неявную работу, связанную с изменением окружения.
>>1018516 Если говорить сугубо языке программирования, то никакое знание математики кроме разве школьного для хаскеля не нужно. Математику (не мат анализ наверное имеется ввиду?) в принципе неплохо понимать чтобы писать хорошие алгоритмы, с другой стороны если голова на месте, то можно интуитивно понять что алгоритм не оптимален, иногда он очевидно не оптимален. Но тут на мой взгляд достаточно просто в теорию алгоритмов окунуться.
Есть один вопрос по Idris, думаю ничего если задам его здесь. Когда я пытаюсь выполнить sum [1..1000] отедается гиг памяти в все зависает. На сколько это ожидаемое поведение? 1.0 под windows.
У меня есть стейт для галлерии. Индекс текущей пикчи и общее кол-во. Нужно написать две функции, которые будут это дело инкрементить. Что-то умнее > if x + 1 > total then shit else fuck можно придумать?
>>1024407 Все вычисления в функторах сводятся к тому, что надо что-то постоянно упаковывать-перепаковывать. Applicative делает это за тебя, liftAx избавляет от синтаксического шума, а программизд сосредотачивается только на самих вычислениях.
сравни: justPlus x y = pure (+) <> x <> y или justPlus' = liftA2 (+)
Заметь, что первые две полиморфны, и можно их юзать вообще для всех Applicative: вдруг задача потребует реализовать ту же функциональность на другом контейнере, или захочется его сменить.
>>1024778 Я все понимаю на уровне тупорылых примеров типа Just 2 + Just 3 Мне не понятно практическое применение этого. Почему я должен захотеть использовать это вместо do нотации с монадами, например.
>>1024911 PageView $ fromMaybe NotFound $ router url $ (do end pure Home) `mplus` (do lit "users" s <- param "sortBy" end pure $ Users s) `mplus` (do lit "users" end pure $ Users "name") `mplus` (do lit "users" i <- int end pure $ User i)
Скажем я прекрасно владею рекурсией, понимаю когда можно использовать фолды и даже всякие foldM. Более менее понятно когда нужны монады.
Но вот интуиции на счет do нотации мне не хватает. Я понимаю что если развернуть do нотацию то получится цепочка лямбд связанных через >>=, что позволяет использовать в последующих вычислениях все что было в предыдущих. Но я немножко не догоняю кто же все таки запускает вычисления.
>>1025401 >Но я немножко не догоняю кто же все таки запускает вычисления. Если говорить про IO, то вычисления "запускает" рантайм GHC. В остальных случаях по разному. Если например монада - список, то на выходе и получается список, а дальше делай с ним что хочешь. Разберись для начала с монадами, потом с трансформерами, а дальше Free на ура пойдет
>>1025407 Да я вроде все понимаю на уровне теории. Понимаю как пользоваться библиотекой, которая построена на монадах. А когда дело доходит до практики, то не возникает желания "А въебу ка я тут монаду".
Трансформеры тоже не очень не понимаю. Я же могу смешивать в одной цепочки do скажем Maybe и log. Но log идет как бы сбоку в виде сайд эффекта. Получается трансформеры нужны чтобы сделать Maybe + Reader например?
>>1025417 >не возникает желания "А въебу ка я тут монаду" Да тут просто надо смотреть на задачу. Есть цепочка однотипных вычислений - юзай анфолд-фолд. Есть у этих вычислений побочные эффекты, порядок которых важен - юзай аппликативный функтор. Важен и порядок вычислений, и эффектов - заверни в монаду.
>Я же могу смешивать в одной цепочки do скажем Maybe и log Можешь смешивать любые монады и без монадных трансформеров. Но при этом тебе придется вручную комбинировать-разбирать их, а bind сделает это за тебя.
Ньюфаг ИТТ. ЧЯДНТ? data Single_Multiple a = Multiple Int a | Single a deriving (Eq, Show) mod_length_enc :: (Eq a) => [a] -> [Single_Multiple a] mod_length_enc xs = [ \(x,y) -> if x==1 then Single y else Multiple x y | (x ,y) <- Lists1.length_enc xs] Lists1.length_enc возвращает список пар (1, "a")(2, "b") и т.д. Ошибка: • Couldn't match expected type ‘Single_Multiple a’ with actual type ‘(Int, a0) -> Single_Multiple a0’ • The lambda expression ‘\ (x, y) -> ...’ has one argument, but its type ‘Single_Multiple a’ has none
Притом, если сделать так: mod_length_enc xs = [ f | (x,y) <- Lists1.length_enc xs, let f = if x==1 then Single y else Multiple x y] то все работает. Почему?
Покажите, кто-нибудь, как в хаскеле выглядят замыкания. Все вокруг твердят, что замыкания относятся к ФП, но я их никогда не встречал в хаскеле. Из ФП знаю только хаскель
>>1036815 Да так же как и везде. Замыкания просто напросто дают доступ к лексической (читай визуально видимой) обласит видимости. http://paste.org.ru/?fxi7za Лямбда которая возвращается из функции tag умеет пользоваться переменными open и close из своего замыкания.
>>1036829 Никогда бы не подумал, что where или let -конструкции кто-то называет замыканиями. Смысл замыканий, насколько я это понимаю, совсем не в этом.
>>1036867 В том что тебе не нужно пихать аргументы во вложенные вспомогательные функции. Или как в примере создавать частично готовые функции. > Замыкание (англ. closure) в программировании — функция первого класса, в теле которой присутствуют ссылки на переменные, объявленные вне тела этой функции в окружающем коде и не являющиеся её параметрами. Говоря другим языком, замыкание — функция, которая ссылается на свободные переменные в своём контексте.
>>1036906 Но в хаскеле переменные не объявляются (а значит, не могут быть вне функции), и ни на что не ссылаются. Все переменные - это и есть только лишь параметры функций. Замыкание призвано решить проблему фунарга - захвата переменных в языках, где переменная ссылается на ячейку памяти (время существования которой может не соответствовать времени вызова функции/процедуры) и аргументы передаются через стек. То есть, замыкания имеют смысл в императивном программировании. Я не понимаю, какой смысл замыкания могут иметь в ФП объясните, плз То, что у тебя - это просто вложенные определения функций.
>>1041503 Это purescript, который похож на хаскель как две капли воды, только конпелится в жс дристню. То что тебе кажется "императивным" на самом деле просто синтаксический сахар над bind и это нормальная практика.
>>1018800 >Если говорить сугубо языке программирования, то никакое знание математики кроме разве школьного для хаскеля не нужно А как же лямбда-исчисление и теория типов?
>>1042252 >>1042260 >>1042455 Все так, но я пытался самостоятельно проделать все шаги бета-редукции, и запутался в том, что куда подстанавливать. Попытался применить индексы де Брауна, стало только хуже. А суть-то я понял, Y работает по тому же принципу, что и Ω, который совсем простой.
Господа джиниусы, я не кодер, для хобби решил попробовать поизучать хаскелл, для разнообразия жизни.
Какого чёрта на Eclipse не устанавливается он? Вернее, были ли у вас проблемы с установкой на эклипс этого плагина?
просто пишет
The selected wizard could not be started. Plug-in net.sf.eclipsefp.haskell.ui was unable to load class net.sf.eclipsefp.haskell.ui.wizards.NewHaskellProjectWizard. An error occurred while automatically activating bundle net.sf.eclipsefp.haskell.ui (247).
Я понимаю, что это уже начинается отсеивание глупцов, вроде меня. Но я всё делал по инструкции. Были ли у вас такие проблемы?
Еще вопрос: когда пишется код алгоритма практически без использования дополнительной памяти(O(1) по памяти) то на хаскелле все равно используется стек для каждой итерации алгоритма и из-за этого алгоритм выполняется на константу медленнее, хотя ассимптотическая оценка времени выполнения та же, так?
А если не хвостовая рекурсия, а к примеру набор данных меняется: есть массив чисел, мы итерируем по нему, считаем сумму элементов и прибавляем промежуточное значение суммы к текущему элементу.
Хаскелл выделит новую память для результата вычислений или воспользуется старой?
Вообще есть случаи когда хаскелл использует больше ресурсов и времени чем императивный язык? Или его свободно можно применять в примеру для системного программирования?
>>1046506 Хули пиздишь, чорт, там всё то же самое. То что там какой-то опущенец прокукарекал возле параши "Hask - это не настоящая категория куд-кудах!", ничего не меняет.
мне как новичку посоветовали учить хаскел или жс. Что лучше и через сколько на хаскеле можно начать взламывать акки вк? и как его учить я по английски не понимаю есть на русском??!
Ну и кто тут хаскеллом больше дня кодит? Давайте, объясните, всемогущие пидоры, какого хера у вас досих пор ничего удобнее npm нет? Там всё просто - локальные и глобальные области, очевидные ключи и установка. И только у вас СУЧАРРРРР какая-то хуйня из кабала и стака, которые одновременно юзать надо ПИДОРРРЫ Хули ничего удобюного нет??? А
>>1050628 Справедливости ради, отмечу что поехавший отчасти прав. Кабал кривое говно, нихуя не собирается. Стек вообще какая-то странная ебала. Поставить можно, удалить нельзя.
Хасканы, объясните мне. Вот чистый функции, ко-ко-ко. Но ведь как только нужно сделать что-то реальное, сразу всплывают Reader+Writer+State+runExcept. Спрашивается, нахуя так выебываться и выпиливать мутабельность, если один хуй мы получаем мутабельность, но хитровыебанную, которую неудобно писать?
У меня есть функция > вжух :: Команда -> Состояние -> Either Пиздец Состояние Теперь я хочу протестить цепочку этих изменений. > main :: IO () > main = putStrLn $ either id show $ вжух Ебанись начальноеСостояние Как мне сделать цепочку изменений, Either в IO впихнуть или шо?
Почему этот тред такой активный? Неужели есть работа на Хаскелле? Или наоборот все отбросы, непринятые рыночком, собрались в этом треде? В противовес ML-тред заглох, т.к. все перекатились в слак. А сюда постят и постят. тред не читал
>>1053744 Ну смотри, люди растут, а значит со времен есть ненулевой шанс, что кто-то решит сделать проект в прод на функциональщине. Например я думаю над тем, чтобы новый проект (по работе) делать на purescript.
>>1036970 Бамп вопросу. ФП-шники, ну расскажите как вы программируете с замыканиями на хаскеле, кто в теме. В упор не понимаю, откуда это пошло, что, мол, замыкания - это из ФП?
>>1054028 Ты тупой, поэтому не можешь понять ответа. >>1054030 Для тупых вариант на жс: > const f = x => y => x(y) Как видишь функция, которая возвращается из f(x) замкнута на x.
>>1054032 Я не знаю JavaScript. Из ФП знаю только хаскель. >замкнута Что ты под этим понимаешь? Параметризацию терма свободной переменной (т.е. абстракцию)? Ну а замыкания то здесь причём?
>>1054044 Мудила, открой уже википедию сраную > Замыкание (англ. closure) в программировании — функция первого класса, в теле которой присутствуют ссылки на переменные, объявленные вне тела этой функции в окружающем коде и не являющиеся её параметрами. Говоря другим языком, замыкание — функция, которая ссылается на свободные переменные в своём контексте.
>>1054044 Ну я же уже писал вот здесь >>1036970 Я видел как это бывает, и сам так программировал с замыканиями на C# и C++. Но как это должно работать в ФП не понимаю.
>>1054033 Это определение (в сущности, тоже самое, что и это >>1054045) годятся в процедурном программировании, но какой смысл всё это может иметь в ФП? в который раз повторяю свой вопрос
>>1054094 f возвращает лямбду (в определении которой есть свободная переменная x) в контексте (лексическом окружении), в котором x связана с конкретным значением.
Два раза вычислив f (в определениях d и e), создались две одинаковые лямбды но с разными контекстами.
>>1054113 >Определи "ФП". Зачем заново определять ФП? Возьмём обыкновенное определение, как аппликативную модель вычислений, данную в виде λ-исчисления или комбинаторной логики.
>>1054120 В терминах \-исчисления замыкание возникает где-то между аппликацией и непосредственным проведением бета-редукции: app (\x . \y -> x y) id closure (\y -> x y) [x := id] beta (\y -> id y)
>>1054108 Как это свободная переменная связана с определённым значением? Так она свободная или нет? >Два раза вычислив f (в определениях d и e), создались две одинаковые лямбды но с разными контекстами. Да ничего там не вычисляется, мы на основе одной абстракции (λ x y. xy) определили две (λ y. const y) и (λ y. id y), у каждой из которых имеется по одной свободной переменной. Замыкание здесь где? Где здесь преодоление захвата переменной (т.е фунарг)?
>>1054152 Свободная она в чистом лямбда выражении (\y-> x y), абстракция f x создает некоторый контекст в котором x свяжется после аппликации.
>Да ничего там не вычисляется, e = f id - аппликация, и в результате не создается абстракция, а либо бета-редуцируется до терма (\y -> id y), либо остается closure (\y -> x y) [x := id]. Можно рассматривать и так, и эдак и все будет правдой. Что там реально создается - зависит от конкретного вычислителя.
>Где здесь преодоление захвата переменной (т.е фунарг)? В абстрагировании (\y-> x y) в функции f x.
>>1054145 Что значит "между"? Аппликация - это не этап вычислений, это любой терм вида (T₁ T₂) где T₁, T₂ ∈ Λ. β-редукция - примерно то что у тебя обозначено как closure, а то, что ты называешь beta - аппликация (тоже терм).
Забавно что хаскелепидоры готовы до посинения обсуждать теоркат, но когда надо реально что-то сделать, они съебывают в туман. Моё недавнее приключение в стране xmonad доказывает это чуть более чем полностью. Окружению уже 10 лет, а оно до сих пор кривое, глючное и с десткими болезнями.
>>1054167 beta-редукция примерно так записывается, когда выражение записано в общем виде (T [x : = something]). У меня чуть другой смысл - у лямбда выражения есть контекст, в котором определены некоторые переменные. Т.е. грубо говоря, абстракция создает контекст с не связанным x. После аппликации, в самом начале бета-редукции мы в этом контексте связали x со значением. Вот в этот момент вся эта конструкция и называется замыканием. А дальше мы можем сразу провести редукцию если переменная иммутабельна, или таскать эту конструкцию по остальной части программы в любом случае.
>>1054164 Что такое "чистое лямбда выражение"? >Свободная она в чистом лямбда выражении (\y-> x y), абстракция f x создает некоторый контекст в котором x свяжется после аппликации. В хаскеле все термы замкнуты (т.к. нет множества свободных переменных, как это полагается в λ-исчислении). >не создается абстракция, а либо бета-редуцируется до терма (\y -> id y)... Так терм (λ y. id y) и есть абстракция. >остается closure (\y -> x y) [x := id] Это я не понял. Что это значит в λ-исчислении?
>>1054178 >у лямбда выражения есть контекст Какой такой контекст? >определены некоторые переменные Но в хаскеле переменные не определяются. Определяются только (замкнутые) термы. >если переменная иммутабельна Как это "иммутабельна"? Переменная она переменная и есть (параметризует терм-абстракцию и всё). Для начала бы понять, возможен ли в ФП захват переменной, если переменная - это не ячейка памяти, ничего не хранит, на неё ничто не может ссылаться, и у неё не времени существования (как в процедурных языках).
>>1054202 Ну при чём здесь это? Спецификация устанавливает конкретный синтаксис языка. Переменные в синтаксисе хаскеля, конечно, имеются, именно для того, чтобы определять абстракции (т.е. они связанные). Но в программе самостоятельную переменную объявить нельзя (да это и не имеет смысла).
>>1054184 >Что такое "чистое лямбда выражение"? "Очищенное" от обстракции f x
>Так терм (λ y. id y) и есть абстракция. Да, я имел ввиду, что это не программист абстрагировал, а вычислил компилятор, или рантайм.
>Это я не понял. Что это значит в λ-исчислении? Я так обозначил контекст для лямбды.
>>1054185 >Какой такой контекст? В котором есть (или будет в момент вычисления этого выражения) определение x.
>Но в хаскеле переменные не определяются. Определяются только (замкнутые) термы. f x = \y -> x y Но ведь тут x не определен. Он становится определен только после вызова f something
>Как это "иммутабельна"? Переменная она переменная и есть (параметризует терм-абстракцию и всё). Это означает, что ее только один раз в конкретном контексте можно связать со значением.
>>1054248 >"Очищенное" от обстракции f x Как это "Очищенное"? >В котором есть (или будет в момент вычисления этого выражения) определение x. Не понимаю. Приведи пример такого контекста. Как это x может быть "определён"? >f x = \y -> x y >Но ведь тут x не определен. Он становится определен только после вызова f something Что значит не определён? f x = \y -> x y эквивалентно f = λ x y. xy Просто взяли и определили (написали) такую абстракцию. А потом взяли и определили аппликацию: d = f const , которая равна (β-редуцируема) абстракции: d ⇌ λ y. const y >Это означает, что ее только один раз в конкретном контексте можно связать со значением. Что значит "связать со значением"? Подстановка терма вместо связанной переменной происходит по правилу сокращения редекса (λ x. A)B → A[x := B]. Почему один раз?
>>1054283 >Как это "Очищенное"? Взял терм f x = \y -> x y , ластиком стер f x = и получил \y -> x y
>Не понимаю. Приведи пример такого контекста. Как это x может быть "определён"?
g = let x = id in \y -> x y
>f x = \y -> x y эквивалентно f = λ x y. xy Эквивалентно \x . \y . x y Здесь абстракция \x - это лексическое окружение для \y . x y, т.к. x во второй лямбде свободная (до тех пор, пока не абстрагировали, конечно же)
>Что значит "связать со значением"? Подстановка терма Я уже говорил, что промежуток между аппликацией и бета-редукцией можно рассматривать как связывание переменной x в контексте \x со значением, после чего выполняется подстановка и редукция.
>>1054368 >Взял терм f x = \y -> x y , ластиком стер f x = и получил \y -> x y Это не терм, а равенство, определяющее f. Зачем стирать "f x ="? И что же мы хотим получить? Абстракцию, которая теперь не связана с f, содержащую свободную переменную (которых нет в хаскеле)? Зачем? >g = let x = id in \y -> x y Здесь x не является переменной (ни свободной, ни связанной). Это именованный терм в ограниченной области видимости. >Эквивалентно \x . \y . x y Ну да. Так обозначается (λ x y. xy) ≡ (λ x. (λ y. xy)). >Здесь абстракция \x - это лексическое окружение для \y . x y, т.к. x во второй лямбде свободная (до тех пор, пока не абстрагировали, конечно же) Так и есть в λ-исчислении, но в хаскеле все термы замкнуты. Значит терм (λ y. xy) определить нельзя. >промежуток между аппликацией и бета-редукцией Какой промежуток? Аппликация - это терм, β-редукция - шаг вычисления. Это разнородные понятия. Какой между ними может быть промежуток? >связывание переменной x Что такое связывание переменной в ФП?
>>1054570 >Что такое "именованный терм"? Обычный именованный терм, как f = (λ x y. xy). >Что такое "область видимости"? Область видимости терма x в >g = let x = id in \y -> x y ограничена определением терма g, т.е. "x = id" только слева от "g =".
>>1054639 Можно было бы принять такое определение замыканий в ФП, но тут я вижу два препятствия: 1. В хаскеле нет свободных переменных (которые там упоминаются). 2. Такое определение по смыслу не связано с замыканиями в процедурно-императивном программировании (т.к. в ФП переменные не могут захватываться).
>>1054682 Кроме синтаксиса в языке есть семантика вычислений. Ещё раз, в хаскеле нельзя определить терм вида (\x -> x y). Такой терм не может быть редуцирован к типизируемому (в хаскеле) значению.
>>1054652 1. Свободная переменная - это та, которая встречается в теле функции, но не является её параметром. В выражении (f x =\y -> x y): x свободная, т.к. в функции \y -> x y не является параметром. 2. Семантика языка другая, но вся разница сводится к мутабельности лексического окружения замыкания.
>>1054686 >Кроме синтаксиса в языке есть семантика вычислений. Ну вот и формализуй мне семантику именованного терма и области видимости.
> Ещё раз, в хаскеле нельзя определить терм вида (\x -> x y). Внутри области видимости, где определён y, можно. При этом в подвыражении (\x -> x y), y считается свободной переменной.
>>1054688 >Нет, но ведь отсюда ясно, что это такое, и можно в соответствии с этим и формализовать. Ну раз тебе ясно — вперёд, формализуй.
>>1054692 Что ж такое-то, по второму кругу чтоли? Определение (f x =\y -> x y) эквивалентно абстракции (f = λ x y. xy), в которой обе переменные связанные (знаком λ). >мутабельности лексического окружения замыкания Вот это я не понял. Поясни.
>>1054694 >При этом в подвыражении (\x -> x y), y считается свободной переменной. Верно. >формализуй Не стану я этим сейчас заниматься. Спрашивай, что конкретно непонятно.
>>1054706 >Что ты хочешь услышать? Что следует из того, что эта переменная свободная? Как это поможет понять замыкания в ФП? >Что тебе кажется. Почему, мне кажется? Разве понятие области видимости чем-то плохо?
>>1054694 >При этом в подвыражении (\x -> x y), y считается свободной переменной. Да подтермы в хаскеле могут быть незамкнуты, но когда я говорю, что в хаскеле нет свободных переменных, я имею в виду, что все именованные термы замкнуты (т.е. все переменные в их определениях связанные), и редуцироваться они будут только к замкнутым термам или атомам (вроде конструкторов данных).
>>1054694 Если угодно, можно незамкнутые подтермы называть замыканиями, но зачем, зачем на них обращать особое внимание, и как это связано с проблемой фунарга (есть ли она в ФП)?
>>1054732 Непонятно, что такое "мутабельность лексического окружения замыкания". Что есть лексическое окружения замыкания? В каком смысле оно мутабельно? Почему?
>>1054731 >незамкнутые подтермы называть замыканиями А что, в каком-то языке в функциях (которые входят в замыкание, конечно же) нет свободных переменных?
>>1054744 Из ФП знаю только хаскель. В императивнах языках, которые я знаю (C#, C++, assebler), понятие "переменная" имеет другой смысл, и такие характеристики как "свободная" и "связанная" к ним не применимы.
>>1054754 Нет с чего бы это. Переменная может быть свободной или связанной в конкретном λ-терме. Здесь переменные параметризуют терм, указывая места подстановок термов (при β-редукциях). В императивных языках переменные - ячейки памяти, на которые можно ссылаться (в т.ч. из сторонних процедур), у которых есть времена существования, возможно типизированные, и т.д.
>>1054770 Где это в сисярпе ты видел ячейки памяти? Семантически там переменные никакого отношения к памяти не имеют (Если не трогать unsafe, а если трогать, то заодно потрогай unsafe в Haskell)
>>1054781 Это аналогия для С++ байтоёбов, у которых прямая работа с памятью впиталась с молоком Кернигана и Ричи. В семантике сисярпа нет прямой работы с памятью, только с переменными, кроме unsafe.
Для них же есть и в хаскеле аналогия - f - это ссылка на область памяти, содержащую функцию.
>>1054795 Так где тогда хранятся значения (если не в ячейках памяти), почему они доступны для изменения? Что это за "переменные" такие, и чем их семантика (именно семантика, а не имплементация) отличается от того, что я пишу? Да какая разница? Может, уже перейдём к замыканиям в ФП?
>>1054804 >Что это за "переменные" такие, и чем их семантика (именно семантика, а не имплементация) отличается от того, что я пишу? Тем, что ты определил переменную как ячейку в памяти. Но в сисярпе семантика такова, что переменная - это объект (не в смысле ООП), с которым можно совершать различные действия, но где он находится (в ОЗУ, ПЗУ, в регистре, на берестяной грамоте) программисту похуй.
>>1054816 >Я, всё же хотел бы понять про замыкания. Нихуя не поймешь, пока не осознаешь, что переменная в общем случае императивных языков это не ячейка памяти.
>>1054818 >объект Ну так а семантика этого "объекта" какова? Чем он отличается от именованной ячейки памяти? Семантика C# - императивная - обобщённая машина Тьюринга с ограниченной лентой памяти.
>>1054827 >Ну так а семантика этого "объекта" какова? Чем он отличается от именованной ячейки памяти? Тем, что это не именованная ячейка памяти, а объект похуй какой природы.
>Семантика C# - императивная - обобщённая машина Тьюринга с ограниченной лентой памяти. Вот тут вот не пизди. МТ - вычислитель, а не семантика.
>>1054822 Да мне несколько поднадоело. Я никогда не испытывал необходимости в замыканиях в хаскеле. Я даже не могу понять какой смысл могут иметь "те самые" замыкания в ФП. Но почему-то часто натыкаюсь на многозначительные замечания, дескать, "замыкания - это из ФП". И всё никак не могу понять, почему. Хоть кто-нибудь в самом деле это понимает? Ну объясните же уже, в конце концов!
>>1054841 >Моделью А семантика тут при чем? Неужели ты на сисярпе прямо МТ программируешь?
>Так что за "объект" то? Некий абстрактный объект, не привязанный к конкретной реализации.
>>1054842 Бесполезно. Судя по тому, что тебе непонятно как в замыкании связано лексическое окружение и анонимная функция, как анонимная функция может менять свое лексическое окружение, ты не понимаешь термина "замыкание" даже на уровне императивщины, всю императивщину скатываешь в байтоеблю, хотя это не так.
>>1054848 >А семантика тут при чем? Так семантика переменной в C# - именованная ячейка памяти, как и в любом императивном языке, моделью которых является МТ (с лентой памяти). >Некий абстрактный объект, не привязанный к конкретной реализации. Так а семантика его какова? Как с ним обращаться? Чем это отличается от именованной ячейки памяти? >ты не понимаешь термина "замыкание" Ну так укажи на изъян в моём понимании. Я не претендую на окончательную истинность. Я в самом деле хочу понять?
>>1054845 Да много раз отвечали. Вот, вроде, сошлись на том, что это незамкнутые подтермы. Дальше у меня были эти вопросы >>1054731 И на этом всё - неопределённость.
>>1054855 >Так семантика переменной в C# - именованная ячейка памяти >как и в любом императивном языке, моделью которых является МТ (с лентой памяти). Это не так. Переменная может быть представлена каким угодно объектом. Императивный подход не оговаривает этого. МТ - это конкретный исполнитель. В семантике языка, которым программируют МТ вообще может не быть переменных.
>Так а семантика его какова? Как с ним обращаться? Чем это отличается от именованной ячейки памяти? Тем, что это некий абстрактный объект, не привязанный к конкретной реализации.
>Ну так укажи на изъян в моём понимании. На один указал, но ты пока упорствуешь и не хочешь абстрагироваться от ячеек.
>>1054859 >Императивный подход не оговаривает этого. Тогда что такое императивный подход? >Тем, что это некий абстрактный объект, не привязанный к конкретной реализации. Так я же про семантику спрашиваю, а не про реализацию. Ещё раз. Семантика его какова? Как с ним обращаться? Чем он отличается от именованной ячейки памяти? Ты хот покажи, как ты это хочешь привязать к замыканиям.
>>1054867 >Тогда что такое императивный подход? Машина Тьюринга, ты же сам сказал. В кратце: запись программы в виде последовательности действий. И где тут переменные?
>Как с ним обращаться? В каждом языке по своему. Например, это может быть такой набор из операций: объявление, присваивание, копирование, передача в процедуры и функции.
>Ты хот покажи, как ты это хочешь привязать к замыканиям. Для начала надо вернуться к определению замыкания. Давай ты его и напишешь и с каждым словом в определении мы разберемся.
>>1054859 >>1054874 >В семантике языка, которым программируют МТ вообще может не быть переменных. Но мы то рассматриваем те, в которых переменные есть, и они являются именованными ячейками памяти. Иначе как возможен фунарг? >запись программы в виде последовательности действий. Каких действий? С ячейками памяти (области на ленте МТ). Там ведь больше нет ничего. >присваивание, копирование, передача в процедуры и функции. А какова семантика этих действий? >Для начала надо вернуться к определению замыкания. Давай ты его и напишешь и с каждым словом в определении мы разберемся. Уже обсуждалось много раз >>1054107 >>1036970 >>1054050
>>1054899 >Но мы то рассматриваем те, в которых переменные есть, и они являются именованными ячейками памяти Т.е. переменные - это надстройка над МТ? А значит эта надстройка может быть добавлена как угодно, а не только ячейками памяти на ленте.
>Каких действий? С ячейками памяти (области на ленте МТ). Там ведь больше нет ничего. Раз есть надстройка над МТ в виде переменных, значит может быть что-то еще и нам это не важно, это забота конкретной машины, которая нам предоставила такой удобный инструмент под названием "переменная".
>А какова семантика этих действий? Точно такая же, как и написано: присваивание, передача итд. Конкретный исполнитель и механизм программисту не важен, он есть, а что там внутри - похуй.
>Уже обсуждалось много раз
>Замыкание - это лямбда с некоторым лексическим окружением. Это простенькое берем для разбора?
>>1054910 >эта надстройка может быть добавлена как угодно Вот в этом я не уверен. Мы всё же должны придерживаться случая, когда (императивная) переменная - это именованная ячейка памяти. >Раз есть надстройка над МТ в виде переменных, значит может быть что-то еще и нам это не важно, это забота конкретной машины, которая нам предоставила такой удобный инструмент под названием "переменная". Да не надо нам рассматривать реализацию. >механизм программисту не важен Как же не важен. При программировании нужно ориентироваться на операционную семантику (этих действий) (на реализацию - необязательно), то есть на то, что это даёт на модели (т.е. МТ). >>Замыкание - это лямбда с некоторым лексическим окружением. >Это простенькое берем для разбора? Да. Это определение годится для императивного случая (за исключением того, что вместо лямбды я бы сказал "функция высшего порядка", т.к. лямбда - это всё же лишь греческая буква).
>>1054919 >Мы всё же должны придерживаться случая, А зачем? Мы уже отошли от МТ, предложенной её автором, введя понятие "переменная". Мы можем создавать какие угодно расширения.
>Как же не важен. Не важен. Есть переменная, у нее есть значение, есть способ присвоить это значение, который предоставляет язык. Если тебе очень важно, чтобы при присвоении значение обязательно попадало в ячейку памяти, то надо подождать, когда тебе станет это не важно и продолжать разговор, иначе не разберешься.
>Да. Точно так же оно годится и для ФП. Там тоже есть ФВП и лексические окружения.
>>1054926 >А зачем? Чтобы был возможен захват переменной. >Точно так же оно годится и для ФП Так вот это и не понятно. Зачем оно если нет фунарга? Что такое ФВП? Что такое лексическое окружение в ФП? Лексическое окружение чего?
>>1054936 >Что такое захват переменной? Ситуация, когда тело процедуры/функции ссылается на внешнюю переменную, которая может не существовать в момент вызова этой процедуры. >Прикладного программиста это вообще волновать не должно. Конечно. В ответ на эту проблему авторы имплементации языка предоставляют прикладному программисту возможность использовать замыкания. >Лексическое окружение ФВП Так что же это такое? >>1054926 >Там тоже есть ФВП Какие там ФВП? Там термы. Именованные термы называют функциями.
>>1054941 >ссылается на внешнюю переменную, которая может не существовать в момент вызова этой процедуры. Как это ее может не существовать? Такая программа не скомпилится в этом случае.
>Конечно. В ответ на эту проблему авторы имплементации языка предоставляют прикладному программисту возможность использовать замыкания. Одно из возможных решений.
>Так что же это такое? Набор свободных переменных, например. (f x z -> \y x z y) Здесь (\y x y) - ФВП, а [x,z] - лексическое окружение.
>Какие там ФВП? Там термы. Термы в лямбда исчислении, а в ФП ФВП.
>>1054948 Намудрил с синтаксисом: >Набор свободных переменных, например. (f x z = \y -> x z y) >Здесь (\y -> x y) - ФВП, а [x,z] - лексическое окружение.
>>1054948 >Как это ее может не существовать? Например, если вызывающая процедура завершилась раньше, чем вызываемая. >Такая программа не скомпиллируется в этом случае. Почему? Компилятор проверяет области видимости а не времена жизни переменных. Время жизни переменной ситуативно и не известно на этапе компилляции. Так зачем же по-твоему нам вообще нужны замыкания в императивном подходе? >[x,z] - лексическое окружение. То есть лексическое окружение - это множество свободных переменных подтерма? >Термы в лямбда исчислении, а в ФП ФВП. λ-исчисление - вычислительная модель ФП. В хаскеле мы имеем дело с самыми настоящими термами. Не понимаю, что тут можно называть ФВП? Что ты имеешь в виду, когда говоришь о ФВП в ФП?
>>1054966 >Например, если вызывающая процедура завершилась раньше, чем вызываемая. МТ - модель вычислений в императивщине. Откуда в машине Тьюринга процедуры и переменные? Там только лента, алфавит ну и еще по мелочи. Команды исполняются строго последовательно и такого просто не может быть.
>Почему? Компилятор проверяет области видимости а не времена жизни переменных Переменные существуют только на этапе написания высокоуровневых программ. После компиляции никаких переменных нет, есть команды исполнителю и лента.
>То есть лексическое окружение - это множество свободных переменных подтерма? Да.
>В хаскеле мы имеем дело С функциями. Это же функциональный язык.
>>1055003 >Откуда в машине Тьюринга процедуры и переменные? Они там не нужны. Но в конкретном императивном языке они определяются в терминах машины Тьюринга. >такого просто не может быть. Чего не может быть? И почему? >Переменные существуют только на этапе написания высокоуровневых программ Переменные - понятие внутриязыковое. В рамках операционной семантики языка переменные существуют во время вычисления. >С функциями. Это же функциональный язык. Аргумент бьющий наповал. Ещё раз, в ФП (т.е в аппликативной модели) мы имеем дело с термами (иначе это не ФП), именованные термы называют функциями. Зачем тут какое-то лишнее понятие ФВП? Его имеет смысл использовать в императивных языках, где некоторые функции (процедуры) могут быть высшего порядка, а другие - нет. >Да. Ну так какая связь (по смыслу) между императивными замыканиями и незамкнутыми подтермами в ФП?
>>1055019 >Ещё раз, в ФП (т.е в аппликативной модели) мы имеем дело с термами С функциями, которые в конкретном функциональном языке определяются в терминах лямбда-исчисления.
>Переменные - понятие внутриязыковое. Так же как и переменные с функциями в ФП.
>могут быть высшего порядка, а другие - нет (\x -> x + 1) (\x -> const x) Первая не ФВП, вторая ФВП.
>>1055019 >Ну так какая связь (по смыслу) между императивными замыканиями и незамкнутыми подтермами в ФП?
Лексическое окружение в ИП = множество ссылок на внешние переменные в анонимной функции Лексическое окружение в ФП = множество свободных переменных в анонимной функции + сама анонимная функция = замыкание.
>>1055040 >Ну какие там ещё функции, кроме термов. В хаскеле это в точности λ-термы, определение которых оснащено сопоставлением с образцом. Вычисление - это редуцирование термов до нормальной формы или до значений (содержащих атомы). Семантика хаскеля именно такова. Если этой семантики в языке нет, значит это не ФП. >Так же как и переменные с функциями в ФП. Ну как так? Переменная - вполне законный λ-терм. В хаскеле имеются переменные, так как они необходимы для определения абстракций. >(\x -> x + 1) >(\x -> const x) >Первая не ФВП, вторая ФВП. (λ x. ((+) x 1)), (λ x. const x) - оба терма - абстракции. Мы до замыканий когда-нибудь доберёмся? Изложи уже своё понимание достаточно развёрнуто. Сколько можно вопросами перебрасываться?
>>1055047 Эта связь не по смысл, а внешняя (хотя бы потому, что переменные в ИП и ФП имеют фундаментально разную природу). Замыкания в ИП решают проблему захвата переменных (которая немыслима в ФП). Какую проблему решают "такие замыкания" в ФП (т.е. множество свободных переменных незамкнутого подтерма + сам незамкнутый подтерм) и как? Повторю этот вопрос: >>1054731
>>1055053 >оба терма - абстракции В лямбда-исчислении. В хаскеле это функции.
>Замыкания в ИП решают проблему захвата переменных Тебе уже писали, что это просто удобная абстракция в Хаскеле, как функторы и прочая поебень. Повторяюсь, это прикладного программиста не должно волновать, что там где захватывается, это проблема разработчика компилятора, и то, что удобная абстракция используется как костыль в императивном языке, не означает, что она была для этого придумана.
>>1055180 >В лямбда-исчислении. В хаскеле это функции. Что ты этим пытаешься сказать? Какие в хаскеле функции, чем они отличаются от термов, как они вычисляются? >удобная абстракция в Хаскеле Удобная для чего? Почему абстракция? Что здесь абстрагируется? Функторы в ФП и замыкания в ИП я (как прикладной программист) использую осмысленно. Скажите, как я осмысленно могу использовать замыкания в ФП, для чего это может пригодиться? Почему тогда, часто твердят, что замыкания в ИТ пришли из ФП, если в ФП это бесполезная неважная "абстракция" и по своей аппликативной специфике она не применима для решения проблемы захвата переменной в ИП?
>>1055289 >А для чего она была придумана? В математике много чего придумано хуй знает для чего, но оказалось, что удобно мыслить замыканиями, к тому же нашлось применение для проблемы фунарга. А в некоторых функциональных языках (Лиспы, например), где лексическое окружение мутабельно, применяется для инкапсуляции.
>>1055380 >Это не имеет отношение к замыканиям. Я тоже так думаю. >>Что здесь абстрагируется? >Один код от другого. Как так? Абстракция - мысленный прём отвлечения от незначительных деталий в рассмотрении. Абстрагируется рассматривающий. Как может абстрагироваться код? >Но прикладные программисты используют замыкания в ИТ для этого. Для чего же могут использовать замыкания прикладные программисты в ФП? В сущности, это есть мой главный вопрос >В математике много чего придумано Где в математике встречается понятие замыкания? >оказалось, что удобно мыслить замыканиями Удобно для чего?
>>1055406 >Как так? Абстракция - мысленный прём отвлечения от незначительных деталий в рассмотрении. Абстрагируется рассматривающий. Как может абстрагироваться код? Поизучай на досуге что такое абстрагированиее в программировании. >Для чего же могут использовать замыкания прикладные программисты в ФП? >>1055383
>Где в математике встречается понятие замыкания? В информатике, которая является разделом математики.
>>1055423 >Поизучай на досуге что такое абстрагированиее в программировании. Можешь на что-нибудь сослаться? Что почитать то? >В информатике, которая является разделом математики. Ну для чего именно? Может тоже посоветуешь что-нибудь читнуть? >Для мозга. Что ты ёрничаешь. При чём здесь мозг? Я спрашиваю, в каких ситуациях удобно мыслить замыканиями и как?
>>1055380 Я несколько промахнулся >Да нет такой проблемы у прикладного программиста. Для чего же могут использовать замыкания прикладные программисты в ФП? В сущности, это есть мой главный вопрос
>>1055434 >Можешь на что-нибудь сослаться? Что почитать то? SICP
>Я спрашиваю, в каких ситуациях удобно мыслить замыканиями и как? Смотришь на выражение, видишь что это замыкание и понимаешь, как с этим работать дальше.
>Для чего же могут использовать замыкания прикладные программисты в ФП? В сущности, это есть мой главный вопрос Сюда смотри >>1055383
>>1055447 >Смотришь на выражение, видишь что это замыкание и понимаешь, как с этим работать дальше. Не понятно. Приведи пример какой-нибудь, если не трудно. >Сюда смотри Ну так я и спрашиваю, что это за замыкания в математике, и прошу сослаться на что-нибудь.
>>1055447 Читал я SICP. Там слово абстракция используется в том значении, в котором я написал. Так же абстракцией там называют само такое рассмотрение/построение. Абстракций кода от кода там нет. Как вообще понимать такое словосочетание?
>>1055447 Так что в итоге то? Нужны замыкания при программировании на хаскеле или нет? Если, например, я - императивный программист, пишу с замыканиями, решил разобраться поглубже. Везде пишут: "замыкания - в ФП". Я берусь за хаскель, а в хаскеле замыкания не используются. Есть какие-то но не те, не соответствующие по смыслу императивным. Так выходит?
>>1055458 >Там слово абстракция используется в том значении, в котором я написал Не до конца понял, значит. Абстрагирование - это сокрытие деталей реализации конкретной функциональности не только от программиста, но и от сторонней функциональности.
>Так что в итоге то? Нужны замыкания при программировании на хаскеле или нет? Охуенность хаскеля в том, что одни и те же выражения можно рассматривать как с точки зрения лямбда-исчисления, комбинаторной логики итд, такое-то поле для фантазий. Хочешь - думай, что у тебя замыкания, хочешь - бета-редукции.
>Есть какие-то но не те, не соответствующие по смыслу императивным. Так выходит? Нет, они идентичные по смыслу, если абстрагироваться от деталей реализации функций и переменных.
>Везде пишут: "замыкания - в ФП" Использование замыканий - признак функционального стиля (ведь использование ФВП, это же признак этого стиля) написания программы, или конкретного участка программы и не более того.
>>1055511 >Абстрагирование - это сокрытие деталей реализации конкретной функциональности не только от программиста, но и от сторонней функциональности. Спасибо. Никогда не встречал такого употребления. Я полагал, это надо называть модульностью или что-то вроде того. >Нет, они идентичные по смыслу, если абстрагироваться от деталей реализации функций и переменных. Как же идентичны по смыслу, если различаются семантически? Реализацию я и не рассматривал. >ведь использование ФВП, это же признак этого стиля Почему это? Признак ФП - аппликативная модель вычислений. А ФВП есть во многих императивных языках, и семантика их вычисления вполне императивная.
>>1055541 >Как же идентичны по смыслу, если различаются семантически? Реализацию я и не рассматривал. Смысл-то общий один: есть некоторые данные, которые связаны с некоторой функциональностью в единый объект, который для остальной части программы представляется как функция. Семантика отдельных частей этого объекта не важна.
>Признак ФП - аппликативная модель вычислений. Признак ФП - это использование функций в математическом смысле.
>>1055571 >Смысл-то общий один: есть некоторые данные, которые связаны с некоторой функциональностью в единый объект, который для остальной части программы представляется как функция. Ну да. Это верно для ИП. В ФП нет никаких (хранимых) данных, "которые связаны с некоторой функциональностью в единый объект". >Семантика отдельных частей этого объекта не важна. Почему? >Признак ФП - это использование функций в математическом смысле. Это что вообще значит? Вот тут же уже было определение ФП: >>1054120 Математический смысл отдельных частей программы устанавливает аксиоматическая семантика, и это в общем-то не зависит от подхода ИП/ФП.
>>1055686 >А в функциональных языках есть. С чего вдруг? Ты имеешь в виду какие-то "императивные IO-переменные"? Это, конечно, расширяет операционную семантику ФП (например хаскеля), но какое отношение это имеет к ФП-замыканиям (множество свободных переменных незамкнутого подтерма + сам незамкнутый подтерм)? >Потому что мы от них абстрагировались От каких частей "этого объекта" мы абстрагировалсь? О чём здесь речь вообще? >Но у ФП другое определение, именно в терминах математических функций Какое другое? Вот это? >Признак ФП - это использование функций в математическом смысле. Так а что это всё значит? Как его понимать, применять? Я не понял, оно отличается от этого >>1054120 или нет? >Функция задана декларативно, без намека на порядок вычислений. Точный порядок вычислений в аппликативной модели может быть задан по-разному.
Помогите. https://pastebin.com/8KPFs9BW Вот этот код должен вычислять числа Фиббоначи за линейное время (считая что арифметические вычисления выполняются за константу). Но он так не делает. Видимо, дело в том, что у меня три раза вызывается функция от n - 1 и это не оптимизируется. Как сделать, чтобы оптимизировалось? Как-то сделать локальную переменную и сохранить в неё?
>>1055708 >С чего вдруг? Свободные переменные -- это те самые данные, а терм - функциональность. Ну что тут непонятного?
>От каких частей "этого объекта" мы абстрагировалсь? О чём здесь речь вообще? Нам не важно что представляют собой данные (императивные переменные в ИП, или свободные переменные в ФП), а что - функциональность (алгоритм в ИП, или абстракции в ФП) . Данные + функциональность + выглядит_как_функция = замыкание.
>Так а что это всё значит? Как его понимать, применять? Это значит, что писать программу надо как набор математических выражений в синтаксисе конкретного языка программирования. Применять - пишешь в соответствии с этим пониманием программу: f = 1 + 2 -- это не "чтобы получить f, возьми 1 и прибавь 2", а "f равен сумме 1 и 2". В первом случае описан алгоритм - императивная семантика, во втором констатация факта - декларативная семантика.
>Я не понял, оно отличается от этого >>1054120 или нет? >Точный порядок вычислений в аппликативной модели может быть задан по-разному. Программиста на ФЯП (функциональный язык программирования) не волнует ни порядок вычислений, ни то, как он осуществляется: аппликативно, императивно (в случае, если компилятор транслирует код в императивный язык), или еще как. Т.е. аппликативность - не признак ФП. Признак ФП - декларативность.
>>1056320 >Свободные переменные -- это те самые данные У терма нет данных. Здесь это слово не применимо. Слово данные имеет два значения: исходные данные задачи (мы здесь не об этом), либо хранимая информация (имеет смысл лишь в ИП). Свободные переменные терма - переменные не связанные знаком λ в абстракции. >Нам не важно что представляют собой данные... Как это не важно, если различие - по смыслу (т.е. в операционной семантике). Понять, что такое ИП-замыкания, и как ими пользоваться, можно лишь в рамках императивной модели вычислений. >Это значит, что писать программу надо как набор математических выражений... Всё это касается аксиоматической семантики, которая в общем случае не чувствительна к вычислительной модели. Я, вообще, сомневаюсь, что понятие замыкания может иметь какое-нибудь место в аксиоматической семантике. Кроме того, невозможно определять алгоритм (т.е. программировать) вне какой-нибудь вычислительной модели. >Программиста на ФЯП ... не волнует ... то, как он (порядок вычислений) осуществляется: аппликативно, императивно. Как же не волнует? Операционная семантика, возможно, самое важное на что постоянно мысленно опирается программист при программировании. Во всяком случае, это принципиально важно для понимания замыканий (как минимум в ИП), как я уже писал. >в случае, если компилятор транслирует код в императивный язык Я не рассматриваю реализацию. Вроде же договорились. >Т.е. аппликативность - не признак ФП. Признак ФП - декларативность. Нет. Аппликативность - именно признак ФП. Декларативность - скорее признак декларативных определений и целых языков (которые могут не относиться к программированию).
>>1056372 >У терма нет данных Любой терм может быть данными (как же ты читал SICP, а значит и немного знаком с лиспом, если не знаешь такой простой вещи?).
>Как это не важно, А вот так. Замыкание и там, и там - это одно и тоже замыкание, достаточно абстрагироваться от модели вычислений, выше я давал такое определение замыкания, оторванное от.
>Всё это касается аксиоматической семантики, И декларативной тоже.
>Кроме того, невозможно определять алгоритм (т.е. программировать) вне какой-нибудь вычислительной модели. В том, то и дело, что в декларативных языках, коими являются ФП языки, нет никаких алгоритмов и даже не определена модель вычислений.
>Нет. Аппликативность - именно признак ФП. Зачем ты себе это придумал?
>>1056403 >Любой терм может быть данными Поясни свою мысль. В каком смысле терм может быть данными? >немного знаком с лиспом Не особо я с ним знаком. >Замыкание и там, и там - это одно и тоже замыкание, достаточно абстрагироваться от модели вычислений Чисто формальная аналогия более-менее понятна, но, когда я использую замыкания в ИП, я всегда имею в виду их императивную семантику (это существенно), а не только синтаксис. >И декларативной тоже. Что есть декларативная семантика? >В том, то и дело, что в декларативных языках, коими являются ФП языки, нет никаких алгоритмов и даже не определена модель вычислений. Ну это уж совсем ересь. У меня просто нет слов. Невозможно программировать вне вычислительной модели. Никак. Декларативные языки, такие как языки разметки или языки запросов к БД, не фиксируют вычислительную модель. Но языки программирования обязательно её имеют, потому что на этих языках кодируются алгоритмы. Понятия алгоритма нет вне вычислительной модели. >Зачем ты себе это придумал? Не придумывал. Так и есть. Каждый раз, когда я программирую на хаскеле, только его семантика и позволяет мне программировать (т.е. определять именно алгоритм, а не спецификацию или что-то ещё).
>>1056407 >Поясни свою мысль. В каком смысле терм может быть данными? Например это может быть нумерал Чёрча.
>Не особо я с ним знаком. Значит ты не читал SICP.
>(это существенно) А почему это существенно-то?
>а не только синтаксис. Не о синтаксисе речь вообще.
>Что есть декларативная семантика? Код рассматривается как декларация, а не как действие.
>Невозможно программировать вне вычислительной модели. Никак. Почему нельзя? Поясни.
>Декларативные языки, такие как языки разметки или языки запросов к БД, не фиксируют вычислительную модель Функциональные и логические тоже.
>Но языки программирования обязательно её имеют Не обязательно. Сам привел в пример языки программирования. В том числе, язык программирования не обязан быть тьюринг-полным, если ты об этом.
>Каждый раз, когда я программирую на хаскеле Но ты же не пишешь алгоритм, ты пишешь декларации функций.
>Например это может быть нумерал Чёрча. А что такое? Термы как термы. В каком смысле они - данные? >Значит ты не читал SICP. Читал то, что было нужно/интересно. С лиспом не разбирался. >А почему это существенно-то? Ну, чтобы их осознанно применять, нужно понимать смысл проблемы, которую они помогают решить. А это можно сделать, лишь имея в виду императивную семантику. >Не о синтаксисе речь вообще. Но сходство чисто формальное, я бы даже сказал, графическое. А семантики совсем разные. >Код рассматривается как декларация, а не как действие. Значит, вычислительная модель не предусмотрена, и мы имеем дело с каким-то декларативным языком, который не является языком программирования (как, например, языки разметки или запросов к БД или что-то ещё). >Почему нельзя? Поясни. Уже писал ведь. Повторю. Языки программирования обязательно имеют вычислительную модель и операционную семантику (придающую смысл синтаксически правильным выражениям в вычислительной модели), потому что на этих языках кодируются алгоритмы. Понятия алгоритма нет вне вычислительной модели. >Функциональные и логические тоже. Но это не так. Тогда на них нельзя было бы программировать реально вычисляемые программы. Хаскель совершенно точно имеет аппликативную семантику. >В том числе, язык программирования не обязан быть тьюринг-полным, если ты об этом. Я не совсем об этом. Я говорю, что язык программиорвания должен иметь семантику, которая точно указывает, как будут вычисляться выражения. >Но ты же не пишешь алгоритм, ты пишешь декларации функций. Я определяю именно алгоритм.
>>1056632 >А что такое? Термы как термы. В каком смысле они - данные? В том смысле, что они семантически - натуральные числа.
>Ну, чтобы их осознанно применять, нужно понимать смысл проблемы, которую они помогают решить. Я уже писал какую проблему решают замыкания в ФП, обобщу: это инструмент для инкапсуляции.
>Языки программирования обязательно имеют вычислительную модель >Я говорю, что язык программиорвания должен иметь семантику, которая точно указывает, как будут вычисляться выражения. Какую вычислительную модель использует HTML, формально, это язык программирования?
>Я определяю именно алгоритм. Когда ты пишешь на хаскеле f = 1 , ты не определяешь алгоритм, ты декларируешь, что ты буковкой обозначил число, а вот в императивщине определен именно алгоритм: положить в ячейку памяти число.
>>1056665 >В том смысле, что они семантически - натуральные числа. В некоторой денотационной семантике над λ-исчислением. Нумералы Чёрча - абстракции вида n = λ s z. (sⁿ z) ≡ λ s z. s (s (s … (sz))…) в нормальной форме. Когда ты говоришь, что нумералы Чёрча могут быть данными, что конкретно ты имеешь в виду? >это инструмент для инкапсуляции Я этого как раз не понял и просил привести пример. >Какую вычислительную модель использует HTML, формально, это язык программирования? Я не очень хорошо разбираюсь в HTML, но думаю, что никакую, потому что это язык разметки веб-страниц (а не программирования). >Когда ты пишешь на хаскеле f = 1 , ты не определяешь алгоритм, ты декларируешь, что ты буковкой обозначил число, а вот в императивщине определен именно алгоритм: положить в ячейку памяти число. Ну и что? Выражение "f = 1" имеет разный смысл в разных языках. В хаскеле это определяет именованный терм-значение (либо терм в нормальной форме, либо атом), который означивается в себя. Это алгоритм. В ИП - это присваивание, со своей императивной семантикой.
>>1056697 >Я этого как раз не понял и просил привести пример. Я привел пример. В SICP есть пример.
>потому что это язык разметки веб-страниц (а не программирования). Формально он является языком программирования.
>который означивается в себя. Это алгоритм Означивающийся в себя - это атом (f в f). А здесь именно декларация (f в 1). И это не алгоритм, здесь нет описания действия.
>>1056697 >нумералы Чёрча могут быть данными, что конкретно ты имеешь в виду? Вот что: Данные — зарегистрированная информация; представление фактов, понятий или инструкций в форме, приемлемой для общения, интерпретации, или обработки человеком или с помощью автоматических средств.
>>1056700 >В SICP есть пример. Можешь по-точнее сослаться? >Формально он является языком программирования. Я слишком поверхностно знаком с HTML, но я сильно сомневаюсь, что языки разметки нуждаются в какой-то вычислительной модели. >Означивающийся в себя - это атом (f в f). А здесь именно декларация (f в 1). Да нет. Я говорю 1 означивается в 1. f - это имя в тексте программы, в семантике его нет. >И это не алгоритм, здесь нет описания действия. 1 - это значение (т.е. дальнейшие редукции невозможны). Но это корректный терм, т.е. алгоритм.
>>1056702 >Данные — зарегистрированная информация; представление фактов, понятий или инструкций в форме, приемлемой для общения, интерпретации, или обработки человеком или с помощью автоматических средств. Словом: любая информация? В таком случае любые термы (в т.ч. и нумералы Чёрча) - это данные. Но ранее (здесь >>1055686) ты говорил, что в ФП есть хранимые данные (полагаю это не любая информация). Это я и не понял, что тут имелось в виду. Я говорил о том, что свободные переменные терма в ФП никак не могут быть "хранимыми данными".
>>1056716 >Можешь по-точнее сослаться? Там куда ни плюнь одни замыкания: фактически, программирование в Лиспах строится на замыканиях в том, или ином виде. Открывай книгу и изучай.
>сильно сомневаюсь, что языки разметки нуждаются в какой-то вычислительной модели. Не нуждаются, и в то же время они являются языкам программирования.
>f - это имя в тексте программы, в семантике его нет. Идентификаторы являются неотъемленной частью семантики языка. А вычислитель обязан знать, что означает тот, или иной идентификатор.
>В таком случае любые термы (в т.ч. и нумералы Чёрча) - это данные Да. Любые термы могут быть как данными, так и кодом. Нумералы Чёрча - самый очевидный представитель данных. Этакий дуализм кода и данных.
>Я говорил о том, что свободные переменные терма в ФП никак не могут быть "хранимыми данными". Свободные переменные в замыканиях связаны с какими-нибудь термами.
>>1056807 >Там куда ни плюнь одни замыкания: фактически, программирование в Лиспах строится на замыканиях в том, или ином виде. Открывай книгу и изучай. Да там много упоминаются замыкания, но вот что написано в сноске на стр. 106 в моём издании: >К сожалению, в сообществе программистов, пишущих на Лиспе, словом «замыкание» обозначается еще и совершенно другое понятие: замыканием называют способ представления процедур, имеющих свободные переменные. В этом втором смысле мы слово «замыкание» в книге не используем. >Не нуждаются, и в то же время они являются языкам программирования. Не понимаю, зачем бы. В любом случае, если нет вычислительной модели, то программировать на языке невозможно. >Идентификаторы являются неотъемленной частью семантики языка. А вычислитель обязан знать, что означает тот, или иной идентификатор. Я имею в виду операционную семантику (погружение программы в вычислительную модель). Здесь идентификаторов (имён присвоенных термам в исходном коде программы) нет (в ФП). >Этакий дуализм кода и данных. Что за дуализм то? Ты же сам определил данные как (почти) любую информацию, а теперь подозреваешь какой-то важный дуализм. >Свободные переменные в замыканиях связаны с какими-нибудь термами. Не связаны они ни с какими термами - они свободные. Если свободная переменная в некотором терме связывается (в абстракции) в каком-то его надтерме, то в какой-нибудь аппликации, в которой этот надтерм стоит в левой части, при редукциях произойдёт подстановка правой части вместо этой (уже связанной) переменной. И больше ничего. Никаких хранимых данных.
>>1056919 >на Лиспе, словом «замыкание» обозначается еще и совершенно другое понятие: замыканием называют способ представления процедур, имеющих свободные переменные. В этом втором смысле мы слово «замыкание» в книге не используем. Означает, что термин "замыкание" несет еще и такой смысл и они во избежание путаницы применяют этот термин только для одного смысла. Что ты хотел этим показать?
>то программировать на языке невозможно. Но на html пишут программы и они даже могут исполняться: браузерами, поисковыми ботами итд. При этом программист даже не задумывается о модели вычисления, ему это знать не надо.
>Что за дуализм то? Нет различия между кодом и данными. Любой терм можно считать кодом, а можно считать и данными.
>Не связаны они ни с какими термами >Если свободная переменная в некотором терме связывается Сам-то противоречия в словах своих не видишь? Не важно каким образом происходит дальнейшее вычисление, важно, что связывание имеет место быть.
>Никаких хранимых данных. Если терм находится в какой либо из нормальных форм - то он является данными. Вычислитель не может его редуцировать просто по определению нормальной формы.
>>1056925 >Что ты хотел этим показать? Я хотел уточнить, какой именно пример из SICP посмотреть, чтобы понять твою мысль о том, что "замыкания в ФП - это инструмент для инкапсуляции". Но в сноске написано, что в книге замыкания в смысле "процедур, имеющих свободные переменные" не рассматриваются. >Но на html пишут программы... Ну значит у него есть вычислительная модель (я же говорю, я не большой знаток HTML). >программист даже не задумывается о модели вычисления, ему это знать не надо Думаю, это печально. >Нет различия между кодом и данными. Любой терм можно считать кодом, а можно считать и данными. Это трюизм, если, как ты говоришь, под данными понимать просто всякую информацию. Это можно усматривать в любом языке (да вообще везде, где есть какой-то код). >Сам-то противоречия в словах своих не видишь? Какое противоречие? Свободные переменные - они свободные в некотором терме, т.е. не связаны в нём знаком λ в абстракции. В некотором надтерме этого терма эти же переменные уже могут быть связанными. >Не важно каким образом происходит дальнейшее вычисление, важно, что связывание имеет место быть. Я не понял, что ты этим хочешь сказать. Какое всё это имеет отношение к "хранимым данным"? >Если терм находится в какой либо из нормальных форм - то он является данными. Что это значит? В каком смысле данными? Теперь ты полагаешь, что данные = терм в нормальной форме? Пусть так, но тогда по прежнему: терм в нормальной форме ≠ "хранимые данные". Хранимых данных в аппликативной модели нет. Действительно в хаскеле есть какие-нибудь императивные IO-переменные, но они, разумеется, вне аппликативной семантики и, уже хотя бы поэтому не имеют отношения к замыканиям (незамкнутым подтермам).
>>1056930 >Но в сноске написано, что в книге замыкания в смысле "процедур, имеющих свободные переменные" не рассматриваются. Не замыкания не рассматриваются, а они так их не называют. Не чувствуешь разницы? Процедуры со свободными переменными они используют и рассматривают постоянно.
>Это можно усматривать в любом языке (да вообще везде, где есть какой-то код). В МТ инструкции и данные разделены.
>В некотором надтерме этого терма эти же переменные уже могут быть связанными. В самом терме они свободные, в надтерме связанные. Поэтому надтерм можно рассматривать как лексическое окружение терма. Но я уже где-то по треду это упоминал.
>Теперь ты полагаешь, что данные = терм в нормальной форме? Например так. Или в слабой заголовочной нормальной форме. В любой нормальной форме, какую можно придумать.
>терм в нормальной форме ≠ "хранимые данные" Почему не равно-то? Пока происходят вычисления других термов, они где-то хранятся же.
>>1056938 >Не замыкания не рассматриваются, а они так их не называют. Не чувствуешь разницы? В сноске написано дословно: "на Лиспе, словом «замыкание» обозначается еще и совершенно другое понятие: замыканием называют способ представления процедур, имеющих свободные переменные. В этом втором смысле мы слово «замыкание» в книге не используем". Это написано в разделе, где замыкания используются, но не те, а в другом смысле. >В МТ инструкции и данные разделены. В МТ инструкции - правила перехода. В обобщённой МТ (на которой можно "кодировать" все другие МТ) инструкции - на ленте, но в общем-то отличимы от другой информации на ленте. Здесь данные (информация), которые хранятся на ленте - хранимые данные. Это второе значение слова "данные", которое я привёл здесь >>1056372. Ты же говорил о данных как о любой информации (здесь >>1056702), затем ты стал рассматривать данные как термы в нормальной форме (значит, только в ФП). Всё это весьма разные значения. Я уже запутался, что ты имеешь в виду. Когда я говорил про трюизм дуализма, я имел в виду твоё первое значение. >В самом терме они свободные, в надтерме связанные. Поэтому надтерм можно рассматривать как лексическое окружение терма. Так о том и речь. Где здесь противоречие? >Почему не равно-то? Смысл (то есть семантика) разный. >Пока происходят вычисления других термов, они где-то хранятся же. Что значит "пока" и "храниться" в аппликативной семантике? Напомню, реализацию мы не рассматриваем.
>>1056942 >Это написано в разделе, где замыкания используются, но не те, а в другом смысле. А те, которые мы ищем используются по всей книге, только их не называют замыканиями для избежания путаницы.
>инструкции - на ленте, но в общем-то отличимы от другой информации на ленте Формат хранения не важен, важно, что в МТ данные четко подразделены на два вида - инструкции и не инструкции. В ФП же одни и те же данные могут быть как данными над которыми совершаются вычисления, так и данными, которые описывают эти вычисления.
>Что значит "пока" и "храниться" в аппликативной семантике? Пока не началась бета редукция с участием этого подтерма, подтермы не одновременно редуцируются, а в определенном порядке. А хранится - где-то эти термы же записаны в каком-то виде, пока не совершается редукция с их участием.
>>1056970 >В ФП же одни и те же данные могут быть как данными над которыми совершаются вычисления, так и данными, которые описывают эти вычисления. В каком смысле "данные"? В смысле "любая информация"? Другими словами: и инструкции и неинструкции в программе - это некоторая информация. Тогда, согласен. Но это в равной степени верно и для ФП и для ИП. Поэтому, такой дуализм бессодержателен. >Пока не началась бета редукция с участием этого подтерма, подтермы не одновременно редуцируются, а в определенном порядке. "Пока не началась бета редукция", "одновременно", "хранится" - нет таких понятий в аппликативной модели (а, значит, и в ФП). >А хранится - где-то эти термы же записаны в каком-то виде, пока не совершается редукция с их участием. Все термы написаны в тексте программы. Никуда их больше писать не надо.
Нет смысла рассматривать реализацию. В реализации ФП-языка авторы могут сколько понадобится использовать императивные замыкания (если они допустимы в том языке, на котором пишется реализация). Там это вполне осмысленно, т.к. ФП-язык реализуется на тьюринг-архитектуре. Но для прикладного программиста это не имеет значение, скорее всего он об этом даже не узнает. Прикладной ФП программист программирует строго в рамках аппликативной модели и императивные замыкания ему никак не доступны.
>>1056981 >это некоторая информация Не просто некоторая информация. В ИП не над всей информацией можно проводить вычисления и не вся информация является описанием вычислений, это два непересекающихся подмножества всей информации. В ФП информация не делится на подобные подмножества.
>нет таких понятий в аппликативной модели Так, давай тогда тащи определение аппликативной модели. А то я запутался что ты имеешь ввиду. То ты лямбда-исчисление в качестве вычислителя используешь, то говоришь, что нет бета-редукций.Определись уже.
>Все термы написаны в тексте программы. Никуда их больше писать не надо. Ага, и вычислять её тоже не надо. А вот процессе вычисления могут возникать новые термы, отличные от исходных. Все равно, что сказать, что вся императивная программа написана в тексте программы, больше никуда ее писать не надо, да и вычислять тоже.
>>1056985 На хаскеле это ровно то, что писалось раньше: терм со свободными переменными. В терминах SICP это называется "процедура со свободными переменными".
>>1056995 >Не просто некоторая информация. В ИП не над всей информацией можно проводить вычисления и не вся информация является описанием вычислений, это два непересекающихся подмножества всей информации. В ФП информация не делится на подобные подмножества. Да это понятно. Ты вот здесь >>1056925 писал >Нет различия между кодом и данными. Любой терм можно считать кодом, а можно считать и данными. В ФП данных (хранимых) нет, поэтому и различия нет, и терм считать данными (хранимыми) нельзя. А если данные понимать как просто информацию, то утверждение о том, что данными является всё в программе - трюизм и в ФП и в ИП. Вот чём я говорю. >Так, давай тогда тащи определение аппликативной модели. Было уже. Какой-нибудь вариант λ-исчисления или комбинаторной логики. >говоришь, что нет бета-редукций. Я говорю, утверждение "Пока происходят вычисления других термов..." не имеет смысл в аппликативной модели. >Ага, и вычислять её тоже не надо. А вот процессе вычисления могут возникать новые термы, отличные от исходных. >Все равно, что сказать, что вся императивная программа написана в тексте программы, больше никуда ее писать не надо, да и вычислять тоже. Все эти вопросы стоят перед тем, кто имплементирует ФП-язык на императивной архитектуре. Для прикладного ФП-программиста они не имеют смысла, если он строго придерживается аппликативной семантики. Я всё это к тому, что терм в нормальной форме ≠ "хранимые данные" (терм в нормальной форме - в ФП-семантике, хранимые данные - в ИП-семантике). Давай, как и условились, оставим вопросы реализации, они не имеют отношения к замыканиям.
>>1057005 Так ведь нет никаких хранимых данных в ФП. Я хочу увидеть пример "инкапсуляции" в ФП, чтобы понять, как осмысленно использовать замыкания в ФП.
>>1057012 >В ФП данных (хранимых) нет Но где-то термы хранятся же (пусть и записанными на листочке бумажки.
>Какой-нибудь вариант λ-исчисления или комбинаторной логики. >Я говорю, утверждение "Пока происходят вычисления других термов..." не имеет смысл в аппликативной модели. В лямбда-исчислении вычисление представляет собой цепочку бета-редукций и "Пока происходят вычисления других термов..." обретает смысл.
>>1057025 >Но где-то термы хранятся же (пусть и записанными на листочке бумажки. Да пусть они хранятся где это угодно авторам имплементации. Семантический смысл хранению данных в ФП придать нельзя. >В лямбда-исчислении вычисление представляет собой цепочку бета-редукций и "Пока происходят вычисления других термов..." обретает смысл. >Только если каким-нибудь внешним образом добавить темпоральность к редукциям (то есть отношение раньше-позже-одновременно). В чистом λ-исчислении и CL такого нет.
>>1057012 >Я хочу увидеть пример "инкапсуляции" в ФП, чтобы понять, как осмысленно использовать замыкания в ФП. Ооо, я пока писал ответ подумал, что если подходить к вопросу так, как ты, то термином замыкание в ФП надо пользоваться только на этапе написания программы, а не во время вычисления. И "свободная переменная потом свяжется" относится к процессу написания программы, т.е. в одном месте программы пишем терм, а затем в другом связываем свободные переменные в этом терме. Можешь осмысленно так пользоваться, если хочешь.
>>1057028 >Да пусть они хранятся где это угодно авторам имплементации. Семантический смысл хранению данных в ФП придать нельзя. Формат хранения не оговорен, потому, что не важен. Но храниться где-то должны. Иначе откуда его вычислитель брать будет?
>>1057030 >Формат хранения не оговорен, потому, Дело не в формате. Еще раз в аппликативной семантике самого понятия "хранение данных" нет. Всё это вопросы имплементации.
>>1057035 >И где термы сидят, когда мы о них говорим? Нигде они не сидят. Программист их просто пишет в тексте программы и всё. >Но могут содержать незамкнутые, вот они-то и есть замыкания. Да это я понял. Проблема в том, что я не вижу, чтобы они соответствовали по смыслу (семантически) императивным замыканиям, а только внешне. Поэтому не понятно, как их осознанно применять в ФП (в каких ситуациях я должен понять: "Ага, а вот тут мне помогут замыкания" и использовать их?).
>>1057039 >Нигде они не сидят. Программист их просто пишет в тексте программы и всё. Тогда при чем тут аппликативная семантика? Самая настоящая денотационная. Ни намека на вычислительный процесс, или алгоритм.
>чтобы они соответствовали по смыслу (семантически) императивным замыканиям, а только внешне Императивные замыкания и называются замыканиями, потому, что внешне похожи на ФП замыкания (откуда название и идея родом).
>Ага, а вот тут мне помогут замыкания Императивные замыкания не помогут (их нет). А ФП замыкания - уже тысячу раз тут обсудили -- это просто название для терма определенного вида и всё.
>>1057054 >Тогда при чем тут аппликативная семантика? Самая настоящая денотационная. Ни намека на вычислительный процесс, или алгоритм. Как причём? ФП-язык имеет аппликативную семантику. Алгоритм - терм. Вычисление - редукция терма до значения. >Самая настоящая денотационная. Почему денотационная? >А ФП замыкания - уже тысячу раз тут обсудили -- это просто название для терма определенного вида и всё. Тогда я повторяю свой вопрос-предположение >>1055463
>>1057058 Как причём? >Почему денотационная? Потому, что записываются чистые математические выражения в немного другом синтаксисе: [hask] f x = x +1 == [math] f(x) = x + 1
>>1057058 >Тогда я повторяю свой вопрос-предположение >Я берусь за хаскель, а в хаскеле замыкания не используются. Как выяснили, используются ФП-замыкания, на которые ИП-замыкания одинаковые по форме и похожи по смыслу. Но таки да, ИП-замыкания ты используешь как костыль.
>>1057067 >Потому, что записываются чистые математические выражения... Программист на ФП записывает термы. >похожи по смыслу Как же похожи по смыслу, если семантика переменных в ФП и ИП разная? Вызов процедуры в ИП и сокращение редекса в ФП тоже различаются семантически.
>>1057077 >Программист на ФП записывает термы. Программист на lambda calculus. А программист на ФП - математические выражения. Последние можно определить в терминах lambda calculus (как и программу в ИП в терминах МТ).
>Как же похожи по смыслу, если семантика переменных в ФП и ИП разная? Вызов процедуры в ИП и сокращение редекса в ФП тоже различаются семантически. Похожи, хоть и не одинаковы. Абстракции, как и процедуры несут в себе информацию о том, что делать с переменными (точнее с тем, что связано с этими переменными), а переменные используются как обозначения данных (термов / ячеек памяти). Этот смысл абстрагирован от вычислительной модели, а дальше начинаются детали, которые различны и не существенны для программиста (если последний не использует замыкания в ИП в смысле костыля для преодоления трудностей фунарга).
>>1057086 >А программист на ФП - математические выражения. Нет, именно термы. Написанное будет вычисляться строго в соответствии с операционной семантикой. А денотационная семантика термов в ФП и процедур в ИП факультативна. >переменные используются как обозначения данных (термов... В ФП переменные не используются как обозначение термов, они используются для указания мест в терме, куда будут подставляться термы при сокращении редекса. >Похожи, хоть и не одинаковы. И самое плохое, что понимание ФП замыкания никак не поможет ИП программисту лучше понять ИП-замыкания. Какой толк писать, что замыкания - из ФП, если в самом ФП их роль весьма фиктивная. Программист просто пишет термы, какие ему нужны, и в них, как бы сами собой, "возникают" незамкнутые подтермы. ФП программист всё время безотчётно плодит "такие замыкания", и концентрироваться на них нет никого смысла.
>>1057094 >Нет, именно термы. Тогда при чем здесь комбинаторная логика? В ней нет термов, в ней есть комбинаторы, которые определяются как одноместные функции.
>А денотационная семантика процедур ИП Процедуры ИП в общем случае не обладают денотационной семантикой (например, x+=1). Выражения в ФП - все поголовно.
>Написанное будет вычисляться строго в соответствии с операционной семантикой. Операционная семантика Хаскеля понадобится только на этапе оптимизации программ. При программировании на Хаскеле в остальном большинстве случаев достаточно его денотационной семантики.
>В ФП переменные не используются как обозначение термов, они используются для указания мест в терме, Именно, именованное место в терме. Почти совсем как в ИП - именованное место на ленте.
>И самое плохое, что понимание ФП замыкания никак не поможет ИП программисту лучше понять ИП-замыкания. Замыкание - это описание вычислений в теле которого есть свободные переменные. Что тут еще надо понимать-то? То, что это иногда используется как костыль в ИП? Конечно тебе ФП не расскажет об этом.
>>1057335 >В ней нет термов, в ней есть комбинаторы, которые определяются как одноместные функции. CL-термы, они же комбинаторы. В λ-исчислении им соответствуют замкнутые термы. CL-термы определяются либо своими комбинаторными характеристиками, либо выражаются в виде аппликаций других CL-термов. Причём тут одноместные функции? >Процедуры ИП в общем случае не обладают денотационной семантикой (например, x+=1). Выражения в ФП - все поголовно. Ну так я и говорю, денотационная семантика факультативна. Если нужно и удалось указать отображение корректных выражений языка в выбранный математический домен, значит задана некоторая денотационная семантика. Но это не обязательно. Операционная же семантика языка программирования имеется всегда. >Операционная семантика Хаскеля понадобится только на этапе оптимизации программ. При программировании на Хаскеле в остальном большинстве случаев достаточно его денотационной семантики. Программировать не опираясь на операционную семантику - всё равно, что программировать вслепую. Не думаю, что в общем случае достаточно денотационной семантики, тем более, что в обще случае она не гарантирована. Вот, к примеру, какой смысл имеют ФП-замыкания в какой-нибудь денотационной семантике? >Почти совсем как в ИП - именованное место на ленте. Но терм - не лента памяти. Вообще ничего общего. >Замыкание - это описание вычислений в теле которого есть свободные переменные. Что тут еще надо понимать-то? Проблема в том, что использование замыканий в ФП и ИП разительно отличается.
>>1057362 >Причём тут одноместные функции? Потому что они такие функции. https://en.wikipedia.org/wiki/Combinatory_logic A combinator is a higher-order function that uses only function application and earlier defined combinators to define a result from its arguments.
>Операционная же семантика языка программирования имеется всегда. Не всегда (декларативные языки разметки). Но денотационная семантика хаскеля позволяет не думать об операционной семантике хаскеля. В ИП такое невозможно.
>Вот, к примеру, какой смысл имеют ФП-замыкания в какой-нибудь денотационной семантике? Именно такой как и в определении. Функция со свободными переменными.
>Но терм - не лента памяти. Вообще ничего общего. Общее здесь - "именованное место".
>Проблема в том, что использование замыканий в ФП и ИП разительно отличается. Вообще нет, если использовать замыкание в точности с его определением, а не в качестве костыля.
>>1057365 >Потому что они такие функции. Так а почему одноместные то? Вообще говорить о термах как о фунциях, значит иметь в виду их денотационную семантику. В чистом λ-исчислении и CL такого нет. И термы там определяются не как функции. >Не всегда (декларативные языки разметки). Но я то говорю о языках программирования. >Но денотационная семантика хаскеля позволяет не думать об операционной семантике хаскеля. В каких то специальных случаях, когда это действительно так и есть. Это верно и для ИП. >Функция со свободными переменными. Так а что это? В каком домене? >Общее здесь - "именованное место". Что-то я упустил нить. Что ты сказать то хочешь. Я имел в виду только, что в ФП переменные не используются как обозначение термов >а не в качестве костыля. Но факт в том, что в ИП это костыль. Если бы я был структурным лингвистом, я сказал бы, что замыкания в ИП и в ФП отличаются прагматически.
>>1057377 >Так а почему одноместные то? С одним аргументом потому что.
>И термы там определяются не как функции. Еще раз ссылку на общепринятое определение комбинатора дать?
>В каких то специальных случаях, когда это действительно так и есть. Это верно и для ИП. Приведи в пример случай, где важна операционная семантика Хаскеля и без нее невозможно понять что вычисляет, тот, или иной кусок кода.
>Так а что это? Например, f(x) = a + x
>Что-то я упустил нить. Что ты сказать то хочешь. Я имел в виду только, что в ФП переменные не используются как обозначение термов Я неправильно выразил свою мысль, назвав обозначением терма, а не обозначением места для терма.
>>1057387 >С одним аргументом потому что. Для K-комбинатора, например, вполне возможна денотационная семантика, где ему соответствует двухместная некаррировнная функция. >Еще раз ссылку на общепринятое определение комбинатора дать? Полагаю, правильное лучше общепризнанного. >Приведи в пример случай, где важна операционная семантика Хаскеля и без нее невозможно понять что вычисляет, тот, или иной кусок кода. Все случаи, где нужно представлять, как идут редукции, на каких термах они останавливаются, как термы типизируются. >Например, f(x) = a + x Так это в домене какого-нибудь кольца многочленов. А в общем-то случае как?
>Все случаи, где нужно представлять, как идут редукции, на каких термах они останавливаются Я просил конкретный пример, а не то же утверждение, сказанное другими словами.
>А в общем-то случае как? Функция со свободными переменными.
>>1057404 >Возможна, но в семантике комбинаторной логики это одноместная функция по определению. Как в самой CL определяются CL-термы я уже писал. В чистой CL не предусмотрена никакая денотационная семантика, только операционная. >https://en.wikipedia.org/wiki/Combinatory_logic Зачем это. Я лучше бы сослался на Карри или Барендрегта, ну или, на худой конец, на какой нибудь неплохой учебник. >Я просил конкретный пример, а не то же утверждение, сказанное другими словами. Ну а какой такой случай? Каждый раз когда встречаем или придумываем новый терм, чтобы понять его и проделать с ним всё, о чём я сказал, нужно опираться на операционную семантику. >Функция со свободными переменными. Так вот, полагаю, такого достаточно общего домена не найдётся но это не точно. И понимать ФП-замыкания в общем случае нужно в смысле аппликативной семантики.
>>1057410 >Зачем это. Я лучше бы сослался на Карри или Барендрегта, ну или, на худой конец, на какой нибудь неплохой учебник. Ну так процитируй это правильное определение.
>Ну а какой такой случай? Просто кусок кода, смысл которого невозможно понять без привлечения знаний об операционной семантике Хаскеля.
>полагаю, такого достаточно общего домена не найдётся Для начала define достаточно общий домен, там и поищем.
>>1057419 >Ну так процитируй это правильное определение. Зачем? То, которое я привёл, разве неправильное? Чем оно отличается от того, что в литературе? >Просто кусок кода, смысл которого невозможно понять без привлечения знаний об операционной семантике Хаскеля. Да любой кусок кода. Повторяю, денотационная семантика не заменяет операционную. Она позволяет уточнить математический смысл выражений, выяснять правильно ли будет оно вычисляться в домене-модели. Чтобы мы могли убедиться, что то, что мы написали, соответствует нашим намерениям. Это расширяет возможности для изучения программы, как решения некоторой математической задачи. >Для начала define достаточно общий домен, там и поищем. Такой домен, в который отображаются все ФП-замыкания.
Я не понимаю уже, о чём этот спор. Про ФП-замыкания я в основном выяснил. Итог: нафиг не нужны "такие замыкания"
>>1057435 >Зачем? То, которое я привёл, разве неправильное? Чем оно отличается от того, что в литературе? От википедии (ссылку привел) отличается. А ты так и не привел ссылку на более авторитетное определение.
>Она позволяет уточнить математический смысл выражений, выяснять правильно ли будет оно вычисляться в домене-модели. Ой вэй, "уточнить смысл математических выражения" как это? Математические выражения не достаточно точные? Поясни. Все-таки пример такого кода не помешал бы, иначе так и будешь плясать вокруг да около.
>Итог: нафиг не нужны "такие замыкания" Твое право не пользоваться этим термином.
>>1057439 >не привел ссылку Я же написал авторов. >авторитетное определение. Да не авторитетное, а более строгое. >"уточнить смысл математических выражения" ...математический смысл (синтаксически правильных) выражений языка... >Твое право не пользоваться этим термином. Так и понятием не получится пользоваться осознанно.
>>1057464 >Я же написал авторов. Книгу с точностью до страницы, хотя бы.
>математический смысл (синтаксически правильных) выражений языка Денотационной семантики хаскеля достаточно для понимания смысла этих математических выражений. Похоже, не дождусь я примера кода, доказывающего, что ты тут прав.
>Так и понятием не получится пользоваться осознанно. Если ты не можешь осознать, то конечно.
>>1057468 >Книгу с точностью до страницы, хотя бы. Барендрегт "Лямбда-исчисление. Его синтаксис и семантика", глва 7. Wolfengagen "Combinatory logic in programming. Computations with objects through examples and exercises", chapter 2. Hindley, Seldin "Lambda-Calculus and Combinators, an Introduction", 2A Зачем тебе эти ссылки? К тому, что я написал про CL, какие-то претензии есть? >Денотационной семантики хаскеля достаточно для понимания смысла этих математических выражений Да не математических выражений а выражений языка. >Если ты не можешь осознать, то конечно. Ну я же выше писал в чём трудность. Анон, мне кажется, с твоей стороны начинается какое-то тралирование.
>Да не математических выражений а выражений языка. Да, точно. Спасибо. Денотационной семантики хаскеля достаточно для понимания смысла этих выражений языка.
>Ну я же выше писал в чём трудность. Не понимаю я твоей трудности в абстрагировании от вычислительной модели. Удивительно, что у тебя не возникает вопросов по таким терминам, как "анонимные функции", "функция высших порядков", "функторы", "монады", ведь все это в итоге сводится к термам в лямбда исчислении.
Basics - http://learnyouahaskell.com/chapters
Medium - http://book.realworldhaskell.org/read
Concurrency - http://chimera.labs.oreilly.com/books/1230000000929/index.html
Web - http://www.yesodweb.com/book