parser

Написать ответ на текущее сообщение

 

 
   команды управления поиском

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

andylars 02.06.2016 03:00

Согласен, разбивка на такие методы и семантика опций выглядит намного лучше.
^hash.put[key][value;options]
$.at[ first | last (default) ] или $.at(index) или $.before[key] или $.after[key]
$.overwrite(true(default)/false)

Тут непонятность, должен ли учитываться $.at, если ключ уже есть в хеше. Сейчас просто перезаписывается значение,
порядок в хеше не меняется.
Да, очевидно, это коллизия, но она вроде решается.

------ I) Аксиома -------------------

Первое, что надо видимо декларировать, это правило, что при прочих равных =
Если явно указан $.at(index), то это и явно задает ожидаемое место (по индексу) - для результата выполнения (или не_выполнения) вставки. Ни в какое другое место (по индексу) в этом случае вставляться не должно. Для $.at(index) при всех состояниях хеша и значениях опций, операция либо выполнится, либо нет, но гарантировано в этом месте индекса.


------ II) Суть проблемы --------------

Для ^hash.put - мы работаем с хешем, либо в плоскости массива (по индексу), либо в плоскости словаря (по ключу), косвенно задавая режим через $.at(index), или $.at/before/after[key].

Как я понимаю, опция $.overwrite - отрабатывает поведение при пересечение 2 ключей (нового и существующего) в уже заданной плоскости: по индексу или по ключу. Однако, существуют ситуации, когда перескаются сразу 3 ключа: новый ключ перескается с сущ.по индексу и другим существующим, но по имени ключа.

Таким образом, в режиме "массива": $.at(index) + $.overwrite, overwrite обслуживает перезапись по индексу, но некому задать поведение при одновременно возникшей коллизии в плоскости ключа, т.к. у нас overwrite у нас один на две плоскости (а они иногда возникают одновременно).



------- III) Формальное решение --------------------

Формально логическая модель требует - две опции $.overwrite_key и $.overwrite_index, но выглядит некрасиво и многословно, поэтому можно "выдавить этот пузырь" через большее число значений самого $.overwrite, например так (тоже грубо, но для удержания смысла и в рамках обсуждения):

$.overwrite[ none | at_index | at_key | both (default) ]

и тогда $.overwrite элегантно обслуживает все 4 состояния.


III.A): Отдельного внимания заслуживает понятие "корректный индекс" и поведение при указании некорректного индекса (предлагается не производить операций), насколько я понимаю, "дыр" в индексе хеша - нет. И все ключи идут строго по-порядку, поэтому корректный индекс, это один из реальных индексов конкретного хеша.

III.B): А также отдельное явление: "вставка со сдвигом индекса". На вставку со сдвигом (нужную для стеков и очередей), фактически уже заявились $.before/after[key], по такой же аналогии туда наверное стоит продублировать и для индекса$.before/after(index), а также $.before[first] (вставка в вершину), $.after[last] (вставка в конец).



------- IV) Проверка гипотезы --------------------
Попробую привести примеры:
1:
  ^hash.put[key][value;$.after[last] $.overwrite[none]]

1.a: 
  по index ключ = не существует    т.к. $.after[last] 
  по key ключ = не существует 
  результат = true
     key:value вставляется в конец хеша со сдвигом

1.b: 
  по index ключ = не существует    т.к. $.after[last] 
  по key ключ = существует 
  результат = false
     операций не производится


2:
  ^hash.put[key][value;$.at(index) $.overwrite[at_index]]

2.a: 
  по index ключ = существует   
  по key ключ = не существует  
  результат = true
    key:value вставляется на место $.at(index) перетирая старый ключ

2.b:
  по index ключ = существует
  по key ключ = существует
  результат = false
     т.к. найден одноименный ключ по key, а $.overwrite только по at_index


3:
  ^hash.put[key][value;$.after[last] $.overwrite[at_key]]

3.a: 
  по index ключ = не существует   т.к. $.after[last] 
  по key ключ = существует     но можно перетирать
  результат = true
     key:value вставляет в конец хеша, при этом одноименный старый ключ
     просто попутно удаляется их хеша ("перетирается из пространства имен"),
     но новый ключ в любом случае вставляется в место $.at/before/after(]
     см.Аксима I (в самом начале сообщения).
    

и так далее...