www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - inout (return) type modifier?

reply no where.com writes:
Inspired by the change in D-0.107:

"InExpressions now, instead of returning a bit, return a pointer to the
associative array element if the key is present, null if it is not. This
obviates the need for many double lookups."

I wonder how many look-ups this code needs:

int[int] map;
..
map[key] += 2;

Do we need two separate look-ups for read/write?  Can we have inout return type
for the index operator (and in general for any functions)?

Is 'inout' same as reference type in C++?  Why right now it's only allowed in
passing function parameters?
Dec 12 2004
parent reply "Walter" <newshound digitalmars.com> writes:
<no where.com> wrote in message news:cpi1ob$2fjt$1 digitaldaemon.com...
 Inspired by the change in D-0.107:

 "InExpressions now, instead of returning a bit, return a pointer to the
 associative array element if the key is present, null if it is not. This
 obviates the need for many double lookups."

 I wonder how many look-ups this code needs:

 int[int] map;
 ..
 map[key] += 2;

Just one. Compile it, run obj2asm, and see!
 Do we need two separate look-ups for read/write?  Can we have inout return

 for the index operator (and in general for any functions)?

That might be a good idea. I'll have to think about it some more.
 Is 'inout' same as reference type in C++?

More or less, yes.
 Why right now it's only allowed in passing function parameters?

Dec 12 2004
next sibling parent "Ivan Senji" <ivan.senji public.srce.hr> writes:
"Walter" <newshound digitalmars.com> wrote in message
news:cpj3iv$e8n$2 digitaldaemon.com...
 <no where.com> wrote in message news:cpi1ob$2fjt$1 digitaldaemon.com...
 Inspired by the change in D-0.107:

 "InExpressions now, instead of returning a bit, return a pointer to the
 associative array element if the key is present, null if it is not. This
 obviates the need for many double lookups."

 I wonder how many look-ups this code needs:

 int[int] map;
 ..
 map[key] += 2;

Just one. Compile it, run obj2asm, and see!
 Do we need two separate look-ups for read/write?  Can we have inout


 type
 for the index operator (and in general for any functions)?

That might be a good idea. I'll have to think about it some more.

This is a great idea! Please, please think about it. :)
 Is 'inout' same as reference type in C++?

More or less, yes.
 Why right now it's only allowed in passing function parameters?


Dec 13 2004
prev sibling next sibling parent reply Chris Sauls <Chris_member pathlink.com> writes:
In article <cpj3iv$e8n$2 digitaldaemon.com>, Walter says...
<no where.com> wrote in message news:cpi1ob$2fjt$1 digitaldaemon.com...
 Do we need two separate look-ups for read/write?  Can we have inout return

 for the index operator (and in general for any functions)?

That might be a good idea. I'll have to think about it some more.

What might the syntax for this be? First thought is something like: # inout int foo(int x) { } -- Chris Sauls
Dec 13 2004
parent reply no where.com writes:
I'm thinking along the lines of introducing a full alias (like a C++ reference)
type into D.

In C++, a variable of reference type can only be init-ed at declaration:

// C++ code
void foo()
{
int i, j;
int& r;      // error, `r' declared as reference but not initialized
int& r = i;  // OK.
}

I'm think about some re-bindable reference type, let's all it alias type:

// imaginary D code
void foo()
{
int i, j;
alias int r; // decl a variable r of alias type

r alias i;   // alias is an operator, r is now alias-ed to i;
r = 3;       // assert( i == 3 );

r alias j;   // r is now alias-ed to j;
r = 3;       // assert( j == 3 );
}

This will help a lot to improve the code, as in the case of map example to
reduce the unnessary look-ups.

Comments?

yqz


In article <cpl3kl$2qha$1 digitaldaemon.com>, Chris Sauls says...
In article <cpj3iv$e8n$2 digitaldaemon.com>, Walter says...
<no where.com> wrote in message news:cpi1ob$2fjt$1 digitaldaemon.com...
 Do we need two separate look-ups for read/write?  Can we have inout return

 for the index operator (and in general for any functions)?

That might be a good idea. I'll have to think about it some more.

What might the syntax for this be? First thought is something like: # inout int foo(int x) { } -- Chris Sauls

Dec 14 2004
next sibling parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
no where.com wrote:

 I'm thinking along the lines of introducing a full alias
 (like a C++ reference) type into D.

Sounds a lot like the C++ references, just even more confusing ? I'm trying to see how this is easier than pointers... But I fail ? But maybe the world could need some more sugar, even if syntactic. Const references are kinda nice, but the others make for nasty bugs. IMHO. --anders
Dec 14 2004
parent reply Matthias Becker <Matthias_member pathlink.com> writes:
 I'm thinking along the lines of introducing a full alias
 (like a C++ reference) type into D.

Sounds a lot like the C++ references, just even more confusing ?

To me his idea sounds simple. You have tow operators '=' and 'alias'. '=' means value-assignment, 'alias' means reference-assignment. But I'm not sure, if we should use alias fo this. Maybe somethings else would be more clear: # void foo() # { # int i, j; # ref int r; # # r := i; // r is now refering to i # r = 3; // assert( i == 3 ); # # r := j; // r is now refering to j; # r = 3; // assert( j == 3 ); # } I just replaced on alias with ref and the alias-operator with := and to me it looks pretty understandable.
I'm trying to see how this is easier than pointers... But I fail ?

# void foo() # { # int i, j; # int *r; # # r = i; // r is now refering to i # *r = 3; // assert( i == 3 ); # # r = j; // r is now refering to j; # *r = 3; // assert( j == 3 ); # } Of course, it's the same as pointers, but you don't have to dereference it. -- Matthias Becker
Dec 15 2004
parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Matthias Becker wrote:

Sounds a lot like the C++ references, just even more confusing ?

To me his idea sounds simple. You have tow operators '=' and 'alias'. '=' means value-assignment, 'alias' means reference-assignment. But I'm not sure, if we should use alias fo this.

Actually alias sort of works for this already, just that you can't reuse the same name twice:
   alias i r;
   alias j r;

 Maybe somethings else would be
 more clear:
 
 # void foo()
 # {
 #    int i, j;
 #    ref int r;
 # 
 #    r := i;   // r is now refering to i
 #    r = 3;    // assert( i == 3 );
 # 
 #    r := j;   // r is now refering to j;
 #    r = 3;    // assert( j == 3 );
 # }
 
 I just replaced on alias with ref and the alias-operator with := and to me it
 looks pretty understandable.

Unless you had to look at Pascal or Ada at some point in your life... They use := for assignment (=) and a single = for equality (==).
I'm trying to see how this is easier than pointers... But I fail ?

# void foo() # { # int i, j; # int *r; # # r = i; // r is now refering to i # *r = 3; // assert( i == 3 ); # # r = j; // r is now refering to j; # *r = 3; // assert( j == 3 ); # }

You meant to write "r = &i", since the above code does not compile.
 Of course, it's the same as pointers, but you don't have to dereference it.

I know the C++ references. No dereferencing, no nullpointers. But still with a high potential for confusion, if used heavily... I think the inout parameters and lack of copy constructors makes D not need them, but maybe some kind of references would be good ? --anders
Dec 15 2004
parent Matthias Becker <Matthias_member pathlink.com> writes:
Actually alias sort of works for this already,
just that you can't reuse the same name twice:

   alias i r;
   alias j r;


It's not the same. We want to be able to use references as return type.
 I just replaced on alias with ref and the alias-operator with := and to me it
 looks pretty understandable.

Unless you had to look at Pascal or Ada at some point in your life... They use := for assignment (=) and a single = for equality (==).

I know Pascal ans some other languages that use these operator names. Well you know = for assignment in D. And I needed another name for a different kind of assignment. So I choosed :=, because many languages use it for assignment. [...]
You meant to write "r = &i", since the above code does not compile.

 Of course, it's the same as pointers, but you don't have to dereference it.

I know the C++ references. No dereferencing, no nullpointers. But still with a high potential for confusion, if used heavily...

I think the inout parameters and lack of copy constructors makes
D not need them, but maybe some kind of references would be good ?

We already have them: pointers. The only problem was, that you have to manually dereference them. Ah, what about this: # void foo() # { # int i, j; # ref int r; # # &r = &i; // r is now refering to i # r = 3; // assert( i == 3 ); # # &r = &j; // r is now refering to j; # r = 3; // assert( j == 3 ); # } so '&somereference' is an l-value if 'somereference' is a reference? That looks way better to me then the ':='. -- Matthias Becker
Dec 16 2004
prev sibling parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
no where.com wrote:

 I'm think about some re-bindable reference type, let's all it alias type:
 
 // imaginary D code
 void foo()
 {
 int i, j;
 alias int r; // decl a variable r of alias type
 
 r alias i;   // alias is an operator, r is now alias-ed to i;
 r = 3;       // assert( i == 3 );
 
 r alias j;   // r is now alias-ed to j;
 r = 3;       // assert( j == 3 );
 }
 
 This will help a lot to improve the code, as in the case of map example to
 reduce the unnessary look-ups.

If it *was* implemented, shouldn't it be done the same way as it's done with arguments, i.e. with the "in", "inout" and "out" designators ?
 int i, j;
 
 inout int ri = i;
 ri = 3;
 assert(i == 3);
 
 inout int rj = j;
 rj = 3;
 assert(j == 3);

With 'out' first initializing the value, as it works with function parameters right now ? http://www.digitalmars.com/d/function.html As with functions, 'in' would have no effect whatsoever, making "r" into just a copy of i. ("in int r = i;" being same as "int r = i;") I'm not sure what the use of such references would be, outside of parameters, though ? **** If the new declaration *was* just an alias, then maybe D needs "unalias" like the "sh" shell has ?
 void main()
 {
   int i, j;
 
   alias i r;
   r = 3;
   assert(i == 3);
 
   unalias r; // <-- new compiler directive
 
   alias j r;
   r = 3;
   assert(j == 3);
 }

Where unalias simply makes a previous alias declaration "disappear" from the name space ? Without it, it throws an error when reusing :
 declaration main.r is already defined

--anders
Dec 15 2004
parent reply no where.com writes:
If it *was* implemented, shouldn't it be done
the same way as it's done with arguments, i.e.
with the "in", "inout" and "out" designators ?

'inout' sounds OK for function parameters or return types; but a bit strange in other place (e.g. local variable, class attribute) to denote reference type.
I'm not sure what the use of such references
would be, outside of parameters, though ?

As in the original example, you can use it as local variable to reduce uncessary look-ups: ref rval = map[key]; // only one lookup is needed rval += 3; otherwise: val = map[key]; // two look-ups map[key] = val+3; (unless you also provide "+=" operator for map; but operator overloading cannot exhaustively provide all the possible functionality of direct access through reference)
 but maybe some kind of references would be good ?

That's what I think. For example, in C++ STL, all the index operators return reference type, so you can manipulate the index-ed data directly without calculate its index everytime you want to access/modify it.
 Actually alias sort of works for this already,
 just that you can't reuse the same name twice:

   alias i r;
   alias j r;


If the new declaration *was* just an alias, then
maybe D needs "unalias" like the "sh" shell has ?

 void main()
 {
   int i, j;
 
   alias i r;
   r = 3;
   assert(i == 3);
 
   unalias r; // <-- new compiler directive
 
   alias j r;
   r = 3;
   assert(j == 3);
 }

Where unalias simply makes a previous alias declaration "disappear" from the name space ? Without it, it throws an error when reusing :
 declaration main.r is already defined


I believe (not sure), the current alias in your quote is just syntax sugar, it's not different from #define in C++: #define j main.r If we go back to the map example: #define rval map[key] then multiple look-ups still happen. Actually now I think use 'alias' maynot be a good notation choice for reference. Since it has been used for syntactical sugar already. If we have both value-assignment and (semantic) reference-assignment, that will be great. As to the notation, maybe we can use another keyword 'ref', or just use C++'s &?
Dec 15 2004
parent =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
no where.com wrote:

 'inout' sounds OK for function parameters or return types; but a bit strange in
 other place (e.g. local variable, class attribute) to denote reference type.

Maybe it needs a synonym ? Like your suggested "ref". I always found the C++ syntax of type& to be confusing...
 As in the original example, you can use it as local variable to reduce
uncessary
 look-ups:
 
 ref rval = map[key];  // only one lookup is needed
 rval += 3;
 
 otherwise:
 
 val = map[key];    // two look-ups
 map[key] = val+3;
 
 (unless you also provide "+=" operator for map; but operator overloading cannot
 exhaustively provide all the possible functionality of direct access through
 reference)

I think the currently suggested approach is to use pointers... Either the old: assert(key in map); type* val = &map[key]; *val += 3; Or the new syntax: type* val = key in map; assert (val != null); *val += 3; "in" was changed from a bit to a pointer, with DMD version 0.107 Or you could make it use D "references" instead, by moving the code in question into a function: void do_stuff(inout type val) { val += 3 }; do_stuff(map[key]); And hope that the compiler is smart enough to inline ? There's plenty of interesting info at http://c2.com/cgi/wiki?NoPointers Already seems to be three fighting sides of the war: C, C++ and Java... --anders
Dec 15 2004
prev sibling parent tetsuya <tetsuya_member pathlink.com> writes:
In article <cpj3iv$e8n$2 digitaldaemon.com>, Walter says...
<no where.com> wrote in message news:cpi1ob$2fjt$1 digitaldaemon.com...
 Inspired by the change in D-0.107:

 Do we need two separate look-ups for read/write?  Can we have inout return

 for the index operator (and in general for any functions)?

That might be a good idea. I'll have to think about it some more.

Can't wait to have it! So is opIndexAssign gonna be deprecated maybe?? -tetsuya
Dec 13 2004