if ( -1 == result ) ...

psihodog

Я уже не в первый раз вижу чужой код, в котором когда значение какой-нть переменной или возвращённое какой-нть функцией сравнивается с чем-нибудь простым, например, константой, сначала пишется эта самая константа, а уж потом переменная или функция вот так:
if ( -1 == fgets(...) ) ...

в то время, как мне всё время казалось естественным писать так, как и читается, т.е. "если fgets вернул -1, то...":
if ( fgets(...) == -1 ) ...

Вот вопрос: это так специально по какой-то причине делают, или просто так?
Единственное, что приходит в голову, что пишут так, чтобы сразу видеть с чем сравнивается, а не искать где-то далеко.

ppplva

Это на случай если == и = перепутаешь.

Maurog

как уже отмечено, это против очепяток типа
if (a = -1)
{
}

vook

Как будто if (fgets = -1) не выдаст ошибку.

Sharp

imho, если у fgets куча параметров, так может быть удобнее читать - сразу видно, что идет проверка на ошибку.

evgen5555

Нормальный программист не станет заворачивать результат функции в условное выражение.

Dasar

> Нормальный программист не станет заворачивать результат функции в условное выражение.
чем это плохо?
т.е. такой код нормальный программист не пишет?

if (!File::Exist("readme.txt"
{
...
}

tamusyav

Нормальный программист не станет заворачивать результат функции в условное выражение.
А чем это плохо?
И как делает нормальный программист?

vall

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

vall

А чем это плохо?
плохо читается.
да и нарваться можно на недоспецификацию языка, например на неопределённый порядок вычисления операндов.

Dasar

> да и нарваться можно на недоспецификацию языка, например на неопределённый порядок вычисления операндов
в if-ах как раз почти все языки специфицируют порядок выполнения.
потому что такой код:

if (item != null && item.IsAlive && item.GetValueCount > 0)
{
}

намного лучше читается, чем лес из if-ов

vall

ясен пень у логических всё строго.
а + - ?

tamusyav

Неопределенный порядок - это вообще-то имеет отношения не только к условным, а к любым выражениям. При сравнении с константой тут никаких подводных камней нет.
А читабельность... имхо, if (!File::Exist("readme.txt" вполне читабельно...

Dasar

какие еще +/-?
и в чем с ними проблема?

vall

прочитай пожалуйста мой предыдущий пост - ответ `у.

vall

порядок вычисления аргументов у них в языке С/С++ и всех других нормальных и не очень языках не определён стандартом. компилятор в каждом конкретном месте может выбрать любой.

Dasar

ты про такое что ли?

if (FunctionWithSideEffect + OtherFunctionWithOtherSideEffect > 10)
{
}

Dasar

вот так действительно не стоит писать:

if (Lock(item) && item.Execute && Unlock(item
{
  printf ("что-то не получилось");
}

но здесь уже фактически используются процедуры (методы, которые что-то делают а не функции (методы, которые что-то возвращают)

lipa

Как будто if (fgets = -1) не выдаст ошибку.
Если fgets возвращает ссылку, то не выдаст.

lipa

порядок вычисления аргументов у них в языке С/С++ и всех других нормальных и не очень языках не определён стандартом. компилятор в каждом конкретном месте может выбрать любой.
хм, я почему-то всегда думал наоборот
сколько видел в книжках, всегда указывается порядок вычисления аргументов, по крайней мере для логических операторов
да и сам юзал эту фичу несколько раз, проблем не возникало

vall

ну не у всех операций. вот для a = f + g; точно не известно в каком порядке будут вызваны функции.

lipa

Полистал стандарт + - вычисляются слева направо.

vall

какого языка стандарт?

evgen5555

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

psihodog


Порядок применения унарных операций и операций присваивания "справа налево", а всех остальных операций - "слева направо". То есть, a=b=c означает a=(b=c a+b+c означает (a+b)+c, и *p++ означает *(p++ а не (*p)++.

psihodog

Понятно :-)
Гм, даже в голову не пришло: ни разу такой ошибки у меня не было, кажется. :-)

vall

тааак что-то я туплю. или в паскале это так. или в с++ это не так как в с. или где в другом месте косяки.
а про порядок вычисления аргументов функции там ничего не написано?

Dasar

> Порядок применения унарных операций и операций присваивания "справа налево", а всех остальных операций - "слева направо". То есть, a=b=c означает a=(b=c a+b+c означает (a+b)+c, и *p++ означает *(p++ а не (*p)++.
при этом не гарантируется, что сначала будет вычислено значение a, а только потом b - а не наоборот.

lipa

приехали...
а что же тогда значит <порядок "слева направо">?

Dasar

это означает только, что к a сначала прибавят b, а только потом с
это важно для мат. операций - например, в выражении 1e70 + (-1e70) + 1e-70
но это не означает что сами a, b, c будут вычислены именно в этом порядке

lipa

с точки зрения языка выражения (a+b) и f(...) не имеют принципиальной разницы, поэтому пофигу, какое именно выражение стоит слева от оператора - оно вычислится первым независимо от вида этого выражения

Dasar

> с точки зрения языка выражения (a+b) и f(...) не имеют принципиальной разницы, поэтому пофигу
что-то ты, вообще, не о том говоришь.
речь идет о том, что выражение вида:
A + B+C
компилятор имеет право заменить, как на
T a = A;
T b = B;
T d = a + b;
T c = C;
T res = d+c;
так и на
T c = C;
T b = B;
T a = A;
T d = a+b;
T res = d+c;
и в том, в и другом случае - сложение выполняется слева направо

vall

всё, значит я пока не сошёл с ума.
>1e70 + (-1e70) + 1e-70
в стандарте С вроде даже нигде не указано что у нас целочисленная арифметика не с насыщением - там тоже порядок важен.

ppplva

с точки зрения языка выражения (a+b) и f(...) не имеют принципиальной разницы

Оба состоят из букв и скобок ?
Речь идет именно об ассоциативности операций, к порядку вычисления аргументов она отношения не имеет. Всего лишь расстановка скобок.

mira-bella

Полистал стандарт + - вычисляются слева направо.

не угадал, учи английский
ассоциативность слева направо (т.е. выражение a+b+c эквивалентно (a+b)+c, и соответственно a-b-c === (a-b)-c, в вот что первое вычисляется: a или b? с или (a+b)? - это не определено)
а порядок вычисления выражений-операндов не определен - это тоже есть в стандарте
порядок вычисления определен только для операторов && || , ?:

mira-bella

апередил

lipa

мда, подстава, пойду напьюсь

vall

сцуко, ты заставил меня усомнится в собственной вменяемости какой я легковерный оказывается

Realist

Порядок вычисления функций произвольный. Более того, нет гарантии, что следующий аргумент начнет вычислятся только после того, как вычислится предыдущий. По причине этой подставы код
 
myfun(auto_ptr(new MyClassauto_ptr(new MyClass;

может приводить к утечкам памяти. Если память первым new выделена, но еще не обернута в auto_ptr, а второй new сгенерировал исключениие

psihodog

при этом не гарантируется, что сначала будет вычислено значение a, а только потом b - а не наоборот.
да, согласен, стормозил

voronetskaya

в джаве еще пишут
if ( "CONST".equals(myInputStringVar) ) ...

все знают почему?

psihodog

все знают почему?
Потому что в жаве не определена (специальная) операция сравнения для строк и жава разрешает существование разных строковых объектов с одинаковым содержимым?

vall

типа чтоб null не ломал всё?

kokoc88

Потому что в жаве не определена (специальная) операция сравнения для строк и жава разрешает существование разных строковых объектов с одинаковым содержимым?
Ну это не значит, что нельзя написать stringVar.equals("constant")

psihodog

типа чтоб null не ломал всё?
охренеть...

vall

охренеть...
if ( "CONST".equals(myInputStringVar) ) ...
выглядит лучше чем
if (myInputStringVar != null && myInputStringVar.equals("CONST") ) ...

psihodog

if ( "CONST".equals(myInputStringVar) ) ...
выглядит лучше чем
if (null == myInputStringVar || myInputStringVar.equals("CONST") ) ...
Да я понимаю.
Давно не программировал на всяких жавах и плюсах, отвык, что в функцию, ожидающую на входе объект могут передать вместо объекта пустое место.

kokoc88

ожидающую на входе объект
В Java функции ожидают на вход ссылку на объект.

psihodog

В Java функции ожидают на вход ссылку на объект.
ну вот отвык я от этих лишних сущностей. :-)

erotic

вот так действительно не стоит писать
if (Lock(item) && item.Execute && Unlock(item{  printf ("что-то не получилось");}

но здесь уже фактически используются процедуры (методы, которые что-то делают а не функции (методы, которые что-то возвращают)
Чем это отличается от
if (Lock(item)==true && item.Execute==true && Unlock(item)==true){  printf ("что-то не получилось");}

в котором твои "процедуры" магическим образом превращаются в "функции"?
Раз порядок вычисления && слева направо четко определен, то так писать ИМХО можно.
Потому что из твоих рассуждений следует, что нельзя писать и
if (p && p->do_something {...} 

потому что вдруг компилятор решит сначала вычислить p->do_something а уж потом только p.

ppplva

Как минимум, стоит добавить Unlock в случае, когда "что-то не получилось".

Dasar

> Чем это отличается от
от этого - ничем не отличается.
> в котором твои "процедуры" магическим образом превращаются в "функции"?
никакого превращения не произошло - процедура как была процедурой, так и осталась.
> Раз порядок вычисления && слева направо четко определен, то так писать ИМХО можно.
можно, но не нужно, т.к. при этом сильно страдает читабельность, и очень легко нарваться на подводные камни.
ps
в свободном мире, в первую очередь - надо знать, что делать не нужно(не стоит а не что можно делать.
pps
для вышеприведенного примера - намного лучше скобочная запись:

;{
CLock lock(item);
item.Execute;
}

tamusyav

Дело здесь не только и, пожалуй, не столько в читабельности, сколько в нарушении принципа - в одной строке - не более, чем одно действие. Хотя, конечно, разделение программы на отдельные "действия" весьма условно, но все-таки желательно избегать вызова нескольких неконстантных функций (то есть которые делают еще какие-то действия, напрямую не связанные с возвращаемым значением) в одной инструкции. Так гораздо удобнее для отладки: выполнилось действие - новая строка.
А вообще конструкции, подобные упомянутому if-у, стоит либо заменить использованием класса (как предложил либо использовать исключения.

Ivan8209

> И как делает нормальный программист?
Программирует на ассемблере.
---
...Я работаю антинаучным аферистом...

Ivan8209

Слушай, а ты не знаешь, какой придурок это придумал?
Такая запись убивает читаемость кода из-за мелочной идиотской перестраховки от опечатки,
очень хорошо отлавливающейся по выдаче компилятора.
---
...Я работаю антинаучным аферистом...

Ivan8209

> в одной строке - не более, чем одно действие.
У тебя трудности с памятью?
Скажи, почему ты не разбил своё сообщение на строки согласно заявленному "принципу?"
> Так гораздо удобнее для отладки: выполнилось действие - новая строка.
Ты готов пожертвовать читаемостью кода в пользу отладки?
Сколько же ты отлаживаешь свой код, раз для тебя это настолько важно.
---
...Я работаю антинаучным аферистом...

kokoc88

Слушай, а ты не знаешь, какой придурок это придумал?
Иди рассуждай о существовании чисел в природе. В этом топике тебе делать нечего.

bleyman

> Такая запись убивает читаемость кода из-за мелочной идиотской перестраховки от опечатки,
Гы, кто бы говорил о читаемости =) Если привыкнуть, то не убивает, а наоборот улучшает. Потому что по началу оператора уже видно, что мы хотим сделать. Типа, появляются как бы метаоператоры
if (NULL == <expression>) <statement>. Типа, префиксный код вместо постфиксного, вот и всё отличие от ФЯ.
>> в одной строке - не более, чем одно действие.
> У тебя трудности с памятью?
Сравни среднюю длину "одного действия" в своём любимом ФЯ и плюсах. Учитывая, что под одним действием в плюсах подразумевается что-нибудь вроде
* присваивание в переменную результата какого-нибудь достаточно сложного арифметического выражения.
* вызов метода объекта + вычисление необходимых параметров.
* полное описание условия выхода из цикла плюс задание стартовых параметров и операции перехода к следующему шагу.
* и всё такое.
Эквивалент "2 2 * 4 ifeq" никто, естественно, переносить на разные строчки не будет.
Вообще удивительно даже, насколько ты, Контра, ограниченный человек.

Ivan8209

> Если привыкнуть, то не убивает, а наоборот улучшает.
И эти люди утверждают, что !@#$%^&* читается лучше S-выражений!
> if (NULL == <expression>) <statement>
Даже в сях можно писать: "if(<expression>) <statement>".
Ты никогда не задумывался, что если ты говоришь про читаемость,
то должно быть как можно более прямое соответствие естественному языку?
"Если считанная строка пуста, то выйти с ошибкой" ---
это "if(gets(str) == NULL) err(1, NULL);".
Довольно странно слышать слова "если привыкнуть" от приверженца "классических" языков,
обычно такие доводы используют сторонники языков
повышенной выразительности, у которых "Skillfully written Forth is like poetry,"
или сторонники "киборганического" подхода, с их стремлением ваять железо "какое надо."
> Сравни среднюю длину "одного действия" в своём любимом ФЯ и плюсах.
Втрое короче на простых действиях, значительно сильнее --- на более сложных.
---
...Я работаю антинаучным аферистом...

tamusyav

Втрое короче на простых действиях, значительно сильнее --- на более сложных.
Гым, мне почему-то казалось, что половину, а то и большую часть занимают идентификаторы и литералы, длина которых никак не связана с языком... Или я не понимаю, что понимается под "длиной действия"?
Например, здесь:
 if ( "CONST".equals(myInputStringVar) ) 

пользовательский идентификатор и литерал занимают примерно половину символов, а если к этому добавить equals и if, то даже больше. На скобках и пробелах не особо сэкономишь...

Marinavo_0507

большую часть занимают идентификаторы и литералы, длина которых никак не связана с языком
Длина идентификаторов связана с языком:
* чем менее читаем язык, тем длинее должны быть названия, чтоб был понятен их смысл;
* чем менее выразителен язык, тем длиннее программы и больше нужно идентификаторов, соответственно, названия длиннее нужны, чтоб их не перепутать.

Ivan8209

> мне почему-то казалось, что половину, а то и большую часть
> занимают идентификаторы и литералы, длина которых никак не связана с языком...
Длина --- возможно*, а количество --- сильно зависит.
Например, скалярное произведение двух векторов можно записать:
а) "{double a = 0; for(i = 0; i < length(x); i++) a += x[i] * y[i]; return a;}";
б) "(apply + (map * x y".
Легко видеть, что в способе "а" требуется два лишних имени.
---
...Я работаю антинаучным аферистом...
*) На самом деле, это неверно, но сейчас не об этом.

tamusyav

Длина идентификаторов связана с языком:
* чем менее читаем язык, тем длинее должны быть названия, чтоб был понятен их смысл;
* чем менее выразителен язык, тем длиннее программы и больше нужно идентификаторов, соответственно, названия длиннее нужны, чтоб их не перепутать.

ИМХО, смысл оказывает большее влияние на длину идентификатора, чем язык. Читаемость языка больше влияет на краткость конструкций, в которых участвуют эти идентификаторы.
Длинные названия нужны чаще не для того, чтобы не перепутать идентификаторы, а чтобы было достаточно ясно назначение переменной/функции/др.

tamusyav

Краткость здесь достигнута лишь потому, что в C нет векторных операций. В C++ подобного выигрыша уже не было бы...
Кстати, C-шный пример заработает только при условии, что соотв. образом определена функция length (причем непонятно, как).

Ivan8209

Считаешь?
Пожалуйста, ещё пример.
Определение новой функции:
а) "number scal(number x[], number y[]) <body>;";
б) "(define (scal x y) <body>)".
Опять выигрыш.
Считаешь, это из-за отсутствия типизации?
Тогда:
в) "fun scal x y = <body>",---
для совсем строго типизированного языка.
---
...Я работаю антинаучным аферистом...

bleyman

> Ты никогда не задумывался, что если ты говоришь про читаемость,
> то должно быть как можно более прямое соответствие естественному языку?
ЛОООЛ. И это говорит человек, пишуший на языке
а) под стековую машину
б) с постфиксной записью арифметических выражений.
в) в котором как минимум половина лексем - это "(" и ")".
А-фи-геть. Хоть минимальную рефлексию можно было бы иногда практиковать, не находишь?
Как можно более прямое соответствие естественному языку ставил перед собой Билл Гейтс при разработке Бейсика. Результат затмевает солнце. А вот создатели регексов такой фигнёй не заморачивались, в результате получился прекрасный язык.
Любой язык, знаешь ли, нужно учить. При этом затраты времени на изучение могут с лихвой окупиться впоследствии.

Ivan8209

Любитель править задним числом.
> Кстати, C-шный пример заработает только при условии,
> что соотв. образом определена функция length (причем непонятно, как).
Это проблема насильников.
Если для них это трудно, то я ничем не могу помочь.
---
"Quae medicamenta non sanat, ferrum sanat,
quae ferrum non sanat, ignis sanat."

psihodog

в) "fun scal x y = <body>",---
для совсем строго типизированного языка.
а где здесь типизация?

tamusyav

И где здесь типизация x, y и возвращаемого значения?

Ivan8209

Спрятана в <body>, разумеется.
Если сишным компиляторам неизвестно, что "+" складывает числа,
это ещё не означает, что такое неизвестно всем компиляторам.
---
...Я работаю антинаучным аферистом...

tamusyav

То есть для того, чтобы определить эти типы, я должен смотреть на тело функции? Где же экономия тогда?

psihodog

Спрятана в <body>, разумеется.
Что ты тогда подразумаваешь под типизацией?
И как она выглядит? она короче, чем объявление прототипа функции?
Если сишным компиляторам неизвестно, что "+" складывает числа,
это ещё не означает, что такое неизвестно всем компиляторам.
А что, + у тебя на всех один?
А если там вектора?

Ivan8209

>> Ты никогда не задумывался, что если ты говоришь про читаемость,
>> то должно быть как можно более прямое соответствие естественному языку?
> ЛОООЛ. И это говорит человек, пишуший на языке
> а) под стековую машину
> б) с постфиксной записью арифметических выражений.
> в) в котором как минимум половина лексем - это "(" и ")".
> А-фи-геть. Хоть минимальную рефлексию можно было бы иногда практиковать, не находишь?
А я принадлежу к сторонникам модернистского подхода.
> Любой язык, знаешь ли, нужно учить.
Предложишь объяснение, почему выражение наподобие
"while(index < limit && handle = get(index) && ptr = lock(handle) && value(ptr) != key && unlock(ptr index++;"
ставит опытного насильника в тупик?
---
...Я работаю антинаучным аферистом...

Ivan8209

Смысл функции должен быть очевиден из имени функции и(или) её употребления.
Экономия заключается в том, что текст программы не перегружается бессмысленными уточнениями,
что эта функция скалярно перемножает вектора, состоящие из чисел.
Потому что из обозначения "*" следует, что перемножаются числа, а не склеиваются строки.
---
...Я работаю антинаучным аферистом...

Ivan8209

> Что ты тогда подразумаваешь под типизацией?
Всю систему проверки по типам выражений.
> И как она выглядит?
Как выглядит число "2" --- с такими вопросами обращайся к Fj, это его область.
> она короче, чем объявление прототипа функции?
Запись получается короче.
Я привёл пример, если ты ещё не в курсе.
> А что, + у тебя на всех один?
> А если там вектора?
Кому нравится перегружать "+", у тех и с векторами работает.
---
...Я работаю антинаучным аферистом...

psihodog

Я привёл пример, если ты ещё не в курсе
на твоём примере не видно, что в итоге это получится короче.

bleyman

>> ставит опытного насильника в тупик?
Потому что в данном случае
а) строчка не подходит под определение "одной операции" вообще никак.
б) количество информации на строчку превышает способность восприятия "опытного насильника".
в) у тебя код фиговый - непонятно, где происходит unlock(ptr) если value(ptr) == key. Есть общепринятые паттёрны работы с ресурсами, которые нужно использовать.

psihodog

Всю систему проверки по типам выражений.
Какую систему? Она везде разная.

tamusyav

Запись получается короче.
Во-первых, пример не приведен до конца. А во-вторых, даже если представить, что там получится, то окажется, что мне нужно будет смотреть описание функции вместо определения прототипа. Может, это и короче по количеству символов, но если мне нужен только прототип, то я получаю избыточную информацию, а это тоже плохо.
Да, насчет скалярного произведения векторов, могу предложить еще более краткий пример: Mathematica. Там для этого трех символов достаточно. Но из этого не следует, что ее язык более читабельный.

Ivan8209

> на твоём примере не видно, что в итоге это получится короче.
Очень хорошо видно.
Ты не умеешь считать знаки?
---
...Я работаю антинаучным аферистом...

Ivan8209

>> ставит опытного насильника в тупик?
> Потому что в данном случае
> а) строчка не подходит под определение "одной операции" вообще никак.
Поиск --- это одно действие.
> б) количество информации на строчку превышает способность восприятия "опытного насильника".
Его личные трудности.
> в) у тебя код фиговый - непонятно, где происходит unlock(ptr) если value(ptr) == key.
После того, как обработаем.
Нафиг делать unlock(ptr)?
Чтобы потом ещё раз запирать?
> Есть общепринятые паттёрны работы с ресурсами, которые нужно использовать.
Общепринятые?
У кого?
---
...Я работаю антинаучным аферистом...

psihodog

Ты не умеешь считать знаки?
как уже было замечено, у тебя не полностью приведён пример.
кроме того, в Си-шном объявлении информации больше, а в остальных двух присутствует целое лишнее слово (define).

Ivan8209

> Во-первых, пример не приведен до конца.
Пример приведён до конца.
Смысл примера не в том, чтобы показать, как красиво записывается скалярное произведение,
а в том, что указывать типы в заголовке функции --- избыточно.
Это сильно загромождает запись, что нисколько не способствует читаемости.
---
...Я работаю антинаучным аферистом...

psihodog

После того, как обработаем.
Нафиг делать unlock(ptr)?
Чтобы потом ещё раз запирать?
тебе не кажется, что это уже зависит от логики приложения?
это одна операция, если она так оформлена, а у тебя написано несколько операций.
код, который делает несколько операций, должен, в частности, проверять, всё ли там ок.
если оформлено, как одна операция, то это оформление включает в себя проверку.

psihodog

а в том, что указывать типы в заголовке функции --- избыточно.
для языка со статической типизацией — вовсе даже не избыточно.

Ivan8209

> в Си-шном объявлении информации больше,
Её никаким боком не больше, потому что эта "информация"
однозначно восстанавливается из определения функции.
> а в остальных двух присутствует целое лишнее слово (define).
Оно не лишнее, просто в твоём примере все эти слова находятся в другом месте.
---
...Я работаю антинаучным аферистом...

Ivan8209

Для языка со статической типизацией --- избыточно.
Если ты считаешь, что приплюснутые си единственным
представителем таких языков, это твои личные заморочки.
---
"Narrowness of experience leads to narrowness of imagination."

bleyman

После того, как обработаем.
Нафиг делать unlock(ptr)?
Чтобы потом ещё раз запирать?
> Есть общепринятые паттёрны работы с ресурсами, которые нужно использовать.
Общепринятые?
У кого?
Конкретно у шарповщиков принято оформлять работу с ресурсами (то есть сущностями, которым нужно делать lock/unlock) вот так:

using (resource = lock(ptr
{
bla bla bla;
}

Приплюснутые насильники вынуждены оформлять этот паттерн в виде "try-finally", чистые насильники как-то справляются так. Я тоже это, как его, придерживаюсь модернистских воззрений =)

Ivan8209

Всё-таки мы упёрлись в это.
Я изначально не хотел говорить о самой главной трудности всех ваших сей:
ни один ваш язык неспособен согласованно вернуть несколько значений сразу,
для этого надо завести кучу имён либо для переменных,
в которых сохраняются выходные данные,
либо для "структуры" возвращаемых данных.
Хороший пример --- это функции getline (GNU) и fgetln (BSD).
В плюсах то же самое выносится в определение "класса,"
что добавляет ещё одно имя --- класса.
---
...Я работаю антинаучным аферистом...

Ivan8209

То есть надо лишний раз отпирать-запирать? Круто!
Я запишу в блокнотик, чтобы больше мне не тыкали якобы
медленными интерпретаторами или виртуальными машинами?
Запирать ресурсы операционной среды --- это, наверное, очень быстро.
---
...Я работаю антинаучным аферистом...

bleyman

Не понял сути претензий. Это быстро. "Лишнего раза" - нет.

ppplva

Это медленно, но лишнего раза - действительно нет.

kokoc88

Приплюснутые насильники вынуждены оформлять этот паттерн в виде "try-finally"
Нет, мы такой паттерн оформляем с помощью деструкторов и классов-обёрток.

Ivan8209

> Приплюснутые насильники вынуждены оформлять этот паттерн в виде "try-finally"
Да, при этом локализуются проверки условий выхода,
но на каждое условие, насколько я понимаю, заводится имя,
которое бросается через throw. Так?
Получается, что хрен редьки не слаще.
Мне это не нравится.
begin while while while while repeat then then then значительно понятнее получается,
особенно, если вместо then использовать ;end
---
...Я работаю антинаучным аферистом...

psihodog

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

Ivan8209

> ну и какие ты знаешь варианты?
Мне достаточно SML.
---
...Я работаю антинаучным аферистом...

bleyman

Выше уже написали, что приплюснутые на самом деле пишут
{
DisposableResourceWrapper wrapper(ptr);
bla bla bla;
}

psihodog

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

bleyman

ни один ваш язык неспособен согласованно вернуть несколько значений сразу,
для этого надо завести кучу имён либо для переменных,
в которых сохраняются выходные данные,
либо для "структуры" возвращаемых данных.
Это называется "строгая типизация", если ты не знал.
То есть либо ты пишешь SomeMethod(param1, param2, out param3, out param4)
Либо
class SomeValueContainer
{
public MyType val1;
public MyType2 val2;
}
и SomeValueContainer value = SomeMethod(param1, param2);
что-нибудь типа
object obj = SomeMethod(zzz, zzzz);
if (obj.SomeField == 42) DoSomething;
возможно в жаваскрипте и мне не нравится.
Ещё в шарпе возможны конструкции типа
NameValuePair<string, int> result = someObj.GetSomeData(zzz);
Или
HashTable<string, object> result = someObj.GetSomeData(zzz);
if (result["SomeField"] == 42) DoSomething;
Но использование последней мне тоже совершенно не нравится, потому что нет проверок на этапе компиляции.
Во-первых, задача описания SomeValueContainer заставляет напрячь моск и приводит, как правило, к вполне вменяемым результатам (осмысленный тип SomeValueContainer, реально соответствующий предметной области во-вторых, даже если возвращаемый тип не несёт какого-то сверхсмысла, объявление контейнера занимает не так уж много места (с учётом того, что "опытный насильник" скользит взглядом по строчкам, содержащим только "{", "}" с точно такой же лёгкостью, как "опытный лиспер" проглатывает "(", ")" )

Ivan8209

>> ни один ваш язык неспособен согласованно вернуть несколько значений сразу,
>> для этого надо завести кучу имён либо для переменных,
>> в которых сохраняются выходные данные,
>> либо для "структуры" возвращаемых данных.
> Это называется "строгая типизация", если ты не знал.
И при строгой типизации бывают анонимные типы.
Что мешает тебе вернуть значение типа "boolean * string"?
> даже если возвращаемый тип не несёт какого-то сверхсмысла,
> объявление контейнера занимает не так уж много места
Если такое объявление требуется на каждые пять строк кода
и само занимает две-три строки, то весь текст вырастает наполовину.
---
...Я работаю антинаучным аферистом...

bleyman

Что мешает тебе вернуть значение типа "boolean * string"?
Не мешает, я ж написал
NameValuePair<bool, string>
В принципе, ты можешь сделать себе ещё тринадцать темплейтов (до шестнадцати значений, чисто по приколу) и возвращать один из них, специфицированный. Единственный недостаток - переменную нужного типа (такого же, как возвращаемое значение) тебе придётся объявлять всё равно, соответственно при изменении этого значения придётся переписывать все эти объявления. Хотя мб это и к лучшему - зато не ошибёшься.

Ivan8209

Вот видишь, никакого решения ты так и не предложил:
хочешь или не хочешь, а пространство имён всё равно засоряется,
засоряется кучей ненужных, по большому счёту, объявлений текст,
растёт объём, и так далее до "Psycological Review,"
когда пропадает читаемость.
> Хотя мб это и к лучшему - зато не ошибёшься.
Никогда не задумывался, почему в сказках заставляют искать в стоге сена,
выбирать из семи (сорока, ста) одинаковых и т. п.?
---
...Я работаю антинаучным аферистом...

bleyman

Возможно, в С# 3.0 добавят ещё синтаксического сахара в виде
Returns<Type1, Type2, ..., TypeN> SomeMethod(...)
и объявление локальной переменной вида
SomeType.SomeMethod.Returns retVal;
Только вряд ли, потому что это никому не нужно. Ну как-то так получилось.

Ivan8209

> Только вряд ли, потому что это никому не нужно.
Догадываешься, почему это "никому не нужно?"
> Ну как-то так получилось.
---
"Narrowness of experience leads to narrowness of imagination."

bleyman

>> Догадываешься, почему это "никому не нужно?"
Догадываюсь, что ты имеешь в виду =) Некоторые вещи никто не делает не потому, что их никто не делал раньше, а потому, что их делать не нужно. Например, можно, по идее, удалять гланды автогеном через прямую кишку.
Кстати Мадкроз мне в аське сказал, что в экспериментальном языке Nemerle таки есть type inference:
Type inference refers to the ability to automatically either partially or fully deduce the type of the value derived from the eventual evaluation of an expression. As this process is systematically performed at compile time, the compiler is often able to infer the type of a variable or the type signature of a function, without explicit type annotations having been given. In many cases, it is possible to omit type annotations from a program completely if the type inference system is robust enough, or the program or language simple enough.
То есть можно не писать свежепридуманное мной слово returns.
Процедурные языки очень шустро развиваются в последнее время, забирая разные полезные фишки из ФЯ, но не теряя сути. Например, во втором шарпе есть жуткая штука yield return (поищи в инете которая процедурна по сути, но заставляет как-то удивиться что ли.

Dasar

> while(index < limit && handle = get(index) && ptr = lock(handle) && value(ptr) != key && unlock(ptr index++;"
потому что это выражение требует временных ресурсов для того, чтобы ответить на следующие вопросы:
1. сколько раз делается lock/unlock
2. на сколько адекватно ведет себя эта конструкция при ошибках
3. что надо изменить, если необходимо лочить сразу две переменных? какую часть кода после этого надо будет перепроверить?
4. какие переменные, кроме index-а должны иметь смысл после выхода из цикла?
5. содержит ли эта конструкция уже ошибки (лочим одно, а разлочиваем другое)? или нет?
и т.д.
еще раз напомню, что есть профессионально заниматься программированием, то один и тот же код приходится читать 10, 100, иногда 1000 раз.
причем приходиться читать с разными целями, и с разными временными ограничениями.
иногда требуется понять - почему программа ведет себя так, а иначе,
иногда надо за пару минут внести небольшое изменение, при этом обычно нет времени на вдумчивое просматривание кода, и на длительную отладку

Dasar

> Длина идентификаторов связана с языком:
> * чем менее читаем язык, тем длинее должны быть названия, чтоб был понятен их смысл;
> * чем менее выразителен язык, тем длиннее программы и больше нужно идентификаторов, соответственно, названия длиннее нужны, чтоб их не перепутать.
как раз такая зависимость слабая, потому что во всех современных языках - поддерживается инкапсуляция в том или ином виде, соответственно больше не надо придумывать длинные имена только ради того, чтобы их не перепутать с другими именами
есть скорее другая сильная зависимость:
чем более ограниченный автор программы, и чем с меньшим кол-вом кода (программ) он имеет дело, с чем меньшим кол-вом других программистов он общается - тем идентификаторы короче и тем больше используется сокращений.

Dasar

> while(index < limit && handle = get(index) && ptr = lock(handle) && value(ptr) != key && unlock(ptr index++;"
данную конструкцию я бы лучше записал так:

for (;index < limit; index++)
{
CPointerFromHandleLock lock(get(index;
if (value(lock.pointer) == key)
{
//bla-bla
break;
}
}

Ivan8209

> Некоторые вещи никто не делает не потому, что их никто не делал раньше,
> а потому, что их делать не нужно.
> Например, можно, по идее, удалять гланды автогеном через прямую кишку.
Двадцатилетний опыт ML-щиков показывает,
что типизация с "type inference" настолько полезна,
что рассматривать всё остальное смысла не имеет.
Разумеется, насильникам этого не понять --- они застряли в семидесятых.
> Процедурные языки очень шустро развиваются в последнее время,
> забирая разные полезные фишки из ФЯ, но не теряя сути.
Живучесть гибридов очень сомнительна:
видно, что процедурщики пошли вразброд.
Я бы сказал, что процедурные языки не развиваются,
а пытаются "популяризовать" простейшие достижения
двадцатилетней, а то и тридцатилетней давности.
---
...Я работаю антинаучным аферистом...

Ivan8209

> данную конструкцию я бы лучше записал так
Ты превращаешь единое выражение в два-три,
то есть уходишь на более низкий уровень программирования.
Если моя запись может хорошо восприниматься как идиома
(по сути, она получилась по аналогии с "Прологом"
то твоя делает упор на детали, что довольно-таки странно
наблюдать для такого высокоуровневого языка программирования.
Вообще, удивительно, что я пишу в высокоуровневом стиле
даже на низкоуровневых языках, а ты в более низкоуровневом стиле ---
на более высокоуровневых языках.
Видимо, ты действительно --- настоящий программист.
---
...Я работаю антинаучным аферистом...

erotic

А давай мы тебе всем форумом Почетную грамоту напишем?
Мб ты тогда успокоишься?
Не, если все равно не успокоишься, скажи сразу - зачем же лишний раз напрягаться.

Ivan8209

> А давай мы тебе всем форумом Почетную грамоту напишем?
Бумагу помягче возьмите и краски получше.
Чтобы не стирались.
---
...Я работаю антинаучным аферистом...

kokoc88

Бумагу помягче возьмите и краски получше.
Чтобы не стирались.
Непременно. И ещё клей покрепче, чтобы приклеить тебе ко лбу, и чтобы отодрать нельзя было.

Dasar

> Если моя запись может хорошо восприниматься как идиома
почему идиома должна состоять из одной строчки?
ты на вопросы кстати не ответил.

Ivan8209

> почему идиома должна состоять из одной строчки?
Потому что иначе это будет не идиома,
а два и более самостоятельных выражений.
> ты на вопросы кстати не ответил.
> потому что это выражение требует временных ресурсов
> для того, чтобы ответить на следующие вопросы:
Каких ресурсов?
Просмотреть строчку трудно?
> 1. сколько раз делается lock/unlock
По одному разу.
> 2. на сколько адекватно ведет себя эта конструкция при ошибках
Полностью адекватно.
> 3. что надо изменить, если необходимо лочить сразу две переменных?
Неважно, поскольку нужно запирать одну переменную.
> какую часть кода после этого надо будет перепроверить?
То же.
> 4. какие переменные, кроме index-а должны иметь смысл после выхода из цикла?
Чем больше, тем лучше.
> 5. содержит ли эта конструкция уже ошибки (лочим одно, а разлочиваем другое)? или нет?
Очевидно, не содержит, раз используется конъюнкция.
---
...Я работаю антинаучным аферистом...

Dasar

ты не ввъехал в вопросы
и что плохо - даже не пытался

Ivan8209

Я очень хорошо всё понял: ты пытаешься подменить условия.
Вместо того, чтобы работать с приведённым примером,
ты пытаешься его изменить и показать, что с изменённым что-то не так.
Ты и с заказчиком так работаешь?
Точно так же втихую подменяешь условия?
---
...Я работаю антинаучным аферистом...
Оставить комментарий
Имя или ник:
Комментарий: