Разве это не тот же эффект, как если бы мы изменили значение в исходной записи с 100 на 0,6
Нет. Рассмотрим код, который ссылается на предыдущую среду с помощью замыкания, например
val x = 7
val f = fn () => x
val x = 8
val _ = print (Int.toString (f ())) (* prints 7 *)
Если исходная запись была создана вне вызова функции, а новая запись была создана при вызове функции, тогда, когда вызов функции возвращается, мы можем получить доступ к исходной записи.
Конечно, ее статическая область действия.
Если обе записи были созданы в одной «области», как в примере выше, исходная запись недоступна?
Она все еще доступна, но не по этому идентификатору. Рассмотрим приведенный выше пример.
Какой смысл делать переменную неизменной в SML и создавать новую запись при переопределении переменной?
Одно из применений этого - изменение тип переменной, но с тем же идентификатором (что вы и делаете в опубликованном вами примере!). Возьмем, к примеру, (в C):
int i = 7;
i = 7.0;
Здесь i
по-прежнему будет иметь тип int
. См. В SML:
val i : int = 7
val i : real = 7.0
Я добавил аннотации типов для иллюстрации, но даже без этого ведет себя так же. После второй привязки i
имеет тип real
.