Использовать процедурный тип при объявлении процедуры\функци

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Использовать процедурный тип при объявлении процедуры\функци

Сообщение zub » 14.04.2017 01:21:54

Имеем примерно такой код
Код: Выделить всё
type TMyCommand=function(arg1:TMyArg):TMyCommandResult
...
function command1(arg1:TMyArg):TMyCommandResult;
...
function command2(arg1:TMyArg):TMyCommandResult;
...
function command100500(arg1:TMyArg):TMyCommandResult;
...
var
com:TMyCommand;
..
com:=GetNeededCommand;
res:=com(arg1:TMyArg)

Т.е. куча функций, та которую надо вызвать вычисляется в рантайме, и вызывается через переменную процедурного типа.
Зачем при объявлении 100500 функций надо писать полную декларацию? Потом приспичивает добавить например arg2 и приходится 100500 раз копипастить.
какнибудь так было бы гораздо логичней:
Код: Выделить всё
...
command1 TMyCommand;
begin
...
end;
...
command2 TMyCommand;
begin
...
end;
...

т.е. при декларации использовать уже определенный процедурный тип. все изменения можно производить централизовано.
Есть мнения за или против?
zub
долгожитель
 
Сообщения: 2884
Зарегистрирован: 14.11.2005 23:51:26

Re: Использовать процедурный тип при объявлении процедуры\фу

Сообщение Дож » 14.04.2017 02:31:19

Я только за, сам частенько страдаю от дублирования сигнатур.

Если сигнатуру много раз использую внутри одного модуля, то использую m4 макросы.

Возможный вариант чисто на текущем fpc — объявить параметры структурой
Код: Выделить всё
type
  TParams = record
    Arg: TMyArg;
  end;
  TResult = TMyCommandResult;

  // Эта сигнатура в будущем не поменяется
  TMyCommand = function(const Params: TParams): TResult;

...

function Params(const Arg: TMyArg): TParams; inline; overload;
begin
  Result.Arg := Arg;
end;

...

var
  com: TMyCommand;
  res: TResult;

com := GetNeededCommand;
res := com(Params(Arg));


Неудобство только из-за необходимости слово Params писать (хотя при будущем рефакторинге возможность оверлоаднуть его может пригодиться), ну и производительность может быть чуть хуже в сравнении с register конвенцией.

А языковое решение в самом fpc вряд ли предвидится в обозримом будущем :)
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47

Re: Использовать процедурный тип при объявлении процедуры\фу

Сообщение Cheb » 14.04.2017 04:31:47

array of const слишком толсто или не к месту? :?: :?
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 994
Зарегистрирован: 06.06.2005 15:54:34

Re: Использовать процедурный тип при объявлении процедуры\фу

Сообщение java73 » 14.04.2017 10:06:10

Дож писал(а):type
  TParams = record
    Arg: TMyArg;
  end;
  TResult = TMyCommandResult;

Разве описание TMyArg само по себе не предполагает, что это тип какой-то структуры или класса? Структуру завертывать в структуру что ли?
А выбор соответствующей функции нельзя поручить фабричному методу с помощью какого-то константного параметра дополнительного?
java73
постоялец
 
Сообщения: 257
Зарегистрирован: 21.11.2013 09:08:10

Re: Использовать процедурный тип при объявлении процедуры\фу

Сообщение zub » 14.04.2017 10:51:33

Дож
>>Возможный вариант чисто на текущем fpc — объявить параметры структурой
Кое где так делаю, но тоже не очень удобно - нужна процедура создающая эту запись. Объеденение совсем уж разных параметров в одну структуру - некрасиво.
>>А языковое решение в самом fpc вряд ли предвидится в обозримом будущем :)
Это понятно, но фичреквест в рассылку написать стоит.
Cheb
>>array of const слишком толсто или не к месту?
к месту, но толсто))
java73
>>А выбор соответствующей функции нельзя поручить фабричному методу с помощью какого-то константного параметра дополнительного?
непонял. но можно
zub
долгожитель
 
Сообщения: 2884
Зарегистрирован: 14.11.2005 23:51:26

Re: Использовать процедурный тип при объявлении процедуры\фу

Сообщение Дож » 14.04.2017 11:10:50

Объеденение совсем уж разных параметров в одну структуру - некрасиво.

А объединение разных параметров в одну сигнатуру (в гипотетическом примере с command1 TMyCommand) чем-то лучше?

Кстати, если бы были кортежи, они могли бы помочь сэкономить на функции-конструкторе:
Код: Выделить всё
type
  TParams = tuple of (TMyArg, AnsiString, LongInt);
  TResult = TMyCommandResult;
  TMyCommnd = function (const Params: TParams): TResult;
...
  Command((Arg, 'afasdf', 32));


Разве описание TMyArg само по себе не предполагает, что это тип какой-то структуры или класса?

Какая разница?

Структуру завертывать в структуру что ли?

Да, а что?
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47

Re: Использовать процедурный тип при объявлении процедуры\фу

Сообщение zub » 14.04.2017 11:42:28

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

>>А объединение разных параметров в одну сигнатуру (в гипотетическом примере с command1 TMyCommand) чем-то лучше?
имхо да. я имею ввиду красоту с точки зрения восприятия кода.
zub
долгожитель
 
Сообщения: 2884
Зарегистрирован: 14.11.2005 23:51:26

Re: Использовать процедурный тип при объявлении процедуры\фу

Сообщение Azazaz » 14.04.2017 15:47:15

Код: Выделить всё
type
TFu = function{$I i2.inc}

function pA{$I i2.inc}
begin
Result:= Byte(A+B);
end;

i2.inc
Код: Выделить всё
(A,B: DWord): Byte;
Azazaz
новенький
 
Сообщения: 41
Зарегистрирован: 21.04.2015 20:00:03

Re: Использовать процедурный тип при объявлении процедуры\фу

Сообщение zub » 14.04.2017 16:01:04

Azazaz
Это понятно, но это не от хорошей жизни
zub
долгожитель
 
Сообщения: 2884
Зарегистрирован: 14.11.2005 23:51:26

Re: Использовать процедурный тип при объявлении процедуры\фу

Сообщение ElectroGuard » 19.04.2017 12:14:59

Код: Выделить всё
type TMyCommand=function(arg1:TMyArg):TMyCommandResult
...
function command1(arg1:TMyArg):TMyCommandResult;
...
function command2(arg1:TMyArg):TMyCommandResult;
...
function command100500(arg1:TMyArg):TMyCommandResult;
...
var
com:TMyCommand;
..
com:=GetNeededCommand;
res:=com(arg1:TMyArg)


А что конкретно тут не получается? Если GetNeededCommand вернёт указатель на функцию, она не вызовется?
Что компилятор напишет, если это попробовать скомпилировать? Сделать тела у функций, описать GetNeededCommand, само собой.
ElectroGuard
новенький
 
Сообщения: 71
Зарегистрирован: 03.06.2016 12:10:22

Re: Использовать процедурный тип при объявлении процедуры\фу

Сообщение zub » 19.04.2017 13:37:13

>>А что конкретно тут не получается? Если GetNeededCommand вернёт указатель на функцию, она не вызовется?
всё получается. но много копипасты + в режиме delphi нет контроля аргументов = можно прокопипастится
zub
долгожитель
 
Сообщения: 2884
Зарегистрирован: 14.11.2005 23:51:26

Re: Использовать процедурный тип при объявлении процедуры\фу

Сообщение olegy123 » 19.04.2017 13:52:39

У вас 100500 команд? или 100500 вариаций команд?
olegy123
долгожитель
 
Сообщения: 1643
Зарегистрирован: 25.02.2016 12:10:20

Re: Использовать процедурный тип при объявлении процедуры\фу

Сообщение zub » 19.04.2017 13:55:20

на данный момент 156 (правда не все выглядят как процедура), в ~10 модулях. В планах гораздо больше
zub
долгожитель
 
Сообщения: 2884
Зарегистрирован: 14.11.2005 23:51:26

Re: Использовать процедурный тип при объявлении процедуры\фу

Сообщение olegy123 » 19.04.2017 13:58:53

Я тут смотрел что нового в С++17 хотят добавить.. кроме как облегчить писание из "много букв" в один значок ничего нового неувидел.. типа негоже прогерам переопределять каждый раз функцию макросом - проще было бы внести в стандарт. Вот и придумывают С++99, С++0х, С++11, С++14, С++17.. вроде как пообещали еще новее стандарт..
Вот бы с паскалем так..

Добавлено спустя 12 минут 11 секунд:
Re: Использовать процедурный тип при объявлении процедуры\функци
zub писал(а):на данный момент 156 (правда не все выглядят как процедура), в ~10 модулях. В планах гораздо больше

Мне надо тоже командую строку.. да еще в XML конфиг все элементы залить.. Еще предполагается бинарный формат. в который все будет складываться в общий пак.

Когда я разрабатывал 3D редактор, мне нужно было сохранять состояние сцены.. конфиг сцены...при этом нужно было чтобы можно было править в ручную.. Нашел что XML тот самый формат который позволит читать как человеком так и машиной..
К чему это, а то что если вы делаете парсер команд и у вас вдруг в этом прогрессия возникла, как бы не случилось бы то что вы делаете в итоге не саму прогу - а парсер для команд.
olegy123
долгожитель
 
Сообщения: 1643
Зарегистрирован: 25.02.2016 12:10:20

Re: Использовать процедурный тип при объявлении процедуры\фу

Сообщение zub » 19.04.2017 14:59:29

Команды - средство наращивания "мяска", я не пишу парсер команд, я делаю команды + небольшой слой их взаимодействия с пользователем. У меня все действия - открыть, сохранить, закрыть, рисовать, переключить на следующий документ.... - отдельные команды.
zub
долгожитель
 
Сообщения: 2884
Зарегистрирован: 14.11.2005 23:51:26

След.

Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 20

Рейтинг@Mail.ru