LINUX.ORG.RU

Монады vs макросы vs фекспры

 , , ,


3

4

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

1) fexprs. Имеют полный контроль над вычислениями.

2) macros. Имеют контроль над вычислениями, ограниченный временем компиляции.

3) monads. То же самое, что п. 2, за исключением того, что в теле функции невозможно получить само выражение аргумент, «как он есть», а лишь его вычисленное значение.

Возможно я ошибаюсь, поэтому дополняйте и исправляйте.

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

То есть средствами языка эта проблема не решается

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

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

чистое в смысле вне контекста, тут [1,2,3] - чистое значение, сами 1,2,3 без исследования контекста ты написать не сможешь.

соотв. написать просто (f :: Num a => [a]) $ (g :: Num a => [a]) $ (h :: Num a => [a]) как-то неполучится..

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

Почти любой поиск ошибок без людей не решается.

Поиск синтаксических ошибок давно решается. И ошибок типов. Отсутствие летающих автомобилей — не повод возвращаться в пещеру.

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

То есть средствами языка эта проблема не решается

Нету никакой проблемы, еще раз. Описанная ситуация на практике невозможна.

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

applicative позволяет написать последовательность действий с эффектами. но applicative не задает порядок их выполнения

Я вижу здесь противоречие. Последовательность действий может быть _последовательностью_ лишь тогда, когда четко и однозначно задан порядок этих действий.Как можно задать последовательность действий, не задавая их порядка? Поясни.

Т.е. в applicative (a *> b) никто не запрещает сначала применить эффект b, потом a, в отличии от.

В монаде тоже никто не запрещает, но мы говорим о конкретных монадах, которые реализованы так, чтобы у них было сперва а, потом b. В чем же отличие от аппликатива? Давай говорить о конкретных аппликативах, у которых сперва а, потом b?

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

Нет, у него проблема в том, что ты не поставишь скобочку в прошивке контроллера и из-за этого машина врежется в столб.

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

Поиск синтаксических ошибок давно решается.

Тогда почему ты называешь это проблемой?

anonymous
()

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

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

Какое странное определение, впервые вижу. Ты его в Душкине вычитал или в вики какой? Может почитаешь хорошие книжки вроде TAPL, чтобы понять, что обычно понимается под контекстом в контексте фп?

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

Я вижу здесь противоречие. Последовательность действий может быть _последовательностью_ лишь тогда, когда четко и однозначно задан порядок этих действий.Как можно задать последовательность действий, не задавая их порядка? Поясни.

ок, applicative не позволяют задать порядок эффектов (заметь, эффектов, а не действий).

В монаде тоже никто не запрещает, но мы говорим о конкретных монадах, которые реализованы так, чтобы у них было сперва а, потом b. В чем же отличие от аппликатива? Давай говорить о конкретных аппликативах, у которых сперва а, потом b?

Вот пример applicative, который не известно как выполняет a и b

import Control.Concurrent.Async
import Control.Applicative

newtype PIO a = PIO { unPIO :: IO a}

instance Functor PIO where
   fmap f (PIO g) = PIO (fmap f g) 

instance Applicative PIO where
   pure a = PIO (pure a)
   f <*> v = PIO $ uncurry ($) <$> concurrently (unPIO f) (unPIO v)

с b потом a справишься?

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

не помню, TAPL читал достаточно давно, вопросы применимые к контексту нашей дискуссии там не поднимались. В общем ты можешь предложить любое другое слово, которое можно использовать в предложении поднятие в <***>, где поднятие относится к fmap, pure, return, и подставить везде выше.

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

Бенджамин Пирс, глава 19.5 оперделение 19.5.3 «evaluation context» хотя и не точно (там рассматривается FJ), но достаточно близко к тому, что под контекстом имел я..

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

Если выкинуть подтипирование и new, то получишь ровно тот же принцип выбора операций из словарей, связанных со структурой данных.

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

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

Напомню - общее слово описывающее стуктуры Functor, Monad, Applicative, Arrow.

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

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

Тем более в том, в чем я был совсем не прав - меня убедили

Ну и слава богу.

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

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

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

Я тебе ровно это и сказал.

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

Грамматика — супер.

Для того, чтобы упорядочивать эффекты, монады ТОЖЕ не обязательны (кстати, ранние версии Хаскеля без них обходились, а, скажем, Clean так и продолжал обходиться).

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

уйди, пожалуйста, уж кому-кому, а не тебе тут пытаться других оскорблять.

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

Я тебе ровно это и сказал.

Ссылку?

Грамматика — супер.

нервы?

стати, ранние версии Хаскеля без них обходились, а, скажем, Clean так и продолжал обходиться).

ранние версии haskell в общем-то без эффектов были аж примерно до 92-93 года, когда там статьи SPJ и Wadler были? Ну и continuations во все поля, опять же см. Wadler о сравнении подходов.

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

порядок редукции тоже не опеределен.

Порядок редукции определяется как нормальный, и при этом он не определен? lol

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

Монады vs макросы vs фекспры (комментарий)

нервы?

Тебе видней, что там у тебя.

без эффектов были

Нет.

По сути, там было что-то типа interact. То есть, на вход поступал массив строк, на выходе тоже был массив строк. Другое дело, что синхронизировать это было безумно сложно, так что в конце концов перешли к более удобному способу — монадам. Но сайд-эффекты типа «вывести на экран вопрос и подождать от юзера ответа» были.

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

В call-by-need семантике при передаче значения я не могу сказать, каким образом оно будет редуцировано.

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

Монады vs макросы vs фекспры (комментарий)

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

Тебе видней, что там у тебя.

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

По сути, там было что-то типа interact. То есть, на вход поступал массив строк, на выходе тоже был массив строк. Другое дело, что синхронизировать это было безумно сложно, так что в конце концов перешли к более удобному способу — монадам. Но сайд-эффекты типа «вывести на экран вопрос и подождать от юзера ответа» были.

назвать interact сайд эффектами.. ладно можно.

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

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

Редуцируется не значение, а выражение. И сказать можно вполне определенно. Например, лямбда терм (\x->y)(\x \x) будет редуцирован в y. Глупости ты говоришь. Просто твердишь какие-то мантры.

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

в этом определении

Определение — в исходниках, а не в моём комменте.

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

«Срываюсь»?

назвать interact сайд эффектами

А чем ещё? Что-то вводится с клавиатуры, что-то выводится на экран. Сайд-эффекты в чистом виде.

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

Это у тебя детское определение сайд эффектов. Сайд-эффект — это присваивание. IO имеет к этому опосредованное отношение.

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

Определение — в исходниках, а не в моём комменте.

В исходниках реализация, а определение в статьях по которым она сделана. Для хацкеля основная это Moggi 88 года.

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

А чем ещё? Что-то вводится с клавиатуры, что-то выводится на экран. Сайд-эффекты в чистом виде.

Если код состоит из блоков вида interact msg (String -> String), то это все же не эффекты, впрочем я в те годы в детский сад ходил, так что как там было не знаю, судя по статье SPJ и Wadler imperative functional programming было: dialogues (Hudak 92) - без сайд эффектов, continuation (Gordon 89) где был набор примитивных «IO» операций, в общем о чем я тут и писал..

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

Сайд-эффект — это присваивание.

сайд-эффект - это то, что не имеет прямого отношения к возвращаемому функцией значению

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

если только ф-ция может это прочитать или записать

не обязательно, вызов другой функции - тоже сайд эффект, или я Вас не очень понял?

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

кроме того все операции ввода/вывода - есть не что иное как «присваивание» (в широком смысле)

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

Поиск синтаксических ошибок давно решается.

В лиспе для этого есть раздельная компиляция. Пишешь (compile-file «testr») и в процессе получаешь полную синтаксическую проверку, а местами даже проверку типов.

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

Редуцируется не значение, а выражение.

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

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

С каких пор присваивание перестало быть IO?

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

Энергичный ЯП:

f=func(arg)(if foo eval arg)
f("func()(side-effect)")
И у тебя нет способа указать, будет ли оно редуцировано и, если да - то когда будет. По-этому если в твоем выражении есть эффект, то этот эффект может быть произведен в любой момент - или вовсе не произвведен и у тебя нету способа узнать, что именно случится в данном конкретном случае.

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

Хочешь разогреть лор в пятницу?

Создай тред с простым вопросом: while(1) {} // <- это алгоритм?

Мне лень регаться на лоре, а анонам нет возможности треды создавать в development...

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

Такой тред удалят скорей всего сразу. Давай здесь обсудим. Начнем с вопроса, а есть ли четкое и внятное определение алгоритма?

Если следовать определению из педивикии

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

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

Только не путать с while(1){action; if some_value break} — это другое.

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

Вообще, у тебя каша в голове. Такой вопрос не может просто возникнуть в принципе. Алгоритм всегда подразумевает какую то задачу. Он есть инструмент ее решения. Любой бесцельный кусок кода, если он не является инструментом решения конкретной задачи, а не только твое чудо, вообще любой, алгоритмом не является, естественно.

terminator-101
() автор топика
Ответ на: комментарий от terminator-101

Алгоритм всегда подразумевает какую то задачу.

Ебанутая шизофреничка продолжает выдумывать себе свои личные, отличные от других определения. Смешная сучка!

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

Если следовать определению из педивикии

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

An informal definition could be «a set of rules that precisely defines a sequence of operations.»

anonymous
()

Забаньте ТС, пожалуйста. То он тикль и перл изучает, через неделю — лиспы и хаскель. Доколе, спрашивается?

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

Монады можно определить как устранение вложенности, то есть в построении терма F A из терма F (F A) для эндофунктора F : Type -> Type с помощью подходящей функции join : F (F A) -> F A обладающей некоторыми дополнительными свойствами. Например join [[1, 2], [3, 4]] ~ [1,2,3,4] — одинаково имеет смысл хоть в теории типов, хоть множеств, хоть категорий, так что привязывать к монадам порядок вычислений как-то странно (точнее, категорная семантика вычислений может быть дана с помощью монад, Moggi и т.п., да, но это не значит, что конструкция монад как-то сама завязана на них или тем более как-то задаёт их порядок — вопрос сводится тупо к населённости функционального пр-ва между определёнными типами функцией с определёнными свойствами, чтобы утверждать что F это монада).

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

И у тебя нет способа указать, будет ли оно редуцировано и, если да - то когда будет.

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

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

И только в этом случае

(define (test x) (write 'nothing))
(test (lambda () (write 'side-effect)))
; nothing

Если ты суешь что-то в функцию - оно обязательно будет вычислено

будет вычислено, да, вопрос только в том, во что. Функция в энергичном ЯП , технически, вычисляется в свою скомпилированную версию — т.е. — в саму себя, семантически — не вычисляется. Точно также, как и вызов функции в качестве аргумента в call-by-need семантике, вычисляется в сам вызов.

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

Даже имитировать в точности эту срань можно.


(define (test x) (write 'nothing))
(define (test2 x) (x))
(define f (lambda () ((lambda()(write 'side-effect)))))
(test f)
(newline)
(test2 f)
;  nothing
;  side-effect

terminator-101
() автор топика
Ответ на: комментарий от terminator-101

Функция в энергичном ЯП , технически, вычисляется в свою скомпилированную версию — т.е. — в саму себя, семантически — не вычисляется.

Что значит «семантически не вычисляется»? Вычисление - это редукция до нормальной формы. Ф-я сама по себе уже находится в нормальной форме, по-этому она и так вычислена, точно так же как вычислены литералы.

алсо, что ты хотел показать своим кодом? Там все вполне вычислено.

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