Перевод: GSerg
К сведению: эта хвалебная ода была написана по Visual Basic.NET beta в 2001 году. Релизной версии я не покупал, и не имею ни малейшего представления, какие мои утверждения применимы к ней. Оставляю всё как есть по историческим причинам.
В 1997 году, когда я впервые оставил Visual Basic, я предпринял небольшое путешествие на другую сторону, чтобы попробовать Delphi. Я обнаружил значительное отличие между моделями программирования VB и Delphi, и, к своему удивлению, понял, что модель VB мне нравится больше. Потом, когда я пробовал среды разработки Java, я обнаружил то же отличие. Java, Delphi, C++ Builder, Visual C++ и все остальные объектно-ориентированные языки, основанные на GUI, отличались от VB одним и тем же образом.
Теперь же готовятся к выходу два новых языка с теми же отличиями от Visual Basic. Один — C#. Другой называется Visual Basic.NET (и не имеет никакого отношения к Visual Basic от 1 до 6). Эти языки, подобно Java и Delphi, основываются на мощной и сложной библиотеке классов. Весь язык построен на этой библиотеке и тесно интегрирован в неё, а поскольку библиотека столь сложна, известный уровень сложности появляется даже в простейших программах. Среды разработки этих языков стараются скрыть сложность, но до конца у них это не получается (да не особо и стараются).
Сравните всё это с Visual Basic. Хотя поздние версии Visual Basic (4-6) обладали определёнными объектно-ориентированными возможностями, сам язык основывался не на них. Он основывался на волшебстве. Что-то там происходило — и вот все эти элементы управления появлялись на форме и взаимодействовали с кодом. Но вы не могли сказать, что именно. И уж точно не запутались бы.
В этом была привлекательность языка. Он просто работал. Можно было создать удивительно мощное приложение в короткое время, используя приёмы, которые просто ощущались правильными, даже если были непонятны при детальном рассмотрении.
В какой-то момент волшебство заканчивалось. Чем сложнее была программа, тем чаще вы встречались с неполнотой и непостоянством. Появившиеся в поздних версиях VB возможности уже не совсем подходили вашим задумкам.
В конце концов, Visual Basic стал похож на машину Руба Голдберга (машиной Руба Голдберга называется любой максимально сложный агрегат, созданный для выполнения максимально простой функции. Проводятся даже конкурсы по этому делу. См, например, http://www.y3k.com/rube.html – прим. перев.), со всеми этими наворотами, прикрученными изолентой и более странными крепёжными средствами. Основание было прочным, но оно было недостаточно большим, чтобы удержать всё новые комнаты и этажи.
Все мы думали, что конструкция продержится ну хотя бы пока они не добавят что-нибудь из того, что мы хотели, или уберут что-нибудь из того, что нас раздражало — но, думаю, все мы знали, что вечно это длиться не может.
Привыкай
Я просил библиотеку классов, но я думал, что они поместят её поверх существующей системы, а не сделают основанием новой. Я просил наследование, но я думал, что сам буду использовать его, без них. Я просил переменные процедурного типа, но для своего использования, а не как основу моделирования событий. Я просил об изменениях в языке, а не о новом языке.
Я был наивен, может быть даже глуп. Теперь, узрев Visual Basic .NET во плоти, я понимаю, как глупо было верить, что можно было внести эти изменения в старый VB. Всё зашло слишком далеко. Оригинальный VB был одной из лучших рабочих лошадок в истории, но всё же не более чем лошадкой.
Так уж вышло, что они не смогли прилепить все эти штуки из других языков к VB. Им пришлось начать с нуля. А когда они закончили создавать новый язык, имеющий всё, что есть у Delphi или Java, оказалось, как ни странно, что то, как он выглядит и работает, очень смахивает на Delphi или Java.
Ладно, я принимаю тот факт, что Visual Basic будет абсолютно новым языком, который даст мне всё, о чём я просил. Ему приходится выглядеть и работать иначе, и он не будет столь прост и очевиден. Но, как и его конкуренты, он будет более мощным и последовательным.
Я слышал крики агонии в VB news groups. Многие разработчики не могли перенести мысли о необходимости полностью переписать свои приложения на незнакомом языке. Некоторые из них хотели, чтобы Майкрософт продолжала поддерживать и развивать VB 6 как отдельный язык. Другие предполагали, что Майкрософт продаст VB 6 другому производителю. Я разделяю ваши чувства, но всем, кто хочет, чтобы за VB 6.1 последовал VB 6.2, и так до VB 6.9999, имею сказать одно.
Привыкайте.
Майкрософт приложит минимум возможных усилий к поддержке VB 6. Они выждут приличествующее случаю время, а потом убьют его. Это новый мир, и назад пути нет. Если вы не можете перейти на VB .NET, лучше уйти сейчас, чем потом.
Если вкратце, я полностью поддерживаю идею перепланировки Visual Basic с фундамента. Я принимаю главные структурные изменения. Сделать их было необходимо, и я, если честно, сделал бы и ещё.
Проблема не в том, что они сделали. Проблема в том, как они это сделали. Они направили низкоуровневых сишников на перепланировку высокоуровневого языка Basic. Результат, скажем так, странный. Новый язык полон беспричинных обид и невежественной глупости. У VB .NET просто нет духа Basic’а. Программистам на Basic довольно сложно проглотить эти изменения, не выглядя глупо и смешно.
Basic #
Из новой архитектуры ясно, что Visual Basic.NET был задуман задним числом. Они не попытались сразу подправить самый популярный и доходный язык в истории. Нет, похоже, они начали с Java.
Несколько лет назад Java была очень популярна среди разработчиков Майкрософт. Каждый мог видеть преимущества использования высокоуровневого объектно-ориентированного языка в деле разработки приложений. C++ отличный язык, но для низкоуровневой работы в операционных системах и компонентах. Но когда ты разрабатываешь приложение для конечного пользователя, преимущества от использования низкоуровневого языка с поддержкой указателей не окупают дополнительных расходов на разработку и вылов ошибок. У Майкрософт был высокоуровневый язык по имени Visual Basic, но большинство разработчиков Майкрософт использовали C++. И им было удобнее перейти на Java.
Но потом начались юридические проблемы с Sun, и в конце концов Майкрософтовский J++ ушёл в небытие по причинам, которые к самому языку отношения не имели.
Это неплохо сочеталось с мечтой Майкрософт о разработке нового языка. Большинство их языков были куплены у других компаний, но в последние несколько лет поползли слухи о кардинально новом языке, называемом COOL.
Если кто-то захочет приоткрыть завесу над настоящей историей COOL, я с удовольствием почитаю. Могу сказать только, что появившийся в конце концов язык был вовсе не КРУТ (а что мне тут было делать – прим. перев.). Он не был кардинальным или новым. Это был искусный и несколько отшлифованный плагиат с Java. Имя этого языка, C#, соответствует содержанию. Вроде и умно, но не очень оригинально.
Я не знаю закулисную историю разработки Visual Basic .NET, но он явно основывается больше на C#, чем на Visual Basic. По всей видимости, после разработки C# кто-то сказал: «Эй, а ведь мы можем срубить бабок, и всего-то нужно склонировать этот C# во что-нибудь с синтаксисом наподобие Visual Basic».
Это похоже на то, когда в фантастических фильмах пришельцы пытаются выдать себя за людей, одев маски. Они всегда выдают себя, потому что не могут достаточно точно сымитировать все тонкости земной культуры. Си-шарпники сделали всё, что могли, чтобы закосить под разработчиков VB, но нас им определённо не одурачить.
Так и вижу, как они обсуждают это дело: «Не понимаю. Зачем мы это делаем вообще? Что этим VB-шникам надо? Почему им просто не использовать C#? Ну ладно. Пусть у VB миллионы пользователей, у а C# ноль. Пусть даже и насмешим. Но в конце концов! Что они за программисты, если думают, что True равен минус единице?».
Ладно, давайте поговорим о неBasic’овских изменениях в Visual Basic .NET. Начнём с потерянной возможности, которая на шкале от 0 до 9, вероятно, равна 3. Её потеря не конец света, но она показывает презрение разработчиков Майкрософт к нам и к нашему противному языку.
Упрощённые до абсурда массивы
“Hardcore Visual Basic” приводит историю массивов Basic прямо от авторов языка, John Kemeny и Thomas Kurtz. Сначала они ввели массивы с начальным индексом 1, потому что так было бы привычнее для обычных людей, а Basic для них и разрабатывался. Но математики и учёные жаловались, что их матрицы начинаются с нуля, и Kemeny с Kurtz добавили команду Option Base, чтобы пользователи могли сами решать, с нуля или с единицы начинать массивы. Но потом они заметили, что цивильные (хе-хе – прим. перев.) высокоуровневые языки, такие как Pascal, позволяют пользователям указывать начало и конец массива. Так что Kemeny и Kurtz ввели и это в Basic, сделав возможным следующее:
- Код: Выделить всё
Dim aiJoeAverage (1 To 10) As Integer
Dim aiMathemetician(0 To 9) As Integer
Dim aiWeatherman (-50 To 125) As Integer
Dim aiNoneOfYourBusiness(iFirst To iLast) As Integer
Я рекомендовал, чтобы программисты Visual Basic всегда явно обозначали начало и конец массива. Следующее допустимое выражение должно считаться опасным:
- Код: Выделить всё
Dim aiUnclearAndConfusing(10) As Integer
Изначально Майкрософт изменило смысл этой команды в VB .NET, чтобы она стала запутывающей как в C++, а не запутывающей как в VB. Потом они вернулись к запутыванию в стиле VB и заявили, что это большая уступка ради совместимости с VB. А восстановить определяемые пользователями нижние границы отказались.
Заметьте, что когда Kemeny и Kurtz разрабатывали массивы Basic, они не спрашивали: «Как компьютеры размещают массивы?». Или «Что легче реализовать?» Или «Что будет эффективнее?» Или «Как сделать совместимость с менее высокоуровневыми языками?» Или «Как мы будем работать с ущербной библиотекой, разработанной для наименьшего общего знаменателя из языков?» Тот факт, что компиляторы и интерпретаторы считают массивы начинающимися с нуля, не имел никакого значения, поскольку для самого языка не составляет труда привести массив к любой границе за кулисами. И даже если бы была потеря в производительности, она не имела бы значения, поскольку Basic — это высокоуровневый язык, разработанный для людей, а не для компьютеров (был, во всяком случае).
Для низкоуровневых языков типа C, C++ и Ассемблера абсолютно нормально предлагать своим пользователям начинающиеся с нуля массивы. Свыкнуться с такими массивами там для программиста — меньшая из проблем. Но как они попали в языки, претендующие на звание высокоуровневых, как Java и C#?
Когда разработчики Майкрософт создали новый язык на основе Java (хоть они это и отрицают), а потом изменили Visual Basic для достижения максимальной совместимости с C#, у них было несколько возможностей на выбор:
1. Отупить Visual Basic до массивов, начинающихся с нуля.
2. Подтянуть C# до массивов с произвольной нижней границей.
3. Дать Visual Basic произвольную границу, а C# нулевую границу.
Они сделали наихудший выбор, первый, вместо правильного, второго. Приверженцы Майкрософт могут заявить, что вариант 3 невозможно было воплотить, не потеряв совместимость с Common Language Runtime (CLR), но я этому не верю. Если Майкрософт даже не может сделать Basic Basic’ом, на какое доверие они могут рассчитывать, убеждая поставщиков переходить на .NET?
Чтобы добавить к несправедливости ещё и обиду, утилита конвертирования кода VB6 в код VB.NET берёт следующее:
- Код: Выделить всё
Dim ai(1 To 10) As Integer
и выдаёт это:
- Код: Выделить всё
Public ai As Object = New VB6.Array(GetType(Short), 1,10)
Очевидно, есть совместимый класс в пространстве имён VB6, который может имитировать настоящий массив Basic, и утилита обновления предположила, что я буду использовать эту странную и ущербную фичу вместо того, чтобы с ругательствами переделывать мои массивы под требования нового языка. Объекты типа массива не только странны, но они ещё и не работают с Option Strict, потому что используют позднее связывание.
Нет худа без добра. Глупость от изъятия произвольных нижних границ с лихвой компенсируется такой приятностью, как возможность инициализировать массивы. Теперь я могу написать так:
- Код: Выделить всё
Public asFruit () As String = { Apple , Orange , Pear , Banana }
Я просто помещаю строки в массив, а компилятор сам разберётся, сколько их там, как и в любом цивильном (хе-хе – прим. перев.) языке. Мы наконец-то можем инициализировать переменные. На это ушло десять лет.
Ещё тирада
Visual Basic .NET являет нам такую возможность, как делегаты (давно пора), но, как и в случае большинства остальных возможностей, идея лучше, чем воплощение. Синтаксис делегатов не то чтобы подходит под философию Basic.
Делегаты похожи на то, что в C называется указателями на функции, а в высокоуровневых языках — переменными или параметрами процедурного типа. FORTRAN и Pascal обладали этим много лет. Первая редакция Hardcore Visual Basic демонстрировала пару грубых приёмов для имитирования процедурных переменных, вторая являла меньшую грубость (но тоже непросто...), основанную на интерфейсах. Мне так кажется, что в основе своей делегаты содержат тот самый трюк с интерфейсом, который я рекомендовал для VB5 и VB6.
Я не собираюсь влезать в детали того, как работают делегаты. Я просто скажу, что на них базируется модель событий, и что они же используются для запуска тредов. Их можно передавать как параметры, хранить в массивах, и делать всё то, что в других языках делали годами, плюс несколько вещей, которых не делали.
Хотя делегаты рулезны, их синтаксис отстоен (сохраняю стиль оригинала – прим. перев.). Каждый раз, используя делегата, вы получаете напоминание: «Я использую высокоуровневый язык, спроектированный людьми, которые не понимают концепции высокоуровневого языка».
Я говорю о синтаксисе AddressOf при назначении делегата:
- Код: Выделить всё
' Assign the DestroyCars procedure having the DestroyProcs signature
' to the destroyer delegate variable
destroyer = New DestroyProcs(AddressOf DestroyCars)
Невзирая на то, как выглядит синтаксис, вы не назначаете адрес DestroyCars переменной destroyer. Вы назначаете саму DestroyCars, со всеми её параметрами и типом возвращаемого значения, если это функция.
В высокоуровневом языке нет понятия адреса. Адреса существуют только в низкоуровневых языках типа ассемблера и C. Вот почему AddressOf вызывала отвращение в VB5/6 (вот тут я подумал – а не зря ли я это перевожу? Я люблю AddressOf, и чувства она вызывает самые тёплые – прим. перев.). Она вносила элемент низкоуровневого нетипизированного языка в высокоуровневый типизированный язык. Вы правда передавали адрес, и правда получили бы краш, передав не то. Но весь смысл высокоуровневого языка в том, что вы вообще не должны знать об этих адресах.
Делегаты типобезопасны (гы! – прим. перев.). Нельзя назначить делегата переменной, если она не обладает совместимым типом, например, DestroyProcs. Так почему давать новой безопасной фиче (всё, надоело печатать «возможность» – прим. перев.) имя старой опасной нетипизированной фичи? Если AddressOf – метафора, то она неудачна. Случайное слово типа TelephoneNumberOf или SocialSecurityNumberOf произвели бы больше смысла. если была цель найти хорошую метафору, почему бы не назвать оператор SignatureOf? Но если уж быть точным и убрать ненужный шум, надо вообще избавиться от дополнительного ключевого слова.
- Код: Выделить всё
destroyer = New DestroyProcs(DestroyCars)
Вы указываете саму процедуру, а не что-то от процедуры. Язык должен понимать смысл этого выражения по контексту без всякого оператора.
Снова я углубился в разглагольствования о символизме и метафорах. Делегаты сами по себе работают нормально; так почему же я взъелся на синтаксис? Представьте, что вы — не говорящий по-английски финский программист, пытающийся изучить этот новый язык. Ключевые слова вам непонятны. Вы заучиваете их наизусть и ищете аналог в вашем языке. Какая вам разница, что ключевое слово для объявления переменных, Dim, было выбрано, похоже, путём открытия словаря на случайной странице? Бессмысленные слова типа Sub и Multicast значат для вас ровно столько же, сколько более осмысленные If и Function.
Большинство людей в этом мире не говорят по-английски, так зачем беспокоиться о том, что Visual Basic .NET использует бессмысленные метафоры? Как бы там ни было, проектировать языки на основе английского бестактно по отношению к другим культурам. Не понимаю, почему они не разработали его на основе латыни, чтобы никто не получал необоснованную фору.
Проглатывая обиду
Я мог бы продолжать и продолжать распространяться о новых фичах Visual Basic .NET и о том, насколько глупо и обидно они реализованы. Почему Майкрософт произвела столько рискованных изменений в самом популярном языке? Одна из причин, по их словам:
«Одной из наших главнейших задач было обеспечить возможность полного взаимодействия кода на Visual Basic с кодом на других языках, таких как Microsoft Visual C# или Microsoft Visual C++...»
Взаимодействие между языками было, вероятно, одним из трёх главнейших приоритетов при разработке языков .NET. Может, оно даже входило в 300 усовершенствований, которые программисты Visual Basic просили внести в следующую версии языка. Это отличие во мнениях создаёт определённую напряжённость.
Честно говоря, Майкрософт не сможет выкрутиться, возлагая ответственность за все эти свои мелкие изменения на возможность взаимодействия. Некоторые изменения выглядят почти как просчитанные оскорбления. Разработчики VB .NET, будучи программистами C++, похоже, сказали «Идите нах, отстои. Мы не собираемся потакать вашим глупым предубеждениям лишь потому, что вас в 10 раз больше, чем нас». Или они просто могли разрушить то, что им незнакомо, потому что не понимали или не хотели понимать историю и культуру нашего языка.
Мне указывали на то, что я не могу знать, что происходило в головах разработчиков VB .NET. Может и так, хотя я думаю, что можно угадать позицию человека по тому, что он делает. Люди определённо делают выводы обо мне, основываясь на тексте моей книги, и многие из них преуспевают в этом. Но если я не прав насчёт разработчиков VB .NET, если они действительно программисты VB, которые любят Basic и преисполнены духом разработчиков языка, Kemeny и Kurtz, тогда всё гораздо хуже. Тогда конечный результат можно объяснить не невежеством и высокомерием, а некомпетентностью и глупостью.
Моё в целом негативное отношение не означает, что мне нечего сказать хорошего о VB .NET. Я могу быть столь же упрям и непреклонен, как Майкрософт, и я собираюсь выступить в защиту некоторых изменений, которые сводят с ума других. Следующий список изменений взят со страницы Visual Fred Карла Петерсона.
Я просто хочу отметить пару положительных и отрицательных моментов, чтобы снять с себя этот груз:
Изменение синтаксиса свойств
Синтаксис свойств был случайно изменён по причинам, которые не может представить ни один программист Visual Basic. Вот старый синтаксис:
- Код: Выделить всё
Property Get Thing() As Integer
Thing = iThingA
End Property
Property Let Thing(iThingA As Integer)
iThing = iThingA
Property Let
А вот новый:
- Код: Выделить всё
Property Thing As Integer
Get
Thing = iThingA
End Get
Set
iThing = Value
End Set
End Property
В чём смысл, если не в разрушении существующего кода? Изменение носит стилистический характер. Никакого особого преимущества с технической точки зрения нет ни у одного варианта. Некоторые сторонники Майкрософт заявляют, что это всё необходимо для совместимости с Common Language Specification (CLS), но это полная чушь для любого, кто знает, как работают парсеры языка. Более того, сотрудники Майкрософт говорили мне, что разработчики CLS отрицают необходимость такого синтаксиса. Если такой синтаксис не может быть обработан, у .NET не остаётся никаких шансов работать с немайкрософтовским языками типа Cobol и Eiffel, .NET-совместимые версии которых Майкрософт якобы скоро представит.
Критики отмечают, что новый синтаксис обладает меньшими возможностями, чем старый, поскольку модификаторы видимости Friend, Private и Public применяются ко всему свойству, а не к Get или Set. Невозможно сделать Get Public, а Set Friend. Хотя сейчас всё обстоит именно так, нет причин, по которым Майкрософт не могла бы произвести незначительные изменения в новом синтаксисе, чтобы разрешить эту возможность (в FW 2.0 студии 2005 они так и сделали; получается, опять хотели срубить бабок, чтобы обязательно потом все перешли на 2005, раз там такая фича поддерживается? – прим. перев.).
С технической точки зрения, два синтаксиса эквивалентны. Так зачем же вносить такое прихотливое изменение? Программисты встречают столько капитальных нововведений, что рады любой стабильности в деталях. Мудрые разработчики берегут сюрпризы для более подходящего случая, вместо того чтобы тратить их на всякую мелочёвку.
Для рядового программиста новый синтаксис property обидный и раздражающий, но в целом проблем не создаёт. Но он создаёт серьёзные проблемы для разработчиков примеров. VB .NET уже добавляет два дополнительных уровня отступа. Функции и процедуры, ранее начинавшиеся с самого левого столбца, теперь начинаются на третьем уровне отступа, внутри Namespace и Class или Module. Код для свойств начинается на четвёртом уровне отступа. Очень вероятно, что ваш код либо начнёт простираться далеко вправо за границу экрана, либо вам придётся использовать переносы строк.
Авторам книг приходится умещать свои примеры менее чем в 80 столбцов, а журнальным авторам и того меньше. Я знаю, что авторы, использующие C++ и Java, давно встречаются с этой проблемой, но они-то используют языки, не зависящие от переноса строк. Они могут разорвать код где угодно, не заботясь об этом гадком символе переноса строки как в VB. Старый синтаксис куда компактнее.
И ещё новый синтаксис добавляет две лишних строи по вертикали. Вертикальное пространство не столь капризно, но авторы не любят зря тратить и его.
Новые имена типов
Одно из наиболее бросающихся в глаза изменений в VB. NET – переименование Integer в Short, а Long в Integer. Противники этого изменения были столь горячи, что целые узлы Internet поджаривались до хрустящей корочки. Единственный немайкрософтовский голос в поддержку этого изменения мой. Я слышу хруст миллионов нарушенных строк кода, но мне всё равно.
Большинство этого кода не было бы нарушено, если бы Майкрософт прислушалась к моему совету во время тестирования беты VB4. Я говорил менеджерам программы VB, что это безумие называть 32-битное целое Long на 32-битной системе. Я говорил им, что это безумие называть Integer 16-битное целое, которое аккуратные программисты почти никогда не станут использовать. И сейчас я с огромнейшим удовольствием могу сказать – я же вам говорил.
Это как если бы я открыл новый вид бабочек и решил назвать его Голубой Ангел. Один из моих коллег возразил бы: «Почему ты называешь её так? Она же красная». А мне всё равно. Я открыл её, и мне всегда нравилось название Голубой Ангел. Голубой был любимым цветом моей матери.
Но она красная.
А мне всё равно. Если Майкрософт может назвать 32-битное целое Long, хотя оно не long, я могу назвать красную бабочку Голубой Ангел.
Так что привыкайте. Short – название для 16-битных целых. Integer – для 32-битных целых. Long – для 64-битных. А Variant и Currency вообще больше нет. Конечно, удаление этих двух типов нарушает некоторую часть кода, включая мой, но я не жалуюсь. Я использовал Variant от случая к случаю, для передачи параметров, которые могут быть строковыми или целыми, но я могу сделать то же самое более явно в VB .NET, используя перегрузку. Я никогда не использовал Currency, кроме как для всяких хитростей, которые в VB .NET становятся ненужными. Формат хранения даты тоже изменился, и мне снова всё равно.
Я знаю многих программистов, которые имели более веские причины быть обеспокоенными этим новшеством, чем я. Больно точно будет. Но боль оправданна, если в новой системе больше гибкости и здравости.
Требуется уточнение членов Enum
В VB. NET всегда нужно уточнять члены Enum именем самого Enum – важное синтаксическое изменение, которое, похоже, осталось неосвещённым в документации к бете. Это нарушает каждую строчку кода с использованием Enum, которая у меня есть. Более того, исчезает основная причина, по которой я использовал Enum. Переписывая свой код, я не добавил бы уточняющее имя Enum, как предлагает мастер обновления. Я изменил бы Enum на Const. Если вкратце, это смехотворное изменение, которое не вносит в язык ничего, кроме неудобства. Если они думают, что это как-то повысит безопасность, пусть добавили бы лучше Option Anal и требовали бы уточнять имена членов Enum только у тех программистов, кто задействует такую опцию.
Нет статических локальных переменных
Представляю комитет разработчиков, заседающий за столом переговоров и решающий, как лучше покалечить язык. На этом воображение заканчивается. Я не могу придумать разумный ход событий, приведший бы к удалению статических локальных переменных. Почему бы кому-то захотелось сознательно сделать наш код менее структурированным и читаемым? Всё, что мне приходит на ум, так что это дельфисты подействовали на них чем-то типа Вуду. Недавно я слышал, что разработчики VB .NET пришли в себя и вернули статические переменные в язык. Если это так (это так – прим. перев.), могу поздравить их с возвращением в сознание.
Нелогичные операторы
Много крови было пролито в VB users group по поводу первоначального решения Майкрософт сделать логические операторы VB .NET совместимыми с логическими операторами C, а не VB. Позже ещё больше крови было пролито по поводу решения вернуть совместимость с VB. Прежде чем я рискну жизнью и конечностями, заняв какую-то позицию в этом споре, я хочу обратить ваше внимание на не менее важный момент. Я хочу оплакать потерю двух операторов, бывших только нашими: Imp и Eqv.
Признаю, что я никогда не использовал эти операторы и лишь однажды встретил человека, который использовал. Я не имел ни малейшего представления, что они означают, кроме того, что они были символом нашей уникальности. Когда другие программисты пытались принизить нас, мы могли указать на мощь операторов Imp и Eqv. Мы могли презрительно фыркнуть, вместо того, чтобы отвечать, что делают эти операторы.
Ныне же горстка засланцев без всякого понимания нашей культуры и традиций удалила уникальную возможность из нашего языка просто потому, что мы никогда не использовали её. И они даже не постарались заменить их чем-нибудь полезным, например операторами Shl и Shr, которые есть в большинстве других языков.
Теперь вернёмся к абсолютно столь же важной вещи, как логические операторы. Начнём с истории. Все современные языки программирования обладают двумя видами логических операторов – побитовыми и логическими. Побитовые работают с отдельными битами своих аргументов. Логические смотрят, равна ли сумма бит нулю. В тривиальных случаях оба типа операторов дают одинаковый результат. Логические могут быть чуть более эффективны, потому что пропускают второе сравнение, если результат первого достаточен для определения выражения. Некоторые языки (FORTRAN, Pascal, Basic) исторически используют побитовые операторы как основные. По техническим причинам, которые я не хочу здесь приводить, эти языки используют –1 как значение True. В отличие от них, языки типа C используют логические операторы как основные, а True равно 1.
Исходя из приведённого выше определения, бейсики от Майкрсофт, включая VB не были современными языками, поскольку использовали побитовые, а не логические операторы. Это элементарно легко исправить, и я видел предложения о внесении логических операторов в ранних версиях Visual Basic (VB5, если не ошибаюсь). Это предложение, как и большинство других, бесславно умерло в тщетных попытках уделить больше времени разработки основным деталям.
В первой бета-версии VB .NET Майкрософт добавила логические операторы, но снабдила их старыми именами And и Or, использовавшимися для побитовых операторов. Старые же были переименованы в BitAnd и BitOr. Значение константы True было изменено на 1 для совместимости с сишными языками типа C#. Майкрософт сделала глупое заявление, что эти изменения необходимы для совместимости с Common Language Runtime, хотя очевидно, что работа любой библиотеки, зависящей от конкретного значения True, будет нарушена. Это разозлило массу программистов VB, которые видели, что эти изменения нарушат работу старого кода, предполагающего, что And и Or побитовые.
Майкрософт услышала эти громкие жалобы и во второй бете сделала And и Or снова побитовыми. Ещё были добавлены новые логические операторы с необычными именами AndAlso и OrElse. Это изменение было встречено криками протеста примерно такого же количества людей, какое протестовало против первого изменения. Любой, кто занимал некую позицию по отношению к этим операторам, рисковал огрести от той или другой стороны, а если позиция оказывалась неоднозначной, то и от обеих сторон. Впрочем, это никогда не удерживало меня от выражения собственного мнения.
С технической точки зрения это много шума из ничего. В любом случае программист имеет доступ как к логическим, так и к побитовым операторам. Технически неважно, равна ли True –1, 1 или 13. При написании нового кода логических операторы используются примерно в 80 процентах случаев, а побитовые в 20. Код будет работать так же вне зависимости от имён операторов. Предупреждения поборников любой концепции о конце цивилизации несколько преувеличены. В большинстве случаев разницы нет.
Доводы в защиту старой системы – практичность и культура. Можно оставить старый код нетронутым без малейшей потери правильности. Можно не спеша пройтись по нему и изменить некоторые побитовые операторы на логические в узких местах кода для повышения производительности. В системе, используемой в бете 1, вам пришлось бы пройтись по всему коду и изменить любое выражение, которое работает с битами. Побитовые выражения возвращали бы мусор без явного применения BitAnd и BitOr. Пришлось бы вручную изменять их все. Не существует механического пути определить отличие между логическими и побитовыми выражениями. Утилита обновления первой беты доказала это, заменяя все спорные выражения неясными и неэффективными совместимыми операторами.
Зачем рисковать нарушением работы кода, изменяя прекрасно работающую систему, имеющую длинную историю в культуре Basic? Единственное объяснение – культурологический империализм. Люди, перекраивавшие наш язык, просто хотели навязать нам свою религию. Это первый шаг по направлению к фигурным скобкам. Те, кому придётся исправлять совсем не обязательные ошибки, вызванные этим изменением, так просто этого не простят.
С другой стороны, довод в защиту системы сишного стиля – эстетичность. Многие логические выражения работают более эффективно с логическими, а не побитовыми операторами. Противно писать большинство кода с использованием AndAlso и OrElse. Эти имена, возможно, что-то и означают, но в итоге код будет гадким. Защитники новой системы создали весьма забавный топик в одной из VB.NET newsgroups, в котором предложили другие подходящие операторы, такие как ThenAgain, MaybeNot, ButAlso, CouldBe, WhoKnows, и ForSure. Я предпочёл бы другие имена для новых логических операторов, но не стоит активно их критиковать, если у вас нет лучших предложений. У меня нет.
Моё тупое мнение в том, что Майкрософт сделала тупую ошибку, изменив операторы в первой тупой бете. Они пытались оправдать эту тупую ошибку, заявляя, что это изменение необходимо для совместимости, хотя дело было не в совместимости. Теперь они исправили эти тупые ошибки, но, чтобы никто не думал, что он знает что делает, они дали новым логическим операторам тупые новые имена. Теперь Майкрософт намекает, что пошла на большие жертвы, чтобы ответить на критику своей тупой базы пользователей. На самом деле изменения незначительны и не окажут большого влияния ни на что, кроме нескольких миллионов строк тупого старого кода.
Nothing означает Nothing
В старые добрые времена COM вы знали, когда объект уничтожается, а когда нет. Погодите! Старые? А разве не вчера мы говорили о COM в религиозном свете? Не проповедники ли Майкрософт говорили нам, что классы их, однажды явленные, продлятся, пока горы не рухнут в море? А теперь они издеваются над нашим поклонением IUnknown и высмеивают жрецов подсчёта ссылок.
В конце концов Майкрософт обнаружила то, что некоторые из нас подозревали, но не смели произнести вслух: COM отстой. Это слишком сложно, слишком трудно осознать. Я не ожидал увидеть, как целую архитектуру бросят псам. Но именно это и произошло с механизмом подсчёта ссылок COM. Его нет. И с ним ушла возможность определить, когда объект уничтожается.
Реки бит утекли на обсуждение этого фундаментального изменения на форумах беты .NET. Я не собираюсь влезать в них, скажу только, что новая система не полагается на подсчёт ссылок и не страдает от циклических ссылок, которые порой сводили с ума программистов COM (особенно VB). Вместо этого новая система памяти использует непредсказуемые механизмы для определения того, когда объект становится мёртвым (на него никто не ссылается) и подлежит очистке.
Можно определить метод Destruct, который освобождает ресурсы, созданные вашим объектом, но нельзя точно сказать, когда именно объект будет уничтожен, и будет вызван этот деструктор. Большинство из нас хотели бы, чтобы система сама заботилась о своих ресурсах, когда мы того хотим, но мы вроде как нервничаем, когда не можем предсказать, когда наши собственные ресурсы (такие как файлы и соединения) будут освобождены. Многие программисты VB серьёзно расстроены этим изменением. Его влияние на портированный из VB6 в VB .NET код будет неуловимо и трудно предсказуемо.
Когда исчезла детерминированная деструкция, с ней ушёл один из прикольнейших моментов Visual Basic – автоматическое создание освобождённых объектов. Можно было объявить переменную вот так:
- Код: Выделить всё
Dim apple As New CFruit
Объект apple будет чудесным образом создаваться при использовании, а если его уничтожить путём установления в Nothing, то тем же чудесным образом он будет создан вновь при следующем обращении. Приведённый код имеет совершенно другое значение в VB .NET.
Это тот редкий случай, когда у меня нет своего мнения, но я боюсь, что придётся подождать и выяснить эмпирическим путём, окажется ли это радикальное изменение модели очистки памяти хорошей идеей.
Конец Wend
Я не использовал цикл While/Wend со времён BASICA, и я говорил читателям своей книги не использовать его. Do/Loop куда гибче и элегантнее. К несчастью, мои читатели весьма упрямая компания. Я часто получал письма от людей, которые возносили мою книгу до небес, после чего демонстрировали мне примеры, доказывающие, что они её не читали (или игнорировали мои советы).
Так что, думаю, я могу сказать всем, чей код будет нарушен из-за изменения синтаксиса окончания цикла с Wend на End While – я вас предупреждал.
Но вот чего я не понимаю. Если While/Wend есть ненужное зло (как я думаю), то следует избавиться от него. Do/Loop делает то же самое. Если такое избавление нарушит слишком много старого кода, тогда оставить его для совместимости.
Но в чём же смысл сохранения с внесением нового синтаксиса? Это разозлит фанатов While/Wend и вызовет отвращение у фанатов Do/Loop, не удовлетворив ни тех, ни других.
Как всегда, политика
Обидные изменения в языке, описанные здесь (а также многие не описанные), вообще-то составляют довольно небольшую часть VB .NET. Большинство их них могут быть исправлены во второй бете. Возможно, Майкрософт услышала наши крики и уже исправляет то, что я здесь описал. Но, честно говоря, я не собираюсь использовать VB .NET, как бы они его не исправили. Причины базируются в основном на политике корпоративной конкуренции.
Прежде всего, если бы я собирался использовать язык .NET, то это был бы C#, а не VB .NET. В отличие от большинства программистов VB, я не подсел на синтаксис Basic. Я вообще-то люблю фигурные скобки. Я предпочитаю строконезависимые языки строкозависимым. Я люблю лаконичность сишных операторов. Я не имею в виду дополнительные скобки и точки с запятыми.
Указатели, управление памятью, петли сообщений и производимая в уме многоуровневая косвенность – вещи, которые не нужны мне в моей каждодневной работе. Если сишный язык может дать мне простое программирование, у меня нет возражений.
Майкрософт сравняла игровое поле, отбросив нечестные преимущества VB. Больше нет редактирования с продолжением выполнения. Больше нет p-code. Больше нет immediate window в design mode. Больше нет волшебства. VB .NET просто ещё один компилируемый язык с визардами для автоматизации трудных частей. Я не вижу серьёзных причин выбирать VB .NET вместо C#.
Если уж вам придётся учить новый язык, почему бы не начать с действительно нового, а не с того, в котором так много обескураживающего сходства. Можно, наверное, написать переводчик с VB на C#, который будет куда точнее, чем переводчик с VB на VB .NET.
Кроме того, эта бета показала, что сердце Майкрософт (если оно вообще есть) принадлежит C#, а не VB. NET. Может, релизная версия и будет содержать примеры, написанные на VB .NET, но они будут переводами с C#, а не настоящими примерами на Basic, написанными программистами, которые любят Basic.
Так что если я сподоблюсь использовать .NET, я выберу C#. Но я не сподоблюсь. C# и VB .NET не языки общего назначения. Они, на настоящий момент, языки Майкрософт. Ставка на один из этих языков – это ставка на Майкрософт и на её способность принуждать или соблазнять другие компании принять её видение .NET. Это всё равно что ставить на то, что мухи полюбят паука. Может и полюбят, но я в этом я участвовать не хочу. Для меня это слишком большое извращение.
Если бы я собирался принять видение большой компании, это была бы скорее Sun, чем Майкрософт. Я не вижу большой разницы между Java со всеми связанными с ней технологиями и возникающим видением .NET. Я не хочу спорить о преимуществах или недостатках писания под .NET CLR по сравнению с работой под Java byte codes и Java virtual machine. Конечно, детали отличаются, но они оба пытаются занять одну нишу. Sun начала весьма самоуверенно, и у неё за плечами не такая сильная репутация недобросовестного конкурента. Некоторые сторонники Майкрософт могут оспорить этот момент, но это всё равно что спорить, кто был хуже – Гитлер или Сталин.
Что я действительно хочу, так это промышленный стандарт, не зависящий от крупных компаний. Возможно, я впадаю в излишнюю тоску по прошлому, но я жажду возвращения старого доброго времени, когда языки создавались маленькими компаниями. Я помню время, когда выбор языка определялся техническими вопросами, а не политическими. Я помню, как всё компилировались в native code, и как язык выбирали по его возможностям, а не по формату вывода. Я помню, как поставщики пытались продать потребителям язык, а не видение мира.
Что ж, эти славные дни ушли. Все мы должны выбрать себе язык. Для кого-то язык .NET станет привлекательным и осмысленным выбором. Для других не будет настоящего выбора по политическим или экономическим причинам. Некоторые обоснованно уйдут куда-то ещё. Иные выберут VB. NET именно то тем причинам, по которым я отказался от него.
Всё, что я могу предположить, что сейчас самое время ещё раз всё обдумать. Очевидный апгрейд до Visual Basic .NET совершенно не очевиден.
Bruce McKinney