Re: Weak story about D's relationship to garbage collection?

2015-11-16 Thread rsw0x via Digitalmars-d

On Tuesday, 17 November 2015 at 02:28:04 UTC, Brian wrote:

about one article:
https://www.quora.com/Which-language-has-the-brightest-future-in-replacement-of-C-between-D-Go-and-Rust-And-Why/answer/Andrei-Alexandrescu

really? In this respect will be improved?

I don't like Go, but I hope to have improved D.


D has two problems with garbage collection

one:
There's little ways to work around it when /necessary/
two:
The current GC is slow and bad.

Both are actively being worked on, even if it doesn't seem so. I 
should have an alternate GC to demo soon-ish and I believe 
deadalnix is also working on an alternate GC. Meanwhile, there 
has been a lot of talk(and some work) on ownership semantics, 
compiler lifetime analysis, and RC implementation.


Bye.


Re: Persistent list

2015-11-16 Thread Dicebot via Digitalmars-d
On Monday, 16 November 2015 at 00:00:18 UTC, Andrei Alexandrescu 
wrote:
This illustrates a simple procedural problem. The entire point 
of my posting a simple example of a complete container was to 
avoid hypotheticals such as this. The code is there and shows 
that no, physical const does not suffice. At least I don't know 
how to do it. If you think it does there's one way to show it, 
it's easy - write the code that does it.


We could sit on our testes all day long, speculate how things 
ought to work, and feel awfully smart in the process. It's very 
easy to do. Hell, I've done it more than too many times. What's 
more difficult is have a positive, constructive approach that 
builds on a weak solution to improve it. This is the kind of 
dialog we need to foster.


Sadly, design I would love to see also doesn't seem to be 
implementable but because of different issue - missing scope 
control. I gave a quick go to implement something that shows my 
desired semantics - 
https://gist.github.com/mihails-strasuns-sociomantic/1d7529eef723b1132564 (only essential functionality to show stuff). As you may see it is totally different from your initial proposal - this is why making constructive feedback is rather hard :)


But chosing between breaking physical const via @mutable and 
waiting until we finally get lond wanted scope control tools I am 
very much in favor of the latter.


Re: Persistent list

2015-11-16 Thread Steven Schveighoffer via Digitalmars-d

On 11/16/15 9:00 PM, Meta wrote:

On Tuesday, 17 November 2015 at 01:49:05 UTC, Steven Schveighoffer wrote:

I think it's quite clear that inout in its current form is a point of
huge confusion. I want to work to fix this perception (and fix the
broken corners of the implementation).

What I would ask is for those who at the moment dislike it keep an
open mind, and hold back on your pitchforks. I need to prepare a
suitable defense, and it's difficult to shake off the "confusing and
complex" albatross without having sufficient time to create something
that is easy to understand/explain for something that is conceptually
simple, but requires a complex proof.

What I am afraid of is that someone makes a decision that something is
bad, and by the time a good defense, or workable proposal is mounted,
the answer is "we already discussed that, it's bad. Let's move on."

At least with this, we have a feature that is part of the language, so
is unlikely to go away. But I'd hate to see a mob of PR requests that
remove inout from all of phobos/druntime before I can counter this.

I think inout is worth saving, it needs a few tweaks and a good
explanation.



Regarding my question on StackOverflow, I understand that I had an
inaccurate picture of how inout works, which was causing my problem.
These are also problems with const and immutable to a degree.


I can understand the confusion.

However, here is the truth: you only need to define opEquals for const 
or mutable. You don't need both (if your wrapped type defines both, then 
the const one can be called in both cases), and you don't need an inout 
version. Here is why: inout is simply *equivalent to const* (but without 
the implicit casting) when there is no inout on the return type. 
Originally this was flagged as an error, but because of templates and 
IFTI, it made writing template functions much harder.


But here is a working system that has no inout:

struct Wrapper(T)
{
T t;

static if(is(typeof(const(T).init == const(T).init)))
{
bool opEquals(const(Wrapper) other) const
{
return t == other.t;
}
bool opEquals(const(T) val) const
{
return t == val;
}
}
else
{
bool opEquals(Wrapper other)
{
return t == other.t;
}
bool opEquals(T val)
{
return t == val;
}
}
}

struct Test
{
bool opEquals(Test t)
{
return true;
}
}

struct Test2
{
bool opEquals(inout(Test2) t) inout
{
return true;
}
}

struct Test3
{
bool opEquals(const(Test3) t) const
{
return true;
}
}

void foo(T)()
{
Wrapper!T a, b;
assert(a == b);
assert(a == T());
}

void main()
{
foo!Test();
foo!Test2();
foo!Test3();
}

This doesn't solve the case that has only a mutable and immutable 
opEquals, and no const version, but you get the idea.



However,
inout is like a fourth qualifier that you have to deal with that is
separate from const and immutable, due to how it currently works. In
that light, I still don't think it pulls its weight. What user will have
the presence of mind to define their Foobar type with an
inout/const/immutable toString function? Almost none, and so
Nullable!Foobar.opEquals cannot be inout.


In almost all cases I've come across, inout isn't another thing that 
needs handling. It's simply an alternative to const (when applicable). 
In cases where it is applicable, you write MUCH LESS code. Where it 
breaks down is composition (i.e. creating a type with an inout member) 
and nested functions.



I first encountered this
problem trying to get Nullable.toString to work with inout, and
couldn't. That's my main gripe with inout.


This may have hit one of the warts of inout.

-Steve


Weak story about D's relationship to garbage collection?

2015-11-16 Thread Brian via Digitalmars-d

about one article:
https://www.quora.com/Which-language-has-the-brightest-future-in-replacement-of-C-between-D-Go-and-Rust-And-Why/answer/Andrei-Alexandrescu

really? In this respect will be improved?

I don't like Go, but I hope to have improved D.


Re: Persistent list

2015-11-16 Thread Meta via Digitalmars-d
On Tuesday, 17 November 2015 at 01:49:05 UTC, Steven 
Schveighoffer wrote:
I think it's quite clear that inout in its current form is a 
point of huge confusion. I want to work to fix this perception 
(and fix the broken corners of the implementation).


What I would ask is for those who at the moment dislike it keep 
an open mind, and hold back on your pitchforks. I need to 
prepare a suitable defense, and it's difficult to shake off the 
"confusing and complex" albatross without having sufficient 
time to create something that is easy to understand/explain for 
something that is conceptually simple, but requires a complex 
proof.


What I am afraid of is that someone makes a decision that 
something is bad, and by the time a good defense, or workable 
proposal is mounted, the answer is "we already discussed that, 
it's bad. Let's move on."


At least with this, we have a feature that is part of the 
language, so is unlikely to go away. But I'd hate to see a mob 
of PR requests that remove inout from all of phobos/druntime 
before I can counter this.


I think inout is worth saving, it needs a few tweaks and a good 
explanation.


-Steve


Regarding my question on StackOverflow, I understand that I had 
an inaccurate picture of how inout works, which was causing my 
problem. These are also problems with const and immutable to a 
degree. However, inout is like a fourth qualifier that you have 
to deal with that is separate from const and immutable, due to 
how it currently works. In that light, I still don't think it 
pulls its weight. What user will have the presence of mind to 
define their Foobar type with an inout/const/immutable toString 
function? Almost none, and so Nullable!Foobar.opEquals cannot be 
inout. I first encountered this problem trying to get 
Nullable.toString to work with inout, and couldn't. That's my 
main gripe with inout.


Re: Persistent list

2015-11-16 Thread Joseph Cassman via Digitalmars-d
On Tuesday, 17 November 2015 at 01:49:05 UTC, Steven 
Schveighoffer wrote:

[...]


I think inout is worth saving, it needs a few tweaks and a good 
explanation.


-Steve


Sounds interesting. Might your ideas help to fix the difficulties 
inout has with composability? That would be excellent.


Joseph



Re: Persistent list

2015-11-16 Thread Steven Schveighoffer via Digitalmars-d

On 11/16/15 8:21 PM, deadalnix wrote:

On Tuesday, 17 November 2015 at 00:30:39 UTC, Steven Schveighoffer wrote:

On 11/16/15 6:56 PM, deadalnix wrote:

On Monday, 16 November 2015 at 22:30:55 UTC, Andrei Alexandrescu wrote:

On 11/16/2015 05:02 PM, Jonathan M Davis wrote:

It's just that you use inout instead of const. How is that worse?


The short answer is my perception is inout is too complicated for what
it does. -- Andrei


I'm happy to read this. inout has the wrong cost/complexity ratio. It
doesn't solve the problem generally (one want to return type depending
on argument qualifier in general, not only for type qualifiers) while
having a high complexity.



The problem it solves is to provide a mechanism that allows one to
safely apply the same qualifiers to the return type, but have the
inputs be constant *throughout the function*.

A templated function doesn't do this, you can have conditional code,
or unchecked method calls that can modify the data when possible.

Of course, if this isn't important, then the template solution is
usable. My take is that whenever you use inout is when you would
normally use const, but const doesn't allow what you need. If your
function doesn't need const inside the function, then you shouldn't
use inout.

To me, it feels like inout is simple, but the implementation has warts
that make it seem inconsistent. There is also the issue that nested
inout is super-confusing, because now you have layers of inout, each
layer meaning possibly something different. If we could somehow fix
the nested part (and allow types with inout members inside there), I
think inout would be less intimidating.

Here is, IMO, the point you are missing.

There many qualifier you'd like to have depend on other qualifiers. For
instance :

void doSomeThingAndCallBack(maybe_pure void function() callback)
pure_if_maybe_pure_argument_is_pure {
 callback();
}


This already works with templates. If all you care about is writing a 
function that has the *ability* to take any kind of input, then 
templates are perfect for that.


What inout solves above templates (and note, you can combine inout AND 
templates), is that during the function call, the parameter is not 
modified -- guaranteed by the compiler (as much as it can). Templates 
cannot offer that. To me the maybe_pure solution doesn't even come close 
to inout's utility (what does it guarantee beside being able to take 
different types of parameters?).


For those who care about const or try to use const (and immutable) to 
provide API guarantees on parameters, it becomes unwieldy to both 
specify "yes! I can take any qualified type of parameter" and "no! I 
promise I won't modify them." Const fills this void, but has the the 
issue of blindly coloring everything const, locking up all your data for 
things like function chaining. Inout is supposed to fix this one 
problem, and should be a seamless replacement for const in those cases. 
It obviously is not.



Thus, the power/complexity ratio is not good.


inout is for one specific thing, I see it to be unrelated to templates. 
It's more of an extension of const. The complexity, IMO, is not 
necessarily huge (perhaps in the current implementation, I'm not sure), 
but the consistency is terrible. There are things you just should be 
able to do, and the compiler won't do them. Inevitably, the templates 
people write end up trying to do these things (because they are 
logically correct), and the compiler spits out cryptic "cannot call this 
function" errors. These can be difficult to figure out.



Also, yes, the implementation is B0rken :) Still it has gotten much
better over time (or I learned the hard way to stay into the patterns
that works ?).



It has definitely gotten better over time. It used to be that if you 
used any kind of template with an inout parameter, it wouldn't compile.


-Steve


Re: Persistent list

2015-11-16 Thread deadalnix via Digitalmars-d
On Sunday, 15 November 2015 at 12:56:27 UTC, Andrei Alexandrescu 
wrote:

On 11/14/2015 05:49 PM, Timon Gehr wrote:
List uses RC internally. I don't think the UB casts will stay 
for the
final version, unless you are willing to completely dilute the 
meaning
of const in ways that Walter has explicitly expressed will not 
be done

in the past.


As I mentioned, he's okay with changing the language to make 
the casts well defined. -- Andrei


Ok Here is what I propose as a spec. This is rough brain dump, 
but that is something I think can be a good start.


There are mutable data that are thread local and immutable data 
that are shared. const is a wildcard type qualifier that can 
refers to mutable or immutable data.


immutable is supposed to be effectively immutable. This means 
that the compiler is allowed to store these data in ro segments 
and optimize redundant loads without having to prove that no 
aliasing write occur in between.


One can cast away const or immutable. It is a @system operation 
and this cast needs to be explicit.


If the underlying data is in ro segment, any write is effectively 
undefined behavior (most likely a fault).
If the underlying data is allocated on the head (using the GC or 
malloc for instance) then writing to it will effectively update 
the underlying memory.


Any read from a const or immutable reference after these write 
can is undefined.

Granted the write was not UB :
1/ Any read from a mutable reference in another thread is 
undefined behavior unless the writing thread release after write 
and the reading one acquire (or any stronger memory barrier).
2/ Any read from a mutable reference in the same thread will see 
the updates in a sequentially consistent manner.


Sounds good ? This definitively allow to do RC for 
const/immutable without throwing away optimization opportunities.




Re: Persistent list

2015-11-16 Thread Steven Schveighoffer via Digitalmars-d

On 11/16/15 8:11 PM, Meta wrote:

On Tuesday, 17 November 2015 at 00:30:39 UTC, Steven Schveighoffer wrote:

The problem it solves is to provide a mechanism that allows one to
safely apply the same qualifiers to the return type, but have the
inputs be constant *throughout the function*.

A templated function doesn't do this, you can have conditional code,
or unchecked method calls that can modify the data when possible.

Of course, if this isn't important, then the template solution is
usable. My take is that whenever you use inout is when you would
normally use const, but const doesn't allow what you need. If your
function doesn't need const inside the function, then you shouldn't
use inout.

To me, it feels like inout is simple, but the implementation has warts
that make it seem inconsistent. There is also the issue that nested
inout is super-confusing, because now you have layers of inout, each
layer meaning possibly something different. If we could somehow fix
the nested part (and allow types with inout members inside there), I
think inout would be less intimidating.

-Steve


I don't mean to derail this thread, but I also am not really crazy about
inout in its current form. Its transitive nature is one issue (though
that can't be changed due to const and immutable also being transitive),
but also the fact that inout is basically a fourth qualifier, which
causes a lot of pain when you're wrapping other types.

For example, calling opEquals on a wrapped struct inside the opEquals of
the wrapper struct (which is marked as inout) when the wrapped struct
does not also define an inout opEquals, will not call the mutable
opEquals of the wrapped struct. It *will not* compile unless the wrapped
struct also defines an inout opEquals, no matter the constness of the
wrapper or the wrappee. Basically, wrapper types cannot with inout.

http://stackoverflow.com/questions/31516713/escaping-from-inout-hell


I think it's quite clear that inout in its current form is a point of 
huge confusion. I want to work to fix this perception (and fix the 
broken corners of the implementation).


What I would ask is for those who at the moment dislike it keep an open 
mind, and hold back on your pitchforks. I need to prepare a suitable 
defense, and it's difficult to shake off the "confusing and complex" 
albatross without having sufficient time to create something that is 
easy to understand/explain for something that is conceptually simple, 
but requires a complex proof.


What I am afraid of is that someone makes a decision that something is 
bad, and by the time a good defense, or workable proposal is mounted, 
the answer is "we already discussed that, it's bad. Let's move on."


At least with this, we have a feature that is part of the language, so 
is unlikely to go away. But I'd hate to see a mob of PR requests that 
remove inout from all of phobos/druntime before I can counter this.


I think inout is worth saving, it needs a few tweaks and a good explanation.

-Steve


Re: Persistent list

2015-11-16 Thread deadalnix via Digitalmars-d
On Tuesday, 17 November 2015 at 00:30:39 UTC, Steven 
Schveighoffer wrote:

On 11/16/15 6:56 PM, deadalnix wrote:
On Monday, 16 November 2015 at 22:30:55 UTC, Andrei 
Alexandrescu wrote:

On 11/16/2015 05:02 PM, Jonathan M Davis wrote:
It's just that you use inout instead of const. How is that 
worse?


The short answer is my perception is inout is too complicated 
for what

it does. -- Andrei


I'm happy to read this. inout has the wrong cost/complexity 
ratio. It
doesn't solve the problem generally (one want to return type 
depending
on argument qualifier in general, not only for type 
qualifiers) while

having a high complexity.



The problem it solves is to provide a mechanism that allows one 
to safely apply the same qualifiers to the return type, but 
have the inputs be constant *throughout the function*.


A templated function doesn't do this, you can have conditional 
code, or unchecked method calls that can modify the data when 
possible.


Of course, if this isn't important, then the template solution 
is usable. My take is that whenever you use inout is when you 
would normally use const, but const doesn't allow what you 
need. If your function doesn't need const inside the function, 
then you shouldn't use inout.


To me, it feels like inout is simple, but the implementation 
has warts that make it seem inconsistent. There is also the 
issue that nested inout is super-confusing, because now you 
have layers of inout, each layer meaning possibly something 
different. If we could somehow fix the nested part (and allow 
types with inout members inside there), I think inout would be 
less intimidating.


-Steve


Here is, IMO, the point you are missing.

There many qualifier you'd like to have depend on other 
qualifiers. For instance :


void doSomeThingAndCallBack(maybe_pure void function() callback) 
pure_if_maybe_pure_argument_is_pure {

callback();
}

You'll note that this is the same problem as inout solves. Thing 
is inout is complex, but only solve a small subset of the problem.


Thus, the power/complexity ratio is not good.

Also, yes, the implementation is B0rken :) Still it has gotten 
much better over time (or I learned the hard way to stay into the 
patterns that works ?).




Re: Persistent list

2015-11-16 Thread Meta via Digitalmars-d
On Tuesday, 17 November 2015 at 00:30:39 UTC, Steven 
Schveighoffer wrote:
The problem it solves is to provide a mechanism that allows one 
to safely apply the same qualifiers to the return type, but 
have the inputs be constant *throughout the function*.


A templated function doesn't do this, you can have conditional 
code, or unchecked method calls that can modify the data when 
possible.


Of course, if this isn't important, then the template solution 
is usable. My take is that whenever you use inout is when you 
would normally use const, but const doesn't allow what you 
need. If your function doesn't need const inside the function, 
then you shouldn't use inout.


To me, it feels like inout is simple, but the implementation 
has warts that make it seem inconsistent. There is also the 
issue that nested inout is super-confusing, because now you 
have layers of inout, each layer meaning possibly something 
different. If we could somehow fix the nested part (and allow 
types with inout members inside there), I think inout would be 
less intimidating.


-Steve


I don't mean to derail this thread, but I also am not really 
crazy about inout in its current form. Its transitive nature is 
one issue (though that can't be changed due to const and 
immutable also being transitive), but also the fact that inout is 
basically a fourth qualifier, which causes a lot of pain when 
you're wrapping other types.


For example, calling opEquals on a wrapped struct inside the 
opEquals of the wrapper struct (which is marked as inout) when 
the wrapped struct does not also define an inout opEquals, will 
not call the mutable opEquals of the wrapped struct. It *will 
not* compile unless the wrapped struct also defines an inout 
opEquals, no matter the constness of the wrapper or the wrappee. 
Basically, wrapper types cannot with inout.


http://stackoverflow.com/questions/31516713/escaping-from-inout-hell


Re: Persistent list

2015-11-16 Thread Steven Schveighoffer via Digitalmars-d

On 11/16/15 6:56 PM, deadalnix wrote:

On Monday, 16 November 2015 at 22:30:55 UTC, Andrei Alexandrescu wrote:

On 11/16/2015 05:02 PM, Jonathan M Davis wrote:

It's just that you use inout instead of const. How is that worse?


The short answer is my perception is inout is too complicated for what
it does. -- Andrei


I'm happy to read this. inout has the wrong cost/complexity ratio. It
doesn't solve the problem generally (one want to return type depending
on argument qualifier in general, not only for type qualifiers) while
having a high complexity.



The problem it solves is to provide a mechanism that allows one to 
safely apply the same qualifiers to the return type, but have the inputs 
be constant *throughout the function*.


A templated function doesn't do this, you can have conditional code, or 
unchecked method calls that can modify the data when possible.


Of course, if this isn't important, then the template solution is 
usable. My take is that whenever you use inout is when you would 
normally use const, but const doesn't allow what you need. If your 
function doesn't need const inside the function, then you shouldn't use 
inout.


To me, it feels like inout is simple, but the implementation has warts 
that make it seem inconsistent. There is also the issue that nested 
inout is super-confusing, because now you have layers of inout, each 
layer meaning possibly something different. If we could somehow fix the 
nested part (and allow types with inout members inside there), I think 
inout would be less intimidating.


-Steve


Re: Formal Review of std.range.ndslice

2015-11-16 Thread Brian Schott via Digitalmars-d

On Monday, 16 November 2015 at 22:45:35 UTC, Jack Stouffer wrote:
This is the start of the two week formal review for the 
proposed std.range.ndslice. This new addition to the standard 
library would add the ability to create and manipulate 
multi-dimensional random access ranges in a way that will be 
very familiar to those of you who use numpy. This has the 
potential to give D a huge boost in popularity in numerical and 
scientific applications.


One thing that stands out is the number of symbols in the Slice 
struct that have simple "///" doc comments. That is, they show up 
in the generated documentation without any explanation.


Re: Persistent list

2015-11-16 Thread deadalnix via Digitalmars-d
On Monday, 16 November 2015 at 22:30:55 UTC, Andrei Alexandrescu 
wrote:

On 11/16/2015 05:02 PM, Jonathan M Davis wrote:
It's just that you use inout instead of const. How is that 
worse?


The short answer is my perception is inout is too complicated 
for what it does. -- Andrei


I'm happy to read this. inout has the wrong cost/complexity 
ratio. It doesn't solve the problem generally (one want to  
return type depending on argument qualifier in general, not only 
for type qualifiers) while having a high complexity.




Re: Implement the "unum" representation in D ?

2015-11-16 Thread Nick_B via Digitalmars-d
On Sunday, 15 November 2015 at 04:19:21 UTC, Lionello Lunesu 
wrote:

On 09/11/15 04:38, Richard Davies wrote:

Yeah, I got curious too. I spend some time on it yesterday and 
had a stab at writing it in D.


Hi. I send a email to John Gustafson yesterday, re this thread.

He replied as follows:

"There are efforts underway worldwide to support unums in C, 
Python, Julia, Java, and now D. And the book has only been out 
for nine months!"


Nick


Re: Persistent list

2015-11-16 Thread deadalnix via Digitalmars-d

On Sunday, 15 November 2015 at 20:11:02 UTC, Dicebot wrote:
On Sunday, 15 November 2015 at 19:51:09 UTC, Andrei 
Alexandrescu wrote:
Just to clarify - is that referring to the part "We need to 
change that if we want things like composable containers that 
work with const." or to the "I think it's a good thing to 
want" part? -- Andrei


Second part. I don't see a case for const containers at all. 
Fully immutable functional style ones - sure, I have actually 
experimented implementing cache this way in 
https://github.com/Dicebot/mood/blob/master/source/mood/storage/generic_cache.d (thing that powers blog.dicebot.lv). But what would you use const containers for? Mixing mutable and immutable elements in one container? That sounds like a source of much trouble.


For the variance. If you wan't write in the container, you make 
make it so that


ConstContainer implicitly convert to ConstContainer if B 
inherit from A.


You can have code that accept mutable and const container as 
well, which is useful, because you can cram immutable container 
in the ro section.


Re: Persistent list

2015-11-16 Thread Steven Schveighoffer via Digitalmars-d

On 11/16/15 5:35 PM, Andrei Alexandrescu wrote:

On 11/16/2015 05:30 PM, Steven Schveighoffer wrote:

I'll reiterate what I said elsewhere: inout is better, safer, and easier
to maintain than the template solution.


Do you have a working solution in dpaste? No change to the return types
please. -- Andrei


Ah, where it breaks down is emplace uses an internal struct with a T, 
which is inout(const(Node)*).


So you *are* hitting one of the limitations of inout, one that Dmitry 
brought up. I stand corrected.


I think it can be fixed, we need to make structs that contain inout 
member variables legal as long as they only exist on inout function 
stacks. It may be possible to fix emplace for inout by changing the ctor 
of the internal struct to inout instead of typing T as inout, but I'm 
not sure.


In this case, in order to work around, you have to cast when you use 
emplace, somewhat defeating the safety of emplace :(


http://dpaste.dzfl.pl/182e2ac5da2d

The only other weird part is where you see inout(const(Node)*) in the 
fixed ctor. This is because it's a different type than inout(Node*), 
it's like const(immutable(Node)*), the pointer itself is const, but the 
data it points at is still immutable.


-Steve


Re: Persistent list

2015-11-16 Thread Steven Schveighoffer via Digitalmars-d

On 11/16/15 4:49 PM, Andrei Alexandrescu wrote:

On 11/16/2015 04:36 PM, Steven Schveighoffer wrote:

We can and should fix this. I'll file an issue if none has been filed.


That's great! -- Andrei


https://issues.dlang.org/show_bug.cgi?id=15347

Note that the trigger is the ctor and dtor of the struct. Each adds 
worse layers of error message horror :)


-Steve


Formal Review of std.range.ndslice

2015-11-16 Thread Jack Stouffer via Digitalmars-d
This is the start of the two week formal review for the proposed 
std.range.ndslice. This new addition to the standard library 
would add the ability to create and manipulate multi-dimensional 
random access ranges in a way that will be very familiar to those 
of you who use numpy. This has the potential to give D a huge 
boost in popularity in numerical and scientific applications.


A quick run down for those that are not familiar with the 
process. After two weeks, the PR author (Ilya Yaroshenko) will 
have time to make proposed changes. Then, when the author feels 
it's ready, the PR will go to a vote. In the vote, everyone in 
the community has a say, but if one of the main contributors or 
maintainers has a very negative opinion (for example) that will 
carry more weight.


Github: https://github.com/D-Programming-Language/phobos/pull/3397
dub: http://code.dlang.org/packages/dip80-ndslice
docs: 
http://dtest.thecybershadow.net/results/bac6211c1d73b2cf62bc18c9844c8c82c92c21e1/5c6071ca953cf113febd8786b4b68916cbb2cdaf/


previous discussion: 
http://forum.dlang.org/thread/rilfmeaqkailgpxoz...@forum.dlang.org


Re: Persistent list

2015-11-16 Thread Andrei Alexandrescu via Digitalmars-d

On 11/16/2015 05:30 PM, Steven Schveighoffer wrote:

I'll reiterate what I said elsewhere: inout is better, safer, and easier
to maintain than the template solution.


Do you have a working solution in dpaste? No change to the return types 
please. -- Andrei


Re: Persistent list

2015-11-16 Thread Andrei Alexandrescu via Digitalmars-d

On 11/16/2015 05:02 PM, Jonathan M Davis wrote:

It's just that you use inout instead of const. How is that worse?


The short answer is my perception is inout is too complicated for what 
it does. -- Andrei


Re: Persistent list

2015-11-16 Thread Observer via Digitalmars-d
On Monday, 16 November 2015 at 16:58:24 UTC, Lionello Lunesu 
wrote:
If it's RC we want, then @mutable is an axe when what we need 
is a scalpel.


The non-observability comes from the fact the refcount is 
changed when the caller has lost its (const) reference and 
constness is a moot point. Changing refcount is fine now, 
provided the object is not immutable. As far as other 
outstanding const references go, these already expect changes 
to happen.


This is what makes refcount special and provably safe to 
mutate. As long as we can ensure the object is not immutable, 
the object is allowed to change its own refcount. But refcount 
needs to be special cased, somehow, or else we'll end up with 
some C++ like `mutable`.


I'm not a compiler or language-design guy, but something strikes
me as odd about this whole discussion.  It seems to me that a lot
of it depends on a presumption that one wants the refcount field
to be user-visible, and that therefore it must also have some
user-visible type and perhaps some attributes.  But at bottom,
doesn't a refcount field behave more like a vptr for a class
instance, which is there in the underlying storage model but is
not directly user-visible?  Or similar to whatever metadata is
used for the start/end pointers of a dynamic array?  As such, is
there any reason for a refcount to be user-visible in the first
place, other than to the compiler-internals implementor?  I have
to wonder whether a refcount field could be appended to the data
payload via some sort of @rc attribute instead of as an explicit
class/struct member, and perhaps referenced via some implicit
pseudo member when the field needs to be manipulated.  Then there
perhaps wouldn't need to be any requirement to define any new
kinds of storage categories for this field, in the same way that
there isn't an explicit storage category for a vptr field.

I could be all wet here with such ideas, but I'm just wondering 
...


Re: Persistent list

2015-11-16 Thread Steven Schveighoffer via Digitalmars-d

On 11/16/15 5:02 PM, Jonathan M Davis wrote:

On Monday, 16 November 2015 at 21:47:07 UTC, Andrei Alexandrescu wrote:

On 11/16/2015 04:18 PM, Jonathan M Davis wrote:

When you can templatize the function on the type that would otherwise be
inout, then there really isn't any reason to use inout. But what do you
do when you're dealing with a member function - especially on a class? I
don't know of any way to templatize a member function on the type of the
this pointer/reference, but maybe there's a template feature with which
I'm not familiar enough. But even if there _is_ such a feature, it won't
work for virtual functions.


It does. Write one-liners that forward to the template function, as
shown in http://dpaste.dzfl.pl/52a3013efe34 (search the page for
QList). -- Andrei


Well, that does reduce the code duplication, but you're still forced to
have up to three separate functions to get each of the different return
types (even if they are then simply wrapper functions). And compare that
with simply declaring the same function once with its implementation
internal to itself. It's just that you use inout instead of const. How
is that worse?


I'll reiterate what I said elsewhere: inout is better, safer, and easier 
to maintain than the template solution.


Example:

static QList cons(QList)(T head, auto ref QList lst)
if (is(Unqual!QList == List))

Tell me how cons guarantees not to modify lst? Is it convention or 
compiler guarantees? find the bug:


static QList cons(QList)(T head, auto ref QList lst)
if (is(Unqual!QList == List))
{
List result;
result._allocator = either(lst.allocator, theAllocator);
import std.conv : emplace;
void[] buf = result.allocator.allocate(Node.sizeof);
auto n = emplace!(const Node)(buf, head, lst.root, 1);
incRef(lst.root);
result.root = n;
static if(!is(QList == const)) lst.root = lst.root.next;
return result;
}

The point of const is to provide a mechanism to those reading the 
signature to say "this function will NOT change the parameter, and the 
compiler guarantees it." The point of inout is the same, but allows 
returning a portion of the parameters without resorting to casts or 
wrappers.


-Steve


Re: Persistent list

2015-11-16 Thread Jonathan M Davis via Digitalmars-d
On Monday, 16 November 2015 at 21:36:41 UTC, Steven Schveighoffer 
wrote:
I just did the naive thing and slapped inout on your functions. 
This is what I got:


persistent_list2.d(146): Error: cannot implicitly convert 
expression (( List!(immutable(int)) __slList1681 = List(null, 
null);
 , __slList1681).this(n, this.allocator())) of type 
List!(immutable(int)) to inout(List!(immutable(int)))


WTF!


Wow is that hideous. I don't recall ever seeing error messages 
that obtuse.


We can and should fix this. I'll file an issue if none has been 
filed.


Please do.

- Jonathan M Davis


Re: Persistent list

2015-11-16 Thread Jonathan M Davis via Digitalmars-d
On Monday, 16 November 2015 at 21:47:07 UTC, Andrei Alexandrescu 
wrote:

On 11/16/2015 04:18 PM, Jonathan M Davis wrote:
When you can templatize the function on the type that would 
otherwise be
inout, then there really isn't any reason to use inout. But 
what do you
do when you're dealing with a member function - especially on 
a class? I
don't know of any way to templatize a member function on the 
type of the
this pointer/reference, but maybe there's a template feature 
with which
I'm not familiar enough. But even if there _is_ such a 
feature, it won't

work for virtual functions.


It does. Write one-liners that forward to the template 
function, as shown in http://dpaste.dzfl.pl/52a3013efe34 
(search the page for QList). -- Andrei


Well, that does reduce the code duplication, but you're still 
forced to have up to three separate functions to get each of the 
different return types (even if they are then simply wrapper 
functions). And compare that with simply declaring the same 
function once with its implementation internal to itself. It's 
just that you use inout instead of const. How is that worse?


There are cases where inout doesn't work as well as const does 
due to limitations with inout, but in many (most?) cases, the 
only difference between using const and inout is that you're 
typing const instead of inout. So, if anything, that makes it 
sound like fixing inout so that it works in those other cases 
would be better than avoiding it in favor of splitting out the 
implementation into a separate function and having multiple 
wrapper functions in the API.


- Jonathan M Davis


Re: Persistent list

2015-11-16 Thread Jonathan M Davis via Digitalmars-d

On Monday, 16 November 2015 at 21:25:52 UTC, Timon Gehr wrote:

On 11/16/2015 10:18 PM, Jonathan M Davis wrote:
I don't know of any way to templatize a member function on the 
type of
the this pointer/reference, but maybe there's a template 
feature with

which I'm not familiar enough.


Indeed there is.

class C{
void foo(this T)(){ pragma(msg, T); }
}

class D: C{}

void main(){
auto c=new const(C)();
c.foo();
auto d=new immutable(D)();
d.foo();
}


Cool. That's good to know about. Thanks.

- Jonathan M Davis



Re: Persistent list

2015-11-16 Thread Andrei Alexandrescu via Digitalmars-d

On 11/16/2015 04:36 PM, Steven Schveighoffer wrote:

We can and should fix this. I'll file an issue if none has been filed.


That's great! -- Andrei


Re: Persistent list

2015-11-16 Thread Andrei Alexandrescu via Digitalmars-d

On 11/16/2015 04:18 PM, Jonathan M Davis wrote:

When you can templatize the function on the type that would otherwise be
inout, then there really isn't any reason to use inout. But what do you
do when you're dealing with a member function - especially on a class? I
don't know of any way to templatize a member function on the type of the
this pointer/reference, but maybe there's a template feature with which
I'm not familiar enough. But even if there _is_ such a feature, it won't
work for virtual functions.


It does. Write one-liners that forward to the template function, as 
shown in http://dpaste.dzfl.pl/52a3013efe34 (search the page for QList). 
-- Andrei


Re: Persistent list

2015-11-16 Thread Steven Schveighoffer via Digitalmars-d

On 11/16/15 3:48 PM, Andrei Alexandrescu wrote:



I think the main problem is the difficulty of getting from "I want to
make this method work with mutable and nonconst data" to "I have a
working solution using inout".


Again, it's not that hard. I have had little trouble with using it 
instead of const where it is appropriate. There are a couple rough 
edges, but you haven't hit them yet.




The semantics is complex and difficult. Error messages are horrifying.
Even explaining code that works is hard. Once a solution works, trying
to change it in meaningful ways again makes the code not work, and again
with uninformative error messages. So there's resistance to changing
working code.


I just did the naive thing and slapped inout on your functions. This is 
what I got:


persistent_list2.d(146): Error: cannot implicitly convert expression (( 
List!(immutable(int)) __slList1681 = List(null, null);
 , __slList1681).this(n, this.allocator())) of type 
List!(immutable(int)) to inout(List!(immutable(int)))


WTF!

This is not how it used to be. What the hell is __slList1681? And what 
is List(null, null)?


This has to be some sort of lowering that was added to the compiler, I 
have never seen such horrible messages for inout. How it should look:


Error: cannot implicitly convert expression List(n, allocator) of type 
List!(immutable(int)) to inout(List!(immutable(int)))


Note, this is not an inout problem. If I put immutable(List) as the 
return type, I get:


persistent_list2.d(146): Error: cannot implicitly convert expression (( 
List!(immutable(int)) __slList1681 = List(null, null);
 , __slList1681).this(n, this.allocator())) of type 
List!(immutable(int)) to immutable(List!(immutable(int)))


We can and should fix this. I'll file an issue if none has been filed.


At the same time, we have a wonderful language ready to help with
features that didn't exist when we introduced inout. Search
http://dpaste.dzfl.pl/52a3013efe34 for QList - it's restricted properly,
works very well, and is easy to explain.


Actually, it's not easier to explain or maintain, and the solution 
existed before inout was introduced (in fact one of the reasons *to* use 
inout was to avoid QList-like solutions).


Example:

static QList cons(QList)(T head, auto ref QList lst)
if (is(Unqual!QList == List))

Tell me how cons guarantees not to modify lst? Is it convention or 
compiler guarantees? find the bug:


static QList cons(QList)(T head, auto ref QList lst)
if (is(Unqual!QList == List))
{
List result;
result._allocator = either(lst.allocator, theAllocator);
import std.conv : emplace;
void[] buf = result.allocator.allocate(Node.sizeof);
auto n = emplace!(const Node)(buf, head, lst.root, 1);
incRef(lst.root);
result.root = n;
static if(!is(QList == const)) lst.root = lst.root.next;
return result;
}

The point of const is to provide a mechanism to those reading the 
signature to say "this function will NOT change the parameter, and the 
compiler guarantees it."


I remember reading originally why Walter put const into the language -- 
because C++ developers who used const extensively to provide guarantees 
simply wouldn't use D if it didn't provide a mechanism to do this. I 
don't recall the exact wording, but I'm sure it's somewhere in the ng.


The point of inout was to provide what const does, but allow you to hook 
the output const flavor to the input const flavor. That's all.



Walter and I think inout didn't turn out well. It became a little
monster mastering a swamp. Template solutions can drain that swamp, make
the monster disappear, and build nice things on that field.


I disagree, and appeals to authority is not very convincing, no matter 
how colorful. I think inout works great for what it's good at. It has 
some finishing to do, but the concept is sound and works fine. It's a 
perfect fit for containers in general. In this particular case it's not 
necessary.


We absolutely should fix the error messages, they are not very helpful.


I think we should slowly marginalize inout - discourage it from new
code, document and publicize better alternatives, the works.


Because we have a poor error message? I can assure you this is not 
endemic to inout.



In this case, it appears to work only because of your cast of _allocator
to mutable whenever you access it via allocator. Other than that, the
only other member is the node pointer, which is const. Effectively, A
list's data is always const, so there is no reason to make the struct
itself const.


Plenty of reason. The list may be member in an object. Also, if you
don't have const List you can't compose List with itself.


Huh? Mutable List casts to const List just fine. If I always return a 
mutable List from a composing operation, then it works for const List as 
well (both as the receiver of the return value and as the parameter).


What I meant to say is that a const(List) isn't particularly needed to 
guard the List's data. That is already const.


-Steve


Re: Wanted: Review manager for std.experimental.range.ndslice

2015-11-16 Thread Ilya Yaroshenko via Digitalmars-d

On Monday, 16 November 2015 at 21:01:03 UTC, Jack Stouffer wrote:

On Monday, 16 November 2015 at 20:12:37 UTC, Ilya wrote:

It is very close draft:
http://wiki.dlang.org/Review/Process


I volunteer then, if you'll have me.


Great! Thank you :)


Re: And in the (quasi-)comedy section…

2015-11-16 Thread bitwise via Digitalmars-d

On Monday, 16 November 2015 at 17:05:14 UTC, Marc Schütz wrote:
On Monday, 16 November 2015 at 14:33:26 UTC, Russel Winder 
wrote:

A quote from @SarcasticRover:


New studies show that Mars' moon Phobos is slowly breaking up 
under pressure… but really, who isn't? Life is hard.


You know, I saw this piece of news, but refrained from making a 
comment here. Though it was tempting :-P


heh... +1




Re: Persistent list

2015-11-16 Thread Timon Gehr via Digitalmars-d

On 11/16/2015 10:18 PM, Jonathan M Davis wrote:

I don't know of any way to templatize a member function on the type of
the this pointer/reference, but maybe there's a template feature with
which I'm not familiar enough.


Indeed there is.

class C{
void foo(this T)(){ pragma(msg, T); }
}

class D: C{}

void main(){
auto c=new const(C)();
c.foo();
auto d=new immutable(D)();
d.foo();
}


But even if there _is_ such a feature, it won't work for virtual functions.


Yup.


Re: Our template emission strategy is broken

2015-11-16 Thread Jonathan M Davis via Digitalmars-d

On Monday, 16 November 2015 at 09:05:16 UTC, Marco Leise wrote:

Am Wed, 11 Nov 2015 14:23:15 +
schrieb Martin Nowak :

Think of that for a moment, no package manager allows you to 
have cycles in your dependencies.


There are package managers that allow packages to mutually
depend on each other. Order is established by qualifying the
dependency similar to how you declare an owning and a weak
reference in a parent/child pointer relation.


LOL. Yeah. I expect that 99+% of Linux boxes contain mutually 
dependent packages. Circular dependencies make setting up Gentoo 
that much more entertaining (e.g. IIRC, OpenSSL and Cyrus SASL 
depend on each other normally). At least some dependencies can be 
eliminated with binary packages, because they're only build 
dependencies, but not all of them are that way, unfortunately.


- Jonathan M Davis


Re: Persistent list

2015-11-16 Thread Jonathan M Davis via Digitalmars-d
On Monday, 16 November 2015 at 20:48:49 UTC, Andrei Alexandrescu 
wrote:
I think we should slowly marginalize inout - discourage it from 
new code, document and publicize better alternatives, the works.


When you can templatize the function on the type that would 
otherwise be inout, then there really isn't any reason to use 
inout. But what do you do when you're dealing with a member 
function - especially on a class? I don't know of any way to 
templatize a member function on the type of the this 
pointer/reference, but maybe there's a template feature with 
which I'm not familiar enough. But even if there _is_ such a 
feature, it won't work for virtual functions.


So, while I completely agree that it's cleaner to avoid inout 
when it's not needed, from what I can see, there are cases where 
you really don't have an alternative aside from duplicating the 
entire function. So, it does seem like on some level, we're stuck 
using inout, even if we can avoid it in many cases.


- Jonathan M Davis


Re: Wanted: Review manager for std.experimental.range.ndslice

2015-11-16 Thread Jack Stouffer via Digitalmars-d

On Monday, 16 November 2015 at 20:12:37 UTC, Ilya wrote:

It is very close draft:
http://wiki.dlang.org/Review/Process


I volunteer then, if you'll have me.


Re: Persistent list

2015-11-16 Thread Daniel N via Digitalmars-d
On Monday, 16 November 2015 at 18:37:18 UTC, Andrei Alexandrescu 
wrote:

On 11/16/2015 12:51 PM, Steven Schveighoffer wrote:

 List tail() const


I'd like tail to be qualifier-idempotent, i.e. return const for 
const and non-const for non-const. -- Andrei


I don't have a compiler at hand right now, but doesn't this work?

auto tail(this U)() const
{
  assert(root);
  auto n = root.next;
  incRef(n);
  return U(n, allocator);
}



Re: Persistent list

2015-11-16 Thread Andrei Alexandrescu via Digitalmars-d

On 11/16/2015 03:38 PM, Steven Schveighoffer wrote:

On 11/16/15 2:37 PM, Andrei Alexandrescu wrote:

On 11/16/2015 01:55 PM, Steven Schveighoffer wrote:

On 11/16/15 1:37 PM, Andrei Alexandrescu wrote:

On 11/16/2015 12:51 PM, Steven Schveighoffer wrote:

 List tail() const


I'd like tail to be qualifier-idempotent, i.e. return const for const
and non-const for non-const. -- Andrei


Why? const(int)[] isn't const, why should List!(const(int)) be?


I'm keeping an eye toward other containers and also more general use.
It's a common need. -- Andrei


Anywhere const can work, inout should work as well. The one exception as
I've described is when you create and build a (im)mutable result, then
converting it to const. In this case, you have to build it at once.
Otherwise, the compiler can't tell whether this mutable thing you are
constructing is safe to cast to inout (and whatever flavor it needs to
cast to upon exit).


I think the main problem is the difficulty of getting from "I want to 
make this method work with mutable and nonconst data" to "I have a 
working solution using inout".


The semantics is complex and difficult. Error messages are horrifying. 
Even explaining code that works is hard. Once a solution works, trying 
to change it in meaningful ways again makes the code not work, and again 
with uninformative error messages. So there's resistance to changing 
working code.


At the same time, we have a wonderful language ready to help with 
features that didn't exist when we introduced inout. Search 
http://dpaste.dzfl.pl/52a3013efe34 for QList - it's restricted properly, 
works very well, and is easy to explain.


Walter and I think inout didn't turn out well. It became a little 
monster mastering a swamp. Template solutions can drain that swamp, make 
the monster disappear, and build nice things on that field.


I think we should slowly marginalize inout - discourage it from new 
code, document and publicize better alternatives, the works.



In this case, it appears to work only because of your cast of _allocator
to mutable whenever you access it via allocator. Other than that, the
only other member is the node pointer, which is const. Effectively, A
list's data is always const, so there is no reason to make the struct
itself const.


Plenty of reason. The list may be member in an object. Also, if you 
don't have const List you can't compose List with itself.



Andrei




Re: Persistent list

2015-11-16 Thread Steven Schveighoffer via Digitalmars-d

On 11/16/15 2:37 PM, Andrei Alexandrescu wrote:

On 11/16/2015 01:55 PM, Steven Schveighoffer wrote:

On 11/16/15 1:37 PM, Andrei Alexandrescu wrote:

On 11/16/2015 12:51 PM, Steven Schveighoffer wrote:

 List tail() const


I'd like tail to be qualifier-idempotent, i.e. return const for const
and non-const for non-const. -- Andrei


Why? const(int)[] isn't const, why should List!(const(int)) be?


I'm keeping an eye toward other containers and also more general use.
It's a common need. -- Andrei


Anywhere const can work, inout should work as well. The one exception as 
I've described is when you create and build a (im)mutable result, then 
converting it to const. In this case, you have to build it at once. 
Otherwise, the compiler can't tell whether this mutable thing you are 
constructing is safe to cast to inout (and whatever flavor it needs to 
cast to upon exit).


In this case, it appears to work only because of your cast of _allocator 
to mutable whenever you access it via allocator. Other than that, the 
only other member is the node pointer, which is const. Effectively, A 
list's data is always const, so there is no reason to make the struct 
itself const.


-Steve


Re: Wanted: Review manager for std.experimental.range.ndslice

2015-11-16 Thread Ilya via Digitalmars-d

On Monday, 16 November 2015 at 19:56:01 UTC, Jack Stouffer wrote:
On Monday, 16 November 2015 at 03:05:03 UTC, Ilya Yaroshenko 
wrote:

Hello,
Review manager for N-dimensional ranges is wanted


What does the job entail?


It is very close draft:
http://wiki.dlang.org/Review/Process


Re: Wanted: Review manager for std.experimental.range.ndslice

2015-11-16 Thread Jack Stouffer via Digitalmars-d
On Monday, 16 November 2015 at 03:05:03 UTC, Ilya Yaroshenko 
wrote:

Hello,
Review manager for N-dimensional ranges is wanted


What does the job entail?


Re: Persistent list

2015-11-16 Thread Andrei Alexandrescu via Digitalmars-d

On 11/16/2015 02:07 PM, Timon Gehr wrote:

On 11/16/2015 07:37 PM, Andrei Alexandrescu wrote:

On 11/16/2015 12:51 PM, Steven Schveighoffer wrote:

 List tail() const


I'd like tail to be qualifier-idempotent, i.e. return const for const
and non-const for non-const. -- Andrei


"Qualifier-idempotent" would rather mean that taking the tail once
results in the same qualifier as taking it twice.

https://en.wikipedia.org/wiki/Idempotence


Jesus. Fine. -- Andrei



Re: Persistent list

2015-11-16 Thread Andrei Alexandrescu via Digitalmars-d

On 11/16/2015 01:55 PM, Steven Schveighoffer wrote:

On 11/16/15 1:37 PM, Andrei Alexandrescu wrote:

On 11/16/2015 12:51 PM, Steven Schveighoffer wrote:

 List tail() const


I'd like tail to be qualifier-idempotent, i.e. return const for const
and non-const for non-const. -- Andrei


Why? const(int)[] isn't const, why should List!(const(int)) be?


I'm keeping an eye toward other containers and also more general use. 
It's a common need. -- Andrei




Re: Wanted: Review manager for std.experimental.range.ndslice

2015-11-16 Thread Ilya Yaroshenko via Digitalmars-d

On Monday, 16 November 2015 at 09:56:57 UTC, Andrea Fontana wrote:
On Monday, 16 November 2015 at 03:05:03 UTC, Ilya Yaroshenko 
wrote:

Hello,
Review manager for N-dimensional ranges is wanted

Docs (see PR for latest version): 
http://dtest.thecybershadow.net/artifact/website-7a646fdea76569e009844cdee5c93edab10980ca-cdcb694c40ec47acf88b0aa878e1623e/web/phobos-prerelease/std_experimental_range_ndslice.html


PR: https://github.com/D-Programming-Language/phobos/pull/3397

DUB: http://code.dlang.org/packages/dip80-ndslice

Best Regards,
Ilya


Nice work!
If I have a matrix like

1 2
3 4

iota(4).sliced(2,2);

Is there a way to transform it to:

1 1 1 2 2 2
1 1 1 2 2 2
1 1 1 2 2 2
3 3 3 4 4 4
3 3 3 4 4 4
3 3 3 4 4 4

or

0 0 0 0 0 0
0 1 0 0 2 0
0 0 0 0 0 0
0 0 0 0 0 0
0 3 0 0 4 0
0 0 0 0 0 0

?

Of course the inverse operation seems quite easier to do using 
slices.


```
import std.algorithm, std.range, std.stdio;
auto m = iota(1, 5).sliced(2, 2);
"%(%(%s %)\n%)\n".writefln(m);

auto w = createSlice!int(6, 6);

w[1..$, 1..$].strided!0(3).strided!1(3)[] = m;
"%(%(%s %)\n%)\n".writefln(w);

foreach(i; 0..3)
foreach(j; 0..3)
w[i..$, j..$].strided!0(3).strided!1(3)[] = m;
"%(%(%s %)\n%)\n".writefln(w);
```

Prints:

1 2
3 4

0 0 0 0 0 0
0 1 0 0 2 0
0 0 0 0 0 0
0 0 0 0 0 0
0 3 0 0 4 0
0 0 0 0 0 0

1 1 1 2 2 2
1 1 1 2 2 2
1 1 1 2 2 2
3 3 3 4 4 4
3 3 3 4 4 4
3 3 3 4 4 4

--Ilya



Re: Persistent list

2015-11-16 Thread Timon Gehr via Digitalmars-d

On 11/16/2015 07:37 PM, Andrei Alexandrescu wrote:

On 11/16/2015 12:51 PM, Steven Schveighoffer wrote:

 List tail() const


I'd like tail to be qualifier-idempotent, i.e. return const for const
and non-const for non-const. -- Andrei


"Qualifier-idempotent" would rather mean that taking the tail once 
results in the same qualifier as taking it twice.


https://en.wikipedia.org/wiki/Idempotence


Re: Persistent list

2015-11-16 Thread Steven Schveighoffer via Digitalmars-d

On 11/16/15 1:37 PM, Andrei Alexandrescu wrote:

On 11/16/2015 12:51 PM, Steven Schveighoffer wrote:

 List tail() const


I'd like tail to be qualifier-idempotent, i.e. return const for const
and non-const for non-const. -- Andrei


Why? const(int)[] isn't const, why should List!(const(int)) be?

-Steve


Re: Persistent list

2015-11-16 Thread Andrei Alexandrescu via Digitalmars-d

On 11/16/2015 12:51 PM, Steven Schveighoffer wrote:

 List tail() const


I'd like tail to be qualifier-idempotent, i.e. return const for const 
and non-const for non-const. -- Andrei


Re: Persistent list

2015-11-16 Thread Steven Schveighoffer via Digitalmars-d

On 11/16/15 1:15 PM, Dmitry Olshansky wrote:

On 16-Nov-2015 19:44, Steven Schveighoffer wrote:

On 11/14/15 3:42 AM, Dmitry Olshansky wrote:

On 14-Nov-2015 02:10, Andrei Alexandrescu wrote:



* Lines 141-152: I couldn't make tail() work with inout. Generally I'm
very unhappy about inout. I don't know how to use it. Everything I read
about it is extremely complicated compared to its power. I wish we
removed it from the language and replaced it with an understandable
idiom.



I can't agree more. Every time dealing with inout when I finally think I
grok how it works the next instant I see that it doesn't do what I
expect.

For me inout inevitably stops at the boundary of being unnable to have
List!(inout(T)) and the like.


One thing we could allow is types that contain inout member variables,
but ONLY in the context of inout functions. In other words, you can
create a type for it, but can only use it in the context of an inout
function.


inout should be indistinguishable of const but the moment you pass
inout(T) to a template it becomes murky.

Appender!(inout(int)) - which qualifier to instantiate?


The idea is, you would instantiate Appender!(inout(int)) :) Should be 
fine to use inside an inout function.


The problem is, you couldn't use it outside inout, so you couldn't use 
this as the return type. But inside the function, you could use it.


Right now, you can effectively do this with arrays, since inout(T)[] 
works fine, and this can essentially map to some fictional template 
instantiation ArrayStruct!(inout(T)) (or some other way to instantiate 
ArrayStruct!T and wrap this in an attribute that means tail). But arrays 
enjoy both auto casting that tail member to other flavors, and also the 
compiler allows you to create inout arrays inside an inout function.


We can at least solve the latter pretty easily. The closer we can move 
to have an actual ArrayStruct template that works just like a real 
array, the closer we are to having a complete solution.






A List!(inout(T)) outside an inout function has no meaning. This is why
we disallowed it.

However, my belief is that it's the lack of a mechanism to apply an
attribute to the tail of some struct that prevents the most utility
here. If you returned a List!(inout(T)) there is no way to magically
convert it to a List!(const(T)) or List!(immutable(T)).

Consider that Node in this code has a "const(Node)* next" as its tail.


Note, I think I was wrong with this. The Node has a Node *next, but root 
is labelled as const.


In the end, this code is a bad example of what is wrong with inout, 
because inout shouldn't be used on it anyway.



Looks a lot like tail-const problem. That is immutable T!E has no way to
convert to T!(immutable E) and similarly to T!(const E).


It all depends on how E is used in T. Tail-const is a specific problem 
that *could* be solved if we could provide a mechanism to do this, but 
providing the mechanism isn't *required*.


-Steve


Re: Style guide is very inconsistent

2015-11-16 Thread maik klein via Digitalmars-d
On Monday, 16 November 2015 at 17:47:10 UTC, Jonathan M Davis 
wrote:

[...]


Thanks for going into so much detail.



Re: Persistent list

2015-11-16 Thread Dmitry Olshansky via Digitalmars-d

On 16-Nov-2015 19:44, Steven Schveighoffer wrote:

On 11/14/15 3:42 AM, Dmitry Olshansky wrote:

On 14-Nov-2015 02:10, Andrei Alexandrescu wrote:



* Lines 141-152: I couldn't make tail() work with inout. Generally I'm
very unhappy about inout. I don't know how to use it. Everything I read
about it is extremely complicated compared to its power. I wish we
removed it from the language and replaced it with an understandable
idiom.



I can't agree more. Every time dealing with inout when I finally think I
grok how it works the next instant I see that it doesn't do what I
expect.

For me inout inevitably stops at the boundary of being unnable to have
List!(inout(T)) and the like.


One thing we could allow is types that contain inout member variables,
but ONLY in the context of inout functions. In other words, you can
create a type for it, but can only use it in the context of an inout
function.


inout should be indistinguishable of const but the moment you pass 
inout(T) to a template it becomes murky.


Appender!(inout(int)) - which qualifier to instantiate?



A List!(inout(T)) outside an inout function has no meaning. This is why
we disallowed it.

However, my belief is that it's the lack of a mechanism to apply an
attribute to the tail of some struct that prevents the most utility
here. If you returned a List!(inout(T)) there is no way to magically
convert it to a List!(const(T)) or List!(immutable(T)).

Consider that Node in this code has a "const(Node)* next" as its tail.

I believe we should be able to achieve both.


Looks a lot like tail-const problem. That is immutable T!E has no way to 
convert to T!(immutable E) and similarly to T!(const E).


Overall I see const/immutable a fine thing at low-level scope but not 
applicable at all to high-level constructs.


If something is conceptually const - its the task of implementation 
which may rely on physical const qualifier somewhere deep inside.



-Steve



--
Dmitry Olshansky


Re: Bitfield bug

2015-11-16 Thread deadalnix via Digitalmars-d
On Monday, 16 November 2015 at 11:20:48 UTC, Lionello Lunesu 
wrote:

On 16/11/15 18:05, deadalnix wrote:

https://issues.dlang.org/show_bug.cgi?id=15305

Any taker ? I don't think this is that hard to fix, and this 
is really bad.


https://github.com/D-Programming-Language/phobos/pull/3815


<3 <3 <3 <3


Re: All functions COMDAT on OSX

2015-11-16 Thread bitwise via Digitalmars-d

On Monday, 16 November 2015 at 17:09:05 UTC, Marc Schütz wrote:

On Monday, 16 November 2015 at 14:37:33 UTC, bitwise wrote:
On Monday, 16 November 2015 at 08:15:39 UTC, Walter Bright 
wrote:

On 11/15/2015 8:44 PM, bitwise wrote:

https://issues.dlang.org/show_bug.cgi?id=15342

DMD emits all functions as COMDAT on OSX.

I'm guessing this was originally a workaround of some 
kind...does anybody know

the story?

Thanks,
 Bit


It enables:

1. the linker to remove duplicates (happens with templates 
and other things)

2. the linker to remove unreferenced COMDATs


I understand what it's for, but it's incorrect behaviour to 
have _all_ functions being emitted as comdat. Non-template 
functions shouldn't be coalesced in this way. If you compile 
the code example in the bug report with *any* compiler other 
than DMD/OSX, the example will fail as described, with a 
linker error. The example compares dmd/osx with gcc/osx, but 
the code will also fail with ldc/osx. And although I don't 
have time to check, I'm pretty sure it will fail with dmd/win 
as well.


If you look at the code I cited, this is obviously a hack:


[...]
#if TARGET_OSX
s->Sclass = SCcomdat;
#else
s->Sclass = SCglobal;
#endif
for (Dsymbol *p = fd->parent; p; p = p->parent) {
if (p->isTemplateInstance()) {
s->Sclass = SCcomdat;
break;
}
}
[...]


FWIW, that's been in the source since somewhen between 2.025 
and 2.026:

https://github.com/D-Programming-Language/dmd/commit/00337ef8d8c4c1c08da68f95963e2fe1658a49ec

Unfortunately there are no intermediate commits in the repo, 
because only released versions have been imported during the 
switch to Git.


Yeah... I'm wondering how much chaos it would cause to fix this, 
because it's a blocking issue for fixing shared libs on OSX.


To support shared libraries, I'de have to add a unique linux 
style global ctor/dtor to each module. LDC already does this. 
There is no alternative solution.


I could special case the ctor/dtors in DMD not to be COMDAT, but 
the effect would be the same as fixing the bug anyways, which 
would be that people would get linker errors if they linked(or 
are currently linking) the same module multiple times in their 
binary.


This breakage is necessary to implement shared libraries, and 
facilitate proper linking behaviour.


Bit



Re: Persistent list

2015-11-16 Thread Steven Schveighoffer via Digitalmars-d

On 11/16/15 12:42 PM, Steven Schveighoffer wrote:

On 11/16/15 12:35 PM, Steven Schveighoffer wrote:


I'm afraid without a working example, I can't figure out what's
*supposed* to work with inout/const.



Update, saw your other note. Working now, trying to figure out how to do
this correctly without any duplication (or wrapping).

-Steve



OK, I have figured it out.

inout isn't necessary here at all because everything is const internally.

For example, you had this:

List tail()
{
assert(root);
auto n = root.next;
incRef(n);
return List(n, allocator);
}
/// ditto
const(List) tail() const
{
assert(root);
auto n = root.next;
incRef(n);
return const(List)(n, allocator);
}

Which I was able to replace with this:

List tail() const
{
assert(root);
auto n = root.next;
incRef(n);
return List(n, allocator);
}

In any case, I think the choice between const and inout is confusing, 
and warrants a more in-depth explanation (when should I choose const or 
inout?)


-Steve


Re: Style guide is very inconsistent

2015-11-16 Thread Jonathan M Davis via Digitalmars-d

On Monday, 16 November 2015 at 16:42:57 UTC, maik klein wrote:
On Monday, 16 November 2015 at 14:26:41 UTC, Jonathan M Davis 
wrote:

On Monday, 16 November 2015 at 14:09:45 UTC, maik klein wrote:

[...]


Per the style guide,

=
Eponymous Templates

[...]


Okay thanks, but I am still not sure about my example.

I am pretty sure that at least "any" should be camel case 
because it's a value, but what about "Contains"? It's neither a 
type nor a eponymous template. My guess is that it should also 
be camel case?


So it would be contains!C.any!T ?


Okay. Your Any template should clearly be camelCased, because its 
result is a bool. The same goes for ContainsImpl. Contains is a 
weird one though. It's pretty abnormal to use a template that's 
not a type, a function, an eponymous template, or a mixin 
template. Contains doesn't actually evaluate to anything on its 
own. It seems like it's just there so that you can have two sets 
of variadic arguments, which would tend to imply that it should 
be camelCased as part of any. However, the style guide says that 
non-eponymous templates should be PascalCased (though that 
_usually_ only applies to mixin templates), so a strict reading 
of the style guide would indicate that Contains should be 
PascalCased.


Of course, using a verb like contains is also a bit weird when 
it's really just holding a list of types so that they can 
essentially be passed as the first argument to any. So, I'd 
probably be inclined to rename the templates to something that 
was closer to what they're actually doing. e.g.


TypeList!(T, U, V).containsAny!(W, X, Y)

But even that's not all that great, since TypeList is then 
specifically tied to containsAny even though it doesn't really 
look like it is at first glance, and the name TypeList is generic 
enough that it does seem like you might want to reuse it 
elsewhere when it really couldn't be. Maybe


ContainsList!(T, U, V).containsAny(W, X, Y)

would be better? I don't know. Coming up with a name for this is 
hard. What you really want is something like


listsIntersect!((T, U, V), (W, X, Y))

or

ListsIntersect!(AliasSeq!(T, U, V), AliasSeq!(W, X, Y))

but there's no way to express it that like that in D (the 
AliasSeqs auto-expand into a single AliasSeq). The requirement 
for two sets of variadic template arguments just makes this 
awkward.


In any case, a strict reading of the style guide would seem to 
indicate that Contains should be PascalCased, because it's not an 
eponymous template, but given how rare what you're trying to do 
is, I doubt that much of anyone would complain if you used 
camelCase instead. I'd probably go with PascalCase though.


- Jonathan M Davis


Re: Persistent list

2015-11-16 Thread Steven Schveighoffer via Digitalmars-d

On 11/16/15 12:35 PM, Steven Schveighoffer wrote:


I'm afraid without a working example, I can't figure out what's
*supposed* to work with inout/const.



Update, saw your other note. Working now, trying to figure out how to do 
this correctly without any duplication (or wrapping).


-Steve



Re: Persistent list

2015-11-16 Thread Steven Schveighoffer via Digitalmars-d

On 11/16/15 11:03 AM, Steven Schveighoffer wrote:

On 11/14/15 10:44 AM, Andrei Alexandrescu wrote:


That doesn't work for me with my unittests, I get:



I'm such an idiot, I depended on dpaste to run the unit test, but forgot
to check the unit test button.

So technically, my updated version *parses* correctly :)

Looking in more depth...



I can't get your original code to work, so it's hard for me to figure 
out what is wrong. Using 2.069.1, I have the following error (after 
factoring out `either`, which I'm assuming is a new function):


Stevens-MacBook-Pro:testd steves$ dmd -unittest persistent_list.d
/Users/steves/.dvm/compilers/dmd-2.069.1/osx/bin/../../src/phobos/std/conv.d(4161): 
Error: template std.conv.emplaceImpl!(const(Node)).emplaceImpl cannot 
deduce function from argument types !()(const(Node), immutable(int), 
const(Node)*, int), candidates are:
/Users/steves/.dvm/compilers/dmd-2.069.1/osx/bin/../../src/phobos/std/conv.d(3932): 
   std.conv.emplaceImpl!(const(Node)).emplaceImpl()(ref UT chunk)
/Users/steves/.dvm/compilers/dmd-2.069.1/osx/bin/../../src/phobos/std/conv.d(4037): 
   std.conv.emplaceImpl!(const(Node)).emplaceImpl(Args...)(ref UT 
chunk, auto ref Args args)
/Users/steves/.dvm/compilers/dmd-2.069.1/osx/bin/../../src/phobos/std/conv.d(5087): 
Error: template instance std.conv.emplace!(const(Node), immutable(int), 
const(Node)*, int) error instantiating
persistent_list.d(169):instantiated from here: 
emplace!(const(Node), immutable(int), const(Node)*, int)

persistent_list.d(195):instantiated from here: opBinaryRight!"~"
persistent_list.d(266):instantiated from here: List!(immutable(int))

However, examining the code, I think you don't even need inout here, 
just a const function will do fine, since nothing on the original is 
changing, and all your nodes are flavored as pointing to const nodes.


I see you have updated the code, and that doesn't work for me either.

I'm afraid without a working example, I can't figure out what's 
*supposed* to work with inout/const.


-Steve



Re: Persistent list

2015-11-16 Thread Andrei Alexandrescu via Digitalmars-d

On 11/16/2015 11:58 AM, Steven Schveighoffer wrote:

On 11/15/15 2:09 PM, Andrei Alexandrescu wrote:

On 11/13/2015 06:10 PM, Andrei Alexandrescu wrote:
[snip]

Thanks all for the feedback. I've uploaded an updated version to
http://dpaste.dzfl.pl/52a3013efe34. It doesn't use "inout", but doesn't
duplicate code either; instead, it relies on private internal functions
to do the deed.


This still doesn't compile for me.


You need my emplace bugfixes, so get the latest toolchain. -- Andrei



Re: Persistent list

2015-11-16 Thread Andrei Alexandrescu via Digitalmars-d

On 11/16/2015 11:58 AM, Lionello Lunesu wrote:

On 16/11/15 22:45, Andrei Alexandrescu wrote:

On 11/16/2015 08:51 AM, Marc Schütz wrote:

On Monday, 16 November 2015 at 02:26:29 UTC, Andrei Alexandrescu
wrote:

Yah, I agree with that argument. Probably @mutable is a more
principled way to go about things.


Glad to here that. I think the current transitive const system
is really good and shouldn't be watered down beyond necessity.
And a @mutable keyword, too, shouldn't just mean "immutability
or const-ness end here", thus allowing any kind of mutation. What
we actually need for immutable/const refcounting etc. is
_non-observable mutation_, i.e. physical mutability, but without
observable effects outside of the type's implementation (better
yet, restricted to very short parts of it, just like @trusted).


The challenge is proving that a mutation is not observable. Got an
 attack on that? -- Andrei


Forgive me, I haven't followed the RC discussions closely, so I miss
a lot of context. Feel free to point me to existing
threads/articles.


The best place to start for absorbing context is look at the casts in
http://dpaste.dzfl.pl/52a3013efe34, understand the necessity of each,
and figure out how they can be either made legal or (preferably) eliminated.


If it's RC we want, then @mutable is an axe when what we need is a
scalpel.


There's more than RC in there.


Andrei




Re: Persistent list

2015-11-16 Thread Andrei Alexandrescu via Digitalmars-d

On 11/16/2015 11:03 AM, Steven Schveighoffer wrote:

On 11/14/15 10:44 AM, Andrei Alexandrescu wrote:


That doesn't work for me with my unittests, I get:



I'm such an idiot, I depended on dpaste to run the unit test, but forgot
to check the unit test button.

So technically, my updated version *parses* correctly :)

Looking in more depth...


Thanks for letting us know. -- Andrei



Re: Persistent list

2015-11-16 Thread Steven Schveighoffer via Digitalmars-d

On 11/15/15 9:54 AM, Andrei Alexandrescu wrote:

On 11/15/2015 09:34 AM, Dicebot wrote:

On Sunday, 15 November 2015 at 14:23:05 UTC, Jonathan M Davis wrote:

As I mentioned, he's okay with changing the language to make the
casts well defined. -- Andrei


Well, that's a big change, since it pretty much means that D's const
isn't physical const anymore, and Walter has been _very_ insistent
about that in the past - to the point that he's argued that C++'s
const is outright useless because it isn't physical const. If casting
away const and mutating is well-defined behavior, then we basically
have C++'s const except that it's transitive ...


Casting away _const_ is already legal if programmer can himself
guarantee underlying object has mutable origin (i.e. not available via
immutable reference), by the very definition of const. It is casting
away immutable and mutating that is strictly UB.


Correct. I'm not sure whether that's clarified in the language
documentation yet. -- Andrei


I argued this way, and eventually lost. I don't think it's feasible to 
have a const that can be cast away, and have optimizations based on 
const or pure.


See this discussion:

forum.dlang.org/post/riiehqozpkyluhhif...@forum.dlang.org

One thing, however, is that if you can mark an island of space within an 
object as ALWAYS mutable, the compiler can know this and avoid 
optimizing away access to those pieces. It would have to be clearly 
marked as such, so the optimizations on non-marked data could still happen.


I think it could be done, because logical const is possible via a global 
lookup table. Any time you go through a cast, however, this could easily 
break down. I hate to say it, but you would likely need another modifier 
like "tainted const" or something in order for that to work.


-Steve


Re: All functions COMDAT on OSX

2015-11-16 Thread Marc Schütz via Digitalmars-d

On Monday, 16 November 2015 at 14:37:33 UTC, bitwise wrote:
On Monday, 16 November 2015 at 08:15:39 UTC, Walter Bright 
wrote:

On 11/15/2015 8:44 PM, bitwise wrote:

https://issues.dlang.org/show_bug.cgi?id=15342

DMD emits all functions as COMDAT on OSX.

I'm guessing this was originally a workaround of some 
kind...does anybody know

the story?

Thanks,
 Bit


It enables:

1. the linker to remove duplicates (happens with templates and 
other things)

2. the linker to remove unreferenced COMDATs


I understand what it's for, but it's incorrect behaviour to 
have _all_ functions being emitted as comdat. Non-template 
functions shouldn't be coalesced in this way. If you compile 
the code example in the bug report with *any* compiler other 
than DMD/OSX, the example will fail as described, with a linker 
error. The example compares dmd/osx with gcc/osx, but the code 
will also fail with ldc/osx. And although I don't have time to 
check, I'm pretty sure it will fail with dmd/win as well.


If you look at the code I cited, this is obviously a hack:


[...]
#if TARGET_OSX
s->Sclass = SCcomdat;
#else
s->Sclass = SCglobal;
#endif
for (Dsymbol *p = fd->parent; p; p = p->parent) {
if (p->isTemplateInstance()) {
s->Sclass = SCcomdat;
break;
}
}
[...]


FWIW, that's been in the source since somewhen between 2.025 and 
2.026:

https://github.com/D-Programming-Language/dmd/commit/00337ef8d8c4c1c08da68f95963e2fe1658a49ec

Unfortunately there are no intermediate commits in the repo, 
because only released versions have been imported during the 
switch to Git.


Re: And in the (quasi-)comedy section…

2015-11-16 Thread Marc Schütz via Digitalmars-d

On Monday, 16 November 2015 at 14:33:26 UTC, Russel Winder wrote:

A quote from @SarcasticRover:


New studies show that Mars' moon Phobos is slowly breaking up 
under pressure… but really, who isn't? Life is hard.


You know, I saw this piece of news, but refrained from making a 
comment here. Though it was tempting :-P


Re: Persistent list

2015-11-16 Thread Lionello Lunesu via Digitalmars-d

On 16/11/15 22:45, Andrei Alexandrescu wrote:

On 11/16/2015 08:51 AM, Marc Schütz wrote:

On Monday, 16 November 2015 at 02:26:29 UTC, Andrei Alexandrescu wrote:

Yah, I agree with that argument. Probably @mutable is a more
principled way to go about things.


Glad to here that. I think the current transitive const system is really
good and shouldn't be watered down beyond necessity. And a @mutable
keyword, too, shouldn't just mean "immutability or const-ness end here",
thus allowing any kind of mutation. What we actually need for
immutable/const refcounting etc. is _non-observable mutation_, i.e.
physical mutability, but without observable effects outside of the
type's implementation (better yet, restricted to very short parts of it,
just like @trusted).


The challenge is proving that a mutation is not observable. Got an
attack on that? -- Andrei


Forgive me, I haven't followed the RC discussions closely, so I miss a 
lot of context. Feel free to point me to existing threads/articles.


If it's RC we want, then @mutable is an axe when what we need is a scalpel.

The non-observability comes from the fact the refcount is changed when 
the caller has lost its (const) reference and constness is a moot point. 
Changing refcount is fine now, provided the object is not immutable. As 
far as other outstanding const references go, these already expect 
changes to happen.


This is what makes refcount special and provably safe to mutate. As long 
as we can ensure the object is not immutable, the object is allowed to 
change its own refcount. But refcount needs to be special cased, 
somehow, or else we'll end up with some C++ like `mutable`.


Perhaps const-but-not-pure is the solution here. The object must be able 
to store (and have stored) a mutable reference, so it can use that 
reference to change the refcount. (This could be optimized to be a flag, 
since the mutable and const reference would refer to the same instance.) 
It means keeping track of const-but-mutable vs const-and-immutable 
references, and somehow telling the compiler that refcount is special.


L.


Re: Persistent list

2015-11-16 Thread Steven Schveighoffer via Digitalmars-d

On 11/15/15 2:09 PM, Andrei Alexandrescu wrote:

On 11/13/2015 06:10 PM, Andrei Alexandrescu wrote:
[snip]

Thanks all for the feedback. I've uploaded an updated version to
http://dpaste.dzfl.pl/52a3013efe34. It doesn't use "inout", but doesn't
duplicate code either; instead, it relies on private internal functions
to do the deed.


This still doesn't compile for me.


While revising feedback I realized I'd missed Steve's version that works
with inout: http://dpaste.dzfl.pl/3fbc786a50c1. It works and the
inout-related parts don't look difficult; the only thing is making sure
the right incantations are in place, and that's the difficult part.


I would say the difficult part is figuring out the incantations from the 
given error messages. When you are depending on something to compile 
because it can call a template function, it's often difficult to figure 
out where it went wrong. The error messages are frequently unhelpful.


inout is actually pretty simple to use. It has a couple of severe 
limitations that make it difficult to work with in certain situations -- 
one of them being composition (you can't compose a type with inout 
members). We can work on fixing these problems.



So one important question is what style we use for Phobos and endorse as
idiomatic. My sense after working on this for a while is - forget inout.
Qualifiers are rather complex, and of them inout is the most. So I'd
rather marginalize it. Please chime in with any thoughts.


I disagree. inout is no more complex than const in most cases. In my 
experience changing to inout is simply changing the term "const" to 
"inout", and everything pretty much works. This was my experience when 
updating dcollections after inout was finally made to work.


I'm going to work on writing an article about inout. It frequently 
confuses the shit out of everyone who uses it, and I don't think it should.


-Steve


Re: Persistent list

2015-11-16 Thread Steven Schveighoffer via Digitalmars-d

On 11/14/15 3:42 AM, Dmitry Olshansky wrote:

On 14-Nov-2015 02:10, Andrei Alexandrescu wrote:



* Lines 141-152: I couldn't make tail() work with inout. Generally I'm
very unhappy about inout. I don't know how to use it. Everything I read
about it is extremely complicated compared to its power. I wish we
removed it from the language and replaced it with an understandable
idiom.



I can't agree more. Every time dealing with inout when I finally think I
grok how it works the next instant I see that it doesn't do what I expect.

For me inout inevitably stops at the boundary of being unnable to have
List!(inout(T)) and the like.


One thing we could allow is types that contain inout member variables, 
but ONLY in the context of inout functions. In other words, you can 
create a type for it, but can only use it in the context of an inout 
function.


A List!(inout(T)) outside an inout function has no meaning. This is why 
we disallowed it.


However, my belief is that it's the lack of a mechanism to apply an 
attribute to the tail of some struct that prevents the most utility 
here. If you returned a List!(inout(T)) there is no way to magically 
convert it to a List!(const(T)) or List!(immutable(T)).


Consider that Node in this code has a "const(Node)* next" as its tail.

I believe we should be able to achieve both.

-Steve


Re: Style guide is very inconsistent

2015-11-16 Thread maik klein via Digitalmars-d
On Monday, 16 November 2015 at 14:26:41 UTC, Jonathan M Davis 
wrote:

On Monday, 16 November 2015 at 14:09:45 UTC, maik klein wrote:

[...]


Per the style guide,

=
Eponymous Templates

[...]


Okay thanks, but I am still not sure about my example.

I am pretty sure that at least "any" should be camel case because 
it's a value, but what about "Contains"? It's neither a type nor 
a eponymous template. My guess is that it should also be camel 
case?


So it would be contains!C.any!T ?



Re: Persistent list

2015-11-16 Thread Steven Schveighoffer via Digitalmars-d

On 11/14/15 10:44 AM, Andrei Alexandrescu wrote:


That doesn't work for me with my unittests, I get:



I'm such an idiot, I depended on dpaste to run the unit test, but forgot 
to check the unit test button.


So technically, my updated version *parses* correctly :)

Looking in more depth...

-Steve



Re: opDispatch and compile time parameters

2015-11-16 Thread Steven Schveighoffer via Digitalmars-d

On 11/14/15 12:18 AM, Jakob Ovrum wrote:

On Saturday, 14 November 2015 at 04:10:59 UTC, Steven Schveighoffer wrote:

Is it me, or is this a bug?

struct Foo
{
   template opDispatch(string s) {
  // if you uncomment this, it compiles
  //void opDispatch() {}
  void opDispatch(T...)() {}
   }
}

void main()
{
   Foo f;
   f.blue!char(); // Error: no property 'blue' for type 'Foo'
}


Usually you should explicitly instantiate opDispatch to see the real
error message(s) that prevented opDispatch from being used, but in this
case I can't find a way to do that. `f.opDispatch!("blue")!char()` is
syntactically invalid, and aliasing doesn't work either: `alias t =
f.opDispatch!"blue"; t!char(); // Error: need `this` for opDispatch`. I
wonder what the real error is.



It appears that you can't directly access the eponymous member, this 
doesn't work:


f.opDispatch!("blue").opDispatch!(char)();

Error: no property 'opDispatch' for type 'void'

Perhaps that fact that it *works* when you have the non-template version 
as the first member is the bug ;)


In any case, I have used Jack Applegame's improved version, and it works 
beautifully!


-Steve


Re: Persistent list

2015-11-16 Thread Jonathan M Davis via Digitalmars-d
On Monday, 16 November 2015 at 08:18:55 UTC, Jonathan M Davis 
wrote:
And actually, this gives me an interesting thought. Does making 
casting away const and mutating defined behavior give us a way 
to fix our postblit problem? I could see an argument that 
postblits should be completely unnecessary for immutable values 
(because you shouldn't need to avoid stuff like sharing 
references when it's immutable), which could mean that we could 
change it so that immutable structs values didn't trigger a 
postblit and thus worked fine as-is, and that would fix the 
problem with postblits and immutable. And if casting away const 
and mutating is legit, then it should be possible to treat the 
struct itself as mutable (or at least tail-const) within the 
postblit constructor, in which case it's then actually possible 
to have postblit constructor that works with const, whereas 
right now, we can't have it, because it would violate const to 
mutate the newly blitted, const struct.


So, if this really fixes our postblit problem, it might be 
worth it just for that. As it stands, postblit constuctors tend 
to have to be avoided in many cases because of how badly they 
interact with const and immutable.


Actually, with regards to immutable, it looks like you can 
already copy immutable objects with postblit constructors. You 
just can't copy it and get a mutable value out of it. But copying 
and creating another immutable value or a const value both work 
just fine. So, it looks like the only thing we're missing with 
regards to immutable and postblits is the ability to get a 
mutable copy, but that's not really much of a loss as far as I 
can think of at the moment.


So, really it's just the issue with const and postblit that 
really needs fixing, and allowing the mutation of const to be 
defined behavior when the underlying object isn't immutable could 
give us the out we need to fix that problem.


- Jonathan M Davis


Re: Persistent list

2015-11-16 Thread Ola Fosheim Grøstad via Digitalmars-d

On Monday, 16 November 2015 at 14:08:23 UTC, Atila Neves wrote:
You described immutable, not const. If one thread has a const 
reference, it's entirely possible another thread has a mutable 
reference.


Are you sure that this is a well defined situation? What is the 
point of having "const" if "shared const" is the exact same thing?


Immutable should never ever change for any reason, because the 
compiler should be able to cache derived values.




Re: Persistent list

2015-11-16 Thread Jonathan M Davis via Digitalmars-d
On Monday, 16 November 2015 at 14:45:35 UTC, Andrei Alexandrescu 
wrote:

On 11/16/2015 08:51 AM, Marc Schütz wrote:
On Monday, 16 November 2015 at 02:26:29 UTC, Andrei 
Alexandrescu wrote:

Yah, I agree with that argument. Probably @mutable is a more
principled way to go about things.


Glad to here that. I think the current transitive const system 
is really
good and shouldn't be watered down beyond necessity. And a 
@mutable
keyword, too, shouldn't just mean "immutability or const-ness 
end here",

thus allowing any kind of mutation. What we actually need for
immutable/const refcounting etc. is _non-observable mutation_, 
i.e.
physical mutability, but without observable effects outside of 
the
type's implementation (better yet, restricted to very short 
parts of it,

just like @trusted).


The challenge is proving that a mutation is not observable. Got 
an attack on that? -- Andrei


That would be a neat trick. As I recall, previous discussions on 
logical const concluded that there was no way to implement it in 
a way that guaranteed that it was actually logical const as 
opposed to just being mutated in spite of being const. But it 
would be _very_ cool if someone figured out how to do it.


Still, even without that guarantee, using something like @mutable 
rather than casting would be far safer - especially if the type 
system can guarantee that such an object can't be immutable.


- Jonathan M Davis


Re: Persistent list

2015-11-16 Thread Jonathan M Davis via Digitalmars-d

On Monday, 16 November 2015 at 14:08:23 UTC, Atila Neves wrote:
You described immutable, not const. If one thread has a const 
reference, it's entirely possible another thread has a mutable 
reference.


Only if it's shared, or you've screwed up with casting and ended 
up with an object which is actually shared being treated as TLS. 
A const, non-shared object can't possibly be mutated while you're 
doing stuff to it unless that same code somehow has access to a 
mutable reference to the same data. And in most cases 
(particularly if you're using pure heavily), it won't have access 
to any other references to the same data, so you can usually rely 
on a const object not being mutated while you operate on it.


- Jonathan M Davis


Re: Persistent list

2015-11-16 Thread Andrei Alexandrescu via Digitalmars-d

On 11/16/2015 08:51 AM, Marc Schütz wrote:

On Monday, 16 November 2015 at 02:26:29 UTC, Andrei Alexandrescu wrote:

Yah, I agree with that argument. Probably @mutable is a more
principled way to go about things.


Glad to here that. I think the current transitive const system is really
good and shouldn't be watered down beyond necessity. And a @mutable
keyword, too, shouldn't just mean "immutability or const-ness end here",
thus allowing any kind of mutation. What we actually need for
immutable/const refcounting etc. is _non-observable mutation_, i.e.
physical mutability, but without observable effects outside of the
type's implementation (better yet, restricted to very short parts of it,
just like @trusted).


The challenge is proving that a mutation is not observable. Got an 
attack on that? -- Andrei


Re: All functions COMDAT on OSX

2015-11-16 Thread bitwise via Digitalmars-d

On Monday, 16 November 2015 at 08:15:39 UTC, Walter Bright wrote:

On 11/15/2015 8:44 PM, bitwise wrote:

https://issues.dlang.org/show_bug.cgi?id=15342

DMD emits all functions as COMDAT on OSX.

I'm guessing this was originally a workaround of some 
kind...does anybody know

the story?

Thanks,
 Bit


It enables:

1. the linker to remove duplicates (happens with templates and 
other things)

2. the linker to remove unreferenced COMDATs


I understand what it's for, but it's incorrect behaviour to have 
_all_ functions being emitted as comdat. Non-template functions 
shouldn't be coalesced in this way. If you compile the code 
example in the bug report with *any* compiler other than DMD/OSX, 
the example will fail as described, with a linker error. The 
example compares dmd/osx with gcc/osx, but the code will also 
fail with ldc/osx. And although I don't have time to check, I'm 
pretty sure it will fail with dmd/win as well.


If you look at the code I cited, this is obviously a hack:


[...]
#if TARGET_OSX
s->Sclass = SCcomdat;
#else
s->Sclass = SCglobal;
#endif
for (Dsymbol *p = fd->parent; p; p = p->parent) {
if (p->isTemplateInstance()) {
s->Sclass = SCcomdat;
break;
}
}
[...]

Bit


And in the (quasi-)comedy section…

2015-11-16 Thread Russel Winder via Digitalmars-d
A quote from @SarcasticRover:


New studies show that Mars' moon Phobos is slowly breaking up under
pressure… but really, who isn't? Life is hard.


-- 
Russel.
=
Dr Russel Winder  t: +44 20 7585 2200   voip: sip:russel.win...@ekiga.net
41 Buckmaster Roadm: +44 7770 465 077   xmpp: rus...@winder.org.uk
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder



signature.asc
Description: This is a digitally signed message part


Re: Style guide is very inconsistent

2015-11-16 Thread Jonathan M Davis via Digitalmars-d

On Monday, 16 November 2015 at 14:09:45 UTC, maik klein wrote:

Why are the variadics written in lower case?


Per the style guide,

=
Eponymous Templates

Templates which have the same name as a symbol within that 
template (and instantiations of that template are therefore 
replaced with that symbol) should be capitalized in the same way 
that that inner symbol would be capitalized if it weren't in a 
template - e.g. types should be PascalCased and values should be 
camelCased.

=

So, whether an eponymous template is camelCased or PascalCased 
depends entirely on what its result is. It's quite possible that 
there are older symbols in Phobos that don't follow those 
guidelines, but most do. However, there are some where it's not 
clear which it should be.


e.g. std.meta.Filter is a funny one, because it works with any 
symbol - be it a type or a value - so it could have gone either 
way, but it was probably targeted primarily at types, so it ended 
up with its name being PascalCased.


But in general, an eponymous template which results in a type is 
supposed to be PascalCased, whereas the others are supposed to be 
camelCased.


Really, pretty much anything that isn't a type is camelCased, 
whereas types are PascalCased. It's just that there a few cases 
that are inherently ambiguous, and there may be some older 
symbols in Phobos which don't properly follow the current style 
guide.


- Jonathan M Davis


Style guide is very inconsistent

2015-11-16 Thread maik klein via Digitalmars-d
I am a very new D user and I almost always try to mirror the 
"official" style guide if one is available.


http://dlang.org/dstyle.html

I have written the following function

template Contains(C...){
  template Any(T...){
import std.meta: anySatisfy;
static if(T.length == 0){
  enum Any = false;
}
else{
  enum Any = ContainsImpl!T;
}
template ContainsImpl(T...){
  enum bool isSameComponent(Comp) = is(Comp == T[0]);
  static if(T.length == 1){
enum ContainsImpl = anySatisfy!(isSameComponent,C);
  }
  else{
enum ContainsImpl = anySatisfy!(isSameComponent,C) && 
ContainsImpl!(T[1..$]);

  }
}
  }
}


No idea how I should type it contains!c.any!T or contains!c.Any!T

Which lead me to have a look at phobos

For example

template Filter(alias pred, TList...)

vs

template anySatisfy(alias F, T...)

Are aliases now written in upper or lower camelCase? Should I use 
T... or TList... for variadics if I can't name them better?


or

private template GenericReplace(args...)

Why are the variadics written in lower case?



Re: Persistent list

2015-11-16 Thread Atila Neves via Digitalmars-d
On Monday, 16 November 2015 at 09:42:43 UTC, Ola Fosheim Grøstad 
wrote:
On Monday, 16 November 2015 at 09:04:33 UTC, Joseph Cassman 
wrote:

[...]


The D designers might want to look at Pony lang's capability 
system, which has been proven sound. It has 6 different 
aliasing capabilites that regulates among other things 
transition from mutable to immutable.


D is a little bit better of (if it does not allow casting away 
const) than C++, because in C++ const is essentially "shared 
const", whereas in D in is "local const with potential 
aliasing". AFAIK the D sementics is that no other thread can 
hold a mutable reference to something you have as const. But it 
is still a relatively weak guarantee. In C you have 
"restricted" for notifying the compiler that the resource is 
aliasing free within the context.


You described immutable, not const. If one thread has a const 
reference, it's entirely possible another thread has a mutable 
reference.


Atila


Re: Persistent list

2015-11-16 Thread Marc Schütz via Digitalmars-d
On Monday, 16 November 2015 at 02:26:29 UTC, Andrei Alexandrescu 
wrote:
Yah, I agree with that argument. Probably @mutable is a more 
principled way to go about things.


Glad to here that. I think the current transitive const system is 
really good and shouldn't be watered down beyond necessity. And a 
@mutable keyword, too, shouldn't just mean "immutability or 
const-ness end here", thus allowing any kind of mutation. What we 
actually need for immutable/const refcounting etc. is 
_non-observable mutation_, i.e. physical mutability, but without 
observable effects outside of the type's implementation (better 
yet, restricted to very short parts of it, just like @trusted).


Re: Persistent list

2015-11-16 Thread Marc Schütz via Digitalmars-d

On Sunday, 15 November 2015 at 20:23:58 UTC, Dicebot wrote:
On Friday, 13 November 2015 at 23:10:04 UTC, Andrei 
Alexandrescu wrote:
I created a simple persistent list with reference counting and 
custom allocation at http://dpaste.dzfl.pl/0981640c2835.



There is also another thing I wanted to mention on topic of 
persistent containers. Right now for me the most intriguing 
topic is trying to define immutable (and actually thread 
shared) cache data structure than can be efficiently and safely 
used without GC. There is whole class of tasks where you can 
get best performance by building new copy of cache in memory 
instead of modifying separate elements, trading increased 
memory concsumption for fast no lock parallel access. However 
in absence of GC task of deleting memory for older generations 
of cache becomes rather challenging. I have been thinking about 
approach with external two-level reference counting + dedicated 
allocator - quick thread-local RC comes first and once it goes 
to 0, shared RC in allocator gets decremented (being effetively 
user thread counter). Do you think it can work?


If the elements are immutable, you can actually write a parallel 
non-stop-the-world GC for your cache. You just need to record the 
"age" of each element, and define a grace period that must have 
passed before they can be freed.


As for your RC idea: You could either start by creating the 
objects as shared and add a `.unshare()` method to them, or start 
with thread-local objects and create the shared RC lazily 
(`.share()`).


Re: RFC in Comparison between Rust, D and Go

2015-11-16 Thread Jacob Carlborg via Digitalmars-d

On 2015-11-14 07:31, Sergey Korshunoff via Digitalmars-d wrote:


PS: you just say that C is not suitable for the system programming


Well, he is the creator of D ;)

--
/Jacob Carlborg


Re: Bitfield bug

2015-11-16 Thread Lionello Lunesu via Digitalmars-d

On 16/11/15 18:05, deadalnix wrote:

https://issues.dlang.org/show_bug.cgi?id=15305

Any taker ? I don't think this is that hard to fix, and this is really bad.


https://github.com/D-Programming-Language/phobos/pull/3815


Re: Our template emission strategy is broken

2015-11-16 Thread deadalnix via Digitalmars-d
On Saturday, 14 November 2015 at 03:43:38 UTC, Walter Bright 
wrote:

On 11/13/2015 9:23 AM, Johannes Pfau wrote:

Ellery filed a bug report and I've posted a reduced test case:

https://issues.dlang.org/show_bug.cgi?id=15324


Thank you!


https://issues.dlang.org/show_bug.cgi?id=15333

Also, thanks to whoever was able to reduce it more than I.


Bitfield bug

2015-11-16 Thread deadalnix via Digitalmars-d

https://issues.dlang.org/show_bug.cgi?id=15305

Any taker ? I don't think this is that hard to fix, and this is 
really bad.


Re: Wanted: Review manager for std.experimental.range.ndslice

2015-11-16 Thread Andrea Fontana via Digitalmars-d
On Monday, 16 November 2015 at 03:05:03 UTC, Ilya Yaroshenko 
wrote:

Hello,
Review manager for N-dimensional ranges is wanted

Docs (see PR for latest version): 
http://dtest.thecybershadow.net/artifact/website-7a646fdea76569e009844cdee5c93edab10980ca-cdcb694c40ec47acf88b0aa878e1623e/web/phobos-prerelease/std_experimental_range_ndslice.html


PR: https://github.com/D-Programming-Language/phobos/pull/3397

DUB: http://code.dlang.org/packages/dip80-ndslice

Best Regards,
Ilya


Nice work!
If I have a matrix like

1 2
3 4

iota(4).sliced(2,2);

Is there a way to transform it to:

1 1 1 2 2 2
1 1 1 2 2 2
1 1 1 2 2 2
3 3 3 4 4 4
3 3 3 4 4 4
3 3 3 4 4 4

or

0 0 0 0 0 0
0 1 0 0 2 0
0 0 0 0 0 0
0 0 0 0 0 0
0 3 0 0 4 0
0 0 0 0 0 0

?

Of course the inverse operation seems quite easier to do using 
slices.




Re: Our template emission strategy is broken

2015-11-16 Thread Tofu Ninja via Digitalmars-d
On Wednesday, 11 November 2015 at 13:08:08 UTC, David Nadlinger 
wrote:

...


Sorry I haven't read this whole thread so maybe this has been 
mentioned before or not. I am not even sure if its really related 
to this topic, but it seemed related to me so I figured I would 
just post it here rather than make a new thread.


ModuleInfo.localClasses doesn't list template class instances. I 
just ran into this(like 5 min ago) and thought it was odd. I 
expected it too list template instances as well so I thought it 
might be a bug, not really sure. Thankfully I don't really need 
it to list template instances of classes so it not affecting my 
project, but I could see it being a problem for others.


Re: Persistent list

2015-11-16 Thread Ola Fosheim Grøstad via Digitalmars-d

On Monday, 16 November 2015 at 09:04:33 UTC, Joseph Cassman wrote:
Just as a side thought, although it is probably a bit of a 
dasoku. But I have always wondered that if the purpose of 
_const_ is to allow some data to be changed by one reference 
but not changed by another, then why is it transitive. Doesn't 
that defeat its purpose?


The D designers might want to look at Pony lang's capability 
system, which has been proven sound. It has 6 different aliasing 
capabilites that regulates among other things transition from 
mutable to immutable.


D is a little bit better of (if it does not allow casting away 
const) than C++, because in C++ const is essentially "shared 
const", whereas in D in is "local const with potential aliasing". 
AFAIK the D sementics is that no other thread can hold a mutable 
reference to something you have as const. But it is still a 
relatively weak guarantee. In C you have "restricted" for 
notifying the compiler that the resource is aliasing free within 
the context.


And then doesn't transitive const effectively have the same 
semantics and use-case as _immutable_? I mean, once you start 
to use transitive const in an interface, how are you supposed 
to get the mutable reference that is so promised? Perhaps this 
is the question that is essentially being asked here?


The right thing to do is to:

1. map out all possible aliasing combinations and pick a set of 
capabilities that is sound


2. poke a clean well defined hole through the constness by 
allowing a "mutable" modifier that does not depend on type state. 
(or you should add type state and an effect system).


3. implement something that is compatible with conservative C++ 
(shared head const with mutable fields and no const_cast).


D really should try to avoid repeating C++'s mistakes or add a 
different set of mistakes, in order to compensate for former 
mistakes.




Re: [Poll] On Linux, what should we commonly use as sub-directory name for D?

2015-11-16 Thread Iain Buclaw via Digitalmars-d
On 16 November 2015 at 09:30, Marco Leise via Digitalmars-d <
digitalmars-d@puremagic.com> wrote:

> Am Mon, 16 Nov 2015 08:49:57 +0100
> schrieb Iain Buclaw via Digitalmars-d
> :
>
> > There should be ways to catch ABI changes in the build or test process.
> > Maybe I'm misremembering something though. :-)
> >
> > There should be a degree of ABI compatibility between releases for plain
> > static functions - assuming that we add no more properties to the
> > language.  That leaves what breaks the most in moving to a new version
> are
> > template instantiations, no?
>
> Frankly I have no idea what level of testing is in place. :D
> To be practical for package maintainers, we would need some
> higher level common D ABI versioning scheme that includes
> Phobos. Then I could start grouping libraries by architecture
> and this ABI version instead of by compiler/FE version. But
> let's take baby steps here and first get DMD to use DWARF EH.
> Once we can dynamically link DMD<->GDC, DMD<->LDC, we can
> think about a stable Dlang ABI in terms of EH, function
> mangling, Phobos etc.
>

A good litmus test would be to take the C++ ABI tests in the D2 testsuite,
and convert the C++ sources to D.  Build one with DMD and the other with
GDC.  If something segfaults or goes wrong at runtime, then raise a bug
about how DMD doesn't pass parameters correctly. ;-)

Besides, I'd worry more about how DMD keeps changing the names of runtime
hooks to be able to do things GDC has done for years.  With Dwarf EH thrown
into the mix, there's now three functions that handle throwing objects (GDC
still only has one).  Not cool man!


Re: Our template emission strategy is broken

2015-11-16 Thread Marco Leise via Digitalmars-d
Am Wed, 11 Nov 2015 14:23:15 +
schrieb Martin Nowak :

> Think of that for a moment, no package manager allows you to
> have cycles in your dependencies.

There are package managers that allow packages to mutually
depend on each other. Order is established by qualifying the
dependency similar to how you declare an owning and a weak
reference in a parent/child pointer relation.
E.g. You must install DMD before druntime/Phobos, but DMD is
only usable after druntime/Phobos has also been installed.

-- 
Marco



Re: Persistent list

2015-11-16 Thread Joseph Cassman via Digitalmars-d
On Monday, 16 November 2015 at 06:24:05 UTC, Jonathan M Davis 
wrote:

[...]


Regardless, I think that it's quite clear that certain idioms 
simply do not work with physical const, and there's been 
complaining about that for years. The only real question here 
is whether those idioms are worth enough to lose out on 
physical const. The answer up until now has always been no (at 
least from Walter), but since Andrei is now hitting this 
himself rather than seeing others complain about it, he clearly 
views it as a problem in a way that he didn't before, so that 
may result in him changing Walter's mind.


- Jonathan M Davis


I appreciate this discussion. I feel better that I am not the 
only one having difficulty with the _const_ keyword. Honestly 
about the only time I use _const_ is to tell the D compiler that 
a struct member function does not modify its containing type. 
When I start to use _const_ I quickly get a headache trying to 
figure out how to fix my code when the compiler starts to 
complain about function overloading issues and starts to require 
explicit casts all over the place, _inout_ doesn't work, did I 
use _Unqual_ or maybe I shouldn't, should this be a template, 
etc. I end up with a headache and all I want is the thing to 
compile. I wonder many times why go through the trouble. Why not 
just use a unit test?


After reading through this discussion I wonder if it has been 
considered to keep _immutable_ and _const_ as they are, but add a 
less restrictive do-not-change-me type qualifier to the language? 
A keyword like _readonly_, for example, could represent the idea 
of intransitive const (or perhaps even a different type of 
do-not-change-me-ness). I appreciate the need to be conservative 
in language additions, especially at this point in the life cycle 
of D2. Still, if people want and can show they need a type of 
do-not-change-me type qualifier in addition to _const_ and 
_immutable_ (not overlapping with unique et. al.) why not provide 
it for them?


Just as a side thought, although it is probably a bit of a 
dasoku. But I have always wondered that if the purpose of _const_ 
is to allow some data to be changed by one reference but not 
changed by another, then why is it transitive. Doesn't that 
defeat its purpose? And then doesn't transitive const effectively 
have the same semantics and use-case as _immutable_? I mean, once 
you start to use transitive const in an interface, how are you 
supposed to get the mutable reference that is so promised? 
Perhaps this is the question that is essentially being asked here?


Joseph


Re: [Poll] On Linux, what should we commonly use as sub-directory name for D?

2015-11-16 Thread Marco Leise via Digitalmars-d
Am Mon, 16 Nov 2015 08:49:57 +0100
schrieb Iain Buclaw via Digitalmars-d
:

> There should be ways to catch ABI changes in the build or test process.
> Maybe I'm misremembering something though. :-)
> 
> There should be a degree of ABI compatibility between releases for plain
> static functions - assuming that we add no more properties to the
> language.  That leaves what breaks the most in moving to a new version are
> template instantiations, no?

Frankly I have no idea what level of testing is in place. :D
To be practical for package maintainers, we would need some
higher level common D ABI versioning scheme that includes
Phobos. Then I could start grouping libraries by architecture
and this ABI version instead of by compiler/FE version. But
let's take baby steps here and first get DMD to use DWARF EH.
Once we can dynamically link DMD<->GDC, DMD<->LDC, we can
think about a stable Dlang ABI in terms of EH, function
mangling, Phobos etc.
I can easily see Phobos being split out of the DMD release
cycle by then, with both loosely depending on each other.

-- 
Marco



Re: All functions COMDAT on OSX

2015-11-16 Thread Walter Bright via Digitalmars-d

On 11/15/2015 8:44 PM, bitwise wrote:

https://issues.dlang.org/show_bug.cgi?id=15342

DMD emits all functions as COMDAT on OSX.

I'm guessing this was originally a workaround of some kind...does anybody know
the story?

Thanks,
 Bit


It enables:

1. the linker to remove duplicates (happens with templates and other things)
2. the linker to remove unreferenced COMDATs


Re: Persistent list

2015-11-16 Thread Jonathan M Davis via Digitalmars-d

On Monday, 16 November 2015 at 06:36:31 UTC, rsw0x wrote:
On Monday, 16 November 2015 at 06:24:05 UTC, Jonathan M Davis 
wrote:

On Sunday, 15 November 2015 at 21:45:08 UTC, Dicebot wrote:

[...]


Except that what if the container is passed to something that 
keeps it around? The ref-count would need to at least be 
incremented when passing it, and if the container were passed 
around enough, it could potentially need to be incremented a 
lot.


Ranges are potentially another big issue. As I understand it, 
there have already been issues with const and ranges with 
std.container.Array, because some of the fancy stuff that it 
does internally really doesn't work with const (though maybe I 
misunderstood).


this has a lot to do with const being virtually useless with 
structs


I'd say that there are two things about const which apply to 
structs which don't apply to classes which make const with 
structs bad. Stuff like having const member functions or having 
const values isn't necessarily any more of a problem with structs 
than it is with classes. What _is_ problematic is


1. const member variables (because they essentially force the 
whole struct to be treated as const even though it isn't - e.g. 
assignment doesn't work)


2. postblits don't work with const or immutable (so if you need a 
postblit, your struct really doesn't work with const or immutable)


Beyond that, const with structs is pretty much the same as it 
with classes. It's definitely restrictive, but not useless.


And actually, this gives me an interesting thought. Does making 
casting away const and mutating defined behavior give us a way to 
fix our postblit problem? I could see an argument that postblits 
should be completely unnecessary for immutable values (because 
you shouldn't need to avoid stuff like sharing references when 
it's immutable), which could mean that we could change it so that 
immutable structs values didn't trigger a postblit and thus 
worked fine as-is, and that would fix the problem with postblits 
and immutable. And if casting away const and mutating is legit, 
then it should be possible to treat the struct itself as mutable 
(or at least tail-const) within the postblit constructor, in 
which case it's then actually possible to have postblit 
constructor that works with const, whereas right now, we can't 
have it, because it would violate const to mutate the newly 
blitted, const struct.


So, if this really fixes our postblit problem, it might be worth 
it just for that. As it stands, postblit constuctors tend to have 
to be avoided in many cases because of how badly they interact 
with const and immutable.


- Jonathan M Davis