Re[15]: Ленивость или Энергичность по умолчанию?
От: Курилка Россия http://kirya.narod.ru/
Дата: 27.02.07 09:55
Оценка: +1
Здравствуйте, Аноним, Вы писали:


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


Давай, не будем делать необоснованных заявлений, пожалуйста

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


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


А теперь расскажи, что из этого следует для серьёзных софтовых систем. Чистота ради чистоты — это круто. Но в реальности нужно решать конкретные задачи. Давай исходить из этой предпостылки.
Re[17]: Ленивость или Энергичность по умолчанию?
От: Klapaucius  
Дата: 27.02.07 13:01
Оценка:
Здравствуйте, lomeo, Вы писали:

L>Не понял


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

K>>Представте, что я тормоз и напишите код, который решает ту же самую задачу, выделяя O(1) памяти.

L>hFileSize? Делается точно также как и везде. В цикле читается буфер пока-не-EOF.

Я в экстазе, дорогая редакция! Короче говоря, я должен написать на C функцию и воспользоваться ей через FFI, так чтоли?
А если я хочу представить файл в виде списка, к которому можно будет применять map, fold, etc., но не поднимать его при этом в память полностью?

K>>Тут все дело в том, что используется чаще, lazy или strict.

L>Зависит от задач, имхо.

Я тоже так считаю.

L>Мы вообще о чем говорим? С чем Вы не согласны из того, что я сказал?


Ну вот опять пошло, поехало.

Кто я? Где я? Куда я, куда?!

Из чего вообще следует, что я с чем-то там не согласен. Я не готов с чем-то несоглашаться априори, мне нужна информация. Я просто задал вопрос.
... << RSDN@Home 1.2.0 alpha rev. 655>>
'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[17]: Ленивость или Энергичность по умолчанию?
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.02.07 13:11
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Это я видел. Он там упоминал potan'a, Зефирова и еще неизвестно кого. Но никаких указаний, что там Хаскелл повредил — не было. Более того, была фраза, что проект успешно завершился.


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

А>Дело не в legacy.


Ты сам только что утверждал это. Так что как-нибудь определись.

А> Попробуй перевернуть логику. Можно было бы делать все только на C/C++. Отчего нет?


Многие так и делают. Собственно реазультата можно добиться и на ассемблере. Вопрос только в стоимости и времени разработки. У С++ эти показатели самые плохие.

А> Все вполне заслуженно. Десятки миллионов строк кода. 90% того, что у тебя на столе, написано на C/C++ — это железобетонная реальность. Уж всяко не чета любым Жаба/Nemerle/whatever.


Большая часть кода ОС по прежнему написана на С. Но почему-то никто из-за этого не брасается писать что-то именно на этом языке.

А>И здесь оказывается, что:

А>1. Хаскелл рулит;
А>2. Хаскелл прекрасно интегрируется со всем этим.

Где он рулит то? Ты так долго доказывал, что рулит то как раз С++ только потому что на нем много кода написано, а как вывод у тебя вдруг получается, что рулит именно Хаскель.

Ты сам то не видишь алогичности этих рассуждений?

А>Что не так???


У меня вопрос — "Что так?".

А>Тут все ругают интероп. Кто-нибудь может внятно сформулировать — что не нравится ??? Я этот вопрос уже во всех (sub)ветках задаю — нет ответа.


Погляди, например как сделан интероп в дотнете. Думаю, вопросы отпадут сами собой. Да и еще раз повторюсь. Если язык полноценный, то и необходимость в интеропе намного меньше. В качестве примера могу привести Интеграцию Немерла со Студией. Для вычислительных и прикладных задач интероп не нужен вовсе, так как сам язык не медленее С++ и при этом имеется куча библиотек. Но интероп нужен для всзаимодействия со Студией. Она написана на С++ с использованием КОМ-а. Но и тут проблем нет. Интероп прозрачен и прост. Его в обще-то не видно даже. Это всего лишь описания интерфейсов и внешних функций. Никаких тебе генераторов, заморочет и т.п.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[18]: Ленивость или Энергичность по умолчанию?
От: Аноним  
Дата: 27.02.07 13:36
Оценка:
Здравствуйте, VladD2, Вы писали:

Я же написал
А>> Попробуй перевернуть логику
Re[18]: Ленивость или Энергичность по умолчанию?
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 27.02.07 14:24
Оценка: 19 (2)
Здравствуйте, Klapaucius, Вы писали:

K>Я, видимо плохо объясняю. Мне нужен список, каждый элемент которого вычисляется при использовании. При первом, втором, и так далее.


Возможно, это то, что я здесь понаписал дальше?

K>Я в экстазе, дорогая редакция! Короче говоря, я должен написать на C функцию и воспользоваться ей через FFI, так чтоли?


Не понял зачем С? Только Хаскель, разумеется, только IO монада, отсюда и императив.

K>А если я хочу представить файл в виде списка, к которому можно будет применять map, fold, etc., но не поднимать его при этом в память полностью?


Если нужен именно список, то unsafeInterleaveIO, как всегда, чтобы неленивое вычисление сделать ленивым:

hGetLines :: Handle -> IO [String]
hGetLines handle =
    unsafeInterleaveIO $
    ifM (hIsEOF handle) (return []) $ do
        x  <- hGetLine handle
        xs <- hGetLines handle
        return (x:xs)


ifM просто функция для облегчения работы с монадами.

ifM :: (Monad m) => m Bool -> m a -> m a -> m a
ifM cond yes no =
    do c <- cond
       if c then yes else no


Т.е. какой нибудь hGetLines handle >>= print . head прочтёт только первую строчку. А hGetLines handle >>= print . length прочтёт все, но память будет жрать O(1).

K>Из чего вообще следует, что я с чем-то там не согласен. Я не готов с чем-то несоглашаться априори, мне нужна информация. Я просто задал вопрос.


Не знаю, мне почудились претензии, но какие именно я не понял :-) Извиняюсь.
Re[17]: Ленивость или Энергичность по умолчанию?
От: Gaperton http://gaperton.livejournal.com
Дата: 28.02.07 08:50
Оценка: :))
Здравствуйте, Аноним, Вы писали:

А>И здесь оказывается, что:

А>1. Хаскелл рулит;
А>2. Хаскелл прекрасно интегрируется со всем этим.

А>Что не так???


Да есть пара пунктов, так, замечаний по мелочи.
1. Хаскель нифига не рулит ни разу.
2. Хаскель херово интегрируется с внешними системами.

А в остальном ты все правильно сказал.

Re[18]: Ленивость или Энергичность по умолчанию?
От: Аноним  
Дата: 28.02.07 23:05
Оценка: +1
Здравствуйте, Gaperton, Вы писали:

G>Да есть пара пунктов, так, замечаний по мелочи.

G>1. Хаскель нифига не рулит ни разу.
G>2. Хаскель херово интегрируется с внешними системами.

Ну, не рулит, так не рулит — Вам виднее.
Напоследок, соблаговолите уж, назовите какую-нить "внешнюю систему" с которой Хаскелл "херово интегрируется".
Re[19]: Ленивость или Энергичность по умолчанию?
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.03.07 09:42
Оценка:
Здравствуйте, <Аноним>, Вы писали:

G>>Да есть пара пунктов, так, замечаний по мелочи.

G>>1. Хаскель нифига не рулит ни разу.
G>>2. Хаскель херово интегрируется с внешними системами.

А>Ну, не рулит, так не рулит — Вам виднее.


Интересно, ты действительно не понял, что он сдебался над уровнем аргументации, приводя инвертированный аналог?

А>Напоследок, соблаговолите уж, назовите какую-нить "внешнюю систему" с которой Хаскелл "херово интегрируется".


Дотент. Интеграция просто нулевая. Даже специально портированный и доработаенный клон практически не пригоден для использования.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Ленивость или Энергичность по умолчанию?
От: GlebZ Россия  
Дата: 02.03.07 11:39
Оценка: +1
Здравствуйте, Gaperton, Вы писали:

G>2) Чужой код на хаскеле очень трудно понимать — требуется жестко ограничить выразительные средства и стиль кодирования code standard-ом.

А вот это мне особенно интересно. Если не секрет, как вы описали стили кодирования? Если тайна, можно примерно на словах описать?
... << RSDN@Home 1.2.0 alpha rev. 0>>
Re[6]: Ленивость или Энергичность по умолчанию?
От: ironwit Украина  
Дата: 03.03.07 06:55
Оценка:
Здравствуйте, VladD2, Вы писали:

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



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


VD>Уверяю тебя, что лучше тебя знаю где мне требуется производительность, а где нет. Я в этом вопросе уже свору собак съел.

чем ругатся лучше бы сказал задачу которая у тебя идет на пределе современного железа?
... << RSDN@Home 1.2.0 alpha rev. 0>>
Я не умею быть злым, и не хочу быть добрым.
Re[7]: Ленивость или Энергичность по умолчанию?
От: VladD2 Российская Империя www.nemerle.org
Дата: 03.03.07 10:17
Оценка:
Здравствуйте, ironwit, Вы писали:

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


У меня еще небыло других задач. Всегда хотя бы один участок кода, да требует максимально доступной производительности. К примеру, сейчас для интеграции Nemerle с VS нужно обеспечить максимально возможную скорость парсинга проекта. Парсинг делает штатный компилятор. Таким образом первый садии компилятор должен длетаь максимально быстро. Конечно 10% разницы никто не заметит. Но если бы использовался интерпретатор, то десятикратное отставание было бы просто неприемлемо.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Ленивость или Энергичность по умолчанию?
От: ironwit Украина  
Дата: 03.03.07 11:06
Оценка:
Здравствуйте, VladD2, Вы писали:

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


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


VD>У меня еще небыло других задач. Всегда хотя бы один участок кода, да требует максимально доступной производительности. К примеру, сейчас для интеграции Nemerle с VS нужно обеспечить максимально возможную скорость парсинга проекта. Парсинг делает штатный компилятор. Таким образом первый садии компилятор должен длетаь максимально быстро. Конечно 10% разницы никто не заметит. Но если бы использовался интерпретатор, то десятикратное отставание было бы просто неприемлемо.


понятно. спасибо.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Я не умею быть злым, и не хочу быть добрым.
Re[7]: Ленивость или Энергичность по умолчанию?
От: Gaperton http://gaperton.livejournal.com
Дата: 05.03.07 09:05
Оценка: 36 (4)
Здравствуйте, GlebZ, Вы писали:

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


G>>2) Чужой код на хаскеле очень трудно понимать — требуется жестко ограничить выразительные средства и стиль кодирования code standard-ом.

GZ>А вот это мне особенно интересно. Если не секрет, как вы описали стили кодирования? Если тайна, можно примерно на словах описать?

Я спрошу, сделали ли ребята документ. Если да, то выложу его сюда.

Основная проблема со стилями кодирования состояла в том, что Хаскель допускает огромное количество вариантов и подходов к реализации.

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

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

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

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

Ну и далее — нужно стилевое руководство для простого кодирования, что-то вроде best practices. С ним наибольшие проблемы, так как совершенно непонятно, что будет лучше а что хуже, в силу небольшого количества проессионалов в Хаскеле и небольшого опыта промышленного применения Хаскеля группами людей. В результате, людям сложно между собой договориться — нет общей базы.
Re[6]: Ленивость или Энергичность по умолчанию?
От: thesz Россия http://thesz.livejournal.com
Дата: 07.03.07 14:53
Оценка:
LCR>>2. часто хочется выполнить грязный код внутри чистого — а это значит, что все проверки компилятора накрываются медным тазом.
G>Разумеется, нет. Это всего-навсего означает, что компилятор даст тебе по рукам, если ты весь код не пометишь как грязный. Попробуй в Хаскеле вставить логгирование куда-нибудь вниз гражданского кода — огребешь тоже самое в точности. Или будешь вынужден протащить параметр наверх, или расставишь везде свой монадный dirty. Нет?

Нет.

В Hawk лазить не стал, вот пример из нашего framework:
probesDir = "Probes"

probe'' f fn s = mapS writeProbe $ zipS s $ fromList [0..]
    where
        writeProbe (x,n) = unsafePerformIO $ do
            h <- openFile (probesDir++"/"++fn) (if n == 0 then WriteMode else AppendMode)
            hPutStrLn h $ show n++": "++show (f x)
            hClose h
            return x
probe' f fn s =
    -- choose one:
    --s    -- no probing.
    probe'' f fn s    -- probing.

probe fn s = probe' id fn s


Если поток значений пропустить через probe (
probe showFunction "probename" stream
), то получится такой же поток, только с созданием отчета при вычислениях (то есть, всегда.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Re[7]: Ленивость или Энергичность по умолчанию?
От: Gaperton http://gaperton.livejournal.com
Дата: 11.03.07 15:18
Оценка:
Здравствуйте, thesz, Вы писали:

G>>Разумеется, нет. Это всего-навсего означает, что компилятор даст тебе по рукам, если ты весь код не пометишь как грязный. Попробуй в Хаскеле вставить логгирование куда-нибудь вниз гражданского кода — огребешь тоже самое в точности. Или будешь вынужден протащить параметр наверх, или расставишь везде свой монадный dirty. Нет?


T>Нет.


T>В Hawk лазить не стал, вот пример из нашего framework:

хъ
T>Если поток значений пропустить через probe (
probe showFunction "probename" stream
), то получится такой же поток, только с созданием отчета при вычислениях (то есть, всегда.


unsafePerformIO играет роль const_cast в С++. В случае хаскеля это означает "внутри нашей чистой функции есть грязный код — вот он. Но мы закрываем на то глаза. И будь что будет". Это, пнимаешь ли, из той же оперы, что и монадный dirty.

Существенной разницы со строгим языком с побочными эффектами нет, не так ли?

pure f( X ) ->
X = do_something(),
X = make_pure( perform_hardcore_IO( X ) ),
do_something_else( X, Y ).
Re[8]: Ленивость или Энергичность по умолчанию?
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 11.03.07 18:00
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>unsafePerformIO играет роль const_cast в С++. В случае хаскеля это означает "внутри нашей чистой функции есть грязный код — вот он. Но мы закрываем на то глаза. И будь что будет". Это, пнимаешь ли, из той же оперы, что и монадный dirty.


G>Существенной разницы со строгим языком с побочными эффектами нет, не так ли?


С другой стороны, логгирование обычно слабо связано с логикой работы функции/программы. В частности, побочный эффект, который оно вызывает, не влияет на работу функции/программы. Функцию по прежнему можно считать чистой (с точки зрения логики программы). Поэтому для логгирования, по моему, unsafePerformIO вполне допустим.

Хотя я бы всё же предпочёл это явно пометить монадой. Это потому, что в логгировании ленивого исполнения я большого смысла не вижу.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[9]: Ленивость или Энергичность по умолчанию?
От: Gaperton http://gaperton.livejournal.com
Дата: 12.03.07 07:58
Оценка: +1
Здравствуйте, lomeo, Вы писали:

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


G>>unsafePerformIO играет роль const_cast в С++. В случае хаскеля это означает "внутри нашей чистой функции есть грязный код — вот он. Но мы закрываем на то глаза. И будь что будет". Это, пнимаешь ли, из той же оперы, что и монадный dirty.


G>>Существенной разницы со строгим языком с побочными эффектами нет, не так ли?


L>С другой стороны, логгирование обычно слабо связано с логикой работы функции/программы. В частности, побочный эффект, который оно вызывает, не влияет на работу функции/программы. Функцию по прежнему можно считать чистой (с точки зрения логики программы). Поэтому для логгирования, по моему, unsafePerformIO вполне допустим.


Разумеется — да. Именно в таких случаях и применяют const_cast в С. Я к тому, что эффективного практического отличия от кода с явными побочными эффектами здесь нет. То же самое, только вид сбоку.

L>Хотя я бы всё же предпочёл это явно пометить монадой. Это потому, что в логгировании ленивого исполнения я большого смысла не вижу.


Смысл такого логгирования есть — при декомпозиции через ленивые списки бесконечно рекурсивные функции описывающие блок у тебя ведут себя как параллельные процессы, и работают независимо. Соответственно, при попытке вставить туда логгирование у тебя нет особого выхода — либо протягивать еще один выход, в который уйдет лог или прочий ввод-вывод (что криво и неудобно), либо вкрячивать туда unsafePerformIO и делать ввод-вывод локально, от чего ровным счетом никакого вреда не будет кроме пользы (проще так и понятнее). В большинстве ситуаций. Т.е. ИМХО в приведенном thesz примере самое простое и правильное — использовать unsafePerformIO. Кстати, паттерн
Re[10]: Ленивость или Энергичность по умолчанию?
От: vdimas Россия  
Дата: 20.03.07 12:42
Оценка: 14 (1)
Здравствуйте, Klapaucius, Вы писали:

для бесконечного списка можно как-то так:
    public class LazyList<T> : IEnumerable<T>
    {
        private IEnumerator<T> _enum;
        private List<T> _buf = new List<T>();

        public LazyList(IEnumerable<T> seq) {
            _enum = seq.GetEnumerator();
        }

        public IEnumerator<T> GetEnumerator() {
            foreach (T item in _buf)
                yield return item;

            while (_enum.MoveNext()) {
                _buf.Add(_enum.Current);
                yield return _enum.Current;
            }
        }

        IEnumerator IEnumerable.GetEnumerator() {
            return GetEnumerator();
        }
    }


Ну и добавить немного кода для клонирования.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.