January 17, 2014
On 1/16/2014 5:42 PM, Andrei Alexandrescu wrote:
> Walter and I were talking today about the null pointer issue and he had the
> following idea.
>
> One common idiom to replace null pointer exceptions with milder reproducible
> errors is the null object pattern, i.e. there is one object that is used in lieu
> of the null reference to initialize all otherwise uninitialized references. In D
> that would translate naturally to:
>
> class Widget
> {
>      private int x;
>      private Widget parent;
>      this(int y) { x = y; }
>      ...
>      // Here's the interesting part
>      static Widget init = new Widget(42);
> }

I was thinking of:

      @property static Widget init() { ... }

January 17, 2014
On 1/16/2014 6:11 PM, Adam D. Ruppe wrote:
> I think people would be a bit surprised if it was "Foo foo;"

We really don't want any foo-foo stuff in D.

January 17, 2014
On 01/17/2014 03:11 AM, Adam D. Ruppe wrote:
> On Friday, 17 January 2014 at 02:04:27 UTC, Andrei Alexandrescu wrote:
>> Yah, that would be expected.
>
> Yeah, but I think people would find it weird. This kind of thing is
> actually possible today:

class Foo{ int x = 2; }

class Bar{ auto foo = new Foo(); }

void main(){
    auto ibar = new immutable(Bar)();
    auto bar = new Bar();
    static assert(is(typeof(ibar.foo.x)==immutable));
    assert(ibar.foo.x==2);
    bar.foo.x=3;
    assert(ibar.foo.x==3); // uh-oh!
}

January 17, 2014
On 01/17/2014 02:42 AM, Andrei Alexandrescu wrote:
>
> class Widget
> {
>      private int x;
>      private Widget parent;
>      this(int y) { x = y; }
>      ...
>      // Here's the interesting part
>      static Widget init = new Widget(42);
> }
>
> Currently the last line doesn't compile, but we can make it work if the
> respective constructor is callable during compilation. The compiler will
> allocate a static buffer for the "new"ed Widget object and will make
> init point there.

immutable(Widget) iwidget; // ?
January 17, 2014
On 2014-01-17 02:42, Andrei Alexandrescu wrote:

> Thoughts?

As others have said, I don't really see the point in this. It just replaces the existing sentinel value (null) with a different one.

-- 
/Jacob Carlborg
January 17, 2014
On Friday, 17 January 2014 at 03:02:57 UTC, inout wrote:
> On Friday, 17 January 2014 at 02:52:15 UTC, bearophile wrote:
>> deadalnix:
>>
>>> Most object don't have a sensible init value. That is just hiding the problem under the carpet.
>>
>> If there's desire to solve this problem I think that improving the type system to avoid nulls where they are not desired is better than having an init object.
>>
>> So aren't not-nullable pointers and references a better solution?
>>
>> Bye,
>> bearophile
>
> This! Also, if anything, it's better to turn `init` into a method
> rather than an object. The following would work all of a sudden:
>
> class Foo
> {
>     Bar bar = new Bar();
>     int i = 42;
>
>     Foo() {
>        assert(bar !is null);
>        assert(i == 42);
>     }
>
>     // auto-generated
>     private final void init(Foo foo) {
>
>        foo.bar = new Bar();
>        foo.i = 42;
>     }
> }
That would be indeed a nice solution and would break AFAIK nothing. :)
January 17, 2014
On 2014-01-17 07:18, Timon Gehr wrote:

> class Foo{ int x = 2; }
>
> class Bar{ auto foo = new Foo(); }
>
> void main(){
>      auto ibar = new immutable(Bar)();
>      auto bar = new Bar();
>      static assert(is(typeof(ibar.foo.x)==immutable));
>      assert(ibar.foo.x==2);
>      bar.foo.x=3;
>      assert(ibar.foo.x==3); // uh-oh!
> }

Oh, that's just bad. Yet another hole in the type system.

-- 
/Jacob Carlborg
January 17, 2014
On Friday, 17 January 2014 at 08:13:05 UTC, Namespace wrote:
> On Friday, 17 January 2014 at 03:02:57 UTC, inout wrote:
>> On Friday, 17 January 2014 at 02:52:15 UTC, bearophile wrote:
>>> deadalnix:
>>>
>>>> Most object don't have a sensible init value. That is just hiding the problem under the carpet.
>>>
>>> If there's desire to solve this problem I think that improving the type system to avoid nulls where they are not desired is better than having an init object.
>>>
>>> So aren't not-nullable pointers and references a better solution?
>>>
>>> Bye,
>>> bearophile
>>
>> This! Also, if anything, it's better to turn `init` into a method
>> rather than an object. The following would work all of a sudden:
>>
>> class Foo
>> {
>>    Bar bar = new Bar();
>>    int i = 42;
>>
>>    Foo() {
>>       assert(bar !is null);
>>       assert(i == 42);
>>    }
>>
>>    // auto-generated
>>    private final void init(Foo foo) {
>>
>>       foo.bar = new Bar();
>>       foo.i = 42;
>>    }
>> }
> That would be indeed a nice solution and would break AFAIK nothing. :)

But IMO even better would be something like this:
----
class A {
	int id;

	this(int id) {
		this.id = id;
	}

	static A init() {
		return new A(42);
	}
}

A a; /// <-- A a = A.init; --> A a = new A(42);
----
Define your own init method which initialize the object to not null.
January 17, 2014
On 01/17/14 06:33, Walter Bright wrote:
> On 1/16/2014 5:42 PM, Andrei Alexandrescu wrote:
>> Walter and I were talking today about the null pointer issue and he had the following idea.
>>
>> One common idiom to replace null pointer exceptions with milder reproducible errors is the null object pattern, i.e. there is one object that is used in lieu of the null reference to initialize all otherwise uninitialized references. In D that would translate naturally to:
>>
>> class Widget
>> {
>>      private int x;
>>      private Widget parent;
>>      this(int y) { x = y; }
>>      ...
>>      // Here's the interesting part
>>      static Widget init = new Widget(42);
>> }
> 
> I was thinking of:
> 
>       @property static Widget init() { ... }


   default() { ... }

because

  a) you've just reinvented default construction;
  b) overloading 'init' like that is a bad idea (should this
     'init()' be called before invoking a "normal" ctor?...)

artur

January 17, 2014
On Fri, 17 Jan 2014 05:29:05 -0000, H. S. Teoh <hsteoh@quickfur.ath.cx> wrote:
> Now, if we modify this sentinel to instead record the location of the
> code that first initialized it (via __FILE__ and __LINE__ default
> parameters perhaps), then we can set it up to print out this information
> at a convenient juncture, so that the source of the uninitialized
> reference can be determined. *Then* perhaps it will be a start of a
> solution to this issue. (Though it still has limitations in the sense
> that the problem can only be caught at runtime, whereas some cases of
> null dereference preferably should be caught at compile-time.)

So.. if we had a base class for all objects which obtained the file and line when created by assignment (from init) and threw on any dereference (opDispatch) that would do it, right?

R

-- 
Using Opera's revolutionary email client: http://www.opera.com/mail/