Ада 202x предложение @ обоснование ограничения? - PullRequest
1 голос
/ 21 марта 2019

У меня есть вопрос о предлагаемом стандарте 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;

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

...