Как-то где-то читал пространные философские рассуждения какого то "умного" гуру о том, что using-и в C# (те что открывают пространства имен) нужно держать в "чистом теле", т.е. заботиться о них, вычищать ненужные, сортировать по алфавиту, и т.п.
Аргументировалось это тем, что мол тру-программисты начинают чтение кода именно с них и из них они получают представление о том, какие типы используются и т.п.
Но на практике это все булшит. Реальный C#-программист пользуется Решарпером который автоматом вставляет/удаляет/сортирует using-и, а на их состав не смотрит вообще, за исключением случаев когда встречаются конфликты имен.
Лично я вообще сворачиваю using-и с помощью фолдинга (колапсед-регион в Студии), а просмотр кода в файле начинаю с описания класса (который, обычно, один на файл).
В Васике даже есть возможность засунуть стандартные пространства имен в специальный файл и не дублировать их в каждом файле проекта.
Собственно, подумалось, что идея открытия пространств имен порочна сама по себе. Намного проще и удобнее исходить из предположения, что все имена доступны глобально, и воздействовать на их видимость только в случае конфликта имен в конкретном файле.
Другими словами предлагаю рассмотреть концепцию закрытия пространств имен, сокрытия ненужных символов и разрешения неоднозначности между конфликтующими именами.
В языке с сильным выводом типов многие неоднозначности могут вообще разрешаться в автомате, подсистемой вывода типов. Если оная не справляется, она выдает программисту сообщение об ошибке в котором говорится о том, что два или более символа конфликтуют между собой. Далее программист может сделать одно из двух:
1. Закрыть пространство имен (или тип) содержащий ненужные символы.
2. Определить какой из типов имеется в виду указав полностью или частично квалифицированное имя.
3. Введя псевдоним с указанием на какой из символов будет разрешаться имя.
По моему такой подход может серьезно упростить жизнь программисту.
Еще одной идеей видится пренос юсингов из отдельных файлов с кодов в описание проекта. Вместо того чтобы по 100500 раз описывать using-и в каждом файле имеет смысл указать какие из пространств имен импортируются из библиотеки. Такой подход за одно позволил бы лучше контролировать использование типов из внешних сборок.
Понятно, что эти подходы не удастся реализовать в имеющихся языках. Но при проектировании новых языков он был бы очень полезен.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>1. Закрыть пространство имен (или тип) содержащий ненужные символы.
К примеру, есть у нас класс Utils, на который куча исходников ссылается. Потом мы добавляем к проекту библиотеку, которая также содержит Utils. Эта библиотека может быть нужна всего-то в одном исходнике, а лопатить придётся кучу.
Здравствуйте, dimgel, Вы писали:
D>К примеру, есть у нас класс Utils, на который куча исходников ссылается. Потом мы добавляем к проекту библиотеку, которая также содержит Utils. Эта библиотека может быть нужна всего-то в одном исходнике, а лопатить придётся кучу.
Имена не так уж часто пересекаются на 100%. Так что не придется. А вот доступ к функциям из Utils-ов нужет очень много где.
Если же у нас в проекте два типа или метода с одним именем, то это уже проблема требующая какого-то решения. Иначе трах с ними будет повсеместный. Да и читать код когда не знаешь, что за тип в данном месте имеется в виду, тоже неудобно.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, dimgel, Вы писали:
D>К примеру, есть у нас класс Utils, на который куча исходников ссылается. Потом мы добавляем к проекту библиотеку, которая также содержит Utils. Эта библиотека может быть нужна всего-то в одном исходнике, а лопатить придётся кучу.
Да, возможно я не очень хорошо объяснил. Наш гипотетический язык умеет различать перегрузки. Например, если в одном модуле Utils у нас есть функция Convert(x : int) : string, а в другом Convert(x : double) : string, то вывод типов сам поймет из какого модуля вызывается функция. Проблемы будет только, если в коде будет создаваться экземпляр класса Utils или будут два идентичных по сигнатуре и имени метода внутри этих классов. Но это уже бардак который нужно устранять, а не разруливать по месту.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Если же у нас в проекте два типа или метода с одним именем, то это уже проблема требующая какого-то решения. Иначе трах с ними будет повсеместный. Да и читать код когда не знаешь, что за тип в данном месте имеется в виду, тоже неудобно.
Ну в общем да, я и сам уже понял, что речь надо вести не про Utils, а про Utils.method().
Здравствуйте, VladD2, Вы писали:
VD>Но на практике это все булшит. Реальный C#-программист пользуется Решарпером который автоматом вставляет/удаляет/сортирует using-и, а на их состав не смотрит вообще, за исключением случаев когда встречаются конфликты имен. VD>Собственно, подумалось, что идея открытия пространств имен порочна сама по себе. Намного проще и удобнее исходить из предположения, что все имена доступны глобально, и воздействовать на их видимость только в случае конфликта имен в конкретном файле.
VD>Другими словами предлагаю рассмотреть концепцию закрытия пространств имен, сокрытия ненужных символов и разрешения неоднозначности между конфликтующими именами.
VD>Еще одной идеей видится пренос юсингов из отдельных файлов с кодов в описание проекта. Вместо того чтобы по 100500 раз описывать using-и в каждом файле имеет смысл указать какие из пространств имен импортируются из библиотеки. Такой подход за одно позволил бы лучше контролировать использование типов из внешних сборок.
Мне эта идея импонирует. Механизм using в C# выглядит каким-то полупродуманным.
То есть ни зависимости между неймспейсами по нему определить невозможно (потому что в коде могут быть прямые ссылки), ни зависимости между сборками.
Опять же — никаких гарантий консистентности между алиасами, использованными в разных файлах проекта.
С учётом того, что зависимости по сборкам всё равно настраиваются на уровне проекта, то я бы, наверое, предпочёл юсинги видеть где-то там же.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, VladD2, Вы писали:
VD>Имена не так уж часто пересекаются на 100%. Так что не придется. А вот доступ к функциям из Utils-ов нужет очень много где.
Вообще то очень часто. Чем больше проект, тем больше однофамильцев. Вот есть в проекте 50-100 модулей. Тех же Utils будет встречаться штук 10-20.
Отдельно замечу, что данная идея НЕ противоречит импорту не только классов, но и методов. Временами я это дело юзаю — несмотря на то, что эта фича Идеей не поддерживается, так что приходится прописывать ручками (да и вообще я, как честный идеалист, частенько вылизываю импорты вручную): import blablabla.MacroUtil0.assertx (таки заюзал я эту гадость, выводящую "a.==(0)" вместо "a == 0", не дождался).
Здравствуйте, VladD2, Вы писали:
VD>Другими словами предлагаю рассмотреть концепцию закрытия пространств имен, сокрытия ненужных символов и разрешения неоднозначности между конфликтующими именами.
Мне кажется здесь поможет что-то вроде области видимости с открытостью выше чем public. Это можно сделать практически не ломая C#. Все, что для этого нужно — экспорт основных экспортируемых типов модуля в глобальное пространство имен. Подключая модуль к проекту, мы получаем все, что от него нужно в большинстве случаев, без лишних юзингов.
VD>Но на практике это все булшит. Реальный C#-программист пользуется Решарпером который автоматом вставляет/удаляет/сортирует using-и, а на их состав не смотрит вообще, за исключением случаев когда встречаются конфликты имен.
Ну то есть C# окончательно превратился в Java, в которой без IDE в жизни не разберешься, что откуда берется.
Здравствуйте, Mamut, Вы писали:
M>Ну то есть C# окончательно превратился в Java, в которой без IDE в жизни не разберешься, что откуда берется.
1. В java это просто следствие огромного количества разнообразного кода, написанного под платформу. Что само по себе есть гуд.
2. А часто приходится разбираться без IDE?
Когда-то давно в языках программирования не было модификаторов доступа. Всё было открыто. Но в итоге пришли к пониманию, что ничего лишнего не должно выставляться наружу. Причём по умолчанию сейчас всегда private. Твоя идея в какой-то мере возврат к прошлому.
Или, например, в современных языках прослеживается тенденция делать типы по-умолчанию иммутабельными (то есть закрытыми от изменения). А если хочешь мутабельность — объявляй это явно.
Всё-таки логичнее явно открывать, чем явно закрывать. Хотя идея с автоматическим определением конфликтов заставляет задуматься. Может ты и прав. Современные IDE меняют старые правила.
VD> возможность засунуть стандартные пространства имен в специальный файл и не дублировать их в каждом файле проекта.
Это с одной стороны логично. Но с другой — в крупном проекте не будет ли слишком сложно разбираться в одном таком огромном файле? Но, опять же, современные средства разработки рулят, да.
Здравствуйте, koodeer, Вы писали:
K>Причём по умолчанию сейчас всегда private. Твоя идея в какой-то мере возврат к прошлому.
В скале по умолчанию public, а ещё есть case-классы для алгебраических типов. И жавовские checked exceptions они убрали.
Вообще, мне всё это напоминает мой собственный путь: дорвавшись до языка со столь мощной системой типов, я начал закручивать гайки по максимуму где надо и где не надо, иногда в ущерб удобству. Со временем начинает приходить понимание, что кое-где всё-таки не надо. (Но классы и traits тем не менее до сих пор наследую из NotNull! )
M>>Ну то есть C# окончательно превратился в Java, в которой без IDE в жизни не разберешься, что откуда берется.
D>1. В java это просто следствие огромного количества разнообразного кода, написанного под платформу. Что само по себе есть гуд. D>2. А часто приходится разбираться без IDE?
Достаточно часто код можно просто просмотреть через веб-интерфейс, например (ну типа GitHub'а или внутреннего Stash'а какого-нибудь). Например.
Во-вторых, что плохого в том, чтобы разобраться в коде без IDE? С каких пор IDE стало обязательным условием для ЯП?
Здравствуйте, Mamut, Вы писали:
M>Достаточно часто код можно просто просмотреть через веб-интерфейс, например (ну типа GitHub'а или внутреннего Stash'а какого-нибудь). Например.
В гитхабе смотреть по месту имеет смысл разве что небольшие куски, в которых не запутаешься. А что-то серьёзное — всё равно скачиваешь проект и настраиваешь IDE. Лично я жму на идентификаторах ctrl+click (goto definition) на порядок чаще, чем даже смотрю в api docs.
M>Во-вторых, что плохого в том, чтобы разобраться в коде без IDE? С каких пор IDE стало обязательным условием для ЯП?
Ты ещё скажи, с каких пор для ЯП стал обязательным условием компилятор. Бейсик, помнится, обходился.
Вопрос в сложности софта. И IDE — один из инструментов, в которые эта сложность вытесняется. Для "hello world" IDE, разумеется, не нужен. Там и веб-интерфейса хватит, ага.
Здравствуйте, Ikemefula, Вы писали:
VD>>Имена не так уж часто пересекаются на 100%. Так что не придется. А вот доступ к функциям из Utils-ов нужет очень много где.
I>Вообще то очень часто. Чем больше проект, тем больше однофамильцев. Вот есть в проекте 50-100 модулей. Тех же Utils будет встречаться штук 10-20.
У меня щас 59 модулей.
$ find -name "*Util*.scala" | wc -l
22
Хм. До хрена, и правда. Но они называются все по-разному, descriptive. Ну, кроме локальных для модулей, которые и не модули вовсе, а отдельные приложения, выполняющиеся во время сборки (т.е. не используемые в качестве зависимостей), — там просто Util.
В проектах на Java очень много конфликтов имён. Часто я пишу идентификатор, жму Ctrl+Space и получаю 3-5 вариантов из разных пакетов. Поэтому идея импортировать всё, на мой взгляд, не практична.
Сортировать импорты нужно. Бывают случаи, когда я смотрю исходники не в IDE. Хорошо упорядоченные импорты сильно помогают. Впрочем согласен, что с этой задачей IDE прекрасно справляется, главное — импортировать конкретные символы, а не целые пакеты.
Здравствуйте, vsb, Вы писали:
vsb>В проектах на Java очень много конфликтов имён. Часто я пишу идентификатор, жму Ctrl+Space и получаю 3-5 вариантов из разных пакетов. Поэтому идея импортировать всё, на мой взгляд, не практична.
Удалил свой предыдущий ответ. Влад уже отвечал мне на эту же претензию: речь не о имени класса, а об имени метода, тут совпадений будет гораздо меньше. А ещё речь о том, что компилятор с помощью вывода типов сузит количество вариантов до одного, т.к. ситуаций, когда и имена классов, и имена методов, и сигнатуры методов совпадают — исчезающе мало.
Неудобно только будет с autocompletion: вводишь имя — и всё равно видишь все эти 3-5 вариантов, т.к. пока что у компилятора/IDE никакой доп. информации нет.
Здравствуйте, VladD2, Вы писали:
VD>Собственно, подумалось, что идея открытия пространств имен порочна сама по себе. Намного проще и удобнее исходить из предположения, что все имена доступны глобально, и воздействовать на их видимость только в случае конфликта имен в конкретном файле.
Я, может не совсем в тему, расскажу, как у нас в DSL реализован пространства имен.
У нас проект состоит из набора модулей. Каждый модуль указывает список модулей, от которых он непосредственно зависит.
Модуль полностью содержится в некотором пространстве имен. Поиск имени идет сначала в текущем пространстве имен, затем во всех остальных, но только среди модулей, от которых текущий модуль зависит (либо непосредственно, либо через другие модули). Если находится несколько вариантов, то надо явно квалифицировать имя. Есть еще фича с указанием приоритета среди пространств имен, но она, конечно, костыльная, и делалась в основном для обратной совместимости (кстати надо бы ее убрать, и добавить что-нибудь вроде упомянутых псевдонимов).
Но у нас кроме функций с оверлоадингом такой же алгоритм поиска используется для других сущностей вроде классов, форм, таблиц, у которых важно лишь имя. А вот если бы нужно было действительно работать только с функциями, то тут можно было бы искать глобально (правда, не в нашем конкретном случае, нам иерархия модулей все равно нужна), так как действительно довольно редко на практике бывают фунции с одинаковыми именем и сигнатурой, но в разных пространствах имен. Так что идея мне кажется вполне рабочей, и, вроде бы, поддержку этого в IDE организовать несложно.
Представим такую ситуацию. В проекте используются две библиотеки, в которых есть два класса с одинаковым именем. Мы используем методы с разной сигнатурой, и вывод типов может определить класс какой библиотеки используется каждый раз. Теоретически, при одновременном обновлении сразу обеих этих библиотек может получиться так, что сигнатуры поменяются и вызываться будут методы не тех классов что нужно. И никаких ошибок компилятора. Случай конечно крайне гипотетический, но все же.
Здравствуйте, VladD2, Вы писали:
VD>Собственно, подумалось, что идея открытия пространств имен порочна сама по себе. Намного проще и удобнее исходить из предположения, что все имена доступны глобально, и воздействовать на их видимость только в случае конфликта имен в конкретном файле.
То есть в BCL добавляется новый класс, и у непредсказуемого количества программистов перестает компилироваться код, потому что у них уже есть класс с таким же именем, в котором есть метод с такой же сигнатурой.
Это удобно.
Здравствуйте, HrorH, Вы писали:
HH>То есть в BCL добавляется новый класс, и у непредсказуемого количества программистов перестает компилироваться код, потому что у них уже есть класс с таким же именем, в котором есть метод с такой же сигнатурой. HH>Это удобно.
Есть куча гипотетических проблем не встречающихся на практике. Эта одна из них.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, ZevS, Вы писали:
ZS>Представим такую ситуацию. В проекте используются две библиотеки, в которых есть два класса с одинаковым именем. Мы используем методы с разной сигнатурой, и вывод типов может определить класс какой библиотеки используется каждый раз. Теоретически, при одновременном обновлении сразу обеих этих библиотек может получиться так, что сигнатуры поменяются и вызываться будут методы не тех классов что нужно. И никаких ошибок компилятора. Случай конечно крайне гипотетический, но все же.
Это очень теоретически. Сейчас эта теоретическая возможность тоже присутствует. Но мир живет и земля не останавливается.
Вообще, если мы имеем одинаковый по названию метод, в одинаковом классе и с одинаковым названием и типами параметров, то это должны быть аналогичные методы. Или что-то не так в этом мире.
Конфликты конечно возможны. И они будут встречаться. Но их разгуливание куда менее затратная задача нежели каждодневная борьба с искусственно созданной проблемой.
Возможно, нужно придумать что-то что предотвращало бы случайные подмены. Я же не предлагаю готовое решение. Я просто озвучил свои мысли.
При использовании Решарпера человек уже не думает о том, что он импортирует. Он просто комплитит и юсинги меняются автоматически. Никаких проблем на практике не возникает. Так какую проблему тогда решают эти юсинги?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Есть куча гипотетических проблем не встречающихся на практике. Эта одна из них.
Так эта проблема не встречается сейчас именно благодаря using.
Простой пример: у скольких программистов до выхода Net 4.0 в коде мог быть класс Task с методом public void Start() ?
Это сотни проектов.
Работающий код становится неработающим из-за появления другого кода, не имеющего к нему никакого отношения.
Здравствуйте, VladD2, Вы писали:
VD>Конфликты конечно возможны. И они будут встречаться. Но их разгуливание куда менее затратная задача нежели каждодневная борьба с искусственно созданной проблемой.
Это как сказать. Я тут пару дней назад изрядно потрахался, чтобы корректно проапгрейдить в проекте сайта Web-стек. Как раз из-за конфликтов. И это на довольно неболшьшом проекте и при наличии юсингов. А если бы все было открыто?
... << RSDN@Home 1.2.0 alpha 5 rev. 100 on Windows 8 6.2.9200.0>>
Здравствуйте, HrorH, Вы писали:
HH>Так эта проблема не встречается сейчас именно благодаря using. HH>Простой пример: у скольких программистов до выхода Net 4.0 в коде мог быть класс Task с методом public void Start() ?
С чего бы год должен перестать работать?
Ты же не создашь в точности такой же класс с точно такими же конструкторами и методами? А раз так, то умный компилятор сможет выбрать нужную версию.
В Шарпе неоднозначности частенько возникают только потому, что там нет вывода типов или он слабый. Но можно создать такой вывод типов который будет отличать любые неодинаковые типы/функции.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, AndrewVK, Вы писали:
AVK>Это как сказать. Я тут пару дней назад изрядно потрахался, чтобы корректно проапгрейдить в проекте сайта Web-стек. Как раз из-за конфликтов. И это на довольно неболшьшом проекте и при наличии юсингов. А если бы все было открыто?
Ну, то есть юсинги тебе никак не помогли в этом? Тогда в чем их ценность?
Может разумнее придумать удобную систему разруливания конфликтов вместо них?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Есть куча гипотетических проблем не встречающихся на практике. Эта одна из них.
На практике встречаются ситуации, когда компания РогаИКопыта пилит некую библиотеку.
А через пять лет кусок этой библиотеки успешно выкупается другим вендором и внезапно переезжает в другой неймспейс.
Побочным эффектом является двойной комплект классов в депендах твоего проекта
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>На практике встречаются ситуации, когда компания РогаИКопыта пилит некую библиотеку. S>А через пять лет кусок этой библиотеки успешно выкупается другим вендором и внезапно переезжает в другой неймспейс. S>Побочным эффектом является двойной комплект классов в депендах твоего проекта
Дублирование одного и того же — это реальная проблема. Особенно когда это две версии одного и того же. Для разруливания таких ситуаций нужно придумывать какие-то решения.
Собственно я пока законченного решения не имею. Тему создал как раз для обсуждения с целью уточнения решения. Предлагаю подумать над решением возникающих проблем вместе.
Проблема дублирующихся классов досаждает и в языках с юсингами. Так что ей все равно стоит найти достойное решение.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Ну, то есть юсинги тебе никак не помогли в этом?
Они не помогли, потому что лятский кодогенератор вьюх втыкает свои юсинги неявно, вот куча вьюх и осыпалась, потому что типы из МСных свежих либ конфликтовали с типами из проекта сайта. Т.е., фактически, получилась твоя глобальная видимость.
VD>Может разумнее придумать удобную систему разруливания конфликтов вместо них?
А что ты там разрулишь, если, к примеру, у МС появился класс Gravatar с методом GetUrl, а IT в свое время тоже написал класс Gravatar с методом GetUrl? Там даже по типам и именам параметров получилось пересечение. Единственное что тут можно сделать — вывалить ошибку о конфликте.
... << RSDN@Home 1.2.0 alpha 5 rev. 100 on Windows 8 6.2.9200.0>>
Здравствуйте, Sinclair, Вы писали:
S>На практике встречаются ситуации, когда компания РогаИКопыта пилит некую библиотеку. S>А через пять лет кусок этой библиотеки успешно выкупается другим вендором и внезапно переезжает в другой неймспейс.
Ну так мы все знаем чем это заканчивается — у публичных типов появляются префиксы — QWidget, TRxPanel и т.п.
... << RSDN@Home 1.2.0 alpha 5 rev. 100 on Windows 8 6.2.9200.0>>
Здравствуйте, AndrewVK, Вы писали:
AVK>Они не помогли, потому что лятский кодогенератор вьюх втыкает свои юсинги неявно, вот куча вьюх и осыпалась, потому что типы из МСных свежих либ конфликтовали с типами из проекта сайта.
Ну, так и РеШарпер втыкает юсинги в автомате, так что хрен проследишь на что отображаются конкретные типы.
AVK>Т.е., фактически, получилась твоя глобальная видимость.
Фактически получается, что решение с юсингами — плохое решение. Я же предлагаю сразу заниматься неоднозначностями и только ими. Причем сделать так, чтобы неоднозначность возникала только при полном совпадении.
Я предлагаю сделать более умный компилятор и забить не рудеминтарные действия.
VD>>Может разумнее придумать удобную систему разруливания конфликтов вместо них?
AVK>А что ты там разрулишь, если, к примеру, у МС появился класс Gravatar с методом GetUrl, а IT в свое время тоже написал класс Gravatar с методом GetUrl?
Если у них разная сигнатура, то это вообще не проблема. Если одинаковая, то это конфликт который нужно разрулить. Разруливать можно для всего проекта и для отдельного файла.
AVK>Там даже по типам и именам параметров получилось пересечение. Единственное что тут можно сделать — вывалить ошибку о конфликте.
Ага. Таких мест будет мало. Разрулить их и будет нам счастье.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
AVK>>Они не помогли, потому что лятский кодогенератор вьюх втыкает свои юсинги неявно, вот куча вьюх и осыпалась, потому что типы из МСных свежих либ конфликтовали с типами из проекта сайта. VD>Ну, так и РеШарпер втыкает юсинги в автомате
Он их не втыкает там где не нужно. А вот разор втыкает их везде, нужно это или нет. Т.е. эмулирует ровно то поведение, которое ты предлагаешь — все МСные либы доступны во всех вьюхах без юсингов.
AVK>>Т.е., фактически, получилась твоя глобальная видимость. VD>Фактически получается, что решение с юсингами — плохое решение.
Без них — еще хуже.
VD> Я же предлагаю сразу заниматься неоднозначностями и только ими. Причем сделать так, чтобы неоднозначность возникала только при полном совпадении.
Я тебе реальный и свежий пример привел, а ты уж думай сам.
AVK>>А что ты там разрулишь, если, к примеру, у МС появился класс Gravatar с методом GetUrl, а IT в свое время тоже написал класс Gravatar с методом GetUrl? VD>Если у них разная сигнатура, то это вообще не проблема.
Разная, но, с учетом дефолтных параметров, вызовы попадали под обе.
... << RSDN@Home 1.2.0 alpha 5 rev. 100 on Windows 8 6.2.9200.0>>
Здравствуйте, AndrewVK, Вы писали:
AVK>Он их не втыкает там где не нужно.
Он их втыкает автоматом. Человек вообще не думает о том какие пространства имен он использует. Это важный факт. Он заставляет усомниться в самой концепции юстингов.
AVK>А вот разор втыкает их везде, нужно это или нет. Т.е. эмулирует ровно то поведение, которое ты предлагаешь — все МСные либы доступны во всех вьюхах без юсингов.
Если бы вывод типов в шарпе был по умнее, и если бы были возможности разрешать неоднозначности, то это бы не создавало проблем.
VD>>Фактически получается, что решение с юсингами — плохое решение. AVK>Без них — еще хуже.
Ты застрял в мире шарпа. Смотри на мир шире. Они не нужны. Они являются способом решения кофликтов имен работающего от принципа "разрешить", а можно жить по принципу "запретить" или даже "разрулить там где есть проблемы".
VD>> Я же предлагаю сразу заниматься неоднозначностями и только ими. Причем сделать так, чтобы неоднозначность возникала только при полном совпадении.
AVK>Я тебе реальный и свежий пример привел, а ты уж думай сам.
Ты меня не слушаешь. В Шарпе вывод типов очень плохой. Он тупо не может отличить двух типов. Если бы это было не так, то неоднозначности были бы большой редкостью и было бы в сто раз проще их разруливать.
Что-то я устал повторяться. Ты прежде чем в следующий раз отвечать постарайся понять то, о чем я говорю.
AVK>>>А что ты там разрулишь, если, к примеру, у МС появился класс Gravatar с методом GetUrl, а IT в свое время тоже написал класс Gravatar с методом GetUrl? VD>>Если у них разная сигнатура, то это вообще не проблема.
AVK>Разная, но, с учетом дефолтных параметров, вызовы попадали под обе.
В совсем неоднозначных случаях нужно разрешать неоднозначности врунчную. Их не будет много. Это куда проще чем открывать разрешать их с помощью открытия пространств имен в каждом фале. По сути ты решаешь проблему во всех файлах проекта вместо того чтобы решить ее один раз.
В таких случаях можно выбрать предпочтение одного из классов/функций во всем проекте или его части или написать специальную функцию которая будет делать выбор сама (аналогично юсингу с алиасом для типа).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
AVK>>Он их не втыкает там где не нужно. VD>Он их втыкает автоматом. Человек вообще не думает о том какие пространства имен он использует.
Человек может и не думает, а я вот думаю.
VD>Если бы вывод типов в шарпе был по умнее, и если бы были возможности разрешать неоднозначности, то это бы не создавало проблем.
Я привел реальный случай.
VD>>>Фактически получается, что решение с юсингами — плохое решение. AVK>>Без них — еще хуже. VD>Ты застрял в мире шарпа.
Ясно. Тебе, как обычно, не чужое мнение нужно, а вещать Единственно Правильную Точку Зрения на вопрос.
AVK>>Я тебе реальный и свежий пример привел, а ты уж думай сам. VD>Ты меня не слушаешь. В Шарпе вывод типов очень плохой.
Это ты меня не слушаешь. Никакой вывод типов в данном случае не спас бы. Прочти мои предыдущие ответы еще раз.
AVK>>Разная, но, с учетом дефолтных параметров, вызовы попадали под обе. VD>В совсем неоднозначных случаях нужно разрешать неоднозначности врунчную. Их не будет много.
То есть вера. То есть обсуждать нечего.
... << RSDN@Home 1.2.0 alpha 5 rev. 100 on Windows 8 6.2.9200.0>>
Здравствуйте, AndrewVK, Вы писали:
AVK>Человек может и не думает, а я вот думаю.
Предлагаешь обсудить тебя?
AVK>Ясно. Тебе, как обычно, не чужое мнение нужно, а вещать Единственно Правильную Точку Зрения на вопрос.
Не обвинять меня в твоих недостатках. Я предлагал обсудить иной подход. Ты полез в бутылку выставляя свое единственно правильное мнение основанное на твоем опыте. Я тебе объяснил, что ты исходишь из не верных предпосылок. Ты же лезешь спорить и ругаться. Мне это не интересно. Мне нужен конструктив.
AVK>Это ты меня не слушаешь. Никакой вывод типов в данном случае не спас бы. Прочти мои предыдущие ответы еще раз.
Я тебя слушаю, но вижу что ты тупо повторяешь неверные доводы.
Мои доводы очень просто. В 99% случаев вывод типов отличит имена на базе информации о типах. В оставшемся одном проценте придется разрулить неоднозначности. Причем это можно будет сделать как на уровне проекта, так и на локальном уровне.
Если твой "данный случай" подпадает под этот самый 1%, то не стоит на этом основании делать далеко идущие выводы. Нужно подумать о картине в целом.
VD>>В совсем неоднозначных случаях нужно разрешать неоднозначности врунчную. Их не будет много.
AVK>То есть вера. То есть обсуждать нечего.
Вера во что?
Мне кажется тебе хочется устроить срач на ровном месте. Если это так, то лучше просто не влезай в спор. А влезаешь, старайся понять чужие аргументы, и обосновать свое мнение.
И так, если ты готов к конструктиву, чем тебе не понравилось мое утверждение выше?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
AVK>>Человек может и не думает, а я вот думаю. VD>Предлагаешь обсудить тебя?
Ты уже начал.
AVK>>Ясно. Тебе, как обычно, не чужое мнение нужно, а вещать Единственно Правильную Точку Зрения на вопрос. VD>Не обвинять меня в твоих недостатках. Я предлагал обсудить иной подход.
Оно и видно: "Ты застрял в мире шарпа. Смотри на мир шире.". Отличное обсуждение, чо.
VD> Ты полез в бутылку выставляя свое единственно правильное мнение основанное на твоем опыте
Я, прощу обратить внимание, вообще своего мнения не высказывал. Потому что я — не знаю. Статистики по конфликтам у меня нет, в личной практике встречался неоднократно с такими конфликтами, которые никакой вывод типов не разрулит. Могу тебе только очевидные вещи сказать — чем больше проект, старее, и больше у него референсов, тем вероятность конфликтов выше. И бывают крайне причудливые ситуации. Например две версии одной и той же библиотеки, подключенные одновременно. Или не подключенные, а просто воткнутые двумя папочками в проект, в одной из которых переименован неймспейс. Разруливать такое без юсингов — это реально застрелиться. И никакой вывод типов, очевидно, тебя при такой ситуации не спасет. Там даже юсинги не всегда спасают, приходится namespace alias использовать.
А вот ты почему то уверен, что проблем 100% не возникнет. Хотелось бы понять на основании каких данных у тебя эта уверенность, а не выслушивать эпитеты, которыми ты щедро оделяешь собеседников на ровном месте.
AVK>>Это ты меня не слушаешь. Никакой вывод типов в данном случае не спас бы. Прочти мои предыдущие ответы еще раз. VD>Я тебя слушаю, но вижу что ты тупо повторяешь неверные доводы.
Я никаких доводов не повторяю. Я привел тебе факт.
VD>Мои доводы очень просто. В 99% случаев вывод типов отличит имена на базе информации о типах.
Докажи.
VD>Если твой "данный случай" подпадает под этот самый 1%, то не стоит на этом основании делать далеко идущие выводы.
Я их и не делаю. Ты, похоже, их сделал за меня.
VD> Нужно подумать о картине в целом.
Нужно прежде всего не отметать неудобные факты, если они не укладываются в твою картину в целом.
AVK>>То есть вера. То есть обсуждать нечего. VD>Вера во что?
В то что таких проблем будет 1%. Для универсального языка, кстати, и 1% это весьма серьезно.
VD>Мне кажется тебе хочется устроить срач на ровном месте.
Срач устраивает тот, кто начинает оскорблять на ровном месте. Зуб даю.
VD>И так, если ты готов к конструктиву, чем тебе не понравилось мое утверждение выше?
Тем что оно предлагает опираться на веру в твое утверждение о 99%.
... << RSDN@Home 1.2.0 alpha 5 rev. 100 on Windows 8 6.2.9200.0>>
Здравствуйте, VladD2, Вы писали:
VD>При использовании Решарпера человек уже не думает о том, что он импортирует. Он просто комплитит и юсинги меняются автоматически. Никаких проблем на практике не возникает. Так какую проблему тогда решают эти юсинги?
Одна зависимость транзитивно притащила бекпорт в 1.4 java.util.concurrent. Так эта гадость через автоимпорты расползлась по куче классов прежде чем заметили.
Здравствуйте, VladD2, Вы писали:
VD>Собственно, подумалось, что идея открытия пространств имен порочна сама по себе. Намного проще и удобнее исходить из предположения, что все имена доступны глобально, и воздействовать на их видимость только в случае конфликта имен в конкретном файле.
+1!
Одноимённых классов намного меньше, чем гемороя с подключением уникальных, так что идея "автоюзинга" абсолютно здравая. Раз в сто лет использую синоним для неоднозначных типов — он всё решает.
Когда только изучаешь язык, вроде бы using кажется разумным. Как только начинаешь писать тонны кода, становится непонятно, почему ты тратишь время на вещи, которые сам компьютер мог бы спокойно разрулить. Вывод типов сделали же! Хотя о нём во времена фортрана даже не мечтали.
Еще один свежий пример оттуда же. В проекте присуствуют публичные методы .IsNullOrEmpty() в количестве 4 штуки. Сигнатуры, очевидно, идентичные. Раскидано по проекту массово.
Второй пример — у соседей в решарпере есть такая штука как атрибуты для аннотаций. Поскольку корневой проект для всех не всегда можно сделать, иногда наборчиков этих несколько штук. Сейчас можно разнести по разным неймспейсам, и даже неважно какой реально подцепится. А вот если не будет юсингов, получится знатный о ла ла.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
Здравствуйте, VladD2, Вы писали:
VD>Собственно, подумалось, что идея открытия пространств имен порочна сама по себе. Намного проще и удобнее исходить из предположения, что все имена доступны глобально, и воздействовать на их видимость только в случае конфликта имен в конкретном файле.
Всё же не очень хорошо, что, пусть и с малой вероятностью, при подключении новой библиотеки неожиданно полезут ошибки.
VD>Еще одной идеей видится пренос юсингов из отдельных файлов с кодов в описание проекта. Вместо того чтобы по 100500 раз описывать using-и в каждом файле имеет смысл указать какие из пространств имен импортируются из библиотеки. Такой подход за одно позволил бы лучше контролировать использование типов из внешних сборок.
Ну, см. заголовок, идея местами очень интересная (хотя больше предназначена для решения проблемы с конфликтом версий). Интересно, существуют ли аналоги для .net?