Здравствуйте, Ikemefula, Вы писали:
I>Это чушь. Поведение не реализуется без состояния. А ФП, мягко говоря, ничем не мешает описывать поведение, более того, активно помогает.
В чистом ФП это описывают так:
new_state=process_event(state, event);
тогда функция process_event остаётся чистой и все довольны. )
Естественно где-то там в коде должно быть столкновение с "грубой реальностью внешнего мира", но для этого в ФП используются спец. средства, типа монад ST/IO в Хаскеле.
Re[31]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, Ikemefula, Вы писали:
I>Нет, я говорю про то же что и Синклер.
I>Твоя функция, раз "такие функции и остаются", никакая не универсальная. А нужна универсальная и это возможно только с монадами.
Ты похоже вообще уже забыл о том, какая задача решалась в той дискуссии. Мы решали проблему "добавление optional в некий существующий код, без его модификации". Монады тут вообще ни при чём, т.к. не дают в принципе подобных решений. Это вопрос скорее из области гибкости языка. Я показал, что на D это в принципе возможно (хотя Евгений указал на недостатки такого решения в области производительности). Причём моё добавление монадой не являлось. Синклер же указал, что подобное решение будет странно работать с функциями "монадного вида". Ну с этим никто и не спорит, только за отсутствием монад у нас и функций таких не должно быть (в старом коде их в принципе быть не может, а новый мы пишем с максимальным обобщением).
Re[28]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>>>То есть на равном месте вводится межпоточная синхронизация, об этом и речь. K>>А вы точно читали то, на что я ссылаюсь? EP>Точно. Там используется lock-free алгоритм для межпоточной синхронизации
Выделено. Вы не поняли, для чего это нужно или есть идеи получше?
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[30]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, Ikemefula, Вы писали:
I>>Это чушь. Поведение не реализуется без состояния. А ФП, мягко говоря, ничем не мешает описывать поведение, более того, активно помогает.
_>В чистом ФП это описывают так: _>
_>new_state=process_event(state, event);
_>
тогда функция process_event остаётся чистой и все довольны. )
Важно, что состояние никуда не девается. Просто новое состояние берётся посредством вычисления из старого, а не так, как в императивном программировании, путем модификации старого.
Re[32]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, alex_public, Вы писали:
I>>Вот, нашел специально для тебя, про эрланг и mpi I>>http://www.slideshare.net/norbu09/mpi-erlang-and-the-web
_>Я как бы в курсе, что в Эрланге реализован некий свой аналог MPI. ))) И что с того? )
Ну стало быть, согласно твоим словам, ты считаешь что Эрлан это другое название для С++, других объяснений нет
Re[28]: Есть ли вещи, которые вы прницпиально не понимаете...
Ню-ню.
I>>У него популярность растет и растет и в основном в распределенных приложениях.
_>Ну так когда растёшь от нуля, то можно и 500% роста в год показывать, но при этом занимать на рынке 1%. )))
Ога. Ты по прежнему доказываешь, что танковый батальон устроен точно так же как и танк
Re[28]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, alex_public, Вы писали:
_>Формально говоря, да.
Мы вроде бы говорили о принципах ФП? Ну, вот контролируемая мутабельность этим принципам не противоречит, она нормально встраивается в чистый код. Мутабельность может быть деталью реализации библиотеки, а код ее использующий — полностью идиоматическим.
_>Но фактически, есть ли у нас сейчас ФП языки программирования, способные записать такое? )
Такое — это какое? Имеется в виду контролируемая мутабельность? Она, разумеется, во всех чистых языках есть. Развитая система для контроля уникальности ссылок есть в Clean. Оптимизации, устраняющие промежуточные результаты, там где это возможно есть в GHC, для списков в стандартной библиотеке и пакете stream-fusion, для массивов в пакетах vector и repa. Вполне работающие.
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[64]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, Ikemefula, Вы писали:
I>>Нет, я говорю про то же что и Синклер.
I>>Твоя функция, раз "такие функции и остаются", никакая не универсальная. А нужна универсальная и это возможно только с монадами.
_>Ты похоже вообще уже забыл о том, какая задача решалась в той дискуссии. Мы решали проблему "добавление optional в некий существующий код, без его модификации".
Правильно и это значит, что нужна универсальная функция.
>Синклер же указал, что подобное решение будет странно работать с функциями "монадного вида". Ну с этим никто и не спорит, только за отсутствием монад у нас и функций таких не должно быть (в старом коде их в принципе быть не может, а новый мы пишем с максимальным обобщением).
Ты предлагаешь законодательно запретить использовать промисы ? Или optional это просто название, а на сама деле это double ? Не пойму чтото. Если новый код пишется с максимальным обобщением, то ожидается универсальная функция
Re[48]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, alex_public, Вы писали:
_>Речь шла про метапрограммирование средствами самого языка (а не внешними средствами).
Погодите. Начали мы с того, что обобщенный код в плюсах нетипизирован. Вы заявили, что обобщенный код везде такой. Когда выяснилось, что это не так, вы заявили, что в плюсах он такой потому, что работает во время компиляции. Когда выяснилось, что тот же параметрический полиморфизм именно во время компиляции и работает, вы заявили, что работа во время компиляции может быть разная. Это, конечно, верно. И именно это и следовало бы обсудить подробнее. Но вы вдруг написали про то, что бывает метапрограммирование внешними средствами, а бывает — средствами языка. При чем тут это? Я запутался.
_>Если у языка есть развитое МП, то даже если в нём и не заложены изначально некоторые возможности, то их практически всегда можно добавить, используя МП.
"Практически всегда" — это очень сильное преувеличение. В некоторых случаях можно, да.
_>Сам D конечно помедленнее чем C/C++, хотя быстрее Java/C#.
Это если не упереться в дишный тормозной GC.
_>Подразумевалось супербыстродействие в сравнение с вариантом "поставлять тексты на том DSL в конечном приложение и просто запускать рантайм интерпретатор их".
Ну это-то понятно.
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[29]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, Klapaucius, Вы писали:
EP>>>>То есть на равном месте вводится межпоточная синхронизация, об этом и речь. K>>>А вы точно читали то, на что я ссылаюсь? EP>>Точно. Там используется lock-free алгоритм для межпоточной синхронизации K>Выделено. Вы не поняли, для чего это нужно или есть идеи получше?
В смысле? Возможно одновременное изменение/чтение одних и тех же данных из нескольких потоков — поэтому и вводится синхронизация.
Re[28]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Неудобно как-то получается, да? Вроде UFP (захват free variable замыканием) — а GC ничем помочь не может
Еще как может. Время жизни продлевает, UFP решает. Вот только prompt finalization такое продлевание не способствует.
EP>>>можем ли мы сделать замыкание на идентификатор ресурса (в funarg ведь про идентификаторы речь) и передать это замыкание наверх? K>>В C# можем, EP>Как? Транзитивно заражая все места использования ручным using'ом?
Нет, наоборот, using никогда не используем. Тогда время "открытости" ресурса будет примерно совпадать со временем жизни захваченного в замыкание объекта. Примерно потому, что: 1) Финализируемый ресурс живет несколько дольше объекта. 2) Ресурс всегда можно закрыть вручную. Строго говоря, контроль рантайма за ресурсами вроде файлов меньше, чем за памятью. Т.е. с большей вероятностью произойдет что-то за пределами рантайма, что сделает файл непригодным для записи.
Т.е. в смысле продления жизни и решения UFP все обстоит лучше либо так же, как и в плюсах. С prompt finalization же все обстоит наоборот хуже. Ну так в этом трейдофф. Для памяти имеет смысл выбрать решение UFP, для файлов закрытие сразу по прекращению использования важнее.
EP>ST не работает в Haskell 98, то есть требует расширение?
Haskell 98 — это подмножество языка, выделенное для того, чтоб гарантировать компилируемость кода в учебниках для начинающих.
EP>как?
Я вам давал ссылку на монадические регионы.
EP>В случае с C++ я знаю как и насколько он поддерживает functional programming. Относительно UFP — я вам приводил несколько вариантов решения, причём которые работают не только для памяти.
Гарантии на продлевание жизни захваченных языковых сущностей ни одно из этих "решений" не дает, а значит и UFP не решает.
EP>Этого видимо недостаточно, поэтому я привёл цитату из haskel.org wiki — чтобы сослаться хоть на какой-то авторитет.
Почему haskell выделено жирным? Намекаете, что это авторитетный ресурс по C++? Я же говорю, перепишите на плюсах функциональный "хеллоуворлд", потом расскажете, как вам помогла авторитетность анонимного вики-контрибьютора.
EP>Так, восстанавливаем контекст: EP>1. Изначально речь шла про автоматическое преобразование обычного кода в монадический.
Ну да. Но это, строго говоря, непонятно как делать, потому что монадичность добавляет возможности, которых раньше не было. В том же вашем примере уже есть обработка пустого значения (одна из веток if возвращает () — не понятно, что это может значить в чистом коде), так что имеет место только замена одной монады на другую. Вот автоматический лифтинг в апплиативный функтр — это более реально.
EP>2. Implicit лифтированние операторов помогает только в некоторых случаях
Ну да, так я показывал именно то, что спрашивал Синклер — обобщенный аналог лифтинга операторов в Nullable.
EP>Например alex_public показал автоматическое лифтирование в D, так вот — там и foldl и foldr не дают необходимого монадического эффекта для Maybe (будут обрабатываться все элементы, даже если есть Nothing). EP>3. В Haskell, за счёт ленивости — получается достичь необходимых монадических эффектов за счёт лифтирования в большем классе случаев, но далеко не во всех. Например для foldr+Maybe работает, а для foldl — нет.
Тут не в монадах дело. foldr для cons и foldl для snoc (но не наоборот) просто можно вычислять с ранним прерыванием. Без всяких монад:
Именно за счет ленивости. foldr в этих примерах не делается монадическим. Вы на сигнатуры посмотрите.
Соотвественно и для операций с Maybe раннее завершение обеспечивает не "монадичность", а ленивость. И без ленивости и след. раннего завершения просто от Maybe мало толку.
EP>Т.е. в общем случае код всё равно придётся переделывать на монадический — ленивость помогает только в некоторых специфичных случаях.
Чем вам эта "монадичность" тут без ленивости поможет? Раннее завершение с помощью именно монады — это монада Cont[inuation].
А ленивость помогает во всех случаях, где это возможно. То, что востребовано для каких-то вычислений невычислить все равно нельзя.
EP>В языках же с call-with-current-continuation: любой код можно сделать монадическим без модификаций (либо нужно сделать минимальные модификации, заменив "x" на "get(x)" — если нет перегрузки всего как в D.
Чего его делать — он и так уже монадический. Одну монаду на другую заменить можно (ряд монад с помощью Cont[inuation] можно заменить, правда не все).
EP>
K>>Мы вроде бы в соседней ветке выяснили, что без ленивости комбинирование функций теряет смысл из-за непрактичности.
EP>Хотя ничего подобного мы не выясняли
Т.е. вычислять ненужное — это практично? Или непрактичность не делает комбинирование бессмысленным? Или имеется в виду, что call-with-current-continuation тоже дает возможность получать комбинаторый код, который не делает бессмысленных действий? Ну да, только реализация языка с континьюэйшенами, которая с более-менее приличной скоростью работает — это сложнее, чем реализация ленивого языка.
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[26]: Есть ли вещи, которые вы прницпиально не понимаете...
_>Вот вот. Собственно говоря, из-за иммутабельности данных в ФП языках вообще нет понятия ссылки, как её понимают в C++ (поменяем данные в одном месте кода и это уловил код в другом месте)
Я надеюсь, вы это все не всерьез пишете.
>
let foo n = do
r <- newIORef n
return (readIORef r, writeIORef r)
> (r, w) <- foo 2
> r
2
> w 42
> r
42
Это семантически наблюдаемое изменение.
Ленивость же использует мутабельность "под капотом", что важно для производительности, но наблюдается только в отладчике:
> let l = [1..]
> :sprint l
l = _
> let l2 = l
> :sprint l2
l2 = _
> l !! 3
4
> :sprint l
l = 1 : 2 : 3 : 4 : _
> :sprint l2
l2 = 1 : 2 : 3 : 4 : _
_>а есть только копирование (то, что внутри оно может оптимизироваться через ссылки, значения не имеет).
Да почему не имеет-то? Да, если не использовать мутабельные ссылки, то семантически наблюдаемой разницы между передачей по ссылке и копированием нет. Но эффективность реализации имеет критическое значение. Какой смысл в фиче, если ее нельзя использовать из-за неприемлимой тормознутости?
_>1. Непонятно с чего вы требуете от C++ наличия [&] вверх по стеку, в то время как чистые ФП языки не имеют этого даже вниз по стеку?
см. выше.
_>Собственно сама конструкция & — это признак скорее императивного языка.
Это не так, потому что в декларативных языках есть, в основном, все то же самое, что и в императивных — только в более управляемом виде. Но, даже если и так — так что с того? Императивному языку не нужно это поддерживать в лямбдах? Как раз наоборот, нужно. И императивные языки с решенной UFP вроде C# поддерживают.
> Да, и кстати [&] вверх по стеку в C++ тоже есть — shared_ptr.
Тормоза и проблемы с циклическими ссылками.
_>2. Непонятно почему вы пренебрегаете новой возможностью C++, обеспечивающей возможность осуществлять "копирование из покидаемой области" с нулевыми накладными расходами — она же как раз полностью решает проблему эффективности [=], делая его таким же эффективным как в ФП языка?
Чего непонятного-то? Я же объяснил. Этот самый "эффективный [=]" позволяет иметь сколько угодно "копий", а то, о чем вы говорите подразумевает только передачу, а не разделение.
_>А например в C++ мы имеем:
_>1. = вверх и вниз по стеку естественно. _>2. const& вниз по стеку, т.е. оптимизированное = вниз по стеку _>3. && (то самое перемещение), т.е. оптимизированное = вверх по стеку _>4. & вниз по стеку, причём оно оптимизировано от рождения _>5. shared_ptr, как реализация & вверх по стеку
Целый парад инвалидов. А нормальной ссылки как не было — так и нет. Выбор хорош тогда, когда его можно не делать — есть хорошее решение по умолчанию, а какое-то другое решение нужно принимать в краевых ситуациях. На C++ же нормального решения по умолчанию нет, есть только краевые, и вдоль вот этих вот стенок "пространства решений" программисту и предлагается двигатся. В результате ФП для него будет не средством облегчения написания и поддержки кода, а цирком с конями в лучшем случае, и изощренной пыткой в остальных.
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[28]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>>>>>Про "неработающие" замыкания в C++ из-за UFP любители GC мне тут уже третий раз говорят, хотя "плюсисты" не имеют с этим проблем. На деле же оказывается что работают, и не только для памяти. EP>В выделенном разговор был не про ФП.
Ну а как можно не испытывать проблем с неработающими замыканиями, если только не пользоваться ими нормально, а рассказывать на форумах про то, что они якобы работающие?
EP>На C++ как раз высокоуровневый код отлично мэппится в железо. The Standard Template Library
Высокоуровневый код — это когда можно делать вид, что языковые сущности — это математические объекты, содержательно рассуждать о них в таком ключе и получать нормально работающий код. Код с использованием STL, конечно, повыше уровнем, чем код на языках 60-х годов, но сейчас уже 2010-е.
EP>То что где-то дорогие абстракции — не означает что они дорогие везде. Естественно, если использовать связанные списки которые плохо мэппятся в железо, thunk'и которые на ровном месте добавляют меж-потоковую синхронизацию и излишние циклы требующие GC — то всё будет тормозить.
Точно, а если копировать массивы, считать ссылки и вычислять то, что вычислять ненужно все будет летать. Сравнимый по высокоуровневости код с такими подходами не то, что тормозить будет — он вообще никуда не поедет. Поэтому никакого высокоуровневого кода и нет — есть только продвинутый интерфейс для двигания указателей. А поддержка высокоуровневых инструментов ограничивается заявлениями о их ненужности. В принципе, объявление всего, чего нет ненужным можно описать словами "все решено" — в каком-то смысле это решение.
EP>В железе есть: изменяемая память(доступ к которой происходит большими порциями ~64B), многоуровневые кэши, синхронизация между кэшами, изменяемые регистры, стэк (с готовыми инструкциями для работы с ним), указатель на текущую инструкцию и разнообразные переходы. Само собой, если даже самые низкоуровневые абстракции в языке делают вид что ничего этого нет и вносят большое penalty сами по себе — то всё будет тормозить.
Самая низкоуровневая абстракция в плюсах — указатель — как раз делает вид, что ничего этого нет. Что память плоская, а не иерархичная, что она с произвольным доступом и т.д.
EP>Так я об этом и говорю — в языках с GC абстракции скрывающие памяти есть, а для других ресурсов как-то не завезли.
Ну правильно, ссылки на абстракции для других ресурсов вроде pipes вы проигнорировали.
K>>В высокоуровневом языке различие между передачей по ссылке и копированием вообще чаще всего семантически ненаблюдаемо. EP>А тут что?
См. выделенное.
EP>Кстати, а зачем используют эту венгерскую ноткацию? Почему не просто "modify" вместо "modifySTRef"?
Зачем вообще венгерскую нотацию используют? По глупости, очевидно. Я тут по соедству уже такие имена высмеивал.
EP>Вопрос в том как передать это замыкание наверх, а не запретить передачу.
Передавайте без всяких брекетов и все будет жить неизвестно сколько. Впрочем, я это подробно описал в соседней подветке.
K>>Связывание управления памятью с управлением дефицитными ресурсами там ни к чему хорошему не приводит.
EP>О каком управлением памятью идёт речь? EP>В C++ есть объекты, у этих объектов есть lifetime. Объекты могут абстрагировать работу с любым ресурсом — память, файлы, соединения и т.п.
Ну понятно, про языки с ГЦ можно еще сказать, что управление памятью там абстрагировано. Но в каком смысле мы абстрагируемся от управления памятью в C++, если гарантии на доступность языковых сущностей нет и постоянно нужно выбирать каким способом и где именно их размещать, каким способом передавать/возвращать и т.д. Что абстрагировано-то?
EP>Что делать в случае когда у нас несколько ресурсов, время жизни которых пересекаются и зависят друг от друга? (решение с использованием одного большого scope — естественно неинтересно)
Ну так в пейпере про монадические регионы, ссылку на который я давал, описаны вложенные регионы.
EP>Так вопрос же про возвращение замыкания.
Какой смысл тогда вообще регионы использовать?
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[33]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, Ikemefula, Вы писали:
I>Ну стало быть, согласно твоим словам, ты считаешь что Эрлан это другое название для С++, других объяснений нет
Нет) Я просто не пойму, почему ты считаешь, что факт существования каких-то аналогов MPI противоречит факту лидирующего положения MPI в программирование суперкомпьютеров и вычислительных кластеров.
Re[29]: Есть ли вещи, которые вы прницпиально не понимаете...