Здравствуйте, Кодёнок, Вы писали:
Кё>Кстати, а как в Nemerle сослаться на оператор + для класса, например, для целых? Пробовал System.Int32.op_Add и System.Int32.operator+, в документации не знаю где искать.
Здравствуйте, Lazy Cjow Rhrr, Вы писали:
LCR>Хм. Будет немного непривычно: LCR>
LCR>12.times { say 'hello' } // _1 принимает значения от 0 до 11
LCR>(2..16).times { say 'hello '_1 } // _1 принимает значения от 2 до 16
LCR>(10+.5).times { say 'hello '_1 } // _1 принимает значения от 5 до 14 (то есть 10 различных значений)
LCR>
Здравствуйте, VladD2, Вы писали:
VD>В Руби для таких случаев используется синтаксис: VD>
VD>foreach (i in 0...3) // то есть добавляется третья точка.
VD>
VD>Но это не интуитивно и легко путается с вариантом с двумя точками.
Это ты где в Ruby цикл foreach нашел?
В Ruby есть понятие Range, которое записывается либо с двумя точками (тогда это соответствует [a,b]), либо с тремя точками (что соответствует [a,b)).
Кроме того, если нужно перебрать все элементы контейнера, то используются методы each:
[1, 2, 3, 4].each { |item| ... }
Если нужно выполнить определенное количество циклов, то используется метод times:
10.times { |n| ... }
Если нужно перебрать значения от a до b, то можно использовать методы upto, downto или Range#each:
1.upto(10) { ... } # от 1 до 10.
10.downto(1) { ... } # от 10 до 1.
(1..10).each { ... } # от 1 до 10.
(1...10).each { ... } # от 1 до 9
Цикла foreach в Ruby нет. Есть for in, для которого важно, чтобы в итерируемом объекте был метод each:
Вы можете использовать for для итерации по любому объекту, который отвечает на метод each, например Array или Range:
for i in ['fee', 'fi', 'fo', 'fum']
print i, " "end
for i in 1..3
print i, " "end
for i in File.open("ordinal").find_all { |l| l =~ /d$/}
print i.chomp, " "end
выводит:
fee fi fo fum 1 2 3 second third
Как только ваш класс определяет соответствующий метод each, вы можете использовать цикл for для его обхода
class Periods
def each
yield"Classical"yield"Jazz"yield"Rock"end
end
periods = Periods.new
for genre in periods
print genre, " "end
VladD2 wrote:
> _>Честно говоря, С++ синтаксис мне больше всего нравится, т.к. более > гибок, позволяет перебирать не только целые числа в некоем интервале с > шагом 1, но фактически что угодно и как угодно. > > Понимаш ли в чем дело? С-шный for никто не отменяет. Но его гибкость > выливается в ошибки и усложнение чтения кода когда он используется для > простых вещей. > > Мы (люди) думаем абстракциями. Когда ты пишешь: > > for (int i = 0; i < array.Length; i++) > array[i] = f(array[i]); > > > ты реально думашь не так: > 1. Объявить перменную целого типа. > 2. Инициализировать ее нулем который является нижней границей массива. > 3. Выполнять условие цикла пока переменная не превысит значения длинны > массива. > 4. На каждой итерации увеличить индекс на один. > 5. Вынуть значение по индексу находящемуся в ячейке с номером заданным в > переменной i. > 6. Применить к значению функцию f(). > 7. Поместить значение преобразования по индексу находящемуся в ячейке с > номером заданным в переменной i.
Нет, конечно. Просто рассматривается цикл как конструкция из 3 частей — начальное условие; условие окончания; операция
получения следующего элемента.
И не важно, что перебирается — индексы, родители, или диапозон, или ещё что...
Мне нравится единообразие при многообразии
for(int i=0; i<arguments.length; i+=2)
{
map[arguments[i]] = arguments[i+1];
}
for(Node *parent = theNode; parent; parent = parent->getParent())
{
}
for(Range r(collection); r; ++r)
{
cout << *r;
}
char *list[] = {"aaa", "bbb", "ccc", NULL};
for(char **elem = list; *elem; ++elem)
{
}
//Синтаксис типа этого будет совершенно не в тему. А преимущества какие?
foreach( int i=[0..arguments.length) )
{
cout << arguments[i];
}
// Ещё можно оправдать такой синтаксис, тем, что выкидывается неиспользуемое здесь понятие "индекс"/"итератор",
используется только "коллекция" и её "элемент коллекции".
foreach int arg(arguments)
{
cout << arg;
}
В этом и заключается абстракция — в совершенно на первый взгляд различных конструкциях увидеть одинаковую сущность. А
придумывание красивого синтаксиса для какого-то частного случая — это процесс обратный абстрагированию, это
синтаксический сахар. Да, сложными абстракциями сложно пользоваться новичку, но это проходит.
Резюме. В перле приняли правильное решение — перебор элементов массива (без итераторов) foreach и универсальный сишный for.
Posted via RSDN NNTP Server 2.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, VladD2, Вы писали:
VD>Хочется услышать мнение народа о том как бы он хотел видеть паттерн перебора значений из некоторого диапазона.
VD>Например, в С/С++ для этого используется императивный стиль: VD>
VD>for (int i = 0; i < len; i++)
VD>
VD>но этот синтаксис слишком громоздок и может приводить к случайным ошибкам (так как императивен).
VD>Во многих ЯП можно увидить синтаксис вроде: VD>
VD>foreach (i in 0..3) // выдает последовательность 0, 1, 2, 3
VD>
VD>этот синтаксис хорош, но неудобен когда нужно перебрать значения индекса некой коллекции: VD>
VD>foreach (i in 0..array.Length - 1) // не нравится этот "- 1"
VD>
Мне кажется, тут должно быть два паттерна: паттерн диапазона и паттерн перебора. Перебор применим как к диапазонам, так и к контейнерам. А диапазон можно использовать отдельно от перебора. Например создать контейнер, содержащий диапазоны.
Согласен, foreach (0 <= i < 3) выглядит естественнее чем foreach (i in 0 ..< 3), но во-первых я предложил, как с минимальными изменениями снять конкретные нарекания вызванные конкретной конструкцией, а во-вторых кто-то возможно найдет, что
foreach (i in offset + delta * (m..n))
более понятен нежели
foreach (offset + delta * m <= i <= offset + delta * n)
VD>foreach (i in 0..array.Length - 1) // не нравится этот "- 1"
VD>
-- Haskell
-- так:
take array.Length [0..]
-- или так:
[i | i <- [0..], i < array.Length]
VD>Вопрос в том как должен выглядить идеальный синтаксис перебора значений из диапазона на ваш взгляд.
Как в Python,Haskell etc. — совокупность генераторов и гардов, другими словами: List comprehension.
Здравствуйте, last_hardcoder, Вы писали:
_>Мне кажется, тут должно быть два паттерна: паттерн диапазона и паттерн перебора. Перебор применим как к диапазонам, так и к контейнерам. А диапазон можно использовать отдельно от перебора. Например создать контейнер, содержащий диапазоны.
Кстати. Вот в St есть #do: (типа foreach) и select: (фильрация коллекции). Наблюдательные программисты подметили, что иногда встречается патерн
типа (коллекция select: [ ...условие... ]) do: [ ...действие...]. То есть выбираем подмножество и его обрабатываем. Результат появление внутреннего итератора с фильтром типа коллекция select: [ ...условие... ] do: [ ...действие...]. От предідущего єтот вариант отличается не только отсутсвием кругліх скобок, но и отсутсвием промежуточной временной коллекции.
Что касается диапазона вообще (класс Interval в ST), то я видел, что бы он применялся только на низком уровне, при реализации самих методов do:, select: и пр.
Что касается исходного примера:
foreach (i in 0..array.Length - 1) // не нравится этот "- 1"
то в ST являются нормальным явлением методы коллекций first, last, allButFirst, allButLast, copyWithouFirst, copyWithouLast. Названия, вроде, говорят сами за себя.
Здравствуйте, Sinclair, Вы писали:
S>Мысль такая:
...
S>Предполагается набор перегруженных конструкторов для указания step. Предполагается наличие свойства Reverse для обращения обхода. Предполагается наличие операций пересечения/объединения интервалов. Велком
Сысль зравая и я даже дошел до ее аналога. Только уже в новом формате. Можно написать простенокий макрос который будет определять тип коллекции и формировать включающий дипазон (ее я озвучил здесь).
macro IndexesOf(collection)
{
// In real code one needs to do check type of collection and make specialized code
<[ $$[0..collection.Length - 1] ]>
}
...
foreach (i in IndexesOf(myArray))
...
Более того товарищь Москаль сказал, что в Немерле в ближайшее время появятся расширяющие методы и расширяющие макросы. Это позволит писать так:
foreach (i in myarr.Indexes)
...
Причем реально код будет переписываться в тот самый for.
Так что ваша улыбочка, сэр, в конце сообщения ниуместна!
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, z00n, Вы писали:
Z>Как в Python,Haskell etc. — совокупность генераторов и гардов, другими словами: List comprehension.
List comprehension перебор для такого случая. В общем-то диапазон и является простым случаем List comprehension, но все же городить нагромождения по этому поводу наверно не стоит.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, eao197, Вы писали:
E>>>5.times { |i| puts "- #{i} -" }
E>Кстати, если само значение счетчика не интересует, то можно писать просто: E>
E>5.times { puts "---" }
E>
Прикольно. Во-первых, в ST этот метод никогда не передаёт значение счетчика и для того, что бы его получить приходится писать 1 to: 5 do: [...]. Не то чтобы я этим часто пользовался, но когда изредка пишу какие-то тестики, то постоянно об этом забываю. Во-вторых, только сейчас заметил, что название метода в ST слегка неконсистентно — timesRepeat:. Почему Repeat если можно было сделать просто times:, или timesDo: на крайняк. История, блин.
Здравствуйте, VladD2, Вы писали:
VD>В Руби есть задание диапазонов с тремя точками (0...3). Об этом и шала речь. VD>Тебе же снова хочется обсудить вопрос не имеющий отношения к делу.
Я хотел сказать, что в Ruby нет оператора foreach.
А так же то, что приведенная тобой для Ruby запись:
foreach (i in 0...3)
не соответствует примеру для других языков:
foreach (i in 0..3) // выдает последовательность 0, 1, 2, 3
Поскольку для Ruby будет выдана последовательность 0, 1, 2 (без тройки). Т.е. твои два примера не эквивалентны.
Если же ты хочешь именно 0,1,2,3, то следует писать диапазон именно с двумя точками.
Так что я не пытаюсь увести разговор в сторону. а исправляю фактические ошибки. Относись к ним как опечаткам, которые заметил читатель.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.