Re: opAssign and const?

2012-05-03 Thread Jonathan M Davis
On Friday, May 04, 2012 08:52:49 Era Scarecrow wrote:
> On Friday, 4 May 2012 at 06:48:40 UTC, Jonathan M Davis wrote:
> > If you make the one which isn't a ref const as well, it'll
> > probably work.
> 
>   Yeah I think so too. It will just be either a direct copy or I
> cast the object as const and pass it through. Seems like extra
> work to me and should be handled by the compiler. Anyways, thanks
> for looking at the problem with me.

With the last beta, there was a discussion in changing how ref and const ref 
works to allow rvalues while disallowing whatever use cases it is that causes 
problems with that in C++. If that gets sorted out and fully implemented, then 
you'd only need one overload. As it stands, the closest that you could get 
would be to use auto ref, but that only works with templated functions.

- Jonathan M Davis


Re: opAssign and const?

2012-05-03 Thread Era Scarecrow

On Friday, 4 May 2012 at 06:48:40 UTC, Jonathan M Davis wrote:
If you make the one which isn't a ref const as well, it'll 
probably work.


 Yeah I think so too. It will just be either a direct copy or I 
cast the object as const and pass it through. Seems like extra 
work to me and should be handled by the compiler. Anyways, thanks 
for looking at the problem with me.


Re: Transforming a range back to the original type?

2012-05-03 Thread Jacob Carlborg

On 2012-05-03 00:34, bearophile wrote:


The newly redesigned containers in Scala language are often able to do
this, but this has required the use of a very advanced static type
system, that is currently not in D (maybe there are ways to implement it
with D templates, but it will require work to implement).


I've heard of that. I've started to read a paper about how the 
collection API is implemented.


--
/Jacob Carlborg


Re: opAssign and const?

2012-05-03 Thread Jonathan M Davis
On Friday, May 04, 2012 08:32:40 Era Scarecrow wrote:
> On Friday, 4 May 2012 at 06:15:21 UTC, Jonathan M Davis wrote:
> > I believe that the issue is that x2 isn't const, so when the
> > compiler decides which of the two overloads to use, it picks
> > the one which doesn't use const. If the const ref version were
> > the only one, then it would work with x2, but since it isn't,
> > the other one gets picked because it's deemed a better match.
> 
>   I figured that was the case too. But I get the feeling that's
> wrong in this case. I was hoping to have only two declared
> opAssing's, one for temporaries (without ref) and one for
> copying. Kinda like the difference between saying a=b and a[]=b[]
> for an array. Be annoying if I had to force the cast to be const
> to do what I wanted; Right?

If you make the one which isn't a ref const as well, it'll probably work.

- Jonathan M Davis


Re: opAssign and const?

2012-05-03 Thread Era Scarecrow

On Friday, 4 May 2012 at 06:32:41 UTC, Era Scarecrow wrote:

opAssing's


 Hmmm suppose to be OpAssign. Nothing quite like a bug in your 
automatic text converter right?




Re: opAssign and const?

2012-05-03 Thread Era Scarecrow

On Friday, 4 May 2012 at 06:15:21 UTC, Jonathan M Davis wrote:
I believe that the issue is that x2 isn't const, so when the 
compiler decides which of the two overloads to use, it picks 
the one which doesn't use const. If the const ref version were 
the only one, then it would work with x2, but since it isn't, 
the other one gets picked because it's deemed a better match.


 I figured that was the case too. But I get the feeling that's 
wrong in this case. I was hoping to have only two declared 
opAssing's, one for temporaries (without ref) and one for 
copying. Kinda like the difference between saying a=b and a[]=b[] 
for an array. Be annoying if I had to force the cast to be const 
to do what I wanted; Right?


Re: Transforming a range back to the original type?

2012-05-03 Thread Jacob Carlborg

On 2012-05-04 01:11, Stewart Gordon wrote:


To sum it up, it can't be done in the general case. The range API
doesn't know or care about the underlying data structure. That's half
the point of it. The underlying data structure might not even exist. An
example is a range used as a file stream, a random number generator or
to lazily generate a mathematical sequence.


Yeah, I know, I know. It's all good in theory but I never found a use 
for it in practice and in most cases it's just annoying.



Moreover, what would you want such a function to return if the range is:
- a file stream with a cache
- an array wrapper to loop infinitely through it?
- a concatenation of ranges that may be of different types?


I was mostly thinking when the range originated from a collection. Where 
it's actually possible to transfer the range back to the original 
collection type.



Moreover, even if there were some "range with an underlying container"
classification, it would be an extra burden on the writer of the range
wrapper to implement this.


No, I was thinking that the developer of the collection would provide 
that. I mean, it's already possible to transform a range to an array, 
I'm sure it's possible to transform it to a list of some kind as well. 
Then we could have this for example:


collA.range.toArray();
collB.range.toList();

What I was asking for was if there is, or could be, a generic interface 
for this. Something like:


collA.range.toCollection();
collA.range.toCollection();

If "collA" is an array "toCollection" would transform the range to an 
array, just as std.array.array does. If "collB" is a list the range 
would be transformed back in to a list.



If you want to generate a range that views a container in a certain way,
and then construct a container of the original type (or indeed any type)
from that range, then create the container and then use a foreach loop
on the range (or a .save of it, if you want to keep the range
afterwards) to put the data into the container.

Stewart.



--
/Jacob Carlborg


Re: ref semantics with hashes

2012-05-03 Thread Andrej Mitrovic
On 5/3/12, Artur Skawina  wrote:
>alias p1.p2.p3.p4.p5.p6.hash hash3;
>alias p1.p2?p1.p2.hash:p3.p4.hash hash4;
>alias getfoo().hash hash5;

I was under the impression that alias would only be used as a
compile-time alias to a nested symbol. So this:

alias p1.p2.p3.hash foo;
test(foo);

would be somewhat equivalent to:
alias p1.p2.p3.hash foo;
mixin("test(p1.p2.p3.hash);");

I never thought of using alias as some sort of pointer in disguise.


Re: opAssign and const?

2012-05-03 Thread Jonathan M Davis
On Friday, May 04, 2012 07:49:29 Era Scarecrow wrote:
>   I have the following dilemma. Hopefully I have this right.
> 
> struct X {
>ref X opAssign(X x2);
>ref X opAssign(ref X x2);
> }
> 
> X fn();
> 
> void func(){
>X x, x2;
> 
>x = x2; //uses ref
>x = fn(); //without ref
> }
> 
>   According to the book, this is how it is suppose to be. const is
> a added promise not to modify anything. So... if i changed the
> ref to ref const... it won't call unless the item input was const
> as well.
> 
> //same as above except..
> struct X {
>ref X opAssign(X x2);
>ref X opAssign(ref const X x2); //const added
> }
> 
> void func(){
>X x, x2;
>const X x3;
> 
>x = x2; //without ref???
>x = x3; //ref
> }
> 
>   Since the input is intended to be read only anyways, why won't
> it work as expected with x = x2? This seems like a bug. If it's
> not, then I need to make two ref versions so it will behave
> properly. (If you need I can past actual working example)

I believe that the issue is that x2 isn't const, so when the compiler decides 
which of the two overloads to use, it picks the one which doesn't use const. 
If the const ref version were the only one, then it would work with x2, but 
since it isn't, the other one gets picked because it's deemed a better match.

- Jonathan M Davis


opAssign and const?

2012-05-03 Thread Era Scarecrow

 I have the following dilemma. Hopefully I have this right.

struct X {
  ref X opAssign(X x2);
  ref X opAssign(ref X x2);
}

X fn();

void func(){
  X x, x2;

  x = x2; //uses ref
  x = fn(); //without ref
}

 According to the book, this is how it is suppose to be. const is 
a added promise not to modify anything. So... if i changed the 
ref to ref const... it won't call unless the item input was const 
as well.


//same as above except..
struct X {
  ref X opAssign(X x2);
  ref X opAssign(ref const X x2); //const added
}

void func(){
  X x, x2;
  const X x3;

  x = x2; //without ref???
  x = x3; //ref
}

 Since the input is intended to be read only anyways, why won't 
it work as expected with x = x2? This seems like a bug. If it's 
not, then I need to make two ref versions so it will behave 
properly. (If you need I can past actual working example)


Re: How to prevent direct public creation of a struct?

2012-05-03 Thread Nick Sabalausky
"Brad Anderson"  wrote in message 
news:jhsccvjskiqqzzqbd...@forum.dlang.org...
> On Thursday, 3 May 2012 at 21:36:53 UTC, Nick Sabalausky wrote:
>> I want to do something like this:
>>
>> --
>> module moduleFoo;
>>
>> // Only allow certain values of "str"
>> template foo(string str)
>> {
>> static assert(str == "a" || str == "b" || str == "c");
>> immutable foo = Foo(str);
>> }
>>
>> struct Foo
>> {
>> // Only "a", "b", and "c" should be allowed,
>> // checked at compile-time via "template foo".
>> // Also, not modifyable.
>> private string _str;
>> @property string str()
>> {
>> return _str;
>> }
>> }
>> --
>>
>> I want struct Foo itself to be public, but I want to *force* all code
>> outside moduleFoo to *create* Foo via the "foo" template. Copying should 
>> be
>> allowed though. Ie:
>>
>> --
>> auto a = foo!"a"; // ok
>> a.str = "b"; // Error: str is a read-only property
>> auto z = foo!"z"; // Error: fails static assert
>> auto a2 = a; // Copy it: ok
>>
>> auto b = Foo("b"); // Error: I want to *force* the usage of "template 
>> foo"
>>
>> Foo x; // Kinda ambivalent about this: I'd prefer if it were disallowed, 
>> but
>> I don't think that's possible. If it's indeed impossible, I know I can 
>> just
>> declare Foo.str as (string str = "a";) so that's not a big problem.
>> --
>>
>> The *key* thing here that I'm not sure how to do is: How do I disallow
>> this?:
>>
>> auto b = Foo("b"); // Error: I want to *force* the usage of "template 
>> foo"
>
> I would have thought adding a private this(string str) constructor would 
> work but then foo can't be called from a separate module ("privcons.d(5): 
> Error: struct privcons.Foo member this is not accessible" which is the 
> same but desirable error it gives if you do "auto b = Foo("b");").  I 
> thought all module members had access to private members of the same 
> module but I guess that's not the case with template functions.

Hmm, interestingly, it works if the template calls through an intermediary 
private function:

http://d.puremagic.com/issues/show_bug.cgi?id=8028

I don't know if I'm relying on a bug or working around a bug, but this seems 
to work, *and* disallows "Foo b;" which is nice:

---
template foo(string str)
{
static assert(["a", "b", "c"].find(str), "Invalid str: '"~str~"'");
immutable foo = _foo(name);
}

private Foo _foo(string str)
{
return Foo(str);
}

struct Foo
{
immutable string str;

private this(string str)
{
this.str = str;
}

@disable this();
}

---
// In a serparate module:

Foo a = foo!"a";  // Ok
auto a2 = a;  // Ok

a.str = "b";  // Error: can only initialize const member name inside 
constructor

auto z = foo!"z";  // Error: static assert  "Invalid str: 'z'"  instantiated 
from here: foo!("z")

auto b = Foo("b");  // Error: struct test2.Foo member this is not accessible

Foo x;  // Error: variable test1.main.x initializer required for type Foo
---

So that's awesome, everything as I wanted :)




Re: Transforming a range back to the original type?

2012-05-03 Thread Stewart Gordon

On 02/05/2012 22:01, Jacob Carlborg wrote:

Is there a general function for transforming a range back to the original type? 
If not,
would it be possible to create one?


To sum it up, it can't be done in the general case.  The range API doesn't know or care 
about the underlying data structure.  That's half the point of it.  The underlying data 
structure might not even exist.  An example is a range used as a file stream, a random 
number generator or to lazily generate a mathematical sequence.


Moreover, what would you want such a function to return if the range is:
- a file stream with a cache
- an array wrapper to loop infinitely through it?
- a concatenation of ranges that may be of different types?

Moreover, even if there were some "range with an underlying container" classification, it 
would be an extra burden on the writer of the range wrapper to implement this.


If you want to generate a range that views a container in a certain way, and then 
construct a container of the original type (or indeed any type) from that range, then 
create the container and then use a foreach loop on the range (or a .save of it, if you 
want to keep the range afterwards) to put the data into the container.


Stewart.


Re: Mixins are not inherited?

2012-05-03 Thread Namespace

Very sad, i thougth that was possible.

As regards to "instanceof"

Try this code:

unittest {
class A {
mixin TRef!(typeof(this));
}

class B : A { }

class C : B { }

A a1 = new B();
A a2 = new C();

assert(instanceof!(A)(a1) == false);
assert(instanceof!(B)(a1));
assert(instanceof!(C)(a1) == false);
}

with my instanceof and then with your version.


Re: How to prevent direct public creation of a struct?

2012-05-03 Thread Jonathan M Davis
On Thursday, May 03, 2012 17:37:47 Nick Sabalausky wrote:
> I want to do something like this:
> 
> --
> module moduleFoo;
> 
> // Only allow certain values of "str"
> template foo(string str)
> {
> static assert(str == "a" || str == "b" || str == "c");
> immutable foo = Foo(str);
> }
> 
> struct Foo
> {
> // Only "a", "b", and "c" should be allowed,
> // checked at compile-time via "template foo".
> // Also, not modifyable.
> private string _str;
> @property string str()
> {
> return _str;
> }
> }
> --
> 
> I want struct Foo itself to be public, but I want to *force* all code
> outside moduleFoo to *create* Foo via the "foo" template. Copying should be
> allowed though. Ie:
> 
> --
> auto a = foo!"a"; // ok
> a.str = "b"; // Error: str is a read-only property
> auto z = foo!"z"; // Error: fails static assert
> auto a2 = a; // Copy it: ok
> 
> auto b = Foo("b"); // Error: I want to *force* the usage of "template foo"
> 
> Foo x; // Kinda ambivalent about this: I'd prefer if it were disallowed, but
> I don't think that's possible. If it's indeed impossible, I know I can just
> declare Foo.str as (string str = "a";) so that's not a big problem.
> --
> 
> The *key* thing here that I'm not sure how to do is: How do I disallow
> this?:
> 
> auto b = Foo("b"); // Error: I want to *force* the usage of "template foo"

Make all constructors private. Then the only way to construct the struct would 
be through it's init value. If you use

@disable this();

you can also prevent the use of init, but that disables init completely, not 
just outside of the module that the struct is in.

It looks like you're relying on the default-generated constructor for POD 
structs, and that isn't going to cut it, since it's public. You'll have to 
declare the appropriate constructor and make it private.

- Jonathan M Davis


Re: Mixins are not inherited?

2012-05-03 Thread Jonathan M Davis
On Thursday, May 03, 2012 23:32:50 Namespace wrote:
> By the following code i get these error messages:
> 
> 
> Error: template RefTest.Ref.__unittest1.instanceof(T : Object,U :
> Object) cannot deduce template function from argument types
> !(A)(B)
> 
> Error: template RefTest.Ref.__unittest1.instanceof does not match
> any function template declaration
> 
> Error: template instance instanceof!(A) errors instantiating
> template
> 
> 
> How is this possible? I thougth that the mixin would be inherited
> and so every subclass would be implicit cast to his super type.
> Isn't that so?
> If i write "mixin TRef!(B);" in class B, it works fine. Can
> anyone explain me why do i have to write it in class B?
> 
> [code]
> unittest {
> bool instanceof(T : Object, U : Object)(const Ref!U obj) {
> const U o = obj.access;
> 
> return const_cast(o).toString() == typeid(T).toString();
> }
> 
> class A {
> mixin TRef!(A);
> }
> 
> class B : A {
> //mixin TRef!(B);
> }
> 
> class C : B {
> //mixin TRef!(C);
> }
> 
> A a1 = new B();
> A a2 = new C();
> 
> assert(instanceof!(A)(a1) == false);
> assert(instanceof!(B)(a1));
> assert(instanceof!(C)(a1) == false);
> 
> writeln(a1);
> 
> B b1 = cast(B) a1;
> 
> assert(instanceof!(A)(b1) == false); // <-- fails
> 
> writeln(b1);
> 
> writeln();
> }
> [/code]
> 
> "TRef" is the same mixin template and "Ref" the same template
> struct as in my last threads.

Nothing you put in a base class is automatically in a derived class. If you 
put a member variable or member function in a base class, it's not in the 
derived class. It's just that the derived class has access to it as long as 
it's protected or public.

In the case of a mixin, you're essentially copying and pasting code. So, it's 
in the base class similarly to if you typed it there yourself. However, 
templated functions aren't virtual, so unlike if you typed them yourself, they 
won't be virtual if you use a template mixin.

So, if you want to mixin something into every class in a hierarchy, you must 
mix it in to every class in the hierarchy, not just the base class.

And if you want to test whether an object is an instance of a specific class, 
then cast it and check whether the result is null. You don't need to create a 
function to figure it out for you. e.g.

auto c = cast(MyClass)object;
if(c is null)
 writeln("c is NOT an instance of MyClass");
else
 writeln("c IS an instance of MyClass");

- Jonathan M Davis


Re: How to prevent direct public creation of a struct?

2012-05-03 Thread Justin Whear
On Thu, 03 May 2012 17:37:47 -0400, Nick Sabalausky wrote:
> The *key* thing here that I'm not sure how to do is: How do I disallow
> this?:
> 
> auto b = Foo("b"); // Error: I want to *force* the usage of "template
> foo"

The @disable annotation can do this, I believe:
struct Foo
{
@disable this();   // Cannot use default constructor
}

But this disables it for code within the module as well as outside, so 
you may wish to also add a private constructor.


Re: How to prevent direct public creation of a struct?

2012-05-03 Thread Brad Anderson

On Thursday, 3 May 2012 at 21:36:53 UTC, Nick Sabalausky wrote:

I want to do something like this:

--
module moduleFoo;

// Only allow certain values of "str"
template foo(string str)
{
static assert(str == "a" || str == "b" || str == "c");
immutable foo = Foo(str);
}

struct Foo
{
// Only "a", "b", and "c" should be allowed,
// checked at compile-time via "template foo".
// Also, not modifyable.
private string _str;
@property string str()
{
return _str;
}
}
--

I want struct Foo itself to be public, but I want to *force* 
all code
outside moduleFoo to *create* Foo via the "foo" template. 
Copying should be

allowed though. Ie:

--
auto a = foo!"a"; // ok
a.str = "b"; // Error: str is a read-only property
auto z = foo!"z"; // Error: fails static assert
auto a2 = a; // Copy it: ok

auto b = Foo("b"); // Error: I want to *force* the usage of 
"template foo"


Foo x; // Kinda ambivalent about this: I'd prefer if it were 
disallowed, but
I don't think that's possible. If it's indeed impossible, I 
know I can just
declare Foo.str as (string str = "a";) so that's not a big 
problem.

--

The *key* thing here that I'm not sure how to do is: How do I 
disallow

this?:

auto b = Foo("b"); // Error: I want to *force* the usage of 
"template foo"


I would have thought adding a private this(string str) 
constructor would work but then foo can't be called from a 
separate module ("privcons.d(5): Error: struct privcons.Foo 
member this is not accessible" which is the same but desirable 
error it gives if you do "auto b = Foo("b");").  I thought all 
module members had access to private members of the same module 
but I guess that's not the case with template functions.


How to prevent direct public creation of a struct?

2012-05-03 Thread Nick Sabalausky
I want to do something like this:

--
module moduleFoo;

// Only allow certain values of "str"
template foo(string str)
{
static assert(str == "a" || str == "b" || str == "c");
immutable foo = Foo(str);
}

struct Foo
{
// Only "a", "b", and "c" should be allowed,
// checked at compile-time via "template foo".
// Also, not modifyable.
private string _str;
@property string str()
{
return _str;
}
}
--

I want struct Foo itself to be public, but I want to *force* all code 
outside moduleFoo to *create* Foo via the "foo" template. Copying should be 
allowed though. Ie:

--
auto a = foo!"a"; // ok
a.str = "b"; // Error: str is a read-only property
auto z = foo!"z"; // Error: fails static assert
auto a2 = a; // Copy it: ok

auto b = Foo("b"); // Error: I want to *force* the usage of "template foo"

Foo x; // Kinda ambivalent about this: I'd prefer if it were disallowed, but 
I don't think that's possible. If it's indeed impossible, I know I can just 
declare Foo.str as (string str = "a";) so that's not a big problem.
--

The *key* thing here that I'm not sure how to do is: How do I disallow 
this?:

auto b = Foo("b"); // Error: I want to *force* the usage of "template foo"





Mixins are not inherited?

2012-05-03 Thread Namespace

By the following code i get these error messages:


Error: template RefTest.Ref.__unittest1.instanceof(T : Object,U : 
Object) cannot deduce template function from argument types 
!(A)(B)


Error: template RefTest.Ref.__unittest1.instanceof does not match 
any function template declaration


Error: template instance instanceof!(A) errors instantiating 
template	



How is this possible? I thougth that the mixin would be inherited 
and so every subclass would be implicit cast to his super type. 
Isn't that so?
If i write "mixin TRef!(B);" in class B, it works fine. Can 
anyone explain me why do i have to write it in class B?


[code]
unittest {
bool instanceof(T : Object, U : Object)(const Ref!U obj) {
const U o = obj.access;

return const_cast(o).toString() == typeid(T).toString();
}

class A {
mixin TRef!(A);
}

class B : A {
//mixin TRef!(B);
}

class C : B {
//mixin TRef!(C);
}

A a1 = new B();
A a2 = new C();

assert(instanceof!(A)(a1) == false);
assert(instanceof!(B)(a1));
assert(instanceof!(C)(a1) == false);

writeln(a1);

B b1 = cast(B) a1;

assert(instanceof!(A)(b1) == false); // <-- fails

writeln(b1);

writeln();
}
[/code]

"TRef" is the same mixin template and "Ref" the same template 
struct as in my last threads.


Re: Fixed-size arrays and randomShuffle()

2012-05-03 Thread bearophile

Vidar Wahlberg:

I'm not sure whether this counts as something that should be 
reported as a bug/improvement,


It's a badly written function (with insufficient unit tests):
http://d.puremagic.com/issues/show_bug.cgi?id=8026

Bye,
bearophile


Re: Fixed-size arrays and randomShuffle()

2012-05-03 Thread Chris Cain
OK, I took a look at your example, and I saw the kind of 
performance you were seeing.


I performed an investigation on what could cause such a disparity 
and came up with a conclusion. The answer is two things: First of 
all, as noted above, D's default generator is a mersenne twister 
RNG. You can emulate Java's RNG like so:


auto rng = LinearCongruentialEngine!(ulong,
25214903917uL, 11uL, 2uL^^48uL)();

Once I equalized that, I looked into the various methods that are 
called and settled in on uniform.


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

As you can see, there's a division at line 1154 and another at 
line 1158. This means there's a minimum of two division 
operations every time uniform is called. Now, normally this isn't 
a big deal, but if we really want maximum performance, we need to 
eliminate at least one.


If you replace lines 1154-1161 (auto bucketSize ... to return...) 
with:

CountType rnum, result;
do
{
rnum = cast(CountType) uniform!CountType(urng);
result = rnum % count;
}
while (rnum > count &&
(rnum - result + (count - 1)) < (rnum - result - 1));
return cast(typeof(return)) (min + result);

Then the time taken shrinks down to roughly the same (within a 
tenth of a second) as Java.


I'll probably clean this up (and write some comments on how this 
works) and see about submitting it as a patch unless anyone sees 
anything wrong with this approach.


Re: ptrace (process trace system call) on Linux from D

2012-05-03 Thread Matej Nanut

Thank you for the reply, your recommendation works.

I could however not find ptrace anywhere in druntime.  There is 
only one mention of it in std.process, in a comment.


But I do have some other questions:

(1) Can I declare a ptrace function which calls the original 
ptrace?  (I would like to check the return value and errno for 
exception throwing and such).  I essentially want to shadow the 
original.


(2) Is it more D-ish to use something like "enum PTRequest { 
traceMe = 0, ... }" instead of the fully capitalised originals?  
It doesn't seem to affect the working of things.


(3) wait() is declared as returning a pid_t in the manpage, and 
is declared as such in core.sys.posix.sys.wait.  In std.c.process 
however, it returns an int.  I can't even find a process.h in my 
Linux install.  What am I supposed to use?  I know it essentially 
doesn't matter, as pid_t is aliased as int.


Are there D alternatives to wait() and fork() that I could use 
with ptrace() instead of the C posix system functions?


(4) Some things are declared only in core.*, not in std.*.  Will 
they be added at some point or is this how it's supposed to be?


Re: cannot cast

2012-05-03 Thread Jonathan M Davis
On Thursday, May 03, 2012 10:54:47 Namespace wrote:
> On Thursday, 3 May 2012 at 08:46:26 UTC, Chris Cain wrote:
> > On Thursday, 3 May 2012 at 08:00:43 UTC, Namespace wrote:
> >> So, you mean that if i declared any parameter as const, it
> >> have to stay const all the time?
> > 
> > Yes. const = you can't change. Changing it is invalid behavior.
> > Imagine const/immutable as bits in readonly memory and you'll
> > have to right mindset.
> > 
> >> What would you do, if you need in a special case a mutable
> >> version or must change the object itself?
> >> Because there is no "mutable" keyword in D you have to cast
> >> away the constness.
> > 
> > In what way do you mean? If it's something you honestly _need_
> > to change and it's const, then maybe throwing an exception
> > would be appropriate.
> 
> I thought that const = "cannot change directly" and immutable
> stands for "cannot change all the time". If not, why exist both
> storage classes beside?

An immutable variable can never be changed by any reference to that data. It's 
also implicitly shared across threads (since it can never change).

If a const variable is a value type, then there really isn't any difference 
between const and immutable. If it's a reference type, then it just indicates 
that that particular reference cannot alter the data. Another reference may or 
may not be able to (and const is _not_ implicitly shared across threads, 
because the data _can_ change if there are mutable references to it). But if a 
reference is const, it's breaking the type system to cast away const and alter 
the data precisely because the compiler can't know whether that data is 
actually mutable or not. For instance, what if if you did something like

const var = new immutable(A);

var may be const, but it refers to a value which is actually immutable. 
Depending on what the compiler does, mutating var could result in nasty stuff 
like segfaults. In the general case, the compiler has no way of knowing 
whether a const variable is really mutable or immutable underneath. So, 
casting away const and mutating a variable is undefined behavior. As far as the 
compiler is concerned, a variable is _never_ mutated through a const 
reference, and it will optimize code based on that. So, casting away const can 
not only result in segfaults if the data is actually immutable, but it can 
result in incorrect behavior due to optimizations that the compiler makes 
based on the assumption that the variable wouldn't change but which you 
violated by casting away const and mutating the variable.

Unlike immutable, _other_ references to the data may mutate it (and the 
compiler must take that into account when optimizing), but you should never 
try and mutate a const variable. Once something is const, _leave_ it that way. 
If you need a mutable reference to it, then you need to get one which was 
mutable in the first place rather than coming from the const reference through 
casting.

Casting away const is legal, because D is a systems language, but actually 
mutating the variable after casting away const is undefined behavior, so you 
should never do it unless you really know what you're doing.

http://stackoverflow.com/questions/4219600/logical-const-in-d

- Jonathan M Davis


Re: string find and replace

2012-05-03 Thread Ary Manzana

On 5/3/12 11:01 PM, Ary Manzana wrote:

On 5/3/12 9:30 PM, Iain wrote:

On Thursday, 3 May 2012 at 14:22:57 UTC, Iain wrote:

Forgive me if I am missing something obvious, but is there a simple
option for finding all instances of a particular character in a string
or char[] and replacing them with another character?

I can do this with std.regex, but it seems overkill, when all I want
is the equivalent of PHP's str_replace() function.

Many thanks!


Apologies, after half an hour searching, I post, then five minutes later
figure it out.

myString = replace(myString, to, from); // from std.array


Note that you can also do:

myString = myString.replace(to, from)

I'd point you to the reference on the official page (UFCS: unified
function call syntax), but I can't find it...


and it should be replace(from, to)


Re: string find and replace

2012-05-03 Thread Ary Manzana

On 5/3/12 9:30 PM, Iain wrote:

On Thursday, 3 May 2012 at 14:22:57 UTC, Iain wrote:

Forgive me if I am missing something obvious, but is there a simple
option for finding all instances of a particular character in a string
or char[] and replacing them with another character?

I can do this with std.regex, but it seems overkill, when all I want
is the equivalent of PHP's str_replace() function.

Many thanks!


Apologies, after half an hour searching, I post, then five minutes later
figure it out.

myString = replace(myString, to, from); // from std.array


Note that you can also do:

myString = myString.replace(to, from)

I'd point you to the reference on the official page (UFCS: unified 
function call syntax), but I can't find it...


Re: Fixed-size arrays and randomShuffle()

2012-05-03 Thread Chris Cain


On a related note, how did you get the other random generators 
working? I tried to compile this and it gives me an error:

-=-=-=-
import std.random, std.stdio, std.datetime;

void main() {
int[] arr = new int[5_000_000];
foreach(i, ref e; arr)
e = i;
auto rng = MinstdRand0(1);
rng.seed(unpredictableSeed);
StopWatch sw = AutoStart.yes;
randomShuffle(arr, rng);
sw.stop();

writeln("Took ", sw.peek().to!("msecs", double)(), "ms");
}
-=-=-=-

The error:
-=-=-=-
C:\D\dmd2\windows\bin\..\..\src\phobos\std\random.d(1263): Error: 
cannot implicitly convert expression (rndGen()) of type 
MersenneTwisterEngine!(uint,32,624,397,31,-1727483681u,11,7,-1658038656u,15,-272236544u,18) 
to LinearCongruentialEngine!(uint,16807,0,2147483647)

-=-=-=-

Is this a bug in 2.059? Or am I doing something wrong?


Re: Fixed-size arrays and randomShuffle()

2012-05-03 Thread Vidar Wahlberg

On 2012-05-03 17:31, Chris Cain wrote:

You might want to post your code...


Sure!
D:
---
import std.random;
import std.stdio;
void main() {
auto iterations = 1000;
int[] a;
for (int i = 0; i < 42; ++i)
a ~= i;
for (int i = 0; i < iterations; ++i)
randomShuffle(a);
}

naushika:~/projects> dmd random.d && time ./random
./random  38,35s user 0,05s system 99% cpu 38,420 total
---


Java (7):
---
import java.util.ArrayList;
import java.util.Collections;
public class Rnd {
public static void main(String... args) {
int iterations = 1000;
ArrayList a = new ArrayList();
for (int i = 0; i < 42; ++i)
a.add(i);
for (int i = 0; i < iterations; ++i)
Collections.shuffle(a);
}
}

naushika:~/projects> javac Rnd.java && time java Rnd
java Rnd  9,92s user 0,03s system 100% cpu 9,922 total
---


Re: Compute in one pass 3 tokens position

2012-05-03 Thread bioinfornatics
Le lundi 30 avril 2012 à 14:52 +0200, bioinfornatics a écrit :
> Hi,
> I would like to know how compute in on pass 3 tokens position in a
> sequence.
> curently i do:
> File f = File( "reader.d", "r" );
> scope(exit) f.close();
> char[1024] buffer;
> char[] content = f.rawRead(buffer);
> char[sizediff_t] token = ['(', '{', ';'];
> auto position = map!( a => content.countUntil( a ) )( [ ['('], ['{'],
> [';'] ] );
> 
> 
> if i use reduce instead map the build fail
> 

update code for add attribute poure notrhow nd safe :)

--
 import std.string;
 import std.stdio;
 import std.conv;
 import std.c.process;
/**
 * searchIndex
 * search at wich index is located each token in given sequence.
 * It compute it in one pass.
 * Returns:
 * An ssociative array:
 *  key = token and value first index where is found
 *  value take -1 if not found in given sequence.
 */
@safe nothrow pure
sizediff_t[char[]] searchIndex( in char[] sequence, in char[][]
token...)
in{
  assert(sequence !is null, "Error given sequence is null");
}
body{
  bool   isComputing = true;
  size_t index   = 0;
  size_t flag= 0;
  sizediff_t[char[]] result;

  foreach( tok; token)
result[tok] = -1;

  while(isComputing){
if( index >= sequence.length )
  isComputing = false;
else if( flag == token.length )
  isComputing = false;
else{
  foreach( tok; token){
if( sequence.length - index >= tok.length ){
  const(char)[] currentToken = (tok.length > 1) ?
sequence[index .. index + tok.length] : [sequence[index]];
  if( currentToken in result && result[currentToken] == -1 ){
result[currentToken] = index;
flag++;
  }
}
  }
  index++;
}
  }
  return result;
}



void main( string[] args ){
  if( args.length == 1 ){
writefln( "Usage %s...", args[0]
);
exit(0);
  }
  writeln( searchIndex( "This a cool statement such as D is fun. Use it
and got the D power. Oh yeah! Are you ready? Try it!! Have fun.",
args[1..$]) );

}




Re: Fixed-size arrays and randomShuffle()

2012-05-03 Thread Chris Cain

On Thursday, 3 May 2012 at 14:41:20 UTC, Vidar Wahlberg wrote:
I tried those two as well. Still significantly slower than what 
I can achieve in Java.


You might want to post your code... I wrote this code in D:
-=-=-=-

import std.random, std.stdio, std.datetime;

void main() {
int[] arr = new int[5_000_000];
foreach(i, ref e; arr)
e = i;

StopWatch sw = AutoStart.yes;
arr.randomShuffle();
sw.stop();

writeln("Took ", sw.peek().to!("msecs", double)(), "ms");
}

-=-=-=-

And it performed _identically_ to this in Java:

-=-=-=-

import java.util.ArrayList;
import java.util.Collections;

public class Main {
public static void main(String[] args) {
ArrayList ints = new ArrayList<>(5000);
for(int i = 0; i < 5_000_000; ++i)
ints.add(i);

long startTime = System.currentTimeMillis();
Collections.shuffle(ints);
long endTime = System.currentTimeMillis();

System.out.println("Took " + (endTime - startTime) + "ms");
}
}

-=-=-=-


Re: Compute in one pass 3 tokens position

2012-05-03 Thread bioinfornatics
Le lundi 30 avril 2012 à 14:52 +0200, bioinfornatics a écrit :
> Hi,
> I would like to know how compute in on pass 3 tokens position in a
> sequence.
> curently i do:
> File f = File( "reader.d", "r" );
> scope(exit) f.close();
> char[1024] buffer;
> char[] content = f.rawRead(buffer);
> char[sizediff_t] token = ['(', '{', ';'];
> auto position = map!( a => content.countUntil( a ) )( [ ['('], ['{'],
> [';'] ] );
> 
> 
> if i use reduce instead map the build fail
> 

- CODE ---
 import std.stdio;
 import std.conv;
 import std.c.process;

sizediff_t[string] counter( in char[] sequence, string[] token...)
in{
  assert(sequence !is null, "Error given sequence is null");
}
body{
  bool   isComputing = true;
  size_t index   = 0;
  size_t flag= 0;
  sizediff_t[string] result;

  foreach( tok; token)
result[tok] = -1;

  while(isComputing){
if( index >= sequence.length )
  isComputing = false;
else if( flag == token.length )
  isComputing = false;
else{
  foreach( tok; token){
if( sequence.length - index >= tok.length ){
  string currentToken = to!string(sequence[index .. index +
tok.length]);
  if( currentToken in result && result[currentToken] == -1 ){
result[currentToken] = index;
flag++;
  }
}
  }
  index++;
}
  }
  return result;
}


void main( string[] args ){
  if( args.length == 1 ){
writefln( "Usage %s...", args[0]
);
exit(0);
  }
  writeln( counter( "This a cool statement such as D is fun. Use it and
ot the D power. Oh yeah! Are you ready? Try it!! Have fun.", args[1..$])
);

}
-- END CODE ---


$ ./test This D !
["D":30, "!":74, "This":0] import std.string;

if all token is found befoore reach end sequence it stop and save us
from some loop
it works too if token do not has same length as shown in example



Re: Passing array as const slows down code?

2012-05-03 Thread Artur Skawina
On 05/03/12 16:07, Steven Schveighoffer wrote:
> On Wed, 02 May 2012 16:05:13 -0400, Joseph Rushton Wakeling 
>  wrote:
> 
>> On 30/04/12 16:03, Steven Schveighoffer wrote:
>>> Try removing the ref and see if it goes back. That usage of ref should not
>>> affect anything (if anything it should be slower, since it's an extra level 
>>> of
>>> indirection).
>>
>> Removing the ref ups the time as described before, but only with GDC (DMD 
>> the runtime is the same).  It's a real effect.
> 
> I'm not familiar with GDC, but as bearophile says, it sounds like a compiler 
> bug.  Maybe GDC is making an optimization in one case and not in the other, 
> but both should be equivalently able to get the optimization.
> 
>>
>>> There is no implicit local copy for const. I have a suspicion that you 
>>> changed
>>> two things and forgot about one of them when running your tests.
>>
>> Really don't think so.  You can even check the version history of changes if 
>> you like!
> 
> IIRC, your original post concerned not-checked in code.  Anyway, if you've 
> re-run the tests, this is a confirmation.  I'd go ahead and file a bug 
> against GDC.  Rest assured, const should not *slow down* anything.

There *was* a GDC bug some time ago, where a 'const' or 'in' function argument
prevented inlining. Iain fixed it, so unless an old GDC version is used, it's
probably not related.

http://forum.dlang.org/thread/jdhb57$10vf$1...@digitalmars.com?page=16#post-mailman.33.1325763631.16222.d.gnu:40puremagic.com

artur


Re: Fixed-size arrays and randomShuffle()

2012-05-03 Thread Vidar Wahlberg

On 2012-05-03 16:26, Dmitry Olshansky wrote:

It's all about RNG used behind the scenes. Default one is Mersane
Twister which (AFAIK) is not particularly fast. But has a period of
2^19937 elements.
You should probably use XorShift or MinstdRand generator and a version
of shuffle with 2nd parameter.


I tried those two as well. Still significantly slower than what I can 
achieve in Java.


Re: string find and replace

2012-05-03 Thread Iain

On Thursday, 3 May 2012 at 14:22:57 UTC, Iain wrote:
Forgive me if I am missing something obvious, but is there a 
simple option for finding all instances of a particular 
character in a string or char[] and replacing them with another 
character?


I can do this with std.regex, but it seems overkill, when all I 
want is the equivalent of PHP's str_replace() function.


Many thanks!


Apologies, after half an hour searching, I post, then five 
minutes later figure it out.


myString = replace(myString, to, from); // from std.array




Re: Fixed-size arrays and randomShuffle()

2012-05-03 Thread Dmitry Olshansky

On 03.05.2012 18:02, Ali Çehreli wrote:



 > A quick follow-up:
 > I've tried some various random number engines, but neither come even
 > close to the performance of whatever is used for Java's
 > "Collection.shuffle()" method. Perhaps someone can shed some light on
this?

I have no idea with that one.



It's all about RNG used behind the scenes. Default one is Mersane 
Twister which (AFAIK) is not particularly fast. But has a period of 
2^19937 elements.
You should probably use XorShift or MinstdRand generator and a version 
of shuffle with 2nd parameter.


--
Dmitry Olshansky


string find and replace

2012-05-03 Thread Iain
Forgive me if I am missing something obvious, but is there a 
simple option for finding all instances of a particular character 
in a string or char[] and replacing them with another character?


I can do this with std.regex, but it seems overkill, when all I 
want is the equivalent of PHP's str_replace() function.


Many thanks!




Re: ref semantics with hashes

2012-05-03 Thread Steven Schveighoffer
On Wed, 02 May 2012 16:32:04 -0400, H. S. Teoh   
wrote:



On Wed, May 02, 2012 at 09:38:35PM +0200, Andrej Mitrovic wrote:
[...]

So if the hash wasn't already initialized then the reference in the
Foo struct is a reference to null, and if you duplicate that reference
and add a key the old reference still points to null.

The only way to ensure a proper link with a hash is to initialize it
with a key and then immediately remove that key, which makes the hash
not-null but empty:

[...]

Why do we have such error-prone semantics?


I was told that this was expected behaviour.

Should the new AA implementation change this, so that it always
allocates an empty AA upon instantiation?


This can't be done.  You can always create a struct without calling any  
code.


What I'd like to see is an initializer function/property, e.g.:

auto a = int[int].create(); // static property that allocates a new empty  
AA.


-Steve


Re: Access Violation in callback from sort

2012-05-03 Thread Steven Schveighoffer

On Wed, 02 May 2012 11:27:57 -0400, Jabb  wrote:

Just got the TDPL book and it's a great read! I learn best when typing  
out the code myself, so I decided to make a single VisualD project and  
put the different exercises in separate modules. I am having problems  
with sort in std.algorithms - well, actually it appears to be a closure  
problem when sort calls my delegate.


There shouldn't be any closure here, sort is not storing the delegate  
pointer.



Here's a sample of the problem - in main.d I have

//--
module main;
import std.algorithm;
void main() {
uint[string] counts = [ "a":4, "b":5, "c":3, "d":1 ];
string[] keys = counts.keys;

sort!((a, b) { return counts[a] > counts[b]; })(keys);
}
//--

Alone this works just fine. But if I add another file called myalgs.d,  
and put the following in it:


//--
module myalgs;
import std.algorithm;
//--

Then I get the following exception:

object.Error: Access Violation

C:\D\dmd2\windows\bin\..\..\src\phobos\std\algorithm.d(7112):  
mainmain__T8sortImplS14main9__lambda3VE3std9algorithm12SwapStrategy0TAAyaZsortImpl



Steping through the code it appears that the Access Violation occurs  
when accessing counts[a].


I am using DMD32 v2.059; my compilation command line looks like:
dmd -g -debug -X -Xf"$(IntDir)\$(TargetName).json"  
-deps="$(OutDir)\$(ProjectName).dep"  
-of"$(OutDir)\$(ProjectName).exe_cv" -map  
"$(INTDIR)\$(SAFEPROJECTNAME).map" -L/NOMAP


I can't see any errors, I think this is worthy of a bug report, it's nice  
and small and self-contained.


http://d.puremagic.com/issues

-Steve


Re: Passing array as const slows down code?

2012-05-03 Thread Steven Schveighoffer
On Wed, 02 May 2012 16:05:13 -0400, Joseph Rushton Wakeling  
 wrote:



On 30/04/12 16:03, Steven Schveighoffer wrote:
Try removing the ref and see if it goes back. That usage of ref should  
not
affect anything (if anything it should be slower, since it's an extra  
level of

indirection).


Removing the ref ups the time as described before, but only with GDC  
(DMD the runtime is the same).  It's a real effect.


I'm not familiar with GDC, but as bearophile says, it sounds like a  
compiler bug.  Maybe GDC is making an optimization in one case and not in  
the other, but both should be equivalently able to get the optimization.




There is no implicit local copy for const. I have a suspicion that you  
changed

two things and forgot about one of them when running your tests.


Really don't think so.  You can even check the version history of  
changes if you like!


IIRC, your original post concerned not-checked in code.  Anyway, if you've  
re-run the tests, this is a confirmation.  I'd go ahead and file a bug  
against GDC.  Rest assured, const should not *slow down* anything.


-Steve


Re: Fixed-size arrays and randomShuffle()

2012-05-03 Thread Ali Çehreli

On 05/03/2012 06:55 AM, Vidar Wahlberg wrote:
> On 2012-05-03 15:34, Ali Çehreli wrote:
>> Fixed-length arrays are value types. 'a' is copied to randomShuffle() so
>> its copy is shuffled. Passing a slice of the whole array works:
>>
>> randomShuffle(a[]);
>
> True, it is however still not exceptionally newbie (or perhaps even
> user?) friendly (my question was more of "does it have to be this way?"
> rather than "how do you do this?", even though I appreciate the answer
> on how to do it).
> Is it not possible for the compilator to let you know that what you're
> doing doesn't make any sense?

Random shuffle can work on a fixed-length array and there is a way for 
the implementation to know:


import std.traits;
// ...
  __traits(isStaticArray, a)

That can be used in a template constraint.

> A quick follow-up:
> I've tried some various random number engines, but neither come even
> close to the performance of whatever is used for Java's
> "Collection.shuffle()" method. Perhaps someone can shed some light on 
this?


I have no idea with that one.

Ali



Re: Fixed-size arrays and randomShuffle()

2012-05-03 Thread ixid
Why would you not want it to shuffle a fixed array? That's a very 
frustrating silent failure.


Re: Transforming a range back to the original type?

2012-05-03 Thread Simen Kjaeraas

On Thu, 03 May 2012 13:17:40 +0200, Jacob Carlborg  wrote:


On 2012-05-03 09:43, Simen Kjaeraas wrote:


In addition to std.array.array, as others have pointed out,
there is also std.range.InputRangeObject.


I'm not sure if I understand what InputRangeObject does. But I don't  
think it does what I want.


It basically wraps a range in a class interface. This allows you to use
InputRangeObject!T instead of T[]. I've never used it, so I'm not sure
what it does or how it does it.


Re: Fixed-size arrays and randomShuffle()

2012-05-03 Thread Vidar Wahlberg

On 2012-05-03 15:34, Ali Çehreli wrote:

Fixed-length arrays are value types. 'a' is copied to randomShuffle() so
its copy is shuffled. Passing a slice of the whole array works:

randomShuffle(a[]);


True, it is however still not exceptionally newbie (or perhaps even 
user?) friendly (my question was more of "does it have to be this way?" 
rather than "how do you do this?", even though I appreciate the answer 
on how to do it).
Is it not possible for the compilator to let you know that what you're 
doing doesn't make any sense?


A quick follow-up:
I've tried some various random number engines, but neither come even 
close to the performance of whatever is used for Java's 
"Collection.shuffle()" method. Perhaps someone can shed some light on this?


Re: Fixed-size arrays and randomShuffle()

2012-05-03 Thread Ali Çehreli

On 05/03/2012 06:30 AM, Vidar Wahlberg wrote:

May be that this works as intended, but it fooled me:
---
import std.random;
import std.stdio;
void main() {
int[5] a = 0;
a[0] = 1;
int[] b = [1, 0, 0, 0, 0];
randomShuffle(a);


Fixed-length arrays are value types. 'a' is copied to randomShuffle() so 
its copy is shuffled. Passing a slice of the whole array works:


randomShuffle(a[]);


writeln(a);
randomShuffle(b);
writeln(b);
}
---

In DMD 2.0.59 the fixed-size array "a" won't be shuffled (the dynamic
array "b" will), and you won't get any warning about it.

I'm not sure whether this counts as something that should be reported as
a bug/improvement, nor if only randomShuffle() displays this behaviour,
perhaps you could enlighten me.


Ali


Fixed-size arrays and randomShuffle()

2012-05-03 Thread Vidar Wahlberg

May be that this works as intended, but it fooled me:
---
import std.random;
import std.stdio;
void main() {
int[5] a = 0;
a[0] = 1;
int[] b = [1, 0, 0, 0, 0];
randomShuffle(a);
writeln(a);
randomShuffle(b);
writeln(b);
}
---

In DMD 2.0.59 the fixed-size array "a" won't be shuffled (the dynamic 
array "b" will), and you won't get any warning about it.


I'm not sure whether this counts as something that should be reported as 
a bug/improvement, nor if only randomShuffle() displays this behaviour, 
perhaps you could enlighten me.


Re: Transforming a range back to the original type?

2012-05-03 Thread Jacob Carlborg

On 2012-05-03 09:43, Simen Kjaeraas wrote:


In addition to std.array.array, as others have pointed out,
there is also std.range.InputRangeObject.


I'm not sure if I understand what InputRangeObject does. But I don't 
think it does what I want.


--
/Jacob Carlborg


Re: ref semantics with hashes

2012-05-03 Thread Artur Skawina
On 05/03/12 00:38, Andrej Mitrovic wrote:
> In fact what would *actually* solve this problem (for me) is if/when
> we have aliases implemented for this scenario:
> 
> import std.stdio;
> 
> struct Foo
> {
>int[] hash;
> }
> 
> void main()
> {
> Foo foo;
> alias foo.hash hash2;
> 
> hash2[0] = 1;
> writeln(foo.hash);  // [1:1]
> writeln(hash2); // [1:1]
> }
> 
> Hopefully we get that one day.

Until then, you can use

   @property ref hash2() { return foo.hash; }

which is a bit more verbose, but functionally equivalent.
Your new alias syntax would be just sugar, and would (a) hide the
complexity of the operation and (b) have to be artificially restricted.

   alias p1.p2.p3.p4.p5.p6.hash hash3;
   alias p1.p2?p1.p2.hash:p3.p4.hash hash4;
   alias getfoo().hash hash5;   

etc would also be possible otherwise and that isn't necessarily a good
idea.

artur


Re: extern and opaque structs

2012-05-03 Thread Jacob Carlborg

On 2012-05-03 07:00, James Miller wrote:

I'm doing C bindings and I have an opaque struct and an extern'd
variable of the type of that struct. The problem is that dmd is
complaining that the struct has no definition (which is true). Making it
a pointer works (expected) but i can't do that because the interface is
expecting an full struct.

Adding __gshared doesn't help.

I assume this is bug, since usage of extern means that I don't need to
know the size, since it will be allocated in the C code, not the D code.

--
James Miller


This doesn't work:

struct Foo;
extern (C) extern Foo foo;

--
/Jacob Carlborg


Re: cannot cast

2012-05-03 Thread Chris Cain

On Thursday, 3 May 2012 at 09:00:08 UTC, Chris Cain wrote:
const = you (as in, your view of the data as you're working 
with it) can't change


Actually, let me be even clearer with this... I mean _you_ cannot 
change it, but it might be changed by someone else's view, in 
which case it would appear to change in your view ... but not by 
any interaction you make with it.


This means concretely that anything you do with the object will 
have no effect on its bit representation in memory, although the 
bit representation in memory might be changed by other 
threads/processes/views.


Re: cannot cast

2012-05-03 Thread Chris Cain

On Thursday, 3 May 2012 at 08:54:48 UTC, Namespace wrote:
I thought that const = "cannot change directly" and immutable 
stands for "cannot change all the time". If not, why exist both 
storage classes beside?


const = you (as in, your view of the data as you're working with 
it) can't change
immutable = no one can change it ... as in, there exists no view 
of the data that can mutate it.


It's a subtle distinction. In fact, you can be handed a "const" 
and it's actually immutable underneath. And since immutable data 
can actually be stored in read only memory...


Re: cannot cast

2012-05-03 Thread Namespace

On Thursday, 3 May 2012 at 08:46:26 UTC, Chris Cain wrote:

On Thursday, 3 May 2012 at 08:00:43 UTC, Namespace wrote:
So, you mean that if i declared any parameter as const, it 
have to stay const all the time?


Yes. const = you can't change. Changing it is invalid behavior. 
Imagine const/immutable as bits in readonly memory and you'll 
have to right mindset.


What would you do, if you need in a special case a mutable 
version or must change the object itself?
Because there is no "mutable" keyword in D you have to cast 
away the constness.


In what way do you mean? If it's something you honestly _need_ 
to change and it's const, then maybe throwing an exception 
would be appropriate.


I thought that const = "cannot change directly" and immutable 
stands for "cannot change all the time". If not, why exist both 
storage classes beside?


Re: cannot cast

2012-05-03 Thread Chris Cain

On Thursday, 3 May 2012 at 08:00:43 UTC, Namespace wrote:
So, you mean that if i declared any parameter as const, it have 
to stay const all the time?


Yes. const = you can't change. Changing it is invalid behavior. 
Imagine const/immutable as bits in readonly memory and you'll 
have to right mindset.


What would you do, if you need in a special case a mutable 
version or must change the object itself?
Because there is no "mutable" keyword in D you have to cast 
away the constness.


In what way do you mean? If it's something you honestly _need_ to 
change and it's const, then maybe throwing an exception would be 
appropriate.


Re: Transforming a range back to the original type?

2012-05-03 Thread Jacob Carlborg

On 2012-05-02 23:40, Jonathan M Davis wrote:

On Wednesday, May 02, 2012 23:01:21 Jacob Carlborg wrote:

Is there a general function for transforming a range back to the
original type? If not, would it be possible to create one?


You mean that if you have something like

auto range = getRangeFromSomewhere();
auto newRange = find(filter!func(range), value);

you want to transform newRange back to the same type as range?


No, I want to transform newRange back to a collection, the same type as 
the original collection. I was thinking something like this:


Collection c = new Collection();
c = c.filter!(x => x < 3).toCollection();

--
/Jacob Carlborg


Re: cannot cast

2012-05-03 Thread sclytrack

On 05/03/2012 09:33 AM, Namespace wrote:

On Wednesday, 2 May 2012 at 22:38:36 UTC, Namespace wrote:

Other, shorter example:

[code]
import std.stdio, std.traits;

class A {
int val;

alias val this;

T opCast(T : Object)() {
writeln("FOO");

return to!(T)(this);
}
}

class B : A {

}

T to(T : Object, U : Object)(const U obj) {
return *(cast(T*) &obj);
}

T const_cast(T)(const T obj) {
return cast(T) obj;
}

void main () {
A a = new B();
a.val = 42;

writefln("a.val: %d", a.val);

B* b = cast(B*) &a;
writefln("*b.val: %d", b.val);

B b1 = to!(B)(a);
writefln("b1.val: %d", b1.val);

B b2 = cast(B) a;
writefln("b2.val: %d", b2.val);

const B b3 = cast(B) a;

B b4 = const_cast(b3);
}
[/code]

print:

alias_this_impl.d(24): Error: function
alias_this_impl.A.opCast!(B).opCast () is
not callable using argument types ()
alias_this_impl.d(44): Error: template instance
alias_this_impl.const_cast!(B) e
rror instantiating

I'm not very skillful in such "template" stories. Maybe someone can
help me?


Solved with

T const_cast(T)(const T obj) {
return to!(T)(obj);
}

But i think that there must exist a more nicer way to cast away const,
isn't there?

To cast away "const" with a simple cast to "T" fails (see my post
above), because i have no idea, how i can restrict my opCast. So i have
to convert it again with "to". Do some of you have any ideas how i can
restrict my opCast, so my const_cast doesn't match it, e.g. with some
template magic?





Unqual können Sie finden in std.traits.


template Unqual(T)
{
version (none) // Error: recursive alias declaration @@@BUG1308@@@
{
 static if (is(T U == const U)) alias Unqual!U Unqual;
else static if (is(T U == immutable U)) alias Unqual!U Unqual;
else static if (is(T U == inout U)) alias Unqual!U Unqual;
else static if (is(T U == shared U)) alias Unqual!U Unqual;
else alias T Unqual;
}
else // workaround
{
 static if (is(T U == shared(const U))) alias U Unqual;
else static if (is(T U == const U )) alias U Unqual;
else static if (is(T U == immutable U )) alias U Unqual;
else static if (is(T U == inout U )) alias U Unqual;
else static if (is(T U == shared U )) alias U Unqual;
else alias T Unqual;
}
}

unittest
{
static assert(is(Unqual!(int) == int));
static assert(is(Unqual!(const int) == int));
static assert(is(Unqual!(immutable int) == int));
static assert(is(Unqual!(inout int) == int));
static assert(is(Unqual!(shared int) == int));
static assert(is(Unqual!(shared(const int)) == int));
alias immutable(int[]) ImmIntArr;
static assert(is(Unqual!(ImmIntArr) == immutable(int)[]));
}



Re: cannot cast

2012-05-03 Thread Namespace

On Thursday, 3 May 2012 at 07:41:32 UTC, Simen Kjaeraas wrote:
On Thu, 03 May 2012 00:38:35 +0200, Namespace 
 wrote:


I'm not very skillful in such "template" stories. Maybe 
someone can help me?


The main problem here is your opCast is non-const. (it's always 
an indication of
const problems when DMD says " is not callable using 
argument types ()")


Solution:

class A {
int val;

alias val this;

T opCast(T : Object)() {
writeln("FOO");

return to!(T)(this);
}

// Add this
T opCast(T : Object)() const {
writeln("FOO");

return to!(T)(this);
}
}


My tests are failed, but isn't it possible, to reduce both 
methods to one with the inout keyword?


Re: cannot cast

2012-05-03 Thread Namespace
If you want to restrict opCast, then use a template constraint, 
constraining
it to what you want to work with it. Also, casting away const 
is generally a
bad idea in D. Casting away const and mutating a variable is an 
_extremely_
bad idea. You _really_ shouldn't be doing it. So, the fact that 
you _have_ a
function which is specifically trying to cast away const is 
almost certainly

_not_ a good idea.

http://stackoverflow.com/questions/4219600/logical-const-in-d


- Jonathan M Davis


So, you mean that if i declared any parameter as const, it have 
to stay const all the time?
What would you do, if you need in a special case a mutable 
version or must change the object itself?
Because there is no "mutable" keyword in D you have to cast away 
the constness.




Re: Transforming a range back to the original type?

2012-05-03 Thread Jacob Carlborg

On 2012-05-02 23:07, Matt Soucy wrote:

On 05/02/2012 05:01 PM, Jacob Carlborg wrote:

Is there a general function for transforming a range back to the
original type? If not, would it be possible to create one?



I believe std.array's array function does what you want.
-Matt


I was thinking of a generic function that works for all types of 
collections and not arrays.


--
/Jacob Carlborg


Re: cannot cast

2012-05-03 Thread Namespace

On Thursday, 3 May 2012 at 07:41:32 UTC, Simen Kjaeraas wrote:
On Thu, 03 May 2012 00:38:35 +0200, Namespace 
 wrote:


I'm not very skillful in such "template" stories. Maybe 
someone can help me?


The main problem here is your opCast is non-const. (it's always 
an indication of
const problems when DMD says " is not callable using 
argument types ()")


Solution:

class A {
int val;

alias val this;

T opCast(T : Object)() {
writeln("FOO");

return to!(T)(this);
}

// Add this
T opCast(T : Object)() const {
writeln("FOO");

return to!(T)(this);
}
}


Hm, simple. Thank you, as long as the bug isn't fixed, this has 
to be enough. :)


Re: cannot cast

2012-05-03 Thread Jonathan M Davis
On Thursday, May 03, 2012 09:33:01 Namespace wrote:
> On Wednesday, 2 May 2012 at 22:38:36 UTC, Namespace wrote:
> > Other, shorter example:
> > 
> > [code]
> > import std.stdio, std.traits;
> > 
> > class A {
> > 
> > int val;
> > 
> > alias val this;
> > 
> > T opCast(T : Object)() {
> > 
> > writeln("FOO");
> > 
> > return to!(T)(this);
> > 
> > }
> > 
> > }
> > 
> > class B : A {
> > 
> > }
> > 
> > T to(T : Object, U : Object)(const U obj) {
> > 
> > return *(cast(T*) &obj);
> > 
> > }
> > 
> > T const_cast(T)(const T obj) {
> > 
> > return cast(T) obj;
> > 
> > }
> > 
> > void main () {
> > 
> > A a = new B();
> > a.val = 42;
> > 
> > writefln("a.val: %d", a.val);
> > 
> > B* b = cast(B*) &a;
> > writefln("*b.val: %d", b.val);
> > 
> > B b1 = to!(B)(a);
> > writefln("b1.val: %d", b1.val);
> > 
> > B b2 = cast(B) a;
> > writefln("b2.val: %d", b2.val);
> > 
> > const B b3 = cast(B) a;
> > 
> > B b4 = const_cast(b3);
> > 
> > }
> > [/code]
> > 
> > print:
> > 
> > alias_this_impl.d(24): Error: function
> > alias_this_impl.A.opCast!(B).opCast () is
> > 
> >  not callable using argument types ()
> > 
> > alias_this_impl.d(44): Error: template instance
> > alias_this_impl.const_cast!(B) e
> > rror instantiating
> > 
> > I'm not very skillful in such "template" stories. Maybe someone
> > can help me?
> 
> Solved with
> 
> T const_cast(T)(const T obj) {
>   return to!(T)(obj);
> }
> 
> But i think that there must exist a more nicer way to cast away
> const, isn't there?
> 
> To cast away "const" with a simple cast to "T" fails (see my post
> above), because i have no idea, how i can restrict my opCast. So
> i have to convert it again with "to". Do some of you have any
> ideas how i can restrict my opCast, so my const_cast doesn't
> match it, e.g. with some template magic?

If you want to restrict opCast, then use a template constraint, constraining 
it to what you want to work with it. Also, casting away const is generally a 
bad idea in D. Casting away const and mutating a variable is an _extremely_ 
bad idea. You _really_ shouldn't be doing it. So, the fact that you _have_ a 
function which is specifically trying to cast away const is almost certainly 
_not_ a good idea.

http://stackoverflow.com/questions/4219600/logical-const-in-d


- Jonathan M Davis


Re: Transforming a range back to the original type?

2012-05-03 Thread Simen Kjaeraas

On Wed, 02 May 2012 23:01:21 +0200, Jacob Carlborg  wrote:

Is there a general function for transforming a range back to the  
original type? If not, would it be possible to create one?


In addition to std.array.array, as others have pointed out,
there is also std.range.InputRangeObject.


Re: cannot cast

2012-05-03 Thread Simen Kjaeraas
On Thu, 03 May 2012 00:38:35 +0200, Namespace   
wrote:


I'm not very skillful in such "template" stories. Maybe someone can help  
me?


The main problem here is your opCast is non-const. (it's always an  
indication of

const problems when DMD says " is not callable using argument types ()")

Solution:

class A {
int val;

alias val this;

T opCast(T : Object)() {
writeln("FOO");

return to!(T)(this);
}

// Add this
T opCast(T : Object)() const {
writeln("FOO");

return to!(T)(this);
}
}


Re: cannot cast

2012-05-03 Thread Namespace

On Wednesday, 2 May 2012 at 22:38:36 UTC, Namespace wrote:

Other, shorter example:

[code]
import std.stdio, std.traits;

class A {
int val;

alias val this;

T opCast(T : Object)() {
writeln("FOO");

return to!(T)(this);
}
}

class B : A {

}

T to(T : Object, U : Object)(const U obj) {
return *(cast(T*) &obj);
}

T const_cast(T)(const T obj) {
return cast(T) obj;
}

void main () {
A a = new B();
a.val = 42;

writefln("a.val: %d", a.val);

B* b = cast(B*) &a;
writefln("*b.val: %d", b.val);

B b1 = to!(B)(a);
writefln("b1.val: %d", b1.val);

B b2 = cast(B) a;
writefln("b2.val: %d", b2.val);

const B b3 = cast(B) a;

B b4 = const_cast(b3);
}
[/code]

print:

alias_this_impl.d(24): Error: function 
alias_this_impl.A.opCast!(B).opCast () is

 not callable using argument types ()
alias_this_impl.d(44): Error: template instance 
alias_this_impl.const_cast!(B) e

rror instantiating

I'm not very skillful in such "template" stories. Maybe someone 
can help me?


Solved with

T const_cast(T)(const T obj) {
return to!(T)(obj);
}

But i think that there must exist a more nicer way to cast away 
const, isn't there?


To cast away "const" with a simple cast to "T" fails (see my post 
above), because i have no idea, how i can restrict my opCast. So 
i have to convert it again with "to". Do some of you have any 
ideas how i can restrict my opCast, so my const_cast doesn't 
match it, e.g. with some template magic?