Здравствуйте, Павел Кузнецов, Вы писали:
ПК> Я, например, последнее время "болею" идеей, как бы можно было бы ввести в язык такую "фичу", чтоб прямо в терминах языка можно было бы for и while прозрачно выразить, оставив в языке только if и goto. Это, собственно, не для for и while нужно, а для того, чтоб алгоритмы, подобные тому, что в STL, были бы в языке first class citizens. А в C#, напротив, foreach в язык "воткнули". Вот такая вот разница.
Хе-хе . Если "язык" — это С++, то все довольно просто. Поехали:
1) Разрешаем в языке т.н. замыкания. Это подразумевает возможность определения функций внутри функций — в локальном контексте, причем из внутренней функции видны переменные, которые определены во внешней.
2) Разрешаем лямда-выражения. Таким образом, что в частности любые операторные скобочки {} определяют безымянную функцию вида void(), а параметры туда будут передаваться неявно, связываясь с локальным контекстом (см пункт 1).
3) Теперь, разрешаем отделять аргументы функций точкой с запятой. Тип такого выражения — функция, употребление {} необходимо только чтобы разрешать противоречия (см пункт 2). Если скобки {} опущены, то тело функции состоит из одного выражения до первой ";".
4) Самое сложное. Надо добавить возможность функции брать в качестве аргумента выражение (функцию) после скобок. Так, чтобы была возможность определить for, например, таким образом.
Здравствуйте, Павел Кузнецов, Вы писали:
>> Невозможность модификации контейнера это не ограничение foreach, а ограничение итераторов стандартных контейнеров.
ПК>Ну и что? Речь шла о том, что foreach подходит не везде. Это был один из примеров. Собственно, суть сводится к тому, что алгоритмов, связанных с обходом контейнера много, и foreach — один из них, далеко не всегда наиболее подходящий.
Следи за губами — foreach это не алгоритм. Алгоритм находится внутри итератора. При наличии итератора, котjрый умеет определенным образом обрабатывать удаления? удалять внутри foreach можно.
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, Павел Кузнецов, Вы писали:
ПК>>например, попробуй-ка модифицировать контейнер, по которому "идешь" с помощью foreach)...
AVK>Невозможность модификации контейнера это не ограничение foreach, а ограничение итераторов стандартных контейнеров.
AndrewVK,
>>> Невозможность модификации контейнера это не ограничение foreach, а ограничение итераторов стандартных контейнеров.
> ПК> Ну и что? Речь шла о том, что foreach подходит не везде. Это был один из примеров. Собственно, суть сводится к тому, что алгоритмов, связанных с обходом контейнера много, и foreach — один из них, далеко не всегда наиболее подходящий.
> Следи за губами — foreach это не алгоритм.
1) Не хами, и не хамим будешь... 2) Все зависит от выбранной терминологии.
> Алгоритм находится внутри итератора.
В моей терминологии внутри итератора находится описание порядка обхода, а foreach — алгоритм, сводящийся к перебору элементов в порядке, заданном итератором. Скажем, remove_if — тоже алгоритм, тоже работающий, основываясь на порядке обхода, заданном итератором, но, очевидно, отличающийся от for_each. Если тебе удобнее называть for_each, find, find_first_if, search, equal, remove_if, copy_if, replace_if, reverse и т.п. другим словом, замени "алгоритм" на него в моих предыдущих сообщениях и ниже.
> При наличии итератора, котjрый умеет определенным образом обрабатывать удаления? удалять внутри foreach можно.
Еще раз. Возможность удаления внутри foreach не является центральным аргументом, это просто пример, тем не менее остающийся валидным: для стандартных итераторов удаление работать не будет. Аргументом является наличие других, отличных от foreach, алгоритмов (в понимании, описанном выше), которые во многих случаях подходят намного лучше.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, TK, Вы писали:
TK>Коллекция может содержать несколько одинаковых элементов.
А может не содержать. А возможно надо удалить любой из них. Это к делу не относится.
TK> В данном случае ты привел пример "неразумного" удаления
В данном случае ты не подумал. Если закрыть глаза на бессмысленость примера, то можно заметить, что в других случаях удаление по ключу или значению может оказаться очнь даже уместным.
TK>Давай проще. перепиши свой код для удаления всех цифр "7" следующих после "3" последовательность следующая: TK>7, 2, 7, 7, 4, 3, 3, 7, 7, 5, 7, 3, 7 после прохода должно получиться 7, 2, 7, 7, 4, 3, 7, 5, 7
А зачем мне твой приме? Других что ли не бывает?
TK>PS TK>В твоем коде удаляется не нужный элемент, а какой придется.
Это всего лишь пример. Он корректен и будет работать на коллекциях не запрещающих удаление во время перечисления. Что опровергает твои утверждения. Только и всего.
TK> Да и возможная производительность твоего кода выглядит очень слабо...
Возможная производительность зависит от реализации коллекции. Более того в некоторых коллекциях кроме как по ключю вообще удалять нельзя.
TK>Похоже, что ты даже элементарных вещей не понимаешь
Очередной пример хамства. Забавно, что ты пояляшся на этом форму только чтобы ответить на мои сообщения и почему-то постоянно пыташся "укусить".
... << RSDN@Home 1.1.4 beta 7 rev. 466>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>alexeiz,
>> Что мне не нравится в большинстве предложений, это то, что лямбда функции определяются внутри (). Поэтому получается, что {} скобки появляются внутри () скобок, и это очень неестественно для C-подобных языков. Так уже сделано в Java и C#. Выглядит это плохо, нечитабильно. В то же время, для родных конструкций типа for блок {} идёт сразу за конструкцией, а не находится внутри неё. Поэтому, хочется, чтобы алгоритмы выглядели как можно ближе к родным конструкциям.
ПК>Мои "мучения" начались именно с этого (плюс ниже), но сейчас к данному неудобству я отношусь уже намного спокойнее, и даже готов смириться, больше "напрягает" второе.
>> Понятно, что нужно где-то определять сигнатуру лямбда функции, потому что функция, которая не принимает никаких параметров и не возвращает значение, не имеет никакого применения для стандартных алгоритмов (а ведь именно это и является целью: упрощение использования стандартных алгоритмов).
ПК>Требование явного задания сигнатуры мне кажется не менее неудачным, как и {} внутри (): тому же for никакая сигнатура для "вызова" {} не нужна. Есть устойчивое ощущение, что если применить для определения "сигнатуры" содержимого {} вывод типов, подобно некоторым функциональным языкам, то можно добиться полной аналогии с встроенными операторами. Причем, что интересно, в какой-то момент в обсуждении auto мелькали идеи возможности его использования для вывода результатов функций. Впрочем, за явное задание сигнатуры тоже есть свои аргументы...
>> Далее следует вопрос, а как организовать замыкания? Наиболее логично, как мне кажется, представлять замыкания как функтор, который имеет operator() и содержит ссылки на локальный контекст.
ПК>Такая модель будет адекватно работать только в случае, если время жизни замыкания не выходит за пределы времени жизни соответствующего контекста. Впрочем, для 99%, имхо, такое ограничение проблемой не является. Но хочется, оставшийся 1% тоже можно поддержать, пусть и несколько более сложным в использовании способом. Все время маячит идея какого-то синтаксиса для создания замыканий в динамической памяти, и перекладыванию ответственности за время жизни на программиста. Нужно только как-то согласовать, что в этом случае контекст таки должен копироваться. Для того, чтоб не было путаницы, скорее всего, более правильным было бы введение различного синтаксиса для "ссылочного" и "копирующего" использования переменных из окружающих блоков в лямбда-выражениях.
VladD2,
> ПК> если посмотреть на результаты тестов, то можно увидеть, что bind в объеме делегатов C# работает на всех известных компиляторах.
> Что-то даже по этой ссылке не очень то на всех.
В объеме делегатов C# (кроме поддержки среды исполнения) — на всех.
> Просто смешно, что глупейший просчет одного человека залатывают трехкаленными наворотами метапрограммирования через 20 лет жизни языка.
Влад, это не просчет, это разница в подходе. Я, например, последнее время "болею" идеей, как бы можно было бы ввести в язык такую "фичу", чтоб прямо в терминах языка можно было бы for и while прозрачно выразить, оставив в языке только if и goto. Это, собственно, не для for и while нужно, а для того, чтоб алгоритмы, подобные тому, что в STL, были бы в языке first class citizens. А в C#, напротив, foreach в язык "воткнули". Вот такая вот разница.
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Влад, это не просчет, это разница в подходе. Я, например, последнее время "болею" идеей, как бы можно было бы ввести в язык такую "фичу", чтоб прямо в терминах языка можно было бы for и while прозрачно выразить, оставив в языке только if и goto. Это, собственно, не для for и while нужно, а для того, чтоб алгоритмы, подобные тому, что в STL, были бы в языке first class citizens.
По-моему, если не ошибаюсь, эта болезнь называется паранойя. Разве нет?
Извини, Паша, просто прикалываюсь
ПК>А в C#, напротив, foreach в язык "воткнули". Вот такая вот разница.
И очень правильно сделали. Весьма удобная штука. У меня в результате for перешёл в разряд редко используемых конструкций.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, Denis2005, Вы писали:
D>Здравствуйте, Павел Кузнецов, Вы писали:
>>> Просто смешно, что глупейший просчет одного человека залатывают трехкаленными наворотами метапрограммирования через 20 лет жизни языка.
ПК>>Влад, это не просчет, это разница в подходе. ... А в C#, напротив, foreach в язык "воткнули". Вот такая вот разница.
D>Павел, а собственно почему в язык "воткнули" RTTI? Страуструп сие безобразие аргументирует (вроде в "Дизайн и эволюция C++") тем, что появилось достаточно много библиотек с несовместимыми между собой реализациями (причина №1). D>И самое главное что он был в этом прав, т.к. мне самому 100 лет назад пришлось прикручивать в одном из крупных проектов свою реализацию RTTI к уже существующей. D>Назревает вопрос, а собственно почему в таком случае по той-же причине (№1) не включить в язык делегаты и пресловутый foreach. Уж самопальных реализаций делегатов мне пришлось поведать достаточно много, также в рамках одного проекта.
RTTI не имеет нормального решения на уровне библиотеки. Delegates имеют. В этом и заключается разница. Основной принцип комитета по стандартизации заключается в том, чтобы включать в язык то, что действительно там необходимо.
Кроме всего прочего, сходи на comp.std.c++ и проверь были ли там предложения по делегатам. Было ли это вообще кому-либо нужно.
Foreach не все считают необходимой feature. Хотя такое предложение появлялось в документах коммитета. Чем закончилось, не знаю.
> Причем более менее "человечную" реализацию (http://www.rsdn.ru/article/cpp/delegates.xml
) удалось осуществить лишь с появлением продвинутых компиляторов.
Я бы не назвал это человечной реализацией. Также спорно утверждение, что VC++7.0 — это продвинутый компилятор.
D>P.S. На мой взгляд "Страуструп и Ко" далеко не всегда правы в своих рассуждениях, а сообщество приверженцев C++ просто напросто закрывает глаза на их просчеты, и всячески пытается доказать, что так и должно быть.
Не нужно делать из Страуструпа диктатора в мире C++. Стандарт разрабатывает комитет по стандартизации. Страуструп всего лишь один из его членов. В коммитете много толковых людей. Посмотри предложения, которые коммитет обсуждает. Страуструп является соавтором разве что нескольких из них.
Здравствуйте, alexeiz, Вы писали:
A>Ты еще многого не знаешь.
Можно привести ход мыслей приводящий в конечном счете к такому выводу?
>>> В этом и заключается разница. Основной принцип комитета по >>> стандартизации заключается в том, чтобы включать в язык то, что >>> действительно там необходимо. >> >> Так ли мне необходимо в языке ключевое слово mutable?
Внятных ответов пока небыло...
К вопросу добавляем необходимость ключевого слова volatile.
>>> Я бы не назвал это человечной реализацией. Также спорно >>> утверждение, что VC++7.0 — это продвинутый компилятор. >> >> Чем неустраивает?
A>Много чем.
Благодарю за полный и исчерпывающий ответ.
A>libsigc++ существовал испокон веков. Если ты черпаешь знания только из A>этого форума, то тогда понятно, почему ты приходишь к таким выводам.
По подробней... испокон веков — это XX век?
Често признаюсь, что этот компилятор в руках не держал, но я его даже не нахожу в этом списке: http://engineering.meta-comm.com/boost-regression/CVS-HEAD/developer/bind_.html.
Черпаю знания в основном из личного опыта, но не буду лукавить, кое-чего подчеркул из этого форума.
A>PS. Я думал, ты хочешь получить честный ответ, почему того или иного нет в A>C++. Из твоих реплик видно, что ты, оказывается, хочешь поспорить, A>пофлэймить, значит. ...And flame thou shalt receive!
Чего я не получил, так это не одного т.с. честного ответа из ваших сообщений.
Здравствуйте, Gaperton, Вы писали:
G>2) Разрешаем лямда-выражения. Таким образом, что в частности любые операторные скобочки {} определяют безымянную функцию вида void(), а параметры туда будут передаваться неявно, связываясь с локальным контекстом (см пункт 1).
Багу нашел. Для фигурных скобок есть исключение. Если функция void(), которая определяется посредством {}, не является аргументом другой функции, то она инлайнится в то место, где она определена.
Вот теперь все в порядке, работать будет. Надеюсь, что эти расширения, придуманные сейчас мной, или что-то подобное никогда не станет частью языка С++, программирование на которм уже сейчас напоминает игру в драконий покер из книг Асприна.
VladD2,
> Паш, вникай в смысл, а резводи бодягу по каждому поводу.
Чего и вам желаю...
> АВК тебе сказал, что невозможность удаления элементов внутри оператора foreach языка C# обусловена не ограничениями этого оператора, а ограничениями итераторов стандартных контерйнеров.
Вот я именно по этому поводу уже третий раз и отвечаю: это на смысл исходного сообщения
, на которое отвечал AVK, вообще никак не влияет.
> Все! Точка! И не нужно разводить софистику на терминологическую тематику.
Вот о чем я и говорю в который раз: как называть foreach алгоритмом или валенком — не важно; важно, что таких "валенков" много, а поддержка в языке присутствует только для одного из них.
P.S. На этом я, пожалуй, закончу повторять одно и то же: кому захочется "вникнуть в смысл, а не развести бодягу по каждому поводу" — перечитает...
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Вот о чем я и говорю в который раз: как называть foreach алгоритмом или валенком — не важно;
Лучше называть его оператором. Будет всем спокойнее.
ПК> важно, что таких "валенков" много, а поддержка в языке присутствует только для одного из них.
В языке пристствует поддержка ООП. Его более чем хватает для создания большинства паттернов. Те что используются особо часто или те которые от интеграции с языком могут выиграть интегрируются в язык.
foreach — это еще фигня. Вот во многих современных языках встравивают такие фишки как list comprehension (конструктор списков). Если подходить к таким фичам с твоей позиции, то это просто таки надругательство над языком, так как в язык уже не просто встраивается паттерн. В его уже встраиваеются целые процедуры. Но вот работа со списками с их использованием становится почти декларативной.
В Руби, например, встроен такой "простенький" паттерн как continuations. Тоже надругательство.
Но вот что странно! Ты постоянно плюешся на подобные вещи в Шарпе и даже словом не объмолвишся о других языках. От чего такая изберательность? Давай обсудим Руби или Хаскель.
ПК>P.S. На этом я, пожалуй, закончу повторять одно и то же: кому захочется "вникнуть в смысл, а не развести бодягу по каждому поводу" — перечитает...
Ты это перед сном повторяй. Можно перед зеркалом. А то пожалуй кроме тебя все уже это запомнили. А тоы вот все пыташся докапаться до слова и уйти в другой лес.
... << RSDN@Home 1.1.4 beta 7 rev. 466>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, TK, Вы писали:
TK>Коллекция может содержать несколько одинаковых элементов. В данном случае ты привел пример "неразумного" удаления TK>Давай проще. перепиши свой код для удаления всех цифр "7" следующих после "3" последовательность следующая: TK>7, 2, 7, 7, 4, 3, 3, 7, 7, 5, 7, 3, 7 после прохода должно получиться 7, 2, 7, 7, 4, 3, 7, 5, 7
В плюсах for_each относится к Non-modifying sequence operations. Этим собственно все сказано.
Если есть нужда менять последовательность, то, в первую очередь, стоит задуматься о замене форыча на что то другое, благо (в плюсах) есть на что.
Здравствуйте, Павел Кузнецов, Вы писали:
>> Просто смешно, что глупейший просчет одного человека залатывают трехкаленными наворотами метапрограммирования через 20 лет жизни языка.
ПК>Влад, это не просчет, это разница в подходе. ... А в C#, напротив, foreach в язык "воткнули". Вот такая вот разница.
Павел, а собственно почему в язык "воткнули" RTTI? Страуструп сие безобразие аргументирует (вроде в "Дизайн и эволюция C++") тем, что появилось достаточно много библиотек с несовместимыми между собой реализациями (причина №1).
И самое главное что он был в этом прав, т.к. мне самому 100 лет назад пришлось прикручивать в одном из крупных проектов свою реализацию RTTI к уже существующей.
Назревает вопрос, а собственно почему в таком случае по той-же причине (№1) не включить в язык делегаты и пресловутый foreach. Уж самопальных реализаций делегатов мне пришлось поведать достаточно много, также в рамках одного проекта. Причем более менее "человечную" реализацию (http://www.rsdn.ru/article/cpp/delegates.xml
) удалось осуществить лишь с появлением продвинутых компиляторов.
P.S. На мой взгляд "Страуструп и Ко" далеко не всегда правы в своих рассуждениях, а сообщество приверженцев C++ просто напросто закрывает глаза на их просчеты, и всячески пытается доказать, что так и должно быть.
Здравствуйте, AndrewVK, Вы писали:
AVK>Невозможность модификации контейнера это не ограничение foreach, а ограничение итераторов стандартных контейнеров.
Для справки: В C# foreach не предоставляет доступ к текущей позиции итератора. так же, как и к самому итератору. И, даже если снять ограничение на изменение итерируемых контейноров — от кривости foreach это не спасет (так и представляю себе "красоту" реализации удаления элемента из середины связянного списка на базе foreach).
Хотя, не спорю — можно и головой гвозди забивать.
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Здравствуйте, VladD2, Вы писали:
VD>АВК тебе сказал, что невозможность удаления элементов внутри оператора foreach языка C# обусловена не ограничениями этого оператора, а ограничениями итераторов стандартных контерйнеров.
Итераторы стандартных контейнеров тут совершенно ни причем. foreach не предоставляет знания о текущей позиции итератора. Следовательно, сколь нибудь разумное изменение итерируемой коллекции выглядит достаточно проблематично.
VD>Все! Точка! И не нужно разводить софистику на терминологическую тематику.
ЗЫ
Выделял-бы "смысл" в своих сообщения тем-же курсивом. А то, фильтровать очень тяжело.
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
IT,
> ПК>А в C#, напротив, foreach в язык "воткнули". Вот такая вот разница.
> И очень правильно сделали. Весьма удобная штука. У меня в результате for перешёл в разряд редко используемых конструкций.
Это все хорошо, но в результате того, что только для foreach есть возможность такого удобного вызова, мы приходим к ситуации, когда у нас в руках молоток, и весь мир превращается в гвозди. Т.е. вместо того, чтоб вызвать remove_if, find_if, replace_if, copy_if и т.п., нам остается только "ручками" это каждый раз реализовывать или пытаться "присобачить" foreach, который далеко не всегда подходит (например, попробуй-ка модифицировать контейнер, по которому "идешь" с помощью foreach)...
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
IT,
> ПК> (например, попробуй-ка модифицировать контейнер, по которому "идешь" с помощью foreach)...
> Когда мне нужно модифицировать контейнер я использую for. Это как раз те самы редкие случаи
for для контейнеров .Net, как я понимаю, в этом смысле тоже далеко не бубль-гум. Например, как обходить контейнеры без произвольного доступа одновременно с модификацией? Кроме того, далеко не для всех контейнеров эффективная модификация тривиальна (см. реализацию remove_if для контейнеров с произвольным доступом). Имхо, от возможности удобной работы с алгоритмами, подобными тем, что в STL (for_each — только один из них), жизнь была бы лучше, а не хуже.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
IT wrote: > Здравствуйте, alexeiz, Вы писали: > >> В коммитете много толковых людей. Посмотри предложения, которые >> коммитет обсуждает. > > Обсуждать можно и на форуме RSDN. А вот решения принимать... это же > надо ответственность на себя брать. А это многим слабо.
Обсуждения на rsdn часто имеют форму флэйма.
Ты думаешь, ты "предложишь", а кто-то за тебя решение примет? Нет, друг.
Хочешь чего-то в C++, сам и проталкивай. На таких людях, кто хочет и может
проталкивать предложения, и держится C++. Внести что-либо в стандарт C++ —
это реальная работа. А тем, кому только пофлэймить нужно, им и флэймовского
форума достаточно.
Здравствуйте, alexeiz, Вы писали:
>> Ты лично предлагал?
A>Это что, попытка шапками забросать? До сих пор именно ты здесь являешься тем, кто плачется, о том как это бессмысленно.
Это попытка вывести демагога на чистую воду. Видишь как ты быстро сдался?
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Если нам не помогут, то мы тоже никого не пощадим.
Паш, ты уж извини, но ты начинашь очень сильно утомлять своей бессмысленной софистикой и докапыванием до слов.
Паш, вникай в смысл, а резводи бодягу по каждому поводу.
АВК тебе сказал, что невозможность удаления элементов внутри оператора foreach языка C# обусловена не ограничениями этого оператора, а ограничениями итераторов стандартных контерйнеров.
Все! Точка! И не нужно разводить софистику на терминологическую тематику.
... << RSDN@Home 1.1.4 beta 7 rev. 466>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Павел Кузнецов, Вы писали:
>> Следи за губами — foreach это не алгоритм.
ПК>1) Не хами, и не хамим будешь...
Я не хамлю. Просто намекаю на то что игнорировать слова собеседника не очень конструктивно.
ПК>2) Все зависит от выбранной терминологии.
Ага, это любимый твой конек — если чувствуешь что не прав перевести спор на обсуждение термингологии. Обсуждать терминологию я не буду. Принципиально.
>> При наличии итератора, котjрый умеет определенным образом обрабатывать удаления? удалять внутри foreach можно.
ПК>Еще раз. Возможность удаления внутри foreach не является центральным аргументом, это просто пример, тем не менее остающийся валидным: для стандартных итераторов удаление работать не будет.
А казалось бы, при чему тут конструкция языка foreach?
ПК> Аргументом является наличие других, отличных от foreach, алгоритмов (в понимании, описанном выше), которые во многих случаях подходят намного лучше.
foreach это не алгоритм, это синтаксический сахар. Пока ты этого не поймешь, дальнейшее обсмуждение бессмысленно.
Здравствуйте, TK, Вы писали:
TK>Итераторы стандартных контейнеров тут совершенно ни причем. foreach не предоставляет знания о текущей позиции итератора. Следовательно, сколь нибудь разумное изменение итерируемой коллекции выглядит достаточно проблематично.
foreach (SomeType value in SomeCollection)
SomeCollection.Remove(value);
TK>ЗЫ TK>Выделял-бы "смысл" в своих сообщения тем-же курсивом. А то, фильтровать очень тяжело.
Каждый выделяет из сообщения то что ему кажется интеесным. Так что я расцениваю эти твои слова как банальное хамство.
... << RSDN@Home 1.1.4 beta 7 rev. 466>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
TK>>Итераторы стандартных контейнеров тут совершенно ни причем. foreach не предоставляет знания о текущей позиции итератора. Следовательно, сколь нибудь разумное изменение итерируемой коллекции выглядит достаточно проблематично.
VD>
VD>foreach (SomeType value in SomeCollection)
VD> SomeCollection.Remove(value);
VD>
Коллекция может содержать несколько одинаковых элементов. В данном случае ты привел пример "неразумного" удаления
Давай проще. перепиши свой код для удаления всех цифр "7" следующих после "3" последовательность следующая:
7, 2, 7, 7, 4, 3, 3, 7, 7, 5, 7, 3, 7 после прохода должно получиться 7, 2, 7, 7, 4, 3, 7, 5, 7
PS
В твоем коде удаляется не нужный элемент, а какой придется. Да и возможная производительность твоего кода выглядит очень слабо...
Похоже, что ты даже элементарных вещей не понимаешь
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Здравствуйте, Шахтер, Вы писали:
Ш>Так не пойдет. Слово gear доложно быть вводным, так же как слово template, например. Иначе поимеешь большие проблемы с парсером. Ш>Ладно, над синтаксисом надо думать, конечно, сходу идеальный вариант не придумаешь...
Здравствуйте, IT, Вы писали:
IT>Не надо их использовать. Будут какие-то проблемы — будем решать их по мере поступления.
... IT>Для нетривиальных случаев будем использовать нетривиальный подход. Пока же всё примитивно и код должен быть примитивным.
... IT>мне пока и с foreach очень неплохо. В данном случае я с удовольствием готов пожертвовать некоторой избыточностью языка ради удобства и простоты.
Идея понятна. Называется она "не будем фигурять". Твой подход вполне нормален для конкретного пользователя языка или библиотеки. Ты оценил возможности языка по своим критериям и принял решение, что данный язык вполне подходит для твоих нужд. Подход вполне разумный. Однако для разработчика/дизайнера языка он не является приемлемым. Он должен мыслить за пределами "мне этого достаточно". И даже за пределами "этого достаточно для 90% пользователей". Есть разница, если язык разрабатывается, чтобы благодаря своим базовым возможностям иметь предельно широкий спектр применений, или для того, чтобы удовлетворить 90% потенциальных пользователей.
Здравствуйте, alexeiz, Вы писали:
IT>>мне пока и с foreach очень неплохо. В данном случае я с удовольствием готов пожертвовать некоторой избыточностью языка ради удобства и простоты.
A>Идея понятна. Называется она "не будем фигурять". Твой подход вполне нормален для конкретного пользователя языка или библиотеки. Ты оценил возможности языка по своим критериям и принял решение, что данный язык вполне подходит для твоих нужд. Подход вполне разумный. Однако для разработчика/дизайнера языка он не является приемлемым. Он должен мыслить за пределами "мне этого достаточно". И даже за пределами "этого достаточно для 90% пользователей". Есть разница, если язык разрабатывается, чтобы благодаря своим базовым возможностям иметь предельно широкий спектр применений, или для того, чтобы удовлетворить 90% потенциальных пользователей.
Мы сейчас обсуждаем как раз то как упростить язык, а не как его усложнить. Со вторым обычно проблем никогда не бывает. А вот первое — это как правило борьба противоположностей и как результат целый комплекс компромисов.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, alexeiz, Вы писали:
IT>>Мы сейчас обсуждаем как раз то как упростить язык, а не как его усложнить. Со вторым обычно проблем никогда не бывает. А вот первое — это как правило борьба противоположностей и как результат целый комплекс компромисов.
A>А ежели мы обсуждаем дизайн языка, то твой подход, — "мне это не нужно, значит и другие обойдутся", — неприемлим. О чём я и говорю.
В огороде бузина, а в Киеве дядька?
Мы не обсуждаем дизайн языка.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, alexeiz, Вы писали:
IT>>>Мы сейчас обсуждаем как раз то как упростить язык, а не как его усложнить. Со вторым обычно проблем никогда не бывает. А вот первое — это как правило борьба противоположностей и как результат целый комплекс компромисов.
A>>А ежели мы обсуждаем дизайн языка, то твой подход, — "мне это не нужно, значит и другие обойдутся", — неприемлим. О чём я и говорю.
IT>В огороде бузина, а в Киеве дядька?
Скатился? Аргументы кончились?
IT>Мы не обсуждаем дизайн языка.
А это что?
IT>>>Мы сейчас обсуждаем как раз то как упростить язык, а не как его усложнить
Здравствуйте, alexeiz, Вы писали:
A>RTTI не имеет нормального решения на уровне библиотеки.
Согласен!
A>Delegates имеют.
Несогласен. Только примитивные реализации, которыми собственно честной народ и занимается с очень давних пор.
Делегат это не просто указатель на объект + указатель на метод (кстати, Влад где-то об этом много говорил).
A>В этом и заключается разница. Основной принцип комитета по стандартизации заключается в том, чтобы включать в язык то, что действительно там необходимо.
) удалось осуществить лишь с появлением продвинутых компиляторов.
A>Я бы не назвал это человечной реализацией. Также спорно утверждение, что VC++7.0 — это продвинутый компилятор.
Чем неустраивает?
Ну если на то пошло, то вообще я предпочитаю Comeau и GCC, а прямых утверждений насчет "VC++7.0 — это продвинутый компилятор" с моей стороны небыло. Я пишу, что "человечная" реализация стала возможна на компиляторах вышедших где-то после 2001 года (которые стали лучше поддержитвать std98), а до этого "много воды утекло".
D>>P.S. На мой взгляд "Страуструп и Ко" далеко не всегда правы в своих рассуждениях, а сообщество приверженцев C++ просто напросто закрывает глаза на их просчеты, и всячески пытается доказать, что так и должно быть.
A>Не нужно делать из Страуструпа диктатора в мире C++. Стандарт разрабатывает комитет по стандартизации. Страуструп всего лишь один из его членов. В коммитете много толковых людей. Посмотри предложения, которые коммитет обсуждает. Страуструп является соавтором разве что нескольких из них.
Специально поясню, что под "Ко" имелся в виду комитет.
Здравствуйте, Denis2005, Вы писали:
A>>В этом и заключается разница. Основной принцип комитета по стандартизации заключается в том, чтобы включать в язык то, что действительно там необходимо.
D> Так ли мне необходимо в языке ключевое слово mutable?
Таки да.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
IT wrote: > Здравствуйте, alexeiz, Вы писали: > >> Ты думаешь, ты "предложишь", а кто-то за тебя решение примет? Нет, >> друг. Хочешь чего-то в C++, сам и проталкивай. На таких людях, кто >> хочет и может проталкивать предложения, и держится C++. Внести >> что-либо в стандарт C++ — это реальная работа. А тем, кому только >> пофлэймить нужно, им и флэймовского форума достаточно. > > Это плохая отмазка. Естественно я не буду ничего никуда проталкивать. > Хотя бы просто потому что понимаю бессмысленность этого занятия. Судя > по "количеству" фич, появившихся в C++ за последнее время — это > вообще никому не удалось.
Это не отмазка. Это — how things work. "Предложить" каждый может.
"понимаю бессмысленность этого занятия" — вот это настоящая отмазка.
IT wrote: > Здравствуйте, alexeiz, Вы писали: > >> Это не отмазка. Это — how things work. "Предложить" каждый может. >> "понимаю бессмысленность этого занятия" — вот это настоящая отмазка. > > Ты лично предлагал?
Это что, попытка шапками забросать? До сих пор именно ты здесь являешься
тем, кто плачется, о том как это бессмысленно.
IT wrote: > Здравствуйте, alexeiz, Вы писали: > >>> Ты лично предлагал? > >> Это что, попытка шапками забросать? До сих пор именно ты здесь >> являешься тем, кто плачется, о том как это бессмысленно. > > Это попытка вывести демагога на чистую воду. Видишь как ты быстро > сдался?
Я всегда пропускаю момент, когда нормальная дискуссия кончается, и тебе
пытаются навязать разборку по-понятиям. Что-ж, нужно тренировать глаз.
Здравствуйте, alexeiz, Вы писали:
>> Делегат это не просто указатель на объект + указатель на метод >> (кстати, Влад где-то об этом много говорил).
A>Нашел кого слушать. Всё, что Влад говорил, это частное мнение одного A>человека, далёкого от C++ к тому-же.
Он меня со спецификацией спутал.
... << RSDN@Home 1.1.4 beta 7 rev. 466>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Трурль, Вы писали:
Т>Здравствуйте, Gaperton, Вы писали:
G>>4) Самое сложное. Надо добавить возможность функции брать в качестве аргумента выражение (функцию) после скобок. Т>Может быть здесь пригодилась бы предлагаемая Страуструпом перегрузка пробела?
Не, по моему и так неплохо получилось. Только осталась еще одна одна маленькая проблема — с break, continue и return внутри безымянных {} блоков, а так — все хорошо.
Ну, это в целом тоже просто. Вводим еще одно правило — употребление имени функции типа void() при условии, что она не является, аргументом функции, эквивалентно вызову этой функции.
Эксцепшены будем ловить внутри for. Остался return — это жесткач. Вводим дополнительное правило — return, употребленный внутри безымянной функции void() приводит не только к выходу из нее, но к выходу из первой функции по стеку, не имеющей в определении модификатора passthrough (или defmacro - привет Lisp-ерам ). На функцию for вешаем модификатор passthrough, остальные функции по умолчанию его не имеют. Таким образом, у нас return будет работать корректно, как и раньше.
Интересная задачка из серии занимательный С++ , не находишь?
Здравствуйте, Шахтер, Вы писали:
Ш>Так не пойдет. Слово gear доложно быть вводным, так же как слово template, например. Иначе поимеешь большие проблемы с парсером.
Не вижу проблем.
В C# вобще нет ни слова template ни generic но тем не менее генерики прекрасно работают.
Для того чтобы это работало не надо вводить дополнительных сущностей нужно просто расширить синтаксис определения функции. Ш>Ладно, над синтаксисом надо думать, конечно, сходу идеальный вариант не придумаешь...
Нужно еще придумать что делать с break, continue, return и как реализовывать конструкции типа switch.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, Юнусов Булат, Вы писали:
TK>>Коллекция может содержать несколько одинаковых элементов. В данном случае ты привел пример "неразумного" удаления TK>>Давай проще. перепиши свой код для удаления всех цифр "7" следующих после "3" последовательность следующая: TK>>7, 2, 7, 7, 4, 3, 3, 7, 7, 5, 7, 3, 7 после прохода должно получиться 7, 2, 7, 7, 4, 3, 7, 5, 7
ЮБ>В плюсах for_each относится к Non-modifying sequence operations. Этим собственно все сказано. ЮБ>Если есть нужда менять последовательность, то, в первую очередь, стоит задуматься о замене форыча на что то другое, благо (в плюсах) есть на что.
Собственно, утверждение о немодифицирующем характере for_each и вызвало возражения со стороны Андрея и Влада. Насколько я понял, Тимофей, как раз и привел вполне веские основания, почему foreach нереально использовать для сколько-нибудь сложных модификаций содержимого коллекций.
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Влад, это не просчет, это разница в подходе. Я, например, последнее время "болею" идеей, как бы можно было бы ввести в язык такую "фичу", чтоб прямо в терминах языка можно было бы for и while прозрачно выразить, оставив в языке только if и goto. Это, собственно, не для for и while нужно, а для того, чтоб алгоритмы, подобные тому, что в STL, были бы в языке first class citizens. А в C#, напротив, foreach в язык "воткнули". Вот такая вот разница.
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>for для контейнеров .Net, как я понимаю, в этом смысле тоже далеко не бубль-гум. Например, как обходить контейнеры без произвольного доступа одновременно с модификацией?
Никак. Не надо их использовать. Будут какие-то проблемы — будем решать их по мере поступления.
ПК>Кроме того, далеко не для всех контейнеров эффективная модификация тривиальна (см. реализацию remove_if для контейнеров с произвольным доступом).
Для нетривиальных случаев будем использовать нетривиальный подход. Пока же всё примитивно и код должен быть примитивным.
ПК>Имхо, от возможности удобной работы с алгоритмами, подобными тем, что в STL (for_each — только один из них), жизнь была бы лучше, а не хуже.
Хуже может и не будет. Но мне пока и с foreach очень неплохо. В данном случае я с удовольствием готов пожертвовать некоторой избыточностью языка ради удобства и простоты. А удобство налицо. Не надо объявлять счётчик цикла + экономится строчка для получения указателя на элемент. Мелочь, а приятно.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Если нам не помогут, то мы тоже никого не пощадим.
Ты о том, что примитивное должно быть примитивным, а Павел — о том, что непримитивное тоже можно сделать примитивным.
Скажу так, что мне приходится регулярно модифицировать содержимое контейнеров в своих задачах на дотнете, и я удивлен — неужели ты используешь контейнеры в основном только для того, чтобы однажды заполнить и затем ничего с ним не делать?
В дотнете мне частенько приходится создавать именно копии контейнеров как результат работы алгоритма, ибо обработка "по месту" не всегда удобна/эффективна/возможна. (В твоем коде ты поступаешь аналогично)
Здравствуйте, vdimas, Вы писали:
V>Ты о том, что примитивное должно быть примитивным, а Павел — о том, что непримитивное тоже можно сделать примитивным.
Скорее не так. Паша говорит, что хочет иметь примитивный инструмент, а я утверждаю, что мне более важна простота результата его применения. Сама же сложность инструмента меня мало волнует.
V>Скажу так, что мне приходится регулярно модифицировать содержимое контейнеров в своих задачах на дотнете, и я удивлен — неужели ты используешь контейнеры в основном только для того, чтобы однажды заполнить и затем ничего с ним не делать?
Смотря в каком коде. В прикладном моё хобби — делать его максимально читабельным и отжимать лишнее. Из 10-ти строчек сделать 3, из 3-х одну. Соответственно, в данном случае возможности языка, его выразительность играют для меня первостепенную роль. В коде того же RFD у меня совсем другие приоритеты. Здесь более важна такая вещь как Reflection и Emit, т.е. не столько сам язык сколько платформа.
V>В дотнете мне частенько приходится создавать именно копии контейнеров как результат работы алгоритма, ибо обработка "по месту" не всегда удобна/эффективна/возможна. (В твоем коде ты поступаешь аналогично)
Ну и в чём проблема:
ArrayList newList = new ArrayList(oldList);
Ровно одна строчка
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Если нам не помогут, то мы тоже никого не пощадим.
Бессысленно противопоставлять оператор foreach и функциональный стиль. Они неплохо живут вместе. Когда-то удобен foreach, когда-то вызов функции. А когда-то и то и другое не применимо. Попробуй ради хохмы сравнить в функциональном стиле элементы двух деревьев. А банальным фором при наличии итераторов — это плевая задача.
... << RSDN@Home 1.1.4 beta 7 rev. 466>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, IT, Вы писали:
IT>Скорее не так. Паша говорит, что хочет иметь примитивный инструмент, а я утверждаю, что мне более важна простота результата его применения. Сама же сложность инструмента меня мало волнует.
Ты имел ввиду способа, ИМХО. Твоя позиция весьма трезвая, здесь многие стараются ее придерживаться.
V>>Скажу так, что мне приходится регулярно модифицировать содержимое контейнеров в своих задачах на дотнете, и я удивлен — неужели ты используешь контейнеры в основном только для того, чтобы однажды заполнить и затем ничего с ним не делать?
IT>Смотря в каком коде. В прикладном моё хобби — делать его максимально читабельным и отжимать лишнее. Из 10-ти строчек сделать 3, из 3-х одну. Соответственно, в данном случае возможности языка, его выразительность играют для меня первостепенную роль. В коде того же RFD у меня совсем другие приоритеты. Здесь более важна такая вещь как Reflection и Emit, т.е. не столько сам язык сколько платформа.
V>>В дотнете мне частенько приходится создавать именно копии контейнеров как результат работы алгоритма, ибо обработка "по месту" не всегда удобна/эффективна/возможна. (В твоем коде ты поступаешь аналогично)
IT>Ну и в чём проблема:
В доступе к контейнеру, который используется многими, и эти "многие" уже его держат через ссылку. Соответственно, мы здесь делаем прокси-контейнер для целевой коллекции, и все остальные держатся за этот прокси.
IT>
IT>ArrayList newList = new ArrayList(oldList);
IT>
IT>Ровно одна строчка
Ну, алгоритмы в STL тоже зачастую одна строчка.
В общем, если по главному моменту у тебя аналогичный поинт: "мне более важна простота способа его применения", то спорить не о чем, ИМХО.
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, alexeiz, Вы писали:
A>>Идея понятна. Называется она "не будем фигурять". Твой подход вполне нормален для конкретного пользователя языка или библиотеки. Ты оценил возможности языка по своим критериям и принял решение, что данный язык вполне подходит для твоих нужд. Подход вполне разумный. Однако для разработчика/дизайнера языка он не является приемлемым. Он должен мыслить за пределами "мне этого достаточно". И даже за пределами "этого достаточно для 90% пользователей". Есть разница, если язык разрабатывается, чтобы благодаря своим базовым возможностям иметь предельно широкий спектр применений, или для того, чтобы удовлетворить 90% потенциальных пользователей.
IT>Мы сейчас обсуждаем как раз то как упростить язык, а не как его усложнить. Со вторым обычно проблем никогда не бывает. А вот первое — это как правило борьба противоположностей и как результат целый комплекс компромисов.
А ежели мы обсуждаем дизайн языка, то твой подход, — "мне это не нужно, значит и другие обойдутся", — неприемлим. О чём я и говорю.
Denis2005 wrote: > Здравствуйте, alexeiz, Вы писали: > >> RTTI не имеет нормального решения на уровне библиотеки. > > Согласен! > >> Delegates имеют. > > Несогласен. Только примитивные реализации, которыми собственно > честной народ и занимается с очень давних пор.
Ты еще многого не знаешь.
> Делегат это не просто указатель на объект + указатель на метод > (кстати, Влад где-то об этом много говорил).
Нашел кого слушать. Всё, что Влад говорил, это частное мнение одного
человека, далёкого от C++ к тому-же.
> >> В этом и заключается разница. Основной принцип комитета по >> стандартизации заключается в том, чтобы включать в язык то, что >> действительно там необходимо. > > Так ли мне необходимо в языке ключевое слово mutable? > >>> Причем более менее "человечную" реализацию >>> (http://www.rsdn.ru/article/cpp/delegates.xml
) удалось осуществить >>> лишь с появлением продвинутых компиляторов. > >> Я бы не назвал это человечной реализацией. Также спорно >> утверждение, что VC++7.0 — это продвинутый компилятор. > > Чем неустраивает?
Много чем.
> Ну если на то пошло, то вообще я предпочитаю Comeau и GCC, а прямых > утверждений насчет "VC++7.0 — это продвинутый компилятор" с моей > стороны небыло.
В статье, которую ты привел, имелся ввиду именно этот компилятор. Если ты
что другое имел ввиду, так и надо было говорить.
>Я пишу, что "человечная" реализация стала возможна на > компиляторах вышедших где-то после 2001 года (которые стали лучше > поддержитвать std98), а до этого "много воды утекло".
libsigc++ существовал испокон веков. Если ты черпаешь знания только из
этого форума, то тогда понятно, почему ты приходишь к таким выводам.
> >>> P.S. На мой взгляд "Страуструп и Ко" далеко не всегда правы в своих >>> рассуждениях, а сообщество приверженцев C++ просто напросто >>> закрывает глаза на их просчеты, и всячески пытается доказать, что >>> так и должно быть. > >> Не нужно делать из Страуструпа диктатора в мире C++. Стандарт >> разрабатывает комитет по стандартизации. Страуструп всего лишь один >> из его членов. В коммитете много толковых людей. Посмотри >> предложения, которые коммитет обсуждает. Страуструп является >> соавтором разве что нескольких из них. > > Специально поясню, что под "Ко" имелся в виду комитет.
А кто такой этот коммитет? Это простые люди, как мы с тобой. Отличаются
они только тем, что желают потратить время и энергию на развитие C++.
PS. Я думал, ты хочешь получить честный ответ, почему того или иного нет в
C++. Из твоих реплик видно, что ты, оказывается, хочешь поспорить,
пофлэймить, значит. ...And flame thou shalt receive!
Здравствуйте, alexeiz, Вы писали:
A>Ты думаешь, ты "предложишь", а кто-то за тебя решение примет? Нет, друг. A>Хочешь чего-то в C++, сам и проталкивай. На таких людях, кто хочет и может A>проталкивать предложения, и держится C++. Внести что-либо в стандарт C++ — A>это реальная работа. А тем, кому только пофлэймить нужно, им и флэймовского A>форума достаточно.
Это плохая отмазка. Естественно я не буду ничего никуда проталкивать. Хотя бы просто потому что понимаю бессмысленность этого занятия.
Судя по "количеству" фич, появившихся в C++ за последнее время — это вообще никому не удалось.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, alexeiz, Вы писали:
A>Это не отмазка. Это — how things work. "Предложить" каждый может. A>"понимаю бессмысленность этого занятия" — вот это настоящая отмазка.
Ты лично предлагал?
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Если нам не помогут, то мы тоже никого не пощадим.
AndrewVK,
> ПК> например, попробуй-ка модифицировать контейнер, по которому "идешь" с помощью foreach)... > > Невозможность модификации контейнера это не ограничение foreach, а ограничение итераторов стандартных контейнеров.
Ну и что? Речь шла о том, что foreach подходит не везде. Это был один из примеров. Собственно, суть сводится к тому, что алгоритмов, связанных с обходом контейнера много, и foreach — один из них, далеко не всегда наиболее подходящий. Остальные алгоритмы столь же удобно использовать не представляется возможным.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, Юнусов Булат, Вы писали:
ЮБ>Здравствуйте, AndrewVK, Вы писали:
AVK>>Здравствуйте, Павел Кузнецов, Вы писали:
ПК>>>например, попробуй-ка модифицировать контейнер, по которому "идешь" с помощью foreach)...
AVK>>Невозможность модификации контейнера это не ограничение foreach, а ограничение итераторов стандартных контейнеров.
ЮБ>Сделали же итераторы с чеовечексим лицом и для форыча ЮБ>http://www.gotdotnet.com/community/usersamples/details.aspx?sampleguid=44999d9f-4713-4516-a5e9-60d680b86f0f
Какая-то не серьёзная подела. Я бы её в своём проекте использовать не стал.
Denis2005,
>>> Так ли мне необходимо в языке ключевое слово mutable? D>Внятных ответов пока небыло...
Некоторые классы нужно реализовать так, чтобы их объекты хранили счётчики обращений или ссылок к себе. Объекты могут быть константными и неконстантными, а счётчик должен меняться всегда. Вот здесь и mutable.
D>К вопросу добавляем необходимость ключевого слова volatile.
Подсказка компилятору "эта переменная может поменяться левым способом, поосторожнее с оптимизациями, друг!".
В нашу спецификацию закрался еще один баг. Проблемы с областью видимости. Вводим правило, что из определений функций-аргументов после скобок должен быть виден локальный контекст функций-аргументов, перечисленых внутри скобок. Чтобы контроллировать область видимости, вводим модификатор open. Таким образом, для цикла for это будет выглядеть так:
Здравствуйте, Gaperton, Вы писали:
G>4) Самое сложное. Надо добавить возможность функции брать в качестве аргумента выражение (функцию) после скобок.
Может быть здесь пригодилась бы предлагаемая Страуструпом перегрузка пробела?
Здравствуйте, Gaperton, Вы писали:
G>Эксцепшены будем ловить внутри for. Остался return — это жесткач. Вводим дополнительное правило — return, употребленный внутри безымянной функции void() приводит не только к выходу из нее, но к выходу из первой функции по стеку, не имеющей в определении модификатора passthrough (или defmacro - привет Lisp-ерам ). На функцию for вешаем модификатор passthrough, остальные функции по умолчанию его не имеют. Таким образом, у нас return будет работать корректно, как и раньше.
Мне, пожалуй, парочку!
G>Интересная задачка из серии занимательный С++ , не находишь?
Здравствуйте, Трурль, Вы писали:
Т>Здравствуйте, Gaperton, Вы писали:
G>>Эксцепшены будем ловить внутри for. Остался return — это жесткач. Вводим дополнительное правило — return, употребленный внутри безымянной функции void() приводит не только к выходу из нее, но к выходу из первой функции по стеку, не имеющей в определении модификатора passthrough (или defmacro - привет Lisp-ерам ). На функцию for вешаем модификатор passthrough, остальные функции по умолчанию его не имеют. Таким образом, у нас return будет работать корректно, как и раньше.
Т>Мне, пожалуй, парочку!
G>>Интересная задачка из серии занимательный С++ , не находишь? Т>
Думаете это все? Да это только начало. Домашнее задание: расширить С++ до такой степени, штобы в терминах языка можно было бы определить конструкцию switch . И пусть живые завидую мертвым.
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Влад, это не просчет, это разница в подходе. Я, например, последнее время "болею" идеей, как бы можно было бы ввести в язык такую "фичу", чтоб прямо в терминах языка можно было бы for и while прозрачно выразить, оставив в языке только if и goto. Это, собственно, не для for и while нужно, а для того, чтоб алгоритмы, подобные тому, что в STL, были бы в языке first class citizens. А в C#, напротив, foreach в язык "воткнули". Вот такая вот разница.
У меня в forth-компилере "ref" не только for и while, но и + и — и прочие "stdcall" и "uses" написаны на этом же языке.
D>К вопросу добавляем необходимость ключевого слова volatile.
Ну, если ты на C++ с аппаратурой не работаешь, то вряд ли тебе потребуется volatile.
Тут был здоровенный флэйм про мультипоточность и volatile: volatile у переменной класса
Здравствуйте, Gaperton, Вы писали:
G>>>Эксцепшены будем ловить внутри for. Остался return — это жесткач. Вводим дополнительное правило — return, употребленный внутри безымянной функции void() приводит не только к выходу из нее, но к выходу из первой функции по стеку, не имеющей в определении модификатора passthrough (или defmacro - привет Lisp-ерам ). На функцию for вешаем модификатор passthrough, остальные функции по умолчанию его не имеют. Таким образом, у нас return будет работать корректно, как и раньше.
Т>>Мне, пожалуй, парочку!
G>>>Интересная задачка из серии занимательный С++ , не находишь? Т>>
G>Думаете это все? Да это только начало. Домашнее задание: расширить С++ до такой степени, штобы в терминах языка можно было бы определить конструкцию switch . И пусть живые завидую мертвым.
Жестко. Так что там Гринспун про 10 правило говорил?
Gaperton,
> ПК> Я, например, последнее время "болею" идеей, как бы можно было бы ввести в язык такую "фичу", чтоб прямо в терминах языка можно было бы for и while прозрачно выразить, оставив в языке только if и goto. Это, собственно, не для for и while нужно, а для того, чтоб алгоритмы, подобные тому, что в STL, были бы в языке first class citizens. А в C#, напротив, foreach в язык "воткнули". Вот такая вот разница.
> Хе-хе . Если "язык" — это С++, то все довольно просто. Поехали: <...>
Да, что-то в более-менее похожем духе. Не обязательно в C++, но интересно. Сами for, while и т.п. переопределять, естественно, не предполагается. Хочется полноценной поддержки "алгоритмов", подобных STL algorithms. Естественно, для этого нужны лямбда-выражения и замыкания. На самом деле, далеко не обязательно, чтоб выглядело буквально как for и while, но хочется, чтоб количество лишних телодвижений у пользователя было минимальным. Также маячит идея, что (по мотивам некоторых функциональных языков) можно более удачно, чем шаблоны C++, ввести поддержку обобщенного программирования. В частности, в определенных случаях очень полезным может оказаться откладывание определения типа выражения, что в C++ не поддерживается. Например:
enum A { a };
enum B { b };
void foo(A);
void foo(B);
template< class T, class F >
void bar( T t, F f )
{
f( t );
}
void g()
{
bar( a, foo );
}
В C++ будет неоднозначность, т.к. выбрать тип foo в точке вызова bar не удастся. Хочется, чтоб можно было bar вызвать с "недовыведенным" типом. Есть устойчивое ощущение, что введение "прозрачных" замыканий лямбда-выражений зависит от возможности отложенного выведения типов.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Gaperton,
>> ПК> Я, например, последнее время "болею" идеей, как бы можно было бы ввести в язык такую "фичу", чтоб прямо в терминах языка можно было бы for и while прозрачно выразить, оставив в языке только if и goto. Это, собственно, не для for и while нужно, а для того, чтоб алгоритмы, подобные тому, что в STL, были бы в языке first class citizens. А в C#, напротив, foreach в язык "воткнули". Вот такая вот разница.
>> Хе-хе . Если "язык" — это С++, то все довольно просто. Поехали: <...>
ПК>Да, что-то в более-менее похожем духе. Не обязательно в C++, но интересно. Сами for, while и т.п. переопределять, естественно, не предполагается. Хочется полноценной поддержки "алгоритмов", подобных STL algorithms. Естественно, для этого нужны лямбда-выражения и замыкания. На самом деле, далеко не обязательно, чтоб выглядело буквально как for и while, но хочется, чтоб количество лишних телодвижений у пользователя было минимальным.
Что мне не нравится в большинстве предложений, это то, что лямбда функции определяются внутри (). Поэтому получается, что {} скобки появляются внутри () скобок, и это очень неестественно для C-подобных языков. Так уже сделано в Java и C#. Выглядит это плохо, нечитабильно.
В то же время, для родных конструкций типа for блок {} идёт сразу за конструкцией, а не находится внутри неё. Поэтому, хочется, чтобы алгоритмы выглядели как можно ближе к родным конструкциям. Например:
vector<int> v;
for_each(v.begin, v.end())
{
// lambda function
}
Здесь {} блок идёт сразу за вызовом функции вместо полагающейся точки с запятой.
Такая запись выглядет гораздо приличнее, естественнее и ближе к тому, чему мы все привыкли. Осталось только подумать, что нужно сделать, чтобы запись типа такой стала реальностью.
Понятно, что нужно где-то определять сигнатуру лямбда функции, потому что функция, которая не принимает никаких параметров и не возвращает значение, не имеет никакого применения для стандартных алгоритмов (а ведь именно это и является целью: упрощение использования стандартных алгоритмов).
Неплохо выглядет предложение использовать ; внутри параметров к функции. Например:
int b;
vector<int> v;
for_each(v.begin(), v.end(); void(int a))
{
cout << a + b << endl;
}
Здесь void(int a) — это сигнатура функции, определённой сразу за for_each().
Далее следует вопрос, а как организовать замыкания? Наиболее логично, как мне кажется, представлять замыкания как функтор, который имеет operator() и содержит ссылки на локальный контекст.
В такой модели, код приведенный выше, преобразуется во что-то вроде следующего:
struct __closure {
int & b_;
__closure(int & b) : b_(b) {}
void operator()(int a) {
cout << a << b_ << endl;
}
};
int b;
vector<int> v;
for_each(v.begin(), v.end(), __closure(b));
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Gaperton,
>> ПК> Я, например, последнее время "болею" идеей, как бы можно было бы ввести в язык такую "фичу", чтоб прямо в терминах языка можно было бы for и while прозрачно выразить, оставив в языке только if и goto. Это, собственно, не для for и while нужно, а для того, чтоб алгоритмы, подобные тому, что в STL, были бы в языке first class citizens. А в C#, напротив, foreach в язык "воткнули". Вот такая вот разница.
>> Хе-хе . Если "язык" — это С++, то все довольно просто. Поехали: <...>
ПК>Да, что-то в более-менее похожем духе. Не обязательно в C++, но интересно. Сами for, while и т.п. переопределять, естественно, не предполагается. Хочется полноценной поддержки "алгоритмов", подобных STL algorithms. Естественно, для этого нужны лямбда-выражения и замыкания. На самом деле, далеко не обязательно, чтоб выглядело буквально как for и while, но хочется, чтоб количество лишних телодвижений у пользователя было минимальным.
Базис языка (Си) очень плохо для этого подходит, ИМХО, что я и старался показать. Для достижения нормального результата (простой красивый язык) придется сказать С++ досвиданья.
ПК>Также маячит идея, что (по мотивам некоторых функциональных языков) можно более удачно, чем шаблоны C++, ввести поддержку обобщенного программирования.
Лучшее, что придумано на эту тему на данный момент — система типов Хиндли-Милнера, или нечто похожее. Примеры — система типов OCaml, Nemerle.
ПК>В частности, в определенных случаях очень полезным может оказаться откладывание определения типа выражения, что в C++ не поддерживается. Например: ПК>
ПК>enum A { a };
ПК>enum B { b };
ПК>void foo(A);
ПК>void foo(B);
ПК>template< class T, class F >
ПК>void bar( T t, F f )
ПК>{
ПК> f( t );
ПК>}
ПК>void g()
ПК>{
ПК> bar( a, foo );
ПК>}
ПК>
ПК>В C++ будет неоднозначность, т.к. выбрать тип foo в точке вызова bar не удастся. Хочется, чтоб можно было bar вызвать с "недовыведенным" типом. Есть устойчивое ощущение, что введение "прозрачных" замыканий лямбда-выражений зависит от возможности отложенного выведения типов.
Здесь проблема в другом. Система не знает детали устройства типа F, в то время как в языке с системой типов Хиндли-Милнера эти детали ей известны. Из контекста bar однозначно выводится, что тип F — это функция (функтор), отображающая T в нечто, чего компилятор С++ делать просто не умеет — система типов не позволяет .
В случае системы типов Хиндли-Милнера компилятор однозначно определит сигнатуру полиморфной функции без помощи программиста.
alexeiz,
> Что мне не нравится в большинстве предложений, это то, что лямбда функции определяются внутри (). Поэтому получается, что {} скобки появляются внутри () скобок, и это очень неестественно для C-подобных языков. Так уже сделано в Java и C#. Выглядит это плохо, нечитабильно. В то же время, для родных конструкций типа for блок {} идёт сразу за конструкцией, а не находится внутри неё. Поэтому, хочется, чтобы алгоритмы выглядели как можно ближе к родным конструкциям.
Мои "мучения" начались именно с этого (плюс ниже), но сейчас к данному неудобству я отношусь уже намного спокойнее, и даже готов смириться, больше "напрягает" второе.
> Понятно, что нужно где-то определять сигнатуру лямбда функции, потому что функция, которая не принимает никаких параметров и не возвращает значение, не имеет никакого применения для стандартных алгоритмов (а ведь именно это и является целью: упрощение использования стандартных алгоритмов).
Требование явного задания сигнатуры мне кажется не менее неудачным, как и {} внутри (): тому же for никакая сигнатура для "вызова" {} не нужна. Есть устойчивое ощущение, что если применить для определения "сигнатуры" содержимого {} вывод типов, подобно некоторым функциональным языкам, то можно добиться полной аналогии с встроенными операторами. Причем, что интересно, в какой-то момент в обсуждении auto мелькали идеи возможности его использования для вывода результатов функций. Впрочем, за явное задание сигнатуры тоже есть свои аргументы...
> Далее следует вопрос, а как организовать замыкания? Наиболее логично, как мне кажется, представлять замыкания как функтор, который имеет operator() и содержит ссылки на локальный контекст.
Такая модель будет адекватно работать только в случае, если время жизни замыкания не выходит за пределы времени жизни соответствующего контекста. Впрочем, для 99%, имхо, такое ограничение проблемой не является. Но хочется, оставшийся 1% тоже можно поддержать, пусть и несколько более сложным в использовании способом. Все время маячит идея какого-то синтаксиса для создания замыканий в динамической памяти, и перекладыванию ответственности за время жизни на программиста. Нужно только как-то согласовать, что в этом случае контекст таки должен копироваться. Для того, чтоб не было путаницы, скорее всего, более правильным было бы введение различного синтаксиса для "ссылочного" и "копирующего" использования переменных из окружающих блоков в лямбда-выражениях.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, Шахтер, Вы писали:
Ш>У меня давно маячит вот такая идея.
Интересно. Только ИМХО надо немного доработать синтаксис чтобы можно было поддерживать всякие find_if
void IntRange(int a, int b, name ValueName = i)
gear void X(int ValueName);
{
for(int i=a; i<=b ;i++)
X(i);
}
void IntStrangeRange(int a, int b, name ValueName = i)
gear(odd) void Odd(int ValueName);
gear(even) void Even(int ValueName);
{
IntRange(a, b, i)
if ( i & 1 )
Odd(i);
else
Even(i);
}
template<class Iter>
Iter find_if(Iter begin, Iter end, name ValueName = i)
gear bool Condition(Iter ValueName);
{
for (; begin != end; ++begin)
if (Condition(begin))
return begin;
return end;
}
int main()
{
int s = 0;
IntRange(1, 100)
s += i;
int odd_sum = 0;
int even_sum = 0;
IntStrangeRange(1, 100)
odd
odd_sum += i;
even
even_sum += i;
std::vector<int> v;
IntRange(1, 100)
v.push_back(i);
std::vector<int> iter = find_if(v.begin(), v.end())
{
return *i % 37 == 0;
}
return 0;
}
Так больше похоже на правду.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, Шахтер, Вы писали:
Ш>>У меня давно маячит вот такая идея. WH>Интересно. Только ИМХО надо немного доработать синтаксис чтобы можно было поддерживать всякие find_if WH>
WH>void IntRange(int a, int b, name ValueName = i)
WH>gear void X(int ValueName);
WH>{
WH> for(int i=a; i<=b ;i++)
WH> X(i);
WH>}
WH>void IntStrangeRange(int a, int b, name ValueName = i)
WH>gear(odd) void Odd(int ValueName);
WH>gear(even) void Even(int ValueName);
WH>{
WH> IntRange(a, b, i)
WH> if ( i & 1 )
WH> Odd(i);
WH> else
WH> Even(i);
WH>}
WH>template<class Iter>
WH>Iter find_if(Iter begin, Iter end, name ValueName = i)
WH>gear bool Condition(Iter ValueName);
WH>{
WH> for (; begin != end; ++begin)
WH> if (Condition(begin))
WH> return begin;
WH> return end;
WH>}
WH>int main()
WH>{
WH> int s = 0;
WH> IntRange(1, 100)
WH> s += i;
WH> int odd_sum = 0;
WH> int even_sum = 0;
WH> IntStrangeRange(1, 100)
WH> odd
WH> odd_sum += i;
WH> even
WH> even_sum += i;
WH> std::vector<int> v;
WH> IntRange(1, 100)
WH> v.push_back(i);
WH> std::vector<int> iter = find_if(v.begin(), v.end())
WH> {
WH> return *i % 37 == 0;
WH> }
WH> return 0;
WH>}
WH>
WH>Так больше похоже на правду.
Так не пойдет. Слово gear доложно быть вводным, так же как слово template, например. Иначе поимеешь большие проблемы с парсером.
Ладно, над синтаксисом надо думать, конечно, сходу идеальный вариант не придумаешь...