Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2011.03.20;
Скачать: [xml.tar.bz2];

Вниз

Высокий/низкий уровень, ручное/автоматическое управление   Найти похожие ветки 

 
_oxffff   (2010-11-23 18:37) [280]


> euru ©   (23.11.10 17:36) [278]
>
> > oxffff ©   (16.11.10 14:24) [276]
> > Повторю, что мне интересен гибридный вариант управления
>
> > кучами.
>
> >Какие преимущества даёт такой вариант? Чем плох вариант,
>  когда в языке вообще нет понятия кучи?


А что есть?


 
_oxffff   (2010-11-23 18:47) [281]


> DiamondShark ©   (23.11.10 18:13) [279]
> > > U:=T; =>  T подтип U, либо есть ImplicitCast(T):U. вот
>
> > Два ограничения.
> >
> > В принципе, я согласен, что в данном случае это можно
> было
> > бы делать автоматически. Но, возможно, есть ситуации,
> когда
> > такой вывод будет некорректен.
>
> Это невозможно делать автоматически. Ограничения "T подтип
> U" и "есть ImplicitCast(T):U" -- семантически очень разные.
>
> Компилятор не долен заниматься телепатией (из этого ничего
> хорошего не получается).

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


>
>
> > Аналогично такую информацию можно вывести из примера.
> > T+U*Z-U.ABC(U,T).
>
> Здесь вообще туши свет.
> В С++ любая часть этого выражения может означать ВООБЩЕ
> ВСЁ ЧТО УГОДНО. Да ещё и разные вещи в разных контекстах!
>  Потому что "+", "*", "-", "( )" -- это всё перегружаемые
> операции. Из лексического анализа этого выражения ВООБЩЕ
> НЕЛЬЗЯ извлечь никакой информации, кроме того, что тут в
> данном месте стоят вот эти вот лексемы. Семантика этого
> выражения будет разной в разных контекстах, а контекст может
> быть в стопицотом по вложенности инклюде.
>


Причем здесь анализаторы. Речь о следующей стандии после лексических и синтаксических анализаторах, а именно о семантическом анализе.


> Плюсные шаблоны -- это ТЕКСТОВЫЕ макросы, в шаблоне вне
> контекста НЕТ СЕМАНТИКИ языка С++.


И?

Templates C++ это параметризованные типы с разнородными параметрами без задания отношений между типами или функциями из типа в тип.


> Шаблон -- это не код, не алгоритм. Это правило преобразования
> текста.
> Шаблоны С++ -- это не часть языка С++, это погружённый в
> С++ ДРУГОЙ ЯЗЫК, язык описания преобразований исходных текстов
> С++.
>
> Я же говорю: С++ проектировали шизофреники.
>
> Генирики -- это, наоборот, семантически определённые, независимые,
>  логически завершённые единцы кода. Они могут быть независимо
> скомпилированы, их семантика не зависит от контекста.


Знакомы с полиморфным лямбда исчислением?
Это два случая одного и того же.


 
euru ©   (2010-11-24 01:36) [282]


> DiamondShark ©   (23.11.10 18:13) [279]
> Это невозможно делать автоматически. Ограничения "T подтип
> U" и "есть ImplicitCast(T):U" -- семантически очень разные.
> Компилятор не долен заниматься телепатией (из этого ничего
> хорошего не получается).

Почему невозможно? Это же взаимоисключающие условия: либо T - подтип U, либо T - не подтип U, но поддерживает операцию неявного привидения типа T к типу U.


 
euru ©   (2010-11-24 01:52) [283]


> _oxffff   (23.11.10 18:37) [280]
> А что есть?

Например, убрать из языка оператор new. Тогда, возможно, и dispose (или его аналоги) не понадобятся.


 
euru ©   (2010-11-24 02:07) [284]


> _oxffff   (23.11.10 18:47) [281]
> > > Аналогично такую информацию можно вывести из примера.
> > > T+U*Z-U.ABC(U,T).
> > Здесь вообще туши свет.
>
> Причем здесь анализаторы. Речь о следующей стандии после
> лексических и синтаксических анализаторах, а именно о семантическом
> анализе.

Если оператор *(U, Z) будет в обоих типах U и Z, то и семантический анализ не поможет однозначно выбрать нужный оператор.


 
_oxffff   (2010-11-24 08:32) [285]


> euru ©   (24.11.10 01:52) [283]
>
> > _oxffff   (23.11.10 18:37) [280]
> > А что есть?
>
> Например, убрать из языка оператор new. Тогда, возможно,
>  и dispose (или его аналоги) не понадобятся.


То есть нет объектов вне записи активации. Тогда все объекты будут вычищаться при финализации записи активации(по выходу из функции\процедуры\методу). То есть динамических структрур данных нет.
Только глобальные преопределенные объекты.
Суть примененения такого языка мне не понятна.


 
_oxffff   (2010-11-24 08:36) [286]


> euru ©   (24.11.10 02:07) [284]
>
> > _oxffff   (23.11.10 18:47) [281]
> > > > Аналогично такую информацию можно вывести из примера.
>
> > > > T+U*Z-U.ABC(U,T).
> > > Здесь вообще туши свет.
> >
> > Причем здесь анализаторы. Речь о следующей стандии после
>
> > лексических и синтаксических анализаторах, а именно о
> семантическом
> > анализе.
>
> Если оператор *(U, Z) будет в обоих типах U и Z, то и семантический
> анализ не поможет однозначно выбрать нужный оператор.


1.  Ничего страшного. Не все generics можно инстанцировать. Будет выведено сообщение о неоднозначности выбора при выборе оператора.
2. Современные языки отслеживают конфликты перегруженных операторов.
Поэтому сообщение об ошибке определения U и Z могут появиться еще до использования generics.


 
euru ©   (2010-11-24 10:42) [287]


> _oxffff   (24.11.10 08:32) [285]
> То есть нет объектов вне записи активации. Тогда все объекты
> будут вычищаться при финализации записи активации(по выходу
> из функции\процедуры\методу). То есть динамических структрур
> данных нет. Только глобальные преопределенные объекты.

Если в языке нет явных конструкций для работы с динамическими структурами, то это не означает, что такая возможность не может существовать неявно.
Примеры: массивы в Бейсике, строки в Паскале.


 
euru ©   (2010-11-24 11:06) [288]


> _oxffff   (24.11.10 08:36) [286]
> 1.  Ничего страшного. Не все generics можно инстанцировать.
>  Будет выведено сообщение о неоднозначности выбора при выборе
> оператора.2. Современные языки отслеживают конфликты перегруженных
> операторов.Поэтому сообщение об ошибке определения U и Z
> могут появиться еще до использования generics.

Допустим, есть два класса:

class U
{
  int operator *(U value1, Z value2)
  {
    return 1;
  }
}

class Z
{
  int operator *(U value1, Z value2)
  {
    return 2;
  }
}


Далее определим ещё один класс:

class A<T>
{
  U field1 = new U();
  T field2;
  int field3;

  A(T field)
  {
    field2 = field;
    field3 = field1 * field2;
  }
}


И где-то дальше в коде определим переменную:
A<Z> a = new A<Z>(new Z());

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


 
DiamondShark ©   (2010-11-24 11:08) [289]


> Почему невозможно? Это же взаимоисключающие условия: либо
> T - подтип U, либо T - не подтип U, но поддерживает операцию
> неявного привидения типа T к типу U.


Потому что есть три возможности сгенерировать констрейнт
- (T is U)
- (ImplicitCast(T):U)
- (T is U) or (ImplicitCast(T):U)

Компилятор не должен угадывать, что имел в виду пользователь.


> 2. Современные языки отслеживают конфликты перегруженных
> операторов.

Эти перегрузки могут быть описаны в разных библиотеках.
Эти перегрузки могут быть вообще не известны на момент компиляции определения генерика.

Генерики должны обеспечивать возможность независимой компиляции, что становится невозможным, если семантический анализ откладывается до момента инстанцирования.

С++ такими вещами не заморачивается, потому что в месте инстанцирования происходит ЛЕКСИЧЕСКАЯ подстановка, и сгенерированный код далее компилируется обычным образом.
Это, кстати, и обуславливает шизофреничность диагностики при ошибках инстанцирования, потому что ошибка возникает не в коде, написанном пользователем, а в сгенерированном коде, который существует только во внутреннем представлении компилятора, и, вообще говоря, не обязан иметь ОБРАТНОЕ отображение в пользовательский код.


 
_oxffff   (2010-11-24 11:10) [290]


> euru ©   (24.11.10 10:42) [287]


А разве строки и массивы в Pascal не имеют оператора New?
Имеют,но по другому называется и вызывается неявно Но смысл тот же.

Речь о том, как Вы собираетесь создать объект(аллокировать и инициализировать) и допустим детерминированно финализировать
без new, dispose?

Можно синтаксис и семантику?


 
DiamondShark ©   (2010-11-24 11:36) [291]


> А разве строки и массивы в Pascal не имеют оператора New?

Строки и массивы в Pascal не имеют оператора New. Это value-типы.


> Можно синтаксис и семантику?

Легко.

Все типы языка -- value-типы. Есть специальный тип reference.
Экземпляр value-типа жив пока жива хоть одна reference на него.

Пример.

type
 MyRecord = record
   a,b,c : integer;
 end;

procedure Foo() : reference to MyRecord;
var
 r: MyRecord;
begin
 r.a := 1;
 r.b := 2;
 r.c := 3;
 return @r;
end;

procedure Bar() : MyRecord;
var
 r: MyRecord;
begin
 r.a := 1;
 r.b := 2;
 r.c := 3;
 return r;
end;

procedure Main;
var
 r: MyRecord;
 rr: reference to MyRecord;
begin
 rr := Foo(); // динамический экземпляр
 r := Bar(); // копирование
 rr := nil; // удаление
end;

Никаких new|dispose


 
euru ©   (2010-11-24 11:48) [292]


> DiamondShark ©   (24.11.10 11:08) [289]
> Компилятор не должен угадывать, что имел в виду пользователь.

Пользователь имел в виду возможность преобразования типа T в тип U.
Компилятору оба типа известны. Если U - базовый тип для T, то используется преобразование (T is U). Если T и U - независимые типы, то проверяется наличие описания преобразования (ImplicitCast(T):U). Если такое преобразование есть, то оно выполняется, если нет - выдаётся сообщение об ошибке. Одновременное выполнение этих условий невозможно, потому что неявное преобразование в базовый класс/из базового класса запрещено (по крайней мере, в C#).
В каких тогда случаях может возникнуть неоднозначность?


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

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


 
euru ©   (2010-11-24 11:59) [293]


> _oxffff   (24.11.10 11:10) [290]
> Можно синтаксис и семантику?

Ну, собственно в [291] приведён пример.
Только теперь мне не совсем понятно, в чём разница между procedure Foo() : reference to MyRecord; и procedure Bar() : MyRecord;. И для каких целей она нужна. :)


 
DiamondShark ©   (2010-11-24 12:38) [294]


> Пользователь имел в виду возможность преобразования типа
> T в тип U.

Это преобразование бывает двух типов: с изменением представления и без изменения представления. Это семантически разные операции.


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

Потому что "a+b" может означать следующее:
- встроенная операция
- перекрытый оператор, определённый как функция верхнего уровня
- перекрытый оператор, определённый типом a
- перекрытый оператор, определённый типом b
- неявное преобразование из a во что-нибудь, что позволит применить что-нибудь из вышеперечисленного
- неявное преобразование из b во что-нибудь, что позволит применить что-нибудь из вышеперечисленного
Всё это помножить на ограничения на тип результата.

Эту всю байду надо записать в метаданные библиотеки. Для этого надо всё это реализовать в компиляторе, задокументировать и протестировать. Получится долго, дорого, тормозно и глючно.
А главное -- нафиг не нужно.

Не нужно, потому что программы пишутся не для того, чтобы запутать израильскую разведку, типа: "я напишу a+b и хрен кто догадается, что это означает". Фигтам. Программы пишут для того, чтобы их понимать и сопровождать. А для этого семантика кода должна быть ясна из самого кода (а не из инклуда на 5 мегов 80 уровня вложенности).

Когда [психически здоровым] программистом пишется "a+b" это подразумевает некую семантику операции (или семантический класс операций), известную в МОМЕНТ НАПИСАНИЯ этого факинг фрагмента кода.
Отсюда следует, что ограничния на типы операндов УЖЕ ИЗВЕСТНЫ этому долбанному уроду, который пишет этот булшит.

Поэтому самым разумным вариантом будет
- викинуть из компиляции генериков анализ перегрузок
- потребовать явного определения контракта взаимодействия параметров.


 
DiamondShark ©   (2010-11-24 12:48) [295]


> И для каких целей она нужна. :)

иллюстрация создания динамических структур без явных операторов new|dispose.

Правда, пользователь такого языка первым делом напишет процедуру

procedure New<TRecord> : reference to TRecord;
var
r: TRecord;
begin
 ZerroMemory(r, sizeof(TRecord));
 return @r;
end;

(а в случае отсутствия генериков -- копию для каждого типа, который предполагается использовать в динамических структурах)
и будет долго материть разработчиков за то, что не предоставили синтаксический сахар в виде оператора new

%)


 
_oxffff   (2010-11-24 13:06) [296]


> euru ©   (24.11.10 11:06) [288]
>
> > _oxffff   (24.11.10 08:36) [286]
> > 1.  Ничего страшного. Не все generics можно инстанцировать.
>
> >  Будет выведено сообщение о неоднозначности выбора при
> выборе
> > оператора.2. Современные языки отслеживают конфликты перегруженных
>
> > операторов.Поэтому сообщение об ошибке определения U и
> Z
> > могут появиться еще до использования generics.
>
> Допустим, есть два класса:
>
> class U
> {
>   int operator *(U value1, Z value2)
>   {
>     return 1;
>   }
> }
>
> class Z
> {
>   int operator *(U value1, Z value2)
>   {
>     return 2;
>   }
> }
>
> Далее определим ещё один класс:
>
> class A<T>
> {
>   U field1 = new U();
>   T field2;
>   int field3;
>
>   A(T field)
>   {
>     field2 = field;
>     field3 = field1 * field2;
>   }
> }
>
> И где-то дальше в коде определим переменную:
> A<Z> a = new A<Z>(new Z());
>
> Какое сообщение должен выдать компилятор, чтобы разработчику
> было понятно, почему его код не компилируется?


1. При определении U и Z компилятор проверяет набор перегруженных операторов. И сообщает об ошибке неоднозначности определения U и Z.

2. При интанцировании обобщенного типа компилятор проверяет автоматически выведенные constraints на существование и единственность оператора *. Единственность можно ослабить в рамках различных классов эквивалентности, добавив например приоритет методам-операторам *(хотя при условии 1 это ненужно).


 
DiamondShark ©   (2010-11-24 14:29) [297]

Мы вот тут спорим, спорим. А на основной вопрос системотехники(*) так и не ответили.

Вот скажите, кому нафиг нужен шаблон типа

U Foo<U,V,W>(V x, W y)
{
return x + y;
}

Что в переводе на человеческий означает эта функция?
"Сделай над операндами x и y нечто, непоймичего, что неизвестно где обозначено символом +; результат неизвестно каким образом преобразуй в тип U".

В чём радость иметь такой, простихоспидя, "обобщённый алкогоритм"?

-------------------
*основной вопрос системотехники: "А нафига?"


 
euru ©   (2010-11-24 14:57) [298]


> DiamondShark ©   (24.11.10 12:38) [294]

> Это преобразование бывает двух типов: с изменением представления
> и без изменения представления. Это семантически разные операции

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


> Потому что "a+b" может означать следующее:

- встроенная операция
Только для встроенных типов. Соответственно, вся необходимая информация компилятору известна.
- перекрытый оператор, определённый как функция верхнего уровня
Такая возможность не должна поддерживаться компилятором, иначе неопределённости возникали бы и без дженериков.
- перекрытый оператор, определённый типом a
- перекрытый оператор, определённый типом b
- неявное преобразование из a во что-нибудь, что позволит применить что-нибудь из вышеперечисленного
- неявное преобразование из b во что-нибудь, что позволит применить что-нибудь из вышеперечисленного

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


> Эту всю байду надо записать в метаданные библиотеки. Для
> этого надо всё это реализовать в компиляторе, задокументировать
> и протестировать. Получится долго, дорого, тормозно и глючно.
> А главное -- нафиг не нужно.

Такая же аргументация в конце прошлого века была и по отношению к объектно-ориентированным языкам. Однако они всё-таки почему-то появились.


> Не нужно, потому что программы пишутся не для того, и т.д.

Если вызывается виртуальная функция либо функция интерфейса, то, я так понимаю, израильская разведка догадается, что может сделать эта функция, и ей не придётся изучать те же 5 мегов.


 
euru ©   (2010-11-24 15:15) [299]


> _oxffff   (24.11.10 13:06) [296]

> 1. При определении U и Z компилятор проверяет набор перегруженных
> операторов. И сообщает об ошибке неоднозначности определения
> U и Z.

Классы U, Z и A<T> определены в библиотеке. Класс U вообще может оказаться приватным.
И что тогда должно разъяснить это сообщение, если программисту вообще неизвестно о существовании такого типа U?


 
euru ©   (2010-11-24 15:29) [300]


> DiamondShark ©   (24.11.10 14:29) [297]

> Вот скажите, кому нафиг нужен шаблон типа

Во-первых, такие же вопросы можно задавать и про сборщик мусора, и про ООП.
Во-вторых, могу предложить другой шаблон:
class Vector<T>
{
  Vector<T> operator +(Vector<T> a, Vector<T> b)
  {
    // Создание нового вектора, элементы которого равны
    // сумме соответствующих элементов векторов a и b
  }
}


 
euru ©   (2010-11-24 15:57) [301]


> DiamondShark ©   (24.11.10 12:48) [295]

> иллюстрация создания динамических структур без явных операторов
> new|dispose.

Не понимаю необходимость таких структур.

procedure New<TRecord> : TRecord;
var r: TRecord;
begin
return r;
end;

По-моему, этого вполне достаточно, чтобы вернуть из функции инстанцированный объект типа TRecord.


 
DiamondShark ©   (2010-11-24 16:28) [302]


> euru ©   (24.11.10 15:57) [301]
> Не понимаю необходимость таких структур.

facepalm.jpg

"
-- Приведите пример функции
-- int Foo() {return 17;}
-- Не понимаю необходимость таких функций
"

Надеюсь, необходимость структур, вроде

TListNode = record
data: string;
next: ^TListNode;
end

вы понимаете?


> По-моему, этого вполне достаточно, чтобы вернуть из функции
> инстанцированный объект типа TRecord.

По-моему, это вернёт копию.


> euru ©   (24.11.10 15:29) [300]
> Во-первых, такие же вопросы можно задавать и про сборщик
> мусора, и про ООП.


ИЧСХ, на них был даден убедительный ответ.

Ответа на вопрос: "Нафига нужна возможность МЕТОД обозначать символом плюсика" нет. Более того, ничего более убедительного, чем: "А шоб было, по-приколу же!" -- и быть не может.


> Во-вторых, могу предложить другой шаблон:


class Vector<T>
{
 Vector<T> Add(Vector<T> a, Vector<T> b)
 {
   // Создание нового вектора, элементы которого равны
   // сумме соответствующих элементов векторов a и b
 }
}

Нафига там плюсик? Ага, знаю. Чтоб можно было написать вот так:
template<T> T PlusAny(T x, T y){ return x + y;}
и назвать это "обобщённым алгоритмом".

Сюда влезет и сложение целых цисел, и векторная сумма и конкатенация строк.

А нафига нужно такое обобщение?


 
Mystic ©   (2010-11-24 16:50) [303]


> Нафига там плюсик? Ага, знаю. Чтоб можно было написать вот
> так:
> template<T> T PlusAny(T x, T y){ return x + y;}
> и назвать это "обобщённым алгоритмом"


Это не обобщенный алгоритм, это просто другой способ записи. Перегрузка операторов эквивалентна вызовам функций. Просто иногда бывает более удобна, например

Y := Add(Multiply(A, X), B);

выглядит малочитаемо :)

Вот выражение U.ABC(U,T) уже интереснее, ибо U.ABC может быть вызовом функции, а может быть именем типа. Но, как раз, C++ такое не разруливает на автомате, обязывая писать typename.


 
DiamondShark ©   (2010-11-24 17:12) [304]


> Перегрузка операторов эквивалентна вызовам функций.

Замечательно.
Можно ли написать такой шаблон:

template<T> T FooBarAny(T x, T y){ return T.FooBar(x, y);}

?

НетЪ.
Почему?


 
Mystic ©   (2010-11-24 17:40) [305]


> НетЪ.
> Почему?


Почему нельзя?


 1 class A
 2 {
 3   public:
 4     static A FooBar(A x, A y) { return A(); }
 5 };
 6
 7 template<typename T>
 8   T FooBarAny(T x, T y)
 9 {
10   return T::FooBar(x, y);
11 }
12
13 int main()
14 {
15   A x, y;
16   FooBarAny(x, y);
17   return 0;
18 }


 
DiamondShark ©   (2010-11-24 18:19) [306]


> Mystic ©   (24.11.10 17:40) [305]

Жэсть. Лишнее подтверждение тому, что плюсные шаблоны -- это лексические макросы.


 
Mystic ©   (2010-11-24 18:36) [307]


> Лишнее подтверждение тому, что плюсные шаблоны -- это лексические
> макросы.


Не совсем, хотя как смотреть...


 1 class A
 2 {
 3   public:
 4     static A FooBar(A x, A y) { return A(); }
 5 };
 6
 7 class B
 8 {
 9   public:
10     class FooBar
11     {
12       public:
13         FooBar(B x, B y) {}
14         operator B() { return B(); }
15     };
16 };
17
18 template<typename T>
19   T FooBarAny(T x, T y)
20 {
21   return T::FooBar(x, y);
22 }
23
24 template<typename T>
25   T FooBarAny2(T x, T y)
26 {
27   return typename T::FooBar(x, y);
28 }
29
30 int main()
31 {
32   A x, y;
33   B xx, yy;
34   FooBarAny(x, y);
35   // FooBarAny(xx, yy); // error: error: dependent-name "T::FooBar" is parsed as a non-type, but instantiation yields a type
36   FooBarAny2(xx, yy);
37   // FooBarAny2(x, y); // error: error: no type named "FooBar" in "class A"
38   return 0;
39 }


 
euru ©   (2010-11-25 10:06) [308]


> DiamondShark ©   (24.11.10 16:28) [302]

> Надеюсь, необходимость структур, вроде
> TListNode = record
> data: string;
> next: ^TListNode;
> end
> вы понимаете?
Необходимость таких структур понимаю. Только с точки зрения описания структуры символ "^" в ней лишний. Замените слово "record" на слово "class", и он станет ненужным, хотя смысл структуры не изменился.
Я уточню. Мне непонятно, зачем в языке поддерживать явное создание динамических структур.


> По-моему, это вернёт копию.

Возьмём пример из Дельфи

const S: String = "очень длинная строка...";

function New(): String;
begin
  Result := S;
end;


Что вернёт функция New? Копию строки или ссылкку на неё?


> ИЧСХ, на них был даден убедительный ответ.

Убедительный - это когда другие варианты ответов будут неверными? Однако существует, например, язык Дельфи, в котором нет сборщика мусора. Существует Прогог, которые не объектно-ориентированный. И с точки зрения этих языков такой ответ ни разу не убедительный.


> Нафига там плюсик? Ага, знаю. Чтоб можно было написать вот
> так:template<T> T PlusAny(T x, T y){ return x + y;}и назвать
> это "обобщённым алгоритмом".Сюда влезет и сложение целых
> цисел, и векторная сумма и конкатенация строк.А нафига нужно
> такое обобщение?

Сошлюсь-ка я на пару постов одно и того же автора из этой же темы: [43] и [119]. Уточнение: селёдка - это С++, паровая машина - это обобщение.


 
DiamondShark ©   (2010-11-25 12:02) [309]


> Необходимость таких структур понимаю. Только с точки зрения
> описания структуры символ "^" в ней лишний. Замените слово
> "record" на слово "class", и он станет ненужным, хотя смысл
> структуры не изменился.

TRectangle = record
Origin: TPoint;
Size: Tsize;
end;

Здесь смысл изменится.

Либо вы имеете структуры и ссылки, либо имеете сущности "record" и "class".
Те же фаберже в разных ракурсах.


> Я уточню. Мне непонятно, зачем в языке поддерживать явное
> создание динамических структур.


А какое ещё? Телепатическое?
Вот есть код:

var
 node: TListNode;
begin
// тут чего-то дофига происходит
node.next.data := "blablabla"; // вот тут чего должно произойти, если node.next = nil ?
Выделение нового узла или NullReferenceException?

Всё вам компилятор с телепатором подай...

Опять же, как различать копирование структур и копирование ссылок?


> Что вернёт функция New? Копию строки или ссылкку на неё?

В Дельфи это зависит от настроек компилятора.
Если String -- это ansi string, то вернётся ссылка;
Если String -- это pascal string, то вернётся копия.


> Убедительный - это когда другие варианты ответов будут неверными?

с абстрактным мышлением туго. Придётся на пальцах.

-- Курение вызывает зависимость и повышает риск заболеваний.
-- Курение нынче не в моде.

Первое утверждение убедительно, но это не значит, что второе неверное.


> Сошлюсь-ка я на пару постов

И всё-таки, зачем нужно обобщение сложения чисел и конкатенации строк?


 
Mystic ©   (2010-11-25 12:16) [310]


> Я уточню. Мне непонятно, зачем в языке поддерживать явное
> создание динамических структур.


Классы иногда лишний оверхид по производительности. Плюс работа с низкоуровневыми библиотеками/API.


 
DiamondShark ©   (2010-11-25 12:34) [311]


> Mystic ©   (25.11.10 12:16) [310]

В данном случае это не принципиально.


 
Mystic ©   (2010-11-25 12:42) [312]


> В данном случае это не принципиально.


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


 
DiamondShark ©   (2010-11-25 12:54) [313]


> Mystic ©   (25.11.10 12:42) [312]

Не-а. Мы пытаемся изобрести синтаксис и семантику языка, где бы вообще не было явного управления памятью.


 
Mystic ©   (2010-11-25 13:19) [314]


> Не-а. Мы пытаемся изобрести синтаксис и семантику языка,
>  где бы вообще не было явного управления памятью.


А чем не устраивают JavaScript, Lisp, Smalltalk?


 
_oxffff   (2010-11-25 14:29) [315]


> DiamondShark ©   (24.11.10 11:08) [289]
>
> > Почему невозможно? Это же взаимоисключающие условия: либо
>
> > T - подтип U, либо T - не подтип U, но поддерживает операцию
>
> > неявного привидения типа T к типу U.
>
>
> Потому что есть три возможности сгенерировать констрейнт
> - (T is U)
> - (ImplicitCast(T):U)
> - (T is U) or (ImplicitCast(T):U)
>
> Компилятор не должен угадывать, что имел в виду пользователь.
>
>


Если не думать в рамках текущей модели generics, а например ввести более общий T:=U(U assignable to T)?


>
> > 2. Современные языки отслеживают конфликты перегруженных
>
> > операторов.
>
> Эти перегрузки могут быть описаны в разных библиотеках.
> Эти перегрузки могут быть вообще не известны на момент компиляции
> определения генерика.

>

Будет выведено сообщение об ошибки о неоднозначности использования оператора * для U и T


 
euru ©   (2010-11-25 14:29) [316]


> DiamondShark ©   (25.11.10 12:02) [309]

> Либо вы имеете структуры и ссылки, либо имеете сущности
> "record" и "class".

Кроме структур и ссылок возможны и другие варианты. Например, в Паскале есть тип file. Это структура или ссылка?
В чём разница между сущностями record и class, кроме того что одна из них value type, а другая - reference type. А могут быть и другие сущности. Например, в Дельфи имеется ещё одна сущность - object. Чем она отличается от первых двух сущностей?


> Вот есть код:
> var  node: TListNode;
> begin
> // тут чего-то дофига происходит
> node.next.data := "blablabla"; // вот тут чего
> должно произойти, если node.next = nil ?Выделение нового
> узла или NullReferenceException?


Из [291] имеем: "Все типы языка -- value-типы. Есть специальный тип reference." Вопрос: зачем нужен reference?
Из [295] получаем ответ: "иллюстрация создания динамических структур без явных операторов new|dispose." Вопрос: зачем нужны динамические структуры?
Из [302] получаем ответ (если, конечно, я его правильно понял): например, для создания динамических списков.
Вопрос: неужели их нельзя создать без использования в языке понятия "ссылки"?

В приведённом примере (при условии, что используется некий язык, в котором все типы - это value type) поле TListNode.next - это тоже value type. Поэтому node.next.data := "blablabla"; отработает корректно и не приведёт ни к каким исключениям.


> Опять же, как различать копирование структур и копирование
> ссылок?
А их не нужно различать при отсутствии понятия "ссылка".


> В Дельфи это зависит от настроек компилятора.
> Если String -- это ansi string, то вернётся ссылка;
> Если String -- это pascal string, то вернётся копия.


Допустим, в настройках указано, что это ansi string. Тогда как будет работать следующий код:

var s1: string;
s1 := New(); // возвращается ссылка на S
s1 := "!!!"; // что произойдёт со строкой S

s1 := New(); // опять возвращается ссылка на S
S := "+++"; // значение s1 тоже изменится?



> И всё-таки, зачем нужно обобщение сложения чисел и конкатенации
> строк?

Про селёдку: Если в Паскале или С-подобных языках "+" используется для конкатенации строк, то это проблемы этих языков. Например, в РНР используется точка, в АВАР строки вообще с помощью команды concatenate объединяются.


 
_oxffff   (2010-11-25 14:37) [317]


> DiamondShark ©   (24.11.10 11:36) [291]
>
> > А разве строки и массивы в Pascal не имеют оператора New?
>
>
> Строки и массивы в Pascal не имеют оператора New. Это value-
> типы.


То есть хотите сказать, что строки строго определенной длины и размещаются на стеке?

>
>
> > Можно синтаксис и семантику?
>
> Легко.
>
> Все типы языка -- value-типы. Есть специальный тип reference.
>
> Экземпляр value-типа жив пока жива хоть одна reference на
> него.
>
> Пример.
>
> type
>  MyRecord = record
>    a,b,c : integer;
>  end;
>
> procedure Foo() : reference to MyRecord;
> var
>  r: MyRecord;
> begin
>  r.a := 1;
>  r.b := 2;
>  r.c := 3;
>  return @r;
> end;
>
> procedure Bar() : MyRecord;
> var
>  r: MyRecord;
> begin
>  r.a := 1;
>  r.b := 2;
>  r.c := 3;
>  return r;
> end;
>
> procedure Main;
> var
>  r: MyRecord;
>  rr: reference to MyRecord;
> begin
>  rr := Foo(); // динамический экземпляр
>  r := Bar(); // копирование
>  rr := nil; // удаление
> end;
>
> Никаких new|dispose


Ну, ну. Прямо таки никаких new. Строго говоря написана обертка для оператора new для myrecord. Базируется на подобии замыканий(захват и продление жизни). И чем это собственно отличается от оператора new?
Для каждого типа своя обертка. А new - полиморфен.
Причем не следуют забывать о том, что new не только аллокирует, но еще и инициализирует сущность. Интересно какой будет введен еще абстрактный механизм для duck typing для конструкторов в вашем языке. Чтобы в итоге получится недовелосипед new?


 
euru ©   (2010-11-25 14:39) [318]


> Mystic ©   (25.11.10 12:42) [312]

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

Нет. Основная идея в том, что если нужен указатель на запись, то там действительно нужен указатель на запись?


 
_oxffff   (2010-11-25 14:42) [319]


> DiamondShark ©   (24.11.10 12:48) [295]
>
> > И для каких целей она нужна. :)
>
> иллюстрация создания динамических структур без явных операторов
> new|dispose.
>
> Правда, пользователь такого языка первым делом напишет процедуру
>
> procedure New<TRecord> : reference to TRecord;
> var
> r: TRecord;
> begin
>  ZerroMemory(r, sizeof(TRecord));
>  return @r;
> end;
>
> (а в случае отсутствия генериков -- копию для каждого типа,
>  который предполагается использовать в динамических структурах)
> и будет долго материть разработчиков за то, что не предоставили
> синтаксический сахар в виде оператора new
>
> %)


Вместо одного new. Вводятся смысл замыкания и еще где опять инициализация типа? Как передать различные параметры? Как проверять?


 
euru ©   (2010-11-25 14:42) [320]


> Mystic ©   (25.11.10 13:19) [314]

> А чем не устраивают JavaScript, Lisp, Smalltalk?

Тем, что они уже есть. :)



Страницы: 1 2 3 4 5 6 7 8 9 
10 11 вся ветка

Форум: "Прочее";
Текущий архив: 2011.03.20;
Скачать: [xml.tar.bz2];

Наверх





Память: 1.14 MB
Время: 0.069 c
4-1246533531
ruben
2009-07-02 15:18
2011.03.20
Не вызываются события при работе с tapi


15-1291843798
Юрий
2010-12-09 00:29
2011.03.20
С днем рождения ! 9 декабря 2010 четверг


8-1208898067
Музыкант
2008-04-23 01:01
2011.03.20
Циклическое проигрывание midi-файла без разрывов в звучании


15-1291751037
Сергей М.
2010-12-07 22:43
2011.03.20
А как нужно умудриться


3-1255340705
Yurikon
2009-10-12 13:45
2011.03.20
Ошибка с драйвером Access





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский