Re[57]: Как не надо писать код
От: samius Япония http://sams-tricks.blogspot.com
Дата: 28.04.11 04:04
Оценка:
Здравствуйте, AlexNek, Вы писали:

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


AN>Я же говорю теоретический, можно ведь предположить что есть такая же функция но без исключений.

Тогда можно предположить что требования выполнены.

AN>Была речь о "волшебстве", которое в итоге как то превращается в "глобальную переменную"

Это было бы проклятие, а не "волшебство".

AN>Предположим вам нужно своему взрослому ребенку объяснить правила движения авто на перекрестке. Будем ли мы для этого искать игрушечные машинки подходящего размера?

AN>Вполне возможно обойтись и резинкой с конфеткой. Данная абстракция вполне достаточна.
В этой абстракции мы предполагаем по умолчанию что у машинки, представленной конфеткой, исправны тормоза, пока не оговорено обратное. То что за конфеткой скрывается машинка — это абстракция. То что тормоза исправны — это конкретика.

s>> Конкретика здесь не нужна. Я лишь говорю о том, что неуточненные детали не есть абстракция.

AN>Ну это смотря на каком уровне их рассматривать и для чего. Я никак не могу взять в толк для чего нужно опускаться еще ниже.
Я не заставляю опускаться ниже.

s>> В случае WriteLine нет вариантов без исключений.

AN>Но ничто не запрещает нам их представить.
Угу, начальнику никто не запрещает представить что вы выполнили работу, бухгалтер представит ведомость, а вы в конце концов представите бутерброд с икрой

AN>Во, требования обработки исключений не стоит. Использовать WriteLine кто то еще, больше не будет. Тогда вопрос, а нафига они нам нужны в этом конкретном случае.

Сначала вы писали что вас не волнует то что в консоли могут быть исключения, что ваша программа должна доработать, даже если в консоль невозможно писать. Без обработки исключений это обеспечить нельзя. Что тут непонятно? Если не нужны они вам в конкретном случае — не обрабатывайте. Тогда ваша программа споткнется о первое исключение, что бы вы там не представили о WriteLine-е.

s>> Если он не будет достаточно гибок для использования в разных условиях, то он может размножиться до 100 строк при необходимости использования в разных условиях. DRY.

AN>(Но...), как и вариантов может быть довольно много, решается строго индивидуально.
AN>Но опять таки "Если он не будет достаточно гибок для использования в разных условиях". Здесь довольно часто нужен оптимальный компромисс. Почти все гибкое довольно сложное в какой либо проекции.
Негибкое в некоторой проекции тоже сложно. В проекции изменения требований.

AN>Если я год назад разбирался с каким либо паттерном это не значит что я его сегодня также хорошо помню. А если просто прочитал для общего развития...

Т.е. вы призываете не использовать что-то для решения задач только потому что сегодня вы не помните нечто так же хорошо? Допустим, есть алгоритм "Дейкстры", который решает вашу задачу, и который вы сегодня не помните так же хорошо. Будете изобретать свой?

AN>Уровень тут особой роли не играет (исключая "ниже планки"). Вот есть два человека с примерно одинаковым уровнем знаний, каждый пишет довольно внятный код, без выпендриваний, каждый понимает, что делает отдельная строчка/функция. Но если не рассказать концепт никто из них не поймет сразу как работает код другого.

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

s>> Ок, тогда мы его усугубим. Предположим (уверен, что такого не будет, но тем не менее), что код, который пишет в консоль о прогрессе вычислений, потребовалось изменить так, что бы он сегодня писал в консоль, при нажатой галочке отправлял на почту, а в некоторой фазе луны сохранял бы вывод в БД или отправлял бы веб сервису. Типичный пример на принцип открытия-закрытия (OCP). Будете из 20 строчек делать 100 что бы "не выпендриваться", или примените приемы, недоступные коллег(е|ам) по команде?

AN>Однозначно сказать не могу, многое зависит от конкретной ситуации. Если работаю глубоко на "своем поле", на которое нехрен ходить, то вероятнее будут 20, если поле на пересечении или планируются частые изменения и эта сотня вполне адекватна, то вероятнее 100. А если решения равнозначны "по весу", то всегда более простое. Или если сотня будет иметь сильно много ограничений, то тогда 20.
Т.е. все-таки существуют какие-то аспекты, которые перевешивают в сторону выпендривания?

AN>Что из последнего помню. Есть у меня один "длинный" switch, раздражал он меня долго и придумал даже как он него избавится. Но потом сравнил решения и оставил как есть.

AN>Когда на switch смотришь все понятно и нет вопросов. А так нужно думать, нафига то, нафига это, а как добавлять новую ветку и пр.
Существуют причины для избавления от свитча, существуют причины для сохранения свитча. Его длина не показатель для избавления.
Re[58]: Как не надо писать код
От: AlexNek  
Дата: 28.04.11 11:50
Оценка:
Здравствуйте, samius, Вы писали:

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


s> AN>Я же говорю теоретический, можно ведь предположить что есть такая же функция но без исключений.


s> Тогда можно предположить что требования выполнены.

Ну вот поэтому в данной функции и не было исключений.

s> AN>Была речь о "волшебстве", которое в итоге как то превращается в "глобальную переменную"


s> Это было бы проклятие, а не "волшебство".

"Console" и "GerServices()" я и называю "глобальными переменными".
Должно быть нечто видное "везде".

s> AN>Предположим вам нужно своему взрослому ребенку объяснить правила движения авто на перекрестке. Будем ли мы для этого искать игрушечные машинки подходящего размера?

s> AN>Вполне возможно обойтись и резинкой с конфеткой. Данная абстракция вполне достаточна.

s> В этой абстракции мы предполагаем по умолчанию что у машинки, представленной конфеткой, исправны тормоза, пока не оговорено обратное. То что за конфеткой скрывается машинка — это абстракция. То что тормоза исправны — это конкретика.

Тормоза, в данном случае, нас не интересуют вообще, на данном уровне абстракции их вообще нет, машинка просто может останавливаться. По какой причине — не интересует.
Если рассматривать другую задачу, в которой будет важна сущность останова, то мы просто добавим объект в возможностью останова и с ограниченной возможностью останова. При этом реальный объект может тормозить из за наличия тормозов, а может и просто из за наличия троса сзади.

s> s>> Конкретика здесь не нужна. Я лишь говорю о том, что неуточненные детали не есть абстракция.


s> AN>Ну это смотря на каком уровне их рассматривать и для чего. Я никак не могу взять в толк для чего нужно опускаться еще ниже.


s> Я не заставляю опускаться ниже.

С каждым уровнем абстракции неуточненных деталей появляется все больше

s> s>> В случае WriteLine нет вариантов без исключений.


s> AN>Но ничто не запрещает нам их представить.


s> Угу, начальнику никто не запрещает представить что вы выполнили работу, бухгалтер представит ведомость, а вы в конце концов представите бутерброд с икрой


Вот и получили некую абстракцию работы Нам ведь не требуется именно выкопать конкретную яму, в конкретном месте. Мы вроде только обсуждаем как это лучше сделать.

s> AN>Во, требования обработки исключений не стоит. Использовать WriteLine кто то еще, больше не будет. Тогда вопрос, а нафига они нам нужны в этом конкретном случае.


s> Сначала вы писали что вас не волнует то что в консоли могут быть исключения, что ваша программа должна доработать, даже если в консоль невозможно писать. Без обработки исключений это обеспечить нельзя. Что тут непонятно? Если не нужны они вам в конкретном случае — не обрабатывайте. Тогда ваша программа споткнется о первое исключение, что бы вы там не представили о WriteLine-е.

Я просто хотел показать два различных варианта один с исключениями, другой без.
Что нужно делать чтобы потом избавляться от них, и что вообще не нужно делать если их нет. При этом не для какого то общего случая, а для абсолютно конкретного.

s> s>> Если он не будет достаточно гибок для использования в разных условиях, то он может размножиться до 100 строк при необходимости использования в разных условиях. DRY.


s> AN>(Но...), как и вариантов может быть довольно много, решается строго индивидуально.

s> AN>Но опять таки "Если он не будет достаточно гибок для использования в разных условиях". Здесь довольно часто нужен оптимальный компромисс. Почти все гибкое довольно сложное в какой либо проекции.

s> Негибкое в некоторой проекции тоже сложно. В проекции изменения требований.

Безусловно, поэтому и идет речь о компромиссе. Если в обозримом будущем не будет требоваться использования Х объектов, то для чего уже сейчас делать их поддержку. Однако, если после прийдется вообще все переделывать для поддержки Х объектов, так лучше предусмотреть их сейчас.
Какое то время назад, я считал, что нужно всегда делать "гибкие объекты". Сейчас так однозначно я уже не думаю.

s> AN>Если я год назад разбирался с каким либо паттерном это не значит что я его сегодня также хорошо помню. А если просто прочитал для общего развития...


s> Т.е. вы призываете не использовать что-то для решения задач только потому что сегодня вы не помните нечто так же хорошо? Допустим, есть алгоритм "Дейкстры", который решает вашу задачу, и который вы сегодня не помните так же хорошо. Будете изобретать свой?

Я не призываю следовать всегда и везде каким либо установкам. Иногда это может быть целесообразно иногда нет. Хотя часто и нет полной уверенности как следует действовать в конкретной ситуации. Однако на выбор будет сильно влиять "режим работы" — командный или в одиночку.
В предложенной Вами ситуации может быть довольно много вариантов. Можно было не слышать и не догадываться что есть подобный алгоритм, можно было просто поискать вначале, если задача достаточно стандартная, возможно уже есть полностью готовое.
Если что то слышал но не помнишь, можно поискать и глянуть, а подойдет ли? Если решение кажется сложным но не придумывается проще можно вполне взять готовое снабдив комментарием на описание/название и т.п. Иногда можно вообще ничего не искать. Если на поиски нужно будет хотя бы полдня (при непредсказуемом результате), а написать можно за два, то нафига что искать.

s> AN>Уровень тут особой роли не играет (исключая "ниже планки"). Вот есть два человека с примерно одинаковым уровнем знаний, каждый пишет довольно внятный код, без выпендриваний, каждый понимает, что делает отдельная строчка/функция. Но если не рассказать концепт никто из них не поймет сразу как работает код другого.


s> Вы достаточно хорошо понимаете работу компилятора вместе с остальной командой, что бы не считать использование компилятора выпендриванием?

По крайней мере мы пишем код вначале "для себя", а уж потом для компилятора.
Можно было вообще никаких отступов не делать — это ведь лишняя работа компилятору.
Возможно необходимо пояснить что имелось в виду под "выпендриванием".

s> s>> Ок, тогда мы его усугубим. Предположим (уверен, что такого не будет, но тем не менее), что код, который пишет в консоль о прогрессе вычислений, потребовалось изменить так, что бы он сегодня писал в консоль, при нажатой галочке отправлял на почту, а в некоторой фазе луны сохранял бы вывод в БД или отправлял бы веб сервису. Типичный пример на принцип открытия-закрытия (OCP). Будете из 20 строчек делать 100 что бы "не выпендриваться", или примените приемы, недоступные коллег(е|ам) по команде?


s> AN>Однозначно сказать не могу, многое зависит от конкретной ситуации. Если работаю глубоко на "своем поле", на которое нехрен ходить, то вероятнее будут 20, если поле на пересечении или планируются частые изменения и эта сотня вполне адекватна, то вероятнее 100. А если решения равнозначны "по весу", то всегда более простое. Или если сотня будет иметь сильно много ограничений, то тогда 20.


s> Т.е. все-таки существуют какие-то аспекты, которые перевешивают в сторону выпендривания?


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

s> AN>Что из последнего помню. Есть у меня один "длинный" switch, раздражал он меня долго и придумал даже как он него избавится. Но потом сравнил решения и оставил как есть.

s> AN>Когда на switch смотришь все понятно и нет вопросов. А так нужно думать, нафига то, нафига это, а как добавлять новую ветку и пр.

s> Существуют причины для избавления от свитча, существуют причины для сохранения свитча. Его длина не показатель для избавления.

В данном случае, меня раздражала именно "длина". Я ведь не пишу рецепт "в каких случаях желательно избавляться от свитча". Хотя "длину в десяток экранов" (несколько преувеличено) я бы записал в него.
avalon 1.0rc3 rev 419, zlib 1.2.3
Re[59]: Как не надо писать код
От: samius Япония http://sams-tricks.blogspot.com
Дата: 28.04.11 12:30
Оценка:
Здравствуйте, AlexNek, Вы писали:

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


s>> Тогда можно предположить что требования выполнены.

AN>Ну вот поэтому в данной функции и не было исключений.
понятно

s>> AN>Была речь о "волшебстве", которое в итоге как то превращается в "глобальную переменную"


s>> Это было бы проклятие, а не "волшебство".

AN>"Console" и "GerServices()" я и называю "глобальными переменными".
По поводу консоли — можно согласиться. А GetServices с чего стал глобальным?
AN>Должно быть нечто видное "везде".
Для чего, и собственно что именно?

AN>Тормоза, в данном случае, нас не интересуют вообще, на данном уровне абстракции их вообще нет, машинка просто может останавливаться. По какой причине — не интересует.

Пусть не интересует
AN>Если рассматривать другую задачу, в которой будет важна сущность останова, то мы просто добавим объект в возможностью останова и с ограниченной возможностью останова. При этом реальный объект может тормозить из за наличия тормозов, а может и просто из за наличия троса сзади.
В исходной задаче вы сказали что "можно определить корректность аргументов". И это подразумевает некоторый способ, который не изменится при смене реализации абстракции.

s>> AN>Ну это смотря на каком уровне их рассматривать и для чего. Я никак не могу взять в толк для чего нужно опускаться еще ниже.


s>> Я не заставляю опускаться ниже.

AN>С каждым уровнем абстракции неуточненных деталей появляется все больше
да

s>> Сначала вы писали что вас не волнует то что в консоли могут быть исключения, что ваша программа должна доработать, даже если в консоль невозможно писать. Без обработки исключений это обеспечить нельзя. Что тут непонятно? Если не нужны они вам в конкретном случае — не обрабатывайте. Тогда ваша программа споткнется о первое исключение, что бы вы там не представили о WriteLine-е.

AN>Я просто хотел показать два различных варианта один с исключениями, другой без.
Нет варианта без исключений. Есть вариант без обработки исключений. Потому как нет такой WriteLine, которая бы не кидала исключений вообще никогда.
AN>Что нужно делать чтобы потом избавляться от них, и что вообще не нужно делать если их нет. При этом не для какого то общего случая, а для абсолютно конкретного.

s>> Негибкое в некоторой проекции тоже сложно. В проекции изменения требований.

AN>Безусловно, поэтому и идет речь о компромиссе. Если в обозримом будущем не будет требоваться использования Х объектов, то для чего уже сейчас делать их поддержку. Однако, если после прийдется вообще все переделывать для поддержки Х объектов, так лучше предусмотреть их сейчас.
AN>Какое то время назад, я считал, что нужно всегда делать "гибкие объекты". Сейчас так однозначно я уже не думаю.
Я не просил вас принимать решение сейчас. Я интересовался, есть ли причины, по которым вы можете использовать неочевидные для коллег приемы, т.е. выпендриваться по вашему. Вижу, что есть. Этого достаточно.

s>> Т.е. вы призываете не использовать что-то для решения задач только потому что сегодня вы не помните нечто так же хорошо? Допустим, есть алгоритм "Дейкстры", который решает вашу задачу, и который вы сегодня не помните так же хорошо. Будете изобретать свой?

AN>Я не призываю следовать всегда и везде каким либо установкам. Иногда это может быть целесообразно иногда нет. Хотя часто и нет полной уверенности как следует действовать в конкретной ситуации. Однако на выбор будет сильно влиять "режим работы" — командный или в одиночку.
Т.е. если командный, то будете склонны изобретать свой метод, вместо использования общеизвестного? Не ясна логика.

AN>В предложенной Вами ситуации может быть довольно много вариантов. Можно было не слышать и не догадываться что есть подобный алгоритм, можно было просто поискать вначале, если задача достаточно стандартная, возможно уже есть полностью готовое.

варианты не интересны. Есть что-то неочевидное для соседа. Будет ли алгоритм Дейкстры менее понятен для соседа, чем ваш велосипед?
AN>Если что то слышал но не помнишь, можно поискать и глянуть, а подойдет ли? Если решение кажется сложным но не придумывается проще можно вполне взять готовое снабдив комментарием на описание/название и т.п. Иногда можно вообще ничего не искать. Если на поиски нужно будет хотя бы полдня (при непредсказуемом результате), а написать можно за два, то нафига что искать.
А потом еще 2 дня объяснять команде, чего тут понаписано?

s>> Вы достаточно хорошо понимаете работу компилятора вместе с остальной командой, что бы не считать использование компилятора выпендриванием?

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

s>> Т.е. все-таки существуют какие-то аспекты, которые перевешивают в сторону выпендривания?


AN>Не всегда известно заранее какая чаша весов перевесит. Безусловно, есть различные ситуации. И даже если я возьму рецепт супер повара это не будет означать что у нас получится одинаковая по вкусу еда.

очевидно

s>> Существуют причины для избавления от свитча, существуют причины для сохранения свитча. Его длина не показатель для избавления.

AN>В данном случае, меня раздражала именно "длина". Я ведь не пишу рецепт "в каких случаях желательно избавляться от свитча". Хотя "длину в десяток экранов" (несколько преувеличено) я бы записал в него.
Ни в коем случае не призываю вас от него избавляться, не зная деталей. Но вот мне что интересно: в вашей команде считается выпендриванием оперирование абстракциями, но гипертрофированный свитч, по всей видимости, не является проблемой для понимания его работы?
Re[4]: Как не надо писать код
От: koandrew Канада http://thingselectronic.blogspot.ca/
Дата: 28.04.11 14:29
Оценка: +1
Здравствуйте, Sinix, Вы писали:

S>1. warning CS3001: Argument type 'uint' is not CLS-compliant

Ну это вообще говоря не проблема для авторов спецификации

S>2. а собсно зачем заводить массив, который займёт >2гб памяти? (берём крайний случай — с byte[]/bool[].) В типовой системе из-за фрагментации легко получить OutOfMemory даже на 200мб.

Ага, "640кб хватит всем". Проходили уже

Но есть ещё одна причина. Смотри сюда:

static class Program
    {
        static void Main(string[] args)
        {
            DoSomething(new byte[0]);
        }
        static void DoSomething(byte[] arr)
        {
            for(var i = 0; i <= arr.Length() - 1; i++)
            {
                
            }
        }

        private static uint Length(this Array arr)
        {
            return (uint) arr.Length;
        }
    }

Как ты думаешь, что будет, если выполнить этот код?
[КУ] оккупировала армия.
Re[5]: Как не надо писать код
От: Sinix  
Дата: 28.04.11 15:09
Оценка:
Здравствуйте, koandrew, Вы писали:

S>>1. warning CS3001: Argument type 'uint' is not CLS-compliant

K>Ну это вообще говоря не проблема для авторов спецификации
CLS — Common Language Specification, не C# Language Specification. Осложнять жизнь при портировании кода под .net — не самый лучший способ завоевать популярность.

K>Ага, "640кб хватит всем". Проходили уже


Нет, просто для таких задач недостаточно примитивной абстракции над непрерывным сегментом памяти. И у гипотетического SlicedArray вполне может быть Length типа long (зачем мелочиться?).

K>Как ты думаешь, что будет, если выполнить этот код?

[k.o.]
Или code analysis warning, или OverflowException в рантайме при тестах, или ArgumentOutOfRange на клиенте. Всё зависит от уровня разработки.
[/k.o.]
Но в целом да, беззнаковый тип для размерностей может породить кучу интересных проблем как раз из-за отсутствия явно недопустимых значений.
Re[6]: Как не надо писать код
От: koandrew Канада http://thingselectronic.blogspot.ca/
Дата: 28.04.11 15:20
Оценка: 18 (1)
Здравствуйте, Sinix, Вы писали:

S>CLS — Common Language Specification, не C# Language Specification. Осложнять жизнь при портировании кода под .net — не самый лучший способ завоевать популярность.

Ну дык я про эту спеку и говорил. Массивы — это часть рантайма, а не C#

S>Нет, просто для таких задач недостаточно примитивной абстракции над непрерывным сегментом памяти. И у гипотетического SlicedArray вполне может быть Length типа long (зачем мелочиться?).

Дык уже У массивов есть LongLength

S>[k.o.]

S>Или code analysis warning, или OverflowException в рантайме при тестах, или ArgumentOutOfRange на клиенте. Всё зависит от уровня разработки.
S>[/k.o.]
Первое — возможно, второго и третьего не будет Просто код поведёт себя совсем не так, как того ожидает разработчик...
S>Но в целом да, беззнаковый тип для размерностей может породить кучу интересных проблем как раз из-за отсутствия явно недопустимых значений.
Да нет — тут проблема чисто в переполнениях и в том, что очень многие разработчики тупо не в курсе проблемы...
[КУ] оккупировала армия.
Re[7]: Как не надо писать код
От: Sinix  
Дата: 28.04.11 15:51
Оценка:
Здравствуйте, koandrew, Вы писали:

K>Дык уже У массивов есть LongLength


Оно есть начиная с .NET 1.1. Позор на мою неседую голову, что ещё сказать.

S>>[k.o.]

S>>Или code analysis warning, или OverflowException в рантайме при тестах, или ArgumentOutOfRange на клиенте. Всё зависит от уровня разработки.
S>>[/k.o.]
K>Первое — возможно, второго и третьего не будет Просто код поведёт себя совсем не так, как того ожидает разработчик...
Кстати да, i у нас будет int. И в цикле нет доступа к массиву. А вот почему не будет overflow при checked-билде?

K>Да нет — тут проблема чисто в переполнениях и в том, что очень многие разработчики тупо не в курсе проблемы...

И не только в них. Если результат IndexOf() == uint.MaxValue — это значит что мы ничего не нашли, или что нашли последний элемент? Конечно можно отдавать Nullable<uint>, но, чую, это только самое начало проблем от использования uint для индексирования массивов/списков.
Re[8]: Как не надо писать код
От: koandrew Канада http://thingselectronic.blogspot.ca/
Дата: 28.04.11 16:04
Оценка: +1
Здравствуйте, Sinix, Вы писали:

S>Оно есть начиная с .NET 1.1. Позор на мою неседую голову, что ещё сказать.



S>Кстати да, i у нас будет int. И в цикле нет доступа к массиву. А вот почему не будет overflow при checked-билде?

Тока что проверил — таки ты прав — будет переполнение. Но что-то я ни разу не видел таких билдов в живой природе

S>И не только в них. Если результат IndexOf() == uint.MaxValue — это значит что мы ничего не нашли, или что нашли последний элемент? Конечно можно отдавать Nullable<uint>, но, чую, это только самое начало проблем от использования uint для индексирования массивов/списков.

Тут тут тока nullable, ну или вообще экепшен бросать
[КУ] оккупировала армия.
Re[60]: Как не надо писать код
От: AlexNek  
Дата: 28.04.11 16:55
Оценка:
Здравствуйте, samius, Вы писали:

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

я немного подчистил текст, если что лишнее убрал — не специально.

s> s>> AN>Была речь о "волшебстве", которое в итоге как то превращается в "глобальную переменную"


s> s>> Это было бы проклятие, а не "волшебство".


s> AN>"Console" и "GerServices()" я и называю "глобальными переменными".


s> По поводу консоли — можно согласиться. А GetServices с чего стал глобальным?

А сколько у вас имплементаций для "хранилища" сервисов?
Кроме того он может выглядеть и так
ServiceController.GetServices();

s> AN>Должно быть нечто видное "везде".


s> Для чего, и собственно что именно?

Что именно абсолютно не интересует (вполне возможно, что подобная формулировка режет слух но это просто различие в уровнях абстракций)
А для чего? Есть задача иметь доступ к чему то из любой части программы.
Ну типа Trace.WriteLine();

s> AN>Тормоза, в данном случае, нас не интересуют вообще, на данном уровне абстракции их вообще нет, машинка просто может останавливаться. По какой причине — не интересует.


s> Пусть не интересует


s> AN>Если рассматривать другую задачу, в которой будет важна сущность останова, то мы просто добавим объект в возможностью останова и с ограниченной возможностью останова. При этом реальный объект может тормозить из за наличия тормозов, а может и просто из за наличия троса сзади.


s> В исходной задаче вы сказали что "можно определить корректность аргументов". И это подразумевает некоторый способ, который не изменится при смене реализации абстракции.

Нет, это никак не подразумевает конкретный способ. Я даже не знаю какие будут аргументы и как их необходимо проверять. Я только знаю что должна быть проверка и что она возвратит результат опять таки в каком либо виде.
То есть должно быть нечно которому "я дам" аргументы и "могу спросить" ответь ка это верно или нет?

s> s>> Сначала вы писали что вас не волнует то что в консоли могут быть исключения, что ваша программа должна доработать, даже если в консоль невозможно писать. Без обработки исключений это обеспечить нельзя. Что тут непонятно? Если не нужны они вам в конкретном случае — не обрабатывайте. Тогда ваша программа споткнется о первое исключение, что бы вы там не представили о WriteLine-е.


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


s> Нет варианта без исключений. Есть вариант без обработки исключений. Потому как нет такой WriteLine, которая бы не кидала исключений вообще никогда.

Держите

WriteLine()
{
}


Вы опять переходите на конкретику. Дело было не в конкретной функции WriteLine. А скажем так в "паттерне размышления".

s> s>> Т.е. вы призываете не использовать что-то для решения задач только потому что сегодня вы не помните нечто так же хорошо? Допустим, есть алгоритм "Дейкстры", который решает вашу задачу, и который вы сегодня не помните так же хорошо. Будете изобретать свой?


s> AN>Я не призываю следовать всегда и везде каким либо установкам. Иногда это может быть целесообразно иногда нет. Хотя часто и нет полной уверенности как следует действовать в конкретной ситуации. Однако на выбор будет сильно влиять "режим работы" — командный или в одиночку.


s> Т.е. если командный, то будете склонны изобретать свой метод, вместо использования общеизвестного? Не ясна логика.

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

s> AN>В предложенной Вами ситуации может быть довольно много вариантов. Можно было не слышать и не догадываться что есть подобный алгоритм, можно было просто поискать вначале, если задача достаточно стандартная, возможно уже есть полностью готовое.


s> варианты не интересны. Есть что-то неочевидное для соседа. Будет ли алгоритм Дейкстры менее понятен для соседа, чем ваш велосипед?

Зависит от ситуации, но вполне возможно что и да. При этом, я не говорю, что мой алгоритм будет лучше. Он может допустим, работать медленней, выжирать память или что еще. Но если плата будет разумной, то я за более понятный вариант.
Однако, не буду утверждать, что всегда об думаю и делаю. Это просто "концепт".

s> AN>Если что то слышал но не помнишь, можно поискать и глянуть, а подойдет ли? Если решение кажется сложным но не придумывается проще можно вполне взять готовое снабдив комментарием на описание/название и т.п. Иногда можно вообще ничего не искать. Если на поиски нужно будет хотя бы полдня (при непредсказуемом результате), а написать можно за два, то нафига что искать.


s> А потом еще 2 дня объяснять команде, чего тут понаписано?

А другом случае пусть они сами потратят неделю на понимание, алгоритм то не мой, отчего его объяснять. Сами должны знать...
Вообще то из практики: требуется хотя бы полгода работы, для объяснения принципов аж в течении двух дней.


s> s>> Вы достаточно хорошо понимаете работу компилятора вместе с остальной командой, что бы не считать использование компилятора выпендриванием?


s> AN>По крайней мере мы пишем код вначале "для себя", а уж потом для компилятора.

s> AN>Можно было вообще никаких отступов не делать — это ведь лишняя работа компилятору.

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


s> AN>Возможно необходимо пояснить что имелось в виду под "выпендриванием".


s> Поясните, будьте добры. Вы его упомянули в ответ на мое предложение подтянуть команду.

Ну, можно далеко не ходить за примером "выпендривания"
bufferLength = Math.Max(bufferLength, 0)

Изучать нового вроде ничего и нужно, но и понять с первого взгляда, "просмотром кода" не получится. Это скажем пример "неочевидного использования". Можно еще подумать над примером "необосновано усложненные действия", ну типа вместо трех вызовов конкретных функций сделать цикл по массиву из трех делегатов.

Вы же имели видимо в виду видимо "неизвестное использование"
Ну типа
return await ххх


А вот при чем здесь инструменты до меня не дошло.

s> s>> Существуют причины для избавления от свитча, существуют причины для сохранения свитча. Его длина не показатель для избавления.


s> AN>В данном случае, меня раздражала именно "длина". Я ведь не пишу рецепт "в каких случаях желательно избавляться от свитча". Хотя "длину в десяток экранов" (несколько преувеличено) я бы записал в него.


s> Ни в коем случае не призываю вас от него избавляться, не зная деталей. Но вот мне что интересно: в вашей команде считается выпендриванием оперирование абстракциями,

Что то я не припоминаю где это я мог упоминать.

s> но гипертрофированный свитч, по всей видимости, не является проблемой для понимания его работы?

Так а что там нужно понимать? Есть выбор и дохрена "комнат".
Нужно что новое — добавляешь "комнату" и все.

Можно было допустим "выпендрится" с атрибутами и забить "комнатки" в функции.
Тогда также было бы просто добавить "комнату", но зато общий код получился бы неочевидным, нужно было уже "думать" как, почему и зачем.
avalon 1.0rc3 rev 419, zlib 1.2.3
Re[61]: Как не надо писать код
От: samius Япония http://sams-tricks.blogspot.com
Дата: 28.04.11 18:55
Оценка: +1
Здравствуйте, AlexNek, Вы писали:

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


AN>я немного подчистил текст, если что лишнее убрал — не специально.

нет проблем

s>> По поводу консоли — можно согласиться. А GetServices с чего стал глобальным?

AN>А сколько у вас имплементаций для "хранилища" сервисов?
Обычно не больше одной

AN>Кроме того он может выглядеть и так

AN>ServiceController.GetServices();
У тех кто не видел проблем от глобальных состояний — может.

s>> AN>Должно быть нечто видное "везде".


s>> Для чего, и собственно что именно?

AN>Что именно абсолютно не интересует (вполне возможно, что подобная формулировка режет слух но это просто различие в уровнях абстракций)
Под что именно я пытался уточнить, речь о глобальных состояниях только, или вообще о методах, классах?
AN>А для чего? Есть задача иметь доступ к чему то из любой части программы.
AN>Ну типа Trace.WriteLine();
Хоть оно и из коробки, но это далеко не образец для подражания. Если при активном использовании Trace начать манипулировать TraceListener-ами во время выполнения в многопоточном приложении — будет большая каша, например.

s>> В исходной задаче вы сказали что "можно определить корректность аргументов". И это подразумевает некоторый способ, который не изменится при смене реализации абстракции.

AN>Нет, это никак не подразумевает конкретный способ. Я даже не знаю какие будут аргументы и как их необходимо проверять. Я только знаю что должна быть проверка и что она возвратит результат опять таки в каком либо виде.
AN>То есть должно быть нечно которому "я дам" аргументы и "могу спросить" ответь ка это верно или нет?
Например, у TryGetValue указано, что должен вылетать ArgumentNullException. Это значит что у всех реализаций должно быть так. Пусть на некотором уровне абстракции способ не важен, но мы не сможем ввести абстракцию, не указав конкретный способ для получения информации о корректости аргументов. Конкретный способ тоже может быть абстрактным, но у этой абстракции должен будет быть конкретный интерфейс.

s>> Нет варианта без исключений. Есть вариант без обработки исключений. Потому как нет такой WriteLine, которая бы не кидала исключений вообще никогда.

AN>Держите

AN>
WriteLine()
AN>{
AN>}
AN>

StackOverflowException вряд ли имеет смысл обрабатывать, но то что он оттуда вылетит при определенных обстоятельствах — это факт.

s>> Т.е. если командный, то будете склонны изобретать свой метод, вместо использования общеизвестного? Не ясна логика.

AN>Я всего лишь сказал, что метод работы будет влиять на выбор, но ничего не говорил о конкретном выборе. Хотя и метод работы не единственное, что будет влиять на выбор. Если допустим, я делаю прогу один, для себя лично, то у меня нет никаких дополнительных ограничивающих факторов, но по мере отклонения от этой линии факторов становится все больше и они могут изменять свой вес.
А я всего лишь хотел спросить, влияет ли командная разработка в пользу своих решений вместо традиционных, не известных команде?

s>> варианты не интересны. Есть что-то неочевидное для соседа. Будет ли алгоритм Дейкстры менее понятен для соседа, чем ваш велосипед?

AN>Зависит от ситуации, но вполне возможно что и да. При этом, я не говорю, что мой алгоритм будет лучше. Он может допустим, работать медленней, выжирать память или что еще. Но если плата будет разумной, то я за более понятный вариант.
О-как? С учетом "непонятности" Math.Max настораживает.
AN>Однако, не буду утверждать, что всегда об думаю и делаю. Это просто "концепт".
понятно

s>> А потом еще 2 дня объяснять команде, чего тут понаписано?

AN>А другом случае пусть они сами потратят неделю на понимание, алгоритм то не мой, отчего его объяснять. Сами должны знать...
Ваш можно объяснить за 2 дня, а не ваш пусть неделю понимают? Конечно, все пишут такие тупые и непонятные вещи, как Math.Max
AN>Вообще то из практики: требуется хотя бы полгода работы, для объяснения принципов аж в течении двух дней.
AN>

Это смотря кому объяснять

s>> Поясните, будьте добры. Вы его упомянули в ответ на мое предложение подтянуть команду.

AN>Ну, можно далеко не ходить за примером "выпендривания"
AN>
bufferLength = Math.Max(bufferLength, 0)
AN>

AN>Изучать нового вроде ничего и нужно, но и понять с первого взгляда, "просмотром кода" не получится.
Что тут не понять с первого взгляда? И как написать так, что бы можно было понять с первого взгляда?

AN>Это скажем пример "неочевидного использования". Можно еще подумать над примером "необосновано усложненные действия", ну типа вместо трех вызовов конкретных функций сделать цикл по массиву из трех делегатов.

Возможно для такого чуда есть повод?

AN>Вы же имели видимо в виду видимо "неизвестное использование"

AN>Ну типа
AN>
return await ххх

Что за неизвестное использование? Спрашиваем гугль и оно становится известное. А вообще в блогах об этом с пол года пишут.

AN>А вот при чем здесь инструменты до меня не дошло.

Притом что компилятор, Math.Max, алгоритм Дейкстры, await, исключения и абстракции над WriteLine — это инструменты для решения задач. Мне показалось, что вы принебрегаете одними, довольно простыми, по причинам "сложности", но используете гораздо более сложные...

s>> Ни в коем случае не призываю вас от него избавляться, не зная деталей. Но вот мне что интересно: в вашей команде считается выпендриванием оперирование абстракциями,

AN>Что то я не припоминаю где это я мог упоминать.

s> Если манипулирование абстракциями на таком уровне является проблемой для команды, то ну ее нафик, эту абстракцию.
Дело не в конкретной проблеме, а в общем подходе. И дело, в основном, упирается во время.
s> А может стоит подтянуть команду? Все же это не ахти какой уровень владения программированием.
Сегодня она одна, завтра совсем другая. Главный принцип "не выпендриваться".


s>> но гипертрофированный свитч, по всей видимости, не является проблемой для понимания его работы?

AN>Так а что там нужно понимать? Есть выбор и дохрена "комнат".
AN>Нужно что новое — добавляешь "комнату" и все.
Вот опять, Math.Max непонятно, а 10и-страничный свитч — "что там нужно понимать?"

AN>Можно было допустим "выпендрится" с атрибутами и забить "комнатки" в функции.

AN>Тогда также было бы просто добавить "комнату", но зато общий код получился бы неочевидным, нужно было уже "думать" как, почему и зачем.
Мне, например, проще думать чем читать 10 страниц со свитчем или улавливать какие-то закономерности на 10и страницах.
Re[62]: Как не надо писать код
От: AlexNek  
Дата: 28.04.11 22:27
Оценка:
Здравствуйте, samius, Вы писали:

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


s> s>> По поводу консоли — можно согласиться. А GetServices с чего стал глобальным?


s> AN>А сколько у вас имплементаций для "хранилища" сервисов?


s> Обычно не больше одной

Так почему ее нельзя считать глобальной?

s> AN>Кроме того он может выглядеть и так

s> AN>ServiceController.GetServices();

s> У тех кто не видел проблем от глобальных состояний — может.

Микрософт их видимо обходит другим путем
s> s>> AN>Должно быть нечто видное "везде".

s> s>> Для чего, и собственно что именно?


s> AN>Что именно абсолютно не интересует (вполне возможно, что подобная формулировка режет слух но это просто различие в уровнях абстракций)


s> Под что именно я пытался уточнить, речь о глобальных состояниях только, или вообще о методах, классах?

Я имел в виду некий объект, доступ к которому может быть необходим из произвольного места кода. Объект может как хранить состояния, так и выполнять некую работу.
Каким образом это будет реализовано, глубоко фиолетово.

s> AN>А для чего? Есть задача иметь доступ к чему то из любой части программы.

s> AN>Ну типа Trace.WriteLine();

s> Хоть оно и из коробки, но это далеко не образец для подражания. Если при активном использовании Trace начать манипулировать TraceListener-ами во время выполнения в многопоточном приложении — будет большая каша, например.

Можно еще попробовать менять системные диски после загрузки ОС и проверить будет ли в этом случае каша.
Я начинаю подозревать что вы так называемый "практический типаж", есть у меня на работе хороший коллега с которым мы поначалу никак не могли найти общий язык. Я начинал ему говорить о проблеме на абстрактном уровне и он ну ничего не мог понять, зато когда приводил пару конкретных примеров, понимал мгновенно. Это ни хорошо, ни плохо, это просто другой тип мышления, который просто нужно учитывать при общении.
Хотя я пока не знаю точно как это учитывать при общении в форуме. Могу только сказать, что нам непросто понять друг друга в этом случае. Тут видимо спасут дополнительные вопросы. Ну это так, лирическое отступление

Метод был взят исключительно для примера глобального метода без исключений как некое противопоставление Console.WriteLine(). А является ли микрософт примером для подражания — это думается, была бы громадная флеймовая ветка.

s> s>> В исходной задаче вы сказали что "можно определить корректность аргументов". И это подразумевает некоторый способ, который не изменится при смене реализации абстракции.


s> AN>Нет, это никак не подразумевает конкретный способ. Я даже не знаю какие будут аргументы и как их необходимо проверять. Я только знаю что должна быть проверка и что она возвратит результат опять таки в каком либо виде.

s> AN>То есть должно быть нечно которому "я дам" аргументы и "могу спросить" ответь ка это верно или нет?

s> Например, у TryGetValue указано, что должен вылетать ArgumentNullException. Это значит что у всех реализаций должно быть так. Пусть на некотором уровне абстракции способ не важен, но мы не сможем ввести абстракцию, не указав конкретный способ для получения информации о корректости аргументов. Конкретный способ тоже может быть абстрактным, но у этой абстракции должен будет быть конкретный интерфейс.

Для чего нам сейчас конкретный интерфейс? Когда можно использовать абстрактный (только в "моем значении"). Если хотите, приведите мне пример конкретного интерфейса и я сделаю из него абстрактный.

s> s>> Нет варианта без исключений. Есть вариант без обработки исключений. Потому как нет такой WriteLine, которая бы не кидала исключений вообще никогда.


s> AN>Держите


s> AN>
WriteLine()
s> AN>{
s> AN>}
s> AN>


s> StackOverflowException вряд ли имеет смысл обрабатывать, но то что он оттуда вылетит при определенных обстоятельствах — это факт.

Описание обстоятельств можно при которых именно "оттуда", а не просто по цепочке стукнуло?

s> s>> Т.е. если командный, то будете склонны изобретать свой метод, вместо использования общеизвестного? Не ясна логика.


s> AN>Я всего лишь сказал, что метод работы будет влиять на выбор, но ничего не говорил о конкретном выборе. Хотя и метод работы не единственное, что будет влиять на выбор. Если допустим, я делаю прогу один, для себя лично, то у меня нет никаких дополнительных ограничивающих факторов, но по мере отклонения от этой линии факторов становится все больше и они могут изменять свой вес.


s> А я всего лишь хотел спросить, влияет ли командная разработка в пользу своих решений вместо традиционных, не известных команде?

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

s> s>> варианты не интересны. Есть что-то неочевидное для соседа. Будет ли алгоритм Дейкстры менее понятен для соседа, чем ваш велосипед?


s> AN>Зависит от ситуации, но вполне возможно что и да. При этом, я не говорю, что мой алгоритм будет лучше. Он может допустим, работать медленней, выжирать память или что еще. Но если плата будет разумной, то я за более понятный вариант.


s> О-как? С учетом "непонятности" Math.Max настораживает.

А что при первом же взгляде на название функции сразу ясно, что она тут может делать? Хотя бы какое то время нужно задержаться и на аргументах.
bufferLength = Math.Max(bufferLength, 0);

Сравните например с этой записью? Какая из двух читабельней?
if (bufferLength < 0)
{
  bufferLength = 0;
}


s> s>> А потом еще 2 дня объяснять команде, чего тут понаписано?


s> AN>А другом случае пусть они сами потратят неделю на понимание, алгоритм то не мой, отчего его объяснять. Сами должны знать...


s> Ваш можно объяснить за 2 дня, а не ваш пусть неделю понимают? Конечно, все пишут такие тупые и непонятные вещи, как Math.Max


Обычно объяснять нужно гораздо меньше чем разбираться самому (может быть и наоборот, но это скорее исключение, чем правило) И свое объяснять проще чем чужое.

s> AN>Вообще то из практики: требуется хотя бы полгода работы, для объяснения принципов аж в течении двух дней.

s> AN>


s> Это смотря кому объяснять

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

s> s>> Поясните, будьте добры. Вы его упомянули в ответ на мое предложение подтянуть команду.


s> AN>Ну, можно далеко не ходить за примером "выпендривания"

s> AN>
bufferLength = Math.Max(bufferLength, 0)
s> AN>

s> AN>Изучать нового вроде ничего и нужно, но и понять с первого взгляда, "просмотром кода" не получится.

s> Что тут не понять с первого взгляда? И как написать так, что бы можно было понять с первого взгляда?

см. ответ выше.

s> AN>Это скажем пример "неочевидного использования". Можно еще подумать над примером "необосновано усложненные действия", ну типа вместо трех вызовов конкретных функций сделать цикл по массиву из трех делегатов.


s> Возможно для такого чуда есть повод?

Для этого нужно убрать слово "необоснованное"

s> AN>Вы же имели видимо в виду видимо "неизвестное использование"

s> AN>Ну типа
s> AN>
return await ххх


s> Что за неизвестное использование? Спрашиваем гугль и оно становится известное. А вообще в блогах об этом с пол года пишут.


А если бы вы это год назад увидели? Рассматривайте просто как пример чего то непонятного (без привлечения посторонних источников) За If ведь никто в гугль не лезет.
s> AN>А вот при чем здесь инструменты до меня не дошло.

s> Притом что компилятор, Math.Max, алгоритм Дейкстры, await, исключения и абстракции над WriteLine — это инструменты для решения задач. Мне показалось, что вы принебрегаете одними, довольно простыми, по причинам "сложности", но используете гораздо более сложные...

А чем сложен компилятор? Нажал кнопу и все. Мне даже не нужно знать, что там где то есть какой то ИЛ. Ну и понятие "инструменты" у меня немного иное, но это думаю неважно. Ну а что сложное, что простое — это опять таки тема отдельной бесконечной дискуссии. У каждого может быть свое "верное" мнение.

s> s>> Ни в коем случае не призываю вас от него избавляться, не зная деталей. Но вот мне что интересно: в вашей команде считается выпендриванием оперирование абстракциями,


s> AN>Что то я не припоминаю где это я мог упоминать.


s>

s> s> Если манипулирование абстракциями на таком уровне является проблемой для команды, то ну ее нафик, эту абстракцию.

s> Дело не в конкретной проблеме, а в общем подходе. И дело, в основном, упирается во время.

s> s> А может стоит подтянуть команду? Все же это не ахти какой уровень владения программированием.

s> Сегодня она одна, завтра совсем другая. Главный принцип "не выпендриваться".


так и не доходит почему это у вас все так связалось. Видимо вы имели в виду "это конкретное", а я нечно "абстрактное".

s> s>> но гипертрофированный свитч, по всей видимости, не является проблемой для понимания его работы?


s> AN>Так а что там нужно понимать? Есть выбор и дохрена "комнат".

s> AN>Нужно что новое — добавляешь "комнату" и все.

s> Вот опять, Math.Max непонятно, а 10и-страничный свитч — "что там нужно понимать?"

у данного switch есть "типовой паттерн". Так как все построено в ключе этого паттерна, то завидев этот switch и пару case можно вообще дальше не смотреть. При этом, до этого времени, паттерна можно и не знать, его сразу "видно".
s> AN>Можно было допустим "выпендрится" с атрибутами и забить "комнатки" в функции.
s> AN>Тогда также было бы просто добавить "комнату", но зато общий код получился бы неочевидным, нужно было уже "думать" как, почему и зачем.

s> Мне, например, проще думать чем читать 10 страниц со свитчем или улавливать какие-то закономерности на 10и страницах.

В том то и дело что их ничего не нужно улавливать. Вам кто то объяснял принцип работы топора? Вот это где то в том же духе. Представим работу собаки ищейки, нюхаем, нюхаем, нашли. Вот где то такой грубый принцип исправления неизвестного чужого кода. А этот switch просто воняет, не найти его невозможно, при этом исправить ошибочно нужно еще постараться.
А требование думать — это весьма часто путь к потенциальным ошибкам. Разработчик думал так, вы думаете по другому, я по третьему. Кто может гарантировать что мы все трое будем думать одинаково?
Можно попробовать пофантазировать на тему исправленного switch.
По любому, case будут отделены от выбора, скорее всего в отдельном файле/файлах.
Ладно, имея один файл можно просто вычислить case-ы, но мы хотим также и узнать где находится выбор, простой поиск не помогает, стэк в точке останова не дает ничего о том откуда пришел реальный вызов. Наконец нашли кое как где это выбор вызывается, но почему вызывается именно данная функция так и осталось загадкой. Через какое то время нашли место инициализации, похоже здесь, но функция которая там используется у меня не в голове, нужно лезть в МСДН. Таймер нужно засекать? Сколько времени понадобилось в первый раз и сколько, во второй? Еще думать хочется?
avalon 1.0rc3 rev 419, zlib 1.2.3
Re[5]: Как не надо писать код
От: koandrew Канада http://thingselectronic.blogspot.ca/
Дата: 28.04.11 23:08
Оценка:
Здравствуйте, samius, Вы писали:


S>Как я понял, koandrew пишет не о том, что бы уметь выделять массивы больших размеров, а о том, что отрицательной длины у массива быть не должно.

Угу

S>А на эту тему у меня есть свежий пример из собственной практики. Увидел ворнинг о сравнении знаковых и беззнаковых в следующем коде на C++:

S>
S>for (int i = vector.size() - 1; i >= 0; i--)
S>     foo(vector[i]);
S>

S>исправил на нечто вроде
S>
S>for (size_t i = vector.size() - 1; i >= 0u; i--)
S>     foo(vector[i]);
S>

S>и потом долго не мог связать срыв крыши у программы с этим изменением.
Я таких багов переловил вагон и маленький бронепоезд, да и сам, каюсь, несколько раз попадался — правда в не столь очевидных случаях
[КУ] оккупировала армия.
Re[63]: Как не надо писать код
От: samius Япония http://sams-tricks.blogspot.com
Дата: 29.04.11 06:19
Оценка:
Здравствуйте, AlexNek, Вы писали:

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


s>> AN>А сколько у вас имплементаций для "хранилища" сервисов?


s>> Обычно не больше одной

AN>Так почему ее нельзя считать глобальной?
Реализацию считать глобальной, потому что нет других реализаций? Вот допустим что существует лишь одна реализация IList<T> — List<T>. Можно ли ее считать глобальной?

s>> Под что именно я пытался уточнить, речь о глобальных состояниях только, или вообще о методах, классах?

AN>Я имел в виду некий объект, доступ к которому может быть необходим из произвольного места кода. Объект может как хранить состояния, так и выполнять некую работу.
AN>Каким образом это будет реализовано, глубоко фиолетово.
Вы же сказали что это будет "глобальная переменная". А это global state, как не реализуй. Так вот, использование глобального хранилища сервисов вряд ли чем-то лучше, чем использование глобальной переменной для каждого сервиса.

AN>Я начинаю подозревать что вы так называемый "практический типаж"

Давайте воздержимся от обсуждения личностей. Хоть ничего оскорбительного я не увидел, но это не по правилам форума.
AN>Метод был взят исключительно для примера глобального метода без исключений как некое противопоставление Console.WriteLine(). А является ли микрософт примером для подражания — это думается, была бы громадная флеймовая ветка.

AN>Для чего нам сейчас конкретный интерфейс? Когда можно использовать абстрактный (только в "моем значении").

Я о том и говорю, что использовать мы его сможем только для абстрактного обсуждения, а при попытке вставить абстракцию в код, без конкретики ничего не выйдет.
AN>Если хотите, приведите мне пример конкретного интерфейса и я сделаю из него абстрактный.
Занятно будет посмотреть
Func<Func<A,B,C>, A, Func<B,C>>


s>> AN>
WriteLine()
s>> AN>{
s>> AN>}
s>> AN>


s>> StackOverflowException вряд ли имеет смысл обрабатывать, но то что он оттуда вылетит при определенных обстоятельствах — это факт.

AN>Описание обстоятельств можно при которых именно "оттуда", а не просто по цепочке стукнуло?
Вы правы, вылетит не именно "оттуда", а при вызове. Как по поводу ThreadAbortException?

s>> А я всего лишь хотел спросить, влияет ли командная разработка в пользу своих решений вместо традиционных, не известных команде?

AN>...
AN>Если задача подразумевает вероятное "академическое решение", то лучше вначале использовать его.
Так вот, вернувшись к выделению абстракции над WriteLine, это и есть вероятное "академическое решение".

AN>А что при первом же взгляде на название функции сразу ясно, что она тут может делать? Хотя бы какое то время нужно задержаться и на аргументах.

AN>
bufferLength = Math.Max(bufferLength, 0);

AN>Сравните например с этой записью? Какая из двух читабельней?
AN>
if (bufferLength < 0)
AN>{
AN>  bufferLength = 0;
AN>}

Безусловно первая. Задерживаюсь на аргументах: в ней меньшая цикломатическая сложность, меньше магических чисел, меньше вероятность ошибиться, проще тестировать. Первая запись является выражением и может быть использована в других выражениях, в то время как вторая — нет.

AN>Обычно объяснять нужно гораздо меньше чем разбираться самому (может быть и наоборот, но это скорее исключение, чем правило) И свое объяснять проще чем чужое.

Это субъективное наблюдение

s>> Это смотря кому объяснять

AN>Для недотеп может и не хватить двух . Но мы ведь на среднюю температуру по больнице ориентируемся. Новый принцип работы трясины все равно кому объяснять, если все из одного болота. Но есть время выдачи основной массы информации, как и способ ее подачи. Ну и сами знаете сколько килограмм продукта нужно для получения килограмма варенья.
Случай, когда объяснятель и объясняемый близки к средней температуре по больнице, не интересен. Они друг дружке что-то принципиально новое вряд ли объяснят.

s>> Что за неизвестное использование? Спрашиваем гугль и оно становится известное. А вообще в блогах об этом с пол года пишут.


AN>А если бы вы это год назад увидели? Рассматривайте просто как пример чего то непонятного (без привлечения посторонних источников) За If ведь никто в гугль не лезет.

Использование неочевидных конструкций подразумевает (но не гарантирует) то что использование очевидных конструкций чем-то не устраивает. По поводу того же await — мне будет проще почитать в паре-тройке мест, что он значит и потом понимать его в 20и местах использования, чем в 20 местах вчитываться в нагромождение очевидных конструкций.

AN>А чем сложен компилятор? Нажал кнопу и все. Мне даже не нужно знать, что там где то есть какой то ИЛ. Ну и понятие "инструменты" у меня немного иное, но это думаю неважно. Ну а что сложное, что простое — это опять таки тема отдельной бесконечной дискуссии. У каждого может быть свое "верное" мнение.

Компилятор достаточно сложен, просто лишь его использование в духе "нажал кнопку". Однако использование не подразумевает понимания процессов, происходящих в конкретном компиляторе. В то время как понимать процессы, происходящие при выделении абстракции, вполне доступно для программиста уровня джуниора.

AN>так и не доходит почему это у вас все так связалось. Видимо вы имели в виду "это конкретное", а я нечно "абстрактное".

Мы обсуждали то, будет ли понятно введение абстракции для команды.

s>> Вот опять, Math.Max непонятно, а 10и-страничный свитч — "что там нужно понимать?"

AN>у данного switch есть "типовой паттерн". Так как все построено в ключе этого паттерна, то завидев этот switch и пару case можно вообще дальше не смотреть. При этом, до этого времени, паттерна можно и не знать, его сразу "видно".
Я-то его не видел. Я просто реагирую на "10и страничный свитч" и представляю себе такого нормального монстрика с вложенными свитчами, goto и всякой прелестью, что является вполне типично для 2х и более страничных свитчей, выходящих из под топора среднеотраслевых мастеров.

AN>А требование думать — это весьма часто путь к потенциальным ошибкам. Разработчик думал так, вы думаете по другому, я по третьему. Кто может гарантировать что мы все трое будем думать одинаково?

Думать можно разными путями, а уж недумая —
AN>Можно попробовать пофантазировать на тему исправленного switch.
AN>По любому, case будут отделены от выбора, скорее всего в отдельном файле/файлах.
AN>Ладно, имея один файл можно просто вычислить case-ы, но мы хотим также и узнать где находится выбор, простой поиск не помогает, стэк в точке останова не дает ничего о том откуда пришел реальный вызов. Наконец нашли кое как где это выбор вызывается, но почему вызывается именно данная функция так и осталось загадкой. Через какое то время нашли место инициализации, похоже здесь, но функция которая там используется у меня не в голове, нужно лезть в МСДН. Таймер нужно засекать? Сколько времени понадобилось в первый раз и сколько, во второй? Еще думать хочется?
Мне кажется что у нас с вами разные отладчики. Не приходилось сталкиваться с описанными проблемами. И стек мне видно и Step Into входит в куда надо и брекпоинты ставятся, и место инициализации находится хоть средой хоть рефлектором за секунды. Такое ощущение, что вы отлаживаетесь по твердой копии исходников...
Re[6]: Как не надо писать код
От: samius Япония http://sams-tricks.blogspot.com
Дата: 29.04.11 06:25
Оценка:
Здравствуйте, koandrew, Вы писали:

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


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

K>Я таких багов переловил вагон и маленький бронепоезд, да и сам, каюсь, несколько раз попадался — правда в не столь очевидных случаях
Да я тоже их когда-то ловил, до перехода на C#. А потом за 8 лет привык к хорошему. В том числе что проверка диапазона часто позволяет определять такие баги на ранней стадии. Здесь же глядя на мусор в результате пришлось локализовывать баг самому. Не помню что мешало переключиться в DEBUG... Видимо не предполагал что ошибка связана с выходом из диапазона.
Re[3]: Как не надо писать код
От: Mystic Украина http://mystic2000.newmail.ru
Дата: 29.04.11 08:57
Оценка:
Здравствуйте, AlexNek, Вы писали:

AN>А откуда появилась информация об обрезании?

AN>И что именно проверяется перед началом?
AN>Какие действия предпринимаются для неправильных данных? Верны они или нет?
AN>Вопросов можно еще найти довольно много и ответ во многих случаях нужно искать, а не "увидеть"

Обрезание из пределов цикла. В начале всякие проверки на null и Length = 0. Вообще, когда тебе попадается такой код, то есть еще и некоторая предметная область.

Я не говорю, что код написал идеально, я просто написал то, что увидел за 10 секунд просмотра.
Re[64]: Как не надо писать код
От: AlexNek  
Дата: 29.04.11 14:19
Оценка:
Здравствуйте, samius, Вы писали:

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


s> s>> AN>А сколько у вас имплементаций для "хранилища" сервисов?


s> s>> Обычно не больше одной


s> AN>Так почему ее нельзя считать глобальной?


s> Реализацию считать глобальной, потому что нет других реализаций? Вот допустим что существует лишь одна реализация IList<T> — List<T>. Можно ли ее считать глобальной?

Если она используется локально, то нет. А когда речь идет о доступности с любого места кода, то я пока не могу найти отличий.

s> s>> Под что именно я пытался уточнить, речь о глобальных состояниях только, или вообще о методах, классах?


s> AN>Я имел в виду некий объект, доступ к которому может быть необходим из произвольного места кода. Объект может как хранить состояния, так и выполнять некую работу.

s> AN>Каким образом это будет реализовано, глубоко фиолетово.

s> Вы же сказали что это будет "глобальная переменная". А это global state, как не реализуй.

Можно списать на "ошибки" вербальной коммуникации, я подразумевал под этим несколько другое.

s> Так вот, использование глобального хранилища сервисов вряд ли чем-то лучше, чем использование глобальной переменной для каждого сервиса.

Видимо под словом "глобальный" мы подразумеваем различные вещи.

s> AN>Я начинаю подозревать что вы так называемый "практический типаж"


s> Давайте воздержимся от обсуждения личностей. Хоть ничего оскорбительного я не увидел, но это не по правилам форума.

Я вроде и не собирался этого делать, думаю из контекста было понятно, что я всего лишь рассуждал в каком ключе было бы удобнее вести с Вами беседу. Если вы расценили это как покушение на "privacy", то могу попросить прощения.
Надеюсь, вы не будет отрицать, что нельзя в одинаковом "ключе" говорить со всеми.
Если у нас, большая разница в "способе мышления", то мои высказывания будут непонятны Вам, а мне Ваши. Поэтому я обычно стараюсь подстраивать высказывания под способ мышления "собеседника", А его высказывания "переводить" на свой.

s> AN>Метод был взят исключительно для примера глобального метода без исключений как некое противопоставление Console.WriteLine(). А является ли микрософт примером для подражания — это думается, была бы громадная флеймовая ветка.


s> AN>Для чего нам сейчас конкретный интерфейс? Когда можно использовать абстрактный (только в "моем значении").


s> Я о том и говорю, что использовать мы его сможем только для абстрактного обсуждения, а при попытке вставить абстракцию в код, без конкретики ничего не выйдет.

Если нам понадобится вставлять в код, тогда можно и обговорить конкретику.

s> AN>Если хотите, приведите мне пример конкретного интерфейса и я сделаю из него абстрактный.


s> Занятно будет посмотреть

s>
s> Func<Func<A,B,C>, A, Func<B,C>>
s>

Вот подобные вещи и можно назвать "выпендриванием", напомнило старый анекдот про японскую деревообрабатывающую машину и стальное бревно. Подразумевалось как бы "в контексте обсуждаемой темы". Хотя в абстрактном виде это видимо выглядело бы так:
"Сделай что то зависящее от A,B,C". Хотя мне и весьма проблематично представить данную строку в описании интерфейса.

s> s>> AN>
WriteLine()
s> s>> AN>{
s> s>> AN>}
s> s>> AN>


s> s>> StackOverflowException вряд ли имеет смысл обрабатывать, но то что он оттуда вылетит при определенных обстоятельствах — это факт.


s> AN>Описание обстоятельств можно при которых именно "оттуда", а не просто по цепочке стукнуло?


s> Вы правы, вылетит не именно "оттуда", а при вызове. Как по поводу ThreadAbortException?

А оно специфично именно для этой функции? В описании "Console.WriteLine" оно также упомянуто? Мы обсуждаем работу многопотоковых приложений?

s> s>> А я всего лишь хотел спросить, влияет ли командная разработка в пользу своих решений вместо традиционных, не известных команде?


s> AN>...

s> AN>Если задача подразумевает вероятное "академическое решение", то лучше вначале использовать его.

s> Так вот, вернувшись к выделению абстракции над WriteLine, это и есть вероятное "академическое решение".

Вообще то имелись в виду различные математические алгоритмы. Но даже и в данном случае это было бы "неоправданным усложнением".

s> AN>А что при первом же взгляде на название функции сразу ясно, что она тут может делать? Хотя бы какое то время нужно задержаться и на аргументах.

s> AN>
bufferLength = Math.Max(bufferLength, 0);

s> AN>Сравните например с этой записью? Какая из двух читабельней?
s> AN>
if (bufferLength < 0)
s> AN>{
s> AN>  bufferLength = 0;
s> AN>}


s> Безусловно первая. Задерживаюсь на аргументах: в ней меньшая цикломатическая сложность, меньше магических чисел, меньше вероятность ошибиться, проще тестировать.

Думаю, какая либо дискуссия тут бесполезна, возможно только статистика бы помогла. Могу только попробовать высказать мои соображения.
— 1. Ассоциативное мышление. Я ожидаю увидеть функцию Math.Max в определенном контексте при выборе из двух "одинаковых сущностей". У меня есть еще второй буфер и нужно найти длина которого из них больше? Нет, есть переменная и константа 0. А нафига из них выбирать наибольшее? Ага, имеет смысл только если переменная меньше нуля. Пусть и небольшие, но все же раздумья.
— 2. "Визуальное восприятие паттернов". (мое "личное" определение, только что придумал ) Когда я смотрю на первый пример я вижу "х = функция от у", когда я вижу
второй то "х=0". Т.е для первого нужно пройти часть пути "ассоциативное мышление".
Во втором сразу видно три хорошо знакомых "паттерна" (if, х<0, x=0), которые можно сразу же прочитать даже на разговорном языке.
— 3. "Примитивизм" — перекликается с 2. Используются настолько простые конструкции, что даже человек не знающий программирования может их понять. А знающий поймет с "закрытыми глазами". В первом же случае нужно знать, что делает функция Max, какие у нее аргументы, почему именно такие аргументы.

s> Первая запись является выражением и может быть использована в других выражениях, в то время как вторая — нет.

Для меня это не достоинство, а громадный недостаток. Есл потребует то лучше сделать что то типа GetNormalizedBufferLength(int x)

s> AN>Обычно объяснять нужно гораздо меньше чем разбираться самому (может быть и наоборот, но это скорее исключение, чем правило) И свое объяснять проще чем чужое.


s> Это субъективное наблюдение

Я не проводил научных исследований, но мне лично обратное еще не встречалось.

s> s>> Это смотря кому объяснять


s> AN>Для недотеп может и не хватить двух . Но мы ведь на среднюю температуру по больнице ориентируемся. Новый принцип работы трясины все равно кому объяснять, если все из одного болота. Но есть время выдачи основной массы информации, как и способ ее подачи. Ну и сами знаете сколько килограмм продукта нужно для получения килограмма варенья.


s> Случай, когда объяснятель и объясняемый близки к средней температуре по больнице, не интересен. Они друг дружке что-то принципиально новое вряд ли объяснят.

Ну отчего же? Вы разрабатывали подсистему А, я подсистему Б. Объяснения друг другу будут весьма полезны. А объяснять работу подсистемы А дежурному сантехнику не будет иметь большого смысла.

s> s>> Что за неизвестное использование? Спрашиваем гугль и оно становится известное. А вообще в блогах об этом с пол года пишут.


s> AN>А если бы вы это год назад увидели? Рассматривайте просто как пример чего то непонятного (без привлечения посторонних источников) За If ведь никто в гугль не лезет.


s> Использование неочевидных конструкций подразумевает (но не гарантирует) то что использование очевидных конструкций чем-то не устраивает.

Конечно

s> По поводу того же await — мне будет проще почитать в паре-тройке мест, что он значит и потом понимать его в 20и местах использования, чем в 20 местах вчитываться в нагромождение очевидных конструкций.

Я привел только пример, что было понятно, что я имею в виду. Но с другой стороны, эти 20 мест уже могут жить в коде лет этак 5 и каждый знает их почти наизусть.
Как я уже говорил, конкретная ситуация может быть самая разная. Да и включение чего
то нового должно быть "официально одобрено". Если "я нашел" этот await вчера, то это не значит, что я его имею право его использовать уже завтра сразу в проекте.

s> AN>А чем сложен компилятор? Нажал кнопу и все. Мне даже не нужно знать, что там где то есть какой то ИЛ. Ну и понятие "инструменты" у меня немного иное, но это думаю неважно. Ну а что сложное, что простое — это опять таки тема отдельной бесконечной дискуссии. У каждого может быть свое "верное" мнение.


s> Компилятор достаточно сложен, просто лишь его использование в духе "нажал кнопку". Однако использование не подразумевает понимания процессов, происходящих в конкретном компиляторе. В то время как понимать процессы, происходящие при выделении абстракции, вполне доступно для программиста уровня джуниора.

Тут видимо опять какое то различие в толкованиях.

s> AN>так и не доходит почему это у вас все так связалось. Видимо вы имели в виду "это конкретное", а я нечно "абстрактное".


s> Мы обсуждали то, будет ли понятно введение абстракции для команды.


s> s>> Вот опять, Math.Max непонятно, а 10и-страничный свитч — "что там нужно понимать?"


s> AN>у данного switch есть "типовой паттерн". Так как все построено в ключе этого паттерна, то завидев этот switch и пару case можно вообще дальше не смотреть. При этом, до этого времени, паттерна можно и не знать, его сразу "видно".


s> Я-то его не видел. Я просто реагирую на "10и страничный свитч" и представляю себе такого нормального монстрика с вложенными свитчами, goto и всякой прелестью, что является вполне типично для 2х и более страничных свитчей, выходящих из под топора среднеотраслевых мастеров.

Видите, а мне описанный Вами свитч тяжело представить
Еще не встречал фирмы где goto был бы разрешен.

s> AN>А требование думать — это весьма часто путь к потенциальным ошибкам. Разработчик думал так, вы думаете по другому, я по третьему. Кто может гарантировать что мы все трое будем думать одинаково?


s> Думать можно разными путями, а уж недумая —

Это довольно просто.
Предположим, я или скажу
"В темной темнице красны девицы.
Без нитки, без спицы вяжут вязеницы"
или просто покажу картинку.
Что быстрее доведет до цели, о чем это я?

s> AN>Можно попробовать пофантазировать на тему исправленного switch.

s> AN>По любому, case будут отделены от выбора, скорее всего в отдельном файле/файлах.
s> AN>Ладно, имея один файл можно просто вычислить case-ы, но мы хотим также и узнать где находится выбор, простой поиск не помогает, стэк в точке останова не дает ничего о том откуда пришел реальный вызов. Наконец нашли кое как где это выбор вызывается, но почему вызывается именно данная функция так и осталось загадкой. Через какое то время нашли место инициализации, похоже здесь, но функция которая там используется у меня не в голове, нужно лезть в МСДН. Таймер нужно засекать? Сколько времени понадобилось в первый раз и сколько, во второй? Еще думать хочется?

s> Мне кажется что у нас с вами разные отладчики. Не приходилось сталкиваться с описанными проблемами. И стек мне видно и Step Into входит в куда надо и брекпоинты ставятся, и место инициализации находится хоть средой хоть рефлектором за секунды. Такое ощущение, что вы отлаживаетесь по твердой копии исходников...

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

[MethodShortcut(Shortcut.CtrlP, "Создать раздел", "Создать раздел")]
private void AddFolder()
{
    _serviceManager.TryExecuteCommand("Favorites.Commands.CreateFolder.DisplayName", new Dictionary<string, object>());
}

Теперь поставьте точку останова на функцию AddFolder и покажите на стеке вызов из ProcessMessageKey, да, и потом поставьте уже на данной строке точку останова и при помощи Step Into зайдите в функцию AddFolder.
             
ProcessMessageKey()
{
...
  methodInfo.Invoke(target, null);
}


Просто как некоторый пример, о чем я вёл речь.
avalon 1.0rc3 rev 419, zlib 1.2.3
Re[4]: Как не надо писать код
От: AlexNek  
Дата: 29.04.11 14:20
Оценка:
Здравствуйте, Mystic, Вы писали:

M> AN>А откуда появилась информация об обрезании?

M> AN>И что именно проверяется перед началом?
M> AN>Какие действия предпринимаются для неправильных данных? Верны они или нет?
M> AN>Вопросов можно еще найти довольно много и ответ во многих случаях нужно искать, а не "увидеть"

M> Обрезание из пределов цикла.

Как говорится, "не верь глазам своим". Там далеко сверху есть еще +1.
M> В начале всякие проверки на null и Length = 0. Вообще, когда тебе попадается такой код, то есть еще и некоторая предметная область.
В том и дело, что такой код. Не должен такой код попадаться на глаза.
И для подобной задачи, не требуется знать предметной области. Задача следующая:
есть некий байтовый буфер, который допустимо изменять. Требуется добавить в его начало специальный символ, при ошибках входных данных желательно выдавать "нулевую комбинацию", а не прерывать выполнение.

M> Я не говорю, что код написал идеально, я просто написал то, что увидел за 10 секунд просмотра.

Код написан просто катастрофически, а вот если бы код был написан хотя бы нормально, то за эти 10 секунд можно было увидеть и понять гораздо больше. Именно это мне и хотелось показать — "Народ, давайте не будет писать подобный код".
avalon 1.0rc3 rev 419, zlib 1.2.3
Re[65]: Как не надо писать код
От: samius Япония http://sams-tricks.blogspot.com
Дата: 29.04.11 19:25
Оценка:
Здравствуйте, AlexNek, Вы писали:

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


s>> Реализацию считать глобальной, потому что нет других реализаций? Вот допустим что существует лишь одна реализация IList<T> — List<T>. Можно ли ее считать глобальной?

AN>Если она используется локально, то нет. А когда речь идет о доступности с любого места кода, то я пока не могу найти отличий.
Обычно под реализацией/имплементацией подразумевают типы, а не экземпляры. Доступность типа в дотнете определяется не количеством, а модификатороми видимости для него и типов, в которые он вложен. Т.е. непонятно что вы подразумеваете под применением термина глобальность к типу(реализации/имплементации).
Все зкземпляры глобальны в рамках процесса. Т.е. имея его ардес/ссылку на экземпляр, не составит труда обратиться к нему отовсюду.

s>> Вы же сказали что это будет "глобальная переменная". А это global state, как не реализуй.

AN>Можно списать на "ошибки" вербальной коммуникации, я подразумевал под этим несколько другое.
И все-таки непонятно, что именно.

s>> Так вот, использование глобального хранилища сервисов вряд ли чем-то лучше, чем использование глобальной переменной для каждого сервиса.

AN>Видимо под словом "глобальный" мы подразумеваем различные вещи.
Может ссылку дадите?

s>> Давайте воздержимся от обсуждения личностей. Хоть ничего оскорбительного я не увидел, но это не по правилам форума.

AN>Я вроде и не собирался этого делать, думаю из контекста было понятно, что я всего лишь рассуждал в каком ключе было бы удобнее вести с Вами беседу. Если вы расценили это как покушение на "privacy", то могу попросить прощения.
Нет, обижаться в данном случае не на что. Просто это запрещено правилами.
AN>Надеюсь, вы не будет отрицать, что нельзя в одинаковом "ключе" говорить со всеми.
нет, не буду
AN>Если у нас, большая разница в "способе мышления", то мои высказывания будут непонятны Вам, а мне Ваши. Поэтому я обычно стараюсь подстраивать высказывания под способ мышления "собеседника", А его высказывания "переводить" на свой.
У нас еще разница в терминологии

s>> Я о том и говорю, что использовать мы его сможем только для абстрактного обсуждения, а при попытке вставить абстракцию в код, без конкретики ничего не выйдет.

AN>Если нам понадобится вставлять в код, тогда можно и обговорить конкретику.
Именно так

s>> AN>Если хотите, приведите мне пример конкретного интерфейса и я сделаю из него абстрактный.


s>> Занятно будет посмотреть

s>>
s>> Func<Func<A,B,C>, A, Func<B,C>>
s>>

AN>Вот подобные вещи и можно назвать "выпендриванием", напомнило старый анекдот про японскую деревообрабатывающую машину и стальное бревно. Подразумевалось как бы "в контексте обсуждаемой темы". Хотя в абстрактном виде это видимо выглядело бы так:
AN>"Сделай что то зависящее от A,B,C". Хотя мне и весьма проблематично представить данную строку в описании интерфейса.
Это фактически и есть интерфейс метода, выполняющего эмуляцию частичного применения функции. Реализация функции занимает одну строчку, делает она вещи, которые не зависят от A, B и тем более C. Этот милый прием позволил мне не писать порядка двухсот классов в текущем проекте.
В описании интерфейса это могло бы выглядеть так:
interface IFoo
{
    Func<B, C> Apply<A, B, C>(Func<A, B, C> func, A a);
}

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

s>> AN>Описание обстоятельств можно при которых именно "оттуда", а не просто по цепочке стукнуло?


s>> Вы правы, вылетит не именно "оттуда", а при вызове. Как по поводу ThreadAbortException?

AN>А оно специфично именно для этой функции? В описании "Console.WriteLine" оно также упомянуто? Мы обсуждаем работу многопотоковых приложений?
Да, специфично. Нет, не упомянуто. В "однопотоковом" оно тоже может вылететь. И я даже как-то не уверен, можно ли на .net написать "однопотоковое" приложение. Можно не запускать никаких вспомогательных потоков явно, но это не значит что их не будет .

s>> Так вот, вернувшись к выделению абстракции над WriteLine, это и есть вероятное "академическое решение".

AN>Вообще то имелись в виду различные математические алгоритмы. Но даже и в данном случае это было бы "неоправданным усложнением".
Предложите другой вариант, кроме как забивание на факт существования исключений. Напомню, что WriteLine взята лишь для примера, и вместо нее может быть любая другая функция. Мы говорим о концепте, не так ли?

s>> Безусловно первая. Задерживаюсь на аргументах: в ней меньшая цикломатическая сложность, меньше магических чисел, меньше вероятность ошибиться, проще тестировать.

AN>Думаю, какая либо дискуссия тут бесполезна, возможно только статистика бы помогла. Могу только попробовать высказать мои соображения.
AN>- 1. Ассоциативное мышление. Я ожидаю увидеть функцию Math.Max в определенном контексте при выборе из двух "одинаковых сущностей". У меня есть еще второй буфер и нужно найти длина которого из них больше? Нет, есть переменная и константа 0. А нафига из них выбирать наибольшее? Ага, имеет смысл только если переменная меньше нуля. Пусть и небольшие, но все же раздумья.
я не понял, т.е. если бы там стояло 100 вместо 0-я, то ничего бы не смущало?
AN>- 2. "Визуальное восприятие паттернов". (мое "личное" определение, только что придумал ) Когда я смотрю на первый пример я вижу "х = функция от у", когда я вижу
AN>второй то "х=0". Т.е для первого нужно пройти часть пути "ассоциативное мышление".
AN>Во втором сразу видно три хорошо знакомых "паттерна" (if, х<0, x=0), которые можно сразу же прочитать даже на разговорном языке.
(if, x<0, y=10) — тоже можно прочитать на разговорном языке, только здесь два небольших отличия, меняющих смысл кардинально. Но что самое интересное, (max, x, 0) — тоже легко читается.
AN>- 3. "Примитивизм" — перекликается с 2. Используются настолько простые конструкции, что даже человек не знающий программирования может их понять. А знающий поймет с "закрытыми глазами". В первом же случае нужно знать, что делает функция Max, какие у нее аргументы, почему именно такие аргументы.
Давайте теперь прикинием, что же нам больше знеакомо, max или if по жизни? Пример: нужно взять самое большое/красное яблоко из 5и штук, отбросив всякую скромность и деликатность. Любой ребенок выберет его бессознательно, не сравнивая при этом каждое с каждым и не оперируя if-ами. А к if-ам вы привыкли, видимо уже в разговоре с компьютером. И так хорошо привыкли, что более высокий уровень общения с компьютером у вас вызывает дискомфорт.
Заменяете ли вы if-ами виртуальные вызовы? Если нет, то что вы слышали о виртуальных вызовах до знакомства с программированием?

s>> Первая запись является выражением и может быть использована в других выражениях, в то время как вторая — нет.

AN>Для меня это не достоинство, а громадный недостаток. Есл потребует то лучше сделать что то типа GetNormalizedBufferLength(int x)
Хороший позыв. Но если заменить в тех примерах bufferLenght на x, то смысл функции GetNormalizedBufferLength будет ускользать. Ну и не будете же вы для каждого if-а плодить GetSomething(x)? Мне тут лично max кажется более уместным, т.к. что делает max мы можем догадаться, а что подразумевается под NormalizedBufferLength — тут нужны экстрасенсы. Так, если привести постороннего человека, то вряд ли он угадает что под нормализованной длиной буфера подразумевается неотрицательная.
Кстати, получение отрицательной длины буфера — это логическая ошибка в программе, которую надо исправлять как можно скорее, а не прятать ее. Но я уже писал об этом. Отрицательная длина не может считаться ненормальной, т.к. отрицательная длина — есть катастрофическая длина.

s>> Это субъективное наблюдение

AN>Я не проводил научных исследований, но мне лично обратное еще не встречалось.
Мне встречалось.

s>> Случай, когда объяснятель и объясняемый близки к средней температуре по больнице, не интересен. Они друг дружке что-то принципиально новое вряд ли объяснят.

AN>Ну отчего же? Вы разрабатывали подсистему А, я подсистему Б. Объяснения друг другу будут весьма полезны. А объяснять работу подсистемы А дежурному сантехнику не будет иметь большого смысла.
Вы не пытались объяснить смысл алгоритма Дейкстры (например) программисту, совершенно незнакомому с теорией графов?

s>> По поводу того же await — мне будет проще почитать в паре-тройке мест, что он значит и потом понимать его в 20и местах использования, чем в 20 местах вчитываться в нагромождение очевидных конструкций.

AN>Я привел только пример, что было понятно, что я имею в виду. Но с другой стороны, эти 20 мест уже могут жить в коде лет этак 5 и каждый знает их почти наизусть.
AN>Как я уже говорил, конкретная ситуация может быть самая разная. Да и включение чего
AN>то нового должно быть "официально одобрено". Если "я нашел" этот await вчера, то это не значит, что я его имею право его использовать уже завтра сразу в проекте.
ну фиг с ним с await. Некоторые до сих пор находят для себя yield return. Значит ли это что его нельзя использовать сразу в проекте? И у вас что, есть перечень конструкций, которые можно/нельзя использовать в проекте?
У меня есть обратный пример, когда проект был скован .net 2.0 спустя пару лет после выхода 3.5. Когда я протащил в проект linq (сваял аналог linqbridge), команда сначала отнеслась без этнузиазма, но спустя пару недель начали продуктивно применять.

s>> Я-то его не видел. Я просто реагирую на "10и страничный свитч" и представляю себе такого нормального монстрика с вложенными свитчами, goto и всякой прелестью, что является вполне типично для 2х и более страничных свитчей, выходящих из под топора среднеотраслевых мастеров.

AN>Видите, а мне описанный Вами свитч тяжело представить
AN>Еще не встречал фирмы где goto был бы разрешен.
А я 8 лет проработал в конторе, где его до сих пор предпочитают другим способам переходов.

s>> Думать можно разными путями, а уж недумая —

AN>Это довольно просто.
AN>Предположим, я или скажу
AN>"В темной темнице красны девицы.
AN>Без нитки, без спицы вяжут вязеницы"
AN>или просто покажу картинку.
AN>Что быстрее доведет до цели, о чем это я?


s>> Мне кажется что у нас с вами разные отладчики. Не приходилось сталкиваться с описанными проблемами. И стек мне видно и Step Into входит в куда надо и брекпоинты ставятся, и место инициализации находится хоть средой хоть рефлектором за секунды. Такое ощущение, что вы отлаживаетесь по твердой копии исходников...

AN>Я думаю, что мы просто разные проекты делаем. Вот например, примерчик из здешнего проекта Janus, найдите любым из перечисленных вами способов откуда вызывается данная функция
Если честно — лень даже скачивать.

AN>Теперь поставьте точку останова на функцию AddFolder и покажите на стеке вызов из ProcessMessageKey, да, и потом поставьте уже на данной строке точку останова и при помощи Step Into зайдите в функцию AddFolder.

AN>
             
AN>  methodInfo.Invoke(target, null);
AN>

AN>Просто как некоторый пример, о чем я вёл речь.
На сколько я понимаю в этих корках от апельсинов — проблема вовсе не в выпендреже, а в вызове через MethodInfo.Invoke. Если создать Action из methodInfo, а потом вызвать его, то будет и стек и StepInto, и девченки.
Re[66]: Как не надо писать код
От: AlexNek  
Дата: 30.04.11 14:47
Оценка:
Здравствуйте, samius, Вы писали:

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


s> s>> Реализацию считать глобальной, потому что нет других реализаций? Вот допустим что существует лишь одна реализация IList<T> — List<T>. Можно ли ее считать глобальной?


s> AN>Если она используется локально, то нет. А когда речь идет о доступности с любого места кода, то я пока не могу найти отличий.


s> Обычно под реализацией/имплементацией подразумевают типы, а не экземпляры.

Тогда скажите как перевести например Data Type Implementation?
Вы видимо имеете в виду Interface Implementation?
s> Доступность типа в дотнете определяется не количеством, а модификатороми видимости для него и типов, в которые он вложен. Т.е. непонятно что вы подразумеваете под применением термина глобальность к типу(реализации/имплементации).
Он подразумевается не к типу.

s> Все зкземпляры глобальны в рамках процесса. Т.е. имея его ардес/ссылку на экземпляр, не составит труда обратиться к нему отовсюду.

И откуда нам знать этот адрес или ссылку? И кстати, где то об этой глобальности и идет речь.
Как например обратится к A1, A2?
void f()
{
  int A1=0;
}

public class X
{
   public int A2 = 0;
}

s> s>> Вы же сказали что это будет "глобальная переменная". А это global state, как не реализуй.

s> AN>Можно списать на "ошибки" вербальной коммуникации, я подразумевал под этим несколько другое.


s> И все-таки непонятно, что именно.

Могу привести некоторые примеры глобального: static и singleton
Console.WriteLine();
A.VariableX;
A.GetInstance();

s> s>> Так вот, использование глобального хранилища сервисов вряд ли чем-то лучше, чем использование глобальной переменной для каждого сервиса.


s> AN>Видимо под словом "глобальный" мы подразумеваем различные вещи.


s> Может ссылку дадите?

Не имею понятия на что именно.
s> s>> Давайте воздержимся от обсуждения личностей. Хоть ничего оскорбительного я не увидел, но это не по правилам форума.

s> AN>Я вроде и не собирался этого делать, думаю из контекста было понятно, что я всего лишь рассуждал в каком ключе было бы удобнее вести с Вами беседу. Если вы расценили это как покушение на "privacy", то могу попросить прощения.


s> Нет, обижаться в данном случае не на что. Просто это запрещено правилами.

Я понимаю если сказать, ты дурак/умный/глупый — это вполне должно запрещено.
А если я говорю, ты видимо художник/веселый/грустный — то никак не представляю, что это может быть где то запрещено.

s> AN>Надеюсь, вы не будет отрицать, что нельзя в одинаковом "ключе" говорить со всеми.


s> нет, не буду

Тогда как узнать в каком ключе нужно говорить с человеком? Можно конечно действовать методом проб и ошибок, а можно и просто каким то образом спросить.
s> AN>Если у нас, большая разница в "способе мышления", то мои высказывания будут непонятны Вам, а мне Ваши. Поэтому я обычно стараюсь подстраивать высказывания под способ мышления "собеседника", А его высказывания "переводить" на свой.

s> У нас еще разница в терминологии

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

s> AN>Если нам понадобится вставлять в код, тогда можно и обговорить конкретику.


s> Именно так


s> s>> AN>Если хотите, приведите мне пример конкретного интерфейса и я сделаю из него абстрактный.


s> s>> Занятно будет посмотреть

s> s>>
s> s>> Func<Func<A,B,C>, A, Func<B,C>>
s> s>>


s> AN>Вот подобные вещи и можно назвать "выпендриванием", напомнило старый анекдот про японскую деревообрабатывающую машину и стальное бревно. Подразумевалось как бы "в контексте обсуждаемой темы". Хотя в абстрактном виде это видимо выглядело бы так:

s> AN>"Сделай что то зависящее от A,B,C". Хотя мне и весьма проблематично представить данную строку в описании интерфейса.

s> Это фактически и есть интерфейс метода, выполняющего эмуляцию частичного применения функции. Реализация функции занимает одну строчку, делает она вещи, которые не зависят от A, B и тем более C.

Ну это если придерживаться точки зрения что List<T> не зависит от T.
А если он от него не зависит, то его вполне можно убрать, но убрать то мы его не можем, значит какая то зависимость все же есть?
s> Этот милый прием позволил мне не писать порядка двухсот классов в текущем проекте.
Мне пока сложно представить такую экономию, но я бы предпочел чего попроще, может с не такой большой экономией.

s> В описании интерфейса это могло бы выглядеть так:

s>
s> interface IFoo
s> {
s>     Func<B, C> Apply<A, B, C>(Func<A, B, C> func, A a);
s> }
s>

s> Но сам метод не нуждается в таком интерфейсе, т.к. подменять его особо незачем.

s> s>> AN>Описание обстоятельств можно при которых именно "оттуда", а не просто по цепочке стукнуло?


s> s>> Вы правы, вылетит не именно "оттуда", а при вызове. Как по поводу ThreadAbortException?


s> AN>А оно специфично именно для этой функции? В описании "Console.WriteLine" оно также упомянуто? Мы обсуждаем работу многопотоковых приложений?


s> Да, специфично.

каким образом? Только из-за того что попало "под горячую руку".
s> Нет, не упомянуто.
s> В "однопотоковом" оно тоже может вылететь.
Вот так, просто само по себе?. И что будет являться инициатором?
s> И я даже как-то не уверен, можно ли на .net написать "однопотоковое" приложение. Можно не запускать никаких вспомогательных потоков явно, но это не значит что их не будет .
Про это вроде разговора не было.

s> s>> Так вот, вернувшись к выделению абстракции над WriteLine, это и есть вероятное "академическое решение".


s> AN>Вообще то имелись в виду различные математические алгоритмы. Но даже и в данном случае это было бы "неоправданным усложнением".


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

Да, о двух разных подходах.

s> s>> Безусловно первая. Задерживаюсь на аргументах: в ней меньшая цикломатическая сложность, меньше магических чисел, меньше вероятность ошибиться, проще тестировать.


s> AN>Думаю, какая либо дискуссия тут бесполезна, возможно только статистика бы помогла. Могу только попробовать высказать мои соображения.

s> AN>- 1. Ассоциативное мышление. Я ожидаю увидеть функцию Math.Max в определенном контексте при выборе из двух "одинаковых сущностей". У меня есть еще второй буфер и нужно найти длина которого из них больше? Нет, есть переменная и константа 0. А нафига из них выбирать наибольшее? Ага, имеет смысл только если переменная меньше нуля. Пусть и небольшие, но все же раздумья.

s> я не понял, т.е. если бы там стояло 100 вместо 0-я, то ничего бы не смущало?

Не смущало, если бы там стояло bufferLength2.

s> AN>- 2. "Визуальное восприятие паттернов". (мое "личное" определение, только что придумал ) Когда я смотрю на первый пример я вижу "х = функция от у", когда я вижу

s> AN>второй то "х=0". Т.е для первого нужно пройти часть пути "ассоциативное мышление".
s> AN>Во втором сразу видно три хорошо знакомых "паттерна" (if, х<0, x=0), которые можно сразу же прочитать даже на разговорном языке.

s> (if, x<0, y=10) — тоже можно прочитать на разговорном языке, только здесь два небольших отличия, меняющих смысл кардинально. Но что самое интересное, (max, x, 0) — тоже легко читается.

И что будет понятно немедленно после прочтения, а также и во время?
"Найдем максимум из двух чисел: Х и 0"
Сравните
"Если Х меньше нуля то сделать его равным нулю" — не нужно ничего не думать ни пояснять, уже во время чтения мы получаем четкие команды.

s> AN>- 3. "Примитивизм" — перекликается с 2. Используются настолько простые конструкции, что даже человек не знающий программирования может их понять. А знающий поймет с "закрытыми глазами". В первом же случае нужно знать, что делает функция Max, какие у нее аргументы, почему именно такие аргументы.


s> Давайте теперь прикинием, что же нам больше знеакомо, max или if по жизни? Пример: нужно взять самое большое/красное яблоко из 5и штук, отбросив всякую скромность и деликатность.

Заметьте: Выбираем из пяти одинаковых предметов одно.
Теперь проделайте с детьми следующий эксперимент:
уберите все яблоки со стола и скажите принести самое большое яблоко со стола, имея в виду яблоко нарисованное на скатерти. Будем делать ставки сколько человек принесет скатерть и через какое время?

s> Любой ребенок выберет его бессознательно, не сравнивая при этом каждое с каждым и не оперируя if-ами. А к if-ам вы привыкли, видимо уже в разговоре с компьютером. И так хорошо привыкли, что более высокий уровень общения с компьютером у вас вызывает дискомфорт.

Дело не только в привычке. Вот вы пришли в кино зал, что вы там ожидаете увидеть?
s> Заменяете ли вы if-ами виртуальные вызовы? Если нет, то что вы слышали о виртуальных вызовах до знакомства с программированием?
Не понятно к чему вы клоните.

s> s>> Первая запись является выражением и может быть использована в других выражениях, в то время как вторая — нет.


s> AN>Для меня это не достоинство, а громадный недостаток. Есл потребует то лучше сделать что то типа GetNormalizedBufferLength(int x)


s> Хороший позыв. Но если заменить в тех примерах bufferLenght на x, то смысл функции GetNormalizedBufferLength будет ускользать.


s> Ну и не будете же вы для каждого if-а плодить GetSomething(x)? Мне тут лично max кажется более уместным, т.к. что делает max мы можем догадаться, а что подразумевается под NormalizedBufferLength — тут нужны экстрасенсы.

Ну вот примерчик, какого либо выражения.
x = Max(Max(acd,0) + 2, Min(GetX() + wsa * 3 / 8, GetAbc(1,2,3,4,5)))
И возможной записи
x = Max(GetWeight1(),GetWeight2())
Не знаю как вам, но мне больше по душе второе.
s> Так, если привести постороннего человека, то вряд ли он угадает что под нормализованной длиной буфера подразумевается неотрицательная.
Не нужно догадываться, можно глянуть описание или код при необходимости. Я просто сразу вижу — происходит что то с размером, он каким либо образом меняется. Обычно на первом этапе просмотра этого достаточно.

s> s>> Это субъективное наблюдение


s> AN>Я не проводил научных исследований, но мне лично обратное еще не встречалось.


s> Мне встречалось.

Именно в качестве преобладающего использования или просто попадалось?

s> s>> Случай, когда объяснятель и объясняемый близки к средней температуре по больнице, не интересен. Они друг дружке что-то принципиально новое вряд ли объяснят.


s> AN>Ну отчего же? Вы разрабатывали подсистему А, я подсистему Б. Объяснения друг другу будут весьма полезны. А объяснять работу подсистемы А дежурному сантехнику не будет иметь большого смысла.


s> Вы не пытались объяснить смысл алгоритма Дейкстры (например) программисту, совершенно незнакомому с теорией графов?

Т.е этот случай должен быть неинтересен, так как "Они друг дружке что-то принципиально новое вряд ли объяснят."
s> s>> По поводу того же await — мне будет проще почитать в паре-тройке мест, что он значит и потом понимать его в 20и местах использования, чем в 20 местах вчитываться в нагромождение очевидных конструкций.

s> AN>Я привел только пример, что было понятно, что я имею в виду. Но с другой стороны, эти 20 мест уже могут жить в коде лет этак 5 и каждый знает их почти наизусть.

s> AN>Как я уже говорил, конкретная ситуация может быть самая разная. Да и включение чего
s> AN>то нового должно быть "официально одобрено". Если "я нашел" этот await вчера, то это не значит, что я его имею право его использовать уже завтра сразу в проекте.

s> ну фиг с ним с await. Некоторые до сих пор находят для себя yield return. Значит ли это что его нельзя использовать сразу в проекте? И у вас что, есть перечень конструкций, которые можно/нельзя использовать в проекте?

Да есть, и довольно обширный (как раз все что не попало в стандарт 2.0). Изменить довольно затруднительно, по различным причинам.
s> У меня есть обратный пример, когда проект был скован .net 2.0 спустя пару лет после выхода 3.5. Когда я протащил в проект linq (сваял аналог linqbridge), команда сначала отнеслась без этнузиазма, но спустя пару недель начали продуктивно применять.
Вполне могу это понять, но для этого нужно вначале убедить большинство команды в ее полезности и изменить правила. Иначе получится полный бардак, я хочу добавить А, другой Б, третий С и так каждый месяц.
s> s>> Я-то его не видел. Я просто реагирую на "10и страничный свитч" и представляю себе такого нормального монстрика с вложенными свитчами, goto и всякой прелестью, что является вполне типично для 2х и более страничных свитчей, выходящих из под топора среднеотраслевых мастеров.

s> AN>Видите, а мне описанный Вами свитч тяжело представить

s> AN>Еще не встречал фирмы где goto был бы разрешен.

s> А я 8 лет проработал в конторе, где его до сих пор предпочитают другим способам переходов.

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

s> s>> Думать можно разными путями, а уж недумая —


s> AN>Это довольно просто.

s> AN>Предположим, я или скажу
s> AN>"В темной темнице красны девицы.
s> AN>Без нитки, без спицы вяжут вязеницы"
s> AN>или просто покажу картинку.
s> AN>Что быстрее доведет до цели, о чем это я?

s>

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

Так что быстрее? Думать или не думать


s> s>> Мне кажется что у нас с вами разные отладчики. Не приходилось сталкиваться с описанными проблемами. И стек мне видно и Step Into входит в куда надо и брекпоинты ставятся, и место инициализации находится хоть средой хоть рефлектором за секунды. Такое ощущение, что вы отлаживаетесь по твердой копии исходников...


s> AN>Я думаю, что мы просто разные проекты делаем. Вот например, примерчик из здешнего проекта Janus, найдите любым из перечисленных вами способов откуда вызывается данная функция


s> Если честно — лень даже скачивать.

А это и не требовалось, просто как пример знакомого открытого проекта.
Кстати, рекомендую просто глянуть сюда
Никогда раньше не пользовался онлайн клиентами, но оказалось удобнейшей штукой.

s> AN>Теперь поставьте точку останова на функцию AddFolder и покажите на стеке вызов из ProcessMessageKey, да, и потом поставьте уже на данной строке точку останова и при помощи Step Into зайдите в функцию AddFolder.

s> AN>
s> AN>  methodInfo.Invoke(target, null);
s> AN>

s> AN>Просто как некоторый пример, о чем я вёл речь.

s> На сколько я понимаю в этих корках от апельсинов — проблема вовсе не в выпендреже, а в вызове через MethodInfo.Invoke. Если создать Action из methodInfo, а потом вызвать его, то будет и стек и StepInto, и девченки.

А каким образом "убрать" Invoke или если я запускаю Thread в одном месте, а он вызывает функцию из другого места?
avalon 1.0rc3 rev 419, zlib 1.2.3
Re[67]: Как не надо писать код
От: samius Япония http://sams-tricks.blogspot.com
Дата: 30.04.11 20:32
Оценка: +1
Здравствуйте, AlexNek, Вы писали:

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


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


s>> s>> Реализацию считать глобальной, потому что нет других реализаций? Вот допустим что существует лишь одна реализация IList<T> — List<T>. Можно ли ее считать глобальной?


s>> AN>Если она используется локально, то нет. А когда речь идет о доступности с любого места кода, то я пока не могу найти отличий.


s>> Обычно под реализацией/имплементацией подразумевают типы, а не экземпляры.

AN>Тогда скажите как перевести например Data Type Implementation?
Реализация типов данных
AN>Вы видимо имеете в виду Interface Implementation?
Нет, я не понимаю, причем глобальность и число реализаций?

s>> Доступность типа в дотнете определяется не количеством, а модификатороми видимости для него и типов, в которые он вложен. Т.е. непонятно что вы подразумеваете под применением термина глобальность к типу(реализации/имплементации).

AN>Он подразумевается не к типу.
А к чему?

s>> Все зкземпляры глобальны в рамках процесса. Т.е. имея его ардес/ссылку на экземпляр, не составит труда обратиться к нему отовсюду.

AN>И откуда нам знать этот адрес или ссылку? И кстати, где то об этой глобальности и идет речь.
Обычно передается по стеку. Но можно сохранить в глобальной переменной.
AN>Как например обратится к A1, A2?
AN>
void f()
AN>{
AN>  int A1=0;
AN>}
AN>

Передайте адрес A1 тому, кто будет к переменной обращаться.
AN>
public class X
AN>{
AN>   public int A2 = 0;
AN>}
AN>

аналогично.

s>> s>> Вы же сказали что это будет "глобальная переменная". А это global state, как не реализуй.


s>> AN>Можно списать на "ошибки" вербальной коммуникации, я подразумевал под этим несколько другое.


s>> И все-таки непонятно, что именно.

AN>Могу привести некоторые примеры глобального: static и singleton
AN>Console.WriteLine();
AN>A.VariableX;
AN>A.GetInstance();
Дык это global state, или убедите меня в обратном.

s>> s>> Так вот, использование глобального хранилища сервисов вряд ли чем-то лучше, чем использование глобальной переменной для каждого сервиса.


s>> Может ссылку дадите?

AN>Не имею понятия на что именно.
На то, что вы подразумеваете под "глобальным"

AN>А если я говорю, ты видимо художник/веселый/грустный — то никак не представляю, что это может быть где то запрещено.

Пардон, перепутал с каким-то другим форумом. Здесь можно.

AN>Тогда как узнать в каком ключе нужно говорить с человеком? Можно конечно действовать методом проб и ошибок, а можно и просто каким то образом спросить.

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

s>> У нас еще разница в терминологии

AN>Я это тоже заметил Просто мы находимся в различных средах.
Уверен, что многие термины, которые я использую, сообщество rsdn в среднем воспринимает схожим образом. Если что-то я не стесняюсь уточнять значения. Например, на википедии (но не на русской).

s>> Это фактически и есть интерфейс метода, выполняющего эмуляцию частичного применения функции. Реализация функции занимает одну строчку, делает она вещи, которые не зависят от A, B и тем более C.

AN>Ну это если придерживаться точки зрения что List<T> не зависит от T.
А есть другая точнка зрения?
AN>А если он от него не зависит, то его вполне можно убрать, но убрать то мы его не можем, значит какая то зависимость все же есть?
T — это тип generic параметра. От типа параметра свойства List<T> не зависят и это верно. Вы же тут говорите не о зависимости от типа T, а о зависимости от наличия generic параметра. Т.е. как-бы перескочили на другую зависимость. Это как если я перейду на зависимость List<T> от "i". Если ее убрать, будет Lst<T>, значит зависимость от "i" имеется
s>> Этот милый прием позволил мне не писать порядка двухсот классов в текущем проекте.
AN>Мне пока сложно представить такую экономию, но я бы предпочел чего попроще, может с не такой большой экономией.
Ваше право, но мне сложно представить что-то проще.

s>> Да, специфично.

AN>каким образом? Только из-за того что попало "под горячую руку".
Тем образом, что ThreadAbort может выскакивать практически откуда угодно.
s>> Нет, не упомянуто.
s>> В "однопотоковом" оно тоже может вылететь.
AN>Вот так, просто само по себе?. И что будет являться инициатором?
Что-нибудь, что решит кончить ваш поток. Но если вы хорошо погуглите, то увидите кучу случаев, когда оно вылетает во вполне невинных сценариях, например
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://someurl.com/");
HttpWebResponse resp = req.GetResponse();


s>> И я даже как-то не уверен, можно ли на .net написать "однопотоковое" приложение. Можно не запускать никаких вспомогательных потоков явно, но это не значит что их не будет .

AN>Про это вроде разговора не было.
Не было, но вы спросили, обсуждаем ли мы работу "многопотоковых приложений". А я отвечаю, что в дотнете таковым является практически любое приложение (наверняка любое).

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

AN>Да, о двух разных подходах.
Т.е. варианта, кроме забивания на исключения, не будет?

s>> я не понял, т.е. если бы там стояло 100 вместо 0-я, то ничего бы не смущало?

AN>Не смущало, если бы там стояло bufferLength2.
var bufferLength2 = 0;
bufferLength = Math.Max(bufferLength, bufferLength2); // ниужели так бы не смущало?


s>> (if, x<0, y=10) — тоже можно прочитать на разговорном языке, только здесь два небольших отличия, меняющих смысл кардинально. Но что самое интересное, (max, x, 0) — тоже легко читается.

AN>И что будет понятно немедленно после прочтения, а также и во время?
AN>"Найдем максимум из двух чисел: Х и 0"
Да, а что тут надо еще понять?
AN>Сравните
AN>"Если Х меньше нуля то сделать его равным нулю" — не нужно ничего не думать ни пояснять, уже во время чтения мы получаем четкие команды.
Вы разве сами не понимаете разницы? В одном случае описано некоторое свойство результата. В другом — команды к получению результата. Для того что бы понять, что будет в результате, вы предпочитаете вместо описания результата описание команд к его получению. Давайте усложним задачу и перейдем от объявления max к объявлению qsort/sin/bind. Вам все еще будут понятнее наборы инструкций по достижению результата?

s>> Давайте теперь прикинием, что же нам больше знеакомо, max или if по жизни? Пример: нужно взять самое большое/красное яблоко из 5и штук, отбросив всякую скромность и деликатность.

AN>Заметьте: Выбираем из пяти одинаковых предметов одно.
Кто сказал что из одинаковых?

AN>Теперь проделайте с детьми следующий эксперимент:

AN>уберите все яблоки со стола и скажите принести самое большое яблоко со стола, имея в виду яблоко нарисованное на скатерти. Будем делать ставки сколько человек принесет скатерть и через какое время?
Не понял, куда вас унесло в поисках аналогии.

s>> Любой ребенок выберет его бессознательно, не сравнивая при этом каждое с каждым и не оперируя if-ами. А к if-ам вы привыкли, видимо уже в разговоре с компьютером. И так хорошо привыкли, что более высокий уровень общения с компьютером у вас вызывает дискомфорт.

AN>Дело не только в привычке. Вот вы пришли в кино зал, что вы там ожидаете увидеть?
кресла, экран, кино, людей. Но я не понимаю к чему вопрос. Когда вы передаете в max два числа, что вы ожидаете от этих чисел, почему нельзя в max подать длину буфера и 0? Там же не сравниваются вес со скоростью, в конце концов
s>> Заменяете ли вы if-ами виртуальные вызовы? Если нет, то что вы слышали о виртуальных вызовах до знакомства с программированием?
AN>Не понятно к чему вы клоните.
Я клоню к повышению абстракции. Работа программиста связана со множеством вещей, которые не знают не знакомые с программированием. Отказываетесь ли вы от этих вещей в пользу вещей, знакомых не знакомым с программированием?

s>> Ну и не будете же вы для каждого if-а плодить GetSomething(x)? Мне тут лично max кажется более уместным, т.к. что делает max мы можем догадаться, а что подразумевается под NormalizedBufferLength — тут нужны экстрасенсы.

AN>Ну вот примерчик, какого либо выражения.
AN>x = Max(Max(acd,0) + 2, Min(GetX() + wsa * 3 / 8, GetAbc(1,2,3,4,5)))
AN>И возможной записи
AN>x = Max(GetWeight1(),GetWeight2())
AN>Не знаю как вам, но мне больше по душе второе.
Вы утрируете. Возможность использования в качестве выражения не подразумевает само по себе необходимость использования только такого варианта. У if-а такой возможности (в C#) нет. И это определенно недостаток.
Вот мой пример:
var maximum = max(a, max(b, max(c, d)));

свой с if-ами можете не приводить.

s>> Так, если привести постороннего человека, то вряд ли он угадает что под нормализованной длиной буфера подразумевается неотрицательная.

AN>Не нужно догадываться, можно глянуть описание или код при необходимости. Я просто сразу вижу — происходит что то с размером, он каким либо образом меняется. Обычно на первом этапе просмотра этого достаточно.
Ниужели это будет понятнее чем max(buffLength, 0)?

s>> Мне встречалось.

AN>Именно в качестве преобладающего использования или просто попадалось?
Достаточно часто встречался с тем, что автор идеи не был в состоянии ее доступно объяснить.

s>> Вы не пытались объяснить смысл алгоритма Дейкстры (например) программисту, совершенно незнакомому с теорией графов?

AN>Т.е этот случай должен быть неинтересен, так как "Они друг дружке что-то принципиально новое вряд ли объяснят."
А что тут принципиально нового? пол века минуло алгоритму.

s>> ну фиг с ним с await. Некоторые до сих пор находят для себя yield return. Значит ли это что его нельзя использовать сразу в проекте? И у вас что, есть перечень конструкций, которые можно/нельзя использовать в проекте?

AN>Да есть, и довольно обширный (как раз все что не попало в стандарт 2.0). Изменить довольно затруднительно, по различным причинам.
Надеюсь, что причины тому разумные.

s>> У меня есть обратный пример, когда проект был скован .net 2.0 спустя пару лет после выхода 3.5. Когда я протащил в проект linq (сваял аналог linqbridge), команда сначала отнеслась без этнузиазма, но спустя пару недель начали продуктивно применять.

AN>Вполне могу это понять, но для этого нужно вначале убедить большинство команды в ее полезности и изменить правила. Иначе получится полный бардак, я хочу добавить А, другой Б, третий С и так каждый месяц.
Хочу — это не то что движет программистами. Обычно ими движет "не хочу": Не хочу делать эту хрень, когда ее можно не делать при схожем результате.

s>> А я 8 лет проработал в конторе, где его до сих пор предпочитают другим способам переходов.

AN>Ну если бы я занимался исключительно программированием железа, то вероятно был бы в похожей ситуации. "Железки" я просто не считаю (там играют по другим законам). Видимо более правильно было бы ограничить неиспользование гото определенной средой "моего обитания" в фирме.
Фирма железа не кует, просто в период пика интереса к программированию ведущих специалистов был популярен Фортран.

s>> s>> Думать можно разными путями, а уж недумая —


s>> AN>Это довольно просто.

s>> AN>Предположим, я или скажу
s>> AN>"В темной темнице красны девицы.
s>> AN>Без нитки, без спицы вяжут вязеницы"
s>> AN>или просто покажу картинку.
s>> AN>Что быстрее доведет до цели, о чем это я?

s>>

AN>Получается даже немного думая тяжело сразу понять ответ, а вот картинка
AN>
AN>Так что быстрее? Думать или не думать
Быстрее думать. Но вы изволите хитрить, т.к. сравниваете алегорическое описание с визуальным образом, вместо того что бы сравнивать декларативное описание с императивным.

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

Пытался раза 3. Не судьба.

s>> AN>
s>> AN>  methodInfo.Invoke(target, null);
s>> AN>


s>> На сколько я понимаю в этих корках от апельсинов — проблема вовсе не в выпендреже, а в вызове через MethodInfo.Invoke. Если создать Action из methodInfo, а потом вызвать его, то будет и стек и StepInto, и девченки.

AN>А каким образом "убрать" Invoke или если я запускаю Thread в одном месте, а он вызывает функцию из другого места?
Какого другого места? Причем тут Thread?
Вы не путаете случаем MethodInfo.Invoke с Control.Invoke?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.