J>> и еще отсутствие разделения на процедуры и функции
СГ>Загадка. Слабо на Си или Си++ написать тип функции принимающей в качестве аргумента и возвращающей переменную ее собственного типа?
Загадка 1. Как на Component Pascal реализуется ну простейшая задача — одномерный динамический массив (список) объектов? Интересует как синтаксически, так и по скорости. Типа vector<CMyType>.
Загадка 2. Как на нем же реализуется собственный тип, который по поведению аналогичен простому типу. Пример: Math.Complex, DateTime. Как синтаксически будет выглядеть работа с этим типом?
Загадка 3. Как часто мне приходилось решать твою загадку на пракике?
Сергей Губанов пишет:
> J> и еще отсутствие разделения на процедуры и функции > Загадка. Слабо на Си или Си++ написать тип функции принимающей в > качестве аргумента и возвращающей переменную ее собственного типа? > На Component Pascal это элементарно:
Да пожалуйста, правда будет не функция, а функтор:
============================
struct ReccuringFunctor
{
ReccuringFunctor* operator()(ReccuringFunctor* some)
{
return some;
}
};
ReccuringFunctor weirdFunc;
ReccuringFunctor *weirdFuncPtr;
J>>> и еще отсутствие разделения на процедуры и функции
СГ>>Загадка. Слабо на Си или Си++ написать тип функции принимающей в качестве аргумента и возвращающей переменную ее собственного типа?
Кё>Загадка 1. Как на Component Pascal реализуется ну простейшая задача — одномерный динамический массив (список) объектов? Интересует как синтаксически, так и по скорости. Типа vector<CMyType>.
ARRAY OF CMyType
POINTER TO ARRAY OF CMyType
Кё>Загадка 2. Как на нем же реализуется собственный тип, который по поведению аналогичен простому типу. Пример: Math.Complex, DateTime. Как синтаксически будет выглядеть работа с этим типом?
TYPE
Complex = RECORD re, im: REAL; END;
DateTime = RECORD
year : INTEGER;
month: BYTE;
day : BYTE;
hour : BYTE;
min : BYTE;
sec : BYTE;
END;
PROCEDURE Sum(IN a,b: Complex; OUT c: Complex);
BEGIN
c.re := a.re + b.re; c.im := a.im + b.im
END Sum;
...
Кё>Загадка 3. Как часто мне приходилось решать твою загадку на пракике?
Наверное Вы ее встретили в первый раз здесь. Ранее она просто в голову не могла придти. Язык ограничивает мышление.
Здравствуйте, Cyberax, Вы писали:
C>Сергей Губанов пишет:
>> J> и еще отсутствие разделения на процедуры и функции >> Загадка. Слабо на Си или Си++ написать тип функции принимающей в >> качестве аргумента и возвращающей переменную ее собственного типа? >> На Component Pascal это элементарно:
C> Да пожалуйста, правда будет не функция, а функтор
Класс объекты которого имеют метод принимающий в качестве аргумента и возвращающий указатели на объекты этого класса интереса для меня не представляет.
Я хочу тип обычной функции.
TYPE
Action = PROCEDURE (a: Action) : Action;
PROCEDURE^ g(a: Action): Action; (* forward declaration *)PROCEDURE f(a: Action): Action;
BEGIN(* ... *)IF a # NIL THEN RETURN a ELSE RETURN g END
END f;
PROCEDURE g(a: Action): Action;
BEGIN(* ... *)IF a # NIL THEN RETURN a ELSE RETURN f END
END g;
Здравствуйте, Сергей Губанов, Вы писали:
Кё>>Загадка 1. Как на Component Pascal реализуется ну простейшая задача — одномерный динамический массив (список) объектов? Интересует как синтаксически, так и по скорости. Типа vector<CMyType>.
СГ>
СГ>ARRAY OF CMyType
СГ>POINTER TO ARRAY OF CMyType
СГ>
простите, забыл привести код использования
PROCEDURE Init(VAR a: ARRAY OF CMyType);
VAR i: INTEGER;
BEGIN
FOR i := 0 TO LEN(a)-1 DO
a[i] := ....
END
END Init
VAR
dynam: POINTER TO ARRAY OF CMyType; (* Размещается в динамической памяти *)
stat : ARRAY 512 OF CMyType; (* Размещается на стеке *)BEGIN
NEW(dynam, 10); (* Создали массив из 10 элементов *)
Init(dynam);
Init(stat);
Здравствуйте, Сергей Губанов, Вы писали:
СГ>Здравствуйте, jazzer, Вы писали:
J>> и еще отсутствие разделения на процедуры и функции
СГ>Загадка. Слабо на Си или Си++ написать тип функции принимающей в качестве аргумента и возвращающей переменную ее собственного типа?
СГ>На Component Pascal это элементарно: СГ>
Здравствуйте, Сергей Губанов, Вы писали:
СГ>Здравствуйте, Cyberax, Вы писали:
C>>Сергей Губанов пишет:
>>> J> и еще отсутствие разделения на процедуры и функции >>> Загадка. Слабо на Си или Си++ написать тип функции принимающей в >>> качестве аргумента и возвращающей переменную ее собственного типа? >>> На Component Pascal это элементарно:
C>> Да пожалуйста, правда будет не функция, а функтор
СГ>Класс объекты которого имеют метод принимающий в качестве аргумента и возвращающий указатели на объекты этого класса интереса для меня не представляет.
СГ>Я хочу тип обычной функции.
> Если не секрет, зачем это нужно? Какую задачу такая штука решает?
Построение конечного автомата, в котором действие возвращает следующее состояние. Предвосхищая продолжение: да, согласен, такое решние не облокотилось при наличии множества других вариантов, доступных в т.ч. и из C++.
Posted via RSDN NNTP Server 1.9
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Кё>>Загадка 1. Как на Component Pascal реализуется ну простейшая задача — одномерный динамический массив (список) объектов? Интересует как синтаксически, так и по скорости. Типа vector<CMyType>.
СГ>ARRAY OF CMyType СГ>POINTER TO ARRAY OF CMyType СГ>PROCEDURE Init(VAR a: ARRAY OF CMyType); СГ>VAR i: INTEGER; СГ>BEGIN СГ> FOR i := 0 TO LEN(a)-1 DO СГ> a[i] := .... СГ> END СГ>END Init
Я немного не об этом. Динамические массивы в паскале — не новость для меня Я имел ввиду:
1. Вызов деструкторов при очищении массива, или перезаписывании одного элемента другим, или — если классы содержат такие указатели, что не могут быть просто так побитово скопированы — правильное копирование при реаллоке памяти, сдвигах при вставке и удалении.
2. Вставка и удаление элементов.
3. list<CMyType> — список объектов
4. map<string,CMyType>, hash_map — словарь
Кё>>Загадка 2. Как на нем же реализуется собственный тип, который по поведению аналогичен простому типу. Пример: Math.Complex, DateTime. Как синтаксически будет выглядеть работа с этим типом?
СГ>PROCEDURE Sum(IN a,b: Complex; OUT c: Complex); СГ>BEGIN СГ> c.re := a.re + b.re; c.im := a.im + b.im СГ>END Sum;
Вот именно. Только вычисляемое надо в возвращаемое значение: [pascal]procedure Sum(a,b:Complex): Complex[pascal]. И выглядеть это будет что-то вроде DateTimeIsGreater(DateTimeDiff(a, b), DateTimeDiff(c, d)) вместо a — b > c — d
Кё>>Загадка 3. Как часто мне приходилось решать твою загадку на пракике?
СГ>Наверное Вы ее встретили в первый раз здесь. Ранее она просто в голову не могла придти. Язык ограничивает мышление.
В конечном автомате Action наверняка будет объектом. Не только выполняемым, но и наверняка со свойствами/данными.
Здравствуйте, Кодёнок, Вы писали:
Кё>1. Вызов деструкторов при очищении массива, или перезаписывании одного элемента другим, или — если классы содержат такие указатели, что не могут быть просто так побитово скопированы — правильное копирование при реаллоке памяти, сдвигах при вставке и удалении.
Язык Component Pascal предполагает наличие сборщика мусора, то есть никаких деструкторов не бывает, у динамического объекта вместо деструктора есть метод FINALIZE-, который может вызвать только GC.
Кё>2. Вставка и удаление элементов. Кё>3. list<CMyType> — список объектов Кё>4. map<string,CMyType>, hash_map — словарь
Это все пишется врукопашную. для каждого конкретного типа отдельно. Впрочем можно написать это для какого-нибудь базового типа (например, для ANYPTR), а потом использовать эти же контейнеры для объектов типы которых есть расширения того базового типа (потомки) — использовать динамическое приведение типов.
Кё> Если только не капризничать "хочу чисто функцию и все тут", то это 100% аналогично приведенному тобой коду на паскале.
А я может капризный такой, вот не хочу тяжеловесное и громоздкое ООП, а хочу самую что ни на есть пересамую завалящуюся обыкновенную функцию...
Здравствуйте, jazzer, Вы писали:
СГ>>Я хочу тип обычной функции.
J>почему?
Вот например, язык Си в некотором смысле есть подмножество языка Си++, а Oberon-1 в некотором смысле есть подмножество языка Component Pascal. Можно сказать, что языки Си и Оберон-1 довольно таки низкоуровневые — все что в них есть, грубо говоря, это просто голые процедуры. Поэтому они очень простые языки. Программы на этих языках используются во встроенных системах. Встроенные системы должны обходиться очень малым количеством ресурсов и, зачастую, не могут позволить себе такое расточительство как runtime system языка С++.
Я хочу самую обычную переобычную самую завалящуюся функцию потому, что не гоже стрелять из пушки по воробъям, во всех случаях где только возможно нужно использовать самые простые средства.
Тип:
TYPE
A = PROCEDURE(a: A): A;
безусловно является самым простым средством. Привлечение же тяжеловесного механизма ООП для той же самой задачи как раз и есть стрельба из пушки по воробъям.
СГ>Язык Component Pascal предполагает наличие сборщика мусора, то есть никаких деструкторов не бывает, у динамического объекта вместо деструктора есть метод FINALIZE-, который может вызвать только GC.
OK, аналогично C#. Но как копирование? Как массив копирует объекты при прераспределении памяти — всегда побитово?
Кё>>2. Вставка и удаление элементов. Кё>>3. list<CMyType> — список объектов Кё>>4. map<string,CMyType>, hash_map — словарь
СГ>Это все пишется врукопашную. для каждого конкретного типа отдельно. Впрочем можно написать это для какого-нибудь базового типа (например, для ANYPTR), а потом использовать эти же контейнеры для объектов типы которых есть расширения того базового типа (потомки) — использовать динамическое приведение типов.
Ну вот, а сказал — не хочешь тяжеловесное и громоздкое ООП. Вот тебе и громоздкость, и ООП, и синтаксическая некрасивость.
Кё>> Если только не капризничать "хочу чисто функцию и все тут", то это 100% аналогично приведенному тобой коду на паскале.
СГ>А я может капризный такой, вот не хочу тяжеловесное и громоздкое ООП, а хочу самую что ни на есть пересамую завалящуюся обыкновенную функцию...
То, что тебе привели, абсолютно ничего тяжеловесного и громоздкого не содержит. Равно как и ООП. Просто считай, Action — пользовательский тип, размером с указатель на функцию, к которому добавлены специальные инструкции компилятору — как его вызывать (как и указатель на ф-ю), как проверять на ноль, и т.д. Все это inline-функции, которые оптимизируются в простейшие инструкции, почти полностью идентичные работе с указателем на функцию.
СГ>Вот например, язык Си в некотором смысле есть подмножество языка Си++, а Oberon-1 в некотором смысле есть подмножество языка Component Pascal. Можно сказать, что языки Си и Оберон-1 довольно таки низкоуровневые — все что в них есть, грубо говоря, это просто голые процедуры. Поэтому они очень простые языки. Программы на этих языках используются во встроенных системах. Встроенные системы должны обходиться очень малым количеством ресурсов и, зачастую, не могут позволить себе такое расточительство как runtime system языка С++.
Какая там runtime system? RTTI редко когда включают, обработка исключений разве что и stack unwinding. Но вот тот же GC в разы более расточителен, обработку исключений тоже можно выключить, если STL не нужна.
СГ>безусловно является самым простым средством. Привлечение же тяжеловесного механизма ООП для той же самой задачи как раз и есть стрельба из пушки по воробъям.
Нет ничего тяжеловесного в (фактически) макросах. Проблема у встроенных систем не с требовательностью языка C++ (нет никакой особой требовательности у него вообще), а в трудности создания компилятора С++. А что касается ресурсов, то встроенные системы обычно легко позволяют себе Java, сбору мусора, и не жужжат
Короче, не надо оправдывать куцость синтаксиса Component Pascal его скоростью , и называть это достоинством. Если там не дай бог нет inline-функций или оптимизатор не сообразит, что в некоторых отдельных случаях приведенную тобой функцию Sum(Complex,Complex,out Complex) можно и подставить, то это еще больший удар по бедной встроенной системе
Сергей Губанов пишет:
> СГ>>Я хочу *тип обычной функции*. > J>почему? > Вот например, язык Си в некотором смысле есть подмножество языка Си++, > а Oberon-1 в некотором смысле есть подмножество языка Component > Pascal. Можно сказать, что языки Си и Оберон-1 довольно таки > низкоуровневые — все что в них есть, грубо говоря, это просто голые > процедуры. Поэтому они очень простые языки. Программы на этих языках > используются во встроенных системах. Встроенные системы должны > обходиться очень малым количеством ресурсов и, зачастую, не могут > позволить себе такое расточительство как runtime system языка С++.
Runtime для С++ может быть очень небольшим...
> Я хочу самую обычную переобычную самую завалящуюся функцию потому, что > не гоже стрелять из пушки по воробъям, во всех случаях где только > возможно нужно использовать самые простые средства.
Да, а почему сам используешь при этом возможности Object Pascal'я, а не
обычный Pascal? Тем более, что функторы — это вовсе не "пушка". Кстати,
а покажи на Паскале аналог вот этого:
========================================
class Something : public virtual boost::signals::trackable
{
public:
void processMessage(std::vector<int> some1, double some2)
{
....
}
};
...
boost::signal<void(std::vector<int>, double)> sig;
Something s1=new Something();
Something s2=new Something();
...
sig.connect(boost::bind(&Something::processMessage,s1,_1,_2));
sig.connect(boost::bind(&Something::processMessage,s2,_1,_2));
sig(param1,param2);
delete s1;
sig(param1,param2);
delete s2;
========================================
> > Тип: > >TYPE > A = PROCEDURE(a: A): A; > > > безусловно является самым простым средством. Привлечение же > тяжеловесного механизма ООП для той же самой задачи как раз и есть > стрельба из пушки по воробъям.
Почему "механизм ООП" тяжеловесен? Кстати, а как твоим функциям
передавать КОНТЕКСТ вычислений? Или как обычно, через глобальные переменные?
Здравствуйте, Сергей Губанов, Вы писали:
СГ>А я может капризный такой, вот не хочу тяжеловесное и громоздкое ООП, а хочу самую что ни на есть пересамую завалящуюся обыкновенную функцию...
Может, в этом и проблема оберона, что простейший класс в С++, ничем не отличающийся и не несущий большей нагрузки для компилятора и рантайма, чем указатель на функцию, на обероне превращается в "тяжеловесное и громоздкое ООП" из-за обязательных GC и т.д?
Здравствуйте, Сергей Губанов, Вы писали:
СГ>Здравствуйте, jazzer, Вы писали:
СГ>>>Я хочу тип обычной функции.
J>>почему?
СГ>Вот например, язык Си в некотором смысле есть подмножество языка Си++, а Oberon-1 в некотором смысле есть подмножество языка Component Pascal. Можно сказать, что языки Си и Оберон-1 довольно таки низкоуровневые — все что в них есть, грубо говоря, это просто голые процедуры. Поэтому они очень простые языки. Программы на этих языках используются во встроенных системах. Встроенные системы должны обходиться очень малым количеством ресурсов и, зачастую, не могут позволить себе такое расточительство как runtime system языка С++.
А можно с этого места подробнее?
Как-то я не испытываю проблем при написании программ на С++ для КПК, и никакогорасточительного рантайма С++ не замечал — в С++ ведь нету никакой постулированной модульности и обязательной сборки мусора и т.д. и т.п..
СГ>Я хочу самую обычную переобычную самую завалящуюся функцию потому, что не гоже стрелять из пушки по воробъям, во всех случаях где только возможно нужно использовать самые простые средства.
class в С++ самое простое средство. В смысле, не сложнее, чем функция.
СГ>Тип: СГ>
СГ>TYPE
СГ> A = PROCEDURE(a: A): A;
СГ>
СГ>безусловно является самым простым средством. Привлечение же тяжеловесного механизма ООП для той же самой задачи как раз и есть стрельба из пушки по воробъям.
мой ответ — в ответе на твой ответ Кодёнку :)
В двух словах — в С++ механизм ООП не тяжеловесен, поэтому в С++ ты можешь выбрать то, что удобнее — эффективность не изменится.
Кё>>OK, аналогично C#. Но как копирование? Как массив копирует объекты при прераспределении памяти — всегда побитово?
СГ>Что значит перераспределение памяти?
Добавление еще 100 элементов, когда для них нет размера.