LINUX.ORG.RU

Вышел 2-й выпуск журнала «Практика функционального программирования»

 , , ,


1

0

Вышел в свет второй выпуск журнала «Практика функционального программирования».

Центральная тема второго выпуска журнала — демонстрация применения функционального программирования в реальных, а не академических проектах.

Первые четыре статьи — Дмитрия Зуйкова, Дмитрия Астапова, Сергея Зефирова в соавторстве с Владиславом Балиным, и Алексея Отта — вытаскивают на поверхность «кухню» нескольких компаний. Статьи демонстрируют, что функциональные языки находят применение в промышленном программировании в самых разных нишах. Конечно, использование «нестандартных» языков накладывает на проекты некоторые сложно оценимые риски, и далеко не все из них рассмотрены в статьях. Но если статьи этого номера позволят развеять хоть часть сомнений, мифов и предрассудков и поднять дискуссию о применимости функциональных языков в промышленном программировании на новый уровень, мы будем считать свою задачу выполненной.

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

Завершающая статья Романа Душкина в большей степени ориентирована на теорию: она познакомит вас с концепцией алгебраических типов данных (АТД) в Haskell и других функциональных языках.

>>> Подробности

★★★★★

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

> А зачем ты при этом хочешь чтобы это был один объект с двумя состояниями? Ты можешь это откатить? Ты представь какой ужас с точки зрения валижной инвариантности - уже три приведенных состояния (целые, разбиты, пожарены) - это просто немеряно надо контрактов энкапсулировать чтобы проконтролировать валидность транзишена этих объектов. Что жаренные не могут быть неразбитыми, или стать обратно целыми. Это ж целый жизненный цикл - немеряно кода.

Тебе точно также надо это контролировать и в фп (например, в функции broke нужно контролировать, чтобы были поданы вход именно сырые яйца, если они сырые, то так их и оставить, и тд, а вот жаренные не пройдут; в функции нагревания тебе нужно контролировать была ли нагрета до этого сковорода или нет - чтобы не нагреть ее еще раз). Ну не различаются в этом отношении функциональная и императивная парадигма. Они отличны в самом понимании процесса вычислений - для фп - всякая программа - это вычислительный процесс в его математическом понимании (фукнция, которую можно сколько угодно раз вычислять, она будет всегда давать один и тот же результат; объекты (entity) - числа, отличающиеся только своим значением, т.е. не чисел 7 - только одно, и одно число 7 не отличается от другого числа 7, и нельзя его изменить, оно всегда существует и существовало до это в математической вселенной, можно только получить из одного числа другое - функции), в императивном же - все не так - там как в жизни - одно яйцо отличается от другого и их не одно в императивной вселенной - а множество, причем ограниченное, и каждое обладает состоянием, можно одно яйцо разбить, а другое оставить сырым, состояние и identity представляют собой вместе не что иное, как деструктивное присваивание.

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

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

Ты похоже в корне не понимаешь каким свойствами обладает состояние и какие с этим связаны проблемы. При чем тут нужно ли проверять это в функциях? В жизни ты можешь точно так же попытаться пожарить яйца не разбивая их.

После того как ты разобьешь яйцо - ты не можешь нарушить его инвариант в жизни. Ну никак!!! Все баста!

Точно так же
e <- broke Egg Raw = Egg Broken

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

А в императивной модели я злобно пишу e.state = целое - и обана - яйцо целое!

Это что - не очевидно?


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

> в императивной модели я злобно пишу e.state = целое - и обана - яйцо целое!

> Это что - не очевидно?

Это просто клевета.

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

> А в императивной модели я злобно пишу e.state = целое - и обана - яйцо целое!

Это легко обходится, но конечно же, не в ужасной яве. На остальное завтра отвечy, когда протрезвею и приду в себя.

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

set_state?

Возражения:

1. В хаскельном коде ты в принципе ничего не сделаешь значению, точно так же как не можешь ничего сделать со значением x = 2 (тут к стати напрашивается вопрос - почему обращение с примитивным данными в таком виде естественно, а возможность создавать такие типы самому звучит странно? Вы ж не задаетесь вопросом в коде x = 2 + y / b что это за указатели и чего там за объекты и в каком они состоянии? И уже почти не задаетесь вопросами в "aaaa" + "bbbb". И практически уже не беспокоитесь что собственно с объектом range в for x in xrange(1,10).... Так почему же долбаные яйца нужны вам с состоянием? Покажите мне хоть один плюс этого.

2. Что насчет "внутри" скоупа в котором определен set_state? Там ничего плохого с this.state случится не может разве? - это про этот момент я говорил к про договор программиста сам с собой. Инкапсуляция для проверки инвариантов это как раз такой договор. Я сам с собой договорюсь что в этом скоупе я разрушать ничего не буду - и ладушки?:)

3. Я злобный рефлективный интроспектор....прячусь в параллельном треде и жду своего часа чтобы сделать setAccessible(true) и...муа-ха-ха....

PS: серьезные только первые 2:)

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

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

Дык, это проблемы, которые решает статическая типизация. Парадигма тут может и не важна на первый взляд, но вот конкретно хаскель в сравнении скажем с жабой выигрывает благодаря более развитой системе типов и отсутствию сайд-эффектов. То есть, выходит, что парадигма всё-таки важна, ещё и как. Вопрос ведь не в том, можно ли отстрелить себе ногу. Это можно всегда и везде. Вопрос в том, как максимально защититься от таких выстрелов. Тут ФП языки со статической типизацией явно превосходят всё иное. О чём r и талдычит уже не первую страницу.

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

После того как ты разобьешь яйцо - ты не можешь нарушить его инвариант в жизни. Ну никак!!! Все баста!

ага

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

А в императивной модели я злобно пишу e.state = целое - и обана - яйцо целое!

Это что - не очевидно?

Нет.

Вот реализация яйца, которое нельзя из скорлупы превратить в целое.

class Egg(object):                                                             
    def __init__(self):                                                        
        self._states = ['raw', 'broken', 'fried', None]                        
                                                                               
    @property                                                                  
    def state(self):                                                           
        return self._states[0]                                                 
                                                                               
    @state.setter                                                              
    def state(self, value):                                                    
        if value and value == self._states[1]:                                 
            self._states.pop(0)                                                
        else:                                                                  
            raise AttributeError ("wrong state")                               
                                                                               
    def break_eggs(self): self.state = 'broken'   

>>> e = Egg()                                                                  
>>> e.state                                                                    
'raw'                                                                          
>>> e.state = "foo"                                                            
Traceback (most recent call last):                                             
  File "<stdin>", line 1, in <module>                                          
  File "/tmp/python-29636EdM.py", line 14, in state                            
AttributeError: wrong state                                                    
>>> e.state = 1                                                                
Traceback (most recent call last):                                             
  File "<stdin>", line 1, in <module>                                          
  File "/tmp/python-29636EdM.py", line 14, in state                            
AttributeError: wrong state               
>>> e.state = "broken"                                                         
>>> e.state = "raw"                                                            
Traceback (most recent call last):                                             
  File "<stdin>", line 1, in <module>                                          
  File "/tmp/python-29636EdM.py", line 14, in state                            
AttributeError: wrong state          
>>> e.state                                                                    
'broken'                                                                       
>>> e.state = "fried"                                                          
>>> e.state                                                                    
'fried'                                                                        
>>>                

Думаю полностью код приготовления яичницы (омлета) приводить не стоит?

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

> точно так же как не можешь ничего сделать со значением x = 2

> Вы ж не задаетесь вопросом в коде x = 2 + y / b что это за указатели и чего там за объекты и в каком они состоянии?

Да блин, потому что это числа, у них нет никакого состояния, я это уже не раз повторял.

> И практически уже не беспокоитесь что собственно с объектом range в for x in xrange(1,10)

Я не беспокоюсь, но x там каждую итерацию мутирует :)

> Что насчет "внутри" скоупа в котором определен set_state? Там ничего плохого с this.state случится не может разве? - это про этот момент я говорил к про договор программиста сам с собой. Инкапсуляция для проверки инвариантов это как раз такой договор. Я сам с собой договорюсь что в этом скоупе я разрушать ничего не буду - и ладушки?:)

Это иллюзия, скажите спасибо гипножабе.

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

> Дык, это проблемы, которые решает статическая типизация.

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

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

Вот конкретно хаскель выигрывает у жабы за счет таких мощных вещей как ADT, pattern matching, HOF и list comprehansion - он просто содержит больше более высокоуровневых абстракций, чем жаба.

> Вопрос ведь не в том, можно ли отстрелить себе ногу. Это можно всегда и везде. Вопрос в том, как максимально защититься от таких выстрелов.

Вопрос в том, что фп, immutable data and pure functions overrated. Писать говеные программы на хаскелле точно также легко, как и на любом другом языке.

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

> приводить не стоит?

В приведённом выше коде уровень bondage and discipline вплотную приблизил яйцо к классу неизменяемых объектов.

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

> Да блин, потому что это числа, у них нет никакого состояния, я это уже не раз повторял.

Почему это верно для чисел и ложно для пользовательских (в т.ч. алгебраических) типов данных?

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

>Думаю полностью код приготовления яичницы (омлета) приводить не стоит?

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

PS:

>>> e = Egg()

>>> e.state = "broken"

>>> e._states.insert(0,"raw")

>>> e.state

'raw'

Хочу нобелевскую премию.



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

Да блин, потому что это числа, у них нет никакого состояния, я это уже не раз повторял.

Серьезно?

>>> class N:
...     def __init__(self, n):
...         self.n = n
...     def prev(self):
...         self.n -=1
...     def succ(self):
...         self.n +=1
...
>>> n = N(5)
>>> n.succ()
>>> n.n
6
>>> n.prev()
>>> n.prev()
>>> n.n
4

ОМГ числа с состоянием! Куда катится мир!

Я не беспокоюсь, но x там каждую итерацию мутирует :)

Откуда ты знаешь?

Это иллюзия, скажите спасибо гипножабе.

Серьезно? Тебе дописать в питоне миетод который напакостит в реальность (помимо того способа что я указал)? Еще открой для себя в других языках концепцию open classes.

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

> Это было бы весьма интересно. Думаю ты обнаружил бы много интересностей о которых я говорил.

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

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

> Хочу нобелевскую премию.

За то, что поднакопил денег, сходил в оружейный магазин, купил пистолет и выстрелил в голову? Ну ничего можно сделать более железобетонно через __setattr__, но тогда конечно же останется лазейка self.__dict__[name], ведь тебя ничего не удержит от самоубийства? :)

Кстати, что там с unfry, или "так нельзя" менять функции? :)

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

> Серьезно?

Разницу между объектом в смысле оо программирования и числом в математике улавливаешь? Ты просто создал класс объектов, состояние которых описывается одним числом, ну и добавил парочку методов. Кстати, какое состояние у числа 42, кстати, что вообще такое состояние числа? :)

> Серьезно? Тебе дописать в питоне миетод который напакостит в реальность (помимо того способа что я указал)? Еще открой для себя в других языках концепцию open classes.

Да не надо, там же можно в динамике переопределить класс объекта, его методы, поля, даже immutable tuple можно поменять.

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

Добрались до практики, и сразу стало всё хорошо видно. Сравните выразительность:

class Egg(object):
    def __init__(self):
        self._states = ['raw', 'broken', 'fried', None]

    @property
    def state(self):
        return self._states[0]

    @state.setter
    def state(self, value):
        if value and value == self._states[1]:
            self._states.pop(0)
        else:
            raise AttributeError ("wrong state")

    def break_eggs(self): self.state = 'broken'
data EggState = Raw | Broken | Fryed deriving (Show)
data Eggs = Eggs EggState Int deriving (Show)

break (Eggs Raw x) = Eggs Broken x
break e@(Eggs Broken x) = e -- yahh, already broken
break _ = error "you mean 'again'?"
fry (Eggs Broken x) p@(Pan Hot Oiled) = (Eggs Fryed x, p)
fry _ (Pan Hot Oiled) = error "what are you gonna do with these eggs?"
fry _ _ = error "on _that_ pan?"
Код на Хаскелле читается, как рассказ.

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

Ну и замечение по реализации: а если будут ещё и варёные яйца?

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

>Каких - о том, что нельзя произвольно менять код функции и она бы при этом оставалась рабочей?

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

>За то, что поднакопил денег, сходил в оружейный магазин, купил пистолет и выстрелил в голову?


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

>ведь тебя ничего не удержит от самоубийства? :)


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

>Кстати, что там с unfry, или "так нельзя" менять функции? :)


Написал ты свою функцию вне библиотеки. Покажи мне как что-то сломалось.

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

>Разницу между объектом в смысле оо программирования и числом в математике улавливаешь?

Я пока так и не уловил что даем мне яйцо в "стиле ОО". Как на счет ответить на этот вопрос?

>Кстати, какое состояние у числа 42, кстати, что вообще такое состояние числа? :)


Его значение. Мало? Могу дофига придумать - история его изменени и всяка ятакая фигня. Сначала у меня было X денег. Потом стало Y. Я купил на это товары A,B,C по такой-то стоимости и подал ничему. Что - сложно представить как это все инкамсулируется в 1 объект?

В чем разница? Раскрой тему что я выиграю от представления яйца объектом.

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

> Код на Хаскелле читается, как рассказ.

Бугага. Кто там говорил об обучении? %)

P.S. подозреваю, что на Ocaml то же самое действительно читалось бы, как рассказа ;)

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

> Его значение. Мало? Могу дофига придумать - история его изменени и всяка ятакая фигня. Сначала у меня было X денег. Потом стало Y. Я купил на это товары A,B,C по такой-то стоимости и подал ничему. Что - сложно представить как это все инкамсулируется в 1 объект?

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

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

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

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

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

> Нет - ты бы обнаружил что в общем суть твоей работу свалась бы к ограничению и удалению императивных свойст которые ты так защищаешь

Ты функциональное программирование почему-то пытаешься противопоставить boilerplate код - что-то вроде ассемблера, где каждый может все изменить, а не реально императивное программирование. Я за модульность, сокрытие реализации и прочие прелести - функциональность сильно способствует модульности (каждая чистая функция оказывается отрезанной от внешнего мира и не может на него повлиять, и он на нее не может), я в этом отношении с фп, но эту же модульность можно достигнуть не только с помощью иммутабельных данных и чистых функций. Те же лексические замыкание невозможны без присваивания, они как раз позволяют создать "железобетонное" сокрытие реализации и еще один уровень абстракции поведения. Функция rand не является чистой функцией, - а я себе с трудом представляю практическое программирование без нее. С другой стороны всем известны проблемы со скрытым изменением состояния. Для параллельного программирования выгода от иммутабельных данных однозначна, однако есть же STM, которая проблему для мутабельных данных решает. Чистота должна быть там, где она уместна, также как и использование императивности должно быть уместно.

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

> Код на Хаскелле читается, как рассказ.

потому что там есть ADT и pattern matching, а питон динамический и в нем даже repaet until нет, не говоря уже о том, что циклы там приходится писать с помощью for x in xrange(10).

> Ну и замечение по реализации: а если будут ещё и варёные яйца?

Как смоделируешь, так и будет.

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

Вспоминается анекдот:

В: Мальчику Васе дали 3 яблока. 1 он съел. Сколько яблок у Васи?

О: Неизвестно, т.к. чёрт его знает сколько у Васи было яблок до этого.

Но это не правильный ответ, на самом деле у Васи lambda.x x-2 яблока.

P.S. Почто на лоре подстановка &lambda; не работает?

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

> Но это не правильный ответ, на самом деле у Васи lambda.x x-2 яблока.

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

λfx.x -> 0

λfx.f x -> 1

λfx.f (f x) -> 2

λfx.f (f (f x)) -> 3

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

>> Ну и замечение по реализации: а если будут ещё и варёные яйца?

> Как смоделируешь, так и будет.

Я имел в виду, что "красивое" решение со стеком в общем случае не подходит.

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

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

> λfx.x -> 0

> λfx.f x -> 1

> λfx.f (f x) -> 2

> λfx.f (f (f x)) -> 3

Числа Чёрча. В Хаскелле всё ок, они не такие. :)

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

> Числа Чёрча. В Хаскелле всё ок, они не такие. :)

Да, но это ни коем образом не влияет на их полностью абстрактную сущность.

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

>Число - это совершенно абстрактное понятие,

У тебя сколько денег на счету? Не поделишься абстракцией?

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


По твоему наличие яиц в холодильнике не описательная характеристика?

Вот забавно откуда беруться люди которые делят вещи на реальные и абстрактные. Уход совершенно абстрактных чисел с твоего счета совершенно реально оставит тебя без яичницы и кровати.

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

>Ты из тех людей, что в микроволновке сушат котов?

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

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


Любой инструмент которым можно воспользоваться неправильно - будет использован неправильно. Дальше все сводится к удобству инструмента.

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

>а не реально императивное программирование.

Реально императивное программирование обладает реально императивными свойствами - ключевое из которых - мутация состояния. Если исключить это ключевое ствойство - это уже _не_ императивный подход. В который раз - не надо путать "императивный" язык и императивный подход. Ту же яишницу можно написать на С так что там не будет ничего императивного,

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

> Реально императивное программирование обладает реально императивными свойствами - ключевое из которых - мутация состояния.

Скорее уж не мутация состояния, а концепция инструкции, пошагового вычисления (которое, конечно, изменяет состояние, но и функциональные программы тоже могут иметь дело с состояниями).

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

>Скорее уж не мутация состояния, а концепция инструкции, пошагового вычисления

Без состояния - визуально неотличимо от функционального подхода.

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

> У тебя сколько денег на счету? Не поделишься абстракцией?

213111,00

> Вот забавно откуда беруться люди которые делят вещи на реальные и абстрактные.

Потому что линейка реальна, а ее длина - абстрактна, это количественная характеристика.

> По твоему наличие яиц в холодильнике не описательная характеристика?

Описательная.

> Уход совершенно абстрактных чисел с твоего счета совершенно реально оставит тебя без яичницы и кровати.

Я тебе сказал число, давай "меняй" его - разоряй меня.

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

> Реально императивное программирование обладает реально императивными свойствами - ключевое из которых - мутация состояния. Если исключить это ключевое ствойство - это уже _не_ императивный подход.

Каждый раз, когда я использую монаду State в хаскелле - я использую императивный подход, но ведь хаскелл чисто-функциональный, как такое возможно? :)

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

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

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

> Любой инструмент которым можно воспользоваться неправильно - будет использован неправильно. Дальше все сводится к удобству инструмента.

Кухонным ножом можно зарезать - запретим ножи?

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

> Каждый раз, когда я использую монаду State в хаскелле - я использую императивный подход, но ведь хаскелл чисто-функциональный, как такое возможно? :)

Что тебя беспокоит?

В одном и том же коде можно увидеть разные абстракции. Вот, например, монада Maybe на C: http://www.reddit.com/r/programming/tb/1761q Естественно, можно там видеть просто сишную структуру и набор функций.

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

>я использую императивный подход

Ты не используешь имепретивный подход. Оператор >>= типкласса Monad по сути дела оператор функциональной композиции. А do-нотация всего лишь удобный способ представления цепочек >>= и >>.

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

> Ты не используешь имепретивный подход. Оператор >>= типкласса Monad по сути дела оператор функциональной композиции. А do-нотация всего лишь удобный способ представления цепочек >>= и >>.

Я то знаю, что я его не использую, вы объясните это товарищу r.

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

> Каждый раз, когда я использую монаду State в хаскелле - я использую императивный подход, но ведь хаскелл чисто-функциональный, как такое возможно? :)

Я поэтому выше и отметил, что центром императивного подхода является шаг, инструкция — «statement».

А Monad State управляется вполне функционально.

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

> Что тебя беспокоит?

То, что r дает некорректные определения, на мой взгляд.

> например, монада Maybe на C: http://www.reddit.com/r/programming/tb/1761q

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

Там именно, что сишная структура и набор функций, которые реализуют определенную абстракцию (в данном случае монаду).

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

> Я поэтому выше и отметил, что центром императивного подхода является шаг,

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

> инструкция — «statement».

под statement обычно понимается if-then-else и сотоварищи. В хаскелле и не только этих statement навалом.

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

> А Monad State управляется вполне функционально.

Я это знаю.

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

> Я уже говорил, что с таким подходом, мы приходим к тому, что у нас императивными будут только assembler да машинный код.

Большинство императивных языков унаследовали это от языков ассемблера (а что делать, «не мы такие, машина такая» :) Конечно, появились абстракции, но семантика осталась. Здесь идут исключением некоторые языки вроде Smalltalk.

> под statement обычно понимается if-then-else и сотоварищи. В хаскелле и не только этих statement навалом.

В ИП if-then[-else] — это просто высокоуровневый аналог jz/jnz. В ФП — это аналог математического определения, например, модуля числа: x = if x>=0 then x else -x. Там нельзя выполнить действие.

Может, я просто неправильно понимаю, что означает statement.

А вообще-то нет: http://en.wikipedia.org/wiki/Statement_%28programming%29

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

>213111,00

Поделиться - в данном случае было фактически - а не "информацией".

>Потому что линейка реальна, а ее длина - абстрактна, это количественная характеристика.


Твоя линейка для меня не абстрактна? Серьезно?!?

>Я тебе сказал число, давай "меняй" его - разоряй меня.


При чем тут кто? Дай характеристику свойств абстрактных объектов и реальных в кеоторых они различаются и по чем ты их разделил.

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

> В ИП if-then[-else] — это просто высокоуровневый аналог jz/jnz. В ФП — это аналог математического определения, например, модуля числа: x = if x>=0 then x else -x. Там нельзя выполнить действие.

[code] Prelude> let func x = if x > 0 then putStrLn "Yes" else putStrLn "No" Prelude> func 4 Yes Prelude> func (-5) No [/code]

? :)

case-statement в do? - это не конструкция? Только не надо говорить, что это синтаксический сахар, я это и так знаю.

> А вообще-то нет: http://en.wikipedia.org/wiki/Statement_%28programming%29

Ну если следовать их логике, а она у них какая-то ну совсем противоречивая, ты тоже не прав. Вот тут.

> Я поэтому выше и отметил, что центром императивного подхода является шаг, инструкция — «statement».

Потому как в например, common lispe вообще нет statements - однако это императивный язык (там есть setf и прочие императивные прелести).

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

> Ты не используешь имепретивный подход. Оператор >>= типкласса Monad по сути дела оператор функциональной композиции. А do-нотация всего лишь удобный способ представления цепочек >>= и >>.

Я думаю, разруха^Wимперативный подход в головах. Можно в do-нотации видеть императивный код, хотя это, на самом деле, функциональная композиция. Разные теории могут давать разные модели одного и того же. Но, конечно же, не все модели одинаково удобны. :)

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

>Каждый раз, когда я использую монаду State в хаскелле - я использую императивный подход,

Монада как раз изолирует изменение с целью создать чистоту. В то время как императивное изменение - имеет целью создать сайд эффект. Монада стейт "добавляет параметр" в функцию и "передает дополнительный результат как параметр" в следующую. Это "эмуляция" императивщины.

Грубо говоря сахар для

(b, s1) = f(a, s)
(c, s2) = g(x, s1)
(d, s3) = z(y, s2)

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

> Там именно, что сишная структура и набор функций, которые реализуют определенную абстракцию (в данном случае монаду).

Там набор буков. :-D

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

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

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

>Кухонным ножом можно зарезать - запретим ножи?


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

Как только ищобретут нож которым можно нарезакть колбаску но нельзя зарезать - ты удивишься куда денуться обычные ножи из обихода.

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

>Объект - это то, что обладает identity и состоянием. Яйцо - это реальный предмет, а число - это абстракция (просто по определению).

Ну так дай ты определение императивного подхода. А то пока не видно ни одного.

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

> [code] Prelude> let func x = if x > 0 then putStrLn "Yes" else putStrLn "No" Prelude> func 4 Yes Prelude> func (-5) No [/code]

> ? :)

> case-statement в do? - это не конструкция? Только не надо говорить, что это синтаксический сахар, я это и так знаю.

Case — это тоже не императивный оператор (или что имеется ввиду под "конструкцией"?), это расширенная if. Вспомните определение модуля: можно случай x = 0 вынести в третью ветку определения, вот и будет вам case.

> Ну если следовать их логике, а она у них какая-то ну совсем противоречивая, ты тоже не прав.

Почему? В смысле что не так описано в Википедии?

> Потому как в например, common lispe вообще нет statements - однако это императивный язык (там есть setf и прочие императивные прелести).

Lisp — это вообще отдельная тема :) Языки лисп-семейства не императивны по сути (равно как и не строго функциональны).

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

>Я уже говорил, что с таким подходом, мы приходим к тому, что у нас императивными будут только assembler да машинный код.

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

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

> Почему? В смысле что не так описано в Википедии?

Там пишется, что оператор вроде как не возвращает значения, в отличие от выражения, однако в тех же сях functions и assignment, запятая таки возвращают значение, и присваивание я, например, могу засунуть в математическое выражение. Кроме того, про лисп пишется, что там дескать нет операторов, хотя там есть те же самые if, do, prog*, setq которые являются специальными формами и по всем статьям должны быть операторами. И к тому же есть в сях есть гнутое расширение, которое из блока кода делает выражение [1], чем оно принципиально отличается от progn, мне вообще непонятно.

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

[1] http://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html#Statement-Exprs

> Lisp — это вообще отдельная тема :) Языки лисп-семейства не императивны по сути (равно как и не строго функциональны).

Лисп (CL) - он императивный по сути, но там ему много чего осталось в наследство от старых функциональных лиспов, да.

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

> Ну так дай ты определение императивного подхода. А то пока не видно ни одного.

Это прямое использование фреймовой (не подстановочной, referentialy opaque) модели вычислений в программе, т.е. если где-то в программе используется деструктивное присваивание, а значит там есть identity и состояния. Это не значит, что программа вся целиком состоит "присваиваний", это не значит, что она не модульная, это не значит, что она должна быть похожа на сишный boilerplate, это не значит, что в ней не могут использоваться pattern matching, high-order functions, anonymous functions и все остальное. (Я эти слова уже пишу раз десятый, но я терпеливый, когда-нибудь ты поймешь:))

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

> - потому что в микроволновке котоов нельзя сушить не потому что их сушить нельзя в принципе - а потому что их сушат изх неверных предпосылок думая что микроволновка это "фен". Я действую из понимания что там происходит. От того что я понимаю что там происходит не проистекает что это хороший способ писать программы.

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

> Твоя рекомендация - это рекомендация вида "чтобы стружка от токарного станка не попала в глаз - не подставляй глаз". Моя - вида "надень очки" (создай систему типов где такое не возможно).

Отличный пример, то, что сделал ты - снял очки и подставил глаз. Хошь я тебе на CL напишу - там есть возмножность скрыть реализацию, или ты мне на слово поверишь?

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

> Поделиться - в данном случае было фактически - а не "информацией".

Получается, что мой счет реален, а вот число, которое его описывает - абстрактно.

> Твоя линейка для меня не абстрактна? Серьезно?!?

Нет конечно, можешь подъехать ко мне, я тебе дам ее потрогать и повертеть в руках, чтобы ты полностью убедился в ее реальности. А вот представление о ней вполне может быть абстрактным. Вот мне интересно, для тебя путин с медведевым абстрактны или нет?

> При чем тут кто? Дай характеристику свойств абстрактных объектов и реальных в кеоторых они различаются и по чем ты их разделил.

Ну тут мы с тобой далеко зайдем :), туда куда я заходить не хочу. Ты лучше напиши, что ты хотел этим вопросом показать, ведь ты же куда-то ведешь. Хотя я предположу, возможно даже неправильно, но ты если что поправь меня.

Ты, наверное, хочешь показать, что яйцо - это абстракция, по крайней мере в нашей программе и нам без разницы взяли мы какое-то конкретное или нет, главное, чтобы оно было "правильного" типа RawEgg, и получили бы на выходе Omlet - не какой-то конкретный, а совершенно абстрактный омлет. А если бы мы хотели поработать с более "конкретными" (и посему менее абстрактными) яйцами, мы бы в описание типа добавили существенные для нас характеристики - вес, цвет, конкретное место в холодильнике, возможно даже номер и прочее, а на выходе из функции получили бы более конкретный омлет - с определенным весом, консистенцией и тд. Я прав?

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

>Это прямое использование фреймовой (не подстановочной, referentialy opaque) модели вычислений в программе

Ты можешь привести чью нить ссылку которая определяет императивную модель через фреймы или типа претьендуешь на оригинальность?

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

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

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

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

>Хошь я тебе на CL напишу - там есть возмножность скрыть реализацию, или ты мне на слово поверишь?


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

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

>Получается, что мой счет реален, а вот число, которое его описывает - абстрактно.

Счет твой никуда не делется - там абстракции станет меньше. К стати! Банкомат вообще мистическая машина - превращает абстракции в реальность нажатием простых кнопок - прямо шутки Калиостро какие-то:)

>Вот мне интересно, для тебя путин с медведевым абстрактны или нет?


Для меня слово "абстракция" соответствует тому что понимал под ним аристотель, а не ССР. Так что два вопроса - 1) почему програмное яйцо для тебя реально, 2) что вообще кому-нибудь кодга-нибудь давало представление объектов реального мира с "проецированием" их свойств конкретно в программировании (конкретно - что ты выиграл представив яйцо объектом с состоянием) - остаются открытыми.

>Ну тут мы с тобой далеко зайдем :), туда куда я заходить не хочу.


Фига се. Это принципиальный вопрос. Ты разделил объекты на 2 категории, отстаиваешь правоту своего деления, но даже обосновать его не хочешь.

>Ты лучше напиши, что ты хотел этим вопросом показать, ведь ты же куда-то ведешь.


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

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


В следствие чего:

Действительная реальность - не имеет никакого значения - мы ее воспринять не в состоянии.

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

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


>Я прав?


Частично. См. выше.



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

> Действительная реальность - не имеет никакого значения - мы ее воспринять не в состоянии.

Такой подход не очень полезен в программировании. Вон Страуструп постоянно пишет о моделировании реальности.

________________________________________________

Попытки наехать на state для меня выглядят... ну мягко скажем бесперспективными.

Состояние существует... эээ... почти что объективно (ну насколько можно говорить об объективности в данном контексте).

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

И опять же соглашусь с анонимусом о наличии двух типов объектов -- реальных с состоянием и "идеальных" (чисел, ...), как раз для ФП.

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

2 anonymous

Любой алгоритм оперирует абстрактными понятиями. Рецепт приготовления омлета из конкретных яиц не нафиг нужен никому - он одноразовый. Даже если мы учитываем вес и цвет яиц, они всё равно в алгоритме будут абстрактные.

Абстрактное мышление, насколько я знаю, врождённым для человека не является. Но его развитию способствует язык - мы все думаем на каком-то языке, называя конкретные вещи абстрактными именами. И именно абстрактное мышление сделало из обезьяны человека. :)

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

>Попытки наехать на state для меня выглядят... ну мягко скажем бесперспективными.

Я пока не увидел ни одной успешной попытки обосновать _необходимость_ стейта в этой задаче. Все попытки сведены к "а вы реальности оно вот такое". А это "как обоснование" даже Платон бы разнес в клочья.

>Состояние существует... эээ... почти что объективно


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

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


Вон яишницу без состояния заделали раньше на сковороде без состояния.

>И опять же соглашусь с анонимусом о наличии двух типов объектов -- реальных с состоянием и "идеальных" (чисел, ...)


Угу - в программах реальных яиц просто немеряно.

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

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

> Вон яишницу без состояния заделали раньше на сковороде без состояния.

И тебе не скучно такой *бред* писать? (К слову, некоторые твои мысли бывают очень интересны).

1. Я, когда предложил написать программу яишницы, подумал, что надо самому бы написать императивный вариант, но при моей температуре меня хватило только на треп. Я кстати и сейчас соображаю на 30% от номинала.

2. "Если ... именем." -- это и есть обоснование полезности рассмотрения состояния. Я понимаю, что тему тут можно раскрыть глубже, но это скучно, и вероятность, что ты найдешь у меня существенную ошибку я оцениваю на уровне 5%. А так как для меня имеет смысл в основном то, когда у меня находят ошибку... короче, будем продолжать дискуссию? тебе интересно?

3. Задача про яишницу сформулирована слишком неточно, чтобы тут точно что-то доказать.

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

В треде я сделал 1-2 наезда на ФП, вот в них-то вероятность меня поймать чуть ли не 50%, так что там гораздо интереснее. Правда, мне еще нужно время, чтобы выйти на номинальную мощность и как следует их сформулировать.

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

>3. Задача про яишницу сформулирована слишком неточно, чтобы тут точно что-то доказать.

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

Вариант А: смотрим о чем предметная область и создаем "объекты предметной области" отвечающие на вопрос "is a" и их свойства "has a". Из этого проистекает ООПшная модель с состояниями.

Вариант Б: представить с какими данными предметной области мы будем иметь дело, категоризировать их и описать как абстрактные данные - это было сделано выше на хаскеле - такая себе штука вроде "алгебры".

Последний вариант предполагает составление абстрактной модели, установления ее ограничений и инвариантов. Первый - проще. У меня человек рядом на работе сидит который не колеблясь выберет первый - седня у нас вышел спор на тему "все люди как люди пишут антовские скрипты для каждого проекта и ничего vs моего "в котором надо разбираться" мегаскрипта (который получился очень маленьким( но построен вокруг определенной модели, а не "надо скопировать файл пишем команду копи", и один скрипт собирает штук 50 разных многомодульных проектов". Спор кончился в момент когда я ему показал проект из 25 модулей и спросил - "ты предлагаешь 25 одинаковых скриптов написать?"

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

Мне не интересно решение вида "о чем? о яйцах? так class Яйцо.. разбитое? так поле разбитое метод разбить". Ну извините.

PS: "абстрактные числа" появились когда людям надоело перекладывать "реальные камушки" для счета. Подумайте об этом.


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

> Спор кончился в момент когда я ему показал проект из 25 модулей и спросил - "ты предлагаешь 25 одинаковых скриптов написать?"

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

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

> Мне не интересно решение вида "о чем? о яйцах? так class Яйцо.. разбитое? так поле разбитое метод разбить". Ну извините.

А здесь именно такая ситуация. "так class Яйцо"

> PS: "абстрактные числа" появились когда людям надоело перекладывать "реальные камушки" для счета. Подумайте об этом.

Мне достаточно близки идеальные объекты (да, кивок в сторону Платона, а слово "абстрактные" не так удачно, ибо несколько занято) и нравятся функциональные структуры данных (сохраняющие всю старую историю).

Но в данном случае как раз уместно обсудить когда нужны реальные, а когда идеальные объекты.

И подумать можно не о числах, а о более интересных вещах. В частности, о *мутабельных* классе Прямоугольник и его подклассе Квадрат. Если мы сделаем объект Прямоугольник мутабельным, но запретим иметь на него несколько ссылок (точно так же, как число 1 мутабельно, но на него несколько ссылок быть не может) то вроде бы решим известную проблему. Так?

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

> Но в данном случае как раз уместно обсудить когда нужны реальные, а когда идеальные объекты.

Так ведь нет никаких реальных объектов в программе, в этом вся соль. Возвращаясь к пресловутым яйцам: "объектно-ориентированное яйцо" настолько же далеко (а может и дальше) от реальности, насколько и "функциональное яйцо". Это тоже идеальный объект, просто из другой парадигмы. Насколько удобно с его помощью ту самую реальность моделировать - вот главный вопрос. Выше был более тонкий пример с лампочкой, и я приводил своё видение того, как её смоделировать, не прибегая к состоянию. Так вот получается (по крайней мере для меня), что ограничение иммутабельности заставляет больше внимания уделять тонкостям типизации и жизненного цикла, а значит способствует построению более корректных моделей. Это не говоря уж о чисто технических преимуществах в реализации, вроде простоты распараллеливания. Философские вопросы о сути бытия здесь сугубо вторичны. А вопрос о двух категориях объектов (реальные vs идеальные) в программе вообще не стоит по-моему. Разве что только в тех, которые непосредственно работают с железом. Вот там действительно императивный подход более уместен пожалуй.

> И подумать можно не о числах, а о более интересных вещах. В частности, о *мутабельных* классе Прямоугольник и его подклассе Квадрат.

А зачем? Чтобы можно было делать аффинные преобразования, оставаясь в рамках одного типа и в итоге прийти к объекту "Квадрат" со свойствами ромба?

> точно так же, как число 1 мутабельно, но на него несколько ссылок быть не может

Не понял, как это число 1 мутабельно? Если мы его мутируем, у нас уже не будет больше числа 1 что ли? Это в каком языке так сделано?

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

> А зачем? Чтобы можно было делать аффинные преобразования, оставаясь в рамках одного типа и в итоге прийти к объекту "Квадрат" со свойствами ромба?

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

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

> Попытки наехать на state для меня выглядят... ну мягко скажем бесперспективными.

Это говорит о тебе гораздо больше, чем о реальности и механизмах её моделирования.

P.S. Яишница --- это состояние яйца, группы яиц или же новый объект?

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

> Ты можешь привести чью нить ссылку которая определяет императивную модель через фреймы или типа претьендуешь на оригинальность?

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

Вся проблема в том, что фп плохо ложится на реальные задачи, т.к. компьютер - это не просто большой калькулятор, как это было 60-70ые года, и как хотелось бы фп-программистам, а "система управления", поэтому там важны не только вычисления, но и побочные эффекты - запись из файла/в файл, вывод на дисплей, работа с устройствами и прочее, кроме того иногда действительно нужны shared mutable data. Я тебе не раз говорил про rand - очень классический случай не функциональной функции, без скрытого состояния ее сложно реализовать, то же относится к вводу/выводу. Именно из-за необходимости работать с такими грязными функциями и желанием получить все плюшки фп (см выше), и пришлось придумать всякие ухищрения вроде передачи мира (universe) в качестве параметра в функцию, монады в конце концов. Кстати, надо сказать хаскелл в решении этой задачи,- создании чистого фп языка с возможностью работы с реальным миром, весьма преуспел.

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

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

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

> А потому что в двух разных местах одлин и тот же или разные люди руководствовались разными соображениями. Но оба знали что делали.

Тот код, которым ты ломал, говорит о том, что человек его писавший, все-таки не знал, что делал.

> Что поверю? Что ты будешь сидеть и превращать систему в набор чистых ...ммм "модулей" в неудобной форме исходя из "само собой разумеется" - оснований, без малейшей продемонстрированной пользы от такого подхода? Еще как поверю.

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

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

> Счет твой никуда не делется - там абстракции станет меньше. К стати! Банкомат вообще мистическая машина - превращает абстракции в реальность нажатием простых кнопок - прямо шутки Калиостро какие-то:)

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

> Фига се. Это принципиальный вопрос. Ты разделил объекты на 2 категории, отстаиваешь правоту своего деления, но даже обосновать его не хочешь.

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

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

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

Объекты* (это те, которые имеют identity и состояния) - это и есть абстракция для программирования (я думал это и так ясно, видимо, я действительно очень плохо выражаю свои мысли :( ) и не только, весьма удобная, кстати.

В фп кирпичик (из которого все строится) - это вычислительный объект (entity) без mutable внутреннего состояния - immutable data, functions and so on.

В ип добавляется еще один - это вычислительный объект (entity) с mutable внутренним состоянием. Простейший пример - это обычная mutable переменная, лексическое замыкание, объект в ооп-смысле. Он добавляет еще один уровень абстракции.

Почему я в своем "анализе" должен себя ограничивать только фп-образными объектами (entities) - immutable data, functions? Чтобы получить эфемерные плюсы подстановочной модели вычислений? Единственный существенный плюс - за который цепляются все фп-фанбои - это модульность, - но как писал господин хьюс в своей фп-агитке - она результат не столько самого фп, сколько HOF и lazy evaluation (хотя основной профит не в lazy evaluation, а в lazy sequences), а это я не считаю прерогативой исключительно фп.

Вспомни такие вещи как САПР (например, автокад), и человеку там, как это ни "парадоксально", естественнее работать с объектами* - передвинуть линию, нарисовать окружность, _поменять у этой окружности_ радиус и прочее, прочее, прочее, хотя человек там работает c абстракцией - чертежом.

Даже когда проводятся теоретические физические расчеты и анализ, мы мыслим (рассуждаем) более объектами* (в указанном смысле), чем функциями, у нас материальная точка (физическая абстракция) имеет состояние - скорость, ускорение, положение, и _она меняет свое состояние_ под воздействием импулься, приложенной силы или еще чего. Конечно, можно говорить, что под воздействием силы мы получаем новую точку с другими характеристиками, но я никогда о таком от учеников не слышал, им намного естественнее о ней думать, именно как об объекте (в указанном выше смысле), даже в абстрактных теоретических расчетах. Это уже потом, когда мы составляем уравнения, и нам приходится считать, - там больше функциональности, в самой математике, не в моделировании и рассуждениях о проблеме.

"Теоретический анализ" (вроде бы) дискретных систем привел создателей симулы к первому объектно-ориентированному языку.

Не зря, как я уже говорил, создатели *ml и scheme включили деструктивное присваивание в свои языки - хотя они были вполне академические, и создавались не для промышленного применения. Они как раз понимали, что не стоит ограничивать программиста только одним типом "кирпичей", ибо есть задачи, которые с помощь фп решаются намного хуже, чем в ип.

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

> Действительная реальность - не имеет никакого значения - мы ее воспринять не в состоянии.

Ну не хочу я залезать в эти дебри, что такое действительность, реальность, абстрактное, описательное, объективное, субъективное, истинное и ложное, мне не хочется обсуждать в этой ветке.

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

Да. Объекты* - это абстракция, и она помогает проводить теоретический анализ.

объекты* - это не те, которые ооп объекты, а те, которые имеют identity и мутабельное состояние; ооп объекты обычно мутабельны, но конечно, это не всегда так.

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

> Любой алгоритм оперирует абстрактными понятиями. Рецепт приготовления омлета из конкретных яиц не нафиг нужен никому - он одноразовый. Даже если мы учитываем вес и цвет яиц, они всё равно в алгоритме будут абстрактные.

да.

> Абстрактное мышление, насколько я знаю, врождённым для человека не является. Но его развитию способствует язык - мы все думаем на каком-то языке, называя конкретные вещи абстрактными именами. И именно абстрактное мышление сделало из обезьяны человека. :)

да.

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

> Я пока не увидел ни одной успешной попытки обосновать _необходимость_ стейта в этой задаче.

А никто тебе необходимость и не доказывает.

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

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

> Можно только выстроить некоторую искуственную точку отсчета, назвать ее 0лем, и сказать - это карандаш. Потому что в точке < нуля - это была деревяшка, а еще дальше - вообще дерево. То есть уже одно это - ограниченная абстрактная модель.

Да. Это "абстрактная" модель. В чем проблема-то?

> Угу - в программах реальных яиц просто немеряно.

Не, там модели яиц.

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

> Вариант А: смотрим о чем предметная область и создаем "объекты предметной области" отвечающие на вопрос "is a" и их свойства "has a". Из этого проистекает ООПшная модель с состояниями.

> Вариант Б: представить с какими данными предметной области мы будем иметь дело, категоризировать их и описать как абстрактные данные - это было сделано выше на хаскеле - такая себе штука вроде "алгебры".

> Первый - проще.

почему ты так думаешь? Ведь все зависит от задачи.

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

> И подумать можно не о числах, а о более интересных вещах. В частности, о *мутабельных* классе Прямоугольник и его подклассе Квадрат. Если мы сделаем объект Прямоугольник мутабельным, но запретим иметь на него несколько ссылок (точно так же, как число 1 мутабельно, но на него несколько ссылок быть не может) то вроде бы решим известную проблему. Так?

Вроде как нет, тут[1] рассказывается, почему это не решает проблему.

[1] http://okmij.org/ftp/Computation/Subtyping/

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

> Так ведь нет никаких реальных объектов в программе, в этом вся соль.

да.

> Насколько удобно с его помощью ту самую реальность моделировать - вот главный вопрос.

да.

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

Про лампочку я не читал, читал про яичницу (омлет). "Объектная*" (даже не в ооп смысле) модель не позволит тебе функцию unbreak (т.е. мы принципиально не можешь разбитое яйцо вернуть обратно), а функциональная позволит. И где тут более корректная модель?

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

Далее, сделай мне private mutable share data - например, у меня есть несколько потоков, которые добавляют, удаляют и читают слова из словаря. Как мне сделать эту вещь не через костыли в фп?

Как мне сделать probably cyclic list? Без костылей естественно. Только не надо приводить код из топика в developement - там не то. Т.е. это можно в хаскелле, например, сделать даже, не используя do нотацию, но это нельзя назвать красивым и идиоматическим решением.

> Это не говоря уж о чисто технических преимуществах в реализации, вроде простоты распараллеливания. Простота-то конечно, простота. Но как компилятор узнает, что ему параллелить? Ведь если он будет параллелить очень простые функции это может только замедлить работу, даже если это будут green threads внутрях настоящего треда. Поэтому параллелить все подряд не получится - значит, нужно оставлять аннотации - вот здесь параллель, а здесь - нет, что будет не сильно отличаться от ручного распараллеливания.

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

> P.S. Яишница --- это состояние яйца, группы яиц или же новый объект?

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

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

> Яишница --- это состояние яйца, группы яиц или же новый объект?

В зависимости от задачи. Возможны, вроде бы, любые 7 комбинаций.

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

> Не понял, как это число 1 мутабельно? Если мы его мутируем, у нас уже не будет больше числа 1 что ли?

Возможны 3 уровня абстракции:

0. без абстракции: "вот к этий куче добавили те камушки -- куча стала больше"

1. средний "вот к этим 15 камушкам добавили 2 -- __именно это__ число 15 стало 17-ью"

2. полностью идеальный, годится для ФП: "15 всегда было, всегда есть и всегда останется таким и неизменным... add(15,2)=17"

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

> Возможны 3 уровня абстракции:

> 1. средний "вот к этим 15 камушкам добавили 2 -- __именно это__ число 15 стало 17-ью"

Числа с identity? Выглядит бредово... Даже если взять этот пример, здесь число - это скорее свойство кучи камушков (количество), но никак не самостоятельный объект. Хотя если скатываться к пуризму и допустить, что всё есть объект, то... Ещё дальше уйдём от реальности по-моему.

> 15 всегда было, всегда есть и всегда останется таким и неизменным

Ну это по-моему и пятикласснику очевидно :) А вот числа c identity вполне могут взорвать ему мозг.

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

Для какой задачи необходимо, чтобы яйцо целое, яйцо разбитое, яишница, кучка говна являлись одним и тем же объектом в разных состояниях?

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

> А как ты смоделируешь это здесь и почему?

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

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

> Для какой задачи необходимо, чтобы яйцо целое, яйцо разбитое, яишница, кучка говна являлись одним и тем же объектом в разных состояниях?

Для той, в которой нам не нужны отдельные свойства для целого, разбитого яйца и яичницы - например, в задаче моделирования процесса приготовления яичницы для лора в разных парадигмах :) (прошу заметить у r - они тоже определены как состояния). Если тебе в принципе интересно, для каких задач легче использовать мутабельное состояние и identity - так я их перечислял где-то в недавних постах.

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

> Ответ на: Re: Вышел 2-й выпуск журнала "Практика функционального программирования" от anonymous 10.10.2009 4:37:02

> anonymous (*) (10.10.2009 14:56:59)

Я думал, анонимус поумнел, а оказывается здесь их несколько.

Развели тут стейтлесс дискуссию (непонятно чьи посты можно воспринимать только по отдельности), а ещё стейт и идентити защищают. Позор! :)

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

> Развели тут стейтлесс дискуссию (непонятно чьи посты можно воспринимать только по отдельности), а ещё стейт и идентити защищают. Позор! :)

Ага, функциональненько так :) А теперь представь, что на всём ЛОРе остались только анонимусы, а регистрироваться низзя (ну ладно, в порядке исключения можно, но только тем, кто сдаст экзамен по теоркату). Удобно?

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

> Ага, функциональненько так :) А теперь представь, что на всём ЛОРе остались только анонимусы, а регистрироваться низзя (ну ладно, в порядке исключения можно, но только тем, кто сдаст экзамен по теоркату).

Лучше уже математическую капчу сделать. :)

> Удобно?

> Разве Карл Маркс запрещает держать на лестнице ковры? Разве где-нибудь у Карла Маркса сказано, что 2-й подьезд Калабуховского дома на Пречистенеке следует забить досками и ходить кругом через черный двор? (c) Булгаков

Разве Хаскелл Карри запрещает пользователям иметь имена?

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