Re: Is there a way to make a class variable visible but constant to outsiders, but changeable (mutable) to the class itself?

2016-05-25 Thread Steven Schveighoffer via Digitalmars-d-learn

On 5/24/16 6:47 PM, Jonathan M Davis via Digitalmars-d-learn wrote:

On Tuesday, May 24, 2016 18:28:44 Meta via Digitalmars-d-learn wrote:

On Tuesday, 24 May 2016 at 15:07:55 UTC, Jonathan M Davis wrote:

On Tuesday, May 24, 2016 10:10:16 Steven Schveighoffer via

Digitalmars-d-learn wrote:

A while ago, I discovered that this works.

class C {

 union
 {

private int _my_var;
public const int my_var;

 }
 void do_something() { _my_var = 4; }

}


Yeah. That's basically what Rebindable does, though in its
case, it's not really allowing you to mutate any data, just
what the reference refers to. Regardless, it does seem like a
hole in the type system.

- Jonathan M Davis


I don't believe so. H. S. Teoh recently fixed a definite bug when
you have something like:

struct S
{
  union
  {
  int n1;
  immutable int n2;
  }
}

But I'm pretty sure the case where n2 is const was purposely not
fixed as it doesn't break the type system. The value of a const
variable can be changed at any time out from under you, so a
union of a mutable and const int does not break any type system
guarantees.


Except that int is a _value_ type, not a reference type. So, unions aside,
once you've declared

const foo = 42;

it's impossible for the value of foo to change, and there's no real
difference between

const foo = 42;

and

immutable foo = 42;

typeof(foo) will give you const in one case and immutable in the other, but
effectively, they're identical.


But this isn't that. That's a declaration with an initializer.

There is a difference between:

struct S
{
   const foo = 42;
}

and

struct S
{
   const int foo;
}

-Steve


Re: Is there a way to make a class variable visible but constant to outsiders, but changeable (mutable) to the class itself?

2016-05-24 Thread Jonathan M Davis via Digitalmars-d-learn
On Tuesday, May 24, 2016 18:28:44 Meta via Digitalmars-d-learn wrote:
> On Tuesday, 24 May 2016 at 15:07:55 UTC, Jonathan M Davis wrote:
> > On Tuesday, May 24, 2016 10:10:16 Steven Schveighoffer via
> >
> > Digitalmars-d-learn wrote:
> >> A while ago, I discovered that this works.
> >>
> >> class C {
> >>
> >> union
> >> {
> >>
> >>private int _my_var;
> >>public const int my_var;
> >>
> >> }
> >> void do_something() { _my_var = 4; }
> >>
> >> }
> >
> > Yeah. That's basically what Rebindable does, though in its
> > case, it's not really allowing you to mutate any data, just
> > what the reference refers to. Regardless, it does seem like a
> > hole in the type system.
> >
> > - Jonathan M Davis
>
> I don't believe so. H. S. Teoh recently fixed a definite bug when
> you have something like:
>
> struct S
> {
>  union
>  {
>  int n1;
>  immutable int n2;
>  }
> }
>
> But I'm pretty sure the case where n2 is const was purposely not
> fixed as it doesn't break the type system. The value of a const
> variable can be changed at any time out from under you, so a
> union of a mutable and const int does not break any type system
> guarantees.

Except that int is a _value_ type, not a reference type. So, unions aside,
once you've declared

const foo = 42;

it's impossible for the value of foo to change, and there's no real
difference between

const foo = 42;

and

immutable foo = 42;

typeof(foo) will give you const in one case and immutable in the other, but
effectively, they're identical.

- Jonathan M Davis



Re: Is there a way to make a class variable visible but constant to outsiders, but changeable (mutable) to the class itself?

2016-05-24 Thread Meta via Digitalmars-d-learn

On Tuesday, 24 May 2016 at 15:07:55 UTC, Jonathan M Davis wrote:
On Tuesday, May 24, 2016 10:10:16 Steven Schveighoffer via 
Digitalmars-d-learn wrote:

A while ago, I discovered that this works.

class C {
union
{
   private int _my_var;
   public const int my_var;
}
void do_something() { _my_var = 4; }
}


Yeah. That's basically what Rebindable does, though in its 
case, it's not really allowing you to mutate any data, just 
what the reference refers to. Regardless, it does seem like a 
hole in the type system.


- Jonathan M Davis


I don't believe so. H. S. Teoh recently fixed a definite bug when 
you have something like:


struct S
{
union
{
int n1;
immutable int n2;
}
}

But I'm pretty sure the case where n2 is const was purposely not 
fixed as it doesn't break the type system. The value of a const 
variable can be changed at any time out from under you, so a 
union of a mutable and const int does not break any type system 
guarantees.


Re: Is there a way to make a class variable visible but constant to outsiders, but changeable (mutable) to the class itself?

2016-05-24 Thread Jonathan M Davis via Digitalmars-d-learn
On Tuesday, May 24, 2016 10:10:16 Steven Schveighoffer via Digitalmars-d-learn 
wrote:
> A while ago, I discovered that this works.
>
> class C {
> union
> {
>private int _my_var;
>public const int my_var;
> }
> void do_something() { _my_var = 4; }
> }

Yeah. That's basically what Rebindable does, though in its case, it's not
really allowing you to mutate any data, just what the reference refers to.
Regardless, it does seem like a hole in the type system.

- Jonathan M Davis



Re: Is there a way to make a class variable visible but constant to outsiders, but changeable (mutable) to the class itself?

2016-05-24 Thread Steven Schveighoffer via Digitalmars-d-learn

On 5/21/16 1:32 PM, dan wrote:

Is it possible to have a class which has a variable which can be seen
from the outside, but which can only be modified from the inside?

Something like:

class C {
   int my_var = 3; // semi_const??
   void do_something() { my_var = 4; }
}

And then in another file

auto c = new C();
c.my_var = 5; // <<<- should trigger a compile-time error
writeln("the value is ", c.my_var);  // <<<- should print 3
c.do_something();
writeln("the value is ", c.my_var);  // <<<- should print 4

Reading Alexandrescu's book suggests the answer is "no" (the only
relevant type qualifiers are private, package, protected, public, and
export, and none seem appropriate).

(This effect could be simulated by making my_var into a function, but i
don't want to do that.)

TIA for any info!


A while ago, I discovered that this works.

class C {
   union
   {
  private int _my_var;
  public const int my_var;
   }
   void do_something() { _my_var = 4; }
}

-Steve


Re: Is there a way to make a class variable visible but constant to outsiders, but changeable (mutable) to the class itself?

2016-05-23 Thread dan via Digitalmars-d-learn

On Monday, 23 May 2016 at 07:03:08 UTC, chmike wrote:

On Saturday, 21 May 2016 at 17:32:47 UTC, dan wrote:

(This effect could be simulated by making my_var into a 
function, but i don't want to do that.)


May I ask why you don't want to do that ?

In D you can call a function without args without ().

So if you write

private int my_var_ = 4; // where 4 is the default 
initialization value

@property int my_var1() { return my_var_; }
final int my_var2() { return my_var_; }
int my_var3() { return my_var_; }

int x = obj.my_var1;
x = obj.my_var2;
x = obj.my_var3;


my_var3 is virtual so I guess you get the overhead of a virtual 
method call which is probably not what you want.


my_var2 can't be overriden and if it doesn't itself override a 
method with a same name in a base class the compiler may 
optimize its call by inlining it. It's like a static method 
with 'this' passed as argument.


I'm not fully sure about my_var1. I'm still a beginner, but I 
think the compiler will optimize it into inlined instruction if 
it can as for my_var2.


Making the user accessing the member variables directly may 
look like it's more efficient, but it's bad API design because 
you can't change the class implementation affecting my_var_ 
without breaking the API. The D way enforces good programming 
and API design and optimizes as much as possible.


Thanks Ch Mike for your reply and explanation, and the
further information about calling functions.

Thanks also to the other Mike, to Daniel for the interesting
union technique, and to Meta for further elaboration.
Daniel's union technique is pretty close to what i was
asking for.

Now, since you explicitly ask me 'why you don't
want to do that', i should answer.  But my answer
won't be nearly as good as your analysis and
explanation, nor as good as any of the other replies.  :(

Just aesthetically, i'd like to refer to the
variable within the class and outside the class
with exactly the same symbol.

But with all the ideas presented in the prior
discussion, i can get pretty close so it would
be a ridiculous point for me to complain about.

Thanks again for your help!

dan


Re: Is there a way to make a class variable visible but constant to outsiders, but changeable (mutable) to the class itself?

2016-05-23 Thread chmike via Digitalmars-d-learn

On Saturday, 21 May 2016 at 17:32:47 UTC, dan wrote:

(This effect could be simulated by making my_var into a 
function, but i don't want to do that.)


May I ask why you don't want to do that ?

In D you can call a function without args without ().

So if you write

private int my_var_ = 4; // where 4 is the default initialization 
value

@property int my_var1() { return my_var_; }
final int my_var2() { return my_var_; }
int my_var3() { return my_var_; }

int x = obj.my_var1;
x = obj.my_var2;
x = obj.my_var3;


my_var3 is virtual so I guess you get the overhead of a virtual 
method call which is probably not what you want.


my_var2 can't be overriden and if it doesn't itself override a 
method with a same name in a base class the compiler may optimize 
its call by inlining it. It's like a static method with 'this' 
passed as argument.


I'm not fully sure about my_var1. I'm still a beginner, but I 
think the compiler will optimize it into inlined instruction if 
it can as for my_var2.


Making the user accessing the member variables directly may look 
like it's more efficient, but it's bad API design because you 
can't change the class implementation affecting my_var_ without 
breaking the API. The D way enforces good programming and API 
design and optimizes as much as possible.




Re: Is there a way to make a class variable visible but constant to outsiders, but changeable (mutable) to the class itself?

2016-05-22 Thread Mike Parker via Digitalmars-d-learn

On Sunday, 22 May 2016 at 19:29:59 UTC, Meta wrote:

Const *is* necessary to prevent _myVar being written to through 
code like:


f.myVar = 4;

Of course this isn't necessary for value types, but for 
reference types.





I was referring specifically to marking the function const, not 
the return type. Marking the return type const is highly 
context-dependent. It's perfectly reasonable to return a 
non-const class reference from a getter property. As long as the 
internal reference is private, it isn't going to be overwritten 
externally without a setter property. I don't see how it could be 
considered necessary. For a pointer, sure, to prevent 
*(bar.fooVer) = Foo(10). But for class references it's only 
necessary if you don't want the returned instances members to be 
modified.


It's also useful for value types, IMO, for preventing someone 
from doing this:


f.myVar = 4;

And wondering why the code has no effect.


The compiler already gives an error message describing the 
problem:


 Error: function mod.Foo.myVar () is not callable using argument 
types (int)


How does const help here?


Re: Is there a way to make a class variable visible but constant to outsiders, but changeable (mutable) to the class itself?

2016-05-22 Thread Daniel N via Digitalmars-d-learn

On Saturday, 21 May 2016 at 17:32:47 UTC, dan wrote:
Is it possible to have a class which has a variable which can 
be seen from the outside, but which can only be modified from 
the inside?


Something like:

class C {
  int my_var = 3; // semi_const??
  void do_something() { my_var = 4; }
}



Yes, I prefer this idiom:

class C
{
  union
  {
private  int  var_rw;
public const(int) var_ro;
  }
}



Re: Is there a way to make a class variable visible but constant to outsiders, but changeable (mutable) to the class itself?

2016-05-22 Thread Meta via Digitalmars-d-learn

On Sunday, 22 May 2016 at 03:06:44 UTC, Mike Parker wrote:

On Saturday, 21 May 2016 at 19:17:00 UTC, dan wrote:

Thanks Vit, Meta, and Yuxuan for your speedy help!

So 3 pieces to put together, function, const, and @property 
(and i guess final for protection against subclasses).


Minimally, there are two pieces to this: a private member 
variable and a function.


class Foo {
  private int _myVar;
  int myVar() { return _myVar; }
}

The private is necessary because class members in D are all 
public by default. If it isn't there, then _myVar can be 
directly modified outside of the module. Be aware, though (if 
you aren't already), that private members *are* accessible 
outside of the class in the same module, e.g.:


module foo;

class Foo {
  private int _myVar;
  int myVar() { return _myVar; }
}

void printMyVar() {
import std.stdio : writeln;
auto f = new Foo;
writeln(f);
}

As for 'const' and '@property', neither is strictly a 
requirement to implement this idiom. Adding const means that 
you can call the function through const references, but if 
that's not something you want to allow for some reason, then 
don't add it.


@property right now doesn't really do anything other than allow 
for self-documenting code. Perhaps one day it will be fully 
implemented and require callers to drop the parentheses in 
calls to @property functions, but for now it doesn't do that. 
Use it as much as you want, but just understand it isn't 
necessary for the functionality you are after.


Const *is* necessary to prevent _myVar being written to through 
code like:


f.myVar = 4;

Of course this isn't necessary for value types, but for reference 
types.


It's also useful for value types, IMO, for preventing someone 
from doing this:


f.myVar = 4;

And wondering why the code has no effect.


Re: Is there a way to make a class variable visible but constant to outsiders, but changeable (mutable) to the class itself?

2016-05-21 Thread Mike Parker via Digitalmars-d-learn

On Sunday, 22 May 2016 at 03:06:44 UTC, Mike Parker wrote:


As for 'const' and '@property', neither is strictly a 
requirement to implement this idiom. Adding const means that


Oh, and the same holds true for final, of course. It's probably 
what you want most of the time, but it isn't strictly necessary 
for the idiom.


Re: Is there a way to make a class variable visible but constant to outsiders, but changeable (mutable) to the class itself?

2016-05-21 Thread Mike Parker via Digitalmars-d-learn

On Saturday, 21 May 2016 at 19:17:00 UTC, dan wrote:

Thanks Vit, Meta, and Yuxuan for your speedy help!

So 3 pieces to put together, function, const, and @property 
(and i guess final for protection against subclasses).


Minimally, there are two pieces to this: a private member 
variable and a function.


class Foo {
  private int _myVar;
  int myVar() { return _myVar; }
}

The private is necessary because class members in D are all 
public by default. If it isn't there, then _myVar can be directly 
modified outside of the module. Be aware, though (if you aren't 
already), that private members *are* accessible outside of the 
class in the same module, e.g.:


module foo;

class Foo {
  private int _myVar;
  int myVar() { return _myVar; }
}

void printMyVar() {
import std.stdio : writeln;
auto f = new Foo;
writeln(f);
}

As for 'const' and '@property', neither is strictly a requirement 
to implement this idiom. Adding const means that you can call the 
function through const references, but if that's not something 
you want to allow for some reason, then don't add it.


@property right now doesn't really do anything other than allow 
for self-documenting code. Perhaps one day it will be fully 
implemented and require callers to drop the parentheses in calls 
to @property functions, but for now it doesn't do that. Use it as 
much as you want, but just understand it isn't necessary for the 
functionality you are after.


Re: Is there a way to make a class variable visible but constant to outsiders, but changeable (mutable) to the class itself?

2016-05-21 Thread dan via Digitalmars-d-learn

Thanks Vit, Meta, and Yuxuan for your speedy help!

So 3 pieces to put together, function, const, and @property (and 
i guess final for protection against subclasses).




Re: Is there a way to make a class variable visible but constant to outsiders, but changeable (mutable) to the class itself?

2016-05-21 Thread vit via Digitalmars-d-learn

On Saturday, 21 May 2016 at 17:32:47 UTC, dan wrote:
Is it possible to have a class which has a variable which can 
be seen from the outside, but which can only be modified from 
the inside?


Something like:

class C {
  int my_var = 3; // semi_const??
  void do_something() { my_var = 4; }
}

And then in another file

auto c = new C();
c.my_var = 5; // <<<- should trigger a compile-time error
writeln("the value is ", c.my_var);  // <<<- should print 3
c.do_something();
writeln("the value is ", c.my_var);  // <<<- should print 4

Reading Alexandrescu's book suggests the answer is "no" (the 
only relevant type qualifiers are private, package, protected, 
public, and export, and none seem appropriate).


(This effect could be simulated by making my_var into a 
function, but i don't want to do that.)


TIA for any info!

dan


class C {
private:
int my_var_ = 3; // semi_const

@property final void my_var(int x){ ///private setter
this.my_var_ = x;
}

public:
@property final int my_var()const{  ///public getter
return my_var_;
}

void do_something() {
my_var = 4;
}
}


Re: Is there a way to make a class variable visible but constant to outsiders, but changeable (mutable) to the class itself?

2016-05-21 Thread Meta via Digitalmars-d-learn

On Saturday, 21 May 2016 at 17:32:47 UTC, dan wrote:
Is it possible to have a class which has a variable which can 
be seen from the outside, but which can only be modified from 
the inside?


Something like:

class C {
  int my_var = 3; // semi_const??
  void do_something() { my_var = 4; }
}

And then in another file

auto c = new C();
c.my_var = 5; // <<<- should trigger a compile-time error
writeln("the value is ", c.my_var);  // <<<- should print 3
c.do_something();
writeln("the value is ", c.my_var);  // <<<- should print 4

Reading Alexandrescu's book suggests the answer is "no" (the 
only relevant type qualifiers are private, package, protected, 
public, and export, and none seem appropriate).


(This effect could be simulated by making my_var into a 
function, but i don't want to do that.)


TIA for any info!

dan


You can create a const accessor for the variable. Then you can 
have it be mutable internally but const externally.


Class C
{
int _my_var = 2;

void setMyVarTo3() { _my_var = 3; }

@property const(int) my_var() { return _my_var; }
}

auto c = new C();
writeln(c.my_var); //Prints 2
c.setMyVarTo3();
writeln(c.my_var); //Prints 3
c.my_var = 4; //Error, cannot modify const(int)


Re: Is there a way to make a class variable visible but constant to outsiders, but changeable (mutable) to the class itself?

2016-05-21 Thread Yuxuan Shui via Digitalmars-d-learn

On Saturday, 21 May 2016 at 17:32:47 UTC, dan wrote:
Is it possible to have a class which has a variable which can 
be seen from the outside, but which can only be modified from 
the inside?


Something like:

class C {
  int my_var = 3; // semi_const??
  void do_something() { my_var = 4; }
}

And then in another file

auto c = new C();
c.my_var = 5; // <<<- should trigger a compile-time error
writeln("the value is ", c.my_var);  // <<<- should print 3
c.do_something();
writeln("the value is ", c.my_var);  // <<<- should print 4

Reading Alexandrescu's book suggests the answer is "no" (the 
only relevant type qualifiers are private, package, protected, 
public, and export, and none seem appropriate).


(This effect could be simulated by making my_var into a 
function, but i don't want to do that.)


TIA for any info!

dan


class C {
   int my_var() { return _my_var; }
   int _my_var;
}


Is there a way to make a class variable visible but constant to outsiders, but changeable (mutable) to the class itself?

2016-05-21 Thread dan via Digitalmars-d-learn
Is it possible to have a class which has a variable which can be 
seen from the outside, but which can only be modified from the 
inside?


Something like:

class C {
  int my_var = 3; // semi_const??
  void do_something() { my_var = 4; }
}

And then in another file

auto c = new C();
c.my_var = 5; // <<<- should trigger a compile-time error
writeln("the value is ", c.my_var);  // <<<- should print 3
c.do_something();
writeln("the value is ", c.my_var);  // <<<- should print 4

Reading Alexandrescu's book suggests the answer is "no" (the only 
relevant type qualifiers are private, package, protected, public, 
and export, and none seem appropriate).


(This effect could be simulated by making my_var into a function, 
but i don't want to do that.)


TIA for any info!

dan