Re[26]: Есть ли вещи, которые вы прницпиально не понимаете...
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 20.01.14 18:03
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Если это состояние хранится в самой функции, то это уже не ФП. А если передаётся в неё как параметр (и при этом естественно является иммутабельным), то никаких проблем.


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

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


_>Не придумывай. ))) Это всего лишь одно из полезных побочных свойств ФП, а совсем не причина такого устройства.


Я вроде ясно говорю — "иммутабельность нужна для решения" а не "иммутабельность есть причина". Для чего еще нужна иммутабельность — дело десятое.

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


Недавно это лет 50-60 назад ?
Re[28]: Есть ли вещи, которые вы прницпиально не понимаете...
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 20.01.14 18:12
Оценка:
Здравствуйте, alex_public, Вы писали:

I>>Каким образом мерить эффективность?


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


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

I>>ФП ничему не противоречит. Ты путаешь особенности вычислителя и требования ФП.


_>Ты можешь предложить реализацию ФП с не иммутабельными данными? )


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

I>>А теперь представь себе распределенное приложение. Внезапно <любой императивный язык> слился весьма бесславно. Ты, конечно, можешь выкрутиться навроде "даже если одна функция написана на С++" значит и всё приложение написано на С++.


_>Что ты подразумеваешь под "распределённым приложением"? Что-то типа MPI? И почему это любой императивный язык тут сливается? )


Я не знаю что такое MPI
Re[60]: Есть ли вещи, которые вы прницпиально не понимаете...
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 20.01.14 18:14
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Здравствуйте, Ikemefula, Вы писали:


I>>Выдай правило, которое расскажет когда же делать эту распаковку, а когда — нет.


_>В смысле когда? Всегда естественно) Ну если конечно эта функция не сводится к комбинации нескольких других такого же типа.


А как быть с функцией, которая уже умеет работать с optional<double> и ей не нужны никакие распаковки ? Заворачивать её в другую фунцию, которая сделает упаковку после распаковки ?
Re[47]: Есть ли вещи, которые вы прницпиально не понимаете...
От: alex_public  
Дата: 20.01.14 18:15
Оценка:
Здравствуйте, Klapaucius, Вы писали:

K>Это как-то можно раскрыть?


Речь шла про метапрограммирование средствами самого языка (а не внешними средствами).

K>Именно об этом. Ничего удивительного в этом как раз нет. В более-менее нормальных языках такое доступно:

K>..
K>Обычное метапрограммирование, параметрический полиморфизм тут не причем.

Ну да, я в том сообщение прямо так и написал, что уже отвлёкся на другую тему.

А МП у нас действительно есть во многих языках, но очень разного уровня. И уровень D я мало где видел, разве что в Nemerle ещё сильнее, но там только МП и есть по сути, так что практической пользы от этого пока нет. Ну и макросы Лиспа конечно же, но это уже совсем другая история. )))

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

K>Это точно про D? Он вроде супербыстродействием никогда похвастать не мог.


Сам D конечно помедленнее чем C/C++, хотя быстрее Java/C#. Но здесь речь вообще не об этом шла. Подразумевалось супербыстродействие в сравнение с вариантом "поставлять тексты на том DSL в конечном приложение и просто запускать рантайм интерпретатор их". Т.е. грубо говоря идёт сравнение вариантов типа PHP или как если бы мы транслировали PHP код в C код и потом вкомпилировали бы их в http сервер. Кстати, интересный нюанс: практически к такому же решению и пришли Фейсбук и Вконтакте на своих серверах, только очень сложным и мучительным путём (например пришлось разрабатывать подмножество PHP и т.п.). А тут у нас всё из коробки работает.
Re[27]: Есть ли вещи, которые вы прницпиально не понимаете...
От: Evgeny.Panasyuk Россия  
Дата: 20.01.14 18:53
Оценка:
Здравствуйте, Klapaucius, Вы писали:

EP>>Оставим prompt finalization в стороне. Вот есть у нас using на ресурс в C#, или регион в Haskell — можем ли мы сделать замыкание на идентификатор ресурса (в funarg ведь про идентификаторы речь) и передать это замыкание наверх?

K>Ну да. Оставляем prompt finalization в стороне и сразу переходим к prompt finalization!

Неудобно как-то получается, да? Вроде UFP (захват free variable замыканием) — а GC ничем помочь не может

EP>>можем ли мы сделать замыкание на идентификатор ресурса (в funarg ведь про идентификаторы речь) и передать это замыкание наверх?

K>В C# можем,

Как? Транзитивно заражая все места использования ручным using'ом?

EP>>можем ли мы сделать замыкание на идентификатор ресурса (в funarg ведь про идентификаторы речь) и передать это замыкание наверх?

K>в хаскеле есть средства для предотвращения этого а-ля ST.

ST не работает в Haskell 98, то есть требует расширение?
Потом, предотвращение — это не решение задачи. Вот, например, нужно чтобы работало что-то типа:
import System.IO

main = do
    closure <- withFile "test.out" WriteMode $ \f -> do
        hPutStr f "ok"
        return $ \s -> do
            hPutStr f "logging: "
            hPutStrLn f s
    closure "fail" -- test.out: hPutStr: illegal operation (handle is closed)
как?

EP>>На haskell.org написанно:

EP>>[...]
EP>>В этой табличке для C++:
EP>>support functional programming by supporting first-class function
EP>>functional style is NOT the dominant one
K>А если я в какой-нибудь вики напишу, что луна из сыра — вы поверите?

В случае с C++ я знаю как и насколько он поддерживает functional programming. Относительно UFP — я вам приводил несколько вариантов решения, причём которые работают не только для памяти.
Этого видимо недостаточно, поэтому я привёл цитату из haskel.org wiki — чтобы сослаться хоть на какой-то авторитет (естественно wiki это не то, но всё же).

K>>>>>>Мы вроде бы в соседней ветке выяснили, что без ленивости комбинирование функций теряет смысл из-за непрактичности.

EP>>>>В том примере нужна не ленивость, а monadic код. Ленивость помогла только в одном случае из двух, и как видно в общем случае не позволяет сделать обычный код монадичным.
K>>>Ничего не понимаю. Ленивость не делает код монадическим. Она нужна, чтоб функции, полученные как результат комбинации других не делали лишние вычисления/проходы. Т.е. в обсуждаемом случае нужна, чтоб монадический код нормально работал.
EP>>Для монады Maybe, ленивость позволяет foldr работать так, как работал бы foldrm.
K>Не знаю, что вы подразумеваете под foldrm, foldr работает как foldr, а foldM совсем другая функция:
K>[...]
K>foldr же в обсуждаемом примере просто расставляет лифтнутые (+) между элементами списка.
K>[...]
K>Ленивость позволяет не вычислять невостребованное. А левая свертка cons списка востребует все, да еще как!

Так, восстанавливаем контекст:
1. Изначально речь шла про автоматическое преобразование обычного кода в монадический.
2. Implicit лифтированние операторов помогает только в некоторых случаях, и не позволяет получить монадические эффекты в общем случае. Например alex_public показал автоматическое лифтирование в D, так вот — там и foldl и foldr не дают необходимого монадического эффекта для Maybe (будут обрабатываться все элементы, даже если есть Nothing).
3. В Haskell, за счёт ленивости — получается достичь необходимых монадических эффектов за счёт лифтирования в большем классе случаев, но далеко не во всех. Например для foldr+Maybe работает, а для foldl — нет.
Т.е. в общем случае код всё равно придётся переделывать на монадический — ленивость помогает только в некоторых специфичных случаях.
В языках же с call-with-current-continuation: любой код можно сделать монадическим без модификаций (либо нужно сделать минимальные модификации, заменив "x" на "get(x)" — если нет перегрузки всего как в D. И то, такая замена можно потребоваться только в листах call-tree, а не по всему коду). Так вот, в языках с call/cc — и foldl и foldr станут монадическими без изменения структуры foldl/foldr.
4. Вы сказали:

K>Мы вроде бы в соседней ветке выяснили, что без ленивости комбинирование функций теряет смысл из-за непрактичности.

Хотя ничего подобного мы не выясняли
Re[34]: Есть ли вещи, которые вы прницпиально не понимаете...
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 20.01.14 18:57
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

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


EP>Допустим у нас такое определение — ОК.

EP>Что делать в случае, когда захватываются ресурсы? (пусть это не относится к UFP по данному выше определению)

Контролировать ресурсы явно, руками. Проблема с ФП в том, что циклические ссылки это норма. Это поначалу просто убивает мозг.

Предположим, ты открываешь ресурс и using разрушит ресурс только когда разрушится замыкание.

Совершенно не ясно как ты собираешься это использовать из за наличия циклических ссылок.
Варианты
1 "вон это замыкание из вон той функции использовать только один раз и сразу разрушать"
2 "вот это замыканиние из вон той функции не трогаем, как отсохнет, само отвалится, хрен его знает как это происходит, но на прошлой неделе это происходило в среднем за 500мс"

Других нет, точнее, они сводятся к двум этим
1 — если используешь один раз, это равносильно вызову в правильном месте
2 — если используешь много раз, получаешь хрень с занятым ресурсом и недетерминированым временем использования. То есть разрушение как бы детерминировано — но вот сколько ресурс будет использовася, хрен его знает, например сильно вряд ли ты просчитаешь сложную рекурсию и тд и тд. Но как только перестанет использоваться — сразу разрушится. Очевидно, этот вариант есть просто некорректный код.

Итого — если делать "как в С++" то надо бороться с циклическими ссылками и желательно что бы эти циклические ссылки искал компилятор, а вот компилятор этого как раз и не умеет. То есть, в итоге пришли к ручному управлению, когда, казалось бы, нужна была автоматизация. Все чего добились — ручная неявная работа с ресурсами.
В С++ придется следить за циклическими ссылками, приседать, обрезать и тд и тд и тд и всё это руками, но ресурсы будут освобождаться неявно. То есть, руками задаёшь стратегию использования, а вызов произойдет неявно.

Что предлагает ФП — работа с ресурсом делается в изолированом контексте. Нужно думать не о ресурсах, а о результатах операций, а ресурсы использовать унутре каждой из операций. И разумеется явно, руками.

В ФП не надо следить за циклическими сслыками, не надо приседать, обрезать и тд и тд. Делаешь всё как с другими функциями — комбинируешь, вызываешь, параметризуешь и тд. Ресурсами управляешь руками — задаёшь руками стратегию использования по месту вызова, в этом случае вызов разрушения будет сделан неявно.

Итого — оба варианта на деле означают одно и то же — ручной контроль ресурсов. Отдельно можно поговорить про аггрегирование.
Re[29]: Есть ли вещи, которые вы прницпиально не понимаете...
От: Evgeny.Panasyuk Россия  
Дата: 20.01.14 19:11
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>>>Это цифры с потолка. Эрланг показывает и доказывает что твои рассуждения ошибочны.

EP>>Какие именно рассуждения, и как он доказывает?
I>На нём пишутся распределенные системы, внезапно !

И как это доказывает то, что он работает не медленнее чем аналогичный код на императивном языке?

I>Эрланг собтсвенно и начал с того, что порвал С++ в распределенных приложениях для телекоммуникаций.


Erlang рулит в первую очередь из-за инфраструктуры, а не из-за самого языка. Точно также как рулит и node.js за счёт инфраструктуры.

EP>>Кстати, про Erlang — выше приводили пример "идиоматичного ФП кода":

EP>>
EP>>f = 0 : 1 : zipWith (+) f (tail f)
EP>>
попробуй изобрази его на Erlang.

EP>>Да, и по-твоему Erlang это чистый ФП?
I>Это скучно.

Конечно, мы же обсуждаем чистые ФП и эффективность их мэппинга в железо. Если тебе скучно — то я
Кстати, ранее в обсуждении утверждалось что ленивость — это пища ФП (весьма тормозная). И пример с zipWith выше как раз и использует ленивость. Но в Erlang'е никакой ленивости нет — к чему бы это?

EP>>Устроен танковый батальон естественно не как танк, но без танков нет батальона. Ты что сказать-то хотел своей метафорой?

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

У распределённых число-дробилок в большинстве случаев узким местом будет как раз процессор.

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


А диспетчер где исполняется? На каком-то чудесном ФП-железе?

I>>>Ты не заметил лямбды в С++ ? Чудеса !

EP>>Это не чистое ФП, а как раз полезные его элементы. И "влазло" оно очень давно.
I>Ажно с первых версий stl.

STL это только конкретный известный пример.

EP>>См. например STL — там же кругом value semantics (привет referential transparency) и higher order functions.

I>Вот-вот.

Что "вот-вот"? Я же говорю — использование элементов ФП это хорошо.

I>Сколько лет stl ?


Около 20.
Re[25]: Есть ли вещи, которые вы прницпиально не понимаете...
От: alex_public  
Дата: 20.01.14 20:17
Оценка:
Здравствуйте, Klapaucius, Вы писали:

K>ОК, разделять данные между версиями в теории не обязательно. Но никакой специфики языка тут нет. В библиотеках для ФЯ эти структуры реализуются так, что данные разделяются.


Вот вот. Собственно говоря, из-за иммутабельности данных в ФП языках вообще нет понятия ссылки, как её понимают в C++ (поменяем данные в одном месте кода и это уловил код в другом месте), а есть только копирование (то, что внутри оно может оптимизироваться через ссылки, значения не имеет). Поэтому:

1. Непонятно с чего вы требуете от C++ наличия [&] вверх по стеку, в то время как чистые ФП языки не имеют этого даже вниз по стеку? Собственно сама конструкция & — это признак скорее императивного языка. Да, и кстати [&] вверх по стеку в C++ тоже есть — shared_ptr. Только это получается нужно в основном для той редкой ситуации, которая в ФП языках вообще запрещена.

2. Непонятно почему вы пренебрегаете новой возможностью C++, обеспечивающей возможность осуществлять "копирование из покидаемой области" с нулевыми накладными расходами — она же как раз полностью решает проблему эффективности [=], делая его таким же эффективным как в ФП языка?


Вообще, когда вы говорите про & и чистые функциональные языки, то на самом деле подразумевается всего лишь const&, которая отличается от = только быстродействием. Соответственно в ФП у нас имеется = или же const& (оптимизированная версия), вниз и вверх по стеку. А например в C++ мы имеем:

1. = вверх и вниз по стеку естественно.
2. const& вниз по стеку, т.е. оптимизированное = вниз по стеку
3. && (то самое перемещение), т.е. оптимизированное = вверх по стеку
4. & вниз по стеку, причём оно оптимизировано от рождения
5. shared_ptr, как реализация & вверх по стеку

Т.е. C++ предоставляет все возможности ФП языков в этой области, и плюс ещё несколько (пункты 4 и 5) вариантов.
Re[27]: Есть ли вещи, которые вы прницпиально не понимаете...
От: alex_public  
Дата: 20.01.14 20:42
Оценка:
Здравствуйте, Ikemefula, Вы писали:

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


Если мы говорим про ФП, то там захватываемые величины становятся просто константами. Так что они явно не могут быть состоянием.
Re[29]: Есть ли вещи, которые вы прницпиально не понимаете...
От: alex_public  
Дата: 20.01.14 20:50
Оценка:
Здравствуйте, Ikemefula, Вы писали:

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

I>То есть, быстродействие кода каждого из узлов всего лишь необходимое условие для некоего минимального уровня выходного сигнала.

И какое это имеет отношение к неэффективности (по быстродействию) языков с чистым ФП?

I>Я могу предложить пример вычислителя, где императивный ЯП будет сливать любому ФЯ — это асинхронный вычислитель.


Ну предложи) С удовольствием посмотрим. )

_>>Что ты подразумеваешь под "распределённым приложением"? Что-то типа MPI? И почему это любой императивный язык тут сливается? )

I>Я не знаю что такое MPI

Эмммм... Вообще то это самый распространённый инструмент для написания распределённых приложений. Вот http://ru.wikipedia.org/wiki/Message_Passing_Interface ссылочка. Кстати, надо пояснять на каком языке там основные реализации?)))

Хех, мне теперь даже страшно предположить, что ты имел в виду под "распределёнными приложениями", если при этом не в курсе про MPI... )
Re[61]: Есть ли вещи, которые вы прницпиально не понимаете...
От: alex_public  
Дата: 20.01.14 20:52
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>А как быть с функцией, которая уже умеет работать с optional<double> и ей не нужны никакие распаковки ? Заворачивать её в другую фунцию, которая сделает упаковку после распаковки ?


Вот как раз такие функции и остаются) Плюс "голые" (без optional вообще). Про это и речь. ) Ты похоже уже запутался в нашей с Синклером дискуссии. Он то хотел вообще третий вид функций привлечь (как раз которые для монад только)... )))
Re[30]: Есть ли вещи, которые вы прницпиально не понимаете...
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 20.01.14 20:54
Оценка:
Здравствуйте, alex_public, Вы писали:

_>И какое это имеет отношение к неэффективности (по быстродействию) языков с чистым ФП?


Непосредственное — эффективность языка зависит от вычислителя. В императивных языках нет ничего для асинхронщины. Вообще ничего.

I>>Я могу предложить пример вычислителя, где императивный ЯП будет сливать любому ФЯ — это асинхронный вычислитель.


_>Ну предложи) С удовольствием посмотрим. )


Уже.

_>Эмммм... Вообще то это самый распространённый инструмент для написания распределённых приложений. Вот http://ru.wikipedia.org/wiki/Message_Passing_Interface ссылочка. Кстати, надо пояснять на каком языке там основные реализации?)))


Ты снова про производительность отдельного нода и его АПИ

_>Хех, мне теперь даже страшно предположить, что ты имел в виду под "распределёнными приложениями", если при этом не в курсе про MPI... )


Я не в курсе твоих аббревиатур. Эрланг в свое время порвал С++, странно что ты этого не знаешь.
Re[28]: Есть ли вещи, которые вы прницпиально не понимаете...
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 20.01.14 20:55
Оценка:
Здравствуйте, alex_public, Вы писали:

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


_>Если мы говорим про ФП, то там захватываемые величины становятся просто константами. Так что они явно не могут быть состоянием.


Это чушь. Поведение не реализуется без состояния. А ФП, мягко говоря, ничем не мешает описывать поведение, более того, активно помогает.
Re[30]: Есть ли вещи, которые вы прницпиально не понимаете...
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 20.01.14 21:10
Оценка:
Здравствуйте, alex_public, Вы писали:

_>>>Что ты подразумеваешь под "распределённым приложением"? Что-то типа MPI? И почему это любой императивный язык тут сливается? )

I>>Я не знаю что такое MPI

_>Эмммм... Вообще то это самый распространённый инструмент для написания распределённых приложений. Вот http://ru.wikipedia.org/wiki/Message_Passing_Interface ссылочка. Кстати, надо пояснять на каком языке там основные реализации?)))


Вот, нашел специально для тебя, про эрланг и mpi

http://www.slideshare.net/norbu09/mpi-erlang-and-the-web

можешь поискать сам про rabbitmq
Re[30]: Есть ли вещи, которые вы прницпиально не понимаете...
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 20.01.14 21:31
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

I>>>>Это цифры с потолка. Эрланг показывает и доказывает что твои рассуждения ошибочны.

EP>>>Какие именно рассуждения, и как он доказывает?
I>>На нём пишутся распределенные системы, внезапно !

EP>И как это доказывает то, что он работает не медленнее чем аналогичный код на императивном языке?


Код никого не интересует. Интересуют выходные характеристики конечной системы.

I>>Эрланг собтсвенно и начал с того, что порвал С++ в распределенных приложениях для телекоммуникаций.


EP>Erlang рулит в первую очередь из-за инфраструктуры, а не из-за самого языка. Точно также как рулит и node.js за счёт инфраструктуры.


Это инфраструктуру без подобного языка заюзать невозможно, в принципе.

I>>Это скучно.


EP>Конечно, мы же обсуждаем чистые ФП и эффективность их мэппинга в железо. Если тебе скучно — то я


Это тебе интересно обсуждать ислючительно мапинг в железо.

EP>Кстати, ранее в обсуждении утверждалось что ленивость — это пища ФП (весьма тормозная). И пример с zipWith выше как раз и использует ленивость. Но в Erlang'е никакой ленивости нет — к чему бы это?


Наверное к тому, что Эрлан это энергичный язык ?

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


EP>У распределённых число-дробилок в большинстве случаев узким местом будет как раз процессор.


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

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


EP>А диспетчер где исполняется? На каком-то чудесном ФП-железе?


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

EP>Что "вот-вот"? Я же говорю — использование элементов ФП это хорошо.


Ты почему то начал спрашивать, когда это ФП попало в нативный код
Re[26]: Есть ли вещи, которые вы прницпиально не понимаете...
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 20.01.14 21:31
Оценка:
Здравствуйте, alex_public, Вы писали:

_>1. Непонятно с чего вы требуете от C++ наличия [&] вверх по стеку, в то время как чистые ФП языки не имеют этого даже вниз по стеку?


Имеют.

>Собственно сама конструкция & — это признак скорее императивного языка. Да, и кстати [&] вверх по стеку в C++ тоже есть — shared_ptr. Только это получается нужно в основном для той редкой ситуации, которая в ФП языках вообще запрещена.


Наоборот, вверх по стеку используется постоянно.


_>2. Непонятно почему вы пренебрегаете новой возможностью C++, обеспечивающей возможность осуществлять "копирование из покидаемой области" с нулевыми накладными расходами — она же как раз полностью решает проблему эффективности [=], делая его таким же эффективным как в ФП языка?


Она ничего не решает, если точнее. Я рядом уже пояснил.

_>1. = вверх и вниз по стеку естественно.

_>2. const& вниз по стеку, т.е. оптимизированное = вниз по стеку
_>3. && (то самое перемещение), т.е. оптимизированное = вверх по стеку
_>4. & вниз по стеку, причём оно оптимизировано от рождения
_>5. shared_ptr, как реализация & вверх по стеку

_>Т.е. C++ предоставляет все возможности ФП языков в этой области, и плюс ещё несколько (пункты 4 и 5) вариантов.


Нет никакого "дополнительно", все что ты показал это вверх и вниз.
Re[31]: Есть ли вещи, которые вы прницпиально не понимаете...
От: alex_public  
Дата: 20.01.14 21:38
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Непосредственное — эффективность языка зависит от вычислителя. В императивных языках нет ничего для асинхронщины. Вообще ничего.


А что есть для неё в функциональных языках? )

_>>Ну предложи) С удовольствием посмотрим. )

I>Уже.

Это типа "асинхронный вычислитель"? ) Мне эта фраза ни о чём не говорит вообще. Давай конкретный пример кода или хотя бы статью в вики на описание архитектуры.

I>Ты снова про производительность отдельного нода и его АПИ


Ээээ что что? ) С помощью указанного выше инструмента программируют большинство современных суперкомпьютеров, вычислительных кластеров и т.п. )

I>Я не в курсе твоих аббревиатур. Эрланг в свое время порвал С++, странно что ты этого не знаешь.


Эрланг ничего так язык. Мне всегда нравился Пролог (жаль что в Эрланге от него только синтаксис и остался, без реального наполнения). И модель акторов тоже хороша (правда сейчас её уже начали спокойно использовать и в C++, а D она вообще входит в стандартную библиотеку). Но насчёт "порвал" — это ты мягко говоря преувеличил. ))) Даже в целевой нише Эрланга только небольшая часть софта пишется на нём. Так что он вообще никого не порвал, а пока что просто сумел выжить и даже имеет парочку примеров написания известного софта (только в других языках таких примеров сотни в той же области). В общем его позиция выглядит намного лучше чем у D или Haskell, но о мейнстриме (даже в своей нише!) ему ещё мечтать и мечтать... )))
Re[32]: Есть ли вещи, которые вы прницпиально не понимаете...
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 20.01.14 21:43
Оценка:
Здравствуйте, alex_public, Вы писали:

I>>Непосредственное — эффективность языка зависит от вычислителя. В императивных языках нет ничего для асинхронщины. Вообще ничего.


_>А что есть для неё в функциональных языках? )


Композиция функций.

_>Это типа "асинхронный вычислитель"? ) Мне эта фраза ни о чём не говорит вообще. Давай конкретный пример кода или хотя бы статью в вики на описание архитектуры.


Я уже раз 100 упомянул, но ты никуда не заглянул. Что изменит 101 раз ?

I>>Ты снова про производительность отдельного нода и его АПИ


_>Ээээ что что? ) С помощью указанного выше инструмента программируют большинство современных суперкомпьютеров, вычислительных кластеров и т.п. )


Ля-ля-ля.

курсе твоих аббревиатур. Эрланг в свое время порвал С++, странно что ты этого не знаешь.

_>Эрланг ничего так язык. Мне всегда нравился Пролог (жаль что в Эрланге от него только синтаксис и остался, без реального наполнения). И модель акторов тоже хороша (правда сейчас её уже начали спокойно использовать и в C++, а D она вообще входит в стандартную библиотеку). Но насчёт "порвал" — это ты мягко говоря преувеличил. )))


Читай историю Эрланга.

>Даже в целевой нише Эрланга только небольшая часть софта пишется на нём.


Эрланг давно вышел из этой ниши.

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


У него популярность растет и растет и в основном в распределенных приложениях.
Re[62]: Есть ли вещи, которые вы прницпиально не понимаете...
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 20.01.14 21:45
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Здравствуйте, Ikemefula, Вы писали:


I>>А как быть с функцией, которая уже умеет работать с optional<double> и ей не нужны никакие распаковки ? Заворачивать её в другую фунцию, которая сделает упаковку после распаковки ?


_>Вот как раз такие функции и остаются) Плюс "голые" (без optional вообще). Про это и речь. ) Ты похоже уже запутался в нашей с Синклером дискуссии. Он то хотел вообще третий вид функций привлечь (как раз которые для монад только)... )))


Нет, я говорю про то же что и Синклер.

Твоя функция, раз "такие функции и остаются", никакая не универсальная. А нужна универсальная и это возможно только с монадами.
Re[27]: Есть ли вещи, которые вы прницпиально не понимаете...
От: Evgeny.Panasyuk Россия  
Дата: 20.01.14 21:58
Оценка:
Здравствуйте, Klapaucius, Вы писали:

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

K>>>Ну правильно: используют не ФЯ, идиомы не ФП — с чего бы им испытывать с этим проблемы, если все тропы протоптаны там, где их нет.
EP>>Нет — речь была не про ФП.
K>Да. Разговор был именно о ФП, точнее о том, что усилия необходимые для использования зачаточного фп-стиля в C++ превышают бенефиты от использования зачаточного ФП-стиля.

В выделенном разговор был не про ФП.

EP>>Особенно оно не нужно там, где плохо мэппится в реальное железо.

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

На C++ как раз высокоуровневый код отлично мэппится в железо. The Standard Template Library

What do I mean when I say that an algorithm does not "impose any performance penalty"? In other words, how do you know that a generic algorithm is efficient? An algorithm is called rel atively efficient if it's as efficient as a nongeneric version written in the same language, and it's called absolutely efficient if it's as efficient as a nongeneric assembly language version.

For many years, I tried to achieve relative efficiency in more advanced languages (e.g., Ada and Scheme) but failed. My generic versions of even simple algorithms were not able to compete with built-in primitives. But in C++ I was finally able to not only accomplish relative efficiency but come very close to the more ambitious goal of absolute efficiency. To verify this, I spent countless hours looking at the assembly code generated by different compilers on different architectures.

I found that efficiency and generality were not mutually exclusive. In fact, quite the reverse is true. If a component is not efficient enough, it usually means that it's not abstract enough. This is because efficiency and abstractness both require a clean, orthogonal design. A similar phenomenon occurs in mathematics: Making a proof more abstract makes it more concise and elegant.

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

В железе есть: изменяемая память(доступ к которой происходит большими порциями ~64B), многоуровневые кэши, синхронизация между кэшами, изменяемые регистры, стэк (с готовыми инструкциями для работы с ним), указатель на текущую инструкцию и разнообразные переходы. Само собой, если даже самые низкоуровневые абстракции в языке делают вид что ничего этого нет и вносят большое penalty сами по себе — то всё будет тормозить.

EP>>2. UFP — это передача замыкания выше области free variables, так? Free variable может чем угодно, а не только памятью

K>Free variable не может быть чем угодно. Это языковая сущность. "Память" — это уже другой, нижележащий уровень абстракции. UFP гарантирует продление жизни языковой сущности. Т.е. объекта File, а не файла, хендлером для которого этот файл является.

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

Например в C# — если какой-то из объектов, где-то в глубине композиции начнёт использовать ресурс как поле, то начнётся ад — вся цепочка объектов становится ресурсами, это означает что требуется добавить новый код во всех местах пользования. Особенно весело будет если мы работаем над библиотекой, которая используется клиентами.
В C++ же абстракция есть для всех ресурсов, и при добавление поля-ресурса зависимый код менять не нужно:
class Foo // used at many places
{
    Resource x;
// ...
};


EP>>Работающего [&] не будет даже при включённом GC. Даже при использовании GC нужен будет [=]

K>В высокоуровневом языке различие между передачей по ссылке и копированием вообще чаще всего семантически ненаблюдаемо.

import Control.Monad.ST
import Data.STRef
import Control.Monad

foo x = modifySTRef x (+1)

main = print $ runST $ do
    x <- newSTRef 0
    foo x -- by reference!
    foo x -- by reference!
    readSTRef x
-- prints 2
А тут что?
Кстати, а зачем используют эту венгерскую ноткацию? Почему не просто "modify" вместо "modifySTRef"?

EP>>Вообще-то вопрос был про то, как в Haskell передать замыкание с ресурсом-free-variable наверх. Region'ы судя по всему это проблему никак не решают, поэтому вопрос остаётся открытым.

K>Регионы предотвращают утечку ресурса.

Вопрос в том как передать это замыкание наверх, а не запретить передачу.

EP>>Ну да, нет нормального решения — "бессмысленно"

K>Но его нет. То, что вы считаете нормальным решением в условиях высокоуровневого языка нормальным не является.

Естественно — лучше запретить.

K>Связывание управления памятью с управлением дефицитными ресурсами там ни к чему хорошему не приводит.


О каком управлением памятью идёт речь?
В C++ есть объекты, у этих объектов есть lifetime. Объекты могут абстрагировать работу с любым ресурсом — память, файлы, соединения и т.п.

EP>>Это в этом варианте?

K>Более-менее осмысленное решение, это делать функцию вида ЭтоНамНадоЧтобПолучитьРесурс -> (ОткрытыйРесурс -> Результат) -> Результат, которая сначала собирает через второй аргумент функции, которые что-то будут с ресурсом делать, а потом выполняется сама, открывая ресурс, скармливая всем этим функциям и закрывая его. Т.е. те самые брекеты и их развитие вроде pipes-safe и resourcet.

EP>>?
K>А в чем вы видите противоречие?

В этом варианте все функции для работы над одним ресурсом должны собраться в одном месте, так?
Что делать в случае когда у нас несколько ресурсов, время жизни которых пересекаются и зависят друг от друга? (решение с использованием одного большого scope — естественно неинтересно)

K>Вы с тем, на что я ссылался ознакомились?


С чем именно? С тем вариантом где хэндлы явно передаются через return? Так вопрос же про возвращение замыкания.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.