Здравствуйте, SV., Вы писали:
SV.>Можете ли вы привести пример, когда булевский параметр метода вам действительно необходим?
Таких ситуаций нет, хотя бы потому, что любую ситуацию, где используется булева переменная, модно переписать на использование какого-нибудь enum`а или int`a. Предлагаю изменить постановку вопроса на: "когда применение булевого параметра было бы оптимальным".
Здравствуйте, Пацак, Вы писали:
П>Здравствуйте, SV., Вы писали:
SV.>>Можете ли вы привести пример, когда булевский параметр метода вам действительно необходим?
П>
Здравствуйте, 0x7be, Вы писали:
0>Здравствуйте, SV., Вы писали:
0>Таких ситуаций нет, хотя бы потому, что любую ситуацию, где используется булева переменная, модно переписать на использование какого-нибудь enum`а или int`a.
Концептуально bool и есть перечисление из двух элементов: true и false. Так что вопрос автора не имеет смысла.
А вот и нифига. В том же C# обычно на свойства вешают что-то с относительно тривиальными методами-аксессорами. Если внутри set/get сложная логика, которая может подолгу крутиться и что-то тяжёлое поднимать, то рекомендуют так и писать методы GetSomething/SetSomething
Здравствуйте, SV., Вы писали:
SV.>Можете ли вы привести пример, когда булевский параметр метода вам действительно необходим?
Совсем недавно создал такой метод. Надо было блокировать и разблокировать часть элементов формы в зависимости от развития ситуации. Свойство нафиг не нужно, потому как состояние меня не интересовало. Читать не надо было. А метод очень даже подошел.
Здравствуйте, konsoletyper, Вы писали:
K>А вот и нифига. В том же C# обычно на свойства вешают что-то с относительно тривиальными методами-аксессорами. Если внутри set/get сложная логика, которая может подолгу крутиться и что-то тяжёлое поднимать, то рекомендуют так и писать методы GetSomething/SetSomething
В таком случае делается класс-конфигурация параметров этого долгого и мучительного процесса. А у класса того исключительно примитивные свойства и будут (см ProcessStartInfo).
Здравствуйте, hardcase, Вы писали:
H>Здравствуйте, 0x7be, Вы писали:
0>>Здравствуйте, SV., Вы писали:
0>>Таких ситуаций нет, хотя бы потому, что любую ситуацию, где используется булева переменная, модно переписать на использование какого-нибудь enum`а или int`a.
H>Концептуально bool и есть перечисление из двух элементов: true и false. Так что вопрос автора не имеет смысла.
Это как посмотреть. Может оно и так если в языке L речь идет о каком-то объекте X, который равняется True. (Т.е. X=True). А вот когда мы о самом этом равенстве (X=True) как о высказывании говорим что оно True или False так мы переходим на другой семантический уровень рассуждая о самом высказывании. Здесь уже True или False объекты метаязыка манипулирующего с конструкциями языка L.
Может заумно.. но это ж ветка философия
Здравствуйте, SV., Вы писали:
SV.>Можете ли вы привести пример, когда булевский параметр метода вам действительно необходим?
(необходим — слишком сильно),
например, в таком случае он нужен:
метод выборки данных по фильтру, состоящему из нескольких его атрибутов, что-то типа findObjectsByCriteria(String param1, Integer param2, ... Boolean paramN, ..., Boolean paramM),
где paramN, paramM соответствуют каким-то булевским атрибутам объектов, среди которых производится поиск
необходимость, как нетрудно догадаться, проистекает из того, что изначально объекты согласно анализу могут иметь среди своих атрибутов либо простые флаговые (типа on/off, active/inactive, started/stopped), либо сочинённые (когда атрибут типа какого-то enum, но у каждого элемента enum, всё равно, есть свой набор булевских субпризнаков, по каждому из которых в программе обработки может появиться ветвление)
Здравствуйте, hardcase, Вы писали:
H>Здравствуйте, batu, Вы писали:
B>>Здесь уже True или False объекты метаязыка манипулирующего с конструкциями языка L.
H>И тем не менее этих объектов две штуки и над ними можно определить алгебру (например булеву).
Можно, можно..
Здравствуйте, SV., Вы писали:
SV.>Можете ли вы привести пример, когда булевский параметр метода вам действительно необходим?
Курить термин: "дизъюнктивная когерентность".
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, 0x7be, Вы писали:
0>Здравствуйте, SV., Вы писали:
SV.>>Можете ли вы привести пример, когда булевский параметр метода вам действительно необходим? 0>Таких ситуаций нет, хотя бы потому, что любую ситуацию, где используется булева переменная, модно переписать на использование какого-нибудь enum`а или int`a. Предлагаю изменить постановку вопроса на: "когда применение булевого параметра было бы оптимальным".
Возьмем С++:
Было :
void DoSomething(bool flag)
{
if (flag)
DoSomethingNow();
else
DoSomethingLater();
}
Стало:
enum DoFlag
{
DO_FLAG_NOW,
DO_FLAG_LATER,
}
void DoSomething(DoFlag flag)
{
switch (flag)
{
case DO_FLAG_NOW:
DoSomethingNow();
break;
case DO_FLAG_LATER:
DoSomethingLater();
break;
default:
// Must never get here
assert(false);
break;
}
}
Здравствуйте, _NN_, Вы писали:
_NN>Нет, конечно. _NN>Ведь enum DoFlag когда-то может быть изменен.
Значит это уже не аналог bool => в первом варианте использовать bool нельзя.
при этом для понимания из какого enum-а брать Italic достаточно вывести тип выражения на основе типа параметра функции MergeFont (что, кстати, уже делает intellisence, но не делает компилятор)
А что значит "действительно необходим"? В любом случае можно обойтись без него, используия целые числа 0 и 1, или содержательные енумы из двух элементов (Для первого примера — WAIT_UNTIL_DONE и DONT_WAIT_UNTIL_DONE). Но не проще ли использовать бул?
DG>при этом для понимания из какого enum-а брать Italic достаточно вывести тип выражения на основе типа параметра функции MergeFont (что, кстати, уже делает intellisence, но не делает компилятор)
Или так:
font += Font.Italic;
font -= Font.Italic;
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
24>А что значит "действительно необходим"? В любом случае можно обойтись без него, используия целые числа 0 и 1, или содержательные енумы из двух элементов (Для первого примера — WAIT_UNTIL_DONE и DONT_WAIT_UNTIL_DONE). Но не проще ли использовать бул?
Проще, без сомнения. Enum сложнее — программа становится на 1 элемент больше. Но это простота, которая хуже воровства. Все, почему-то, приводят декларации: waitUntilDone, repeats, isFirstRun... А вы вызовы приведите:
Так вот. Очевидно, что авторы таких методов делают что — используют (reuse) не по делу встроенный в язык универсальный нетипизированный enum (true, false), лишь бы свой не объявлять. Популярные языки не позволяют писать так:
Вот людям и не хочется заводить отдельные сущности. Это относится к половине приведенных примеров. Другая половина лечится (действительно, лечится, то есть, становится лучше) путем введения дополнительного класса с булевскими свойствами. Ах, да. Есть еще ответ про когерентность — он некогерентен, и про абсолютную обходимость — он непрагматичен и потому легко обходим.
Теперь к вашему вопросу про "необходимо". Необходимо, это когда необходимо. Когда нужен именно универсальный нетипизированный enum в параметрах, и любая попытка обойти делает код очевидно хуже.
Я пока вижу только работу с флагами, в сугубо закрытых методах реализаций. Неужели больше никто ничего придумать не может? Если так, то давно следует если не ошибку компиляции давать на bool в публичных методах, то уж warning точно. Не знаю, не ломлюсь ли я в открытую дверь — идея весьма очевидна.
Здравствуйте, SV., Вы писали:
SV.>Вот людям и не хочется заводить отдельные сущности. Это относится к половине приведенных примеров.
я думал, что к этому ведёт вопрос, поэтому добавлю, что при вызовах методов с булевскими флагами практикую одно из двух:
1) либо объявляю для общего пользования в том же классе, где и метод с булевским параметром, две булевских константы с говорящими именами
2) либо пишу при вызове true /* isFirstRun */, false /* don't wait until done */
Здравствуйте, SV., Вы писали:
SV.>Все, почему-то, приводят декларации: waitUntilDone, repeats, isFirstRun... А вы вызовы приведите:
Вот вызов на Objective-C:
в идеале слово Font здесь лишнее (однозначно восстанавливаемое из контекста) S>
S>font += Italic;
S>font -= Italic;
S>
зы
вот этот метод мне не очень нравится, он создает неоднозначности при дальнейших расширениях
font -= Font.Italic;
одно из желаемых расширений — это чтобы можно было наложить сразу группу "эффектов" (это в частности необходимо, когда эффекты возвращаются внешней функций):
var effects = Italic + !Bold + 24px; //var effects = GetEffects();
font += effects;
если же есть функция -=, то необходимо разбираться что дает минус группа: эффект пропадает только при строгом сравнении, при нестрогом, как-то еще.
Здравствуйте, SV., Вы писали:
SV.>Можете ли вы привести пример, когда булевский параметр метода вам действительно необходим?
Конечно.
database.AllowSnapshotIsolation(true);
во первых это нетривиальная операция и пропертей ей быть не следует
во вторых переход выглядит как disabled -> enabling -> enabled и булом его описать нельзя
Здравствуйте, rm822, Вы писали:
SV.>>Можете ли вы привести пример, когда булевский параметр метода вам действительно необходим? R>Конечно. R>
R>database.AllowSnapshotIsolation(true);
R>
R>во первых это нетривиальная операция и пропертей ей быть не следует R>во вторых переход выглядит как disabled -> enabling -> enabled и булом его описать нельзя
Здесь вообще никакие параметры не нужны, IMHO. Ни булевы, ни не булевы.
enum State
{
Disabling,
Disabled,
Enabling,
Enabled,
}
class Database
{
State GetState();
void EnableSnapshotIsolation();
void DisableSnapshotIsolation();
}
R>Интерфейс определяется решаемыми задачами, а не твоими фантазиями R>привычный синтаксис таков R>
R>ALTER DATABASE <dbname> SET ALLOW_SNAPSHOT_ISOLATION <ON|OFF>;
R>
Я не в курсе про SQL-ный интерфейс к этому классу.
R>и методы должны по возможности близки к нему
AllowSnapshotIsolation(true); -- вот это вы называете "по возможности близки"? Если уж задаваться такой целью, нужен enum { ON, OFF }.
R>State же просто никому не нужен, это твои фантазии
Извините, вот это кто написал? "во вторых переход выглядит как disabled -> enabling -> enabled и булом его описать нельзя". Если вы не читаете из этого свойства (оно write-only), то его МОЖНО описать булом. А если читаете, то читать надо отдельным методом GetSatate(), поскольку такие свойства, в которых кладешь одно, а они возвращают другое, делать Заратустра не позволяет.
R>ну и в конце концов батарея из 30 методов начинающихся на Enable\Disable это просто нечитаемый отстой, колторый к тому же и не комплитится нормально
Здравствуйте, SV., Вы писали:
R>>и методы должны по возможности близки к нему SV.>AllowSnapshotIsolation(true); -- вот это вы называете "по возможности близки"? Если уж задаваться такой целью, нужен enum { ON, OFF }.
Я не силен в сиквелах, но: а это не случай ли с классом-конфигурацией? В SQL Server Management Studio я смутно припоминаю несколько диалогов с PropertyBrowser'ами, что и навело меня на такое подозрение. AllowSnapshotIsolation не одно ли из этих свойств, которые пачками устанавливаются?
Здравствуйте, DarkGray, Вы писали: DG>одно из желаемых расширений — это чтобы можно было наложить сразу группу "эффектов" (это в частности необходимо, когда эффекты возвращаются внешней функций):
Непонятно, зачем. Мы всегда можем переделать эту функцию в
Font ApplyEffects(Font source)
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
SV.>AllowSnapshotIsolation(true); -- вот это вы называете "по возможности близки"? Если уж задаваться такой целью, нужен enum { ON, OFF }.
Ну и зачем изобретать собственный бул если читаеость от этого не улучшается?
SV.>Если вы не читаете из этого свойства (оно write-only), то его МОЖНО описать булом.
см п1
во первых это нетривиальная операция и пропертей ей быть не следует
Здравствуйте, rm822, Вы писали:
SV.>>AllowSnapshotIsolation(true); -- вот это вы называете "по возможности близки"? Если уж задаваться такой целью, нужен enum { ON, OFF }. R>Ну и зачем изобретать собственный бул если читаеость от этого не улучшается?
Читаемость не улучшится, но зато соблюдается требование "по возможности близки".
Если забить на это странное требование, и принять во внимание то, что вы написали про цепочку состояний, получается, что это асинхронный запрос сколько-нибудь длительной операции. И я бы его сделал так, как написал — отдельным безпараметровым методом, либо (если архитектура к тому располагает) методом с одним параметром — классом-конфигурацией.
SV.>>Если вы не читаете из этого свойства (оно write-only), то его МОЖНО описать булом. R>см п1 R>во первых это нетривиальная операция и пропертей ей быть не следует
Если вы забираете п.2, то я забираю назад метод GetState(). Я просто объяснил, откуда он взялся.
Нет, знаете что — расскажите лучше про типовой юз-кейс вызова AllowSnapshotIsolation. Не могу представить, как так получается, что делается запрос на изменение состояния и не интересует результат.
Здравствуйте, 24, Вы писали:
SV.>>Все, почему-то, приводят декларации: waitUntilDone, repeats, isFirstRun... А вы вызовы приведите: 24>Вот вызов на Objective-C:
24>
Скажу честно, вопроса не понял. Если буквально, то ответ — все те же. Если это утверждение, что булевы параметры становятся не так плохи, когда имя параметра явно указывается, то я с ним согласен, но это решение порождает другие проблемы.
24>>Какие альтернативы булу в данном случае?
SV.>Скажу честно, вопроса не понял. Если буквально, то ответ — все те же. Если это утверждение, что булевы параметры становятся не так плохи, когда имя параметра явно указывается,
Нет, это не утверждение. Мне интересно посмотреть, что, при способе именования как в Objective-C, можно использовать вместо BOOL, и чем это будет лучше. Если заменить на
То в этом случае нужно смотреть либо определение, либо доки, чтоб по вызову понять, какие туда можно передавать константы. А по первому вызову сразу видно, что варианта всего два, и смысл waitUntilDone:YES воспринимается вполне однозначно.
SV.>но это решение порождает другие проблемы.
Какие проблемы в этом решении, и как можно преобразовать этот вызов, чтоб стало лучше?
DG>>одно из желаемых расширений — это чтобы можно было наложить сразу группу "эффектов" (это в частности необходимо, когда эффекты возвращаются внешней функций): S>Непонятно, зачем. Мы всегда можем переделать эту функцию в S>
S>Font ApplyEffects(Font source)
S>
а где сами эффекты?
или это метод? и source — это effects? но тогда какие поля из source надо накладывать, а какие нет?
вообще, если разбирать базовые операции над типами — то они развиваются следующим образом:
сравнение -> получение разницы -> применение разницы (и тот же css — это как раз возможность записать разницу между аттрибутами элемента, а потом ее применить)
для структурного типа результат получения разницы имеет тип более расширенный, чем исходный тип: у каждого поля еще появляется значение, что поле не поменялось (и если для reference типов полей это можно отобразить в null, то для value-type-ов приходится вводить новую структуру, например, nullable-поля)
или если вернуться к примеру, то тип выражения: Italic + !Bold + Size(24px) — есть FontDifference(или даже более общий), а не Font
SV.>Нет, знаете что — расскажите лучше про типовой юз-кейс вызова AllowSnapshotIsolation. Не могу представить, как так получается, что делается запрос на изменение состояния и не интересует результат.
О, это довольно занятная тема. SI — это режим версионника для MSSQL, т.е. нам дозволяется читать старые версии данных. Для того чтобы их читать нужен undo-log, ведение которого на самом-то деле и включает AllowSnapshotIsolation.
Долгий переход(упрощенно) же связан с тем что на момент переключения уже есть транзакции, которые никакого undo-лога не вели, и пока все они не завершатся — переход не произойдет.
Поэтому типичный сценарий выглядит так
1. AllowSnapshotIsolation
2. подождать К-минут, пока завершатся все активные транзакции
3. убить все транзакции старше К-минут, считаем их неадекватными
DG>>>одно из желаемых расширений — это чтобы можно было наложить сразу группу "эффектов" (это в частности необходимо, когда эффекты возвращаются внешней функций): S>>Непонятно, зачем. Мы всегда можем переделать эту функцию в S>>
S>>Font ApplyEffects(Font source)
S>>
DG>а где сами эффекты?
Внутри функции, вестимо. Вы зачем-то хотите их сначала вытащить, а потом применить. В то время, как надо просто дать их применить и всё.
DG>вообще, если разбирать базовые операции над типами — то они развиваются следующим образом: DG>сравнение -> получение разницы -> применение разницы (и тот же css — это как раз возможность записать разницу между аттрибутами элемента, а потом ее применить)
Какую разницу? В CSS ничего про разницу нету. Это вы что-то не то курите.
DG>или если вернуться к примеру, то тип выражения: Italic + !Bold + Size(24px) — есть FontDifference(или даже более общий), а не Font
Зачем вам вообще такое выражение?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
DG>>а где сами эффекты? S>Внутри функции, вестимо. Вы зачем-то хотите их сначала вытащить, а потом применить. В то время, как надо просто дать их применить и всё.
потому что я хочу декларативный подход, а не императивный.
а при декларативном подходе все состояния меняются явно, а не внутри инкапсуляций.
DG>>вообще, если разбирать базовые операции над типами — то они развиваются следующим образом: DG>>сравнение -> получение разницы -> применение разницы (и тот же css — это как раз возможность записать разницу между аттрибутами элемента, а потом ее применить) S>Какую разницу? В CSS ничего про разницу нету. Это вы что-то не то курите.
подумай еще раз, в этот раз подольше.
и попробуй ответить на простой вопрос — каким типом с точки зрения статической типизации является конструкция?:
и в чем отличие этого типа от типа результата функции diff(element1.style, element2.style)?
DG>>или если вернуться к примеру, то тип выражения: Italic + !Bold + Size(24px) — есть FontDifference(или даже более общий), а не Font S>Зачем вам вообще такое выражение?
чтобы в коде можно было записать в один в один то, что можно записать через css (со всеми статик-проверками и т.д.)
сейчас получается, что css мощнее, чем универсальный язык.
Здравствуйте, DarkGray, Вы писали: DG>потому что я хочу декларативный подход, а не императивный. DG>а при декларативном подходе все состояния меняются явно, а не внутри инкапсуляций.
1. Неправда. Декларативный подход никак не отменяет инкапсуляцию.
2. В коде, который я привёл, вообще никакие состояния не меняются, ни явно, ни неявно. DG>и в чем отличие этого типа от типа результата функции diff(element1.style, element2.style)?
Ну, на мой взляд, он ничем не отличается от типа element1.style.
DG>чтобы в коде можно было записать в один в один то, что можно записать через css (со всеми статик-проверками и т.д.)
Не вижу проблемы.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, hardcase, Вы писали:
K>>А вот и нифига. В том же C# обычно на свойства вешают что-то с относительно тривиальными методами-аксессорами. Если внутри set/get сложная логика, которая может подолгу крутиться и что-то тяжёлое поднимать, то рекомендуют так и писать методы GetSomething/SetSomething
H>В таком случае делается класс-конфигурация параметров этого долгого и мучительного процесса. А у класса того исключительно примитивные свойства и будут (см ProcessStartInfo).
Класс-конфигурация, состоящая из единственного поля?
Здравствуйте, SV., Вы писали:
SV.>Проще, без сомнения. Enum сложнее — программа становится на 1 элемент больше. Но это простота, которая хуже воровства. Все, почему-то, приводят декларации: waitUntilDone, repeats, isFirstRun... А вы вызовы приведите:
На C# можно так:
Здравствуйте, blackhearted, Вы писали:
B>Здравствуйте, cppnick, Вы писали: C>>Класс-конфигурация, состоящая из единственного поля?
B>oop , сударь, ресурсов хватит на всех.
А удобство использования? И кто там говорил, не плодить лишних сущностей?
Здравствуйте, cppnick, Вы писали:
C>Здравствуйте, blackhearted, Вы писали:
B>>Здравствуйте, cppnick, Вы писали: C>>>Класс-конфигурация, состоящая из единственного поля?
B>>oop , сударь, ресурсов хватит на всех.
C>А удобство использования? И кто там говорил, не плодить лишних сущностей?
Здравствуйте, SV., Вы писали:
SV.>А просто !p || q написать?
Написать можно что угодно. implies это простейший пример, в котором необходим именно булевый параметр, но конечно же можно представить себе и более сложный. А умея мыслить абстрактно и представлять ничего не надо, implies в достаточной мере демонстрирует, что методы, в которых необходимы булевые параметры, существуют.
Здравствуйте, igna, Вы писали:
I>Написать можно что угодно. implies это простейший пример, в котором необходим именно булевый параметр, но конечно же можно представить себе и более сложный. А умея мыслить абстрактно и представлять ничего не надо, implies в достаточной мере демонстрирует, что методы, в которых необходимы булевые параметры, существуют.
Есть такая чисто философская статья — "Кто мыслит абстрактно?". Можете полюбопытствовать. Спойлер: в этом смысле абстрактно мыслят невежды, а инженеры мыслят примерами.
Неявный вопрос, который заставил меня создать этот топик, такой: можем ли мы в языке Я запретить булевы параметры вообще, или какой-то ребенок тоже будет с ними выплеснут?
В простейшем виде ваш implies не жалко. А вот более сложный — может быть, будет жалко. Но для этого его надо привести, а не абстрактно признать его существование.
Здравствуйте, SV., Вы писали:
SV.>Неявный вопрос, который заставил меня создать этот топик, такой: можем ли мы в языке Я запретить булевы параметры вообще, или какой-то ребенок тоже будет с ними выплеснут?
Аналогично можно ведь и int запретить. Или ты видишь разницу? Какую?
SV.>В простейшем виде ваш implies не жалко. А вот более сложный — может быть, будет жалко. Но для этого его надо привести, а не абстрактно признать его существование.
Здравствуйте, igna, Вы писали:
SV.>>Неявный вопрос, который заставил меня создать этот топик, такой: можем ли мы в языке Я запретить булевы параметры вообще, или какой-то ребенок тоже будет с ними выплеснут? I>Аналогично можно ведь и int запретить. Или ты видишь разницу? Какую?
Совсем вы зафилософствовались. Разница в том, что одно — целые, а другое — булевские значения. Какой еще вам разницы надо?
SV.>>В простейшем виде ваш implies не жалко. А вот более сложный — может быть, будет жалко. Но для этого его надо привести, а не абстрактно признать его существование. I>Тебе надо, ты и приводи.
Если бы это было надо мне, и никому больше, я бы пошел и заплатил денег. Но это, потенциально, много кому может быть интересно (сколько доморощенных языков тут довели до продукта?), поэтому я создал для тех, кому это интересно и/или полезно, эту ветку. Я не модератор, но на правах топикстартера хотелось бы внести посильный вклад в эффективность обсуждения. В частности, не дать ему стать абстрактным настолько, насколько хотят "необразованные люди" (цитата из неосиленного Гегеля — "Кто мыслит абстрактно?", всячески рекомендую).
Игра тут такая: я решил, что булевы параметры методов несут много всякого зла, а толку с них никакого. Этот тезис предлагается почтенной публике. Тот, кто его опровергнет примером, выигрывает в этой игре и кладет меня на обе лопатки. Некогда играть — иди, зарабатывай деньги. Кто ж неволит.
SV. wrote:
> Игра тут такая: я решил, что булевы параметры методов несут много > всякого зла, а толку с них никакого. Этот тезис предлагается > почтенной публике. Тот, кто его опровергнет примером, выигрывает в > этой игре и кладет меня на обе лопатки. Некогда играть — иди, > зарабатывай деньги. Кто ж неволит.
Здравствуйте, SV., Вы писали:
SV.>Совсем вы зафилософствовались. Разница в том, что одно — целые, а другое — булевские значения. Какой еще вам разницы надо?
Так по тем же соображениям по которым вместо bool имеет смысл использовать enum, часто вместо int имеет смысл использовать специальный тип, например какой-нибудь string_length. И точно так же иногда нужен именно int. Ситуация ничем принципиально не отличается.
Здравствуйте, avp_, Вы писали:
_>SV. wrote:
>> Игра тут такая: я решил, что булевы параметры методов несут много >> всякого зла, а толку с них никакого. Этот тезис предлагается >> почтенной публике. Тот, кто его опровергнет примером, выигрывает в >> этой игре и кладет меня на обе лопатки. Некогда играть — иди, >> зарабатывай деньги. Кто ж неволит.
_>bool IsSoftRegistered=...; _>... _>SuperButton.SetVisible( IsSoftRegistered )
Так было же уже. Если по уму, свойства нужны. Где их не сделали, там булевы параметры необходимы, вопросов нет.
Здравствуйте, igna, Вы писали:
SV.>>Совсем вы зафилософствовались. Разница в том, что одно — целые, а другое — булевские значения. Какой еще вам разницы надо?
I>Так по тем же соображениям по которым вместо bool имеет смысл использовать enum, часто вместо int имеет смысл использовать специальный тип, например какой-нибудь string_length. И точно так же иногда нужен именно int. Ситуация ничем принципиально не отличается.
Тогда я вас не понял. Теперь понял. Возвращаюсь в исходную точку:
>Аналогично можно ведь и int запретить.
Отвечаю. Запретить int и запретить bool (контекст: как параметры публичных методов) — вещи разные. Разница вот в чем. Для int легко придумать пример, когда он будет, цитирую, "действительно необходим".
public uint abs(int a)
{
return a >= 0 ? a : -a;
}
Возьмите любую математическую формулу, с целыми числами, и это готовый шаблон функции с целочисленными параметрами. Я от математики далек, но какая-нибудь малая теорема Ферма, по-моему, опирается на класс целых (необязательно положительных) чисел. Далее, даже если по смыслу формула одинаково работает для вещественных и целых чисел, для оптимизации есть смысл разделять эти два класса (отдельно считать, например, степени — int pow(int n, int p)).
То есть, хотя "часто вместо int имеет смысл использовать специальный тип, например какой-нибудь string_length", часто имеет смысл использовать обобщенный int.
Покажите такой же фокус с bool, и да, окажется, что "ситуация ничем принципиально не отличается". Пока она принципиально отличается именно этим.
SV.>public uint abs(int a)
SV.>{
SV.> return a >= 0 ? a : -a;
SV.>}
SV.>Покажите такой же фокус с bool, и да, окажется, что "ситуация ничем принципиально не отличается". Пока она принципиально отличается именно этим.
Ну чем это implies "принципиально отличается" от abs? А скажем функция возвращающая true тогда и только тогда, когда один и только один из ее аргументов равен true?
Здравствуйте, igna, Вы писали:
I>Здравствуйте, SV., Вы писали:
I>
SV.>>public uint abs(int a)
SV.>>{
SV.>> return a >= 0 ? a : -a;
SV.>>}
I>
SV.>>Покажите такой же фокус с bool, и да, окажется, что "ситуация ничем принципиально не отличается". Пока она принципиально отличается именно этим.
I>Ну чем это implies "принципиально отличается" от abs? А скажем функция возвращающая true тогда и только тогда, когда один и только один из ее аргументов равен true?
Отличается, но в целях экономии времени я обращаю ваше внимание на другие примеры. К вашим услугам элементарная теория чисел.
Есть и чисто компьютерный пример:
void SetPixel(int x, int y, Color color);
в относительной системе координат (иначе был бы смысл заменить int на uint).
Это что, пример, где нужно использовать int?! Тому, кто хочет заменить bool на enum везде, здесь вместо int два типа определить нужно, что-нибудь вроде XCoord и YCoord.
Здравствуйте, igna, Вы писали:
SV.>>А покажите.
I>
SV.>>void InitApplication(bool firstRun); | void InitApplication(EInitOption option);
SV.>>... | ...
SV.>>InitApplication(true); | InitApplication(EInitOption.FirstRun);
SV.>>------------------------------------------------------------------------
SV.>>SetPixel(int x, int y, Color color); |
SV.>>... | ???
SV.>>SetPixel(42, 34, Color.Red); |
I>
I>То есть самому не понятно, как? Что-то сильно похоже на троллинг, не обессудь, если не так, но не буду ничего показывать.
Кто-нибудь еще понимает, что он хотел сказать своими XCoord и YCoord? Бессмысленно и беспощадно затайпдефить их, сохранив тот же диапазон допустимых значений?
Здравствуйте, SV., Вы писали:
SV.>Кто-нибудь еще понимает, что он хотел сказать своими XCoord и YCoord? Бессмысленно и беспощадно затайпдефить их, сохранив тот же диапазон допустимых значений?
Если не троллишь, то тебя основательно заклинило. Элементарные же вещи, да вот хотя бы так (C++):
class XCoord {
int x_;
public:
explicit XCoord(int x) : x_(x) {}
operator int() { return x_; }
};
Все-таки какая-никакая защита от непреднамеренного использования произвольного целого в качестве XCoord.
Здравствуйте, igna, Вы писали:
SV.>>Кто-нибудь еще понимает, что он хотел сказать своими XCoord и YCoord? Бессмысленно и беспощадно затайпдефить их, сохранив тот же диапазон допустимых значений?
I>Если не троллишь, то тебя основательно заклинило. Элементарные же вещи, да вот хотя бы так (C++):
I>
I>Все-таки какая-никакая защита от непреднамеренного использования произвольного целого в качестве XCoord.
Во-первых, какая польза от такой обертки? Не все ли равно, кто будет кидать exception, конструктор протектора или реализация SetPixel()?
Во-вторых, какое это имеет отношение к теме? Аналогичную обертку МОЖНО написать и вокруг bool'ов, а вот всегда заменить целочисленные параметры на свойства/enum'ы/конфигураторы к большей пользе (как в случае с параметрами-bool'ами) НЕЛЬЗЯ.
P.S. Про заклинило и троллинг — не надо валить с больной головы на здоровую. Я пытаюсь оставаться вежливым, пытаюсь понять вашу аргументацию и так далее. Наших людей это бесит. Перешел от витания в абстрактных облаках к примерам — тролль, задал уточняющий вопрос — заклинило. Что интересно, каждый раз оказывается, что и пытаться понять не стоило.
Здравствуйте, SV., Вы писали:
SV.>Во-первых, какая польза от такой обертки? Не все ли равно, кто будет кидать exception, конструктор протектора или реализация SetPixel()?
Вообще-то не все равно, лучше проверять диапазон в одном конструкторе, чем во всех функциях. Но в данном случае я никакой проверки диапазона и не предлагал, а только проверку типа. То есть до исключения дело и не дойдет, компилятор выдаст ошибку, если x и y в следующем примере объявлены как int:
SetPixel(x, y, Color.Red);
А если они объявлены как XCoord и YCoord соответственно, то код скомпилируется.
Твой вызов с константами нужно будет переписать так: