Julia: Переименовать в `shift!` И `unshift!`?

Созданный на 27 сент. 2017  ·  59Комментарии  ·  Источник: JuliaLang/julia

Как упоминалось в Slack несколько дней назад, unshift! может быть унаследовано, но это довольно плохое имя ИМХО. Поскольку до версии 1.0 настало время исправить эти вещи, как насчет этого?

Поскольку используется prepend , как насчет unshift! -> pushfront! и shift! -> popfront! ?

Самый полезный комментарий

Еще одна идея: push/pop!(first, x, ...) и push/pop!(last, x, ...) .

Теоретически этот синтаксис хорошо обобщается на такие вещи, как pop!(min, x) .

Все 59 Комментарий

Мы могли бы полностью переименовать эти функции:

| старый | новый |
| ----- | ----- |
| push! | rpush! |
| pop! | rpop! |
| unshift! | lpush! |
| shift! | lpop! |

Или ключевое слово влево / вправо (начало / конец? Первый / последний?), Если проблемы с производительностью могут быть решены.

Левый и правый кажутся немного двусмысленными; возможно, будет яснее передняя / задняя часть @c42f или что-то подобное?

Не уверен, что спереди и сзади четче, чем слева и справа. Конечно, для терминологии «левый / правый» немного прискорбно, что мы печатаем векторы вертикально, но передняя / задняя стороны в этом отношении не лучше.

О, и мы уже используем l и r для левых и правых сокращений, так что есть прецедент - если мы не хотим их тоже менять.

Не уверен, что спереди и сзади четче, чем слева и справа.

Я тоже не уверен. front ассоциируется с более низкими индексами (например, Base.front ), а back с более высокими индексами в моем сознании, но я уверен, что такого рода ассоциации различаются.

Возможно, лучшие идеи: head - tail и first - last кажутся явно менее двусмысленными, учитывая их ранее существовавшие значения?

Имена hpush! , hpop! , tpush! и tpop! неплохие. Однако мы уже связываем левое и правое с порядком расположения массивов в foldl и foldr и т. Д. На самом деле, поскольку у них есть l и r в В конце аналогичными именами являются pushl! , popl! , pushr! и popr! что мне нравится :)

Из имеющихся на данный момент вариантов переименования всех четырех функций мне лучше всего подходят версии с суффиксами pushl! , popl! , pushr! и popr! .

У меня есть некоторые оговорки по поводу переименования push! и pop! . Например, рассмотрите возможность отправки и перехода в очередь с приоритетом. В этом случае нет «правого» и «левого», есть только естественный порядок и структура данных, которая возвращает наименьший / наибольший элемент. Также есть версия pop! которая принимает ключ для использования со словарями, такими как структуры данных, и popr! также не имеет большого смысла в качестве глагола в этом случае.

Я думаю, что push! и pop! могут остаться и использоваться PriorityQueues. Они также могут использовать псевдонимы pushr! и popr! для массивов.

Я люблю shift! & unshift! , то же самое и с javascript. пожалуйста, зарезервируйте это!

Пока мне больше всего нравится предложение из первого поста.

Я думаю, что хорошо использовать имена push*! и pop*! чтобы подчеркнуть сходство между вариантами и чтобы варианты можно было легко найти, завершив табуляцию. (Мне нравятся суффиксы r и l .)

От -2 до терминологии r и l . Названия немного некрасивые, их 4. Я бы предпочел только переименовать shift и unshift, как предлагает OP. Но я также чувствую, что shift и unshift используются достаточно широко, и мы могли бы просто оставить их. Было бы неудачно вводить термины, которые никто другой

@JeffBezanson В векторе C ++ используется push_front , поэтому для этого есть прецедент.

Я предполагаю, что существующие имена можно проследить до shift встроенного в sh , и, предположительно, perl взял это и изобрел unshift (http://www.perlmonks.org /? node_id = 613144) Далее последовали другие языки (php, javascript, ...?), так что есть много прецедентов.

Я предпочитаю правильные английские слова ... :) ( unshift в OED датируется 1972 г.)

или хотя бы упомяните shift! & unshift! в документе pop! & push! :

help?> pop!
search: pop! popdisplay apropos deepcopy precompile __precompile__ peakflops promote_type
also see: `shift!` `unshift!` `push!`

  pop!(collection, key[, default])

  Delete and return the mapping for key if it exists in collection, otherwise return default, or
  throw an error if default is not specified. 

Еще одна идея: push/pop!(first, x, ...) и push/pop!(last, x, ...) .

Теоретически этот синтаксис хорошо обобщается на такие вещи, как pop!(min, x) .

или хотя бы упомяните shift! & unshift! в документе pop! & push! :

Относится к # 23789

Классная идея, @TotalVerb!

Или объединить с splice! / insert! , с first и last качестве псевдоиндексов?

Еще одна идея: push / pop! (Сначала x, ...)

Ах что? Хорошо, это действительно креативная идея :-)

Кажется довольно странным использовать функции first и last исключительно как синтаксис, вместо того, чтобы иметь какое-либо отношение к фактическому коду внутри них. Это неплохо, но я не уверен, что такие вещи следует поощрять в экосистеме, поскольку это может привести к странным затруднениям? Например, если вы когда-нибудь хотели переименовать функции, которые использовались в качестве синтаксиса, что тогда? По общему признанию, это совсем не похоже на first и last , но все же.

Должен сказать, насколько я считаю эту идею крутой - она ​​напоминает мне об идее @mbauman использовать функции редукции при индексировании, как в X[mean, :, sum] - я думаю, что это слишком модно для такой фундаментальной операции. Думаю, на данный момент я предпочитаю следующие варианты:

  1. Оставьте все как есть - какими бы ненадежными ни были "shift" и "unshift", они вполне стандартные.
  2. Переименуйте shift! и unshift! в popl! и pushl! .
  3. Помимо 2, переименуйте pop! и push! в popr! и pushr! .
  4. В дополнение к 3 создайте псевдонимы pop! и push! для popr! и pushr! .

Я в основном между 1 и 2, но есть некоторая привлекательность и для 3 и 4.

Я думаю, что 1) имеет смысл, что применение одной и той же операции (нажатие или выталкивание) к началу и концу массива должно иметь как минимум связанные имена; push! и shift! - пара не интуитивно понятная; 2) слово shift! можно спутать со сдвигом битов >> , что легко увидеть, выполнив поиск в документации по запросу "shift"; 3) у многих пользователей Julia все равно не будет фона perl / javascript.
Таким образом, я предпочитаю вариант 2 в сообщении выше.
Но если мы их переименуем, что делать с circshift! ?

Варианты 2 или 4 Стефана мне кажутся хорошими. Я не думаю, что circshift! нужно менять, потому что это не операция, подобная pop

Предложение:

| старый | новый | псевдонимы |
| ----: | ----: | ----: |
| push! | pushr! | push! |
| pop! | popr! | pop! |
| unshift! | pushl! | |
| shift! | popl! | |

Я должен сказать, что это заманчиво, особенно если мы сохраним push! и pop! качестве псевдонимов для случаев, когда вы используете только структуру как стек и не особо заботитесь о том, левый ли он. или прямо вы толкаете и выскакиваете.

Я использую front и back (значительно) яснее, чем сокращение left и right .

Тем более, что наши векторы вертикальные (значит, он должен быть сверху / снизу) 🙂. Другими вариантами могут быть начало / конец или первый / последний.

мне кажется, что влево / вправо все в порядке; это согласуется с нашей терминологией сокращения ( foldl и foldr ) и с тем, как векторы обычно вводятся [a,b,c,…] и выводятся с помощью print .

Еще одна приятная вещь о левом / правом - это то, что он имеет устоявшееся односимвольное сокращение.

Серьезно, я не знаю, какой конец вектора является передним или задним. Передний индекс 1 или это задний? Да, мы иногда печатаем наши векторы вертикально, но в других случаях мы также печатаем их слева направо. Мы уже последовательно используем унаследованное левое / правое именование для многих других функций.

Как насчет того, чтобы просто иметь новые методы для добавления! и готово! где второй аргумент - скаляр?

Этот разговор вернулся к https://github.com/JuliaLang/julia/issues/23902#issuecomment-332615200, что, в свою очередь, снова вызывает https://github.com/JuliaLang/julia/issues/23902#issuecomment-332668546 , т.е. либо head / tail или first / last терминология? :)

Упс, извините за то, что продолжаю обсуждение. Моя точка зрения заключалась в том, что вместо того, чтобы изобретать новые слова, мы должны повторно использовать существующие.

Упс, извините за то, что продолжаю обсуждение. Моя точка зрения заключалась в том, что вместо того, чтобы изобретать новые слова, мы должны повторно использовать существующие.

Извини @phavernity! Мы устроили одновременный сеанс. Мой ответ должен был следовать за @StefanKarpinski , а не комментировать ваш комментарий :). Лучший!

Мне больше всего нравятся popfirst! , pushfirst! , poplast! , pushlast! с pop! и push! качестве псевдонимов для двоих. последний.

где второй аргумент - скаляр?

Общее определение скаляра невозможно.

«Невозможно определить скаляр в общем виде».

Ах я вижу. Вы могли бы указать, скажем,

добавить! (x :: Vector {T}, y :: T)

, но вы действительно хотите, чтобы y было «чем-то, что можно преобразовать в T». Но система типов (пока?) Не знает, какой набор типов можно преобразовать. Облом.

Давайте проведем (необязательное, информативное) голосование:

  • 👍 для pushr! , popr! , pushl! и popl! с push! и pop! качестве псевдонимов для первых двух
  • 👎 для того, чтобы вещи оставались такими, какие они есть
  • 😕 для другого варианта

Такой выбор смайликов несколько предвзято;).

И: +1: по предложению OP, если вам это больше нравится;)

У меня есть несколько мыслей о переименовании этих функций, поэтому я заранее извиняюсь за то, что, возможно, добавил немного шума в этот разговор. Пока имена Джулии для функций push! , pop! , shift! и unshift! совпадают с именами Perl, Ruby и JavaScript (https: // en .wikipedia.org / wiki / Double-end_queue # Операции). Лично я не возражаю против этих имен, поскольку я изначально выучил их на Perl, но я полностью признаю, что shift / unshift не запоминаются. Также, похоже, есть лагерь, который считает, что пуш / поп - плохая дополнительная пара .

Еще одна идея: push/pop!(first, x, ...) и push/pop!(last, x, ...) .

Если бы мы пошли в этом направлении, я бы предложил использовать enqueue! и dequeue! в качестве имен этих функций.

Что мне нравится в оригинальных названиях, так это то, что они состоят из одного слова. Пытаясь сохранить одно слово, но создать более приятные пары, я придумал push! и pull! для FIFO и push! и pop! для FILO. Это заставит push / pop работать в начале очереди вместо конца:

Старый | Новый
------- | -----
толкать! | положил!
поп! | тянуть!
сдвиг! | толкать!
без сдвига! | поп!

Мы могли бы оставить push / pop в конце и переместить put / pull в начало, чтобы меньше ломалось, но я думаю, что это оставит ситуацию несколько запутанной.

Другой альтернативой является использование append! и prepend! для ссылки соответственно на push! и shift! . Однако у меня нет разумных слов для удаления из очереди, и behead и curtail были лучшими, что я мог придумать ...

@phaverty. Пока возможно иметь Vector{Any} , это будет неоднозначно.

Я перепубликую это: https://github.com/JuliaLang/julia/issues/23902#issuecomment -332919287

@omus Переименование shift! в push! кажется необоснованно запутанным.

append! работает с двумя коллекциями, а push! et. al. работает с одним элементом, поэтому IMO это имя просто не может использоваться здесь.

Наконец, мы всегда могли использовать юникод и использовать что-то вроде:

ASCII | Юникод | Юникод-имя | Псевдоним
--- | --- | --- | ---
толкать! | ⇤ | стрелка влево к панели |
поп! | ↦ | стрелка вправо из бара | mapsto
сдвиг! | ⇥ | стрелка вправо к панели |
без сдвига! | ↤ | стрелка вправо из бара | карты

Думайте о полосе в юникоде как о очереди. ~ К сожалению, эти символы Юникода не имеют хороших псевдонимов в REPL, насколько я могу судить ~.

Переименование shift! в push! кажется необоснованно запутанным.

Честно говоря, я был бы недоволен, если бы мы действительно приняли такой подход. Такой подход определенно пытается понравиться новичкам и по-настоящему значить для существующих пользователей Julia.

@omus , например ↦ - это \mapsto .

Хорошо, я соврал: мне нужно сказать еще кое-что. В качестве более серьезного предложения мы могли бы пойти с этим подходом. Он теряет приятный push / pop, но гораздо более понятен в отношении происходящей операции:

Старый | Новый
- | -
толкать! | Lastin!
поп! | последний раз!
сдвиг! | первый в!
без сдвига! | первый!

Не стесняйтесь голосовать против большинства этих предложений. Покопавшись в этой теме, я пришел к единственному верному выводу: компьютерные ученые приняли терминологию push / pop и понятия не имели, как назвать shift / unshift.

Теперь, когда у нас есть сворачивание констант, аргументы ключевых слов для этого должны быть быстрыми, правильно? Я не понимаю, почему у нас для этого должно быть 4 функции вместо 2, тем более что многословные функции специально не рекомендуются для содействия рефакторингу.

Каким бы занимательным это ни было, кажется, что мы не можем добиться здесь большего, чем статус-кво.

Каким бы занимательным это ни было, кажется, что мы не можем добиться здесь большего, чем статус-кво.

Сумма поддержки OP кажется значительной? Возможно, закрывать этот вопрос преждевременно? :)

Да, предложение OP имеет 11 вверх и 0 вниз ...

Я истолковал это как поддержку общей идеи переименования, а не как конкретное предложение.

Мне ясно, что после всей этой дискуссии мы не нашли действительно убедительной альтернативы.

FWIW pushfront! по-прежнему является моим любимым и заслуживающим внимания переименованием, на мой взгляд, но это может быть просто моим предвзятым отношением к C ++.

Мне нравятся pushfront! и popfront! .

Что ж, я сделал PR в # 25100, чтобы использовать pushfront! / popfront! поскольку я думаю, что это минимальная вещь, которую мы можем сделать, чтобы переименовать unshift! . На самом деле единственное, что есть в unshift! , это (а) это статус-кво и (б) у него есть прецедент в perl / javascript / php / других языках, наследующих сомнительные варианты от perl.

Смело стреляйте ;-)

Подобно тому, что @ Sacha0 упомянул в # 25100. Я думаю, что если мы действительно хотим переименовать, я предлагаю:

enqueue!(::typeof(first), a, item) = unshift!(a, item)
enqueue!(::typeof(last), a, item) = push!(a, item)
dequeue!(::typeof(first), a) = shift!(a)
dequeue!(::typeof(last), a) = pop!(a)
julia> enqueue!(::typeof(first), a, item) = unshift!(a, item);

julia> enqueue!(::typeof(last), a, item) = push!(a, item);

julia> dequeue!(::typeof(first), a) = shift!(a);

julia> dequeue!(::typeof(last), a) = pop!(a);

julia> foo = [1, 2, 3]
3-element Array{Int64,1}:
 1
 2
 3

julia> enqueue!(first, foo, 0)
4-element Array{Int64,1}:
 0
 1
 2
 3

julia> dequeue!(first, foo)
0

julia> enqueue!(last, foo, 5)
4-element Array{Int64,1}:
 1
 2
 3
 5

julia> dequeue!(last, foo)
5

Альтернативно:

push!(::typeof(first), a, item) = unshift!(a, item)
push!(::typeof(last), a, item) = push!(a, item)
pop!(::typeof(first), a) = shift!(a)
pop!(::typeof(last), a) = pop!(a)

Мы также могли бы оставить push! и pop! не передавая first или last которые по умолчанию будут push!(last, ...) и pop!(last, ...) .

Была ли эта страница полезной?
0 / 5 - 0 рейтинги