Здравствуйте, Павел Кузнецов, Вы писали:
ПК>alexeiz,
>> Что мне не нравится в большинстве предложений, это то, что лямбда функции определяются внутри (). Поэтому получается, что {} скобки появляются внутри () скобок, и это очень неестественно для C-подобных языков. Так уже сделано в Java и C#. Выглядит это плохо, нечитабильно. В то же время, для родных конструкций типа for блок {} идёт сразу за конструкцией, а не находится внутри неё. Поэтому, хочется, чтобы алгоритмы выглядели как можно ближе к родным конструкциям.
ПК>Мои "мучения" начались именно с этого (плюс ниже), но сейчас к данному неудобству я отношусь уже намного спокойнее, и даже готов смириться, больше "напрягает" второе.
>> Понятно, что нужно где-то определять сигнатуру лямбда функции, потому что функция, которая не принимает никаких параметров и не возвращает значение, не имеет никакого применения для стандартных алгоритмов (а ведь именно это и является целью: упрощение использования стандартных алгоритмов).
ПК>Требование явного задания сигнатуры мне кажется не менее неудачным, как и {} внутри (): тому же for никакая сигнатура для "вызова" {} не нужна. Есть устойчивое ощущение, что если применить для определения "сигнатуры" содержимого {} вывод типов, подобно некоторым функциональным языкам, то можно добиться полной аналогии с встроенными операторами. Причем, что интересно, в какой-то момент в обсуждении auto мелькали идеи возможности его использования для вывода результатов функций. Впрочем, за явное задание сигнатуры тоже есть свои аргументы...
>> Далее следует вопрос, а как организовать замыкания? Наиболее логично, как мне кажется, представлять замыкания как функтор, который имеет operator() и содержит ссылки на локальный контекст.
ПК>Такая модель будет адекватно работать только в случае, если время жизни замыкания не выходит за пределы времени жизни соответствующего контекста. Впрочем, для 99%, имхо, такое ограничение проблемой не является. Но хочется, оставшийся 1% тоже можно поддержать, пусть и несколько более сложным в использовании способом. Все время маячит идея какого-то синтаксиса для создания замыканий в динамической памяти, и перекладыванию ответственности за время жизни на программиста. Нужно только как-то согласовать, что в этом случае контекст таки должен копироваться. Для того, чтоб не было путаницы, скорее всего, более правильным было бы введение различного синтаксиса для "ссылочного" и "копирующего" использования переменных из окружающих блоков в лямбда-выражениях.
Здравствуйте, VladD2, Вы писали:
VD>АВК тебе сказал, что невозможность удаления элементов внутри оператора foreach языка C# обусловена не ограничениями этого оператора, а ограничениями итераторов стандартных контерйнеров.
Итераторы стандартных контейнеров тут совершенно ни причем. foreach не предоставляет знания о текущей позиции итератора. Следовательно, сколь нибудь разумное изменение итерируемой коллекции выглядит достаточно проблематично.
VD>Все! Точка! И не нужно разводить софистику на терминологическую тематику.
ЗЫ
Выделял-бы "смысл" в своих сообщения тем-же курсивом. А то, фильтровать очень тяжело.
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Здравствуйте, Шахтер, Вы писали:
Ш>У меня давно маячит вот такая идея.
Интересно. Только ИМХО надо немного доработать синтаксис чтобы можно было поддерживать всякие 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, например. Иначе поимеешь большие проблемы с парсером.
Ладно, над синтаксисом надо думать, конечно, сходу идеальный вариант не придумаешь...
Здравствуйте, Шахтер, Вы писали:
Ш>Так не пойдет. Слово gear доложно быть вводным, так же как слово template, например. Иначе поимеешь большие проблемы с парсером.
Не вижу проблем.
В C# вобще нет ни слова template ни generic но тем не менее генерики прекрасно работают.
Для того чтобы это работало не надо вводить дополнительных сущностей нужно просто расширить синтаксис определения функции. Ш>Ладно, над синтаксисом надо думать, конечно, сходу идеальный вариант не придумаешь...
Нужно еще придумать что делать с break, continue, return и как реализовывать конструкции типа switch.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, TK, Вы писали:
TK>Итераторы стандартных контейнеров тут совершенно ни причем. foreach не предоставляет знания о текущей позиции итератора. Следовательно, сколь нибудь разумное изменение итерируемой коллекции выглядит достаточно проблематично.
foreach (SomeType value in SomeCollection)
SomeCollection.Remove(value);
TK>ЗЫ TK>Выделял-бы "смысл" в своих сообщения тем-же курсивом. А то, фильтровать очень тяжело.
Каждый выделяет из сообщения то что ему кажется интеесным. Так что я расцениваю эти твои слова как банальное хамство.
... << RSDN@Home 1.1.4 beta 7 rev. 466>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Шахтер, Вы писали:
Ш>Так не пойдет. Слово gear доложно быть вводным, так же как слово template, например. Иначе поимеешь большие проблемы с парсером. Ш>Ладно, над синтаксисом надо думать, конечно, сходу идеальный вариант не придумаешь...
Здравствуйте, 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
В твоем коде удаляется не нужный элемент, а какой придется. Да и возможная производительность твоего кода выглядит очень слабо...
Похоже, что ты даже элементарных вещей не понимаешь
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Здравствуйте, 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. Этим собственно все сказано.
Если есть нужда менять последовательность, то, в первую очередь, стоит задуматься о замене форыча на что то другое, благо (в плюсах) есть на что.
Здравствуйте, Юнусов Булат, Вы писали:
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 нереально использовать для сколько-нибудь сложных модификаций содержимого коллекций.
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, 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>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.