val a = 5
val a = a + 1
Будет ли переводчик выделять новое место в памяти для «нового» * 1003 *?
Да, точно.
SML имеет двавещи, привязки значений и изменяемые ссылки (как переменные, например, в C).
Что вы описываете привязки значений и ихзначение не может изменяться в одной и той же области.
Здесь значение a
не изменяется , оно затенено другой a
, создавая новую областьсо старым a
скрытым.Поэтому, если вы используете старые a
и shadow a
, использование старого a
не изменится.Более наглядный пример:
val a = 5
fun f x = x + a
val a = 10
val b = f 1 (* = 6, not 11 *)
В чем преимущества этой идеи?
В вашем примере есть две идеи ( привязки значений и shadowing ), поэтому я хочу убедиться, что отвечаю на правильный вопрос:
Привязки значений вместо изменяемых ссылок означает, что именованные значения не меняются в течение срока их службы.Это хорошо, потому что тогда рассуждать о вашем коде проще.Чтобы найти значение привязки, вы можете перейти к ее определению, и вы поймете, что с тех пор оно никогда не меняло значения.
Вы можете сделать привязки значений различными, передавая значения вфункции.Вы можете думать об этом как о переменной в математическом смысле, но не в смысле изменяемой ссылки .Таким образом, они различаются только в зависимости от входных параметров функции.Например,
fun factorial 0 = 1
| factorial n = n * factorial (n - 1)
Здесь n
- это значение привязки и переменная в математическом смысле, но не изменяемая ссылка .
Затенение означает, что именованные значения могут быть скрыты другими именованными значениями с тем же именем.Это не очень хорошая функция, так как это может вызвать путаницу.Точно так же, как важно правильно называть вещи, одинаково важно не давать двум одинаковое имя.
Многие функциональные языки программирования не позволяют shadowing .
Например, вErlang следующее является ошибкой:
f(X) ->
A = 5,
A = 6,
X + A.
И в Haskell следующее является ошибкой:
f :: Int -> Int
f x = x + a
where
a = 5
a = 6
SML имеет переменные, но они не меняются .
Верно, это верно для привязок значений , которые наиболее распространены в SML.«Неизменяемые переменные» могут вызвать путаницу, поскольку «переменная» может означать как «изменяемая ссылка», так и «параметр функции».
SML, имеющий как функциональные, так и императивные функции языка, также имеет изменяемые ссылки :
val a = ref 5
fun f x = x + !a
val _ = a := 10
val b = f 1 (* 11, not 6 *)
Здесь ref : 'a -> 'a ref
создает ссылку и ! : 'a ref -> 'a
разыменовывает ее.
Они так же опасны, как и в других языках;возможно, меньше, потому что вы не будете случайно смешивать 'a
и 'a ref
, поскольку система типов вызовет ошибку.Синтаксически они немного непрактичны, но это должно служить напоминанием о том, что вам следует опасаться их использования.: -)