February 14, 2006
John Demme wrote:
> The ability to protect not a reference, but the memory a reference points to is a feature that (at least a few) people have been asking for for some time.  (Think: real constant arrays.)  Walter, this is something you've said is a 2.0 feature, yes?  Nick, this would satisfy your issue with a reference "in" parameter?
> 
> ~John Demme
> 
> Walter Bright wrote:
> 
>> "nick" <nick_member@pathlink.com> wrote in message news:dsqr3t$2seg$1@digitaldaemon.com...
>>> I think that if we changed the semantics of /in/ or provided some
>>> equivalent of
>>> a 'const type*', that would help.
>> I agree, but in investigating this it turned out to be quite a quagmire, so I abandoned it for now.
> 

Thanks, John. That pretty much solves my problems.
February 14, 2006
On 2006-02-13 21:40:30 -0800, "Walter Bright" <newshound@digitalmars.com> said:

> 
> "Matthew" <nowhere@noaddress.co.us> wrote in message news:dsri7o$j2i$1@digitaldaemon.com...
>> IIRC most, though not all, of Walter's objections have pertained to the physical subversion of logical constness, and how that may impact code generation and other compilery things I don't understand.
> 
> It's not just that. It's that there are many different definitions of const, each with its own advantages and problems. C++ uses two of them (confusingly conflated).
> 
> 1) is the reference const?
> 2) is what the reference refers to const?
> 3) does (2) apply recursively?
> 4) is it only const by that reference, i.e. can other references to the same data concurrently modify it?
> 5) is it ROMable?
> 6) is it initialize-once?
> 7) is it an error to subvert const'ness, or is it legal? (Since D has pointers, one can always find a way to subvert it, the question is is that defined behavior.)
> 8) is there a place for 'mutable' members of const objects?
> 9) how does aliasing (multiple references to the same data) fit into all this?
> 10) does C++ have it backwards - const should be the default, and non-const should be explicit?
> 11) what happens when a const reference is supplied to a non-const reference?
> 12) is there a way to do const that can take advantage of hardware support for read-only?
> 13) how can const fit in with the notion of COW?
> 14) how does this fit in with the notion of an atomic function (a function with no side effects)?
> 15) how to do this in an aesthetically pleasing way that has a slap-ones-head-of-course-thats-the-way-to-do-it obviousness about it that everyone missed before? <g>
> 
> I've asked a friend who's a languages expert about this, who views programming languages through the lense of academic rigor, and he unhelpfully suggested D do all variations <sigh>.
> 
> My views on the failings of C++ const are pretty well documented in these n.g.'s, so I shan't repeat them. Suffice to say whatever D gets won't look or behave like that, and D is better off with no const at all than the C++ const. (I might add, however, that D does have C++'s readonly notion of const, and that works well. Just not the type modifier version.)

What does const currently do?    I'm not familiar with read only memory attributes, but on MacOS X I did this:

char[] foo = "Hello";  and then idiotically tried to modify foo, the program segfaulted on me.   The fix was to do "Hello".dup

Can you make this happen at will to a portion of memory?  If so I propose this syntax:

const Type  Name = <initializer>;  //This would make the reference constant.
TypeDef Name = const new Type; //This would make the data itself constant (What's this good for?  Can't imagine a class which would let you readonly it.  The class would need to be written in such a way as to allow it to be a readonly class.)
const Type Name = const New Type;  //Both the reference and data are readonlyized

This is the behavior I would expect out of const.  Modifying a const variable would result in your program segfaulting due to an memory access error.

-S.

Let me fill out your questionnaire:

> 1) is the reference const?

See above

> 2) is what the reference refers to const?

See above

> 3) does (2) apply recursively?

No;  IE a char[] in a class that was defined as const would still be writable unless the class itself defined it as const.

> 4) is it only const by that reference, i.e. can other references to the same data concurrently modify it?

No.

> 5) is it ROMable?

Yes

> 6) is it initialize-once?

Yes

> 7) is it an error to subvert const'ness, or is it legal? (Since D has pointers, one can always find a way to subvert it, the question is is that defined behavior.)

Yes, see above

> 8) is there a place for 'mutable' members of const objects?

See above about making a readonly class.  I suspect it would be wise to add some kind of keyword saying this class can be a readonly class.  It might even make sense to only allow structures to be const'd (Aside from the references, I'm referring to the actual heap data.)

> 9) how does aliasing (multiple references to the same data) fit into all this?

*Shrug* The memory is ROMized. *BOOM*

> 10) does C++ have it backwards - const should be the default, and non-const should be explicit?

Nope, I don't want to have to declare the majority of what I use as mutable.

> 11) what happens when a const reference is supplied to a non-const reference?

That's not a problem, since the reference is what is constant.  We care that the const reference always point to the correct object, not that nothing else does.

> 12) is there a way to do const that can take advantage of hardware support for read-only?

Sure, if it exists.

> 13) how can const fit in with the notion of COW?

How does this relate?

> 14) how does this fit in with the notion of an atomic function (a function with no side effects)?

Huh?

> 15) how to do this in an aesthetically pleasing way that has a slap-ones-head-of-course-thats-the-way-to-do-it obviousness about it that everyone missed before? <g>

I like the syntax I proposed.

February 14, 2006
On 2006-02-12 21:26:48 -0800, nick <nick.atamas@gmail.com> said:

> S. Chancellor wrote:
>> On 2006-02-12 19:32:47 -0800, nick <nick.atamas@gmail.com> said:
>> 
>>> What's worse, I can use the function prototype:
>>> 
>>> void surprise(inout A a);
>>> 
>>> and the results will be exactly the same. That just seriously breaks all
>>> the high level language features that D puts in place. So I guess my
>>> question is: "Shouldn't there be a mechanism to deal with this?"
>> 
>> Language do not fix people.   Writing software is not subject
>> to malicious attacks by hackers.  People are not intentionally injecting
>> bad code into your software!  You do not need security features built
>> into the language.  If it were up to me I'd abolish the private and
>> protected keywords too!  They're rather stupid, their intent is to
>> "recommend" people not to use them.  Quite often, especially in .NET i
>> want to use a protected method and end up having to subclass the F*CKING
>> class to expose it to the rest of my program.
>> 
>> -S.
>> 
> 
> Now you're talking crazy talk. Throws declarations may be a bad idea - I
> agreed after having read up on it. I have yet to hear a good reason why
> the unsafe keyword or some other safeguard against dangerous pointer
> code is a bad idea.
> 
> I'm just going to quote Joel here:
> "Now, I freely admit that programming with pointers is not needed in 90%
> of the code written today, and in fact, it's downright dangerous in
> production code."
> 
> http://joelonsoftware.com/articles/ThePerilsofJavaSchools.html

I frankly do not care about Joel or what his opinion is.

> 
>> If you're working with people who are idiots, they're going to be idiots
>> regardless of a damn unsafe keyword, or a friggin' throws keyword, or
>> whatever!

> When will people finally realize that stupid an unexperienced aren't the
> same thing. Some individuals who write code are mathematicians,
> physicists, or electrical engineers by training. Programming languages
> aren't just for hardcore experts like Matthew or Walter. Most
> programmers are amateurs; you're not going to change that. Furthermore,
> humans are prone to error.

For your information I'm a physicist, and I have absolutely no problem with pointers.

> If you think that safeguards aren't for you, then maybe you should
> double-check the list of D features: in/out/inout, nested functions,
> typesafe variadic arguments, contract programming, guaranteed
> initialization, and others. Are you telling me that all those should be
> thrown out because they are just there to prevent mistakes?

Sure!  I end up getting annoyed when private interfaces have functions I need to use all the time.  I end up having to modify the library myself, or subclass the damn thing if it's protected.  It would be nice if I could just tell the compiler to shut the hell up and let me call the protected member instead.

The point of those keywords are to help keep people from doing things that were not intended, not to prevent them from doing it when it is intended.  And quite obviously people get too gung-ho about this and I end up having to modify the interface to the library to use a damn private method.  Nonsense.

Removing pointers from a systems programming language is just dumb. End  -   of    -    story.   Pointers are not something you accidently do. They are not like shoving the wrong type of variable into the wrong place in an arguments list (Which typedef protects from, and no implicit conversions) or calling an internal interface accidently (Which private/protected protect from.) or calling an int with a value out of range when the interface designer wanted a discreet subset (what enums protect against)   You already have to go out of your way to use pointers by using the little * symbol, that's your unsafe keyword for you right there.

-S.

February 14, 2006
On 2006-02-12 23:12:26 -0800, nick <nick.atamas@gmail.com> said:

> Andrew Fedoniouk wrote:
>>> I will skip the "pointers are unsafe" rigmarole.
>>> 
>>> Should D provide something analogous to the C# unsafe keyword?
>> 
>> 
>> If "safe" means "managed" and
>> "unsafe" means "unmanaged" then answer is no.
>> By definition as  D code is "unmanaged".
>> 
>> To implement realy "safe" mode (whatever it means) you need
>> at least VM creating safe sandbox for you.
>> 
>> Andrew.
> 
> I didn't say I had a solution, I just said I have a problem. The
> "unsafe" thing is just some syntax that looked pretty cool in C#.
> 
> If c-style pointers are left the way they are now, you might as well not
> have in/out/inout parameters. To save you from reading the rest of the
> thread, here is an example:
> 
> CODE:
> -----
> 
> import std.stdio;
> 
> class A
> {
> 	private int data[];
> 	
> 	public this()
> 	{
> 		data.length = 10;
> 	}
> 	
> 	public void printSelf()
> 	{
> 		writefln("Data: ", this.data);
> 	}
> }
> 
> void surprise(in A a)
> {
> 	byte *ap = cast(byte *)(a);
> 	ap[9] = 5;	
> }
> 
> int main()
> {
> 	A a = new A();
> 	a.printSelf();
> 	surprise(a);
> 	a.printSelf();
> 	return 0;
> }
> 
> 
> OUTPUT:
> -------
> 
> Data before surprise: [0,0,0,0,0,0,0,0,0,0]
> Data after surprise:
> [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4287008,0,2004,216,1245184,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8855552,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,8855680,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8855808,
<..SNIP..>
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]




Good 
> 
job!  You intentionally screwed up an a reference, and look at the trouble you had to go through to do it!  You had to first convert it to a pointer, and then set a byte of the object to something different intentionally!   I don't see how you think this can be done accidentally. It's not like "Oops, shit! I just cast that object to a pointer and randomly set a byte in it to something else!"   On the other hand many of the other security features D includes helps prevent "Oops" errors.

Welcome to a systems programming language.   If your co-workers are intentionally doing things like this, then I am very sorry for you.

-S.

February 14, 2006
In article <dssk1o$1gd0$2@digitaldaemon.com>, S. Chancellor says...
>
>On 2006-02-12 23:12:26 -0800, nick <nick.atamas@gmail.com> said:
>
>> Andrew Fedoniouk wrote:
>>>> I will skip the "pointers are unsafe" rigmarole.
>>>> 
>>>> Should D provide something analogous to the C# unsafe keyword?
>>> 
>>> 
>>> If "safe" means "managed" and
>>> "unsafe" means "unmanaged" then answer is no.
>>> By definition as  D code is "unmanaged".
>>> 
>>> To implement realy "safe" mode (whatever it means) you need at least VM creating safe sandbox for you.
>>> 
>>> Andrew.
>> 
>> I didn't say I had a solution, I just said I have a problem. The "unsafe" thing is just some syntax that looked pretty cool in C#.
>> 
>> If c-style pointers are left the way they are now, you might as well not have in/out/inout parameters. To save you from reading the rest of the thread, here is an example:
>> 
>> CODE:
>> -----
>> 
>> import std.stdio;
>> 
>> class A
>> {
>> 	private int data[];
>> 
>> 	public this()
>> 	{
>> 		data.length = 10;
>> 	}
>> 
>> 	public void printSelf()
>> 	{
>> 		writefln("Data: ", this.data);
>> 	}
>> }
>> 
>> void surprise(in A a)
>> {
>> 	byte *ap = cast(byte *)(a);
>> 	ap[9] = 5;
>> }
>> 
>> int main()
>> {
>> 	A a = new A();
>> 	a.printSelf();
>> 	surprise(a);
>> 	a.printSelf();
>> 	return 0;
>> }
>> 
>> 
>> OUTPUT:
>> -------
>> 
>> Data before surprise: [0,0,0,0,0,0,0,0,0,0]
>> Data after surprise:
>> [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4287008,0,2004,216,1245184,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8855552,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,8855680,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8855808, <..SNIP..> 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
>
>
>
>
>Good
>> 
>job!  You intentionally screwed up an a reference, and look at the trouble you had to go through to do it!  You had to first convert it to a pointer, and then set a byte of the object to something different intentionally!   I don't see how you think this can be done accidentally. It's not like "Oops, shit! I just cast that object to a pointer and randomly set a byte in it to something else!"   On the other hand many of the other security features D includes helps prevent "Oops" errors.
>
>Welcome to a systems programming language.   If your co-workers are intentionally doing things like this, then I am very sorry for you.
>
>-S.
>

Pointers are scary!


February 14, 2006
Yes, that's one possible design. I like the idea of being able to put *allocated* data into a readonly segment, but this may be difficult to achieve.


February 14, 2006
On 2006-02-14 11:03:04 -0800, "Walter Bright" <newshound@digitalmars.com> said:

> Yes, that's one possible design. I like the idea of being able to put *allocated* data into a readonly segment, but this may be difficult to achieve.

I'm not sure what you mean.

Also, but I forgot this part:

const StructType Foo;  <-- Foo's data would obviously be readonly also, (since structures don't have reference semantics by default)  so if any references were created they couldn't modify it's data either.

Where does this leave arrays that have psuedo reference semantics?

-S.

February 14, 2006
Walter Bright wrote:
> Yes, that's one possible design. I like the idea of being able to put *allocated* data into a readonly segment, but this may be difficult to achieve. 

This would be great if it's possible.  I assume one method would be to allocate from a write-protected memory page for this purpose, but this sounds a bit slow and not terribly portable.  Are there any other options?


Sean
February 16, 2006
Walter Bright wrote:
>  (I might add, however, that D does have C++'s readonly notion of const, and that works well. Just not the type modifier version.) 
> 

Yes, except that there is no way apply the readonly notion to the referenced data, only to the variable (self) value.

-- 
Bruno Medeiros - CS/E student
"Certain aspects of D are a pathway to many abilities some consider to be... unnatural."
February 21, 2006
> Pointers are scary! 

I've heard this for decades, and I still don't really understand it.
I've never found pointers to be worse than uninitialised variables.
(in fact, I think many problems attributed to pointers are actually caused by uninitialised variables).

And the absolute worst is languages that don't require you to declare a variable before you use it. That's _really_ scary.