[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: programming languages



Evening, Andrei. 

Andrei Sosnin <demonsly@hot.ee> 01:39 11/1/2003 wrote:

>>  AS> В С++ эти элементы имеют определенные типы! Они, правда, подводятся
>>  AS> под шаблоны, но проверка типов там строгая, и трюки с void * там не
>>  AS> пройдут - придется применять специальные операторы-функции:
>>  AS> static_cast или dynamic_cast! Вот точное, концептуальное определение
>>  AS> данной функции (из STL):
>>  AS> template<class In, class Op> Op for_each( In first, In last, Op
>> f){
>>  AS> 	while (first != last) f(*first++);
>>  AS> 	return f;
>>  AS> }
>> Вопрос: где зафиксирована информация о том, что f должна принимать
>> аргумент того же типа, который имеет (*first++)?

 AS> В определении Op (класса объекта f).
[skip общие сведения об итератора, операторах ++ и *]
 AS> Значение элемента всегда имеет строго определенный тип. В приведенном
 AS> ниже примере *(lc.begin()) будет иметь тип Club, так как lc.begin()
 AS> указывает на первый элемент списка lc, состоящего из объектов типа
 AS> Club.
Вот именно. Всегда будет иметь _строго_ _определенный_ тип. А как насчет
_произвольного_ типа, главное, чтобы он совпадал с типом аргумента функции
f, который тоже _произвольный_? Как сделать hard-coded решение на шаблонах
для конкретной задачи - мне понятно. Мне также понятно, как можно возвести
это решение в ранг "универсального"/"библиотечног", обвешав его "своими", "удобными"
реализациями контейнеров, итераторов и т.п. (по этому пути пошел STL). Мне
непонятно, как заставить это решение работать в самом общем случае. Более
того - я уверен, что реализовать такое решение невозможно.

 AS> Например (из "Языка программирования С++"):
[skip пример со строго указанными hardcoded типами]


>> И где же ответ на мои вопросы? Я повторю:
>> 1)Каким образом происходит проверка того, что function_obj принимает аргумент
>> именно того типа, который содержится в списке?

 AS> Это уже компетенция компилятора, я думаю... ;-) То есть компилятор
 AS> ДОЛЖЕН проверять это, и он это делает. Это провеяет модуль STL
 AS> (Standard Templates Library), который "инстанцирует" из шаблона list
 AS> классы вида list<int>, list<MyClass>, ... Если ты берешь объект
 AS> my_list класса list<MyClass> и пытаешься сделать с ним вот это:

 AS> for_each(my_list.begin(), my_list.end(), addvaluesbyone());

AS> И при этом класс addvaluesbyone не перегружает оператор () или этот
 AS> перегруженный оператор не принимает объекты типа MyClass, а только int
 AS> или float, или user_defined, то будет выдана ошибка компиляции.
Вот. А если функция принимает, к примеру, аргумент типа ConcreteSuperclassOfMyClass -
будет ли ошибка или нет? Если нет - то правильно ли это? :) Я считаю, что
это - неправильно, приводит к трудноловимым ошибкам и костылям.

>> 2)Этот вопрос я сформулировал неверно. Постараюсь изменить. Есть ли способ
>> сделать type-safe композицию двух произвольных функций?
>> Т.е. написать функцию compose типа
>> forall c a b. (b -> c) -> (a -> b) -> a -> c
>> которая реализует композицию фунций (в том смысле, в котором это
>> определено
>> в математике, (compose f g)(x) = f(g(x)))
>> Сколько строк кода на это потребуется? Что будет с проверкой типов?
>>

 AS> Ах вот оно что! Ты хочешь реализацию сложной функции f(g(x))?

 AS> Вот реализация на С:

 AS> float f(float (*g_func)(float x)){
	
 AS> 	float a = (*g_func)(x);
 AS> 	return sin(sqrt(a));

 AS> }

 AS> float g(float x){
	
 AS> 	return do_something(x);

 AS> }

 AS> Совершенно type-safe.
Да-да. Машина может быть любого цвета, лишь бы этот цвет был черным (с)
компания Форд.

Ты не замечаешь разницы между тем, что написал я, и тем, что написал ты? У
меня функция f имеет тип "отображение из X в Y", функция g имеет тип
"отображение из Y в Z", результат compose имеет тип "отображение из X в Z",
где X,Y,Z - _произвольные_ типы. Главное, чтобы тип результата f и
аргумента g совпадал.

Как мне при помощи твоего "решения" скомбинировать функции из float в
string и из string в int ?

 AS> Другое дело, что с такой специлизацией это в
 AS> универсальную библиотеку С не в ставишь, но для конкретных мелких
 AS> задач вполне подойдет.
Т.е. не Иванов, а Рабинович, не в лотерею, а в казино, не Волгу, а
Мерседес, и не выиграл, а проиграл? :) Как по мне - соверешенно не похоже
на "да! это можно сделать и на С!".

 AS> На С++ это можно записать совершенно также, но можно применить и ООП-метод.
Увы, скорее "так же", а не "также". Так же плохо.

AS> Например:

 AS> template <class T>
 AS> class composite_func {
 AS> T rep;
[skip]
 AS> 	T operator()(T arg){
 AS> 		//do something with arg using g
 AS> 		return arg;
 AS> 	}
 AS> };

 AS> Теперь composite_func можно использовать как обычную функцию. Только
 AS> инстанциация должна проходить так, например: composite_func<float>();
Ничего, что у тебя получаются только функции из X в X? :)


 AS> Наконец, замечу, что С++ все-таки язык системного программирования, и
 AS> он оптимизирован именно под системные нужды - скорость,
 AS> низкоуровневость (привязанность к системным особенностям), ... Я не
 AS> могу сказать, что он лучше всех, сверх-универсален, "и ваще". :-)
Этого никто и не говорил. И не просил доказать. Просто были
продемонстрированы (мной) некие принципы, которые, по моему мнению, делают
ФЯ более предпочтительными средствами для программирования, чем
императивные языки. Было сказано - "на С++ можно все то же самое". Из твоей
последней фразы следует, что где-то по пути предмет спора был волшебным
образом подменен на какой-то другой, мне неизвестный ... :)

 AS> Еще я советую где-нибудь достать христоматийную книгу от Бьерна
 AS> Страуструпа "Язык программирования С++". У меня дома лежит русский
 AS> перевод от издательства "БИНОМ" 1999 года. Оригинал был издан
 AS> Addison-Wesley Longman. Очень полезная книга для тех кто сомневается в
 AS> достоинствах С++ или плохо с ним знаком.
Да-да.... А кто до сих пор сомневается - плохо ее читал, так? :)

-- 
Dmitry Astapov //ADEpt                               E-mail: adept@umc.com.ua
GPG KeyID/fprint: F5D7639D/CA36 E6C4 815D 434D 0498  2B08 7867 4860 F5D7 639D



Reply to: