Re: readonly member (but assignable at constructor time)

2018-04-30 Thread bauss via Digitalmars-d-learn

On Monday, 30 April 2018 at 10:57:51 UTC, Jonathan M Davis wrote:
On Monday, April 30, 2018 10:36:52 bauss via 
Digitalmars-d-learn wrote:

On Saturday, 28 April 2018 at 04:56:26 UTC, lempiji wrote:
> On Friday, 27 April 2018 at 02:59:16 UTC, Dr.No wrote:
>> In C# you can have a readonly member assignable either at 
>> declaration or constructor time, like this:

>>
>> class C
>> {
>>
>>   readonly myClass mc;
>>
>>   this()
>>   {
>>
>> mc = new myClass();
>>
>>   }
>>
>>
>>   void doSomething()
>>   {
>>
>> mc = new myClass(); // wrong! result in compiler error, 
>> mc

>>
>> is readonly
>>
>>   }
>>
>> }
>>
>> Does D have something like this natively or there's a way 
>> to do so with traits/CTFE at runtime?

>
> You can use std.experimenta.typecons.Final. 
> https://dlang.org/phobos/std_experimental_typecons.html#.Final


I don't know why D always swears to have library solutions for 
everything.


This is clearly something that should have a DIP and a 
language implementation in my opinion, considering it's a 
type-system addition.


It looks like a bad hack honestly.


Well, once upon a time, early in D2's development, it actually 
did have both head and tail const, but it was deemed too 
complicated, and we ended up with the transitive const that we 
have today that works as tail-const under some circumstances 
but not all. The fact that immutable exists really complicates 
things, more or less requiring tranitive const, and the fact 
that the type system doesn't really distinguish between a class 
and its reference also complicates things.


Personally, I think that head-const is almost worthless, so I 
see no real value in adding it, but the fact that we're forced 
to have Rebindable to get tail-const for classes is defintely 
ugly, though AFAIK, Walter and Andrei both consider it to be a 
perfectly acceptable solution given the issues with altering 
how the language treats classes.


Maybe a solid DIP could be constructed which would be accepted, 
but it's likely going to need some good arguments given how 
much this has been argued over in the past.


- Jonathan M Davis


Yeah, honestly I'm in the same opinion as you.

Usually when I have been writing C# and used readonly, what I 
really wanted to use is immutable.


I'm not saying we need to implement this in the language, but 
just that the library solution isn't really elegant at all, 
compared to what a language implementation would have been.


Re: readonly member (but assignable at constructor time)

2018-04-30 Thread Jonathan M Davis via Digitalmars-d-learn
On Monday, April 30, 2018 10:36:52 bauss via Digitalmars-d-learn wrote:
> On Saturday, 28 April 2018 at 04:56:26 UTC, lempiji wrote:
> > On Friday, 27 April 2018 at 02:59:16 UTC, Dr.No wrote:
> >> In C# you can have a readonly member assignable either at
> >> declaration or constructor time, like this:
> >>
> >> class C
> >> {
> >>
> >>   readonly myClass mc;
> >>
> >>   this()
> >>   {
> >>
> >> mc = new myClass();
> >>
> >>   }
> >>
> >>
> >>   void doSomething()
> >>   {
> >>
> >> mc = new myClass(); // wrong! result in compiler error, mc
> >>
> >> is readonly
> >>
> >>   }
> >>
> >> }
> >>
> >> Does D have something like this natively or there's a way to
> >> do so with traits/CTFE at runtime?
> >
> > You can use std.experimenta.typecons.Final.
> > https://dlang.org/phobos/std_experimental_typecons.html#.Final
>
> I don't know why D always swears to have library solutions for
> everything.
>
> This is clearly something that should have a DIP and a language
> implementation in my opinion, considering it's a type-system
> addition.
>
> It looks like a bad hack honestly.

Well, once upon a time, early in D2's development, it actually did have both
head and tail const, but it was deemed too complicated, and we ended up with
the transitive const that we have today that works as tail-const under some
circumstances but not all. The fact that immutable exists really complicates
things, more or less requiring tranitive const, and the fact that the type
system doesn't really distinguish between a class and its reference also
complicates things.

Personally, I think that head-const is almost worthless, so I see no real
value in adding it, but the fact that we're forced to have Rebindable to get
tail-const for classes is defintely ugly, though AFAIK, Walter and Andrei
both consider it to be a perfectly acceptable solution given the issues with
altering how the language treats classes.

Maybe a solid DIP could be constructed which would be accepted, but it's
likely going to need some good arguments given how much this has been argued
over in the past.

- Jonathan M Davis



Re: readonly member (but assignable at constructor time)

2018-04-30 Thread bauss via Digitalmars-d-learn

On Saturday, 28 April 2018 at 04:56:26 UTC, lempiji wrote:

On Friday, 27 April 2018 at 02:59:16 UTC, Dr.No wrote:
In C# you can have a readonly member assignable either at 
declaration or constructor time, like this:


class C
{
  readonly myClass mc;

  this()
  {
mc = new myClass();
  }


  void doSomething()
  {
mc = new myClass(); // wrong! result in compiler error, mc 
is readonly

  }
}

Does D have something like this natively or there's a way to 
do so with traits/CTFE at runtime?


You can use std.experimenta.typecons.Final.
https://dlang.org/phobos/std_experimental_typecons.html#.Final


I don't know why D always swears to have library solutions for 
everything.


This is clearly something that should have a DIP and a language 
implementation in my opinion, considering it's a type-system 
addition.


It looks like a bad hack honestly.


Re: readonly member (but assignable at constructor time)

2018-04-27 Thread lempiji via Digitalmars-d-learn

On Friday, 27 April 2018 at 02:59:16 UTC, Dr.No wrote:
In C# you can have a readonly member assignable either at 
declaration or constructor time, like this:


class C
{
  readonly myClass mc;

  this()
  {
mc = new myClass();
  }


  void doSomething()
  {
mc = new myClass(); // wrong! result in compiler error, mc 
is readonly

  }
}

Does D have something like this natively or there's a way to do 
so with traits/CTFE at runtime?


You can use std.experimenta.typecons.Final.
https://dlang.org/phobos/std_experimental_typecons.html#.Final


Re: readonly member (but assignable at constructor time)

2018-04-26 Thread Jonathan M Davis via Digitalmars-d-learn
On Friday, April 27, 2018 02:59:16 Dr.No via Digitalmars-d-learn wrote:
> In C# you can have a readonly member assignable either at
> declaration or constructor time, like this:
>
> class C
> {
>readonly myClass mc;
>
>this()
>{
>  mc = new myClass();
>}
>
>
>void doSomething()
>{
>  mc = new myClass(); // wrong! result in compiler error, mc is
> readonly
>}
> }
>
> Does D have something like this natively or there's a way to do
> so with traits/CTFE at runtime?

D has const, though that has some pretty far-reaching repercussions, since
it means that the object can't be mutated at all, and the only member
functions that can be called on it are const or inout.

If you want to specifically make it so that the object is mutable but the
reference can't be assigned to, then it would have to be protected by a
wrapper struct that @disabled opAssign and then either used alias this or
opDispatch to forward calls to the class reference inside the struct. D's
const is transitive and does not have any form of head-const, so const can't
be used in a case like that.

- Jonathan M Davis



readonly member (but assignable at constructor time)

2018-04-26 Thread Dr.No via Digitalmars-d-learn
In C# you can have a readonly member assignable either at 
declaration or constructor time, like this:


class C
{
  readonly myClass mc;

  this()
  {
mc = new myClass();
  }


  void doSomething()
  {
mc = new myClass(); // wrong! result in compiler error, mc is 
readonly

  }
}

Does D have something like this natively or there's a way to do 
so with traits/CTFE at runtime?


Re: Readonly field for class type

2018-03-15 Thread Ali Çehreli via Digitalmars-d-learn

On 03/15/2018 03:16 AM, Andrey wrote:
Hello, is there way to declare read only field for class type with 
ability to call inner non constant methods? i.e.:



class A {
    int value = 12;
    void updateValue() {
    value = 13;
    }
}

class B {
    const A a;

    this() {
    a = new A();
    a.updateValue();  // error: mutable method is not callable 
using const object

    }
}



Another option is assigning a pre-made A to the member:

class A {
int value = 12;
void updateValue() {
value = 13;
}
}

// Magic recipe is moved here:
A makeA() {
auto a = new A();
a.updateValue();
return a;
}

class B {
const A a;

this() {
a = makeA();
}
}

void main() {
auto b = new B();
}

Which can be compressed into a lambda in the constructor:

this() {
a = {
// This 'a' is a local variable inside the lambda:
auto a = new A();
a.updateValue();
return a;
}();
}

Ali


Re: Readonly field for class type

2018-03-15 Thread Seb via Digitalmars-d-learn

On Thursday, 15 March 2018 at 13:44:20 UTC, Seb wrote:

On Thursday, 15 March 2018 at 10:57:52 UTC, Mike Parker wrote:

On Thursday, 15 March 2018 at 10:55:16 UTC, Mike Parker wrote:



class A {
private int _value = 12;

int value() @property { return _value; }
void updateValue() { value = 13; }
}

...
auto a = new A();
writeln(a.value);
a.updateValue();
writeln(a.value);


Sorry. I overlooked that B.a is const.


It still works, the `value` just needs to be `const` (or 
`inout`) and _value needs to be used in updateValue:


class A {
private int _value = 12;

int value() const { return _value; }
void updateValue() { _value = 13; }
}


auto a = new A();
writeln(a.value);
a.updateValue();
writeln(a.value);


In action: https://run.dlang.io/is/Tk1rY1

@Robert: If you need this a lot, the accessors package might be 
interesting to you:


https://code.dlang.org/packages/accessors


... and I didn't add `const` to A

-> https://run.dlang.io/is/QObN1w

but better have a look at Simen's response 
(https://forum.dlang.org/post/ottyywbmrwgfabgpf...@forum.dlang.org), it's what you are looking for. I read too quickly and only have of it :/


Re: Readonly field for class type

2018-03-15 Thread Seb via Digitalmars-d-learn

On Thursday, 15 March 2018 at 13:44:20 UTC, Seb wrote:

On Thursday, 15 March 2018 at 10:57:52 UTC, Mike Parker wrote:

On Thursday, 15 March 2018 at 10:55:16 UTC, Mike Parker wrote:


[...]


Sorry. I overlooked that B.a is const.


It still works, the `value` just needs to be `const` (or 
`inout`) and _value needs to be used in updateValue:


class A {
private int _value = 12;

int value() const { return _value; }
void updateValue() { _value = 13; }
}


auto a = new A();
writeln(a.value);
a.updateValue();
writeln(a.value);


In action: https://run.dlang.io/is/Tk1rY1

@Robert: If you need this a lot, the accessors package might be 
interesting to you:


https://code.dlang.org/packages/accessors


(I meant @Andrey - sorry)


Re: Readonly field for class type

2018-03-15 Thread Seb via Digitalmars-d-learn

On Thursday, 15 March 2018 at 10:57:52 UTC, Mike Parker wrote:

On Thursday, 15 March 2018 at 10:55:16 UTC, Mike Parker wrote:



class A {
private int _value = 12;

int value() @property { return _value; }
void updateValue() { value = 13; }
}

...
auto a = new A();
writeln(a.value);
a.updateValue();
writeln(a.value);


Sorry. I overlooked that B.a is const.


It still works, the `value` just needs to be `const` (or `inout`) 
and _value needs to be used in updateValue:


class A {
private int _value = 12;

int value() const { return _value; }
void updateValue() { _value = 13; }
}


auto a = new A();
writeln(a.value);
a.updateValue();
writeln(a.value);


In action: https://run.dlang.io/is/Tk1rY1

@Robert: If you need this a lot, the accessors package might be 
interesting to you:


https://code.dlang.org/packages/accessors


Re: Readonly field for class type

2018-03-15 Thread Mike Parker via Digitalmars-d-learn

On Thursday, 15 March 2018 at 10:16:49 UTC, Andrey wrote:
Hello, is there way to declare read only field for class type 
with ability to call inner non constant methods? i.e.:



class A {
int value = 12;
void updateValue() {
value = 13;
}
}

class B {
const A a;

this() {
a = new A();
a.updateValue();  // error: mutable method is not 
callable using const object

}
}


class A {
private int _value = 12;

int value() @property { return _value; }
void updateValue() { value = 13; }
}

...
auto a = new A();
writeln(a.value);
a.updateValue();
writeln(a.value);


Re: Readonly field for class type

2018-03-15 Thread Simen Kjærås via Digitalmars-d-learn

On Thursday, 15 March 2018 at 10:16:49 UTC, Andrey wrote:
Hello, is there way to declare read only field for class type 
with ability to call inner non constant methods? i.e.:



class A {
int value = 12;
void updateValue() {
value = 13;
}
}

class B {
const A a;

this() {
a = new A();
a.updateValue();  // error: mutable method is not 
callable using const object

}
}


You can do this:

class B {
private A _a;
@property const(A) a() { return _a; }

this() {
_a = new A();
_a.updateValue();
}
}

--
  Simen


Re: Readonly field for class type

2018-03-15 Thread Mike Parker via Digitalmars-d-learn

On Thursday, 15 March 2018 at 10:55:16 UTC, Mike Parker wrote:



class A {
private int _value = 12;

int value() @property { return _value; }
void updateValue() { value = 13; }
}

...
auto a = new A();
writeln(a.value);
a.updateValue();
writeln(a.value);


Sorry. I overlooked that B.a is const.


Readonly field for class type

2018-03-15 Thread Andrey via Digitalmars-d-learn
Hello, is there way to declare read only field for class type 
with ability to call inner non constant methods? i.e.:



class A {
int value = 12;
void updateValue() {
value = 13;
}
}

class B {
const A a;

this() {
a = new A();
a.updateValue();  // error: mutable method is not 
callable using const object

}
}






Why D doesn't have an equivalent to C#'s readonly?

2015-06-30 Thread Assembly via Digitalmars-d-learn
I believe it's a design choice, if so, could someone explain why? 
is immutable better than C#'s readonly so that the readonly 
keyword isn't even needed? for example, I'd like to declare a 
member as readonly but I can't do it directly because immutable 
create a new type (since it's a type specific, correct?) isn't 
really the same thing.


MyClass x = new MyClass();

if I do

auto x = new immutable(MyClass)();

give errors


Re: Why D doesn't have an equivalent to C#'s readonly?

2015-06-30 Thread Gary Willoughby via Digitalmars-d-learn

On Monday, 29 June 2015 at 20:12:12 UTC, Assembly wrote:
I believe it's a design choice, if so, could someone explain 
why? is immutable better than C#'s readonly so that the 
readonly keyword isn't even needed? for example, I'd like to 
declare a member as readonly but I can't do it directly because 
immutable create a new type (since it's a type specific, 
correct?) isn't really the same thing.


MyClass x = new MyClass();

if I do

auto x = new immutable(MyClass)();

give errors


There are a few ways you can enforce a field to be readonly.

You can use properties:

import std.stdio;

class Foo
{
private int _bar;

this(int bar)
{
this._bar = bar;
}

public @property int bar()
{
return this._bar;
}
}

void main(string[] args)
{
auto foo = new Foo(1337);

writefln(%s, foo.bar);

// Error:
// foo.bar = 10;
}

or a manifest constant:

import std.stdio;

class Foo
{
public enum int bar = 1337;
}

void main(string[] args)
{
auto foo = new Foo();

writefln(%s, foo.bar);

// Error:
// foo.bar = 10;
}


Re: Why D doesn't have an equivalent to C#'s readonly?

2015-06-30 Thread anonymous via Digitalmars-d-learn

On Monday, 29 June 2015 at 22:11:16 UTC, sigod wrote:

`new immutable(MyClass)()` is invalid code.


It's perfectly fine, actually.



Re: Why D doesn't have an equivalent to C#'s readonly?

2015-06-30 Thread sigod via Digitalmars-d-learn

On Monday, 29 June 2015 at 20:12:12 UTC, Assembly wrote:
I believe it's a design choice, if so, could someone explain 
why? is immutable better than C#'s readonly so that the 
readonly keyword isn't even needed? for example, I'd like to 
declare a member as readonly but I can't do it directly because 
immutable create a new type (since it's a type specific, 
correct?) isn't really the same thing.


MyClass x = new MyClass();

if I do

auto x = new immutable(MyClass)();

give errors


Why? I think `const` and `immutable` even better than C#'s 
`readonly`. Also, are you aware that it's recommended to use 
`const` instead of `readonly`?


`new immutable(MyClass)()` is invalid code. Try `immutable 
MyClass x = new MyClass();`.


Re: Why D doesn't have an equivalent to C#'s readonly?

2015-06-30 Thread sigod via Digitalmars-d-learn

On Monday, 29 June 2015 at 22:22:46 UTC, anonymous wrote:

On Monday, 29 June 2015 at 22:11:16 UTC, sigod wrote:

`new immutable(MyClass)()` is invalid code.


It's perfectly fine, actually.


Yes, you're right. It seems I've mistyped `immutable` when was 
checking it with compiler.


Re: Readonly-to-outside variable

2015-04-28 Thread Baz via Digitalmars-d-learn

On Tuesday, 28 April 2015 at 19:30:06 UTC, tcak wrote:
Is there any way to define a variable or an attribute as 
read-only without defining a getter function/method for it?


Thoughts behind this question are:
1. For every reading, another function call process for CPU 
while it could directly read the value from memory.


2. Repetition of same name for variable and getVariableName. 
(Some might not agree with this but I like the code when it 
looks nice.)


an quick attempt:

---
union ReadOnlyOutside(T)
{
alias value this;
private T _value;
public const T value;
}
---

when you declare such a variable inside a struct or a class, the 
code located in another module won't be able to modify the value:


module1:

---
struct Foo
{
ReadOnlyOutside!size_t roField;
}
---

module2:

void something(ref Foo foo)
{
writeln(foo.roField); // OK
writeln(foo.roField.value); // OK
foo.roField = 1; // FAIL
foo.roField.value = 1,// FAIL (because const).
foo.roField._value = 1,// FAIL (because not visible).
}



Readonly-to-outside variable

2015-04-28 Thread tcak via Digitalmars-d-learn
Is there any way to define a variable or an attribute as 
read-only without defining a getter function/method for it?


Thoughts behind this question are:
1. For every reading, another function call process for CPU while 
it could directly read the value from memory.


2. Repetition of same name for variable and getVariableName. 
(Some might not agree with this but I like the code when it looks 
nice.)




Re: Readonly-to-outside variable

2015-04-28 Thread Justin Whear via Digitalmars-d-learn
On Tue, 28 Apr 2015 19:30:04 +, tcak wrote:

 Is there any way to define a variable or an attribute as read-only
 without defining a getter function/method for it?
 
 Thoughts behind this question are:
 1. For every reading, another function call process for CPU while it
 could directly read the value from memory.
 
 2. Repetition of same name for variable and getVariableName. (Some might
 not agree with this but I like the code when it looks nice.)

1. I wouldn't worry too much about the performance--compiling with gdc or 
ldc with inlining should reduce it to a simple access.
2. You can clean it up if it annoys you with something like this:

mixin template readonly(T, string name)
{
mixin(`private T _`~name~`;T `~name~`()@property{return _`~name~`;}`);
}

Use it like:

class Foo
{
// injects a private int _x, public int x()
mixin readonly!(int, x);
}


Re: Can I make a variable public and readonly (outside where was declared) at same time?

2014-09-27 Thread via Digitalmars-d-learn
On Friday, 26 September 2014 at 18:18:45 UTC, Steven 
Schveighoffer wrote:
On 9/26/14 1:36 PM, Marc =?UTF-8?B?U2Now7x0eiI=?= 
schue...@gmx.net wrote:


Alternatively, you could create a union with a private and a 
public
member with the same types, but I wouldn't recommend it. 
Besides, the

members would need to have different names:

class Foo {
union {
private int a;
public int b;
}
}


Hm.. that doesn't provide readonly access to either a or b.

But it gave me an idea:

class Foo {
   union {
  private int _a;
  public const int a;
   }
   void setA(int x) { _a = x; }
}



Yes, that's what I originally intended. Just forgot the const, 
and didn't even notice it after I reread it :-P


Re: Can I make a variable public and readonly (outside where was declared) at same time?

2014-09-27 Thread AsmMan via Digitalmars-d-learn
On Friday, 26 September 2014 at 18:18:45 UTC, Steven 
Schveighoffer wrote:
On 9/26/14 1:36 PM, Marc =?UTF-8?B?U2Now7x0eiI=?= 
schue...@gmx.net wrote:


Alternatively, you could create a union with a private and a 
public
member with the same types, but I wouldn't recommend it. 
Besides, the

members would need to have different names:

class Foo {
union {
private int a;
public int b;
}
}


Hm.. that doesn't provide readonly access to either a or b.

But it gave me an idea:

class Foo {
   union {
  private int _a;
  public const int a;
   }
   void setA(int x) { _a = x; }
}

Hot damn! It works too :) Can't access _a from outside the 
module, can access a, but can't write it (even from within 
Foo). It's like an auto-inlined property function.


I don't know how it would affect the optimizer, or the GC 
scanner. Unions are ugly things...


-Steve


This is really a loot cool and works. Thanks. If private in D had 
same behavior like in C#/C++, ie, private to scope of where class 
was declared and not public to the entire module, I guess we 
could even do:


class Foo {
union {
private int a_;

public @property int a() {
return a_;
}

private @property void a(int value) {
a_ = value;
}
}

//no one need knows the 'a_' (ugly?) identifier
void setValue(int x)
{
a = x;
}
}

And then

Foo f = new Foo();
f.a = 10; // give a compile error becaus it is private and 
acessible within Foo class only


BTW: I'm not sure about memory usage where using properties. But 
it is still cool.


Re: Can I make a variable public and readonly (outside where was declared) at same time?

2014-09-27 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/27/14 5:48 AM, Marc =?UTF-8?B?U2Now7x0eiI=?= schue...@gmx.net

Yes, that's what I originally intended. Just forgot the const, and
didn't even notice it after I reread it :-P


I wondered... ;)

-Steve


Can I make a variable public and readonly (outside where was declared) at same time?

2014-09-26 Thread AsmMan via Digitalmars-d-learn
I know I can combine it by making an extra variable plus a 
property like this:


class Foo
{
  private int a_;

  void do_something1()
  {
a_ = baa();
  }

  void do_something2()
  {
if(cond) a_ = baa2();
  }

  @property int a()
  {
  return a;
   }
}

This is the C#'s to do which I'm translated to D within my 
limited knowledge. I don't do much OOP, maybe it's possible and I 
don't know. I'm using @property to make 'a' accessible and 
readonly at same time but I wanted to do that without this a_ 
extra variable, i.e, only the methods within the Foo class can 
assign a new value to a but a instance of Foo can't. An imaginary 
code example:


class Foo
{
  public MAGIC_HERE int a;

  void do_something1()
  {
a = baa();
  }

  void do_something2()
  {
if(cond) a = baa2();
  }
}


And then:

Foo f = new Foo();
writeln(f.a); // output value of a
f.a = 10; // compile error: a is readonly outside Foo's methods.

I hope it's clear (sorry for por English)


Re: Can I make a variable public and readonly (outside where was declared) at same time?

2014-09-26 Thread Gary Willoughby via Digitalmars-d-learn

On Friday, 26 September 2014 at 17:16:04 UTC, AsmMan wrote:
I know I can combine it by making an extra variable plus a 
property like this:


class Foo
{
  private int a_;

  void do_something1()
  {
a_ = baa();
  }

  void do_something2()
  {
if(cond) a_ = baa2();
  }

  @property int a()
  {
  return a;
   }
}

This is the C#'s to do which I'm translated to D within my 
limited knowledge. I don't do much OOP, maybe it's possible and 
I don't know. I'm using @property to make 'a' accessible and 
readonly at same time but I wanted to do that without this a_ 
extra variable, i.e, only the methods within the Foo class can 
assign a new value to a but a instance of Foo can't. An 
imaginary code example:


class Foo
{
  public MAGIC_HERE int a;

  void do_something1()
  {
a = baa();
  }

  void do_something2()
  {
if(cond) a = baa2();
  }
}


And then:

Foo f = new Foo();
writeln(f.a); // output value of a
f.a = 10; // compile error: a is readonly outside Foo's methods.

I hope it's clear (sorry for por English)


I think the extra variable and the properties are the way to go 
and it's the idiomatic way. In fact that's the reason properties 
are there.


Saying that though, you can achieve what you want implementing a 
little more code using opDispatch. opDispatch intercepts calls to 
undefined members and deals with them, in this case forwarding to 
a private variable.


http://dlang.org/operatoroverloading.html#dispatch


Re: Can I make a variable public and readonly (outside where was declared) at same time?

2014-09-26 Thread Ali Çehreli via Digitalmars-d-learn

On 09/26/2014 10:16 AM, AsmMan wrote:

 I know I can combine it by making an extra variable plus a property like
 this:

That's the proper way of doing it in D.

If it's too much work, it is possible to take advantage of mixins to 
reduce the boilerplate. I found the following code among my D samples; 
it must have been found on these forums.


Defining without set would disallow the setter:

alias AutoImplementedProperty!(string, get) title;

The code:

import std.stdio;

class Bar
{
alias AutoImplementedProperty!(string, get, set) title;
}

template AutoImplementedProperty(T, args...)
{
import std.typetuple;
@property
{
private T _name;
static if (args.length)
{
static if (staticIndexOf!(get, args)  -1)
{
public T AutoImplementedProperty()
{
return _name;
}
}

static if (staticIndexOf!(set, args)  -1)
{
public void AutoImplementedProperty(T value)
{
_name = value;
}
}

}
}
}

void main(string[] args)
{
Bar a = new Bar();
a.title = asf;
writeln(a.title);

return;
}

 I wanted to do that without this a_ extra variable

If the value is set only once and it is known during construction, it is 
indeed mark the variable public const:


import std.stdio;

class Foo
{
public const int a;

this (int x)
{
a = 2 * x;
}
}

void main()
{
Foo f = new Foo(21);
writeln(f.a); // output value of a

Foo f2 = f;// copy works
f2 = f;// assignment works

// f.a = 10; // compile error: a is readonly outside Foo's methods.
}

Ali



Re: Can I make a variable public and readonly (outside where was declared) at same time?

2014-09-26 Thread via Digitalmars-d-learn

On Friday, 26 September 2014 at 17:16:04 UTC, AsmMan wrote:
I know I can combine it by making an extra variable plus a 
property like this:


class Foo
{
  private int a_;

  void do_something1()
  {
a_ = baa();
  }

  void do_something2()
  {
if(cond) a_ = baa2();
  }

  @property int a()
  {
  return a;
   }
}

This is the C#'s to do which I'm translated to D within my 
limited knowledge. I don't do much OOP, maybe it's possible and 
I don't know. I'm using @property to make 'a' accessible and 
readonly at same time but I wanted to do that without this a_ 
extra variable, i.e, only the methods within the Foo class can 
assign a new value to a but a instance of Foo can't. An 
imaginary code example:


class Foo
{
  public MAGIC_HERE int a;

  void do_something1()
  {
a = baa();
  }

  void do_something2()
  {
if(cond) a = baa2();
  }
}


And then:

Foo f = new Foo();
writeln(f.a); // output value of a
f.a = 10; // compile error: a is readonly outside Foo's methods.

I hope it's clear (sorry for por English)


The closest you can get is probably this:

class Foo {
private int a_;

@property int a() {
return a_;
}

private @property void a(int value) {
a_ = value;
}
}

You can then assign to `a` inside the class `Foo` _and_ inside 
its module (because `private` is always accessible from within 
the same module), while from other modules, it can only be read.


But it's not exactly a read-only variable, because you cannot 
take an address from it, for example.


Alternatively, you could create a union with a private and a 
public member with the same types, but I wouldn't recommend it. 
Besides, the members would need to have different names:


class Foo {
union {
private int a;
public int b;
}
}


Re: Can I make a variable public and readonly (outside where was declared) at same time?

2014-09-26 Thread bearophile via Digitalmars-d-learn

Marc Schütz:

Alternatively, you could create a union with a private and a 
public member with the same types, but I wouldn't recommend it. 
Besides, the members would need to have different names:


class Foo {
union {
private int a;
public int b;
}
}


You can call them a and a_. Why are you not recommending this 
solution? It looks cool (if it works).


Bye,
bearophile


Re: Can I make a variable public and readonly (outside where was declared) at same time?

2014-09-26 Thread via Digitalmars-d-learn

On Friday, 26 September 2014 at 17:52:58 UTC, bearophile wrote:

Marc Schütz:

Alternatively, you could create a union with a private and a 
public member with the same types, but I wouldn't recommend 
it. Besides, the members would need to have different names:


   class Foo {
   union {
   private int a;
   public int b;
   }
   }


You can call them a and a_. Why are you not recommending this 
solution? It looks cool (if it works).


Don't know, it feels hacky. And I really don't like the two 
different names, what's the point if I have to distinguish the 
two manually?


Now yet another way came to my mind:

struct PrivatelyWritableProperty(T) {
private T value_;
const(T) get() const { return value_; }
private void opAssign(T value) { value_ = value; }
alias get this;
}

class Foo {
PrivatelyWritableProperty!int a;
}

But this looks even more fragile; there are probably some 
corner-cases where it doesn't work (for example, what happens 
when someone copies the containing struct?).


Re: Can I make a variable public and readonly (outside where was declared) at same time?

2014-09-26 Thread Steven Schveighoffer via Digitalmars-d-learn
On 9/26/14 1:36 PM, Marc =?UTF-8?B?U2Now7x0eiI=?= schue...@gmx.net 
wrote:



Alternatively, you could create a union with a private and a public
member with the same types, but I wouldn't recommend it. Besides, the
members would need to have different names:

 class Foo {
 union {
 private int a;
 public int b;
 }
 }


Hm.. that doesn't provide readonly access to either a or b.

But it gave me an idea:

class Foo {
   union {
  private int _a;
  public const int a;
   }
   void setA(int x) { _a = x; }
}

Hot damn! It works too :) Can't access _a from outside the module, can 
access a, but can't write it (even from within Foo). It's like an 
auto-inlined property function.


I don't know how it would affect the optimizer, or the GC scanner. 
Unions are ugly things...


-Steve


Re: rmdirRecurse vs readonly

2013-12-25 Thread Lemonfiend

On Tuesday, 24 December 2013 at 16:11:15 UTC, Ali Çehreli wrote:

On 12/24/2013 04:13 AM, Lemonfiend wrote:

std.file.rmdirRecurse refuses to remove readonly files.

How would I go about deleting them anyway?


Call std.file.setAttributes() first, which has apparently been 
added just three days ago: :)



https://github.com/D-Programming-Language/phobos/blob/master/std/file.d#L971

If you can't work with git head version of dmd, then do what it 
does yourself, depending on your platform:


void setAttributes(in char[] name, uint attributes)
{
version (Windows)
{
cenforce(SetFileAttributesW(std.utf.toUTF16z(name), 
attributes), name);

}
else version (Posix)
{
assert(attributes = mode_t.max);
cenforce(!chmod(toStringz(name), 
cast(mode_t)attributes), name);

}
}

For example, if you are on Linux:

import core.sys.posix.sys.stat;
import std.conv;

// ...

chmod(/my/file, cast(mode_t)octal!777)

Ali


Haha, how very timely.

Thanks! And merry xmas :)


rmdirRecurse vs readonly

2013-12-24 Thread Lemonfiend

std.file.rmdirRecurse refuses to remove readonly files.

How would I go about deleting them anyway?


Re: rmdirRecurse vs readonly

2013-12-24 Thread Ali Çehreli

On 12/24/2013 04:13 AM, Lemonfiend wrote:

std.file.rmdirRecurse refuses to remove readonly files.

How would I go about deleting them anyway?


Call std.file.setAttributes() first, which has apparently been added 
just three days ago: :)



https://github.com/D-Programming-Language/phobos/blob/master/std/file.d#L971

If you can't work with git head version of dmd, then do what it does 
yourself, depending on your platform:


void setAttributes(in char[] name, uint attributes)
{
version (Windows)
{
cenforce(SetFileAttributesW(std.utf.toUTF16z(name), 
attributes), name);

}
else version (Posix)
{
assert(attributes = mode_t.max);
cenforce(!chmod(toStringz(name), cast(mode_t)attributes), name);
}
}

For example, if you are on Linux:

import core.sys.posix.sys.stat;
import std.conv;

// ...

chmod(/my/file, cast(mode_t)octal!777)

Ali



How to translate C# 'readonly' keyword into D

2013-02-04 Thread o3o
I'm a C# programmer, when I apply IoC pattern  I use readonly 
keyword 
(http://msdn.microsoft.com/en-us/library/acdd6hb7%28v=vs.71%29.aspx) 
in this manner:


:// C# code
:interface IFoo {
:  void Fun();
:}
:
:class Foo: IFoo {
:  void Fun() {...}
:}
:class Bar {
:  private readonly IFoo foo;
:  // inject IFoo into Bar
:  Bar(IFoo foo) {
:// assert(foo != null);
:this.foo = foo;
:  }
:  void Gun() {
:// foo = new Foo();  ERROR: foo is readonly!
:foo.Fun();
:  }
:}

Can someone help me to translate readonly IFoo foo; so that the 
dmd compiler raises an error when I write foo = new Foo(); ?


I try:
:// D code
:interface IFoo {
:   void fun();
:}
:
:class Foo: IFoo {
:   void fun() {
:  writeln(fun...);
:   }
:}
:
:class Bar {
:   private const IFoo service;
:   this(const IFoo service) {
:  this.service = service;
:   }
:
:   void gun() {
:  service.fun();
:   }
:}
:unittest {
:  const(IFoo) s = new Foo;
:  auto bar = new Bar(s);
:  bar.gun();
:}
but the compiler complains:
Error: function main.IFoo.fun () is not callable using argument 
types () const




Re: How to translate C# 'readonly' keyword into D

2013-02-04 Thread simendsjo

On Monday, 4 February 2013 at 09:02:31 UTC, o3o wrote:
I'm a C# programmer, when I apply IoC pattern  I use readonly 
keyword 
(http://msdn.microsoft.com/en-us/library/acdd6hb7%28v=vs.71%29.aspx) 
in this manner:


:// C# code
:interface IFoo {
:  void Fun();
:}
:
:class Foo: IFoo {
:  void Fun() {...}
:}
:class Bar {
:  private readonly IFoo foo;
:  // inject IFoo into Bar
:  Bar(IFoo foo) {
:// assert(foo != null);
:this.foo = foo;
:  }
:  void Gun() {
:// foo = new Foo();  ERROR: foo is readonly!
:foo.Fun();
:  }
:}

Can someone help me to translate readonly IFoo foo; so that 
the dmd compiler raises an error when I write foo = new 
Foo(); ?


I try:
:// D code
:interface IFoo {
:   void fun();
:}
:
:class Foo: IFoo {
:   void fun() {
:  writeln(fun...);
:   }
:}
:
:class Bar {
:   private const IFoo service;
:   this(const IFoo service) {
:  this.service = service;
:   }
:
:   void gun() {
:  service.fun();
:   }
:}
:unittest {
:  const(IFoo) s = new Foo;
:  auto bar = new Bar(s);
:  bar.gun();
:}
but the compiler complains:
Error: function main.IFoo.fun () is not callable using argument 
types () const


In D, everything accessible from const is also const. You 
specifically state that you will not modify your IFoo instance. 
But then you call foo(). foo() in turn isn't marked as const, so 
this can modify IFoo, and thus break const.
So.. Every method you call through a const instance must also be 
const, otherwise you have the ability to change something that 
should be a constant.




Re: How to translate C# 'readonly' keyword into D

2013-02-04 Thread simendsjo

On Monday, 4 February 2013 at 10:26:55 UTC, simendsjo wrote:

On Monday, 4 February 2013 at 09:02:31 UTC, o3o wrote:
I'm a C# programmer, when I apply IoC pattern  I use 
readonly keyword 
(http://msdn.microsoft.com/en-us/library/acdd6hb7%28v=vs.71%29.aspx) 
in this manner:


:// C# code
:interface IFoo {
:  void Fun();
:}
:
:class Foo: IFoo {
:  void Fun() {...}
:}
:class Bar {
:  private readonly IFoo foo;
:  // inject IFoo into Bar
:  Bar(IFoo foo) {
:// assert(foo != null);
:this.foo = foo;
:  }
:  void Gun() {
:// foo = new Foo();  ERROR: foo is readonly!
:foo.Fun();
:  }
:}

Can someone help me to translate readonly IFoo foo; so that 
the dmd compiler raises an error when I write foo = new 
Foo(); ?


I try:
:// D code
:interface IFoo {
:   void fun();
:}
:
:class Foo: IFoo {
:   void fun() {
:  writeln(fun...);
:   }
:}
:
:class Bar {
:   private const IFoo service;
:   this(const IFoo service) {
:  this.service = service;
:   }
:
:   void gun() {
:  service.fun();
:   }
:}
:unittest {
:  const(IFoo) s = new Foo;
:  auto bar = new Bar(s);
:  bar.gun();
:}
but the compiler complains:
Error: function main.IFoo.fun () is not callable using 
argument types () const


In D, everything accessible from const is also const. You 
specifically state that you will not modify your IFoo instance. 
But then you call foo(). foo() in turn isn't marked as const, 
so this can modify IFoo, and thus break const.
So.. Every method you call through a const instance must also 
be const, otherwise you have the ability to change something 
that should be a constant.


So this works:
interface IFoo {
void fun() const;
}

class Foo : IFoo {
void fun() const {}
}

class Bar {
private const IFoo service;
this(const IFoo service) {
this.service = service;
}

void gun() {
service.fun();
}
}

unittest {
const s = new Foo();
auto bar = new Bar(s);
bar.gun();
}

void main() {}


Re: How to translate C# 'readonly' keyword into D

2013-02-04 Thread Jacob Carlborg

On 2013-02-04 10:02, o3o wrote:

I'm a C# programmer, when I apply IoC pattern  I use readonly keyword
(http://msdn.microsoft.com/en-us/library/acdd6hb7%28v=vs.71%29.aspx) in
this manner:

:// C# code
:interface IFoo {
:  void Fun();
:}
:
:class Foo: IFoo {
:  void Fun() {...}
:}
:class Bar {
:  private readonly IFoo foo;
:  // inject IFoo into Bar
:  Bar(IFoo foo) {
:// assert(foo != null);
:this.foo = foo;
:  }
:  void Gun() {
:// foo = new Foo();  ERROR: foo is readonly!
:foo.Fun();
:  }
:}

Can someone help me to translate readonly IFoo foo; so that the dmd
compiler raises an error when I write foo = new Foo(); ?


The closest would probably be defining a property with only a getter:

class Bar
{
private IFoo foo_;

private @property foo () { return foo_; }

this (IFoo foo)
{
foo_ = foo;
}
}

You can still change the foo_ variable.

--
/Jacob Carlborg


Re: How to translate C# 'readonly' keyword into D

2013-02-04 Thread o3o

On Monday, 4 February 2013 at 10:26:55 UTC, simendsjo wrote:

[cut]
So.. Every method you call through a const instance must also 
be const, otherwise you have the ability to change something 
that should be a constant.

Thanks simendsjo, now I get it...

So, let me continue the example (I remove const for 
simplicity)...

I would like check that bar.gun() call fun() function from IFoo

unittest {
 auto foo = new MockIFoo(); //Will not compile.Mock doesn't 
(yet) exist

 auto bar = new Bar(foo);
 bar.gun();
 foo.Received().fun(); // pass if 'fun' was called
}

void main() {}

In other words, I need a mock object like nsubstitute 
(http://nsubstitute.github.com/help/getting-started/) or moq 
(http://code.google.com/p/moq/)


In your old post 
http://forum.dlang.org/thread/il29hs$2svt$1...@digitalmars.com
you were asking for mocking frameworks...do you found any 
solution?

Thanks


Re: How to translate C# 'readonly' keyword into D

2013-02-04 Thread rumbu
First, AFAIK, there is no equivalent of C# readonly in D, 
despite the fact that D uses 3 keywords for various kinds of 
immutability.


Second, here you can find a  mocking library for D: 
http://www.dsource.org/projects/dmocks/wiki/DMocks




On Monday, 4 February 2013 at 13:35:24 UTC, o3o wrote:

On Monday, 4 February 2013 at 10:26:55 UTC, simendsjo wrote:

[cut]
So.. Every method you call through a const instance must also 
be const, otherwise you have the ability to change something 
that should be a constant.

Thanks simendsjo, now I get it...

So, let me continue the example (I remove const for 
simplicity)...

I would like check that bar.gun() call fun() function from IFoo

unittest {
 auto foo = new MockIFoo(); //Will not compile.Mock 
doesn't (yet) exist

 auto bar = new Bar(foo);
 bar.gun();
 foo.Received().fun(); // pass if 'fun' was called
}

void main() {}

In other words, I need a mock object like nsubstitute 
(http://nsubstitute.github.com/help/getting-started/) or moq 
(http://code.google.com/p/moq/)


In your old post 
http://forum.dlang.org/thread/il29hs$2svt$1...@digitalmars.com
you were asking for mocking frameworks...do you found any 
solution?

Thanks


Re: How to translate C# 'readonly' keyword into D

2013-02-04 Thread Jacob Carlborg

On 2013-02-04 14:35, o3o wrote:


So, let me continue the example (I remove const for simplicity)...
I would like check that bar.gun() call fun() function from IFoo

unittest {
  auto foo = new MockIFoo(); //Will not compile.Mock doesn't (yet)
exist
  auto bar = new Bar(foo);
  bar.gun();
  foo.Received().fun(); // pass if 'fun' was called
}

void main() {}


The syntax for template instantiation is:

auto foo = new Mock!(IFoo)();

--
/Jacob Carlborg


Re: readonly?

2012-07-12 Thread Artur Skawina
On 07/12/12 01:09, Jonathan M Davis wrote:
 On Wednesday, July 11, 2012 10:56:23 Artur Skawina wrote:
 Can anybody think of a reason to keep the current (broken) behavior?
 
 Easily.

You misunderstand the current (broken) behavior part - it is about
what 'C*' is, it is not at all about class references.

 Making Object* point to the object itself rather than the reference would be 
 so broken that it's not even funny. I can understand why you would think that 
 such a change should be made, but that's only because you haven't thought 
 through all of the consequences of that. It's all wrapped up in the very 
 reason why Rebindable is in the library rather than being built into the 
 language.
 
 For starters, if you have
 
 class C {}
 C c;
 
 the type of c is C. C is a reference to the class named C. It does _not_ mean 
 the same thing as the C in the class declaration at all. If it were a struct 
 rather than a class, it would be equivalent to C* (save for the fact that a 
 reference and a pointer aren't quite the same). So, _everywhere_ in the type 
 system that you see C, it's really C*, _not_ C as in the class C. There is 
 _no 
 way_ in the type system to refer to the class itself. So, making C* be a 
 pointer to the object rather than the reference isn't even representable in 
 the type system.

Of course it is - you even say it above: _everywhere_ in the type system that
you see C, it's really C*.
But instead of considering the implications and required semantics, you are 
making several assumptions, which are wrong.
For example - let 'C' be a class, then: 'new C' must return a reference to C,
not a pointer; dereferencing a 'C*' pointer should of course not be valid.


 There are all kinds of practical side effects for this. For instance, if you 
 had
 
 class D : C {}
 
 C c;
 C* cPtr = c;
 
 and C* was a pointer to the class itself, then it would almost be like doing
 
 C* c;
 C* cPtr = c;
 
 which makes no sense at all.

This is actually what effectively happens with the *current* model, it in deed
makes little sense, and is the reason for my why? questions...


 It also introduces object slicing - as in the 
 type of slicing that C++ has when you assign a derived object to a base class 
 object which is on the stack. In C++,
 
 D d;
 C c = d;
 
 results in the D portion of d being chopped off, potentially putting it in an 

D and C (in D) are references - there's no problem. I have no idea why you think
classes would be value types.

 invalid state, and almost certainly isn't what you wanted to do. D avoids 
 this 
 by requiring that polymorphic objects (classes) be on the heap. But if C* 
 referred to the object itself, it becomes a probem again.
 
 C c = new C;
 C* cPtr = c;
 *cPtr = new D;
 
 Since cPtr was a pointer to the object, *cPtr would be the object itself, and 
 so the D object would be assigned to the C object and get sliced, just like 
 in 
 the C++ example.

Dereferencing a class pointer has to be illegal, i thought that was obvious and
not needed to be spelled out. It's a simple and easily understandable rule.
So '*cPtr' wouldn't be valid - there is no problem.

 In additon, making Object* be a pointer to the object itself would make 
 dealing with pointers to local objects _very_ inconsistent. Take this for 
 example
 
 void func(T)(T* t, T value)
 {
  *t = value;
 }
 
 int i;
 func(i, 7);
 
 C c = getC();
 func(c, new C);
 
 When func is called with i, it sets i to 7. But when it's called with c, it 
 doesn't set c. It sets what c refers to. This means that instead of changing 

'*t' would not compile for a T*==C* (when the latter means a direct
pointer to the instance) ; see above.

Whether that should compile, in the model i gave as an example, is a
different question - there the call is 'func(C**, C)' which results in
'C* = implicit_cast(C*)C' -- this modifies the reference. I can see
arguments for disallowing this, but then the 'rebindable' problem would
be back, so I'd lean toward keeping it legal.

 the local variable c, you've changed an object on the heap which other 
 references could refer to, and now instead of just affecting the local 
 reference, _every_ reference is affected. This is _completely_ different from 
 how it works with i. It's more in like with how it would work if you had
 
 int* iPtr = getIntPtr();
 func(iPtr, new int);
 
 and since C is essentially equivalent to C*, it would then be impossible to 
 pass the reference itself to func to be set.

That's why I have 'C_instance' result in 'C**'. not 'C*'. Yes, it means
classes are treated differently -- but they *already* are. Yes, it's *only*
about the type, most (ie all desirable) semantics of references are kept. 

 It would also make it so that taking a pointer for a parameter was very 
 different from taking ref or out for classes, when it's nearly identical for 
 everything else.
 
 void refFunc(T)(ref T t, T value)
 {
  t = value;
 }
 
 int i;
 refFunc(i, 7);
 
 C c = getC();
 refFunc(c, new 

Re: readonly?

2012-07-11 Thread Tobias Pankrath

This escapes a stack reference.


Ins't b supposed to be allocated on the heap?


Re: readonly?

2012-07-11 Thread Jonathan M Davis
On Wednesday, July 11, 2012 08:34:28 Tobias Pankrath wrote:
  This escapes a stack reference.
 
 Ins't b supposed to be allocated on the heap?

The object is. The reference is not. b is taking the address of the 
reference, not the object.

- Jonathan M Davis


Re: readonly?

2012-07-11 Thread David Nadlinger

On Wednesday, 11 July 2012 at 06:34:29 UTC, Tobias Pankrath wrote:

This escapes a stack reference.


Ins't b supposed to be allocated on the heap?


The Bar instance is, but the pointer to it is not. Making _b a 
Rebindable instead of using a pointer (to what effectively is a 
pointer to the real object) should help.


David


Re: readonly?

2012-07-11 Thread Tobias Pankrath

On Wednesday, 11 July 2012 at 06:48:59 UTC, David Nadlinger wrote:
On Wednesday, 11 July 2012 at 06:34:29 UTC, Tobias Pankrath 
wrote:

This escapes a stack reference.


Ins't b supposed to be allocated on the heap?


The Bar instance is, but the pointer to it is not. Making _b a 
Rebindable instead of using a pointer (to what effectively is a 
pointer to the real object) should help.


David


Bar b = new Bar;
auto b2 = b; // type of b2 is Bar*

So does it meen, that a pointer of type Bar* does not point to 
the real object?

How do I get such a pointer then and which type does it have?



Re: readonly?

2012-07-11 Thread Jonathan M Davis
On Wednesday, July 11, 2012 09:00:26 Tobias Pankrath wrote:
 Bar b = new Bar;
 auto b2 = b; // type of b2 is Bar*
 
 So does it meen, that a pointer of type Bar* does not point to
 the real object?

It's a pointer to a reference, not to the object.

 How do I get such a pointer then and which type does it have?

I don't think that you can. It's a reference, not a pointer. And if you _can_ 
do it, I bet that it's not at all pretty. References are _not_ intended to be 
treated the same as pointers. They're similar, but they're fundamentally 
different. And instances of classes are intended to be referred to by 
references, _not_ be pointed to by pointers.

Rebindable is the correct solution to this readonly issue.

- Jonathan M Davis


Re: readonly?

2012-07-11 Thread David Nadlinger

On Wednesday, 11 July 2012 at 08:56:39 UTC, Artur Skawina wrote:

On 07/11/12 09:00, Tobias Pankrath wrote:

Bar b = new Bar;
auto b2 = b; // type of b2 is Bar*

So does it meen, that a pointer of type Bar* does not point to 
the real object?


Yeah, unfortunately.
Can anybody think of a reason to keep the current (broken) 
behavior?


Why would it be broken? Bar intrinsically is a reference type, so 
Bar* is a pointer to a reference.


David


Re: readonly?

2012-07-11 Thread Tobias Pankrath

On Wednesday, 11 July 2012 at 09:49:43 UTC, David Nadlinger wrote:

On Wednesday, 11 July 2012 at 08:56:39 UTC, Artur Skawina wrote:

On 07/11/12 09:00, Tobias Pankrath wrote:

Bar b = new Bar;
auto b2 = b; // type of b2 is Bar*

So does it meen, that a pointer of type Bar* does not point 
to the real object?


Yeah, unfortunately.
Can anybody think of a reason to keep the current (broken) 
behavior?


Why would it be broken? Bar intrinsically is a reference type, 
so Bar* is a pointer to a reference.


David


The languages conflates reference and instance type for classes. 
See here http://dpaste.dzfl.pl/a55ad2b6 . I wouldn't say this 
should change but it is a minor inconsistency I just stumbled on.





Re: readonly?

2012-07-11 Thread Artur Skawina
On 07/11/12 11:49, David Nadlinger wrote:
 On Wednesday, 11 July 2012 at 08:56:39 UTC, Artur Skawina wrote:
 On 07/11/12 09:00, Tobias Pankrath wrote:
 Bar b = new Bar;
 auto b2 = b; // type of b2 is Bar*

 So does it meen, that a pointer of type Bar* does not point to the real 
 object?

 Yeah, unfortunately.
 Can anybody think of a reason to keep the current (broken) behavior?
 
 Why would it be broken? Bar intrinsically is a reference type, so Bar* is a 
 pointer to a reference.

Because it doesn't let you have a real pointer to a class.

The obvious alternative would be:

   auto r = new Bar(); // reference
   Bar* p = r; // pointer to Bar; ref implicitly converts to pointer.
   auto pr = r;   // typeof(pr)==Bar** ; can't do better w/o ref types.

So, does the current scheme have any advantages?
(currently, the second example is illegal and the last 'r' expression results
 in 'Bar *')

artur


Re: readonly?

2012-07-11 Thread David Nadlinger

On Wednesday, 11 July 2012 at 10:00:33 UTC, Tobias Pankrath wrote:
The languages conflates reference and instance type for 
classes. See here http://dpaste.dzfl.pl/a55ad2b6 . I wouldn't 
say this should change but it is a minor inconsistency I just 
stumbled on.


This is not an inconsistency, but by design. Classes 
intrinsically are reference types, there isn't something like an 
»instance type« for them, which helps avoiding things like the 
slicing problem in C++. Yes, in D, types are always only either 
value types (structs) or polymorphic reference types (classes), 
but I fail to see anything inconsistent here.


David


Re: readonly?

2012-07-11 Thread David Nadlinger

On Wednesday, 11 July 2012 at 10:05:40 UTC, Artur Skawina wrote:

Because it doesn't let you have a real pointer to a class.


What is a »real pointer«? Class references are really just 
pointers, in a way – you can cast them to void*.



The obvious alternative would be:

   auto r = new Bar(); // reference
   Bar* p = r; // pointer to Bar; ref implicitly 
converts to pointer.
   auto pr = r;   // typeof(pr)==Bar** ; can't do better 
w/o ref types.


So, does the current scheme have any advantages?


When discussing a language change, the question should always be: 
Does the _new_ scheme have any advantages?


David


Re: readonly?

2012-07-11 Thread Ali Çehreli

On 07/11/2012 08:52 AM, David Nadlinger wrote:

 I fail to see anything inconsistent here.

Most other operations act on the object:

class B
{
// ...
}

auto b = new B();

++b;// on the object
b  b;  // on the object
// etc.
b; // on the reference

That can be seen as an inconsistency. Perhaps it is that the 
non-overridable operators are on the class reference?


Ali



Re: readonly?

2012-07-11 Thread Artur Skawina
On 07/11/12 17:54, David Nadlinger wrote:
 On Wednesday, 11 July 2012 at 10:05:40 UTC, Artur Skawina wrote:
 Because it doesn't let you have a real pointer to a class.
 
 What is a »real pointer«? Class references are really just pointers, in a way 
 – you can cast them to void*.

A real pointer is a pointer.
Class refs are basically pointers, but with some extra limitations and syntax
sugar. The key distinction is that you can implement references on top of
pointers, but the opposite isn't true. Hence refs are not real pointers.
Casting refs in order to extract their value /is/ possible, but that gets
ugly and dangerous (if not actually 'undefined'); the ClassPtr type that
i posted in this thread is a good example - it may be just ~6 lines of code,
but that's six line of code that everybody that's reading or using it must
analyze, before determining if it's correct and sane. (and, yes, it's not
perfect, eg it doesn't even try to handle immutable - simply because I had
no need for that so far)

 The obvious alternative would be:

auto r = new Bar(); // reference
Bar* p = r; // pointer to Bar; ref implicitly converts to pointer.
auto pr = r;   // typeof(pr)==Bar** ; can't do better w/o ref types.

 So, does the current scheme have any advantages?
 
 When discussing a language change, the question should always be: Does the 
 _new_ scheme have any advantages?

Yeah, except when the old scheme was an accident, which I have to assume is
the case here. Hence the questions, just in case the behavior was in fact
chosen deliberately and I'm missing something.

The advantages of having pointers to classes? Eg solving the problem that
triggered this thread w/o hacks like ClassPtr (Rebindable is an even worse
hack). [1]
Not to mention that the current model is extremely misleading; consider that
three different people got it wrong in this thread alone...

artur

[1] direct pointers, going via a ref obviously works, even if less efficient.
Which brings us back to the question - are there any advantages of /that/ 
scheme?


Re: readonly?

2012-07-11 Thread Jesse Phillips

On Tuesday, 10 July 2012 at 19:27:56 UTC, Namespace wrote:

Maybe D need's a readonly keyword.
[...]
Or has D an alternative?


https://github.com/D-Programming-Language/dmd/pull/3


Re: readonly?

2012-07-11 Thread Jonathan M Davis
On Wednesday, July 11, 2012 09:51:37 Ali Çehreli wrote:
 On 07/11/2012 08:52 AM, David Nadlinger wrote:
  I fail to see anything inconsistent here.
 
 Most other operations act on the object:
 
 class B
 {
 // ...
 }
 
 auto b = new B();
 
 ++b; // on the object
 b  b; // on the object
 // etc.
 b; // on the reference
 
 That can be seen as an inconsistency. Perhaps it is that the
 non-overridable operators are on the class reference?

It's the fact that in the type system B is a reference to the class named B, 
_not_ the class itself. ++b operates on the object itself, because it's not 
legal to increment a reference. Such an operation makes no sense. Almost all 
operations get forwarded to the object just like using . with a pointer gets 
forwarded to the pointee.

One of the few operations which makes sense on the reference itself is , 
since it gives you the address of the reference. On the other hand, it makes 
no sense to take the address of the object itself, since there is _no way_ in 
the type system to refer to that object, and the type system purposefully 
makes it so that you don't and can't mess with class objects directly, since 
it avoids problems such as object slicing.

So, while it may seem odd at first that  operates on the reference itself 
rather than the object, remember that the fact that a reference uses a pointer 
is an implementation detail which is _not_ represented in the type at all. 
Think of it like this:

struct S
{
 //opDispatch defined here and
 //all overloaded operators defined here to forward to *ptr...

private:
 C* ptr;
}

S s;

s would naturally refer to s, not ptr, and there's no way to access ptr 
directly. What engenders so much confusion is that in D's type system, S is 
referred to as C, so you essentially get

struct C
{
 ...

private:
 C* ptr;
}

C c;

where C refers to the struct everywhere except with ptr, which refers to the 
actual class object.

So, while some of the behaviors with regards to classes may seem odd at first, 
they're actually _very_ consistent with everything else.

- Jonathan M Davis


Re: readonly?

2012-07-11 Thread Jonathan M Davis
On Wednesday, July 11, 2012 23:09:17 Artur Skawina wrote:
 The advantages of having pointers to classes? Eg solving the problem that
 triggered this thread w/o hacks like ClassPtr (Rebindable is an even worse
 hack). [1]

You'd also lose polymorphism, which you don't with Rebindable. In D, 
references are polymorphic. Pointers are not. You really don't want to be 
using a pointer to a class. D was designed with the idea that classes would 
accessed through references, not pointers, and the related features are all 
designed around that.

- Jonathan M Davis


Re: readonly?

2012-07-11 Thread Jonathan M Davis
On Wednesday, July 11, 2012 10:56:23 Artur Skawina wrote:
 Can anybody think of a reason to keep the current (broken) behavior?

Easily.

Making Object* point to the object itself rather than the reference would be 
so broken that it's not even funny. I can understand why you would think that 
such a change should be made, but that's only because you haven't thought 
through all of the consequences of that. It's all wrapped up in the very 
reason why Rebindable is in the library rather than being built into the 
language.

For starters, if you have

class C {}
C c;

the type of c is C. C is a reference to the class named C. It does _not_ mean 
the same thing as the C in the class declaration at all. If it were a struct 
rather than a class, it would be equivalent to C* (save for the fact that a 
reference and a pointer aren't quite the same). So, _everywhere_ in the type 
system that you see C, it's really C*, _not_ C as in the class C. There is _no 
way_ in the type system to refer to the class itself. So, making C* be a 
pointer to the object rather than the reference isn't even representable in 
the type system. It's exactly the same in Java and C# with their classes. 
Walter tried to get around this to implement Rebindable in the language and 
gave up on it. It may be possible, but it's _ugly_ if it is.

There are all kinds of practical side effects for this. For instance, if you 
had

class D : C {}

C c;
C* cPtr = c;

and C* was a pointer to the class itself, then it would almost be like doing

C* c;
C* cPtr = c;

which makes no sense at all. It also introduces object slicing - as in the 
type of slicing that C++ has when you assign a derived object to a base class 
object which is on the stack. In C++,

D d;
C c = d;

results in the D portion of d being chopped off, potentially putting it in an 
invalid state, and almost certainly isn't what you wanted to do. D avoids this 
by requiring that polymorphic objects (classes) be on the heap. But if C* 
referred to the object itself, it becomes a probem again.

C c = new C;
C* cPtr = c;
*cPtr = new D;

Since cPtr was a pointer to the object, *cPtr would be the object itself, and 
so the D object would be assigned to the C object and get sliced, just like in 
the C++ example.

In additon, making Object* be a pointer to the object itself would make 
dealing with pointers to local objects _very_ inconsistent. Take this for 
example

void func(T)(T* t, T value)
{
 *t = value;
}

int i;
func(i, 7);

C c = getC();
func(c, new C);

When func is called with i, it sets i to 7. But when it's called with c, it 
doesn't set c. It sets what c refers to. This means that instead of changing 
the local variable c, you've changed an object on the heap which other 
references could refer to, and now instead of just affecting the local 
reference, _every_ reference is affected. This is _completely_ different from 
how it works with i. It's more in like with how it would work if you had

int* iPtr = getIntPtr();
func(iPtr, new int);

and since C is essentially equivalent to C*, it would then be impossible to 
pass the reference itself to func to be set.

It would also make it so that taking a pointer for a parameter was very 
different from taking ref or out for classes, when it's nearly identical for 
everything else.

void refFunc(T)(ref T t, T value)
{
 t = value;
}

int i;
refFunc(i, 7);

C c = getC();
refFunc(c, new C);

With your suggestion, this code operates identically for i but does something 
completely different for c. Now, instead of setting the object, it's setting 
the reference.

AAs would also be very broken if Object* pointed to the object rather than the 
reference. Take this code:

int[string] aa;
int* intPtr = hello in aa;

C[string] bb;
C* cPtr = hello in bb;

With aa, you get a pointer to the value which is at the key hello. With bb, 
you get a pointer to the object which the value at hello refers to. So, once 
again, setting *cPtr sets the object rather than the reference, and slicing 
becomes a problem. On top of that, what happens with null? Right now, you can 
do

bb[hello] = null;
C* v1 = hello in bb;
C* v2 = world in bb;

The fact that v1 is non-null tells you that hello is in bb, and the fact 
that v2 is null tells you that world isn't in bb. You can then dereference 
v1 and get at the value which is at hello, which is null. But what happens 
when C* nows points to the object rather than the reference? It becomes 
impossible to distinguish between the case when the key isn't in the AA and 
when the value at that key is null. You could fix that by making it so that

C[string] bb;

was implicitly

C*[string] bb;

but then the type that in returns would have to be C**, making it so that 
Objects behaved differently with AAs than every other type, since in all other 
cases with T[U], in returns T*, not T**.

I could go on, but this post is already ridiculously long. The point is that 
the type system is built around the fact that class variables 

readonly?

2012-07-10 Thread Namespace

Maybe D need's a readonly keyword.
Sometimes i have a class which can take an object from 
everywhere to store it. So it can not be const, because i didn't 
just initialized it with a ctor.
But i don't want to change the object, i only want to read or 
call const methods. What now?

I'd suggest a readonly keyword for that.

[code]
class Foo {
readonly:
Bar _b;

public:
void SetBar(readonly Bar b) {
_b = b;
}
}
[/code]

Or has D an alternative?


Re: readonly?

2012-07-10 Thread Simen Kjaeraas
On Tue, 10 Jul 2012 21:27:54 +0200, Namespace rswhi...@googlemail.com  
wrote:



Maybe D need's a readonly keyword.
Sometimes i have a class which can take an object from everywhere to  
store it. So it can not be const, because i didn't just initialized it  
with a ctor.
But i don't want to change the object, i only want to read or call const  
methods. What now?

I'd suggest a readonly keyword for that.

[code]
class Foo {
readonly:
 Bar _b;

public:
void SetBar(readonly Bar b) {
 _b = b;
}
}
[/code]

Or has D an alternative?


If Bar is a class, use std.typecons.Rebindable.

Otherwise, it's hairier. What should readonly mean?

From what I see, it provides const access, and is reassignable. This is  
easily implemented in user code today:


import std.traits;

struct Readonly( T ) {
private T payload;

this( Unqual!T value ) {
payload = value;
}

auto opAssign( const T value ) {
payload = cast()value;
return this;
}

@property
const(T) get( ) const {
return payload;
}

alias get this;
} unittest {
struct S {
int n;

void foo() {}
void bar() const {}
}

Readonly!S a;
a = S( 3 );
assert( a.n == 3 );
assert( !__traits( compiles, a.n = 4 ) );
assert( !__traits( compiles, a.foo() ) );
assert( __traits( compiles, a.bar() ) );
}


Re: readonly?

2012-07-10 Thread Tobias Pankrath

On Tuesday, 10 July 2012 at 19:27:56 UTC, Namespace wrote:

Maybe D need's a readonly keyword.
Sometimes i have a class which can take an object from 
everywhere to store it. So it can not be const, because i 
didn't just initialized it with a ctor.
But i don't want to change the object, i only want to read or 
call const methods. What now?

I'd suggest a readonly keyword for that.

[code]
class Foo {
readonly:
Bar _b;

public:
void SetBar(readonly Bar b) {
_b = b;
}
}
[/code]

Or has D an alternative?


const(T)* ?




Re: readonly?

2012-07-10 Thread Namespace

const(T)* ?


Example?


Re: readonly?

2012-07-10 Thread Ali Çehreli

On 07/10/2012 03:53 PM, Namespace wrote:

const(T)* ?


Example?


class Bar
{}

class Foo
{
const(Bar) * _b;

void SetBar(const(Bar) * b) {
_b = b;
}
}

void main()
{
auto b = new Bar();
auto f = new Foo();
f.SetBar(b);
}

Ali


Re: readonly?

2012-07-10 Thread Namespace

class Bar
{}

class Foo
{
const(Bar) * _b;

void SetBar(const(Bar) * b) {
_b = b;
}
}

void main()
{
auto b = new Bar();
auto f = new Foo();
f.SetBar(b);
}

Ali


Hmm... That's good. Thanks.


Re: readonly?

2012-07-10 Thread Timon Gehr

On 07/11/2012 12:58 AM, Ali Çehreli wrote:

On 07/10/2012 03:53 PM, Namespace wrote:

const(T)* ?


Example?


class Bar
{}

class Foo
{
 const(Bar) * _b;

 void SetBar(const(Bar) * b) {
 _b = b;
 }
}

void main()
{
 auto b = new Bar();
 auto f = new Foo();
 f.SetBar(b);
}

Ali


This escapes a stack reference.