December 17, 2009
On 2009-12-16 16:46:14 -0500, Jason House <jason.james.house@gmail.com> said:

> Walter Bright Wrote:
> 
>> Jason House wrote:
>>> KennyTM~ Wrote:
>>> 
>>>> auto const?
>>> 
>>> I was wondering the same thing.
>> 
>> The const transport thing is, unfortunately, a very different problem.
> 
> Of course, but it may still go through bikeshed issues. This morning I read about inout, return, vconst, aconst, sameconst, autoconst, auto const, and bikeshed. At least one of those was in jest :) auto const isn't that bad, and you obviously liked auto ref...

Since this is just a special kind of const, it could be called "const^" (const or a derived constness):

	const?(Object) func(const?(Object) o) {
		return o;
	}

The interesting thing about it, beside not taking a keyword, is that it can scale in the future if we need to add many distinct constness to the same function signature:

	const?(Object) func(const?(Object) o, const?2(Object) o2, out const?2(Object) o3) {
		o3 = o2;
		return o;
	}

Not that you'd need that often, but if it does becomes necessary in the future we'll still have some options.

Furthermore, the concept could be extended to any type. This could be useful with class hierarchies:

	Object? func(Object? o) {
		writeln(o.toString());
		return o;
	}

	MyObject o = func(new MyObject);

Here, "Object?" means Object or a derived type.

Yeah, that breaks the proposed syntax for nullable types... just too bad. If that's really a problem we could use ^ instead.


-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/

December 17, 2009
On 2009-12-16 19:05:09 -0500, Michel Fortin <michel.fortin@michelf.com> said:

> Since this is just a special kind of const, it could be called "const^" (const or a derived constness):

Bad editing. That should be "const?". Sorry if it confuses anyone.


-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/

December 17, 2009
On Wed, 16 Dec 2009 12:00:46 +0100, KennyTM~ <kennytm@gmail.com> wrote:

> On Dec 16, 09 15:18, Walter Bright wrote:
>> There's a need in generic code to have a function take a parameter by
>> ref if it is an lvalue, and by value if it is an rvalue. This can be
>> addressed by making it a template using auto ref:
>>
>> T foo(T)(auto ref T x) { ... }
>>
>> foo(3) // call by value
>> int y;
>> foo(y) // call by reference
>>
>> There is also a need to 'transmit' the ref'ness to the return value.
>> This can be done with auto ref:
>>
>> auto ref foo(T)(auto ref T x) { return x; }
>>
>> foo(3) => int foo(int x)
>> foo(y) => ref int foo(ref int x)
>>
>> This means that the generic forwarding function would look like:
>>
>> auto ref foo(alias F, T...)(auto ref T args) { return F(args); }
>
> auto const?

auto const auto ref Foo bar( auto const auto ref Foo arg ) {
    return arg;
}

Am I the only one who finds this confusing?

-- 
Simen
December 17, 2009
On 12/17/2009 01:05 AM, Michel Fortin wrote:
> Object? func(Object? o) {
> writeln(o.toString());
> return o;
> }
>
> MyObject o = func(new MyObject);
>
> Here, "Object?" means Object or a derived type.
>
You know, just Object means Object or a derived type. That's what inheritance is.
December 17, 2009
On 2009-12-17 01:57:50 -0500, Pelle Månsson <pelle.mansson@gmail.com> said:

> On 12/17/2009 01:05 AM, Michel Fortin wrote:
>> Object? func(Object? o) {
>> writeln(o.toString());
>> return o;
>> }
>> 
>> MyObject o = func(new MyObject);
>> 
>> Here, "Object?" means Object or a derived type.
>> 
> You know, just Object means Object or a derived type. That's what inheritance is.

The idea is to be able to say in the function signature that the same type is returned, avoiding a cast that would be unnecessary otherwise. It's the same principle as for "const?", or "inout".

But you're right that my definition isn't very good.

-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/

December 17, 2009
On Dec 17, 09 19:44, Michel Fortin wrote:
> On 2009-12-17 01:57:50 -0500, Pelle Månsson <pelle.mansson@gmail.com> said:
>
>> On 12/17/2009 01:05 AM, Michel Fortin wrote:
>>> Object? func(Object? o) {
>>> writeln(o.toString());
>>> return o;
>>> }
>>>
>>> MyObject o = func(new MyObject);
>>>
>>> Here, "Object?" means Object or a derived type.
>>>
>> You know, just Object means Object or a derived type. That's what
>> inheritance is.
>
> The idea is to be able to say in the function signature that the same
> type is returned, avoiding a cast that would be unnecessary otherwise.
> It's the same principle as for "const?", or "inout".
>
> But you're right that my definition isn't very good.
>

T func(T)(T o);
December 17, 2009
On 2009-12-17 07:09:57 -0500, KennyTM~ <kennytm@gmail.com> said:

> On Dec 17, 09 19:44, Michel Fortin wrote:
>> On 2009-12-17 01:57:50 -0500, Pelle Månsson <pelle.mansson@gmail.com> said:
>> 
>>> On 12/17/2009 01:05 AM, Michel Fortin wrote:
>>>> Object? func(Object? o) {
>>>> writeln(o.toString());
>>>> return o;
>>>> }
>>>> 
>>>> MyObject o = func(new MyObject);
>>>> 
>>>> Here, "Object?" means Object or a derived type.
>>>> 
>>> You know, just Object means Object or a derived type. That's what
>>> inheritance is.
>> 
>> The idea is to be able to say in the function signature that the same
>> type is returned, avoiding a cast that would be unnecessary otherwise.
>> It's the same principle as for "const?", or "inout".
>> 
>> But you're right that my definition isn't very good.
> 
> T func(T)(T o);

That would work, unless you want a virtual function.

If templates were always an acceptable solution, the whole discussion about passing const qualifiers from the argument to the return value wouldn't be of any use either.


-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/

December 17, 2009
Simen kjaeraas, el 17 de diciembre a las 02:16 me escribiste:
> On Wed, 16 Dec 2009 12:00:46 +0100, KennyTM~ <kennytm@gmail.com> wrote:
> 
> >On Dec 16, 09 15:18, Walter Bright wrote:
> >>There's a need in generic code to have a function take a parameter by ref if it is an lvalue, and by value if it is an rvalue. This can be addressed by making it a template using auto ref:
> >>
> >>T foo(T)(auto ref T x) { ... }
> >>
> >>foo(3) // call by value
> >>int y;
> >>foo(y) // call by reference
> >>
> >>There is also a need to 'transmit' the ref'ness to the return value. This can be done with auto ref:
> >>
> >>auto ref foo(T)(auto ref T x) { return x; }
> >>
> >>foo(3) => int foo(int x)
> >>foo(y) => ref int foo(ref int x)
> >>
> >>This means that the generic forwarding function would look like:
> >>
> >>auto ref foo(alias F, T...)(auto ref T args) { return F(args); }
> >
> >auto const?
> 
> auto const auto ref Foo bar( auto const auto ref Foo arg ) {
>     return arg;
> }
> 
> Am I the only one who finds this confusing?

Just call "auto const auto ref" "auto auto":

auto auto Foo bar( auto auto Foo arg ) {
    return arg;
}

=P

-- 
Leandro Lucarella (AKA luca)                     http://llucax.com.ar/
----------------------------------------------------------------------
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
----------------------------------------------------------------------
We are born naked, wet and hungry
Then things get worse
December 17, 2009
"Michel Fortin" <michel.fortin@michelf.com> wrote in message news:hgd9jb$26v9$1@digitalmars.com...
> On 2009-12-17 07:09:57 -0500, KennyTM~ <kennytm@gmail.com> said:
>
>> On Dec 17, 09 19:44, Michel Fortin wrote:
>>> On 2009-12-17 01:57:50 -0500, Pelle Månsson <pelle.mansson@gmail.com> said:
>>>
>>>> On 12/17/2009 01:05 AM, Michel Fortin wrote:
>>>>> Object? func(Object? o) {
>>>>> writeln(o.toString());
>>>>> return o;
>>>>> }
>>>>>
>>>>> MyObject o = func(new MyObject);
>>>>>
>>>>> Here, "Object?" means Object or a derived type.
>>>>>
>>>> You know, just Object means Object or a derived type. That's what inheritance is.
>>>
>>> The idea is to be able to say in the function signature that the same type is returned, avoiding a cast that would be unnecessary otherwise. It's the same principle as for "const?", or "inout".
>>>
>>> But you're right that my definition isn't very good.
>>
>> T func(T)(T o);
>
> That would work, unless you want a virtual function.
>
> If templates were always an acceptable solution, the whole discussion about passing const qualifiers from the argument to the return value wouldn't be of any use either.
>

Pardon my ignorance, but why is it that templated functions can't be virtual?


December 17, 2009
== Quote from Nick Sabalausky (a@a.a)'s article
> Pardon my ignorance, but why is it that templated functions can't be virtual?

This is an unfortunate consequence of compilation model leaking out into language design.  You're supposed to be able to subclass a base class even if you don't have the full source code to it.  Let's say we have:

class A {
    void doStuff(T)(T arg) {}
}

class B : A {
    void doStuff(T)(T arg) {
        writeln("In B.");
    }
}

And then we do:

B b = new B;
b.doStuff(1);

The instantiation of B.doStuff() with an int would require that the vtable for A be updated to include doStuff!(int).  This is not possible if we also allow base classes to be compiled separately from derived classes and the code that uses the derived class.

The only solution I see would be to completely get rid of separate compilation. For my personal use, since most of my projects are under 10k lines and take a negligible amount of time to compile anyhow, I'd be in favor of this.  However, for larger projects or projects that require things to work based only on interface, without access to the full source code, this is probably impractical.