Re[3]: EnumHelper: request for breaking changes
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 21.09.16 12:12
Оценка: +1
Здравствуйте, Sinix, Вы писали:

S>Ассерты (EnumCode) в комплекте. Я их ещё подополняю, дальше будем смотреть — переносить их в Code или пусть отдельно живут.

S>Лично я за то, чтобы их отдельно держать, но если большинство против — спорить не буду

Меня этот вопрос тоже посетил. Однозначного ответа пока нет.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[12]: EnumHelper: request for breaking changes
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 21.09.16 12:12
Оценка:
Здравствуйте, samius, Вы писали:

S>Тут мое мнение по части типового программиста расходится с остальнымм народом (кому не понравился Intersects). Насколько я себе представляю, знакомство с теорией множеств входит в стандартный курс вышки, который читают даже студентам нетехнических специальностей.


Вот только такой подход порождает тот же unfold из соседней темы. Тоже вроде, если в теме, понятен смысл. Но читабельность кода для незнакомых с термином затрудняет преизрядно.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[16]: EnumHelper: request for breaking changes
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 21.09.16 12:12
Оценка: +1
Здравствуйте, samius, Вы писали:

S>Тут сложно придумать что-либо соответствующее теории множетсв, разве что .Update(value, enabled) или .Combine(value, enabled).


Update(this ref)? Вряд ли. А если это чистая функция, то Update как то диссонирует. А вот Combine на мой вкус выглядит вполне нормально. Ну и Exclude без флажка enabled тоже, имхо, нужен.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[13]: EnumHelper: request for breaking changes
От: samius Япония http://sams-tricks.blogspot.com
Дата: 21.09.16 13:04
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Вот только такой подход порождает тот же unfold из соседней темы. Тоже вроде, если в теме, понятен смысл. Но читабельность кода для незнакомых с термином затрудняет преизрядно.

А для знакомых с темой — преизрядно упрощает.
Вопрос в грани, где ее провести и зачем? Отказываться от рекурсии в надежде на то, что код будет читать незнакомый с ней? Что делать с yield и await? Ведь изучить их где-нибудь вне программирования вообще не представляется вероятным.
Re[17]: EnumHelper: request for breaking changes
От: samius Япония http://sams-tricks.blogspot.com
Дата: 21.09.16 13:06
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Update(this ref)? Вряд ли. А если это чистая функция, то Update как то диссонирует. А вот Combine на мой вкус выглядит вполне нормально. Ну и Exclude без флажка enabled тоже, имхо, нужен.

Exclude тоже диссонирует в качестве чистой функции.
Re[18]: EnumHelper: request for breaking changes
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 21.09.16 13:39
Оценка: 27 (1)
Здравствуйте, samius, Вы писали:

S>Exclude тоже диссонирует в качестве чистой функции.


Меньше, чем Update, имхо. Ну, можно тогда Without или Except.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[14]: EnumHelper: request for breaking changes
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 21.09.16 13:39
Оценка:
Здравствуйте, samius, Вы писали:

AVK>>Вот только такой подход порождает тот же unfold из соседней темы. Тоже вроде, если в теме, понятен смысл. Но читабельность кода для незнакомых с термином затрудняет преизрядно.

S>А для знакомых с темой — преизрядно упрощает.

Вот только незнакомых — намного больше.

S>Вопрос в грани, где ее провести и зачем? Отказываться от рекурсии в надежде на то, что код будет читать незнакомый с ней?


От массового применения — безусловно. Пример XSLT перед глазами.

S> Что делать с yield и await?


А зачем с ними что то делать? Это как раз обратный случай, когда хитро высушенные продолжения заменяются псевдоимперативными конструкциями, намного более понятными не знакомым с ФП спецификой людям.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[15]: EnumHelper: request for breaking changes
От: Sinix  
Дата: 21.09.16 14:15
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Вот только незнакомых — намного больше.

Так, я тут посмотрел внимательно, и обнаружил, что немножко фигню натворил.

В чём проблема:
был метод x.IsFlagNotMatch(y), который по проверял, что ни один флаг из y в x не входит.

Я его на автомате переименовал в x.IsAnyFlagUnset(y), название, понятное дело, не отражает то что метод делает.
В качестве заплатки переименовал в x.AreAllFlagsUnset(y) + добавил TestEnumUseCase, который на более-менее реальном примере показывает использование всех методов сразу.

Дальше попробую подобрать нормальные имена и заведу топик в профильной ветке.

Если не устраивает — можно просто откатить все исправления.
Re[19]: EnumHelper: request for breaking changes
От: samius Япония http://sams-tricks.blogspot.com
Дата: 21.09.16 14:44
Оценка: +1
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, samius, Вы писали:


S>>Exclude тоже диссонирует в качестве чистой функции.


AVK>Меньше, чем Update, имхо. Ну, можно тогда Without или Except.

Супер. Without лучше тем, что к нему можно в пару записать With. Except тоже хорош.
Re[15]: EnumHelper: request for breaking changes
От: samius Япония http://sams-tricks.blogspot.com
Дата: 21.09.16 15:03
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, samius, Вы писали:


S>>А для знакомых с темой — преизрядно упрощает.


AVK>Вот только незнакомых — намного больше.

Незнакомых с программированием вообще — намного больше, чем знакомых.

S>>Вопрос в грани, где ее провести и зачем? Отказываться от рекурсии в надежде на то, что код будет читать незнакомый с ней?


AVK>От массового применения — безусловно. Пример XSLT перед глазами.

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

S>> Что делать с yield и await?


AVK>А зачем с ними что то делать? Это как раз обратный случай, когда хитро высушенные продолжения заменяются псевдоимперативными конструкциями, намного более понятными не знакомым с ФП спецификой людям.

Не вполне точно выразился. Я не предлагаю с ними что-то делать, я про границу применения концепций. Пусть будет не await, а косинус, хэштаблица или конечный автомат. Стоит ли мне проводить анкетирование программистов, прежде чем заюзать их в коде?
Re[16]: EnumHelper: request for breaking changes
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 21.09.16 15:19
Оценка:
Здравствуйте, samius, Вы писали:

AVK>>Вот только незнакомых — намного больше.

S>Незнакомых с программированием вообще — намного больше, чем знакомых.

Но они не являются целевой аудиторией, в отличие от.

AVK>>От массового применения — безусловно. Пример XSLT перед глазами.

S>Я не про массовое применение. Я про здесь и сейчас, про код, который пишу я, который не предназначен для массового чтения тех, кто не знаком с рекурсией.

В каком плане незнаком? Людей, которые незнакомы с ней вообще, можно во внимание не принимать. А вот те, кто с трудом воспринимает сложные рекурсивные алгоритмы, которых как собак на блохе в некоторых ФП, вот их во внимание принимать нужно обязательно.

S>Не вполне точно выразился. Я не предлагаю с ними что-то делать, я про границу применения концепций. Пусть будет не await, а косинус, хэштаблица или конечный автомат.


Нельзя такие вещи в контексте разговора обсуждать скопом. Косинус это вообще предметная область — если уж кто в нее влез, тот обязан с ней быть знаком. Хэштаблица — основополагающая структура, незнакомым хотя бы с базовыми свойствами этого алгоритма в программировании на универсальных дотнетных языках делать нечего. А вот КА штука действительно весьма неспособствующая читабельности кода. Я год назад вынужден был в тему глубоко погрузиться (это не считая того, что у меня вполне профильное образование со всеми вытекающими), и с ней посему знаком неплохо, но по прежнему считаю что явно такие вещи, ровно как терминологию оттуда, стоит использовать только в суперкрайних случаях.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[17]: EnumHelper: request for breaking changes
От: samius Япония http://sams-tricks.blogspot.com
Дата: 21.09.16 16:42
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, samius, Вы писали:


AVK>>>Вот только незнакомых — намного больше.

S>>Незнакомых с программированием вообще — намного больше, чем знакомых.

AVK>Но они не являются целевой аудиторией, в отличие от.

А где граница? Знакомому с программированием познакомиться с unfold гораздо проще, чем познакомиться с программированием вообще.

AVK>>>От массового применения — безусловно. Пример XSLT перед глазами.

S>>Я не про массовое применение. Я про здесь и сейчас, про код, который пишу я, который не предназначен для массового чтения тех, кто не знаком с рекурсией.

AVK>В каком плане незнаком? Людей, которые незнакомы с ней вообще, можно во внимание не принимать. А вот те, кто с трудом воспринимает сложные рекурсивные алгоритмы, которых как собак на блохе в некоторых ФП, вот их во внимание принимать нужно обязательно.

А почему не нужно принимать во внимание людей, кто с трудом воспринимают сложные нерекурсивные алгоритмы, которые с помощью рекурсии можно записать проще?

S>>Не вполне точно выразился. Я не предлагаю с ними что-то делать, я про границу применения концепций. Пусть будет не await, а косинус, хэштаблица или конечный автомат.


AVK>Нельзя такие вещи в контексте разговора обсуждать скопом. Косинус это вообще предметная область — если уж кто в нее влез, тот обязан с ней быть знаком. Хэштаблица — основополагающая структура, незнакомым хотя бы с базовыми свойствами этого алгоритма в программировании на универсальных дотнетных языках делать нечего. А вот КА штука действительно весьма неспособствующая читабельности кода. Я год назад вынужден был в тему глубоко погрузиться (это не считая того, что у меня вполне профильное образование со всеми вытекающими), и с ней посему знаком неплохо, но по прежнему считаю что явно такие вещи, ровно как терминологию оттуда, стоит использовать только в суперкрайних случаях.


Я не пытался перейти на обсуждение таких вещей скопом. Я пытаюсь понять правила, согласно которым можно определять, что программисту из целевой аудитории знать обязательно, а от чего его надо беречь. Исключительно в рамках темы EnumHelper. Почему в рамках фреймворка Enumerable.Intersect — хорошо, а в библиотеке EnumHelper.Intersects — плохо? (await-ы, КА и прочее — лишь примеры).
Re[18]: EnumHelper: request for breaking changes
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 21.09.16 16:47
Оценка:
Здравствуйте, samius, Вы писали:

AVK>>Но они не являются целевой аудиторией, в отличие от.

S>А где граница?

Какая граница? Если человек не знаком с программированием, то его CodeJam не заинтересует ни при каком раскладе.

AVK>>В каком плане незнаком? Людей, которые незнакомы с ней вообще, можно во внимание не принимать. А вот те, кто с трудом воспринимает сложные рекурсивные алгоритмы, которых как собак на блохе в некоторых ФП, вот их во внимание принимать нужно обязательно.

S>А почему не нужно принимать во внимание людей, кто с трудом воспринимают сложные нерекурсивные алгоритмы

Я вроде бы написал, что нужно.

S>Я не пытался перейти на обсуждение таких вещей скопом. Я пытаюсь понять правила, согласно которым можно определять, что программисту из целевой аудитории знать обязательно, а от чего его надо беречь. Исключительно в рамках темы EnumHelper. Почему в рамках фреймворка Enumerable.Intersect — хорошо, а в библиотеке EnumHelper.Intersects — плохо? (await-ы, КА и прочее — лишь примеры).


Конкретно касательно Intersect у меня однозначного мнения пока нет. Но если удастся придумать менее контекстно зависимое название, то лучше использовать его.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[16]: EnumHelper: request for breaking changes
От: Sinix  
Дата: 22.09.16 08:20
Оценка: +1
Здравствуйте, samius, Вы писали:

S>>Чуть позже заведу тему в основном разделе, пусть народ поучаствует. Найдётся вариант лучше — будем менять.

S>

Так, хорошие новости: я вчера адски тупил
В общем, я успешно перепутал местами методы IsAnyFlagUnset и IsFlagUnset. Ага, в логику могут не только лишь все
Тысячу извинений, сам удивляюсь, как легко сначала сделать ошибку, затем пропустить и затем геройски бороться с последствиями. Добавил к себе в примеры как делать не надо.


И таки что у нас получается:
табличку поправил,
код поправил + добавил нормальные use case tests. Теперь можно обсуждать.

Итого у нас два варианта — текущий многострадальный (он наконец меня устраивает):
  Скрытый текст
        [Test]
        public void TestEnumUseCaseShort()
        {
            Action<bool> istrue = Assert.IsTrue;
            Action<bool> isfalse = Assert.IsFalse;

            var permissions = PermittedActions.None;
            var readOrOwner = PermittedActions.Read | PermittedActions.SetOwner;

            permissions = permissions.SetFlag(PermittedActions.Read);
            permissions = permissions.SetFlag(PermittedActions.Write);
            permissions = permissions.ClearFlag(PermittedActions.Write);

            // conditional set or clear
            permissions = permissions.SetFlag(PermittedActions.ReadContent, enabled: false);
            permissions = permissions.SetFlag(PermittedActions.ReadWrite, enabled: true);

            // Checks that entire bit combination is set
            isfalse(permissions.IsFlagSet(readOrOwner));
            istrue(permissions.IsFlagSet(PermittedActions.Read));
            isfalse(permissions.IsFlagSet(PermittedActions.SetOwner));

            // Checks that any bit is NOT set
            istrue(permissions.IsAnyFlagUnset(readOrOwner));
            isfalse(permissions.IsAnyFlagUnset(PermittedActions.Read));
            istrue(permissions.IsAnyFlagUnset(PermittedActions.SetOwner));

            // Checks that any bit is set
            istrue(permissions.IsAnyFlagSet(readOrOwner));
            istrue(permissions.IsAnyFlagSet(PermittedActions.Read));
            isfalse(permissions.IsAnyFlagSet(PermittedActions.SetOwner));

            // Checks that entire bit combination is NOT set
            isfalse(permissions.IsFlagUnset(readOrOwner));
            isfalse(permissions.IsFlagUnset(PermittedActions.Read));
            istrue(permissions.IsFlagUnset(PermittedActions.SetOwner));
        }


и тот, что в этом топике нарисовался:
  Скрытый текст
        [Test]
        public void TestEnumUseSetBased()
        {
            Action<bool> istrue = Assert.IsTrue;
            Action<bool> isfalse = Assert.IsFalse;

            var permissions = PermittedActions.None;
            var readOrOwner = PermittedActions.Read | PermittedActions.SetOwner;

            permissions = permissions.With(PermittedActions.Read);
            permissions = permissions.With(PermittedActions.Write);
            permissions = permissions.Without(PermittedActions.Write);

            // conditional set or clear
            permissions = permissions.WithOrWithout(PermittedActions.ReadContent, include: false);
            permissions = permissions.WithOrWithout(PermittedActions.ReadWrite, include: true);

            // Checks that entire bit combination is set
            isfalse(permissions.Includes(readOrOwner));
            istrue(permissions.Includes(PermittedActions.Read));
            isfalse(permissions.Includes(PermittedActions.SetOwner));

            // Checks that any bit is NOT set
            istrue(permissions.ExcludesAny(readOrOwner));
            isfalse(permissions.ExcludesAny(PermittedActions.Read));
            istrue(permissions.ExcludesAny(PermittedActions.SetOwner));

            // Checks that any bit is set
            istrue(permissions.IncludesAny(readOrOwner));
            istrue(permissions.IncludesAny(PermittedActions.Read));
            isfalse(permissions.IncludesAny(PermittedActions.SetOwner));

            // Checks that entire bit combination is NOT set
            isfalse(permissions.Excludes(readOrOwner));
            isfalse(permissions.Excludes(PermittedActions.Read));
            istrue(permissions.Excludes(PermittedActions.SetOwner));
        }

выбираем, предлагаем ещё

ничего не добавится — закину в основной раздел для обсуждения.
Отредактировано 22.09.2016 16:25 Sinix . Предыдущая версия .
Re[17]: EnumHelper: request for breaking changes
От: Дьяченко Александр Россия  
Дата: 22.09.16 14:31
Оценка: 50 (1)
Здравствуйте, Sinix, Вы писали:

S>И таки что у нас получается:

S>табличку поправил,
S>код поправил + добавил нормальные use case tests. Теперь можно обсуждать.

У меня стойкое впечатление, что и в табличке и в примерах что-то с порядком методов.

NewNew (как должно быть)
set flagfileAccess = fileAccess.SetFlag(FileAccess.Write);fileAccess = fileAccess.SetFlag(FileAccess.Write);
clear flagfileAccess = fileAccess.ClearFlag(FileAccess.Write);fileAccess = fileAccess.ClearFlag(FileAccess.Write);
conditional set (or clear) flagfileAccess = fileAccess.UpdateFlag(FileAccess.Write, enable: true);fileAccess = fileAccess.UpdateFlag(FileAccess.Write, enable: true);
check if all flags are setif (fileAccess.IsFlagSet(FileAccess.Write)) ...if (fileAccess.IsFlagSet(FileAccess.Write)) ...
check if all flags are not setif (fileAccess.IsAnyFlagUnset(FileAccess.Write | FileAccess.Read)) ...if (fileAccess.IsFlagUnset(FileAccess.Write)) ...
check if any flag is setif (fileAccess.IsAnyFlagSet(FileAccess.Write | FileAccess.Read)) ...if (fileAccess.IsAnyFlagSet(FileAccess.Write | FileAccess.Read)) ...
check if any flag is not setif (fileAccess.IsFlagUnset(FileAccess.Write)) ...if (fileAccess.IsAnyFlagUnset(FileAccess.Write | FileAccess.Read)) ...
assert that all flags are setEnumCode.FlagSet(fileAccess, "fileAccess", FileAccess.Write);EnumCode.FlagSet(fileAccess, "fileAccess", FileAccess.Write);
assert that all flags are not setEnumCode.AnyFlagUnset(fileAccess, "fileAccess", FileAccess.Write | FileAccess.Read);EnumCode.FlagUnset(fileAccess, "fileAccess", FileAccess.Write);
assert that any flag setEnumCode.AnyFlagSet(fileAccess, "fileAccess", FileAccess.Write | FileAccess.Read);EnumCode.AnyFlagSet(fileAccess, "fileAccess", FileAccess.Write | FileAccess.Read);
assert that any flag is not setEnumCode.FlagUnset(fileAccess, "fileAccess", FileAccess.Write);EnumCode.AnyFlagUnset(fileAccess, "fileAccess", FileAccess.Write | FileAccess.Read);


S>выбираем, предлагаем ещё


Варианте New, но в нем как-то не хватает симетричности можно попробывать такие варианты:

Вариант 1 (Set-Clear)
set flagfileAccess = fileAccess.SetFlag(FileAccess.Write);
clear flagfileAccess = fileAccess.ClearFlag(FileAccess.Write);
conditional set (or clear) flagfileAccess = fileAccess.SetFlagValue(FileAccess.Write, value: true);
check if all flags are setif (fileAccess.IsAllFlagSet(FileAccess.Write)) ...
check if all flags are not setif (fileAccess.IsAllFlagClear(FileAccess.Write)) ...
check if any flag is setif (fileAccess.IsAnyFlagSet(FileAccess.Write | FileAccess.Read)) ...
check if any flag is not setif (fileAccess.IsAnyFlagClear(FileAccess.Write | FileAccess.Read)) ...
assert that all flags are setEnumCode.AllFlagSet(fileAccess, "fileAccess", FileAccess.Write);
assert that all flags are not setEnumCode.AllFlagClear(fileAccess, "fileAccess", FileAccess.Write);
assert that any flag setEnumCode.AnyFlagSet(fileAccess, "fileAccess", FileAccess.Write | FileAccess.Read);
assert that any flag is not setEnumCode.AnyFlagClear(fileAccess, "fileAccess", FileAccess.Write | FileAccess.Read);
Вариант 2 (Set-Unset)
set flagfileAccess = fileAccess.SetFlag(FileAccess.Write);
clear flagfileAccess = fileAccess.UnsetFlag(FileAccess.Write);
conditional set (or clear) flagfileAccess = fileAccess.UpdateFlag(FileAccess.Write, value: true);
check if all flags are setif (fileAccess.IsAllFlagSet(FileAccess.Write)) ...
check if all flags are not setif (fileAccess.IsAllFlagUnset(FileAccess.Write)) ...
check if any flag is setif (fileAccess.IsAnyFlagSet(FileAccess.Write | FileAccess.Read)) ...
check if any flag is not setif (fileAccess.IsAnyFlagUnset(FileAccess.Write | FileAccess.Read)) ...
assert that all flags are setEnumCode.AllFlagSet(fileAccess, "fileAccess", FileAccess.Write);
assert that all flags are not setEnumCode.AllFlagUnset(fileAccess, "fileAccess", FileAccess.Write);
assert that any flag setEnumCode.AnyFlagSet(fileAccess, "fileAccess", FileAccess.Write | FileAccess.Read);
assert that any flag is not setEnumCode.AnyFlagUnset(fileAccess, "fileAccess", FileAccess.Write | FileAccess.Read);
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Re[17]: EnumHelper: request for breaking changes
От: samius Япония http://sams-tricks.blogspot.com
Дата: 22.09.16 15:07
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, samius, Вы писали:


S>Так, хорошие новости: я вчера адски тупил

S>В общем, я успешно перепутал местами методы IsAnyFlagUnset и IsFlagUnset. Ага, в логику могут не только лишь все
S>Тысячу извинений, сам удивляюсь, как легко сначала сделать ошибку, затем пропустить и затем геройски бороться с последствиями. Добавил к себе в примеры как делать не надо.

Так это повод поменять названия
Re[18]: EnumHelper: request for breaking changes
От: Sinix  
Дата: 22.09.16 16:04
Оценка:
Здравствуйте, samius, Вы писали:

S>Так это повод поменять названия

Это не повод поменять названия, а кое-кто протупил жестоко
Re[18]: EnumHelper: request for breaking changes
От: Sinix  
Дата: 22.09.16 16:18
Оценка:
Здравствуйте, Дьяченко Александр, Вы писали:

ДА>У меня стойкое впечатление, что и в табличке и в примерах что-то с порядком методов.

Ага, накосячил, поправил.

ДА>Варианте New, но в нем как-то не хватает симетричности можно попробывать такие варианты:

Принято, добавлю.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.