У меня есть вопрос о предлагаемом стандарте Ada 202x. В частности, мне интересно узнать об ограничениях для функции целевого имени (@
). Похоже, что эта функция будет доступна только в операторах присваивания, а не в агрегатах записей или массивов. В чем причина этого ограничения?
Чтобы объяснить, почему я думаю, было бы полезно расширить область применения целевого имени. Сравните эти две функции.
Внедрение, насколько я понимаю, предлагаемого стандарта:
function Mutate (State : Some_State) return Some_State is (State with delta
Internal_Component => (State.Internal_Component with delta
Component_Array => (State.Internal_Component.Component_Array with delta
Array_Index => State.Internal_Component.Component_Array (Array_Index) + 1,
Other_Index => State.Internal_Component.Component_Array (Other_Index) - 1)));
Если функция целевого имени была расширена до агрегатов, то это может быть:
function Mutate (State : Some_State) return Some_State is (State with delta
Internal_Component => (@ with delta -- @ is State.Internal_Component
Component_Array => (@ with delta -- @ is State.Internal_Component.Component_Array
Array_Index => @ + 1, -- @ is State.Internal_Component.Component_Array (Array_Index)
Other_Index => @ - 1))); -- @ is State.Internal_Component.Component_Array (Other_Index)
Если дельта-агрегаты могут неявно вкладываться, это может привести к очень чистому результату:
function Clean_Mutate (State : Some_State) return Some_State is (State with delta
Internal_Component.Component_Array => @ with delta (
Array_Index => @ + 1,
Other_Index => @ - 1));
Конечно, как написано, можно использовать:
function Mutate (State : Some_State) return Some_State is
Result : Some_State := State;
begin
Result.Internal_Component.Component_Array (Array_Index) := @ + 1;
Result.Internal_Component.Component_Array (Other_Index) := @ - 1;
return Result;
end Mutate;
Но это все еще не так чисто, и это сильно затрудняет использование целевого имени в выражениях без присваивания.