Что семантика перемещения подразумевает для ссылочной прозрачности в Rust? - PullRequest
5 голосов
/ 11 января 2020

Я пытаюсь выяснить, как семантика перемещения влияет на прозрачность ссылок.

Ссылочная прозрачность (RT) позволяет нам заменять любое выражение на результат без изменения смысла программы. (Перефразировано из Функциональное программирование в Scala). Например, я могу заменить 1 + 1 в любом месте моей программы на 2, и ничего не должно измениться. Эта Python программа прозрачна по ссылкам:

@dataclass
class Bucket:
    things: List[str]

leaves = ["leaves"]

def bucket_with_sand(things: List[str]) -> Bucket:
    return Bucket(things + ["sand"])

bucket_with_sand(leaves)  # can be replaced with Bucket(["leaves", "sand"]) with no change to the program

, тогда как эта функция изменяет свой аргумент на место

def bucket_with_sand(things: List[str]) -> Bucket:
    things += ["sand"]
    return Bucket(things)

, поэтому замена вызова функции ее результатом меняет смысл. Это больше не ссылочная прозрачность. На языке с семантикой перемещения, такой как в Rust, мы можем избежать этой проблемы, перемещая leaves (и полагаясь на тот факт, что Vec не является Copy):

struct Bucket {
    things: Vec<&str>,
}

let leaves = vec!["leaves"];

fn bucket_with_sand(things: Vec<&str>) -> Bucket {
    things.push("sand");
    Bucket { things }
}

bucket_with_sand(leaves); // mutates `things`
// doesn't matter that `leaves` has been mutated here as it's now out of scope

Похоже, это снова прозрачный референс. Это правильно? Ослабляют ли такие действия обычные ограничения на дизайн RT? Или ходы не прозрачны? Мне особенно интересно узнать, есть ли более широкие последствия для RT, которых я не видел.

...