Hey /prog/, can your toy language do this? MODE P = PROC (P) P;
P i = (P x) P : x;
P v = (P x) P : v;
P k = (P x) P : ((P x, y) P: x)(x, );
P s = (P x) P : ((P x, y) P: ((P x, y, z) P: x(z)(y(z)))(x, y, ))(x, );
P succ = s(s(k(s))(k));
PROC side effect = (PROC VOID f) P : ((PROC VOID f, P x) P : (f; x))(f, );
PROC church = (INT n) P : (P f := k(i); TO n DO f := s(s(k(s))(k))(f) OD; f);
PROC int = (P f) INT : (INT n := 0; f((P x) P : (n +:= 1; i))(i); n);
OP + = (P x, y) P : ((P x, y, z) P : ((P x, y, z, w) P : x(z)(y(z)(w)))(x, y, z, ))(x, y, );
succ(church(10))(side effect(VOID : print(("Hello, world!", new line))))(i);
print(int(succ(church(100) + church(20))))
Name:
Anonymous2012-06-03 21:19
In C++, there's the confusing pointers vs. references vs. const vs. lvalues vs. rvalues vs. literals distinction. C++11 adds rvalue references and constexpr. This all relates to how certain constructs in C++ must be constant expressions but others are allowed to be variable. C++ also passes values as mutable copies. If you want to alter the original object, you pass a reference or pointer.
Algol 68 is much more consistent. ALL of those are unified. All of these C++ concepts are expressed in terms of values (immutable) and ref values (mutable). In Algol 68, nothing needs to be a constant expression. References are values too, so there can be references to references to references and so on. In Algol 68, parameters are passed by value (identity declaration) and all values are immutable. (int i)int: i := 100 is a syntax error because ints are immutable values. It makes just as much sense to do 7 := 100. No copying is required whether a parameter is passed by value, by reference (ref) or by name (proc) because the original storage can always be used, whether it's mutable or immutable.
There are no lvalues or rvalues. The equivalent to an "lvalue" is a ref. If you do loc int i := 5 you create an anonymous local variable (ref int) and assign the value 5 to it. Any ref type can be used anywhere a variable can be used. If f is a proc (string) ref int, f("index") := 50 is valid Algol 68. The := operator dereferences until there is one more level of ref on the left side than on the right side.
Algol 68 has no "constant variables" because that's an oxymoron. There are either identity declarations, which give an identifier the value of an expression calculated at a particular point in time, like single assignment in functional languages, or assignations, which create a reference to mutable storage.
Since there's a GC, there are no pointers, only references. A reference to a reference can be made to refer to any existing mutable storage, just like a pointer can, but it's type safe and only refers to allocated memory.
The other use of pointers in C/C++, to access an array of values, is done using arrays or references to arrays. An array is a first-class data type, and is not related to ref at all ("orthogonal"), except that it adds mutability. Algol 68 arrays are much more flexible (no pun intended) than C arrays. []int(1,2,3,4,5,6,7)[@-3] is an array of integers with a lower bound of -3. arr[50:10] is the 10 element slice of array arr beginning at element 50. Multidimensional arrays can be sliced along any dimension. The built-in string type is defined as flex[0]char, a flexible array of characters. Bounds-checking prevents buffer overflows, preventing a huge number of bugs that are found in C/C++ programs.