OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Пятница, 04 Июль, 2025 20:03

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 172 ]  На страницу Пред.  1, 2, 3, 4, 5 ... 9  След.
Автор Сообщение
 Заголовок сообщения: Re: Сюда?
СообщениеДобавлено: Вторник, 02 Декабрь, 2008 12:15 

Зарегистрирован: Четверг, 12 Июль, 2007 23:18
Сообщения: 1982
Откуда: Узбекистан, Чирчик
Иван Кузьмицкий писал(а):
Теперь, оказывается, могут быть такие closures, которые могут этот смысл передать наружу.
В этом и есть суть замыканий, так что они все такие...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Сюда?
СообщениеДобавлено: Вторник, 02 Декабрь, 2008 12:29 

Зарегистрирован: Четверг, 12 Июль, 2007 23:18
Сообщения: 1982
Откуда: Узбекистан, Чирчик
Илья Ермаков писал(а):
Я хотел сказать, что мне непонятно (так вот сразу), какой момент из реальности этим моделируется. Сами по себе функции ФП - абстракции отнюдь не первого порядка, а замыкания - это уже асбтракции поверх этих функций...
Поэтому и сопоставлять с ООП некорректно. Оттого, что какой-то технический закидон можно эмулировать и через одно, и через другое?

Ну хорошо, соглашусь, что объекты из ООП могут хорошо имитировать объекты реального мира.
Но, извините! В Оберонах, например, нет объектов, они эмулируются расширяемыми записями. Ну так вполне можно представиить себе, что в направлении программирования, где всё есть функция (т.е. в ФП) объекты реального мира можно имитировать функциями...
Может быть это для Вас непривычно, ну так извините -- записи, пусть даже расширяемые, тоже не для всех привычны в роли объектов... Как тут заметили -- привычки зависят от начального базиса...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Сюда?
СообщениеДобавлено: Вторник, 02 Декабрь, 2008 12:32 

Зарегистрирован: Четверг, 12 Июль, 2007 23:18
Сообщения: 1982
Откуда: Узбекистан, Чирчик
А прикольно написано в англовики:
Цитата:
Because closures delay evaluation—i.e., they do not "do" anything until they are called—they can be used to define control structures. For example, all Smalltalk's standard control structures, including branches (if/then/else) and loops (while and for), are defined using objects whose methods accept closures. Users can easily define their own control structures as well.

Так что эти самые "сферические кложурсы" даже для труЪ-ООП являются важным кирпичом в фундаменте языка...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Сюда?
СообщениеДобавлено: Вторник, 02 Декабрь, 2008 13:00 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 12:02
Сообщения: 8500
Откуда: Троицк, Москва
Geniepro писал(а):
.. Но, извините! В Оберонах, например, нет объектов, они эмулируются расширяемыми записями.
Извинить невозможно. Объект узнается по поведению (полиморфизм etc.), а не по названию.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Сюда?
СообщениеДобавлено: Вторник, 02 Декабрь, 2008 13:34 

Зарегистрирован: Четверг, 12 Июль, 2007 23:18
Сообщения: 1982
Откуда: Узбекистан, Чирчик
Цитата:
Because closures delay evaluation—i.e., they do not "do" anything until they are called—they can be used to define control structures. For example, all Smalltalk's standard control structures, including branches (if/then/else) and loops (while and for), are defined using objects whose methods accept closures. Users can easily define their own control structures as well.

И, кстати, в Хаскелле тоже используется эта техника, как в смоллтоке. Вот, например, кусочек из моей утилитки для кассовых аппаратов, которая мониторит сетевые папки и занимается обменом файлов из сетевых папок в локальные и обратно (эта отдельная утилитка нужна, что бы основное приложение не подвисало на 10-20 сек когда разрывается соединение с серверром):
Код:
moveFiles :: String -> [String] -> String -> IO ()
moveFiles !from !to !hbrf = do
    files' <- getDirectoryContents from
    let files = filter (\fn -> fn /= "." && fn /= "..") files'
    case files of
        [] -> return ()
        _  -> do
            forM_ files $ \fn -> do
                hbr <- case (fn, hbrf) of
                          (_,      "") -> return True
                          ("hb.it", _) -> return =<< doesFileExist hbrf
                          _            -> return True
                let fromfile = from ++ "\\" ++ fn
                ffex <- doesFileExist fromfile
                when (hbr && ffex) $ do
                    forM_ to $ \dir -> do
                        copyFile fromfile $! dir ++ "\\" ++ fn
                    removeFile fromfile
             `E.catch` \err -> print err
Тут тоже циклы типа for и ветвление if-then выполнены в виде функций (forM_ и when), которым передаётся эти самые "сферические кложурсы", представляющие собой тела этих циклов и ветвлений. Единственно, что эти замыкания не выдаются куда-то наружу в качестве результата -- в данной задаче это не нужно...
В смоллтоке такие тела называются сообщениями, в Хаскеле -- замыканиями...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Сюда?
СообщениеДобавлено: Вторник, 02 Декабрь, 2008 16:26 

Зарегистрирован: Четверг, 17 Ноябрь, 2005 11:51
Сообщения: 2935
Откуда: г. Ярославль
Geniepro писал(а):
Иногда это может быть нужно...
Если сравнивать с ООП, то экспортируемые поля объекта тоже как-бы передают наружу некий внутренний смысл...


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

Кажется, есть такое модное течение, "из-под пятницы суббота" - когда девушки выставляют наружу бретельки лифчика. У меня примерно такой образ и всплывает, когда пытаюсь осмыслить closures :)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Сюда?
СообщениеДобавлено: Среда, 03 Декабрь, 2008 00:13 

Зарегистрирован: Воскресенье, 28 Май, 2006 22:12
Сообщения: 1693
Geniepro писал(а):
В смоллтоке такие тела называются сообщениями, в Хаскеле -- замыканиями...

По-моему, в Смолтоке это называется "блоком кода"...
Но они "роднятся" - это - да!
Я думаю, нельзя жёстко замыкаться на одну парадигму... Язык (не доходя до состояния мусорной свалки) ДОЛЖЕН предоставлять возможности по выражению разного рода идей и парадигм... Просто потому, что на основе "возможности выражений" начинают происходит КАЧЕСТВЕННЫЕ изменения в способах осмысления и (опять-таки) возможностей выражения этих идей. И - короче!... :о)
То есть отношение "объем мысли на знак" повышается...
Это - плохо?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Сюда?
СообщениеДобавлено: Среда, 03 Декабрь, 2008 00:16 

Зарегистрирован: Воскресенье, 28 Май, 2006 22:12
Сообщения: 1693
Иван Кузьмицкий писал(а):
Я вот всегда рассматривал локальные переменные, как изолированные от основной программы. Для меня это способ обеспечить безопасность кода.

Просто это другой "угол зрения". Можно и про процедуры, как про объекты думать. СО своими особенными свойствами и их особенным поведением (как на этапе компиляции, так и потом при выполнении)...
Увязка (ПОЛНАЯ!) с "безопасностью" здесь не совсем уместна.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Сюда?
СообщениеДобавлено: Среда, 03 Декабрь, 2008 01:17 

Зарегистрирован: Воскресенье, 09 Март, 2008 22:38
Сообщения: 372
Владимир Лось писал(а):
язык - СИЛЬНО простой... Даже замыканий нет..."


Илья Ермаков писал(а):
не верю я, что у этого пацана есть задачи, которые не решаются просто и красиво обычной структурной декомпозицией. А он клосуры комбинирует

Ребята, срочно поясните, что вы имеете в виду. А то мне в башку, кроме "транзитивного замыкания", ничего не приходит ;)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Сюда?
СообщениеДобавлено: Среда, 03 Декабрь, 2008 07:26 

Зарегистрирован: Четверг, 12 Июль, 2007 23:18
Сообщения: 1982
Откуда: Узбекистан, Чирчик
Владимир Лось писал(а):
Geniepro писал(а):
В смоллтоке такие тела называются сообщениями, в Хаскеле -- замыканиями...

По-моему, в Смолтоке это называется "блоком кода"...
Ну так эти блоки кода отсылаются объектам как сообщения!
Хорошо, заменим слово "называются" на "являются"...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Сюда?
СообщениеДобавлено: Среда, 03 Декабрь, 2008 07:41 

Зарегистрирован: Четверг, 12 Июль, 2007 23:18
Сообщения: 1982
Откуда: Узбекистан, Чирчик
TAU писал(а):
Ребята, срочно поясните, что вы имеете в виду. А то мне в башку, кроме "транзитивного замыкания", ничего не приходит ;)

http://www.rsdn.ru/article/funcprog/fp.xml#E3GAE
http://en.wikipedia.org/wiki/Closure_(computer_science)

кривой источник: http://ru.wikipedia.org/wiki/Замыкание_(программирование)


Последний раз редактировалось Geniepro Среда, 03 Декабрь, 2008 10:33, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Сюда?
СообщениеДобавлено: Среда, 03 Декабрь, 2008 09:37 
Аватара пользователя

Зарегистрирован: Суббота, 29 Март, 2008 19:27
Сообщения: 1053
Откуда: Россия, Чебоксары
Цитата:
Замыкание — это особый вид функции. Она определена в теле другой функции и создаётся каждый раз во время её выполнения. В записи это выглядит как функция, находящаяся целиком в теле другой функции. При этом вложенная внутренняя функция содержит ссылки на локальные переменные внешней функции. Каждый раз при выполнении внешней функции происходит создание нового экземпляра внутренней функции, с новыми ссылками на переменные внешней функции.
Так это что же, это ж было сто лет назад ещё в самом первом описании Паскаля? Про видимость локальных переменных? Вот вроде этого:
Код:
function a(x:integer):integer;
  procedure b;
  begin
    x:=x*2;
  end;
begin
  b; a:=x;
end;
Тогда я не пойму, в чём фишка-то? Просто в удобстве или ещё в чём?

А дальше в википедии идут примеры на странных языках, ни с одним из которых мне сталкиваться не приходилось, и приводятся достаточно тривиальные примеры, совсем не соответствующие приведённому выше описанию... Там делаются всякие достаточно тривиальные макроподстановки комбинаций функций с параметрами... И оно опять сто лет как было в любом макроассемблере ;)

P.S. Вообще, для функционального программирования мозги должны быть как-то странно устроены... По-математически, наверное :lol:
Как лямбда может облегчить мне жизнь, в упор не понимаю... Ну, позволит свернуть кое-что... путём возрастания сложности понимания такой модели... а в целом баланс тот же...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Сюда?
СообщениеДобавлено: Среда, 03 Декабрь, 2008 09:51 

Зарегистрирован: Четверг, 12 Июль, 2007 23:18
Сообщения: 1982
Откуда: Узбекистан, Чирчик
Иван Кузьмицкий писал(а):
Справедливо ли проводить аналогию между имеющими состояние объектами и функциями?

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

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

Ну вот представим себе, что нам нужно создать объект-точку с методами доступа и изменения его внутреннего состояния.
Немного искусственный пример, на Хаскеле так обычно не делается, для этой задачи больше подошёл бы обычный АТД, но просто для демонстрации замыканий попробуем так:
Код:
-- Это описание типа этого "объекта" с перечислением его "методов"
-- В динамически типизируемых ФЯ можно было бы обойтись и без этого определения,
-- но Хаскелл капризничает: дай мне тип, иначе не могу вывести его сам
-- бесконечный цикл в типах образуется...
--
data (Num a) => Point a = Point { getX      :: ()     -> a
                                , getY      :: ()     -> a
                                , setX      :: a      -> Point a
                                , setY      :: a      -> Point a
                                , moveTo    :: (a, a) -> Point a
                                , rMoveTo   :: (a, a) -> Point a
                                }

-- Ну а это своего рода "фабрика объектов", реализующая эти "методы"
--
makePoint (x, y) = Point { getX    = \()           -> x
                         , getY    = \()           -> y
                         , setX    = \newX         -> makePoint (newX,  y  )
                         , setY    = \newY         -> makePoint ( x  , newY)
                         , moveTo  = \(newX, newY) -> makePoint (newX, newY)
                         , rMoveTo = \(dX,   dY  ) -> makePoint (x+dX, y+dY)
                         }
"Методы" являются замыканиями, так как эти функции захватывают в себе значения аргументов функции makePoint.

Теперь надо придумать пример использования этого "объекта". Чем отличаются объекты в ФП-реализации от обычных объектов из ООП, так это тем, что в ФП приходится явно заботиться о поддержании жизни в этих объектах. То есть каждый "метод" этого "объекта", изменяющие его "состояние", на самом деле возвращает копию этого "объекта" с какими-то изменёниями. И вот с этой копией придётся что-то делать, что бы дальше работать уже с ней, а оригинал забыть и отправить в утиль.
Код:
test1 = do
    let p0 = makePoint  (10,  20)
        p1 = p0`moveTo` (30,  50)
        p2 = p1`rMoveTo`(-10, 10)

    print $ p2`getX`()
    print $ p2`getY`()
Этот пример напечатает 20, а затем 60, т.е. сначала создали точку с координатами (10, 20), потом переместили её в координаты (30, 50), а затем сдвинули влево на 10 и вверх на 10. Текущие координаты -- (20, 60).

Тут налицо некоторый синтаксический оверхед по сравнению с ООП.

Попробуем подвигать эту точку в цикле:
Код:
test2 = do
    let loop i n pt | i == n    = pt
                    | otherwise = loop (i+1) n $ pt`rMoveTo`(1, -3)

        p = loop 0 10 $ makePoint (10, 20)

    print (p`getX`(), p`getY`())
Этот пример напечатает (20, -10), т.е. сначала создали точку с координатами (10, 20), а затем 10 раз сдвинули на вправо на 1 и вниз на 3. Текущие координаты -- (20, -10).

Можно сказать, что мы имеем вполне себе объект, у которого есть какие-то спрятанные внутренние поля (инкапсуляция), методы работы с этим объектом, только обращаться с ним с непривычки может быть не так удобно, как в ООП...
Можно даже сказать, что функция -- это синтаксический сахар для объекта, и в то же время объект -- синтаксический сахар для функции. Как любят говорить функциональщики и почему-то Илья Ермаков -- изоморфизм! Разница только в марке сахара... :о)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Сюда?
СообщениеДобавлено: Среда, 03 Декабрь, 2008 09:56 

Зарегистрирован: Четверг, 12 Июль, 2007 23:18
Сообщения: 1982
Откуда: Узбекистан, Чирчик
Alexey_Donskoy писал(а):
Так это что же, это ж было сто лет назад ещё в самом первом описании Паскаля? Про видимость локальных переменных? Вот вроде этого:
Код:
function a(x:integer):integer;
  procedure b;
  begin
    x:=x*2;
  end;
begin
  b; a:=x;
end;
Тогда я не пойму, в чём фишка-то? Просто в удобстве или ещё в чём?

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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Сюда?
СообщениеДобавлено: Среда, 03 Декабрь, 2008 10:03 
Аватара пользователя

Зарегистрирован: Суббота, 29 Март, 2008 19:27
Сообщения: 1053
Откуда: Россия, Чебоксары
Ну как же? Я процитировал определение замыканий из википедии. Один в один про приведённый мною пример на Паскале ;)

Одно из двух, или определение кривое (не отражающее сути), либо всё от лукавого ;)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Сюда?
СообщениеДобавлено: Среда, 03 Декабрь, 2008 10:32 

Зарегистрирован: Четверг, 12 Июль, 2007 23:18
Сообщения: 1982
Откуда: Узбекистан, Чирчик
Alexey_Donskoy писал(а):
Одно из двух, или определение кривое (не отражающее сути), либо всё от лукавого ;)
То, что эта вики-статья кривая, указано в ней самой -- она не завершена...
Англоязычная статья более толковая...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Сюда?
СообщениеДобавлено: Среда, 03 Декабрь, 2008 11:13 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2461
Откуда: Россия, Томск
Alexey_Donskoy писал(а):
Так это что же, это ж было сто лет назад ещё в самом первом описании Паскаля? Про видимость локальных переменных?
Дело не только в видимости локальных переменных, а дело в том, что вложенная функция (closure) имеет к ним доступ даже тогда, когда объемлющая функция уже завершила работу. Вот пример, не так давно пробегавший в рассылке oberon@lists.inf.ethz.ch:
Код:
MODULE ClosureDemo;
IMPORT
   Out;
TYPE
   Printer = PROCEDURE();
VAR
   p, q: Printer;

PROCEDURE CreateNumberPrinter(n: INTEGER): Printer;
     PROCEDURE PrintingProcedure;
     BEGIN Out.WriteInt(n)
     END PrintingProcedure;
BEGIN
     RETURN PrintingProcedure
END CreateNumberPrinter;

BEGIN
   p := CreateNumberPrinter(1);
   q := CreateNumberPrinter(2);
   p; (* prints 1 *)
   q; (* prints 2 *)
END ClosureDemo.
Вот почему в статье говорится о создании новых экземпляров локальных функций, - потому, что надо где-то запомнить контекст конкретного экземпляра PrintingProcedure (под контекстом понимаю весь набор параметров всех объемлющих процедур). На Обероне мы должны создать такой контекст явно, описав его в RECORD, и так же явно должны его проинициализировать:
Код:
MODULE ClosureDemo;
IMPORT
   Out;
TYPE
  Printer = RECORD (* closure context description *)
     n: INTEGER
  END;
VAR
  p, q: Printer; (* memory for 'n' is allocated within the RECORD *)

PROCEDURE (VAR prn: Printer) PrintingProcedure;
(* type-bound procedure (AKA method) executed in the 'prn' context *)
BEGIN Out.WriteInt(prn.n)
END PrintingProcedure;

PROCEDURE CreateNumberPrinter(n: INTEGER): Printer;
VAR res: Printer; (* result *)
BEGIN
  res.n := n; (* initialize the context *)
  RETURN res
END CreateNumberPrinter;

BEGIN
  p := CreateNumberPrinter(1);
  q := CreateNumberPrinter(2);
  p.PrintingProcedure; (* prints 1 *)
  q.PrintingProcedure; (* prints 2 *)
END ClosureDemo.
Обратите внимание, куда переместился параметр "n". Остальной код практически без изменений.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Сюда?
СообщениеДобавлено: Среда, 03 Декабрь, 2008 11:41 
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Geniepro писал(а):
Можно даже сказать, что функция -- это синтаксический сахар для объекта, и в то же время объект -- синтаксический сахар для функции.

Я Вам, батенька, скажу, что вообще все эти штуки (процедуры, обжекты...) сводятся к двум основным понятиям - алгоритму и процессу его выполнения.

Цитата:
Как любят говорить функциональщики и почему-то Илья Ермаков -- изоморфизм! Разница только в марке сахара... :о)

А почему бы мне не любить... Человеку с дипломом математика не нужно изучать ФП для того, чтобы это знать.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Сюда?
СообщениеДобавлено: Среда, 03 Декабрь, 2008 13:15 
Аватара пользователя

Зарегистрирован: Суббота, 19 Ноябрь, 2005 15:59
Сообщения: 803
Откуда: Зеленоград
Geniepro писал(а):
Можно даже сказать, что функция -- это синтаксический сахар для объекта, и в то же время объект -- синтаксический сахар для функции. Как любят говорить функциональщики и почему-то Илья Ермаков -- изоморфизм! Разница только в марке сахара... :о)
Наверное, где-то так. :)
Эта ветка началась с того, что молодое дарование взгрустнуло, что язык (КП) "сильно простой... даже замыканий нет...". Дядя Володя Лось тут же начал рефлексировать по этому поводу.
Однако, возник естественный вопрос: что нам могут дать замыкания по сравнению с объектами.
Пока максимум предложенного - "синтаксический сахар", и тот - иногда (порой - прямо наоборот).
Кто-нибудь хочет, чтобы Оберон пустился в погоню "за сладким"?
Ведь, в крайнем случае, когда захочется сахарку, есть целый кондитерский отдел других языков... :)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Сюда?
СообщениеДобавлено: Среда, 03 Декабрь, 2008 13:36 

Зарегистрирован: Четверг, 12 Июль, 2007 23:18
Сообщения: 1982
Откуда: Узбекистан, Чирчик
AVC писал(а):
Кто-нибудь хочет, чтобы Оберон пустился в погоню "за сладким"?
Это явно будет не в духе оберонов... :wink:


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 172 ]  На страницу Пред.  1, 2, 3, 4, 5 ... 9  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2025, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB