Language LValue RValue

From dis-Emi-A

Jump to: navigation, search


Contents

Definition

RValue 
refers to a value which can be used as a parameter to a function or assigned or referenced by another variable.
LValue 
refers not to a value, but rather to an expression to which an RValue can be assigned or referenced by

RValues

RValues are the typical results of expressions, the returns of functions, the value of a variable. This includes system values, constants, function pointers, type instances, type definitions, and virtually anything in the system (for our language at least, in other languages not all constructs are RValues).

In the upcoming draft for C++ and in CSharp there is also a concept of a "RValue Reference". We can largely ignore this as it is strictly an optimization strategy of the type we intend on removing from the syntax of the language and pushing to the compiler.

LValues

LValues are typically the part on the left side of an assignment or reference operation. And indeed, the question is should that be the only place where an LValue is allowed, and must LValues be named items, or can an RValue masquerade as an LValue.

Considerations

In order to support extended types it is important that there is a complete syntax for dealing with such types. The basic situations involve simple variables, member variables, tuples, arrays, maps, matrices, registries, and other data storage constructs.

Consider the following code that works in other languages (though not in all languages).

Basic

a = 5; //simple enough, LV is "a" in the current context
class.member = 7; //LV is "member" in context "class"

Tuples

( a, b ) = ( c, d ); //fragmented tuple assignment, LV's "a" and "b"

Vectors/Matrices

arr[i] = 4; //LV is the "i^th" element of array "arr"
mat[i,j] = 6; //LV is i,j row-column cell of the matrix "mat"
lists[i][j] = 7; //LV is the "j^th" entry of the "i^th" entry of list "lists"
dict["key"] = v; //LV is the "key" element in the map "dict"
arr[] = 5; //LV is a new value in array "arr"

Pointers

*a = 3; //LV is the dereferenced ptr in "a"
func( int& res ) { res = 5; } ... int a; func( a ); //LV is "a"
memset( &a, 0, sizeof(a) ); //LV is "a"

Accessors

GetPerson().name = "Tom"; //LV is the "name" member in the context returned by "GetPerson"
GetName() = "Tom"; //LV is the return of the function "GetName()"
(*stack.top()) = 6; //LV is the item at the top of the stack "stack"

Exceptions

catch( Exception e ); //LV is new instance e
catch( Exception& e ); //e is bound to an RValue, no traditional LV

Exotic

arr[3..7] = sublist; //LV is the set of cells in "arr" from  3 through 7 (sublist must be the same size)

C and C++ have direct manners of passing LValues around as regular parameters. This allows a great deal of flexibility but also introduces a great deal of confusion.

Java has no such facility (only named variables and members can be used as LValues, everything else requires a setter). This makes the language syntax simple, but it makes extended types hard to use.

Perl has a concept I think we might use, and that is to declare function returns as LValues, in which case the return must refer to an LValue within the function context. Though in Perl's case they wish to fix some problems arising from this.

Support

So the question is which of those forms do we wish to support and furthermore should such support be hardcoded or should the language in general allow extended LValue definitions.

The only forms which we don't want to support are the explicit pointer and reference forms of C/C++. The other forms we basically wish to support as native syntax (otherwise compound types become hard to use).

As an extension to this question we also need to consider whether types can intercept assignment to one of their members, which in effect becomes similar to functions returning LValues.

LValue Type

One option we have to be generic and consistent is to create an explicit LValue type, but rather than defining it is a pointer, we define it is a function which takes a single argument and has no returns. In this case we have that every assignment/reference is actually a call to this function, in this fashion all the fundamental types work as expected and the extended types can provide useful functionality with controlled accessors.

In this fashion we need only two fundamental LValue uses, one for assignment and one for reference. (Though in practice several other fundamental types will be implemented specifically).

Personal tools