четверг, 2 апреля 2009 г.

Из непонятого: alias this в языке D 2.0

В преддверии 1-го апреля Вальтер Брайт выпустил новые версии своего компилятора языка программирования D. Списки изменений для версий 1.0 и 2.0 можно посмотреть здесь:

http://www.digitalmars.com/d/1.0/changelog.html
http://www.digitalmars.com/d/2.0/changelog.html

В язык D 2.0 была добавлена фича, которую я раньше нигде не видел: alias this. Как я смог понять из документации, эта конструкция позволяет переадресовать все вызовы, которые компилятор не смог связать с самим объектом, на указанный атрибут этого объекта. Вот пример из документации:

struct S
{   int x;
    alias x this;
}

int foo(int i) { return i * 2; }

void test()
{
    S s;
    s.x = 7;
    int i = -s;   // i == -7
    i = s + 8;    // i == 15
    i = s + s;    // i == 14
    i = 9 + s;    // i == 16
    i = foo(s);   // implicit conversion to int
}

Здесь получается, что большинство операций над экземпляром s на самом деле переадресуется его атрибуту x. Т.е. такая конструкция позволяет легко выдать экземпляр/объект структуры/класса за экземпляр другого типа. Всего лишь с помощью alias this. В C++ для этого пришлось бы определять кучу операторов. А в D – только alias this :)

Вероятно, данная конструкция была введена в D из-за каких-то прагматических соображений. Но я не могу понять каких. Равно как не могу сообразить, в каких случаях мне мог бы понадобиться подобный прием.

Но вот есть у меня серьезное подозрение, что понимаемость D-шных программ, в которых данный трюк используется, основательно снизится. И это все в языке, который декларировался как более простой и логичный C++. И если C++ ругают за то, что в результате своего развития он превратился в клоаку очень разрозненных идей и концепций, то у D есть все шансы переплюнуть C++ в этом отношении.

4 комментария:

Анонимный комментирует...

Это я тут бродить стал по старым записям, извинити :)

Мне эта фишка напоминает обобщение идеи «прототипа» в прототип-ориентированных языках (напр. io). Там у объекта есть свойство «prototype», которому и уходят все «непонятые» сообщения. Используется далеко не только для организации наследования (хотя и для этого тоже: prototype изначально и есть «родитель; объект, с которого меня склонировали»), но и для многих разностей, вроде организации и смены лексического scope (блок кода — это объект, у которого в свойстве prototype хранится scope, в котором будет вычисляться весь код).

eao197 комментирует...

Когда этот релиз обсуждался на linux.org.ru, там подобная мысль прозвучала (http://www.linux.org.ru/view-message.jsp?msgid=3614097#3614706). Назвали это дело "неполиморфное наследование для структур".

Твоя интерпритация мне больше нравится.

Хотя, как по мне, как это только желание съэкономить на коде, который нужен для переопределения операторов для структур в некоторых экзотических случаях.

Анонимный комментирует...

Ну, мне это кажется одной из забавных «чужих» идей, которые лучше не заимствовать — потому что для других языков они не только не идиоматичны сами по себе, но и в целом плохо вписываются в общую идиоматику (к примеру, ara t. howard некоторое время поддерживал библиотеку prototype.rb, но никто ей особого применения так и не нашёл, кажется, включая самого Ару)

eao197 комментирует...

:)

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