Re: Interested in D, spec confuses me.

2016-02-04 Thread Era Scarecrow via Digitalmars-d

On Thursday, 4 February 2016 at 06:34:15 UTC, Kagamin wrote:

On Wednesday, 3 February 2016 at 20:30:01 UTC, Bambi wrote:
I'm pretty sure casting away a const pointer to a const value 
is undefined behaviour.


const data in C can be immutable, but also can be mutable and 
change over time, that's why immutable optimizations are 
illegal on it: you can't tell if it's immutable, the const 
qualifier tells nothing about that, it only helps the callee to 
not modify the data.


I tend to take away the meanings in D:

 Immutable: This data Cannot/Will not change
 Const: I promise not to change your data on you (but the owner 
might make changes to it at some point)


 So converting a const pointer to a const value... it still 
remains const (and it's value doesn't/won't change if const is 
honored). You could throw away the constness; This assumes that 
it doesn't have referenced data/pointers and you're editing only 
a local copy (or duplicated it first); But that's it's own thing 
to discuss.


Re: Interested in D, spec confuses me.

2016-02-03 Thread Kagamin via Digitalmars-d

On Tuesday, 2 February 2016 at 14:36:05 UTC, Bambi wrote:

1. const isn't constant


The idea was to ease porting C code to D, so many things work the 
same in C and D except for maybe integer types that were borrowed 
from java.


The example snippet ' immutable(int[]) bar() immutable {} ' 
brings back bad memories of redundant declarations of the style 
' Object object = new Object(); '.


Redundancy is not all that bad, but if you want less of it, you 
can: `auto bar() immutable {}` - the compiler will infer the 
return type.



2. when is an extern an extern?
 The wiki page on interfacing with C states that C globals 
require an extra extern.


extern attribute is optimized for binding extern functions, which 
is what you need most of the time. In C you would need two 
attributes `extern cdecl` - one for extern and one for calling 
convention, in D it's done with one attribute, though it only 
specifies calling convention, because everything is implicitly 
extern anyway. It works well for functions, but not for 
variables, when you can't differentiate between declaration and 
definition.



3. typeof is an operator, sizeof is a property


sizeof is a property because it can work that way, and making it 
a whole special syntactical construct for this single purpose 
would be overkill. Now it can be implemented as a template, but 
it wasn't always this way.


Re: Interested in D, spec confuses me.

2016-02-03 Thread Bambi via Digitalmars-d

On Tuesday, 2 February 2016 at 23:41:07 UTC, H. S. Teoh wrote:
You're misunderstanding D's type system.  Immutable is not a 
"better const", as though const is somehow defective.  Perhaps 
the following diagram may help to clear things up:


const
   / \
(mutable)   immutable

What this means is that both mutable and immutable are 
implicitly convertible to const. Or, to put it another way, 
const is a kind of "wildcard" that can point to underlying data 
that's either mutable or immutable.


Mutable data is, well, mutable -- anybody who can get to it, 
can modify it. Immutable means *nobody* can modify it once it's 
initialized.


Why const, then?  Const is useful for when a function doesn't 
care whether the underlying data is mutable or not, because it 
doesn't need to change the data. Const provides guarantees to 
the caller that the function won't touch the data -- even if 
the data is actually mutable in the caller's context.  It's a 
"no-mutation view" on data that's possibly mutable by a third 
party.


Furthermore, since const provides actual guarantees that the 
called function isn't going to touch the data, this opens up 
optimization opportunities for the compiler. E.g., it can 
assume that any part(s) of the data that are held in registers 
will remain valid after the function call (provided said 
registers aren't touched by the function), so it doesn't need 
to issue another load after the function returns. As a 
contrived example, say you have code like this:


struct Data { int x; }
int func1(Data* d) { ... }
int func2(const(Data)* d) { ... }
...
void main() {
Data d;
int value1 = d.x*func1() + d.x;
int value2 = d.x*func2() + d.x;
d.x++;
}

When evaluating value1, the compiler may have issued a load for 
the first occurrence of d.x, then it calls func1. But since 
func1 may modify d.x, the second d.x needs another load in 
order to ensure the correct value is used.


When evaluating value2, however, since func2 takes a const 
pointer to the Data, the compiler knows the value of d.x cannot 
possibly change across that function call, so it can safely 
reuse the value of d.x that was previously loaded.  It may also 
go further and refactor the expression as d.x*(func2() + 1), 
because the const guarantees that func2 can't mutate d.x behind 
our backs and invalidate the result. Such a refactoring is 
invalid with func1, because there is no guarantee that d.x will 
have the same value after func1 returns.


Now, the same argument applies if immutable was used in place 
of const. However, the last line in main() illustrates why we 
need const rather than immutable in this case: we actually 
*want* to modify d.x in main(). We just don't want func2 to 
touch anything. So we can't use immutable -- since immutable 
means *nobody* can touch the data. So, const provides both the 
guarantee that func2 won't touch the data, thus allowing the 
aforementioned optimization, and also continues to let main() 
mutate the data at its leisure.



T


In C90+, const can apply to both values and pointers to those 
values. And since pointers are themselves values of a memory 
address that is consistent usage. That seems to be the only 
meaningful distinction here. Pointing to a const value makes the 
pointer mutable but the value immutable. Pointing a const to a 
value makes the pointer immutable but the value mutable. etc.


Immutable accomplishes nothing distinct here that I can see, 
other than making the use of const confusing. To make a function 
not change a value you declare a const input. Because it is the 
value declared in the function definition that is a const, not 
the value you pass it. "Passing as const" doesn't make any 
logical sense. To be honest, it smells like the kind of opaque 
cleverness D is ostensibly supposed to obviate.


Re: Interested in D, spec confuses me.

2016-02-03 Thread Kagamin via Digitalmars-d

On Wednesday, 3 February 2016 at 00:43:36 UTC, Dicebot wrote:
The fact DMD doesn't do anything scary right now when you do it 
is a mere coincidence and may change in any release with no 
notice.


DMD performs some immutable optimizations and people noticed it.


Re: Interested in D, spec confuses me.

2016-02-03 Thread Bambi via Digitalmars-d

On Wednesday, 3 February 2016 at 12:12:03 UTC, Kagamin wrote:
Immutability provides stronger guarantee that allows more 
optimizations, e.g. reading the same immutable value is known 
to result in the same value so such repeated reading can be 
optimized out, in C such optimization is illegal, because const 
data can change over time.


In C, you can only make pointers to const data a const pointer. 
The guarantee is built in there. Sure you can cast the address of 
a const to a regular pointer but then you are kind of going out 
of your way to break the rules and deliberately shoot yourself in 
the foot. I'm pretty sure casting away a const pointer to a const 
value is undefined behaviour.


Re: Interested in D, spec confuses me.

2016-02-03 Thread Steven Schveighoffer via Digitalmars-d

On 2/2/16 8:42 PM, Chris Wright wrote:

On Tue, 02 Feb 2016 15:41:07 -0800, H. S. Teoh via Digitalmars-d wrote:


Furthermore, since const provides actual guarantees that the called
function isn't going to touch the data, this opens up optimization
opportunities for the compiler.


const opens up optimizations at the call site, so it's useful. immutable
is useful on top of const because it allows optimizations within the
function.

Want to memoize a function? If it takes const(char[]), you have to copy
your input and later check the entire array to see if the parameters
match a previous call. If it takes an immutable(char[]), you can compare
pointers.


This isn't exactly right. If I call a function with "hello", I'd want it 
to memoize if the function is called with "hello" that resides elsewhere.


What *is* true is that you can safely save the array (pointer + len) of 
"hello" and be sure it won't change when you check against it later. 
With const(char[]), you'd need to allocate a new block to make sure it 
doesn't change.


-Steve


Re: Interested in D, spec confuses me.

2016-02-03 Thread Kagamin via Digitalmars-d
Another nice property of immutable data is that it can be safely 
shared between threads: const data that is a readonly view into 
changing mutable data may require locking to get consistent view 
of data; immutable data doesn't require locking, since it doesn't 
change.


Re: Interested in D, spec confuses me.

2016-02-03 Thread Kagamin via Digitalmars-d

On Wednesday, 3 February 2016 at 20:30:01 UTC, Bambi wrote:
I'm pretty sure casting away a const pointer to a const value 
is undefined behaviour.


const data in C can be immutable, but also can be mutable and 
change over time, that's why immutable optimizations are illegal 
on it: you can't tell if it's immutable, the const qualifier 
tells nothing about that, it only helps the callee to not modify 
the data.


Re: Interested in D, spec confuses me.

2016-02-03 Thread Kagamin via Digitalmars-d

On Wednesday, 3 February 2016 at 11:38:06 UTC, Bambi wrote:
Immutable accomplishes nothing distinct here that I can see, 
other than making the use of const confusing. To make a 
function not change a value you declare a const input.


Immutablity provides stronger guarantee that allows more 
optimizations, e.g. reading the same immutable value is known to 
result in the same value so such repeated reading can be 
optimized out, in C such optimization is illegal, because const 
data can change over time.


Re: Interested in D, spec confuses me.

2016-02-03 Thread Chris Wright via Digitalmars-d
On Wed, 03 Feb 2016 09:29:30 -0500, Steven Schveighoffer wrote:

> On 2/2/16 8:42 PM, Chris Wright wrote:
>> On Tue, 02 Feb 2016 15:41:07 -0800, H. S. Teoh via Digitalmars-d wrote:
>>
>>> Furthermore, since const provides actual guarantees that the called
>>> function isn't going to touch the data, this opens up optimization
>>> opportunities for the compiler.
>>
>> const opens up optimizations at the call site, so it's useful.
>> immutable is useful on top of const because it allows optimizations
>> within the function.
>>
>> Want to memoize a function? If it takes const(char[]), you have to copy
>> your input and later check the entire array to see if the parameters
>> match a previous call. If it takes an immutable(char[]), you can
>> compare pointers.
> 
> This isn't exactly right. If I call a function with "hello", I'd want it
> to memoize if the function is called with "hello" that resides
> elsewhere.

In the general case, yes.

It's much faster to look up a pointer/length pair in a hashtable than to 
look up a very long string, so if you expect long strings and many calls 
with the same addresses, you might have a fast cache by pointer.

You might also have values that are automatically generated, and you're 
relatively certain that it will be rare to have duplicate values.

Or you might have a complex data structure that's immutable and has an id 
and a revision. If you know for certain that id+revision is unique, you 
can memoize based on that, and immutable gives you some extra protection.


Re: Interested in D, spec confuses me.

2016-02-02 Thread anonymous via Digitalmars-d

On 02.02.2016 20:50, Bambi wrote:

Making the return value immutable is a very different thing from making
every value of the object immutable to the method alone.


Sure it's a different thing, but the meaning of "immutable" is the same.

By the way, it's not that the object's fields are made immutable for the 
method, but the method can only be called on immutable objects.



These are
different meanings. It reads like a redundancy but has different
meanings. This isn't good in my eyes.


I don't see how it reads like a redundancy. Surely, you don't expect a 
redundancy in this:


void f(immutable int[] a, immutable int[] b);

The other signature is no different. Two occurrences of "immutable", 
applying to two different things.


I agree that it can be unclear to newbies what exactly is immutable when 
a method is marked immutable, but the meaning of the keyword is the same 
as elsewhere. Using another word there would be more confusing.


Re: Interested in D, spec confuses me.

2016-02-02 Thread Steven Schveighoffer via Digitalmars-d

On 2/2/16 2:50 PM, Bambi wrote:

On Tuesday, 2 February 2016 at 15:48:02 UTC, anonymous wrote:

"immutable" is not a homonym here. It means the same thing ("cannot
ever change"). And it's not redundant either, as the two instances
apply to different targets. It's clear what the first "immutable" ties
to: It qualifies the return type. The second one is less clear: It
qualifies the type of the object, meaning the method can only be
called on an immutable object.

Leaving either of them out changes the meaning of the signature:
`int[] bar() immutable {}` - Return type is mutable now.
`immutable(int[]) bar() {}` - Object type is mutable now. I.e., this
method can be called on a mutable object, and it cannot be called on
an immutable object.


Making the return value immutable is a very different thing from making
every value of the object immutable to the method alone. These are
different meanings. It reads like a redundancy but has different
meanings. This isn't good in my eyes.


Technically, it doesn't *make* it immutable, it is just an overload that 
accepts an immutable object. I like to think of a method like this:


immutable(int)[] bar() immutable

as a function that looks like this:

immutable(int)[] bar(immutable(Object) this)

If you tried to call this method on a mutable object, and there wasn't a 
mutable overload (i.e. without an attribute), the call would fail.




Also it's not so much an issue of clarification - well, the extern one
is, I genuinely didn't understand what the documentation meant - but it
is an issue of the design choices not making much sense to me. These
just stand out to me as unnecessarily confusing and obscure in an
otherwise nice and clear language.


A lot of things in D come from C++. This is how C++ specifies const methods.

The purpose is to be familiar to C++ developers, and to make porting easier.

This means it can look confusing as not all C/C++ decisions were the 
best. However, this one I happen to like -- I can't think of a better way.


-Steve


Re: Interested in D, spec confuses me.

2016-02-02 Thread Bambi via Digitalmars-d

On Tuesday, 2 February 2016 at 15:48:02 UTC, anonymous wrote:
"immutable" is not a homonym here. It means the same thing 
("cannot ever change"). And it's not redundant either, as the 
two instances apply to different targets. It's clear what the 
first "immutable" ties to: It qualifies the return type. The 
second one is less clear: It qualifies the type of the object, 
meaning the method can only be called on an immutable object.


Leaving either of them out changes the meaning of the signature:
`int[] bar() immutable {}` - Return type is mutable now.
`immutable(int[]) bar() {}` - Object type is mutable now. I.e., 
this method can be called on a mutable object, and it cannot be 
called on an immutable object.


Making the return value immutable is a very different thing from 
making every value of the object immutable to the method alone. 
These are different meanings. It reads like a redundancy but has 
different meanings. This isn't good in my eyes.


Also it's not so much an issue of clarification - well, the 
extern one is, I genuinely didn't understand what the 
documentation meant - but it is an issue of the design choices 
not making much sense to me. These just stand out to me as 
unnecessarily confusing and obscure in an otherwise nice and 
clear language.


Re: Interested in D, spec confuses me.

2016-02-02 Thread H. S. Teoh via Digitalmars-d
On Tue, Feb 02, 2016 at 07:50:57PM +, Bambi via Digitalmars-d wrote:
> On Tuesday, 2 February 2016 at 15:48:02 UTC, anonymous wrote:
> >"immutable" is not a homonym here. It means the same thing ("cannot
> >ever change"). And it's not redundant either, as the two instances
> >apply to different targets. It's clear what the first "immutable"
> >ties to: It qualifies the return type. The second one is less clear:
> >It qualifies the type of the object, meaning the method can only be
> >called on an immutable object.
> >
> >Leaving either of them out changes the meaning of the signature:
> >`int[] bar() immutable {}` - Return type is mutable now.
> >`immutable(int[]) bar() {}` - Object type is mutable now. I.e., this
> >method can be called on a mutable object, and it cannot be called on
> >an immutable object.
> 
> Making the return value immutable is a very different thing from
> making every value of the object immutable to the method alone. These
> are different meanings. It reads like a redundancy but has different
> meanings. This isn't good in my eyes.
[...]

It's an unfortunate historical accident that function attributes can
easily be conflated with return type attributes. Different people have
pushed for prohibiting (apparently) ambiguous cases, but so far Walter
has been resistant to the idea. Because of this, my own recommendation
is to always use parenthesis when writing type qualifiers, and always
write function attributes on the right rather than on the left:

struct S {
// Do write:
immutable(int) func() { ... }
int func() immutable { ... }
immutable(int) func() immutable { ... }

// Don't write:
immutable int func() { ... }
immutable immutable int func() { ... } // may not compile
}

I'd even recommend using parenthesis in variable declarations, just for
consistency's sake:

// Do write:
immutable(int) x;

// Don't write:
immutable int x;

Even though the two are identical, I think it's better to always write
parentheses so that you get into the habit of thinking of the type in
terms of parentheses, and don't get confused when you encounter
ambiguous cases (or at least you'll be on the alert when parentheses are
absent, and be sure read the function signature more carefully).


T

-- 
Debian GNU/Linux: Cray on your desktop.


Re: Interested in D, spec confuses me.

2016-02-02 Thread IceCreamEater via Digitalmars-d

On Tuesday, 2 February 2016 at 20:17:20 UTC, H. S. Teoh wrote:
On Tue, Feb 02, 2016 at 09:13:41PM +0100, anonymous via 
Digitalmars-d wrote: [...]
The other signature is no different. Two occurrences of 
"immutable", applying to two different things.


I agree that it can be unclear to newbies what exactly is 
immutable when a method is marked immutable, but the meaning 
of the keyword is the same as elsewhere. Using another word 
there would be more confusing.


Another way to think about it, is that the "immutable" on the 
function means that the implicit `this` reference to the object 
is immutable.



T


I thought immutable was added to the language as a better 
guarantee to 'const'. Which really tells me const wasn't cutting 
it and wasn't a proper guarantee.


Re: Interested in D, spec confuses me.

2016-02-02 Thread Chris Wright via Digitalmars-d
On Tue, 02 Feb 2016 21:35:13 +, IceCreamEater wrote:

> On Tuesday, 2 February 2016 at 20:17:20 UTC, H. S. Teoh wrote:
>> On Tue, Feb 02, 2016 at 09:13:41PM +0100, anonymous via Digitalmars-d
>> wrote: [...]
>>> The other signature is no different. Two occurrences of "immutable",
>>> applying to two different things.
>>> 
>>> I agree that it can be unclear to newbies what exactly is immutable
>>> when a method is marked immutable, but the meaning of the keyword is
>>> the same as elsewhere. Using another word there would be more
>>> confusing.
>>
>> Another way to think about it, is that the "immutable" on the function
>> means that the implicit `this` reference to the object is immutable.
>>
>>
>> T
> 
> I thought immutable was added to the language as a better guarantee to
> 'const'. Which really tells me const wasn't cutting it and wasn't a
> proper guarantee.

D1 const (and up to about D2.007) was, if I recall, strictly for compile-
time constants.

When designing immutable, Bartosz and Walter realized that many functions 
don't care whether their parameters are mutable by anyone or not. For 
instance, the 'find' function in std.array -- it's not mutating the 
array, but it should be usable on mutable arrays.

So we got const, where all values implicitly cast to const. Functions 
promise not to modify anything marked const, so it's always safe to 
submit immutable values. They don't get access to potential optimizations 
available with immutable objects, which means they're safe for mutable 
values.


Re: Interested in D, spec confuses me.

2016-02-02 Thread Jacob Carlborg via Digitalmars-d

On 2016-02-02 17:41, jmh530 wrote:


Sure, but - as this post illustrates - there are clearly sections of the
spec that could have their explanations improved.


I think the spec on "extern" [1][2] is pretty clear. I think the 
explanation of "const" and "immutable" [3] is clear as well. All of the 
sections have examples as well.


[1] http://dlang.org/spec/declaration.html#extern
[2] http://dlang.org/spec/attribute.html#linkage
[3] http://dlang.org/spec/const3.html

--
/Jacob Carlborg


Re: Interested in D, spec confuses me.

2016-02-02 Thread H. S. Teoh via Digitalmars-d
On Tue, Feb 02, 2016 at 09:35:13PM +, IceCreamEater via Digitalmars-d wrote:
> On Tuesday, 2 February 2016 at 20:17:20 UTC, H. S. Teoh wrote:
> >On Tue, Feb 02, 2016 at 09:13:41PM +0100, anonymous via Digitalmars-d
> >wrote: [...]
> >>The other signature is no different. Two occurrences of "immutable",
> >>applying to two different things.
> >>
> >>I agree that it can be unclear to newbies what exactly is immutable
> >>when a method is marked immutable, but the meaning of the keyword is
> >>the same as elsewhere. Using another word there would be more
> >>confusing.
> >
> >Another way to think about it, is that the "immutable" on the
> >function means that the implicit `this` reference to the object is
> >immutable.
> >
> >
> >T
> 
> I thought immutable was added to the language as a better guarantee to
> 'const'. Which really tells me const wasn't cutting it and wasn't a
> proper guarantee.

You're misunderstanding D's type system.  Immutable is not a "better
const", as though const is somehow defective.  Perhaps the following
diagram may help to clear things up:

const
   / \
(mutable)   immutable

What this means is that both mutable and immutable are implicitly
convertible to const. Or, to put it another way, const is a kind of
"wildcard" that can point to underlying data that's either mutable or
immutable.

Mutable data is, well, mutable -- anybody who can get to it, can modify
it. Immutable means *nobody* can modify it once it's initialized.

Why const, then?  Const is useful for when a function doesn't care
whether the underlying data is mutable or not, because it doesn't need
to change the data. Const provides guarantees to the caller that the
function won't touch the data -- even if the data is actually mutable in
the caller's context.  It's a "no-mutation view" on data that's possibly
mutable by a third party.

Furthermore, since const provides actual guarantees that the called
function isn't going to touch the data, this opens up optimization
opportunities for the compiler. E.g., it can assume that any part(s) of
the data that are held in registers will remain valid after the function
call (provided said registers aren't touched by the function), so it
doesn't need to issue another load after the function returns. As a
contrived example, say you have code like this:

struct Data { int x; }
int func1(Data* d) { ... }
int func2(const(Data)* d) { ... }
...
void main() {
Data d;
int value1 = d.x*func1() + d.x;
int value2 = d.x*func2() + d.x;
d.x++;
}

When evaluating value1, the compiler may have issued a load for the
first occurrence of d.x, then it calls func1. But since func1 may modify
d.x, the second d.x needs another load in order to ensure the correct
value is used.

When evaluating value2, however, since func2 takes a const pointer to
the Data, the compiler knows the value of d.x cannot possibly change
across that function call, so it can safely reuse the value of d.x that
was previously loaded.  It may also go further and refactor the
expression as d.x*(func2() + 1), because the const guarantees that
func2 can't mutate d.x behind our backs and invalidate the result. Such
a refactoring is invalid with func1, because there is no guarantee that
d.x will have the same value after func1 returns.

Now, the same argument applies if immutable was used in place of const.
However, the last line in main() illustrates why we need const rather
than immutable in this case: we actually *want* to modify d.x in main().
We just don't want func2 to touch anything. So we can't use immutable --
since immutable means *nobody* can touch the data. So, const provides
both the guarantee that func2 won't touch the data, thus allowing the
aforementioned optimization, and also continues to let main() mutate the
data at its leisure.

As an added benefit, you can also call func2 with immutable Data: you
know it's safe, because even though func2 doesn't require immutability,
it also guarantees that it won't touch the data. So you don't need to
write two copies of func2, one to work with mutable data and one to work
with immutable data. This is why both mutable and immutable can
implicitly cast to const.


T

-- 
He who does not appreciate the beauty of language is not worthy to bemoan its 
flaws.


Re: Interested in D, spec confuses me.

2016-02-02 Thread bubbasaur via Digitalmars-d

On Wednesday, 3 February 2016 at 00:43:36 UTC, Dicebot wrote:
Casting immutable and violating it is undefined behavior and 
once you do it all bets are off - compiler is even allowed to 
attempt formatting your hard drive when compiling this program 
:)


The fact DMD doesn't do anything scary right now when you do it 
is a mere coincidence and may change in any release with no 
notice.


Well if anything bad happen it will mess with dpaste. :)

By the way, now you and Ali are saying this isn't correct, so I 
took a look on this page: http://dlang.org/spec/const3.html


And looking on the bottom: "Implicit Conversions" - I wonder, is 
this page missing something or what? Look what I'm seeing right 
now:


http://i.imgur.com/L4a6bx6.png

It shouldn't be some circles or crosses showing the conversion on 
that table?


Bubba.



Re: Interested in D, spec confuses me.

2016-02-02 Thread Ali Çehreli via Digitalmars-d

On 02/02/2016 04:31 PM, bubbasaur wrote:

> Ok, but what would differ using immutable instead of const in your
> example (AS ARGUMENTS)?
>
> See:
>
> import std.stdio;
>
>  struct Data { int x; }
>  auto func1(Data* d) { return d.x; }
>  auto func2(const(Data)* d) { return d.x; }

I cannot trust that a member of 'd' will not be modified later on. So, I 
cannot store 'd' as is. If I want to make use of its current state 
later, I must make a copy of it (which may have its own 
member-with-inderection issues).


In short, the promise of "I will not change members of 'd'" is not 
related to what can happen to that date by other parts of the code.


>  auto func3(immutable(Data)* d) { return d.x; }

There, I know that 'd' will not change state. I can store it somewhere 
for later use; no need to copy. I can even pass it to a thread without 
needing a lock.


>  auto value2 = d.x*func2() + d.x;
>  auto value3 = d.x*func3(cast(immutable)) + d.x;

That's not very nice because we've just fooled func3(). :) Although it 
required immutable data, we've given it mutable data. The programmer is 
on his or her own at that point. We hope the program will work correctly. :)


> Functions 2 and 3 are acting in the same way

I like this explanation:

- A const parameter is a promise by the callee to not modify

- An immutable parameter is a requirement for the caller to never modify

Ali



Re: Interested in D, spec confuses me.

2016-02-02 Thread bubbasaur via Digitalmars-d

On Wednesday, 3 February 2016 at 00:41:31 UTC, Ali Çehreli wrote:

I like this explanation:

- A const parameter is a promise by the callee to not modify

- An immutable parameter is a requirement for the caller to 
never modify


Well this explanation on the matter was simple, solid and 
comprehensive enough.


Bubba.


Re: Interested in D, spec confuses me.

2016-02-02 Thread Ali Çehreli via Digitalmars-d

On 02/02/2016 04:56 PM, bubbasaur wrote:

I took a
look on this page: http://dlang.org/spec/const3.html


That table has a bunch of check marks, which happens to be a Unicode 
character: ✔.


It looks like a font issue. Perhaps we should update that page and use a 
more available character like 'x'. :p


Ali



Re: Interested in D, spec confuses me.

2016-02-02 Thread Chris Wright via Digitalmars-d
On Tue, 02 Feb 2016 15:41:07 -0800, H. S. Teoh via Digitalmars-d wrote:

> Furthermore, since const provides actual guarantees that the called
> function isn't going to touch the data, this opens up optimization
> opportunities for the compiler.

const opens up optimizations at the call site, so it's useful. immutable 
is useful on top of const because it allows optimizations within the 
function.

Want to memoize a function? If it takes const(char[]), you have to copy 
your input and later check the entire array to see if the parameters 
match a previous call. If it takes an immutable(char[]), you can compare 
pointers.

Do you need to acquire a lock to read this data? If it's immutable, no, 
you don't.


Re: Interested in D, spec confuses me.

2016-02-02 Thread H. S. Teoh via Digitalmars-d
On Tue, Feb 02, 2016 at 09:13:41PM +0100, anonymous via Digitalmars-d wrote:
[...]
> The other signature is no different. Two occurrences of "immutable",
> applying to two different things.
> 
> I agree that it can be unclear to newbies what exactly is immutable
> when a method is marked immutable, but the meaning of the keyword is
> the same as elsewhere. Using another word there would be more
> confusing.

Another way to think about it, is that the "immutable" on the function
means that the implicit `this` reference to the object is immutable.


T

-- 
"How are you doing?" "Doing what?"


Re: Interested in D, spec confuses me.

2016-02-02 Thread Era Scarecrow via Digitalmars-d

On Tuesday, 2 February 2016 at 16:41:54 UTC, jmh530 wrote:
Sure, but - as this post illustrates - there are clearly 
sections of the spec that could have their explanations 
improved.


 It's sorta why i don't refer to the spec to see how the language 
currently works, and instead refer to the D book that's the 
baseline for the D2 standard; even if it's incredibly out of 
date. Too much of the spec from when i glanced at it felt like i 
was reading a lexx/yacc definition, which is a total turn-off.


Re: Interested in D, spec confuses me.

2016-02-02 Thread Jacob Carlborg via Digitalmars-d

On 2016-02-02 15:36, Bambi wrote:


1. const isn't constant
  To my mind, a const is a value that cannot change from the moment it
is defined. But D allows for modification of const values through
non-const references and pointers, and does not promise to optimize
const by placing it in read only memory or similar. Instead, it provides
immutable, which does promise an constant value throughout the lifetime
of the value. I'm not sure why this distinction was created, or what
const is supposed to accomplish here. It's just very confusing to have
two keywords that intuitively do the same thing but don't really.
Applying these keywords to methods would seem to make the data of the
parent object immutable to only the function. Which might be useful but
isn't immediately obvious from the written form.


"const" is like a read-only view of data.

int a = 3;
const(int*) b = 
assert(*b == 3);
a = 4;
assert(*b == 4);
*b = 5; // Error: cannot modify const expression *b

"const" also acts like a super set of immutable and mutable data:

const(int*) a = new int;
immutable(int)* b = new int;
int* c = new int;
foo(a);
foo(b);
foo(c);

void foo(const(int*) a) {}

That would mean that "foo" will not change "a" regardless of if the 
original data is immutable, const or mutable.



The example snippet ' immutable(int[]) bar() immutable {} ' brings back
bad memories of redundant declarations of the style ' Object object =
new Object(); '. And homonyms in programming languages seem like a bad
idea in general.


The first immutable means that "bar" returns an immutable array of ints. 
The second immutable means that "bar" cannot modify the "this" reference:


class Foo
{
int a = 3;

void bar() immutable
{
a = 4; // Error: cannot modify immutable expression this.a
}
}


2. when is an extern an extern?
  The wiki page on interfacing with C states that C globals require an
extra extern. The extern definition in the spec clarifies that extern(C)
alone will copy the global into the current module, but that extern
extern(C) will read it right from the C code. Or maybe it means to say
that using extern(C) alone will only specify a different calling
convention for the variable you are declaring. It's honestly not clear.
Homonym problem again.


"extern(C)" means C linkage and calling conventions. "extern" means that 
a symbol is defined in another object file.


extern (C) int foo;

Compiling that and running the "nm" command to print the symbols will 
list "foo":


00d0 S _foo

Adding "extern" and doing the same:

extern(C) extern int foo;

Will result in this output:

U _foo

That means "foo" is undefined. That is, the linker needs to find that 
symbol in some other library.


If you create bindings to a C library, you would use "extern(C) extern". 
If you create a library in D that some C code should access you would 
use "extern(C)".,


--
/Jacob Carlborg


Re: Interested in D, spec confuses me.

2016-02-02 Thread anonymous via Digitalmars-d

On 02.02.2016 15:36, Bambi wrote:

The example snippet ' immutable(int[]) bar() immutable {} ' brings back
bad memories of redundant declarations of the style ' Object object =
new Object(); '. And homonyms in programming languages seem like a bad
idea in general.


"immutable" is not a homonym here. It means the same thing ("cannot ever 
change"). And it's not redundant either, as the two instances apply to 
different targets. It's clear what the first "immutable" ties to: It 
qualifies the return type. The second one is less clear: It qualifies 
the type of the object, meaning the method can only be called on an 
immutable object.


Leaving either of them out changes the meaning of the signature:
`int[] bar() immutable {}` - Return type is mutable now.
`immutable(int[]) bar() {}` - Object type is mutable now. I.e., this 
method can be called on a mutable object, and it cannot be called on an 
immutable object.


Re: Interested in D, spec confuses me.

2016-02-02 Thread jmh530 via Digitalmars-d

On Tuesday, 2 February 2016 at 15:21:29 UTC, Jacob Carlborg wrote:

[snip]


Does it make sense to add any of this to the spec?




Re: Interested in D, spec confuses me.

2016-02-02 Thread Daniel Kozak via Digitalmars-d
Everything is there already
Dne 2. 2. 2016 17:15 napsal uživatel "jmh530 via Digitalmars-d" <
digitalmars-d@puremagic.com>:

> On Tuesday, 2 February 2016 at 15:21:29 UTC, Jacob Carlborg wrote:
>
>> [snip]
>>
>
> Does it make sense to add any of this to the spec?
>
>
>


Re: Interested in D, spec confuses me.

2016-02-02 Thread jmh530 via Digitalmars-d

On Tuesday, 2 February 2016 at 16:23:01 UTC, Daniel Kozak wrote:

Everything is there already



Sure, but - as this post illustrates - there are clearly sections 
of the spec that could have their explanations improved.


Re: Interested in D, spec confuses me.

2016-02-02 Thread bubbasaur via Digitalmars-d

On Tuesday, 2 February 2016 at 23:41:07 UTC, H. S. Teoh wrote:
Now, the same argument applies if immutable was used in place 
of const. However, the last line in main() illustrates why we 
need const rather than immutable in this case: we actually 
*want* to modify d.x in main(). We just don't want func2 to 
touch anything. So we can't use immutable -- since immutable 
means *nobody* can touch the data. So, const provides both the 
guarantee that func2 won't touch the data, thus allowing the 
aforementioned optimization, and also continues to let main() 
mutate the data at its leisure.


Ok, but what would differ using immutable instead of const in 
your example (AS ARGUMENTS)?


See:

import std.stdio;

struct Data { int x; }
auto func1(Data* d) { return d.x; }
auto func2(const(Data)* d) { return d.x; }
auto func3(immutable(Data)* d) { return d.x; }  

void main() {
Data d;
auto value1 = d.x*func1() + d.x;
auto value2 = d.x*func2() + d.x;
auto value3 = d.x*func3(cast(immutable)) + d.x;
d.x++;
writeln(d.x++);
}

Functions 2 and 3 are acting in the same way and different from 
what you said I can change the d.x in main.


Bubba.


Re: Interested in D, spec confuses me.

2016-02-02 Thread Dicebot via Digitalmars-d
On 02/03/2016 02:31 AM, bubbasaur wrote:
> import std.stdio;
> 
> struct Data { int x; }
> auto func1(Data* d) { return d.x; }
> auto func2(const(Data)* d) { return d.x; }
> auto func3(immutable(Data)* d) { return d.x; }   
> 
> void main() {
> Data d;
> auto value1 = d.x*func1() + d.x;
> auto value2 = d.x*func2() + d.x;
> auto value3 = d.x*func3(cast(immutable)) + d.x;
> d.x++;
> writeln(d.x++);
> }
> 
> Functions 2 and 3 are acting in the same way and different from what you
> said I can change the d.x in main.


Casting immutable and violating it is undefined behavior and once you do
it all bets are off - compiler is even allowed to attempt formatting
your hard drive when compiling this program :)

The fact DMD doesn't do anything scary right now when you do it is a
mere coincidence and may change in any release with no notice.


Re: Interested in D, spec confuses me.

2016-02-02 Thread Ali Çehreli via Digitalmars-d

On 02/02/2016 06:14 PM, bubbasaur wrote:

On Wednesday, 3 February 2016 at 02:00:09 UTC, Jack Stouffer wrote:

Works for me. Something isn't loading properly for you. If you have
any plugins, try disabling them to see if that helps. If that isn't
it, hit alt-super-j if you're on chrome and paste here what it says
there.


I just have Ublock Origin here, I tried dev-tools on chrome and there
are NO errors or anything, them I changed the Font family from "ROBOT
SLAB" to "SAN SERIF" and this is what I got: http://i.imgur.com/zuaLXx0.png

Bubba.



Yay! Now assume that those empty boxes are check marks. :)

Ali



Re: Interested in D, spec confuses me.

2016-02-02 Thread Jack Stouffer via Digitalmars-d

On Wednesday, 3 February 2016 at 00:56:41 UTC, bubbasaur wrote:

http://i.imgur.com/L4a6bx6.png

It shouldn't be some circles or crosses showing the conversion 
on that table?


Bubba.


Works for me. Something isn't loading properly for you. If you 
have any plugins, try disabling them to see if that helps. If 
that isn't it, hit alt-super-j if you're on chrome and paste here 
what it says there.


Re: Interested in D, spec confuses me.

2016-02-02 Thread bubbasaur via Digitalmars-d
On Wednesday, 3 February 2016 at 02:00:09 UTC, Jack Stouffer 
wrote:
Works for me. Something isn't loading properly for you. If you 
have any plugins, try disabling them to see if that helps. If 
that isn't it, hit alt-super-j if you're on chrome and paste 
here what it says there.


I just have Ublock Origin here, I tried dev-tools on chrome and 
there are NO errors or anything, them I changed the Font family 
from "ROBOT SLAB" to "SAN SERIF" and this is what I got: 
http://i.imgur.com/zuaLXx0.png


Bubba.