Re[8]: get_or_create как правильно назвать
От: Lloyd Россия  
Дата: 15.12.08 12:22
Оценка:
Здравствуйте, _FRED_, Вы писали:

L>>Широко-распространенные бибилиотеки де-факто и задают стандарт.

L>>За примером далеко ходить не надо: Hashtable из .Net Framework-а.

_FR>Не очень удачный пример неудачно спроектированного контейнера. Чего с него пример брать? Взгляни на более продуманный IDictionary<,>.


С чего ты взял, что он более продуманный? Он просто другой.
Re[9]: get_or_create как правильно назвать
От: _FRED_ Черногория
Дата: 15.12.08 12:58
Оценка: :)
Здравствуйте, Lloyd, Вы писали:

L>>>Широко-распространенные бибилиотеки де-факто и задают стандарт.

L>>>За примером далеко ходить не надо: Hashtable из .Net Framework-а.

_FR>>Не очень удачный пример неудачно спроектированного контейнера. Чего с него пример брать? Взгляни на более продуманный IDictionary<,>.


L>С чего ты взял, что он более продуманный? Он просто другой.


Ты реализацию Hashtable.get_Item видел? c Thread.Sleep внутри? А не думал, почему в System.Collections.Generic не сделали никакой поддержки многопоточности вообще? Hashtable пытались сделать суперпростой и суперфункциональной одновременно, что бы любой дурак понял, как ей пользоваться.

Наверное, это было важно в первом релизе нового фреймворка, что бы сложными идиомами не отпугнуть армию индусов. С этой задачей, не спорю, Hashtable справилась.

А в "наследство" нам достались такие вот хитрости:
Hashtable map = …;
var count1 = map.Count;
var item = map[key];
map[key] = item;
var count2 = map.Count; // count2 может отличаться от count1.


У меня сейчас нет под рукой Framework Design Guidelines, но, думаю, не сильно ошибусь, если предположу, что в ней советуют вместо ArrayList использовать List<object>, а вместо Hashtable Dictionary<object, object> (если более точные типы указать нельзя).

Кстати, ни в стл::мап, ни в МФЦ::ЦМар нету такой функциональности, что бы по отсутствующему ключу возвращать что-то специальное. Дизайн самик контейнеров сделан так, что этот вопрос не стоит. А в Hashtable стоит. Вернее, стоял. До появления первых бет второго фреймворка, когда стало ясно, что всё вскоре будет по-другому и симпотичнее.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Help will always be given at Hogwarts to those who ask for it.
Re[10]: get_or_create как правильно назвать
От: _FRED_ Черногория
Дата: 15.12.08 13:06
Оценка: +1
Здравствуйте, _FRED_, Вы писали:

_FR>Кстати, ни в стл::мап,


Э, нет, эти

If the argument key value is not found, then it is inserted along with the default value of the data type.

Тьфу!
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Help will always be given at Hogwarts to those who ask for it.
Re[2]: get_or_create как правильно назвать
От: _FRED_ Черногория
Дата: 15.12.08 13:13
Оценка:
Здравствуйте, Lloyd, Вы писали:

K>>чем бы заменить слишком длинное имя item_get_or_create?


L>Умные дядьки рекомендуют для облегчения жизни явно разделять функции запрашивающие состояние и меняющие его.

L>Так что бей на два метода и не ошибешься.

Наоборот, "умные дядьки" делают то, что народу нужно. Для примера: умные дидьки из Оракла сделали ALTER_OR_CREATE (точно не знаю, как зовётся, но смысл, думаю, понятен), а другие дядьки из MSSQL, которых мы не будем никак характеризовать, "жмутся". Разработчикам БД это ой как жизнь портит.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Help will always be given at Hogwarts to those who ask for it.
Re[10]: get_or_create как правильно назвать
От: Andrei F.  
Дата: 15.12.08 13:27
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>А в "наследство" нам достались такие вот хитрости:


Это разве хитрости? Один знакомый "фокусник" любил писать вот в таком духе:
string path = CurDir.Files[name]; // здесь очень весело - если файла с таким именем нет в коллекции, то он не только в нее добавляется, но еще и создается на диске ;)

Очень свежее решение. Нетривиальное
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re[3]: get_or_create как правильно назвать
От: Andrei F.  
Дата: 15.12.08 13:27
Оценка: +1
Здравствуйте, Undying, Вы писали:

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



collection.EnsureItem(val) — ясно и однозначно понятно любому, кто знает английский
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re[2]: get_or_create как правильно назвать
От: Andrei F.  
Дата: 15.12.08 13:31
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Умные дядьки рекомендуют для облегчения жизни явно разделять функции запрашивающие состояние и меняющие его.


Для облегчения жизни себе или пользователю твоей библиотеки?
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re[11]: get_or_create как правильно назвать
От: _FRED_ Черногория
Дата: 15.12.08 13:36
Оценка:
Здравствуйте, Andrei F., Вы писали:

_FR>>А в "наследство" нам достались такие вот хитрости:

AF>Это разве хитрости? Один знакомый "фокусник" любил писать вот в таком духе:
AF>string path = CurDir.Files[name]; // здесь очень весело - если файла с таким именем нет в коллекции, то он не только в нее добавляется, но еще и создается на диске ;)

AF>Очень свежее решение. Нетривиальное

Да уж Операция-то, конечно, сама по себе нормальная, но называться ждолжна не "индексер", а Ensure…, кстати о теме топика
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Help will always be given at Hogwarts to those who ask for it.
Re[10]: get_or_create как правильно назвать
От: Lloyd Россия  
Дата: 15.12.08 14:20
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Ты реализацию Hashtable.get_Item видел? c Thread.Sleep внутри? А не думал, почему в System.Collections.Generic не сделали никакой поддержки многопоточности вообще? Hashtable пытались сделать суперпростой и суперфункциональной одновременно, что бы любой дурак понял, как ей пользоваться.


Ссылочку на авторство этого высказывания дашь?
Да, кстати, как связаны дизайн контейнера и его реализация? Как-то не могу понять.

_FR>Наверное, это было важно в первом релизе нового фреймворка, что бы сложными идиомами не отпугнуть армию индусов. С этой задачей, не спорю, Hashtable справилась.


О каких сложных идиомах в случае Dictionary идет речь?

_FR>А в "наследство" нам достались такие вот хитрости:

_FR>
_FR>Hashtable map = …;
_FR>var count1 = map.Count;
_FR>var item = map[key];
_FR>map[key] = item;
_FR>var count2 = map.Count; // count2 может отличаться от count1.
_FR>


Ну вот, то "не отпугнуть индусов", то "хитрости". Ты уж как-нибудь определись.

_FR>У меня сейчас нет под рукой Framework Design Guidelines, но, думаю, не сильно ошибусь, если предположу, что в ней советуют вместо ArrayList использовать List<object>, а вместо Hashtable Dictionary<object, object> (если более точные типы указать нельзя).


Понятно, что List, а не ArrayList. Только это аргументом за то или иное поведение индексера ну никак не является.
Re[3]: get_or_create как правильно назвать
От: Lloyd Россия  
Дата: 15.12.08 14:22
Оценка:
Здравствуйте, Andrei F., Вы писали:

L>>Умные дядьки рекомендуют для облегчения жизни явно разделять функции запрашивающие состояние и меняющие его.


AF>Для облегчения жизни себе или пользователю твоей библиотеки?


Для облегчения жизни кодо-писателю.
Re[11]: get_or_create как правильно назвать
От: _FRED_ Черногория
Дата: 15.12.08 14:30
Оценка:
Здравствуйте, Lloyd, Вы писали:

_FR>>Ты реализацию Hashtable.get_Item видел? c Thread.Sleep внутри? А не думал, почему в System.Collections.Generic не сделали никакой поддержки многопоточности вообще? Hashtable пытались сделать суперпростой и суперфункциональной одновременно, что бы любой дурак понял, как ей пользоваться.


L>Ссылочку на авторство этого высказывания дашь?


Какого именно?

L>Да, кстати, как связаны дизайн контейнера и его реализация? Как-то не могу понять.


А так, что из плохого дизайна хорошую реализацию сложно сделать.

_FR>>Наверное, это было важно в первом релизе нового фреймворка, что бы сложными идиомами не отпугнуть армию индусов. С этой задачей, не спорю, Hashtable справилась.


L>О каких сложных идиомах в случае Dictionary идет речь?


Об использовании TryGetItem

_FR>>А в "наследство" нам достались такие вот хитрости:


L>Ну вот, то "не отпугнуть индусов", то "хитрости". Ты уж как-нибудь определись.


Я определён: "хитрости" могли бы "отпугнуть индусов".

_FR>>У меня сейчас нет под рукой Framework Design Guidelines, но, думаю, не сильно ошибусь, если предположу, что в ней советуют вместо ArrayList использовать List<object>, а вместо Hashtable Dictionary<object, object> (если более точные типы указать нельзя).


L>Понятно, что List, а не ArrayList. Только это аргументом за то или иное поведение индексера ну никак не является.


Это к лову о том, почему я назвал Hashtable неудачно спроектированным контейнером
Автор: _FRED_
Дата: 15.12.08
. Будь он удачно спроектирован, зачем, с появлением дженериков надо было бы менять такие важные части его как работа в многопоточной среде и прочее?
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Help will always be given at Hogwarts to those who ask for it.
Re[12]: get_or_create как правильно назвать
От: Lloyd Россия  
Дата: 15.12.08 14:42
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>>>Ты реализацию Hashtable.get_Item видел? c Thread.Sleep внутри? А не думал, почему в System.Collections.Generic не сделали никакой поддержки многопоточности вообще? Hashtable пытались сделать суперпростой и суперфункциональной одновременно, что бы любой дурак понял, как ей пользоваться.


L>>Ссылочку на авторство этого высказывания дашь?


_FR>Какого именно?


На то, что разработчики "пытались сделать суперпростой и суперфункциональной одновременно, что бы любой дурак понял, как ей пользоваться".

L>>Да, кстати, как связаны дизайн контейнера и его реализация? Как-то не могу понять.


_FR>А так, что из плохого дизайна хорошую реализацию сложно сделать.


Гм. Мы вроде как обсуждали поведение индексера. Что могло помешать им бросить exception в нем?

_FR>>>Наверное, это было важно в первом релизе нового фреймворка, что бы сложными идиомами не отпугнуть армию индусов. С этой задачей, не спорю, Hashtable справилась.


L>>О каких сложных идиомах в случае Dictionary идет речь?


_FR>Об использовании TryGetItem


Ну если ты считаешь это сложной идиомой, пусть будет так.

_FR>>>А в "наследство" нам достались такие вот хитрости:


L>>Ну вот, то "не отпугнуть индусов", то "хитрости". Ты уж как-нибудь определись.


_FR>Я определён: "хитрости" могли бы "отпугнуть индусов".


Как-то не согласуется. С одной стороны ты говоришь, что проектировали для индусов. С другой — что есть "хитрости" которые могли бы "отпугнуть индусов".
Я так и не понял, напугали их или нет в итоге?

_FR>>>У меня сейчас нет под рукой Framework Design Guidelines, но, думаю, не сильно ошибусь, если предположу, что в ней советуют вместо ArrayList использовать List<object>, а вместо Hashtable Dictionary<object, object> (если более точные типы указать нельзя).


L>>Понятно, что List, а не ArrayList. Только это аргументом за то или иное поведение индексера ну никак не является.


_FR>Это к лову о том, почему я назвал Hashtable неудачно спроектированным контейнером
Автор: _FRED_
Дата: 15.12.08
. Будь он удачно спроектирован, зачем, с появлением дженериков надо было бы менять такие важные части его как работа в многопоточной среде и прочее?


Да блин, как это к инексеру-то относится?
Re[13]: get_or_create как правильно назвать
От: _FRED_ Черногория
Дата: 15.12.08 15:05
Оценка:
Здравствуйте, Lloyd, Вы писали:

_FR>>>>Ты реализацию Hashtable.get_Item видел? c Thread.Sleep внутри? А не думал, почему в System.Collections.Generic не сделали никакой поддержки многопоточности вообще? Hashtable пытались сделать суперпростой и суперфункциональной одновременно, что бы любой дурак понял, как ей пользоваться.

L>>>Ссылочку на авторство этого высказывания дашь?
_FR>>Какого именно?
L>На то, что разработчики "пытались сделать суперпростой и суперфункциональной одновременно, что бы любой дурак понял, как ей пользоваться".

Это мой собственный вывод из того, что я вижу.

L>>>Да, кстати, как связаны дизайн контейнера и его реализация? Как-то не могу понять.

_FR>>А так, что из плохого дизайна хорошую реализацию сложно сделать.
L>Гм. Мы вроде как обсуждали поведение индексера. Что могло помешать им бросить exception в нем?

Этого я не знаю. Если интересно, могу выложить свои догадки.

_FR>>>>Наверное, это было важно в первом релизе нового фреймворка, что бы сложными идиомами не отпугнуть армию индусов. С этой задачей, не спорю, Hashtable справилась.

L>>>О каких сложных идиомах в случае Dictionary идет речь?
_FR>>Об использовании TryGetItem
L>Ну если ты считаешь это сложной идиомой, пусть будет так.

Я видел с десяток парней с профильным образованием и опытом в несколько лет, которые педалили Hashtable несколько лет, потом пересели на дженерики, заметили, что те выбрасывают исключение и стали педалить так
if(!map.ContainsKey(key)) {
  Smth smth = new Smth();
  map.Add(key, smth);
}//if
return map[key];

Использовать TryGetValue отчего-то даже после намёка на это не получалось по-первой.

_FR>>>>А в "наследство" нам достались такие вот хитрости:

L>>>Ну вот, то "не отпугнуть индусов", то "хитрости". Ты уж как-нибудь определись.
_FR>>Я определён: "хитрости" могли бы "отпугнуть индусов".
L>Как-то не согласуется. С одной стороны ты говоришь, что проектировали для индусов. С другой — что есть "хитрости" которые могли бы "отпугнуть индусов".
L>Я так и не понял, напугали их или нет в итоге?

Я нигде не говорил, что "хитрости" "могли бы "отпугнуть индусов"." Я только сказал что "хитрости" есть, которые невооружённым индусским взглядом не заметишь.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Help will always be given at Hogwarts to those who ask for it.
Re[14]: get_or_create как правильно назвать
От: Lloyd Россия  
Дата: 15.12.08 15:15
Оценка:
Здравствуйте, _FRED_, Вы писали:

L>>Как-то не согласуется. С одной стороны ты говоришь, что проектировали для индусов. С другой — что есть "хитрости" которые могли бы "отпугнуть индусов".

L>>Я так и не понял, напугали их или нет в итоге?

_FR>Я нигде не говорил, что "хитрости" "могли бы "отпугнуть индусов"." Я только сказал что "хитрости" есть, которые невооружённым индусским взглядом не заметишь.


А это наверное злой хакер написал, укравший твой парол? Вот ведь подлец!

Я определён: "хитрости" могли бы "отпугнуть индусов".

Re[15]: get_or_create как правильно назвать
От: _FRED_ Черногория
Дата: 15.12.08 15:21
Оценка: +1
Здравствуйте, Lloyd, Вы писали:

L>>>Как-то не согласуется. С одной стороны ты говоришь, что проектировали для индусов. С другой — что есть "хитрости" которые могли бы "отпугнуть индусов".

L>>>Я так и не понял, напугали их или нет в итоге?

_FR>>Я нигде не говорил, что "хитрости" "могли бы "отпугнуть индусов"." Я только сказал что "хитрости" есть, которые невооружённым индусским взглядом не заметишь.


L>А это наверное злой хакер написал, укравший твой парол? Вот ведь подлец!

L>Я определён: "хитрости" могли бы "отпугнуть индусов".


Ага, как обычно скатились к буквам

Можешь считать, что "хитрости" бывают первого и второго рада.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Help will always be given at Hogwarts to those who ask for it.
Re[16]: get_or_create как правильно назвать
От: Lloyd Россия  
Дата: 15.12.08 15:27
Оценка: +1
Здравствуйте, _FRED_, Вы писали:

_FR>Можешь считать, что "хитрости" бывают первого и второго рада.


Ладно. Ты можешь просто и доходчиво объяснить, почему не-бросание исключения было ошибкой?
Не прибегая к индусам, синхронизации и неспособностям твоих коллег понять "сложные идиомы"?
Re[17]: get_or_create как правильно назвать
От: _FRED_ Черногория
Дата: 15.12.08 16:24
Оценка: 66 (2)
Здравствуйте, Lloyd, Вы писали:

L>Ты можешь просто и доходчиво объяснить, почему не-бросание исключения было ошибкой?


Для начала: я пока нигде (в этом топике) не утверждал о том, что "не-бросание исключения было ошибкой". Мы стали спорить о том, что "стандартнее" и о том, что Hashtable: пример плохого, "непродуманного", контейнера. Вспомни своё сообщение
Автор: Lloyd
Дата: 15.12.08
:

U>>Например, для Dictionary стандартное поведение это бросить исключение при обращении по несуществующему ключу,
_FR>Что это за стандарт? Зависит только от библиотеки.
Широко-распространенные бибилиотеки де-факто и задают стандарт.
За примером далеко ходить не надо: Hashtable из .Net Framework-а.


Я понимаю так:
U>>>По стандарту надо бросить
_FR>>Что это за стандарт?
L>Hashtable

То есть это тебе с Undying спорить надо было, о том, чем же хороша и стандартна Hashtable. Я-то как раз хотел показать, что все делают по-разному (не факт, что хорошо, но — по разному).

Возвращаясь к нашим тараканам: теперь я скажу, что "не-бросание исключения было ошибкой", вернее, следствием ошибки проектирования Hashtable.

Дело не в "небросании", а целиком в том, что нельзя сразу и получить объект и узнать, что его там нету. Только двумя запросами. Это способствует тому, что во многих местах игнорируются ситуации, когда ключа, с которым код обратился к словарю в словаре не оказалось. В дизайне IDictionary<> надо всегда помнить, что нужного ключа может и не быть, а не то сразу получишь KeyNotFound. При дизайне Hashtable — ни о чём не говорящий NullReference.

Например, как выглядит код, который, при необходимочти возвращает данные из кэша:
private Hashtable cache…

object GetService(string name) {
  object servive = cache[name];
  if(servive == null) { // (*)
    servive = CreateService(…);
    cache.Add(name, servive);
  }//if
  return service;
}

(*) Главная проблем в том, что можно проверить, а можно и не проверить. И о том, что не проверил, ты узнаешь неизвестно где в самый неподходящий момент. Хорошее проектирование предполагает обраружение ошибки как можно ближе к месту её, ошибки, возникновения. IDictionary<> эту проблему решает на корню. Ошибиться так же можно и с ней, но результат будет совсем другой.

Дизайн IDictionary<> позволяет, при желании, работать по-старому:
static class Extensions
{
  public static TItem GetOrDefault<TKey, TItem>(this IDictionary<TKey, TItem> source, TKey key, TItem defaultValue) {
    if(source == null) {
      throw ewn ArgumentNullException("source");
    }//if

    TItem item;
    return source.TryGetValue(key, out item) ? item : defaultValue;
  }
  
  public static TItem GetOrDefault<TKey, TItem>(this IDictionary<TKey, TItem> source, TKey key) {
    return source.GetOrDefault(key, default(TItem));
  }
}

И даже здесь удачно подобранное имя "хелпера" (выделено жирным) не позволяет "случайно забыть" о том, что же происходит. А вот на Hashtable так же производительно, как в IDictionary<> реализовать TryGetValue нельзя.



Лирическое отступление. Наболело много лет назад, пока не вышла первая бета дженериков, всвязи с чем болеть перестало, но сейчас разбередили

Как альтернатива TryGetValue, можно было бы либо
class Hashtable : …
{
  public static readonly object NotFound = new object();
  …
}

в геттере возвращать заместо null этот самый "special value" NotFound, что было бы уже лучше, но так же спорно. Можно было бы возвращать из индексера некий
struct Option
{
  public bool HasValue { get; }
  public object Value { get; }
}

но опять, же, ИМХО, TryGetValue выглядит приятнее.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Help will always be given at Hogwarts to those who ask for it.
Re[18]: get_or_create как правильно назвать
От: Lloyd Россия  
Дата: 15.12.08 16:31
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>но опять, же, ИМХО, TryGetValue выглядит приятнее.


Ну вот, можешь же. А то начал какую-то тягомотину про sleep-ы, да про коллег.
Re[4]: get_or_create как правильно назвать
От: Erop Россия  
Дата: 15.12.08 16:37
Оценка: +1 :)
Здравствуйте, Andrei F., Вы писали:

AF>

AF>collection.EnsureItem(val) — ясно и однозначно понятно любому, кто знает английский

Могу предложить по крайней мере две трактовки:
1) аналог std::vector::at, в отличии от collection.Item, возможно являющегося аналогом std::vector::operator []
2) Выставляет этому элементу флажок уверенности в нём. Типа элементы бывают гарантированные и негарантированные...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[18]: get_or_create как правильно назвать
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 15.12.08 22:44
Оценка: +1
Здравствуйте, _FRED_, Вы писали:

_FR>Как альтернатива TryGetValue, можно было бы либо

_FR>
_FR>class Hashtable : …
_FR>{
_FR>  public static readonly object NotFound = new object();

Нафик нафик. Никак вон с DBNull размахаться не получается :)

_FR>[c#]
_FR>struct Option
_FR>{
_FR>  public bool HasValue { get; }
_FR>  public object Value { get; }
_FR>}
_FR>


Этот вариант уже вполне нормален, но в большинстве случаев синтаксически немножко более избыточен, чем TryGetValue. Оба этих варианта легко переходят один к другому при помощи простеньких статических хелперов.
... << RSDN@Home 1.2.0 alpha 4 rev. 1120 on Windows Vista 6.0.6001.65536>>
AVK Blog
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.