Как Юлия интерпретирует 10:1?

Я эмигрант с долгое время сосредоточиться на R, где : Оператор (двоеточие) создает целочисленные последовательности от первого до второго аргумента:

1:10
# [1]  1  2  3  4  5  6  7  8  9 10
10:1
# [1] 10  9  8  7  6  5  4  3  2  1

Заметив, что в Джулии это работает одинаково, я столкнулся с ошибкой:

1:10 .== 10:1

DimensionMismatch ("массивы не могут быть переданы в общий размер")

Так как:

10:1

Выходы

10:9

Я озадачен тем, как это могло произойти. Кажется вполне естественным, не нужно использовать 10:-1:1 - почему Джулия подумала 10:9 была правильная интерпретация 10:1?

2 ответа

Решение

Джулия не R. Есть другие языки, которые имеют схожую интерпретацию синтаксиса двоеточия как Джулия. MATLAB лечит 10:1 в качестве пустого массива и синтаксиса среза Python (хотя и отличается в других отношениях) также обрабатывает индексирование с 10:1 как пустой выбор. Юлия выбирает нормализовать пустые целочисленные диапазоны так, чтобы разница между стартом и стопом всегда была -1так становится 10:9,

Так что я не думаю, что есть однозначно очевидная интерпретация 10:1, Однако, на мой взгляд, есть несколько очень убедительных аргументов в пользу интерпретации Юлии:

  • Пустой диапазон 10:9 используется для представления местоположения между индексами 9 и 10 в некоторых API.

  • Диапазоны являются основной конструкцией в Юлии и for x in 1:10 абсолютно и однозначно должно быть так же быстро, как эквивалентный цикл C. Потому что синтаксис x:y всегда увеличивая на единицу (и никогда не отрицая), Джулия (и LLVM) может использовать эту константу при компиляции для циклов, чтобы обеспечить дальнейшую оптимизацию. Делая это не постоянным --- или хуже, динамическое переключение между UnitRange а также StepRange в зависимости от значений конечных точек эта оптимизация может помешать или будет нестабильной.

  • Лично я нахожу интерпретацию R такой же удивительной, как и интерпретацию Джулии. Я бы сказал, что нужно четко указать, что вы хотите сделать шаг -1 выгодно как в удобочитаемости, так и в предотвращении ошибок. Но я признаю, что мой опыт работы с предыдущими языками такой же предвзятый, как и ваш.

В Юлии мы предполагаем a:b строит диапазон с размером шага 1, так10:1 является UnitRange который должен быть пустым диапазоном. поскольку a:a-1 также пустой диапазон, это эквивалентно a:b где b<aПожалуйста, посмотрите на исходный код здесь.

julia> dump(10:1)
UnitRange{Int64}
  start: Int64 10
  stop: Int64 9

julia> dump(10:-1:1)
StepRange{Int64,Int64}
  start: Int64 10
  step: Int64 -1
  stop: Int64 1

Вот 10:-1:1 это StepRange с размером шага -1, что, я думаю, является более точным и естественным для представления идеи "10 к 1".

Другие вопросы по тегам