LINUX.ORG.RU

Сall/cc — императивная или функциональная конструкция?

 , ,


0

3

call/cc может изменить состояние вычислений

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

Продолжение, захватываемое call/cc часто сохраняется посредством деструктивного присваивания для последующего использования.

И, наконец, call/cc чаще всего, внезапно, связывают с функциональной парадигмой, Емнип, она есть даже в Хаскеле.



Последнее исправление: linux-101 (всего исправлений: 1)

У тебя новый ник?

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

Не противоречит. Если считаешь иначе приводи ссылки на описание ФП парадигмы с чем происходит противоречие. При чем тут стековач модель тоже не ясно.

Продолжение, захватываемое call/cc часто сохраняется посредством деструктивного присваивания для последующего использования.

Нет.

Два ложных устверждения и основанный на них вопрос, неплохо.

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

Первое что на глаза попалось

Фу́нкция в программировании — поименованный фрагмент программного кода (подпрограмма), к которому можно обратиться из другого места программы. С именем функции неразрывно связан адрес первой инструкции (оператора), входящей в функцию, которой передаётся управление при обращении к функции. После выполнения функции, управление возвращается обратно в адрес возврата — точку программы, где данная функция была вызвана.
Нет.

Да

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

Связана, в плане реализации. Передача аргументов происходит через стек, рекурсивные вызова строятся через стек, много всего.

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

И какое отношение определение подпрограммы, не являющееся точным при наличии setjmp/longjmp, имеет к функциональной парадигме?

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

Ладно, я дал пруф, теперь твоя осередь, давай пруф из «правильного» источника, где утверждается обратное.

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

После выполнения функции, управление возвращается обратно в адрес возврата — точку программы, где данная функция была вызвана.

Ну и? Продолжение возвращает другую функцию, в чем проблема?

функция, которую она получает в качестве аргумента, не возвращает управление в место вызова

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

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

Такое, что функциональная парадигма — это парадигма построенная на функциях, прежде всего. В ФП определение функции еще строже. В частности, функция обязана возвращать значение.

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

Ну и? Продолжение возвращает другую функцию, в чем проблема?

Какую другую? Я говорю, что функция, которая получает продолжение, не возвращает управление в место своего вызова.

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

Ты опять о чем то своем


(define search (lambda (wanted? lst)
   (call/cc (lambda(c) (for-each (lambda(element)
       (if (wanted? element) (c element))) lst)))))

(write (search (lambda(element) (= element 2)) '(1 2 3)))

Здесь, вместо того, чтобы возвратить управление в место вызова — один из рекурсивных вызовов for-each, управление возвращается в место вызова call/cc. Стек вызовов for-each, не схлопывается, а просто сбрасывается, насколько я понимаю.

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

И то и другое это детали реализации и зависят от call convention и не являются обязательными условиями, напр. в Haskell нету С-like стека.

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

Ты клоун, да? Давай начнём хотя бы с википедии

In computer science, functional programming is a programming paradigm, a style of building the structure and elements of computer programs, that treats computation as the evaluation of mathematical functions and avoids changing-state and mutable data

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

Ещё раз: понятие процедуры к функциональной парадигме отношения не имеет.

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

В случае call/cc она может вообще ничего не возвратить. Она возвратит что-то, но только не туда, откуда вызвана.

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

В ФП под функцией имеется ввиду функция в математическом смысле, подпрограмма, в которую передаются значения из множества A и она возвращает значение из множества B. Никаких предположений о связи с архитектурой вычислителя, соглашениях о вызове и т.п. не делается. Книжное определение может и позже дам, это не важно тут.

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

Еще раз, если ты утверждаешь, что в ФП функция не обязана возвращать результат в место вызова (в том же LC, lol), то давай пруф, а философия твоя не нужна.

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

один из рекурсивных вызовов for-each

Что? Где ты увидел «рекурсивные вызовы for-each»? Кто тебе вообще сказал что for-each реализован рекурсивно? А даже если код реализован рекурсивно, то кто тебе сказал, что на стеке вызовов есть что-то кроме одного вызова for-each? (man оптимизация хвостового вызова)

И даже более того: вместо логики работы кода ты пытаешься подсунуть логику работы конкретной реализации.

kim-roader ★★
()
Ответ на: комментарий от linux-101

Ещё раз: ты вместо пруфа по теме ФП используешь неполное определение процедуры из императивных языков прошлого века.

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

list n = (n):list (n+1)
myList = list 1

main =
  print (myList !! 5)

И вот у тебя ломается вся твоя стековая логика: ведь функция list 1 должна рекурсивно вызывать себя и умирать из-за переполнения стека!!11

kim-roader ★★
()

Чистая функция всегда возвращает один и тот же результат. Куда она его возвращает - не так уж важно.

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

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

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

А то, что мы прыгаем в СОХРАНЕННОЕ состояние, еще раз: СОСТОЯНИЕ, это тоже для фп-фанбоя не проблема, да? Немного демагогии, и все нормально.

Куда она его возвращает - не так уж важно.

Пруфец хотелось бы увидеть.

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

не можешь утверждать даже последовательной работы программы

А когда ты ифы используешь, ты тоже не можешь утверждать о последовательной работе?

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

ломается вся твоя стековая логика

Ничего там не ломается, там сахара слишком много, не более того.

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

Здесь, вместо того, чтобы возвратить управление в место вызова — один из рекурсивных вызовов for-each, управление возвращается в место вызова call/cc. Стек вызовов for-each, не схлопывается, а просто сбрасывается, насколько я понимаю.

Нет, здесь вместо возврата «процедуры-предыдущего шага рекурсии» возвращается «процедура-следующая после вызова call/cc» и она и выполняется. Если тебе это поможет: все вызовы процедур в Схеме являются хвостовыми и неявно передают продолжение. call/cc просто позволяет сделать это явно со связыванием продолжения с некоторым символом.

(define search (lambda (wanted? lst)

И перестань писать как наркоман, пиши как нормальный человек.

(define (search wanted? lst)
korvin_ ★★★★★
()
Последнее исправление: korvin_ (всего исправлений: 1)
Ответ на: комментарий от korvin_

Ну так тебе об этом и говорят, с чем ты споришь? for-each вычисляется, но не один из вызовов внутри него, в данном случае, не возвращает ничего в точку вызова. Вызовы есть, возвратов — нет.

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

все вызовы процедур в Схеме являются хвостовыми

Не все вызовы процедур являются хвостовыми,товарищ, а хвостовые являются хвостовыми, как это не пародоксально (для тебя) звучит. Учи матчасть.

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

СОСТОЯНИЕ

Ты путаешь состояние и окружение.

Пруфец хотелось бы увидеть

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

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

Нет, это ты путаешь окружение (которое тут вообще не при чем), с состоянием вычисления. Ты можешь заморозить вычисление, сохранить его, а затем продолжить вычисление с сохраненной точки. В этом суть call/cc.

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

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

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

Если у нас все функции чистые, то связи там будут такими же.

buddhist ★★★★★
()

стековая дисциплина достаточно позднее изобретение в программировании.

вообще стековость это наследие Алгола60.

помань J-оператор Ландина.

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

вообще же вот это полистай :

https://archive.org/stream/programsforelect00wilk#page/n9/mode/2up

Programs for an Electrical Computer (1951)

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

удивись и есть общий потомок алголки и скобкоты

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

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

Я не понял о чем ты. call|cc — это оператор из scheme. В некоторых других языках есть его кастрированная версия. И да, он похож на оператор J(jump). call/cc тоже прыгает. А вопроса никакого и не было, был сарказм. Это не ФП конструкция, хотя бы потому, что она позволяет функциям не возвращать значения.

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

Это вопрос точки зрения. call/cc вполне естественно вписывается в ФП-мир после CPS-преобразования. Чтобы никто не ушёл обиженным, там все вызовы функций не возвращают значений до самого конца вычислений.

ilammy ★★★
()

Сама по себе — нет. Пруф — монада Cont в хаскеле.

Miguel ★★★★★
()

императивная или функциональная

мультипарадигменная!!!

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

Ну так тебе об этом и говорят, с чем ты споришь? for-each вычисляется, но не один из вызовов внутри него, в данном случае, не возвращает ничего в точку вызова. Вызовы есть, возвратов — нет.

Ты точно прочитал мое сообщение? Возврат есть всегда. Всегда возвращается продолжение.

Не все вызовы процедур являются хвостовыми, товарищ, а хвостовые являются хвостовыми, как это не пародоксально (для тебя) звучит. Учи матчасть.

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

korvin_ ★★★★★
()

А какая разница? Тебе религия ее использовать не позволит если она императивная?

loz ★★★★★
()

Сначала define что такое функциональная парадигма, потом можно начинать обсуждение.

x4DA ★★★★★
()

anonimous залогинься и не неси чушь, а то тебя снова забанят.

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