Есть ли язык, который позволяет манипулировать примитивами?
В большинстве случаев языки не позволяют манипулировать ссылками на примитивы. Например.:
var a = 0;
var b = a; // value is copied
b++; // b now represents a new value as this is really b = b + 1; so a != b
Хотя манипулирование не примитивами вызовет (иногда разрушительное) манипулирование состоянием, которое отражается во всех переменных (с использованием JS):
var a = [];
var b = a; // b is now a reference to the value stored in a.
a.push(1); // b[0] is now 1 -- b and a are pointing to the same thing.
Это имеет смысл. Я могу полностью понять, почему такие вещи, как String.replace, будут возвращать значение вместо выполнения манипуляции с состоянием.
Однако мне было интересно, если бы не было языков, позволяющих примитивам манипулировать состоянием. Например.:
var a = 0;
var b = a; // b references a
b++; // b and a are now = 1.
Я знаю указатель на более низкоуровневых языках, и это почти делает то, о чем я говорю, но у меня возникает ощущение, что это всего лишь повторное присвоение значения, а не обновление ссылки.
Я также знаю о ссылках на PHP, но так как PHP не позволяет такие вещи:
$str = "abcd";
$st[0] = "q"; // this causes an error.
Кроме того, при объединении ряда строк в PHP цикл $str .= 'var'
предполагается создавать новые строки на каждой итерации.
Возможно, я схожу с ума от того, что даже удивляюсь этому, но с увеличением распространенности объектных моделей в качестве фона для переменных, кажется, что это может действительно существовать (это кажется безумно сложным в некоторых отношениях, особенно если вы позволили int
объектом, которым манипулируют, но кажется, что такой синтаксис был бы хорошим источником изучения).
1 ответ
Вопреки тому, что вы, похоже, предполагаете, это не новая и не темная идея. Языки более низкого уровня не заботятся о том, чтобы обеспечить неизменность любого типа (в конце концов, ++i
в противном случае не существовало бы и не было бы расточительным - и аппаратное обеспечение не имеет постоянных регистров, верно?), но они также предпочтут типы значений (то есть a = b
копирует значение, а не молча выдает ссылку на одно и то же значение), поэтому вам нужно запачкать руки и попросить его ссылаться на одно и то же значение дважды, например, с помощью указателей. В С:
int x = 0;
int *p = &x;
*p = 1;
/* x == 1 */
Точно так же C++ имеет одинаково мощные указатели, а также ссылки, которые для этих целей работают как указатели, которые неявно разыменовываются (и не могут быть изменены, чтобы указывать на что-либо еще, и не могут быть NULL):
int x = 0;
int &y = x;
y = 1;
// x == 1
В любом случае, никому и в голову не приходило сделать примитивные типы неизменяемыми (почему они должны? Машины Вон Неймана все-таки об изменении состояния, в конце концов), указатели теряют большую часть своей ценности, если вы не можете изменить значение указывать и запрещать указатели на определенные изменяемые типы было бы бессмысленным и серьезным ограничением.