Опять про Oberon 07
От: Разраб  
Дата: 23.04.24 10:57
Оценка:
В процессе реализации аналогичного кода(пузырьковая сортировка)
на языках зиг, питон, раст
и т.п.
обратил внимание, что отсутствие конструкции FOR i := 0 TO N — 1 DO (* something do *) END
усложняет понимание и разработку алгоритма, так в зиг забыл обнулить счетчик вложенного цикла(for отсутствует как класс).
Тоже самое касается множественных return из функции.
Все таки ЯП и синтаксис(!) чертовски важны.
Согласны?
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re: Опять про Oberon 07
От: elmal  
Дата: 23.04.24 12:08
Оценка: 1 (1)
Здравствуйте, Разраб, Вы писали:

Р>Тоже самое касается множественных return из функции.

Р>Все таки ЯП и синтаксис(!) чертовски важны.
Р>Согласны?
Важны некоторые возможности. Начнем с того, что большинство программистов пишут код сортировки и подобное сильно реже одного раза в год, больнинство вообще в практической работы не писали ни разу (я модифицированные сортировки, отличные от стандартной — писал, правда реюзал стандартную один черт).
А вот for со счетчиком по большому счету именно в языке не нужен нафик. Однако в хорошем языке должна быть возможность подобную конструкцию реализовать в библиотеках, и это будет выглядить органично. Объясню даже почему — в цикле со счетчиком очень легко ошибиться на 1, и чаще всего на практике требуется именно for each. Также цикл со счетчиком прекрасно заменяется с for each по индексам чего то там, здесь не ошибешься. Такой for each еще хорошь тем, что его можно легко распараллелить допустим по ядрам процессора вообще без непрягов и практически без доп кода, for each сам по себе позволяет все делать параллельно в большинстве случаев.

Ну и если уж приспичило именно for со счетчиком, я вообще не понимаю сложности создать функцию, в которой в качестве аргумента передается начальное числовое значение, функция изменения этого значения, функция сравнения с условием а также функция, которая зависит от счетчика. При этом за счет параметрического полиморфизма можно создать до фига функция с одним именем, но разными аргументами, например в одном случае будет как я сказал, в другом случае вторым аргументом будет просто конечное число и итерироваться мы будем по одному, а третьим функция от этого аргумента. Можно еще вариант со step создать и все такое. for со счетчиком ну совершенно избыточная конструкция для современного языка программирования, которая требуется крайне редко на практике. А именно в языке программирования по хорошему нужны в основном часто используемые практичные конструкции, все маловажное либо в стандартные библиотеки, а совсем не важное и специфичное пусть сам пользователь пишет при желании.
Re: Опять про Oberon 07
От: GarryIV  
Дата: 23.04.24 12:15
Оценка:
Здравствуйте, Разраб, Вы писали:

Р>В процессе реализации аналогичного кода(пузырьковая сортировка)

Р>на языках зиг, питон, раст
Р>и т.п.
Р>обратил внимание, что отсутствие конструкции FOR i := 0 TO N — 1 DO (* something do *) END
Р>усложняет понимание
ээм
for x in range(2, 6):
  print(x)

сложно бедолаге?
WBR, Igor Evgrafov
Re[2]: Опять про Oberon 07
От: Разраб  
Дата: 23.04.24 14:18
Оценка:
Здравствуйте, GarryIV, Вы писали:

GIV>ээм

GIV>
GIV>for x in range(2, 6):
GIV>  print(x)
GIV>

GIV>сложно бедолаге?
2 и 6 вкл?
range это функция? что производительностью?
непрозрачно, ихмо
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[3]: Опять про Oberon 07
От: GarryIV  
Дата: 23.04.24 14:22
Оценка: :)
Здравствуйте, Разраб, Вы писали:

Р>range это функция?

то есть питончик даже на базовом уровне не того

Р>непрозрачно, ихмо

с таким уровнем неудивительно
WBR, Igor Evgrafov
Re[4]: Опять про Oberon 07
От: Разраб  
Дата: 24.04.24 00:22
Оценка: +2
Здравствуйте, GarryIV, Вы писали:

GIV>Здравствуйте, Разраб, Вы писали:


Р>>range это функция?

GIV>то есть питончик даже на базовом уровне не того
так функция ли что?
я вот оберон тоже не знаю
но когда смотрю
FOR i:=2 TO 6 DO
Out.Ln;
END;

или
for i = 2 to 6 do
    printfn "%d" i

даже не задумываюсь
Р>>непрозрачно, ихмо
GIV>с таким уровнем неудивительно
>>> range
<class 'range'>
s = 0
for i in range(1,1000_000_001):
    s = s + i

print(s)

т.е. вот этот класс вместо банального инкремента, творит какую-то неведомую магию?
Иначе почему выполнялось 3 минуты вместо 4 секунд(аналогичный скрипт на F#)
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[4]: Опять про Oberon 07
От: Michael7 Россия  
Дата: 24.04.24 01:12
Оценка: 2 (1) +2
Здравствуйте, GarryIV, Вы писали:

Р>>непрозрачно, ихмо

GIV>с таким уровнем неудивительно

А вот это немножко контринтуитивно, что в конструкции range(2,6) итерации включают 2, но не включают 6. С другой стороны, если бы включали, была бы путаница в длине последовательности 4 или 5. Также может сбивать с толку использование индексов, хотя их вроде придумали наоборот для удобства и питон как бы считается мощным языком для манипуляций с векторами, матрицами, списками подобным образом.

a = [x for x in range(2,5)] # a = [2,3,4]
print(a[-1]) # 4
print(a[:-1]) # [2,3]
print(a[::]) # [2,3,4]


Питонисты к этому привыкают, но я например до сих пор несколько напрягаюсь в подобных местах, особенно в чужом коде. Учитывая, что например, все эти двоеточия, запятые и -1 ведут себя слегка по разному "просто в питоне", в numpy и в torch. И встретив какое-нибудь

a  = x[:,0,:]


Вот так сходу скажешь, что эта конструкция делает? Без подсказки про размерности.

>>> import torch
>>> x = torch.tensor([[[1., 2.],[3.,4.]], [[5., 6.], [7.,8.]],[[9.,10.],[11.,12.]]])
>>> x
tensor([[[ 1.,  2.],
         [ 3.,  4.]],

        [[ 5.,  6.],
         [ 7.,  8.]],

        [[ 9., 10.],
         [11., 12.]]])
>>> a = x[:,0,:]
>>> a
tensor([[ 1.,  2.],
        [ 5.,  6.],
        [ 9., 10.]])


Понятно, интуитивно? А так?

>>> x[:0,:]
tensor([], size=(0, 2, 2))
>>> x[:,:0]
tensor([], size=(3, 0, 2))
>>> x[:,:-1]
tensor([[[ 1.,  2.]],

        [[ 5.,  6.]],

        [[ 9., 10.]]])
>>> x[:,0:]
tensor([[[ 1.,  2.],
         [ 3.,  4.]],

        [[ 5.,  6.],
         [ 7.,  8.]],

        [[ 9., 10.],
         [11., 12.]]])
>>> x[:,-1,:]
tensor([[ 3.,  4.],
        [ 7.,  8.],
        [11., 12.]])
>>> x[:,-1:]
tensor([[[ 3.,  4.]],

        [[ 7.,  8.]],

        [[11., 12.]]])
Отредактировано 24.04.2024 1:18 Michael7 . Предыдущая версия . Еще …
Отредактировано 24.04.2024 1:16 Michael7 . Предыдущая версия .
Отредактировано 24.04.2024 1:13 Michael7 . Предыдущая версия .
Re[2]: Опять про Oberon 07
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 24.04.24 04:20
Оценка:
Здравствуйте, elmal, Вы писали:

E>А вот for со счетчиком по большому счету именно в языке не нужен нафик.


Интересно, а как ты без индекса будешь интегрироваться по нескольким массивам одновременно. Вполне частый случай, когда обрабатывается константный массив объектов, для которого вычисляются признаки/характеристики, складываемые в другой массив, той же длины. И после этого получаем два массива, по которым надо пройти параллельно или просто ссылаться по индексу на другой.
Если говорить про вычисления типа алгебры, то там такая ситуация вообще на каждом шагу.
Re[3]: Опять про Oberon 07
От: elmal  
Дата: 24.04.24 04:58
Оценка:
Здравствуйте, Nuzhny, Вы писали:

N>Интересно, а как ты без индекса будешь интегрироваться по нескольким массивам одновременно.

Элементарно. Итерироваться не по счетчику, а по for each индекса массива. Сильно надежнее получается, и не нужно думать о всяких прибавлениях или вычитаниях единицы.
Re[5]: Опять про Oberon 07
От: FR  
Дата: 24.04.24 06:12
Оценка: 3 (1)
Здравствуйте, Разраб, Вы писали:


Р>print(s)

Р>[/python]
Р>т.е. вот этот класс вместо банального инкремента, творит какую-то неведомую магию?
Р>Иначе почему выполнялось 3 минуты вместо 4 секунд(аналогичный скрипт на F#)

Потому что питон интерпретатор, аналогичный код (вместо 0..=1000_000_000 подставляется std::ops::Range)
fn main() {
    let mut s: usize = 0;
    for i in 0..=1000_000_000 {
        s += i
    }
    println!("{}", s);
}


на rust вообще всегда 0 показывает времени, так как оптимизируется до подстановки результата, в C++ с range весьма вероятно также будет.
Re: Опять про Oberon 07
От: rudzuk  
Дата: 24.04.24 06:14
Оценка: 3 (1)
Здравствуйте, Разраб, Вы писали:

Р> Все таки ЯП и синтаксис(!) чертовски важны.

Р> Согласны?

Ясен перец! Паскаль рулит!
avalon/3.0.2
Re[4]: Опять про Oberon 07
От: rudzuk  
Дата: 24.04.24 06:14
Оценка:
Здравствуйте, elmal, Вы писали:

e>Сильно надежнее получается, и не нужно думать о всяких прибавлениях или вычитаниях единицы.


for var i := Low(arr) to High(arr) do;

И никаких тебе единичек
avalon/3.0.2
Re[3]: Опять про Oberon 07
От: FR  
Дата: 24.04.24 06:21
Оценка: +1
Здравствуйте, Nuzhny, Вы писали:

N>Интересно, а как ты без индекса будешь интегрироваться по нескольким массивам одновременно.


Ну для нескольких массивов функциональщики всякие zip и т. п. придумали, это не проблема.
Индексы реально нужны только если нужен (почти) произвольный доступ, например как во всяких фильтрах для графики (например окружение точки в двухмерном массиве).
Re[4]: Опять про Oberon 07
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 24.04.24 06:22
Оценка:
Здравствуйте, elmal, Вы писали:

N>>Интересно, а как ты без индекса будешь интегрироваться по нескольким массивам одновременно.

E>Элементарно. Итерироваться не по счетчику, а по for each индекса массива. Сильно надежнее получается, и не нужно думать о всяких прибавлениях или вычитаниях единицы.

Индекс массива — это что такое? Если как в Питоне с enumerate, то так себе по удобству.
Через 1 он может? Через 2? Не до конца массива, а до len-1? Попутно удалять элементы из массива?
Re[4]: Опять про Oberon 07
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 24.04.24 06:25
Оценка:
Здравствуйте, FR, Вы писали:

FR>Ну для нескольких массивов функциональщики всякие zip и т. п. придумали, это не проблема.

FR>Индексы реально нужны только если нужен (почти) произвольный доступ, например как во всяких фильтрах для графики (например окружение точки в двухмерном массиве).

Это тоже. CUDA/OpenCL — там в принципе всё исключительно на индексах
Re[4]: Опять про Oberon 07
От: Sinclair Россия https://github.com/evilguest/
Дата: 24.04.24 06:34
Оценка: 3 (1)
Здравствуйте, FR, Вы писали:
FR>Индексы реально нужны только если нужен (почти) произвольный доступ, например как во всяких фильтрах для графики (например окружение точки в двухмерном массиве).
Окружение точки в двухмерном массиве нужно делать аккуратно, т.к. легко вылететь куда не надо.
На развитых платформах можно делать рантайм-оптимизации безопасным образом: https://githib.com/evilguest/linq2d
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[5]: Опять про Oberon 07
От: elmal  
Дата: 24.04.24 07:13
Оценка:
Здравствуйте, Nuzhny, Вы писали:

N>Индекс массива — это что такое? Если как в Питоне с enumerate, то так себе по удобству.

Примерно так. В других языках это можно допустим через array.WithIndex или еще как, когда при итерации будет пара индекс значение, а можно что то вроде indexes, когда для массива из трех элементов будет сгенерировано 0, 1, 2, и по нима фигачить уже for each.
N>Через 1 он может? Через 2? Не до конца массива, а до len-1? Попутно удалять элементы из массива?
Через 1 это уже достаточно редкий случай. Как и не до len-1. И тут никакой проблемы не составит это все сделать через цикл while с внешним мутирующимся счетчиком или даже через функцию, которая делает все то, что делает цикл for со счетчиком.
Re[5]: Опять про Oberon 07
От: elmal  
Дата: 24.04.24 07:52
Оценка:
Здравствуйте, Nuzhny, Вы писали:

N>Это тоже. CUDA/OpenCL — там в принципе всё исключительно на индексах

Вот только там ни хрена не цикл for с индексом. Индексы тупо приходят извне, ибо вся обработка идет параллельно.
Re[6]: Опять про Oberon 07
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 24.04.24 07:59
Оценка:
Здравствуйте, elmal, Вы писали:

E>Примерно так. В других языках это можно допустим через array.WithIndex или еще как, когда при итерации будет пара индекс значение, а можно что то вроде indexes, когда для массива из трех элементов будет сгенерировано 0, 1, 2, и по нима фигачить уже for each.


То есть при проходе по картинке размером, скажем, 20 Мп нам сгенерируют индекс размером 20 млн элементов? Хм, оптимальненько.

E>Через 1 это уже достаточно редкий случай. Как и не до len-1. И тут никакой проблемы не составит это все сделать через цикл while с внешним мутирующимся счетчиком или даже через функцию, которая делает все то, что делает цикл for со счетчиком.


Звучит костыльненько
Re[7]: Опять про Oberon 07
От: elmal  
Дата: 24.04.24 08:03
Оценка:
Здравствуйте, Nuzhny, Вы писали:

N>То есть при проходе по картинке размером, скажем, 20 Мп нам сгенерируют индекс размером 20 млн элементов? Хм, оптимальненько.

Там кроме языка есть еще и оптимизатор. Который поймет что там требуется и не будет ни черта генерировать в памяти, а тупо сделает цикл или даже что поэффективнее, например SIMD операции.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.