May 18, 2007
Daniel Keep wrote:
> Is final really necessary?

No. It's there because nearly all the time, one won't be rebinding a parameter, so making it easier to be final seems like a good idea.

> I can understand const and scope; but is it
> really a problem if the function rebinds the argument?  I mean, that
> shouldn't affect the calling code in the slightest, should it?

No, it does not affect the caller. Only the callee.

> void foo(const scope int[] a)
> {
>     a = [1,2];
> }
> 
> static bar = [3,4];
> foo(bar);
> assert( bar == [3,4] ); // This should still hold, right?

Yes.

> There are a few functions I've written which re-bind the argument as
> they run; the simplest examples being functions that process strings
> (effectively, it just loops until there's just an empty slice left).
> 
> Apart from that, I don't think there's any problems with doing this.  Oh
> well; I'll just have to declare an extra argument.  :P
> 
>> Adding in all those 'in's is tedious, as I'm finding out :-(, but I
>> think the results will be worth the effort.
> 
> Actually, I was thinking of doing this anyway so that my argument lists
> are nice and symmetric (qualifiers on all of them, instead of just ref
> and out).  Now I have an excellent reason to do so other than my
> pedantic-ness. :)
> 
> One question: is there a keyword for "normal" arguments--

No. We could use 'auto' for that, but what's the point <g>.

> for instance, I
> know that most variables are "auto" if you don't specify the storage
> class explicitly.  I can't imagine where it would be useful; just curious.
> 
> At any rate, looks spiffy.
> 
> 	-- Daniel
> 
May 18, 2007
Don Clugston wrote:
> Walter Bright wrote:
>> final - the parameter will not be reassigned within the function
>> const - the function will not attempt to change the contents of what is referred to
>> scope - the function will not keep a reference to the parameter's data that will persist beyond the scope of the function
> 
> Looks great, although somewhat overwhelming for a newcomer.
> Will functions be overloadable on all of these?

Just for const.

> Anyway, it sounds as though we'll see 2.0 beta 1 before DMD 1.15 ?

Probably <g>.
May 18, 2007
Manuel König wrote:
> I think he is concerning to the scope rule. When 'f' gets called with 'g' as param, then 'a' has implicitly a reference to 'g', namely in a[0]. This would be a violation of the scope rule.

Passing things through void* is a way of escaping the type checking, and if you break the rules by doing so, your program might break.
May 18, 2007
Walter Bright wrote

> Passing things through void* is a way of escaping the type checking, and if you break the rules by doing so, your program might break.

The compiler seems to follow the specs which say

| A pointer T* can be implicitly converted to one of the following:
|
|    void*

There is no hint in the specs that this even _implicite_ possible conversion is breaking the security of the type system.

But let me assume for now, that this implicite conversion is an exception and that "breaks type system" will be included in the specs.

Now how about using a circular list, i.e avoiding use of `void *'

struct T{
  T* next;
}
T a;
void main(){
  T g;
  g.next= &g;
  void f( in T p){
    a= *(p.next); // @*_
  }
  f( g); // breaking of scope rule?
}

-manfred
May 18, 2007
Walter Bright wrote
> Making copies is allowed.

A copy of a reference is not the reference itself?

Then `g = a;' does not make a copy of the adress contained in `a'?

WHat does it do then?

-manfred
May 18, 2007

Frits van Bommel wrote:
> Daniel Keep wrote:
>>     // Invariant, so a reference to it is fine
>>     char[] value(invariant char[] v)
>>     {
>>         _value = v;
>>         return v;
>>     }
> 
> But a mutable reference to it shouldn't be fine. So IMHO this should fail because you're trying to return an invariant char[] as a mutable char[]...

*grumbles* Fine, Mr. Pick On My Mistakes...

> invariant char[] value(invariant char[] v)
> {
>     _value = v;
>     return v;
> }

There, all better now? :)

	-- Daniel

-- 
int getRandomNumber()
{
    return 4; // chosen by fair dice roll.
              // guaranteed to be random.
}

http://xkcd.com/

v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP  http://hackerkey.com/
May 18, 2007
Manfred Nowak wrote:
> Walter Bright wrote
>> Making copies is allowed.
> 
> A copy of a reference is not the reference itself?
> 
> Then `g = a;' does not make a copy of the adress contained in `a'?

It does make a copy, but if g is 'scope', you're only allowed to have local copies of a.

This would be fine:

int[] b = a;

> 
> WHat does it do then?
> 
> -manfred
May 18, 2007
torhu wrote

> It does make a copy, but if g is 'scope', you're only allowed to have local copies of a.
> 
> This would be fine:
> 
> int[] b = a;

I understand this exactly as you say it: only local copies are allowed!

But `writef( &b);' as well as `writef( &a);' may create global copies, i.e. at least not local copies.

If this holds, then the scope-rule forbids printing out.

But Walter responds with "Making copies is allowed." Which seems to mean, that global copies are allowed by printing out---or his remark has nothing to do with the problem stated.

How to resolve this contradiction?

-manfred
May 18, 2007
Manfred Nowak wrote:
> torhu wrote
> 
>> It does make a copy, but if g is 'scope', you're only allowed to
>> have local copies of a.
>> 
>> This would be fine:
>> 
>> int[] b = a;
> 
> I understand this exactly as you say it: only local copies are allowed!
> 
> But `writef( &b);' as well as `writef( &a);' may create global copies, i.e. at least not local copies.
> 
> If this holds, then the scope-rule forbids printing out.
> 
> But Walter responds with "Making copies is allowed." Which seems to mean, that global copies are allowed by printing out---or his remark has nothing to do with the problem stated.
> 
> How to resolve this contradiction?

It's not a contradiction.  Only references that are actually inside your application are relevant for this rule.
May 18, 2007
Manfred Nowak wrote:
> Walter Bright wrote
> 
>> Passing things through void* is a way of escaping the type
>> checking, and if you break the rules by doing so, your program
>> might break. 
> 
> The compiler seems to follow the specs which say
> 
> | A pointer T* can be implicitly converted to one of the following:
> |
> |    void*
> 
> There is no hint in the specs that this even _implicite_ possible conversion is breaking the security of the type system.
> 
> But let me assume for now, that this implicite conversion is an exception and that "breaks type system" will be included in the specs.
> 
> Now how about using a circular list, i.e avoiding use of `void *'
> 
> struct T{
>   T* next;
> }
> T a;
> void main(){
>   T g;
>   g.next= &g;
>   void f( in T p){
>     a= *(p.next); // @*_
>   }
>   f( g); // breaking of scope rule?
> }

Yes, you're breaking it.