I think it would be prettier if the sscanf function could be implemented in Pike (implicit references) rather then to use explicit pointer operators, but pointer operators are easier to understand and makes it clearer what's going on, and are probaby way easier to implement.
I've never really felt the need for pointers or call by reference, though. I've grown used to returning multple values via an array.
/ Mirar
Previous text:
2003-04-16 00:55: Subject: Pointers/lvalues
Grubba and I started talking a bit about adding lvalues as an explicit data type in Pike. I'll jot down what we arrived at for the record (well, some of it are later thoughts by me):
An lvalue is a pointer to a variable that allows the variable to be changed (as opposed to a pointer to a function). Generic variable pointers could be implemented by adding two new svalue types: Pointer to variable in object and pointer to variable in frame (if programs get "proper" static variables in some future they would get this too).
The frame case is used for pointers to local variables in functions. Refcounting in frames is already implemented for the sake of nested functions, so returning a pointer to a local variable shouldn't be a problem.
The solution with special pointer svalue types is better than the double svalue (the thing to index followed by the index) approach currently used internally for lvalues for two reasons: Firstly the index operation is performed when the pointer is created instead of when it's dereferenced, which trigs errors closer to the source. Secondly it would avoid odd effects in various functions that doesn't expect variable pointers.
Pointers to values in arrays, mappings and multisets don't need new svalue types since their iterator objects can be used then (more on that later).
Variable pointers would be used like in C. Silly example:
int append_to_buf (Stdio.File f, pointer(string) buf) { string in = f->read(); *buf += in; return sizeof (in); }
Some new operator lfuns would be needed:
&foo => Get the pointer to foo; calls `& in foo. &foo->bar => Get the pointer to foo->bar; calls `&->("bar") in foo. &foo[bar] => Ditto for []; calls `&[](bar) in foo.
`& and ``& already exist, so the first operator above would actually become ```& with the current naming system. We're however contemplating a new system with more verbose lfun names; `&this for the new operator, `this&_ for `&, and `_&this for ``&.
The similarity between pointers and iterators is obvious, so iterators should be able to act as pointers. To accomplish that an lfun corresponding to the dereferencing * operator is necessary:
*foo => Gets the value the pointer points to; calls `*this in foo.
It's also interesting to have an lfun that returns a pointer svalue so that it can be used in an lvalue context. An example:
for (pointer ptr = &my_obj[0]; *ptr; ptr++) *ptr = reverse (*ptr); ^^^^ Here `&*this would be called to produce a pointer value which is used as lvalue.
If `&*this returns an object instead of a basic pointer svalue, `&*this would presumably be tried again, which would make it possible to produce a infinite loop if `&*this should be silly enough to return the iterator itself. A simple check for that might be a good idea.
To be symmetric with `[]= and `->=, one would add a `*this=_ instead of `&*this. I do however like `&*this better since it's then possible to do e.g.
*ptr += ({17});
with an efficient `+= operation without the need for a special `*this+=_.
A `&*this lfun makes it possible to try it in any expression where no better suited lfun is available:
foo + bar => Try: foo->`+(bar) Then: bar->``+(foo) Then: *(foo->`&*this) + bar Then: foo + *(bar->`&*this)
That could be handy when implementing e.g. "smart" strings like Locale.DeferredLocale. I don't know yet if it overall is a good idea or not, though. It's clearly not a good idea in simple assignments and arbitrary function calls.
/ Martin Stjernholm, Roxen IS