Re: Error when exiting program

2011-02-20 Thread Joel Christensen

On 19-Feb-11 6:53 PM, Jesse Phillips wrote:

Joel Christensen Wrote:


I'm using some one else's bindings to a C library.

The problem seems to be limited to D2 programs.

Error as follows:
An exception was thrown while finalizing an instance of class jec2.bmp.Bmp

I also get other errors at program exit.

Thanks for any help. :-)


I think you are going to have to give us more detail. What library, what error?


I don't think any one wants to see my code (a mess). I've started a new 
library thingy, and so far no problem.


Re: shared/unshared classes

2011-02-20 Thread Johannes Pfau
Steven Schveighoffer wrote:
>On Sat, 19 Feb 2011 21:55:53 -0500, Jonathan M Davis
> wrote:
>
>> On Saturday 19 February 2011 18:26:25 Steven Schveighoffer wrote:
>>> I was working on an I/O library that I plan to use in development,
>>> and possibly submit to phobos, and I thought of this case.
>>>
>>> A standard file can be shared or unshared.  In C, since there is
>>> no notion
>>> of shared/unshared, everything is shared.  So any writes/reads from
>>> a FILE
>>> * lock the object.
>>>
>>> But in D, we can avoid those locks when the file is unshared.
>>> However, this means I have to write two pretty much identical
>>> functions for each call.
>>>
>>> Is there an expected way to do this?  I've really avoided doing
>>> anything with shared or threads since the new concurrency model
>>> came out, but with
>>> I/O, I'll have to deal with it.
>>>
>>> I think a logical thing to do would be to have the shared version
>>> of the function call the unshared version after locking the
>>> object.  Is that a good idea?  Is the correct way to do this to
>>> mark the shared function synchronized, and then cast 'this' to
>>> unshared to call the other function?  Does this automatically
>>> happen with shared functions?
>>
>> I would point out that per TDPL, either an entire class is
>> synchronized or none
>> of it is. You don't synchronize individual functions. Now, I don'
>> think that
>> that's the way that it's implemented at the moment, but that's the  
>> eventual
>> situation as I understand it. So, your class shouldn't have a
>> mixture of synchronized or unsynchronized. According to TDPL, it's
>> illegal.
>>
>
>OK, I kind of remember that now.  So that means, I need to create two  
>identical hierarchies, a synchronized one and a non-synchronized one?
>
>I think what I'll do for now is write the non-synchronized versions,
>and then see about maybe automating the synchronized parts.
>
>-Steve

Creating two types, one synchronized, one not, doesn't sound like a
good solution. If you need fine grained locking you can still do that
manually (mark the function as shared, use the synchronized statement
in the function). When I tried to do that for my std.signals
replacement (which reminds me that I finally have to propose it for
review) I found quite some bugs in the shared system. There's no
shared signal because of those:

http://d.puremagic.com/issues/show_bug.cgi?id=3733
This one is very annoying and I think I hit one or two cases where
even the workaround didn't work.

IIRC operators couldn't be overloaded with shared functions.

Then I hit this issue:
http://lists.puremagic.com/pipermail/digitalmars-d-learn/2010-November/019858.html
And I gave up ;-)
-- 
Johannes Pfau


signature.asc
Description: PGP signature


Re: GC: finalization order?!

2011-02-20 Thread Simen kjaeraas

Jonathan M Davis  wrote:

Yes. You're right. They can reference the non-GC heap just fine. It's  
just that
they can't reference the GC heap - probably because the destructor order  
is

indeterminate and so that the GC doesn't have to worry about dealing with
circular references between garbage collected objects.


D could support finalizers in lieu of (or in addition to) destructors. In
such a case, they would be called before the object graph were garbage-
collected, and one could hence reference other objects on the GC heap. Is
there any reason why this approach was not chosen?

--
Simen


Re: GC: finalization order?!

2011-02-20 Thread Martin Kinkelin
I came to the same conclusion. Even if Parent is a struct, it may get
destructed after its Child (e.g., in case the Parent struct is a field
of another class).
What I did is to use a custom allocator for Child, so that Child
instances are not managed by the GC:

--
import std.stdio;
import std.c.stdlib;
import core.exception;

private class Child
{
new(size_t size)
{
writeln("Child.new()");
void* p = malloc(size);
if (!p)
onOutOfMemoryError();
return p;
}
delete(void* p)
{
writeln("Child.delete()");
if (p)
free(p);
}


private size_t _refs;

this()
{
writeln("Child.__ctor()");
_refs = 1;
}
~this()
{
writeln("Child.__dtor()");
if (_refs != 0)
throw new Exception("still referenced");
}

void addRef() { _refs++; }
void release()
{
if (--_refs == 0)
delete this;
}
}

class Parent
{
private Child _child;

this()
{
writeln("Parent.__ctor()");
_child = new Child();
}
~this()
{
writeln("Parent.__dtor()");
if (_child)
_child.release();
}
}

unittest
{
auto p = new Parent();
}
--

Output:
--
Parent.__ctor()
Child.new()
Child.__ctor()
Parent.__dtor()
Child.__dtor()
Child.delete()
--

This way, Child is destructed as soon as the last related Parent is destructed.
Thanks for clarifying!


Re: GC: finalization order?!

2011-02-20 Thread Jonathan M Davis
On Sunday 20 February 2011 04:10:18 Simen kjaeraas wrote:
> Jonathan M Davis  wrote:
> > Yes. You're right. They can reference the non-GC heap just fine. It's
> > just that
> > they can't reference the GC heap - probably because the destructor order
> > is
> > indeterminate and so that the GC doesn't have to worry about dealing with
> > circular references between garbage collected objects.
> 
> D could support finalizers in lieu of (or in addition to) destructors. In
> such a case, they would be called before the object graph were garbage-
> collected, and one could hence reference other objects on the GC heap. Is
> there any reason why this approach was not chosen?

I'm really not very well versed in the details of the GC, and I don't know all 
that much about why it works the way that it works. For the most part, though, 
I 
don't see much need for either destructors or finalizers in classes. The main 
reason for them in C++ is for managing memory, which the GC takes care of for 
you. And since RAII is taken care of by structs, there really isn't much reason 
for class destructors that I can see - at least not normally. I can see why you 
might need it occasionally, but for the most part, you don't. Java has 
finalizers 
(but no constructors), but I've never needed them, and I've never seen them 
used. So, while the situation with class destructors and finalizers could be 
handled better in D, I don't think that it's normally an issue at all.

Regardless, I'm not particularly well versed in the details of the GC, so I'm 
really not the best person to answer questions about it.

- Jonathan M Davis


Re: shared/unshared classes

2011-02-20 Thread spir

On 02/20/2011 04:41 AM, Jonathan M Davis wrote:

On Saturday 19 February 2011 19:12:17 Jonathan M Davis wrote:

On Saturday 19 February 2011 19:01:16 Steven Schveighoffer wrote:

On Sat, 19 Feb 2011 21:55:53 -0500, Jonathan M Davis


wrote:

On Saturday 19 February 2011 18:26:25 Steven Schveighoffer wrote:

I was working on an I/O library that I plan to use in development, and
possibly submit to phobos, and I thought of this case.

A standard file can be shared or unshared.  In C, since there is no
notion
of shared/unshared, everything is shared.  So any writes/reads from a
FILE
* lock the object.

But in D, we can avoid those locks when the file is unshared.
However, this means I have to write two pretty much identical
functions for each call.

Is there an expected way to do this?  I've really avoided doing
anything with shared or threads since the new concurrency model came
out, but with
I/O, I'll have to deal with it.

I think a logical thing to do would be to have the shared version of
the function call the unshared version after locking the object.  Is
that a good idea?  Is the correct way to do this to mark the shared
function synchronized, and then cast 'this' to unshared to call the
other function?  Does this automatically happen with shared
functions?


I would point out that per TDPL, either an entire class is synchronized
or none
of it is. You don't synchronize individual functions. Now, I don' think
that
that's the way that it's implemented at the moment, but that's the
eventual
situation as I understand it. So, your class shouldn't have a mixture
of synchronized or unsynchronized. According to TDPL, it's illegal.


OK, I kind of remember that now.  So that means, I need to create two
identical hierarchies, a synchronized one and a non-synchronized one?

I think what I'll do for now is write the non-synchronized versions, and
then see about maybe automating the synchronized parts.


I'd have to study up on it more to know what the best way to handle it is
(I've generally avoided dealing with shared), but what you'd probably end
up doing is creating a wrapper class which was synchronized. However, you
might be able to get it to just automatically use the right one
(unsynchronized for unshared and synchronized for shared) if you use
templates.


Actually, now that I think about it, we're probably going to want a template of
some kind in Phobos which wraps an unsynchronized class with a synchronized one.
There are going to be plenty of cases where it would be nice to have an
unsynchronized class made synchronized (a prime example would be a container
class), and it would be annoying to have to keep creating your own wrappers
every time that you want to do that.


I have not had a look at D's threading implementation, but from what I read I 
thought what you describe precisely was the whole point of unshared-by-default 
and the 'shared' keyword. Eg I thought something like:

class Foo {...}
shared foo = new Foo();
would do what you write above. Else, what does 'shared' mean?

Denis
--
_
vita es estrany
spir.wikidot.com



Re: shared/unshared classes

2011-02-20 Thread Jonathan M Davis
On Sunday 20 February 2011 05:36:25 spir wrote:
> On 02/20/2011 04:41 AM, Jonathan M Davis wrote:
> > On Saturday 19 February 2011 19:12:17 Jonathan M Davis wrote:
> >> On Saturday 19 February 2011 19:01:16 Steven Schveighoffer wrote:
> >>> On Sat, 19 Feb 2011 21:55:53 -0500, Jonathan M Davis
> >>> 
> >>> 
> >>> wrote:
>  On Saturday 19 February 2011 18:26:25 Steven Schveighoffer wrote:
> > I was working on an I/O library that I plan to use in development,
> > and possibly submit to phobos, and I thought of this case.
> > 
> > A standard file can be shared or unshared.  In C, since there is no
> > notion
> > of shared/unshared, everything is shared.  So any writes/reads from a
> > FILE
> > * lock the object.
> > 
> > But in D, we can avoid those locks when the file is unshared.
> > However, this means I have to write two pretty much identical
> > functions for each call.
> > 
> > Is there an expected way to do this?  I've really avoided doing
> > anything with shared or threads since the new concurrency model came
> > out, but with
> > I/O, I'll have to deal with it.
> > 
> > I think a logical thing to do would be to have the shared version of
> > the function call the unshared version after locking the object.  Is
> > that a good idea?  Is the correct way to do this to mark the shared
> > function synchronized, and then cast 'this' to unshared to call the
> > other function?  Does this automatically happen with shared
> > functions?
>  
>  I would point out that per TDPL, either an entire class is
>  synchronized or none
>  of it is. You don't synchronize individual functions. Now, I don'
>  think that
>  that's the way that it's implemented at the moment, but that's the
>  eventual
>  situation as I understand it. So, your class shouldn't have a mixture
>  of synchronized or unsynchronized. According to TDPL, it's illegal.
> >>> 
> >>> OK, I kind of remember that now.  So that means, I need to create two
> >>> identical hierarchies, a synchronized one and a non-synchronized one?
> >>> 
> >>> I think what I'll do for now is write the non-synchronized versions,
> >>> and then see about maybe automating the synchronized parts.
> >> 
> >> I'd have to study up on it more to know what the best way to handle it
> >> is (I've generally avoided dealing with shared), but what you'd
> >> probably end up doing is creating a wrapper class which was
> >> synchronized. However, you might be able to get it to just
> >> automatically use the right one (unsynchronized for unshared and
> >> synchronized for shared) if you use templates.
> > 
> > Actually, now that I think about it, we're probably going to want a
> > template of some kind in Phobos which wraps an unsynchronized class with
> > a synchronized one. There are going to be plenty of cases where it would
> > be nice to have an unsynchronized class made synchronized (a prime
> > example would be a container class), and it would be annoying to have to
> > keep creating your own wrappers every time that you want to do that.
> 
> I have not had a look at D's threading implementation, but from what I read
> I thought what you describe precisely was the whole point of
> unshared-by-default and the 'shared' keyword. Eg I thought something like:
>   class Foo {...}
>   shared foo = new Foo();
> would do what you write above. Else, what does 'shared' mean?

shared means that it's not thread local, and that means that you need to worry 
about mutexes and synchronized and the like. So, Steve's concern is that if you 
use the class and it's shared, it needs to be synchronized. But if it's not 
shared, you don't want the overhead of synchronization. So, you make a version 
which is not synchronized and then whoever uses it has to worry about using 
mutexes to protect it. Creating a wrapper class which is synchronized is a good 
way to do so. Having a template which produced such a wrapper for you would be 
particularly useful so that you don't have to write a new wrapper class by hand 
every time that you need have a synchronized version of an unsynchronized class.

- Jonathan M Davis

- Jonathan M Davis


Re: Is std.array.replace supposed to work with char[]?

2011-02-20 Thread Jacob Carlborg

On 2011-02-19 23:20, Steven Schveighoffer wrote:

On Sat, 19 Feb 2011 16:23:12 -0500, Jacob Carlborg  wrote:


Compiling the following code with DMD 2.052 on Mac OS X:

import std.array;

void main ()
{
char[] a;
char[] b;
a.replace(1, 3, b);
}

Results in the following error:

test.d(7): Error: template std.array.replace(T,Range) if
(isDynamicArray!(Range) && is(ElementType!(Range) : T)) does not match
any function template declaration
test.d(7): Error: template std.array.replace(T,Range) if
(isDynamicArray!(Range) && is(ElementType!(Range) : T)) cannot deduce
template function from argument types !()(char[],int,int,char[])

What am I doing wrong or isn't std.array.replace supposed to work with
char[]?


D currently suffers from a form of schizophrenia. in Phobos, char[] and
wchar[] (and related const/immutable versions) are *NOT* treated as
arrays of char and wchar. They are treated as bi-directional ranges of
dchar. The compiler does not see it this way, it thinks they are arrays.

The error in your assumption is that Range's element type is char, when
in fact it is dchar (Range is the type of the second char[]). So the
is(ElementType!(char[]) : char) fails.

-Steve


So you're saying that I can only use dstrings for anything with the same 
template constraint?


--
/Jacob Carlborg


Re: Read non-UTF8 file

2011-02-20 Thread Nrgyzer
== Auszug aus spir (denis.s...@gmail.com)'s Artikel
> On 02/19/2011 02:42 PM, Nrgyzer wrote:
> > == Auszug aus Stewart Gordon (smjg_1...@yahoo.com)'s Artikel
> >> On 13/02/2011 21:49, Nrgyzer wrote:
> >> 
> >>> It compiles and works as long as the returned char-array/string
of f.readLine() doesn't
> >>> contain non-UTF8 character(s). If it contains such chars,
writeln() doesn't write
> >>> anything to the console. Is there any chance to read such files?
> >> Please post sample input that shows the problem, and the output
generated by replacing the
> >> writeln call with
> >>   writefln("%s", cast(ubyte[]) convertToUTF8(f.readLine()));
> >> so that we can see what it is actually reading in.
> >> Stewart.
> >
> > My file contains the following:
> >
> > �
> > �
> > �
> >
> > Now... and with writefln("%s", cast(ubyte[])
convertToUTF8(f.readLine())); I get the following:
> >
> > [195, 131, 164]
> > [195, 131, 182]
> > [195, 131, 188]
> At first sight, I find your input strange. Actually, it looks like
utf-8 (195
> is common when representing converted latin text). But having 3
times (195,
> 131) which is the code for 'Ã' is weird.
> What is your source text, what is its encoding, and where does it
come from?
> What don't you /start/ and tell us about that?
> Denis

It seems that my input chars doesn't show correctly above... it
contains the following chars:

0xE4 (or 228), 0xF6 (or 246) and 0xFC (or 252)

I used notepad to create the file and saved it as ANSI encoding. The
file is for testing purposes only.


Are function pointers compile time constants?

2011-02-20 Thread d coder
Greetings

I tried to initialize a struct member with a function pointer, and
found that DMD2 did not like it. Are not function pointers compile
time constants? And why they should not be?

Regards
- Cherry


Re: Are function pointers compile time constants?

2011-02-20 Thread Simon

On 20/02/2011 14:59, d coder wrote:

Greetings

I tried to initialize a struct member with a function pointer, and
found that DMD2 did not like it. Are not function pointers compile
time constants? And why they should not be?

Regards
- Cherry


No a function doesn't have an address until the .exe is loaded into 
memory. And with Address space randomisation on 'doze there is no 
reasonable way to make a function pointer a compile time value.


--
My enormous talent is exceeded only by my outrageous laziness.
http://www.ssTk.co.uk


Re: Are function pointers compile time constants?

2011-02-20 Thread d coder
Thanks Simon.


Re: Is std.array.replace supposed to work with char[]?

2011-02-20 Thread Steven Schveighoffer

On Sun, 20 Feb 2011 09:45:36 -0500, Jacob Carlborg  wrote:


On 2011-02-19 23:20, Steven Schveighoffer wrote:

On Sat, 19 Feb 2011 16:23:12 -0500, Jacob Carlborg  wrote:


Compiling the following code with DMD 2.052 on Mac OS X:

import std.array;

void main ()
{
char[] a;
char[] b;
a.replace(1, 3, b);
}

Results in the following error:

test.d(7): Error: template std.array.replace(T,Range) if
(isDynamicArray!(Range) && is(ElementType!(Range) : T)) does not match
any function template declaration
test.d(7): Error: template std.array.replace(T,Range) if
(isDynamicArray!(Range) && is(ElementType!(Range) : T)) cannot deduce
template function from argument types !()(char[],int,int,char[])

What am I doing wrong or isn't std.array.replace supposed to work with
char[]?


D currently suffers from a form of schizophrenia. in Phobos, char[] and
wchar[] (and related const/immutable versions) are *NOT* treated as
arrays of char and wchar. They are treated as bi-directional ranges of
dchar. The compiler does not see it this way, it thinks they are arrays.

The error in your assumption is that Range's element type is char, when
in fact it is dchar (Range is the type of the second char[]). So the
is(ElementType!(char[]) : char) fails.

-Steve


So you're saying that I can only use dstrings for anything with the same  
template constraint?


Yes, dstrings act like arrays according to phobos.  wstrings and strings  
do not.  Some functions have specialized versions for strings, some do  
not.  Expect to be confused...


-Steve


Re: GC: finalization order?!

2011-02-20 Thread Steven Schveighoffer

On Sun, 20 Feb 2011 07:15:06 -0500, Martin Kinkelin  wrote:


I came to the same conclusion. Even if Parent is a struct, it may get
destructed after its Child (e.g., in case the Parent struct is a field
of another class).
What I did is to use a custom allocator for Child, so that Child
instances are not managed by the GC:

--
import std.stdio;
import std.c.stdlib;
import core.exception;

private class Child
{
new(size_t size)
{
writeln("Child.new()");
void* p = malloc(size);
if (!p)
onOutOfMemoryError();
return p;
}
delete(void* p)
{
writeln("Child.delete()");
if (p)
free(p);
}



I hate to deflate your bubble, but this feature (custom handlers for new  
and delete) is going to be deprecated.


However, you can reinflate with the intended replacement.  Essentially,  
you will move allocation handling outside of child and move it to Parent.   
Check out emplace (not sure what module it is).


-Steve


Re: rdmd problems (OS X Leopard, DMD 2.052)

2011-02-20 Thread Magnus Lie Hetland

On 2011-02-19 22:25:31 +0100, Nick Sabalausky said:

[snip]
Unfortunately, rdmd doesn't seem to have gotten much attention lately. 
I've had a few patches for it sitting in bugzilla for a number of 
months. (Not that I'm complaning, I realize there's been other 
priorities.)


I see. Kind of surprising, given that rdmd is distributed in the 
official DMD zip file. But, yeah, no complaints. :)


Actually, if you want, you can grab a version of rdmd.d with my patches 
applied here:

http://www.dsource.org/projects/semitwist/browser/trunk/rdmdAlt.d


Thanks!

(Yes, it is 4 months old, and I can do the match: 3 < 4, but this *is* 
the same as the latest official version just with my patches applied: 
The latest official commit to rdmd.d was one of my patches (albiet 
slightly modified, IIRC))


However, the latest version of DMD I used this with was 2.050, so it 
might still need some updating for 2.052.


Hm. Are most minor releases of DMD backward-incompatible? (Sort of a 
scary prospect to me, at least...)


--
Magnus Lie Hetland
http://hetland.org



Re: Is std.array.replace supposed to work with char[]?

2011-02-20 Thread Jacob Carlborg

On 2011-02-20 17:12, Steven Schveighoffer wrote:

On Sun, 20 Feb 2011 09:45:36 -0500, Jacob Carlborg  wrote:


On 2011-02-19 23:20, Steven Schveighoffer wrote:

On Sat, 19 Feb 2011 16:23:12 -0500, Jacob Carlborg  wrote:


Compiling the following code with DMD 2.052 on Mac OS X:

import std.array;

void main ()
{
char[] a;
char[] b;
a.replace(1, 3, b);
}

Results in the following error:

test.d(7): Error: template std.array.replace(T,Range) if
(isDynamicArray!(Range) && is(ElementType!(Range) : T)) does not match
any function template declaration
test.d(7): Error: template std.array.replace(T,Range) if
(isDynamicArray!(Range) && is(ElementType!(Range) : T)) cannot deduce
template function from argument types !()(char[],int,int,char[])

What am I doing wrong or isn't std.array.replace supposed to work with
char[]?


D currently suffers from a form of schizophrenia. in Phobos, char[] and
wchar[] (and related const/immutable versions) are *NOT* treated as
arrays of char and wchar. They are treated as bi-directional ranges of
dchar. The compiler does not see it this way, it thinks they are arrays.

The error in your assumption is that Range's element type is char, when
in fact it is dchar (Range is the type of the second char[]). So the
is(ElementType!(char[]) : char) fails.

-Steve


So you're saying that I can only use dstrings for anything with the
same template constraint?


Yes, dstrings act like arrays according to phobos. wstrings and strings
do not. Some functions have specialized versions for strings, some do
not. Expect to be confused...

-Steve


I'm confused about how someone can implement a library like this. Every 
time I try to use D2 it's just a PITA to use. I've used D1 and Tango for 
several years and had no problem with that.


I assume this has been discussed, did that resolve in any plans to solve 
this?


--
/Jacob Carlborg


Re: Is std.array.replace supposed to work with char[]?

2011-02-20 Thread bearophile
Jacob Carlborg:

> Every time I try to use D2 it's just a PITA to use. I've used D1 and Tango 
> for 
> several years and had no problem with that.

I use this thread to ask regarding one specific little problem I have with 
strings. I want to generate a random string of AB using the array, map, etc, 
this looks like a possible implementation (in std.random there is no choice() 
function yet):


import std.stdio, std.random, std.string, std.algorithm, std.range;
void main() {
auto m = map!((i){ return "AB"[uniform(0,2)]; })(iota(10));
string s = join(array(m));
writeln(s);
}


It gives this error:
...\dmd\src\phobos\std\array.d(62): Error: result[i] isn't mutable
test.d(5): Error: template instance 
std.array.array!(Map!(__dgliteral1,Iota!(int,uint))) error instantiating

What's the right way to write it in D?

The same code in Python2.x:

from random import choice
s = "".join(choice("AB") for _ in xrange(10))
print s

Bye,
bearophile


Re: Is std.array.replace supposed to work with char[]?

2011-02-20 Thread Steven Schveighoffer
On Sun, 20 Feb 2011 14:51:10 -0500, bearophile   
wrote:



Jacob Carlborg:

Every time I try to use D2 it's just a PITA to use. I've used D1 and  
Tango for

several years and had no problem with that.


I use this thread to ask regarding one specific little problem I have  
with strings. I want to generate a random string of AB using the array,  
map, etc, this looks like a possible implementation (in std.random there  
is no choice() function yet):



import std.stdio, std.random, std.string, std.algorithm, std.range;
void main() {
auto m = map!((i){ return "AB"[uniform(0,2)]; })(iota(10));
string s = join(array(m));
writeln(s);
}


It gives this error:
...\dmd\src\phobos\std\array.d(62): Error: result[i] isn't mutable
test.d(5): Error: template instance  
std.array.array!(Map!(__dgliteral1,Iota!(int,uint))) error instantiating


What's the right way to write it in D?

The same code in Python2.x:

from random import choice
s = "".join(choice("AB") for _ in xrange(10))
print s


Just a blind guess, I have not tested, but maybe it's because the compiler  
is using const(char) as the return type for your delegate literal since  
you never specify one?


-Steve


Re: Is std.array.replace supposed to work with char[]?

2011-02-20 Thread Steven Schveighoffer

On Sun, 20 Feb 2011 13:40:08 -0500, Jacob Carlborg  wrote:




I'm confused about how someone can implement a library like this. Every  
time I try to use D2 it's just a PITA to use. I've used D1 and Tango for  
several years and had no problem with that.


Strings are a sore spot for me, I think the current implementation is a  
hack which leaves much to be desired.  However, it seems that Andrei  
believes the current implementation is not only decent, but actually  
better than any alternative.


I assume this has been discussed, did that resolve in any plans to solve  
this?


I am, in my spare time, working on a way to represent strings that allows  
strings to be what they are and arrays of chars or wchars to be what they  
are.  It is not finished yet, but I've put forth a couple incomplete  
examples.  Search for [review] on the D news group.


Things have gotten quite more complex when I realized that dchar is  
actually not the most natural "element" of a string, since a dchar doesn't  
represent a visible character (or one that a human would interpret as a  
single character) and also that the exact same string can be sometimes  
represented by two distinct sequences of dchars.  When I can finish the  
proposed change, I will probably try integrating it with Phobos to see how  
well it works.


-Steve


foreach: rvalue aggregate expression not finalized!

2011-02-20 Thread Martin Kinkelin
Hi again,

I just came across something odd - if the aggregate expression in a
foreach statement constructs a new struct (returning an rvalue), it
isn't finalized (well, to be precise, its implicit copy isn't).

Test:
--
import std.stdio;

struct A
{
int[3] _data;
string _name;

this(string name) { writeln("A.__ctor() for ", name); _name = name; }
~this() { writeln("A.__dtor() for ", _name); }
this(this) { _name ~= "2"; writeln("Postblit constructor for ", _name); }

A dup()
{
A r = A(_name ~ ".dup");
r._data[] = _data[];
return r;
}

int opApply(int delegate(ref int) dg)
{
int r = 0;
for (int i = 0; i < _data.length; i++)
{
r = dg(_data[i]);
if (r)
break;
}
return r;
}
}

unittest
{
A a = A("a");
a._data = [ 1, 2, 3 ];

writeln("Iterating through a:");
foreach (ref e; a)
writeln(e);

writeln("\nIterating through a.dup:");
{
foreach (ref e; a.dup)
writeln(e);
writeln("ending inner scope");
}
writeln("inner scope ended");
}
--

Output:
--
A.__ctor() for a
Iterating through a:
1
2
3

Iterating through a.dup:
A.__ctor() for a.dup
Postblit constructor for a.dup2
A.__dtor() for a.dup
1
2
3
ending inner scope
inner scope ended
A.__dtor() for a
--

The problem is remedied by assigning a.dup manually to an lvalue and iterating
over that:
--
...
A dup = a.dup;
foreach (ref e; dup)
...
--

Output:
--
A.__ctor() for a
Iterating through a:
1
2
3

Iterating through a.dup:
A.__ctor() for a.dup
Postblit constructor for a.dup2
A.__dtor() for a.dup
1
2
3
ending inner scope
A.__dtor() for a.dup2
inner scope ended
A.__dtor() for a
--

I just figured this out and think it should be considered as bug as it is far
from obvious, at least from my point of view.


Re: GC: finalization order?!

2011-02-20 Thread Martin Kinkelin
Hehe, thx for deflating and pointing in the right direction.


Re: foreach: rvalue aggregate expression not finalized!

2011-02-20 Thread Dmitry Olshansky

On 20.02.2011 23:34, Martin Kinkelin wrote:

Hi again,

I just came across something odd - if the aggregate expression in a
foreach statement constructs a new struct (returning an rvalue), it
isn't finalized (well, to be precise, its implicit copy isn't).

Test:
--
import std.stdio;

struct A
{
 int[3] _data;
 string _name;

 this(string name) { writeln("A.__ctor() for ", name); _name = name; }
 ~this() { writeln("A.__dtor() for ", _name); }
 this(this) { _name ~= "2"; writeln("Postblit constructor for ", _name); }

 A dup()
 {
 A r = A(_name ~ ".dup");
 r._data[] = _data[];
 return r;
 }

 int opApply(int delegate(ref int) dg)
 {
 int r = 0;
 for (int i = 0; i<  _data.length; i++)
 {
 r = dg(_data[i]);
 if (r)
 break;
 }
 return r;
 }
}

unittest
{
 A a = A("a");
 a._data = [ 1, 2, 3 ];

 writeln("Iterating through a:");
 foreach (ref e; a)
 writeln(e);

 writeln("\nIterating through a.dup:");
 {
 foreach (ref e; a.dup)
 writeln(e);
 writeln("ending inner scope");
 }
 writeln("inner scope ended");
}
--

Output:
--
A.__ctor() for a
Iterating through a:
1
2
3

Iterating through a.dup:
A.__ctor() for a.dup
Postblit constructor for a.dup2
A.__dtor() for a.dup
1
2
3
ending inner scope
inner scope ended
A.__dtor() for a
--

The problem is remedied by assigning a.dup manually to an lvalue and iterating
over that:
--
...
 A dup = a.dup;
 foreach (ref e; dup)
...
--

Output:
--
A.__ctor() for a
Iterating through a:
1
2
3

Iterating through a.dup:
A.__ctor() for a.dup
Postblit constructor for a.dup2
A.__dtor() for a.dup
1
2
3
ending inner scope
A.__dtor() for a.dup2
inner scope ended
A.__dtor() for a
--

I just figured this out and think it should be considered as bug as it is far
from obvious, at least from my point of view.

It looks like the manifestation of
http://d.puremagic.com/issues/show_bug.cgi?id=3516
vote up ! ;)

--
Dmitry Olshansky



Re: Are function pointers compile time constants?

2011-02-20 Thread Nick Sabalausky
"Simon"  wrote in message 
news:ijrdif$1nn6$1...@digitalmars.com...
> On 20/02/2011 14:59, d coder wrote:
>> Greetings
>>
>> I tried to initialize a struct member with a function pointer, and
>> found that DMD2 did not like it. Are not function pointers compile
>> time constants? And why they should not be?
>>
>> Regards
>> - Cherry
>
> No a function doesn't have an address until the .exe is loaded into 
> memory. And with Address space randomisation on 'doze there is no 
> reasonable way to make a function pointer a compile time value.
>

I didn't know Windows did that, I thought it was just certain versions of 
Unix/Linux. Do you happen to know which version of Windows was first to have 
it? 




Re: rdmd problems (OS X Leopard, DMD 2.052)

2011-02-20 Thread Nick Sabalausky
"Magnus Lie Hetland"  wrote in message 
news:ijrm9q$259n$1...@digitalmars.com...
> On 2011-02-19 22:25:31 +0100, Nick Sabalausky said:
>
> [snip]
>> Unfortunately, rdmd doesn't seem to have gotten much attention lately. 
>> I've had a few patches for it sitting in bugzilla for a number of months. 
>> (Not that I'm complaning, I realize there's been other priorities.)
>
> I see. Kind of surprising, given that rdmd is distributed in the official 
> DMD zip file. But, yeah, no complaints. :)
>
>> Actually, if you want, you can grab a version of rdmd.d with my patches 
>> applied here:
>> http://www.dsource.org/projects/semitwist/browser/trunk/rdmdAlt.d
>
> Thanks!
>
>> (Yes, it is 4 months old, and I can do the match: 3 < 4, but this *is* 
>> the same as the latest official version just with my patches applied: The 
>> latest official commit to rdmd.d was one of my patches (albiet slightly 
>> modified, IIRC))
>>
>> However, the latest version of DMD I used this with was 2.050, so it 
>> might still need some updating for 2.052.
>
> Hm. Are most minor releases of DMD backward-incompatible? (Sort of a scary 
> prospect to me, at least...)
>

It used to be fairly common for little things to change, but it's becoming 
much less and less common (And, as you've seen, when they do change, they're 
generally very trivial to fix). These days there's typically only these 
three cases where something might break:

A. Someone's code is accidentialy relying on a bug in DMD or Phobos, and 
that bug gets fixed. Not really a frequent occurrance.

B. Certain parts of Phobos are still somewhat in flux (only for D2 though). 
For instance, std.xml is definitely going to get completely replaced.

C. The occasional regression. (Which is less and less common these days, 
because of both an extensive test suite running on multiple OSes and because 
we now have a beta mailing list with people who test each release candidate 
before it's actually relesed.)

We used to have occasional breking changes in the language itself (in 
D2-only), since D2 was the deliberately the "development" branch rather than 
the "stable" branch that D1 has been, but D2's language spec is pretty much 
finalized now.





Re: rdmd problems (OS X Leopard, DMD 2.052)

2011-02-20 Thread Nick Sabalausky
"Nick Sabalausky"  wrote in message 
news:ijs1vp$3b3$1...@digitalmars.com...
> "Magnus Lie Hetland"  wrote in message 
> news:ijrm9q$259n$1...@digitalmars.com...
>> On 2011-02-19 22:25:31 +0100, Nick Sabalausky said:
>>
>> [snip]
>>> Unfortunately, rdmd doesn't seem to have gotten much attention lately. 
>>> I've had a few patches for it sitting in bugzilla for a number of 
>>> months. (Not that I'm complaning, I realize there's been other 
>>> priorities.)
>>
>> I see. Kind of surprising, given that rdmd is distributed in the official 
>> DMD zip file. But, yeah, no complaints. :)
>>
>>> Actually, if you want, you can grab a version of rdmd.d with my patches 
>>> applied here:
>>> http://www.dsource.org/projects/semitwist/browser/trunk/rdmdAlt.d
>>
>> Thanks!
>>
>>> (Yes, it is 4 months old, and I can do the match: 3 < 4, but this *is* 
>>> the same as the latest official version just with my patches applied: 
>>> The latest official commit to rdmd.d was one of my patches (albiet 
>>> slightly modified, IIRC))
>>>
>>> However, the latest version of DMD I used this with was 2.050, so it 
>>> might still need some updating for 2.052.
>>
>> Hm. Are most minor releases of DMD backward-incompatible? (Sort of a 
>> scary prospect to me, at least...)
>>
>
> It used to be fairly common for little things to change, but it's becoming 
> much less and less common (And, as you've seen, when they do change, 
> they're generally very trivial to fix). These days there's typically only 
> these three cases where something might break:
>
> A. Someone's code is accidentialy relying on a bug in DMD or Phobos, and 
> that bug gets fixed. Not really a frequent occurrance.
>
> B. Certain parts of Phobos are still somewhat in flux (only for D2 
> though). For instance, std.xml is definitely going to get completely 
> replaced.
>
> C. The occasional regression. (Which is less and less common these days, 
> because of both an extensive test suite running on multiple OSes and 
> because we now have a beta mailing list with people who test each release 
> candidate before it's actually relesed.)
>
> We used to have occasional breking changes in the language itself (in 
> D2-only), since D2 was the deliberately the "development" branch rather 
> than the "stable" branch that D1 has been, but D2's language spec is 
> pretty much finalized now.
>

I just realized I didn't give a direct answer to your question: I'd say that 
most minor releases of DMD are *not* backward-incompatible.




Re: Is std.array.replace supposed to work with char[]?

2011-02-20 Thread Jacob Carlborg

On 2011-02-20 21:30, Steven Schveighoffer wrote:

On Sun, 20 Feb 2011 13:40:08 -0500, Jacob Carlborg  wrote:




I'm confused about how someone can implement a library like this.
Every time I try to use D2 it's just a PITA to use. I've used D1 and
Tango for several years and had no problem with that.


Strings are a sore spot for me, I think the current implementation is a
hack which leaves much to be desired. However, it seems that Andrei
believes the current implementation is not only decent, but actually
better than any alternative.


I assume this has been discussed, did that resolve in any plans to
solve this?


I am, in my spare time, working on a way to represent strings that
allows strings to be what they are and arrays of chars or wchars to be
what they are. It is not finished yet, but I've put forth a couple
incomplete examples. Search for [review] on the D news group.

Things have gotten quite more complex when I realized that dchar is
actually not the most natural "element" of a string, since a dchar
doesn't represent a visible character (or one that a human would
interpret as a single character) and also that the exact same string can
be sometimes represented by two distinct sequences of dchars. When I can
finish the proposed change, I will probably try integrating it with
Phobos to see how well it works.

-Steve


Oh, I remember that thread(s). It got so overly complicated so I stopped 
reading it.


--
/Jacob Carlborg


regex.d(339): *+? not allowed in atom

2011-02-20 Thread Jacob Carlborg
I'm using the regex module in Phobos and getting the following runtime 
exception:


regex.d(339): *+? not allowed in atom

What does that mean and what's an "atom" in this case?
I'm using DMD 2.052 on Mac OS X.

--
/Jacob Carlborg


Re: Is std.array.replace supposed to work with char[]?

2011-02-20 Thread bearophile
Steven Schveighoffer:

> Just a blind guess, I have not tested, but maybe it's because the compiler  
> is using const(char) as the return type for your delegate literal since  
> you never specify one?

Right, this works:

import std.stdio, std.random, std.string, std.algorithm, std.range;
void main() {
string s = array(map!((i){ return cast(char)("AB"[uniform(0,2)]); 
})(iota(10))).idup;
writeln(s);
}

Thank you, bye,
bearophile


Re: Is std.array.replace supposed to work with char[]?

2011-02-20 Thread bearophile
http://d.puremagic.com/issues/show_bug.cgi?id=5630


Re: Is std.array.replace supposed to work with char[]?

2011-02-20 Thread Steven Schveighoffer

On Sun, 20 Feb 2011 17:10:28 -0500, Jacob Carlborg  wrote:


On 2011-02-20 21:30, Steven Schveighoffer wrote:

On Sun, 20 Feb 2011 13:40:08 -0500, Jacob Carlborg  wrote:




I'm confused about how someone can implement a library like this.
Every time I try to use D2 it's just a PITA to use. I've used D1 and
Tango for several years and had no problem with that.


Strings are a sore spot for me, I think the current implementation is a
hack which leaves much to be desired. However, it seems that Andrei
believes the current implementation is not only decent, but actually
better than any alternative.


I assume this has been discussed, did that resolve in any plans to
solve this?


I am, in my spare time, working on a way to represent strings that
allows strings to be what they are and arrays of chars or wchars to be
what they are. It is not finished yet, but I've put forth a couple
incomplete examples. Search for [review] on the D news group.

Things have gotten quite more complex when I realized that dchar is
actually not the most natural "element" of a string, since a dchar
doesn't represent a visible character (or one that a human would
interpret as a single character) and also that the exact same string can
be sometimes represented by two distinct sequences of dchars. When I can
finish the proposed change, I will probably try integrating it with
Phobos to see how well it works.

-Steve


Oh, I remember that thread(s). It got so overly complicated so I stopped  
reading it.


Yeah, UTF is so overly complicated, it's difficult to properly implement  
it.


-Steve


Re: Are function pointers compile time constants?

2011-02-20 Thread Steven Schveighoffer

On Sun, 20 Feb 2011 16:23:14 -0500, Nick Sabalausky  wrote:


"Simon"  wrote in message
news:ijrdif$1nn6$1...@digitalmars.com...

On 20/02/2011 14:59, d coder wrote:

Greetings

I tried to initialize a struct member with a function pointer, and
found that DMD2 did not like it. Are not function pointers compile
time constants? And why they should not be?

Regards
- Cherry


No a function doesn't have an address until the .exe is loaded into
memory. And with Address space randomisation on 'doze there is no
reasonable way to make a function pointer a compile time value.



I didn't know Windows did that, I thought it was just certain versions of
Unix/Linux. Do you happen to know which version of Windows was first to  
have

it?


Probably the first one with dlls?  I don't see how else you could have  
dlls, because you can't just say "this function will always be at address  
12345, and no other function anyone else ever compiles can take that spot".


That being said, I'm not sure why the OP's issue couldn't be solved --  
clearly position independent code works (and that is statically created),  
why couldn't a reference to that function also be created in a struct  
initializer?  Is it a limitation of the linker?


-Steve


Re: foreach over string enum

2011-02-20 Thread Daniel Murphy
"Jesse Phillips"  wrote in message 
news:ij2drt$1mq3$1...@digitalmars.com...
>
> Magic.
>
> No really, the best I can tell is that the compiler will try to run the 
> foreach loop at compile-time if there is something in the body that must 
> be evaluated at compile time.
>

Actually this happens because __traits(allMembers ...) returns a TypeTuple 
of string literals.
TypeTuples can contain elements of different types (and types themselves as 
elements), so in order for them to be used in foreach loops, they MUST be 
unrolled.

It's not something in the body, it's the iterable itself that forces 
unrolling.

http://www.digitalmars.com/d/2.0/tuple.html

You can do LOTS of cool stuff with this:

switch(x)
{
  foreach(i; TypeTuple!(1, 2, 6, 8, 17))
case i:
  doSomething();
}

---

class C {}
class D : C {}
class E : C {}
class F : C {}
class G : C {}

C[] list;
foreach(T; TypeTuple!(D, E, F, G))
  list ~= new T();



int id = runtimeInput();

foreach(i, T; TypeTuple!(C, D ,E, F, G, H))
  if (i == id)
return new T(); 




wstring format

2011-02-20 Thread Bekenn
Is there a wstring version of string.format?  I can't seem to find it 
anywhere...


Re: problem while updating to 2.052

2011-02-20 Thread novice2
Christian Köstlin Wrote:

> unfortunately not ... I looked several minutes at the stacktrace (would 

i am sorry for offtopic, but
how you produce stacktrace? sometime i very want to see it...


Re: wstring format

2011-02-20 Thread Jonathan M Davis
On Sunday 20 February 2011 21:26:05 Bekenn wrote:
> Is there a wstring version of string.format?  I can't seem to find it
> anywhere...

There probably isn't one. A lot of functions are string-only and do not work 
with char[], wchar[], dchar[], wstring, or dstring. That may or may not change 
in the future, but the result is that often the best way to do things is to 
just 
use string everywhere and then convert to one of the others when you need to.

A lot of the problem is that to implement string functions for each string type 
tends to up forcing you to actually have at least 3 different implementations 
for 
the same function. Range-based functions treat all strings as ranges of dchar, 
so _they_ tend to work with any string type, there are downsides to some 
functions treating a string as a range of dchar, so the functions in std.string 
don't do that, and most functions that specifically want some type of string 
don't do that. It's generally just the functions which deal with generic ranges 
which treat strings as ranges.

- Jonathan M Davis


Re: problem while updating to 2.052

2011-02-20 Thread Jonathan M Davis
On Sunday 20 February 2011 22:11:13 novice2 wrote:
> Christian Köstlin Wrote:
> > unfortunately not ... I looked several minutes at the stacktrace (would
> 
> i am sorry for offtopic, but
> how you produce stacktrace? sometime i very want to see it...

1. It doesn't work on Windows yet, I don't believe. So, for now, you're out of 
luck. I don't know about Mac OS X.

2. On Linux, any Throwable (be it an Exception or an Error) which escapes main 
will print a stack trace.  IIRC, you also get a stack trace when you convert an 
Exception to a string. Regardless, you need to have linked with -L--export-
dynamic to get the function names to work, but that's in the dmd.conf, so you 
should always be building with it.

- Jonathan M Davis


Re: problem while updating to 2.052

2011-02-20 Thread novice2
Jonathan M Davis, thank you for explanation,
but i am on windows :(