Re: Is this a compiler bug, or a breaking fix/enhancement?

2013-05-28 Thread Kenji Hara

On Wednesday, 29 May 2013 at 04:44:16 UTC, estew wrote:

Hi All,

I updated to dmd 2.063 today and all has been going smoothly 
until I decided to try out msgpack.d. I got an error compiling 
the msgpack.d unittest, so out of interest I decided to check 
this using dmd2.062 and it compiled and ran fine.


I admit I don't really understand whether the code should work 
or if it is broken and dmd 2.063 now correctly issues an error. 
To my untrained-D-eye the code looks OK, so any advice would be 
appreciated.



ERROR:
---
msgpack.d(3215): Error: cannot resolve type for value.as!(E).

EXAMPLE:
---
import std.stdio;
import std.traits;

enum E : int {F = -20}
struct S {
int val;
@trusted @property T as(T)()
if(is(Unqual!T == int) && !is(Unqual!T == enum))
{
return cast(T)(val);
}
@trusted @property T as(T)()
if(is(Unqual!T == enum))
{
return cast(T)as!(OriginalType!T);
}
}

void main() {
S val = S(-20);
assert(val.as!int == -20);
assert(val.as!E == E.F); // val.as!E causes a compile time 
error.

}
---


This is a compiler regression in 2.063 release.
http://d.puremagic.com/issues/show_bug.cgi?id=10197

Kenji Hara


Re: Linker error

2013-05-28 Thread Namespace

Davis (Debug) wird erzeugt

Performing main compilation...

Current dictionary: 
C:\Users\Besitzer\Documents\Projects\Davis\Davis


D:\D\dmd2\windows\bin\dmd.exe -debug -gc "main.d"  
"-ID:\D\dmd2\src\ext" "-ID:\D\dmd2\src\druntime\import" 
"-ID:\D\dmd2\src\phobos" "-odobj\Debug" 
"-ofC:\Users\Besitzer\Documents\Projects\Davis\Davis\bin\Debug\Davis.exe"



OPTLINK (R) for Win32  Release 8.00.12

Copyright (C) Digital Mars 1989-2010  All rights reserved.

http://www.digitalmars.com/ctg/optlink.html

D:\D\dmd2\src\ext\Dgame\build\lib\Release\DgameGraphics.lib(object) 
 Offset 00DF6H Record Type 0091


 Error 1: Previous Definition Different : 
_D60D:\D\dmd2\windows\bin\..\..\src\druntime\import\object.di.6112__ModuleInfoZ


D:\D\dmd2\src\ext\Dgame\build\lib\Release\DgameGraphics.lib(object) 
 Offset 00E85H Record Type 00C3


 Error 1: Previous Definition Different : 
_D60D:\D\dmd2\windows\bin\..\..\src\druntime\import\object.di.617__arrayZ


D:\D\dmd2\src\ext\Dgame\build\lib\Release\DgameGraphics.lib(object) 
 Offset 00EAFH Record Type 00C3


 Error 1: Previous Definition Different : 
_D60D:\D\dmd2\windows\bin\..\..\src\druntime\import\object.di.618__assertFiZv


D:\D\dmd2\src\ext\Dgame\build\lib\Release\DgameGraphics.lib(object) 
 Offset 00ED9H Record Type 00C3


 Error 1: Previous Definition Different : 
_D60D:\D\dmd2\windows\bin\..\..\src\druntime\import\object.di.6115__unittest_failFiZv


D:\D\dmd2\src\ext\Dgame\build\lib\Release\DgameCore.lib(object)  
Offset 00DF6H Record Type 0091


 Error 1: Previous Definition Different : 
_D60D:\D\dmd2\windows\bin\..\..\src\druntime\import\object.di.6412__ModuleInfoZ


D:\D\dmd2\src\ext\Dgame\build\lib\Release\DgameCore.lib(object)  
Offset 00F0AH Record Type 00C3


 Error 1: Previous Definition Different : 
_D60D:\D\dmd2\windows\bin\..\..\src\druntime\import\object.di.647__arrayZ


D:\D\dmd2\src\ext\Dgame\build\lib\Release\DgameCore.lib(object)  
Offset 00F34H Record Type 00C3


 Error 1: Previous Definition Different : 
_D60D:\D\dmd2\windows\bin\..\..\src\druntime\import\object.di.648__assertFiZv


D:\D\dmd2\src\ext\Dgame\build\lib\Release\DgameCore.lib(object)  
Offset 00F5EH Record Type 00C3


 Error 1: Previous Definition Different : 
_D60D:\D\dmd2\windows\bin\..\..\src\druntime\import\object.di.6415__unittest_failFiZv


obj\Debug\Davis.obj(Davis)

 Error 42: Symbol Undefined 
_D5Dgame4Math7Vector214__T7Vector2TsZ7Vector26__dtorMFNaZv


--- errorlevel 9

Exit code 9

Erzeugung abgeschlossen -- 2 Fehler, 0 Warnungen



- Fertig -


Build: 2 Fehler, 0 Warnungen


Issue with linking to dll

2013-05-28 Thread Stephen Jones
I am trying to get my head around linking to dlls, and have been 
playing around with the mydll sample distributed with dmd2.062. 
If I create mydll.lib from implib with the driver (implib /noi /s 
mydll.lib mydll.dll) I get a lib file that I can link in with an 
interface file (dmd test.d mydll.di mydll.lib) to get a working 
exe.


But if I gendef a .def file off the dll (gendef mydll.dll), and 
reconstruct the lib file from the def file (implib /noi /s 
mydll.def) I can no longer use the d interface file to construct 
a valid exe (dmd test.d mydll.di mydll.lib). The error returned 
is:


...\lib\phobos.lib(dmain2)
Error 42: Symbol undefined _D5mydll8dllprintFZv

Which is odd because the def file is:

;
; Definition file of MYDLL.DLL
; Automatic generated by gendef
; written by Kai Tietz 2008
;
LIBRARY "MYDLL.DLL"
EXPORTS
D5mydll8dllprintFZv

Which does not underscore the symbol. I have tested implib with 
/system switch rather than /s, and without the /s switch at all, 
in all cases I get the same error.


If I open both mydll.lib files (from dll and from def) I find 
that the from dll lib file does contain the symbol with an 
underscore, whereas the lib from the def file does not.


Have I missed something to do with gendef?


Re: Linker error

2013-05-28 Thread alex

On Tuesday, 28 May 2013 at 22:28:50 UTC, Namespace wrote:
I don't even understand the error. Where is a previous 
definition? And why?

Seems like I have to switch back to 2.062.


In the case of using Mono-D,
could you give me your build log please? That might help!

When copypasting the command, please also try to execute the 
command in a terminal to try to get an argument configuration 
which does not throw. Ah, wait, multiple definitions..could it be 
that it takes phobos.a or so twice?


Re: Is this a compiler bug, or a breaking fix/enhancement?

2013-05-28 Thread estew

Here's a link to the msgpack.d source:
https://github.com/msgpack/msgpack-d/blob/master/src/msgpack.d

And the error is on line 3211, not 3215 as mentioned in the 
previous post.


Thanks,
Stewart


Is this a compiler bug, or a breaking fix/enhancement?

2013-05-28 Thread estew

Hi All,

I updated to dmd 2.063 today and all has been going smoothly 
until I decided to try out msgpack.d. I got an error compiling 
the msgpack.d unittest, so out of interest I decided to check 
this using dmd2.062 and it compiled and ran fine.


I admit I don't really understand whether the code should work or 
if it is broken and dmd 2.063 now correctly issues an error. To 
my untrained-D-eye the code looks OK, so any advice would be 
appreciated.



ERROR:
---
msgpack.d(3215): Error: cannot resolve type for value.as!(E).

EXAMPLE:
---
import std.stdio;
import std.traits;

enum E : int {F = -20}
struct S {
int val;
@trusted @property T as(T)()
if(is(Unqual!T == int) && !is(Unqual!T == enum))
{
return cast(T)(val);
}
@trusted @property T as(T)()
if(is(Unqual!T == enum))
{
return cast(T)as!(OriginalType!T);
}
}

void main() {
S val = S(-20);
assert(val.as!int == -20);
assert(val.as!E == E.F); // val.as!E causes a compile time 
error.

}
---


Thanks,
Stewart


Re: Failed to sort range

2013-05-28 Thread Sergei Nosov

On Tuesday, 28 May 2013 at 20:43:32 UTC, Ali Çehreli wrote:

On 05/28/2013 12:47 PM, Anthony Goins wrote:

> sort!("a
> This worked for me with the code at your link.

I've noticed that too. The reason that works is because in that 
case it uses Tim Sort. Apparently, the Tim Sort algorithm does 
not expose the bugs that were in the code.


Ali


I believe the issues with opIndex and opSlice caused the bug. 
Now, those are fixed, and I guess it's safe to say that range 
interface is correct.


Although, I remember a discussion in the NG about somewhat 
"standardized" testing facilities for ranges ( 
http://forum.dlang.org/thread/20130321130858.3ef4@unknown ). 
Precisely the semantic/runtime behavior, to supplement 
isSomeRange templates family. Do you, guys know, was there any 
activities on it?


Re: Linker error

2013-05-28 Thread Namespace
I don't even understand the error. Where is a previous 
definition? And why?

Seems like I have to switch back to 2.062.


Re: Linker error

2013-05-28 Thread Namespace

This is still there with the new release of 2.063.

[quote]
OPTLINK (R) for Win32  Release 8.00.12
Copyright (C) Digital Mars 1989-2010  All rights reserved.
http://www.digitalmars.com/ctg/optlink.html
Graphics.lib(object)  Offset 201F6H Record Type 0091
 Error 1: Previous Definition Different : 
_D60D:\D\dmd2\windows\bin\..\..\src\druntime\import\object.di.6112__ModuleInfoZ

Graphics.lib(object)  Offset 20285H Record Type 00C3
 Error 1: Previous Definition Different : 
_D60D:\D\dmd2\windows\bin\..\..\src\druntime\import\object.di.617__arrayZ

Graphics.lib(object)  Offset 202AFH Record Type 00C3
 Error 1: Previous Definition Different : 
_D60D:\D\dmd2\windows\bin\..\..\src\druntime\import\object.di.618__assertFiZv

Graphics.lib(object)  Offset 202D9H Record Type 00C3
 Error 1: Previous Definition Different : 
_D60D:\D\dmd2\windows\bin\..\..\src\druntime\import\object.di.6115__unittest_failFiZv

Core.lib(object)  Offset 00EF8H Record Type 0091
 Error 1: Previous Definition Different : 
_D60D:\D\dmd2\windows\bin\..\..\src\druntime\import\object.di.6412__ModuleInfoZ

Core.lib(object)  Offset 00F87H Record Type 00C3
 Error 1: Previous Definition Different : 
_D60D:\D\dmd2\windows\bin\..\..\src\druntime\import\object.di.647__arrayZ

Core.lib(object)  Offset 00FB1H Record Type 00C3
 Error 1: Previous Definition Different : 
_D60D:\D\dmd2\windows\bin\..\..\src\druntime\import\object.di.648__assertFiZv

Core.lib(object)  Offset 00FDBH Record Type 00C3
 Error 1: Previous Definition Different : 
_D60D:\D\dmd2\windows\bin\..\..\src\druntime\import\object.di.6415__unittest_failFiZv

obj\Debug\Davis.obj(Davis)
 Error 42: Symbol Undefined 
_D5Dgame4Math7Vector214__T7Vector2TsZ7Vector26__dtorMFNaZv

--- errorlevel 9
Exit code 9
[/quote]

What is the matter? It works pretty well with 2.062.


direct conversion to integral type for floor, ceil, and friends that return integer as real

2013-05-28 Thread Timothee Cour
What's the most efficient way to convert a float/double/real to an integer
type with a specified rounding scheme (eg floor/ceil etc)?

Is there anything besides:
int x=floor(1.2); ?
there's also
core.stdc.math.floor{l,f,}

Because these first convert to floating point representation and then then
the conversion to int happens.

Could we support the following instead:

T floor(T,S)(S x) if (/+insert good template constraits+/) {
//right now just return existing floor and convert to T but later can
provide more efficient direct implementation, so user can start using it
right now.
}

and friends, modeled after std.conv.to.


Re: Immutability vs reference types

2013-05-28 Thread Ali Çehreli

On 05/27/2013 05:24 PM, Francois Chabot wrote:

> If with immutable(Type)[], I can have a re-assignable reference
> to arrays of immutable data, I really should be able to have some
> form of syntactical equivalent for single instances. But there
> just doesn't seem to be one. Immutability for reference types
> seem to always apply both to the referenced data as well as the
> reference itself no matter what.

I agree.

I've been puzzled by this recently as well:

class C
{}

void main()
{
const(C) c;
c = new const(C);// <-- compilation error
}

That is silly because not c, but what it refers to is const. It is 
supposed to be "turtles all the way down", not "turtles all the way up." :)


Somehow this issue feels even more strange on 'const' because 'const' 
doesn't bring any requirement on the data anyway. It only says that "I 
shall not mutate". It should be fine with everybody... The variable 
should be able to go ahead and not mutate something else. :)


Ali



Re: iteration over a string

2013-05-28 Thread bearophile

Timothee Cour:


3A)
why not having an Enumerate(R) containing a single 'opApply' 
public method,


Unfortunately opApply doesn't not work well with all the other 
range-based functions.
Also that Enumerate code is for illustrative purposes, it's not 
meant to be good library code.




3B)
requiring one to use 'myrange.enumerate' for inputRanges and 
'myrange' in

other cases is bad for generic programming and user time.


Generic programming must know if you are iterating only on items 
or on index-item pairs. As Python Zen says, explicit is better 
than implicit.




This is a very
frequent idiom that should just work out of the box. Language 
is more

orthogonal and less surprising in this case.


Yet Python designers have preferred to use enumerate instead of 
messing with the Python for.


Bye,
bearophile


Re: Where does the log get written when there's a core dump?

2013-05-28 Thread Adam D. Ruppe

On Tuesday, 28 May 2013 at 21:06:14 UTC, Gary Willoughby wrote:
playing and I got a message of a seg fault and a core dump 
written to a log.


like this?

Segmentation fault (core dumped)


That's actually more of a linux thing than a D thing. The file 
will be called "core" in the current directory. If your 
executable file was called test, you can check out the core dump 
with gdb like this:


 gdb ./test core


$ ulimit -c 5 # enable core dumps, see man bash for more info
$ ./test # this program writes to a null pointer
Segmentation fault (core dumped)

$ ls -lh core # newly created
-rw--- 1 me users 1.4M 2013-05-28 17:13 core

$ gdb ./test core # load the thing in the debugger
/* snip some irrelevant stuff */
Core was generated by `./test'.
Program terminated with signal 11, Segmentation fault.
#0  0x0805ca31 in _Dmain ()
(gdb)


Where does the log get written when there's a core dump?

2013-05-28 Thread Gary Willoughby
I was trying some funky stuff with D, not real code just playing 
and I got a message of a seg fault and a core dump written to a 
log. I just wondered where these logs are written to. It's not 
immediately apparent where it is.


Re: iteration over a string

2013-05-28 Thread Timothee Cour
Thanks for the enumerate pointer.

3A)
why not having an Enumerate(R) containing a single 'opApply' public method,
to avoid returning tuples in 'front()'

3B)
requiring one to use 'myrange.enumerate' for inputRanges and 'myrange' in
other cases is bad for generic programming and user time. This is a very
frequent idiom that should just work out of the box. Language is more
orthogonal and less surprising in this case. That being said, enumerate
still has its value (eg for foreach (i, k, v;
associativeArray.byPair.enumerate()) )

3C)
if no-one can find a concrete argument why it would cause clashing /
confusion, I will file an enhancement request for it (dip sounds overkill)



On Tue, May 28, 2013 at 10:31 AM, bearophile wrote:

> Timothee Cour:
>
>
>  Where do you think it can cause clashing?
>>
>
> I don't know.
>
> But my solution is to introduce a simple "enumerate" range:
> http://d.puremagic.com/issues/**show_bug.cgi?id=5550
>
> So if you have a range and you don't need indexes you use:
>
> foreach (item; myrange) {}
>
> If you also want an index:
>
> foreach (index, item; myrange.enumerate) {}
>
> This is the solution used by Python, it's clean, and it doesn't make the
> foreach syntax & compiler more complex. Later the compiler should optimize
> this idiom well.
>
> Bye,
> bearophile
>


Re: Failed to sort range

2013-05-28 Thread Ali Çehreli

On 05/28/2013 12:47 PM, Anthony Goins wrote:

> sort!("a
> This worked for me with the code at your link.

I've noticed that too. The reason that works is because in that case it 
uses Tim Sort. Apparently, the Tim Sort algorithm does not expose the 
bugs that were in the code.


Ali



Re: Failed to sort range

2013-05-28 Thread Anthony Goins

On Tuesday, 28 May 2013 at 12:57:12 UTC, Sergei Nosov wrote:

Hi!

I'm trying to implement an array, which uses malloc to allocate 
memory. Also, I want to implement a random access range 
interface for it.


That went pretty well, until I tried to sort it. Sorting 
function asserted "Failed to sort range of type Array!(int)."


I've spent quite some time trying to figure out what's going on 
with no success.


The implementation can be found at:
https://gist.github.com/snosov1/5662471

I used
DMD64 D Compiler v2.062 and
LDC - the LLVM D compiler (trunk): based on DMD v2.062 and LLVM 
3.2svn
on Ubuntu. Phobos version was the one that came with the dmd 
compiler.


Does anyone have any ideas what's wrong with the code I've 
provided?


sort!("a

Re: Failed to sort range

2013-05-28 Thread Sergei Nosov

On Tuesday, 28 May 2013 at 18:38:01 UTC, Ali Çehreli wrote:

On 05/28/2013 11:31 AM, Ali Çehreli wrote:

>  @property Array!T opSlice(size_t i, size_t j) {
>  // ...
>  ret.front_ = i;
>
> I feel like the initialization of front_ above is not right
either.
> Imagine quick sort where we are slicing the right-hand side
of a range
> as [0..10], which has already been sliced before. Setting
front_ to 0
> would be wrong because then opIndex would still be counting
from the
> beginning of the original elements.

My explanation is wrong but I think there is still a bug. 
Imagine we are in the right-hand range that has been sliced as 
[10..$]. Now front_ is 10 and all is good: s[0] provides the 
arr[10] of the original array.


Now imagine our slice again by [5..$]. s_further[0] should 
provide arr[15] of the original array but your setting front_ 
to 5 would unfortunately provide arr[5].


Ali


Yes, exactly.

I believe, the same fix should be applied here: front_ + i, 
front_ + j. It passes the sorting test.


Thank you so much, Ali. Feels like to be back in school again.


Re: Failed to sort range

2013-05-28 Thread Ali Çehreli

On 05/28/2013 11:31 AM, Ali Çehreli wrote:

>  @property Array!T opSlice(size_t i, size_t j) {
>  // ...
>  ret.front_ = i;
>
> I feel like the initialization of front_ above is not right either.
> Imagine quick sort where we are slicing the right-hand side of a range
> as [0..10], which has already been sliced before. Setting front_ to 0
> would be wrong because then opIndex would still be counting from the
> beginning of the original elements.

My explanation is wrong but I think there is still a bug. Imagine we are 
in the right-hand range that has been sliced as [10..$]. Now front_ is 
10 and all is good: s[0] provides the arr[10] of the original array.


Now imagine our slice again by [5..$]. s_further[0] should provide 
arr[15] of the original array but your setting front_ to 5 would 
unfortunately provide arr[5].


Ali



Re: Failed to sort range

2013-05-28 Thread Ali Çehreli

On 05/28/2013 11:19 AM, Sergei Nosov wrote:

> Do you mean it's a good idea
> to separate storage and access (via range) to the container? Like
> std.container's containers (heh) have nested Range struct?

Yes, that is generally the right approach. Note that built-in arrays 
have a similar design which may not be obvious: The storage is in an 
array that is owned by the D runtime. (The exception is fixed-length 
arrays where the entire array may be on the stack.)


Then, the elements are accessed by slices, which are ranges. Consuming 
the slice does not invalidate the consumed elements (as long as there 
are other accesses to those elements.)


>> ref T opIndex(size_t idx) {
>> return vec_[front_ + idx];
>> }
>>
>> It is a start but still not the solution. Sorry... :/
>
> That's obviously a bug, thanks. But, yeah, not the last one =)

@property Array!T opSlice(size_t i, size_t j) {
// ...
ret.front_ = i;

I feel like the initialization of front_ above is not right either. 
Imagine quick sort where we are slicing the right-hand side of a range 
as [0..10], which has already been sliced before. Setting front_ to 0 
would be wrong because then opIndex would still be counting from the 
beginning of the original elements.


Ali



Re: Failed to sort range

2013-05-28 Thread Sergei Nosov

Thx, Ali!

1) First, an observation: This Array design conflates the 
concepts of container and range. If there are actual elements 
that are being stored (as opposed to elements being generated), 
it is better tha a range merely provides access to those 
elements. popFront should consume the range, not the container. 
(Unless it is some special type of range with the 
responsibility of removing elements from the container.)


I'm not sure I understand this correctly. Do you mean it's a good 
idea to separate storage and access (via range) to the container? 
Like std.container's containers (heh) have nested Range struct?


2) As a minor comment, "back" usually means the last element 
but your back_ has the meaning of one-past-the-last element.


Yeah, that's probably a not-so-good name.

3) You have to rethink the indexing as well. opIndex indexes 
directly on vec_:


ref T opIndex(size_t idx) {
return vec_[idx];
}

However, we may be on a slice which has already been sliced 
before (as is the case in quick sort, which 
SwapStrategy.unstable uses). So, I think opIndex should add 
front_ to idx:


ref T opIndex(size_t idx) {
return vec_[front_ + idx];
}

It is a start but still not the solution. Sorry... :/


That's obviously a bug, thanks. But, yeah, not the last one =) I 
updated the gist. And also, replaced the malloc call with new. 
The behavior is the same.




Re: iteration over a string

2013-05-28 Thread bearophile

Timothee Cour:


Where do you think it can cause clashing?


I don't know.

But my solution is to introduce a simple "enumerate" range:
http://d.puremagic.com/issues/show_bug.cgi?id=5550

So if you have a range and you don't need indexes you use:

foreach (item; myrange) {}

If you also want an index:

foreach (index, item; myrange.enumerate) {}

This is the solution used by Python, it's clean, and it doesn't 
make the foreach syntax & compiler more complex. Later the 
compiler should optimize this idiom well.


Bye,
bearophile


Re: iteration over a string

2013-05-28 Thread Jonathan M Davis
On Tuesday, May 28, 2013 03:05:52 Timothee Cour wrote:
> 2A)
> Thanks for your answer;
> 
> You skipped over this one, which I don't understand:
> > string a="ΩΩab";
> > auto b1=a.map!(a=>"<"d~a~">"d).array;
> > writeln(b1);//["<Ω>", "<Ω>", "", "", "", ""]
> > Why are there 2 empty strings at the end? (one per Omega if you vary the
> 
> number of such symbols in the string).
> 
> The above is just weird; is that a bug?

I didn't look into it, since I was in a hurry, but it definitely looks like a 
bug.

> 2B)
> 
> > The reason that we don't do that is mostly because it makes pretty much
> 
> no sense to iterate over ranges of code units 99.99% of the time
> 
> And yet "ΩΩab".map!foo seems to operate on code units and in order to
> operate on code points we need "ΩΩab".stride(1).map!foo, so isn't it
> inconsistent with the fact that std.algorithm.find("ΩΩab") operates on code
> points ?

Any and all range-based functions operate on code points when operating on 
strings. If they do otherwise, it's a bug - probably due to a failed attempt 
to optimize for strings.

> 2C)
> 
> > Remember that ranges don't provide indices unless they're random access,
> 
> For input ranges ranges, I don't understand why the compiler can't accept
> the foreach(i,ai;a) syntax:
> 
> it should behave as follows:
> foreach(i , ai; a){expr}
> 
> rewritten as:
> for(size_t i=0, ai=a.front; !a.empty; a.popFront;){expr}
> 
> but it doesn't compile (it only accepts foreach(ai;a){expr}

foreach and ranges don't do anything with indices. I believe that the reason 
that's usually brought up as to why is that for some types of ranges, it would 
make no sense. There's probably an enhancement request open for it though as 
it would certainly seem to make sense for most ranges. Though if you're 
looking at the counter as being an index, it really doesn't make sense for 
anything other than random-access ranges, as only they have indexing 
operations.

In any case, if you're feeling fancy, you can use iota and zip to solve the 
problem:

 foreach(i, e; zip(iota(0, size_t.max), range))
 {...}

and lockstep uses opApply to add an index, but it doesn't work with just one 
range, so it wouldn't help with just giving foreach an index with normal range 
iteration.

- Jonathan M Davis


Re: Failed to sort range

2013-05-28 Thread Ali Çehreli

On 05/28/2013 05:57 AM, Sergei Nosov wrote:

Hi!

I'm trying to implement an array, which uses malloc to allocate memory.
Also, I want to implement a random access range interface for it.

That went pretty well, until I tried to sort it. Sorting function
asserted "Failed to sort range of type Array!(int)."

I've spent quite some time trying to figure out what's going on with no
success.

The implementation can be found at:
https://gist.github.com/snosov1/5662471

I used
DMD64 D Compiler v2.062 and
LDC - the LLVM D compiler (trunk): based on DMD v2.062 and LLVM 3.2svn
on Ubuntu. Phobos version was the one that came with the dmd compiler.

Does anyone have any ideas what's wrong with the code I've provided?


1) First, an observation: This Array design conflates the concepts of 
container and range. If there are actual elements that are being stored 
(as opposed to elements being generated), it is better tha a range 
merely provides access to those elements. popFront should consume the 
range, not the container. (Unless it is some special type of range with 
the responsibility of removing elements from the container.)


2) As a minor comment, "back" usually means the last element but your 
back_ has the meaning of one-past-the-last element.


3) You have to rethink the indexing as well. opIndex indexes directly on 
vec_:


ref T opIndex(size_t idx) {
return vec_[idx];
}

However, we may be on a slice which has already been sliced before (as 
is the case in quick sort, which SwapStrategy.unstable uses). So, I 
think opIndex should add front_ to idx:


ref T opIndex(size_t idx) {
return vec_[front_ + idx];
}

It is a start but still not the solution. Sorry... :/

Ali



Re: Why does this snippet print the enum identifiers instead of their values?

2013-05-28 Thread Kenji Hara

On Tuesday, 28 May 2013 at 11:49:25 UTC, Gary Willoughby wrote:

Why does the following snippet print:

"Started name revision" instead of "Started my-app 1.0a"?

import std.stdio;

enum application : string
{
name = "my-app",
revision = "1.0a",
}

void main(string[] arguments)
{
	writefln("Started %s %s", application.name, 
application.revision);

}


This is not compiler bug, it is an intended behavior of writefln.

writefln always print the name for named enum members.

enum E1 { a, b }
writefln("%s", E1.a);// prints a

enum E2 { a = 10, b = 20 }
writefln("%s", E2.a);// prints a

enum E3 : string { a = "aaa", b = "bbb" }
writefln("%s", Ee.a);// prints a

If you want to make a set of compile time values, you can write 
as follows:


struct application  // or class
{
enum name = "my-app",
 revision = "1.0a";
}

Kenji Hara


Re: Why does this snippet print the enum identifiers instead of their values?

2013-05-28 Thread bearophile

On Tuesday, 28 May 2013 at 14:35:22 UTC, Jesse Phillips wrote:

I do not believe this is a bug.


You are right, I was wrong. writeln is meant to write the name of 
enums and not their contents.


Bye,
bearophile


Re: Why does this snippet print the enum identifiers instead of their values?

2013-05-28 Thread Jesse Phillips
I do not believe this is a bug. You should be able to print the 
value by casting to string. (to!() will not work as it will 
provide the same results)


Usually enumeration values are not descriptive for how they 
should be used. And when printing to the screen it is usually for 
debugging or some other task where a meaningful name would be 
better.


String enum's are a little different since there value can be 
fairly descriptive. But still they usually are not descriptive 
about how they should be used. And it would be odd for enum of 
int to print the enum name while string enum to print the value.


Re: Failed to sort range

2013-05-28 Thread Sergei Nosov

On Tuesday, 28 May 2013 at 13:41:19 UTC, bearophile wrote:

Sergei Nosov:

That went pretty well, until I tried to sort it. Sorting 
function asserted "Failed to sort range of type Array!(int)."


If you take a look a the implementation of Phobos sort, you see 
there is a recently added runtime test mostly meant to catch 
wrongly implemented comparison functions, like q{a <= b} 
instead of q{a < b}. Maybe that's the one that has fired. But I 
don't know why.


Bye,
bearophile


I don't think that is the case, since I use the default
comparison function for ints.


Re: Failed to sort range

2013-05-28 Thread bearophile

Sergei Nosov:

That went pretty well, until I tried to sort it. Sorting 
function asserted "Failed to sort range of type Array!(int)."


If you take a look a the implementation of Phobos sort, you see 
there is a recently added runtime test mostly meant to catch 
wrongly implemented comparison functions, like q{a <= b} instead 
of q{a < b}. Maybe that's the one that has fired. But I don't 
know why.


Bye,
bearophile


Re: Failed to sort range

2013-05-28 Thread Sergei Nosov

On Tuesday, 28 May 2013 at 12:57:12 UTC, Sergei Nosov wrote:

Hi!

I'm trying to implement an array, which uses malloc to allocate 
memory. Also, I want to implement a random access range 
interface for it.


That went pretty well, until I tried to sort it. Sorting 
function asserted "Failed to sort range of type Array!(int)."


I've spent quite some time trying to figure out what's going on 
with no success.


The implementation can be found at:
https://gist.github.com/snosov1/5662471

I used
DMD64 D Compiler v2.062 and
LDC - the LLVM D compiler (trunk): based on DMD v2.062 and LLVM 
3.2svn
on Ubuntu. Phobos version was the one that came with the dmd 
compiler.


Does anyone have any ideas what's wrong with the code I've 
provided?


Forgot to mention, that my hand-made sorting function (simply a 
copy-paste of some quicksort implementation that uses array 
indexing syntax) works just fine


void qSort(alias less, Range)(Range A, int low, int high) {
int i = low;
int j = high;
auto x = A[(low+high)/2];
do {
while(less(A[i], x)) ++i;
while(less(x, A[j])) --j;
if(i <= j){
auto temp = A[i];
A[i] = A[j];
A[j] = temp;
i++; j--;
}
} while(i < j);
if(low < j) qSort!less(A, low, j);
if(i < high) qSort!less(A, i, high);
}


Re: Passing large or complex data structures to threads

2013-05-28 Thread Joseph Rushton Wakeling
On 05/28/2013 08:56 AM, Ali Çehreli wrote:
> That is a difficult situation to manage though: What operations are valid 
> under
> the 8 total mutable combinations of 3 members? The compiler must know what
> operations to be applied on what type of data so that it can both check the 
> code
> and compile it accordingly.
> 
> To have such a flexibility, the type must be templatized.

... which is what I imagined; I wasn't certain, though, whether it was possible
to templatize purely relative to type qualifiers, though I guessed not.


Failed to sort range

2013-05-28 Thread Sergei Nosov

Hi!

I'm trying to implement an array, which uses malloc to allocate 
memory. Also, I want to implement a random access range interface 
for it.


That went pretty well, until I tried to sort it. Sorting function 
asserted "Failed to sort range of type Array!(int)."


I've spent quite some time trying to figure out what's going on 
with no success.


The implementation can be found at:
https://gist.github.com/snosov1/5662471

I used
DMD64 D Compiler v2.062 and
LDC - the LLVM D compiler (trunk): based on DMD v2.062 and LLVM 
3.2svn
on Ubuntu. Phobos version was the one that came with the dmd 
compiler.


Does anyone have any ideas what's wrong with the code I've 
provided?


Re: Why does this snippet print the enum identifiers instead of their values?

2013-05-28 Thread John Colvin

On Tuesday, 28 May 2013 at 12:16:51 UTC, John Colvin wrote:

There really ought to be a property .value of enums.


or alternatively .name of course. Either way there should be a 
way to choose whether you want the name or the value.


Re: Why does this snippet print the enum identifiers instead of their values?

2013-05-28 Thread John Colvin

On Tuesday, 28 May 2013 at 11:49:25 UTC, Gary Willoughby wrote:

Why does the following snippet print:

"Started name revision" instead of "Started my-app 1.0a"?

import std.stdio;

enum application : string
{
name = "my-app",
revision = "1.0a",
}

void main(string[] arguments)
{
	writefln("Started %s %s", application.name, 
application.revision);

}


I don't really know what the correct way of doing this is. There 
really ought to be a property .value of enums.


The stringof property will return what you want, although 
annoyingly with quotation marks around it ([1 .. $-1] on the end 
will clear that up of course). For types other than string it 
returns cast(application)value as a string, which is not 
particularly helpful.


BTW this only happens with named enums, anonymous enums print the 
value not the name.



I don't know how much any of this is intended behaviour and how 
much is just by chance.


Re: Why does this snippet print the enum identifiers instead of their values?

2013-05-28 Thread bearophile

Gary Willoughby:


Why does the following snippet print:

"Started name revision" instead of "Started my-app 1.0a"?

import std.stdio;

enum application : string
{
name = "my-app",
revision = "1.0a",
}

void main(string[] arguments)
{
	writefln("Started %s %s", application.name, 
application.revision);

}


It looks like a compiler bug :-) (Enums of strings are not well 
supported. enums were invented mostly for integral types.) If 
it's not already in Bugzilla then I suggest to add it there.


By the way, in D enum names as "application" usually start with 
an upper case ("Application"), and the name of the main array is 
usually "args". Sticking with common practices is better, unless 
you have (uncommon) real reasons to do something different.


Bye,
bearophile


Why does this snippet print the enum identifiers instead of their values?

2013-05-28 Thread Gary Willoughby

Why does the following snippet print:

"Started name revision" instead of "Started my-app 1.0a"?

import std.stdio;

enum application : string
{
name = "my-app",
revision = "1.0a",
}

void main(string[] arguments)
{
	writefln("Started %s %s", application.name, 
application.revision);

}


Re: Two questions about assignments

2013-05-28 Thread bearophile

I will add it to Bugzilla then, if it's not already there.


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

Bye,
bearophile


Re: How do you guys debug large programs?

2013-05-28 Thread Timon Gehr

On 05/27/2013 09:55 PM, Gary Willoughby wrote:

This is quite an open ended question but i wondered how you guys debug
your D programs (i'm talking about stepping through code, setting
breakpoints, etc). The lack of nice IDE's with integrated debuggers is
worrying when working with D but up until now i haven't need one.

Now i've started to write much larger programs, i'm wondering which
debuggers do you use? Especially using Linux.


writeln, assert, gdb.


Re: How do you guys debug large programs?

2013-05-28 Thread estew
Sorry, ignore the two lines stating "Then (12 months ago):" and 
"Now:". They are a cut-paste schmozzle and shouldn't be 
there...no edits of posts?.


My middle mouse button is both a blessing an a curse :)

Stewart


Re: How do you guys debug large programs?

2013-05-28 Thread estew

Then (12 months ago):
If you're on linux and after VStudio style debugging in the GUI 
then I found QtCreator worked well.


I was just using the Qt SDK bundle but it should work just from 
the QtCreator download (saves installing the monolithic Qt 
development libs).


I would build the D application with -gc for C symbols and it 
just worked, expect for one small caveat. I had to load the D 
source file containing main() into the IDE editor, set a 
breakpoint (F9) anywhere and then:


Debug->Start Debugging->Start and Debug External Application

Reason for this was that QtCreator's "break at main" function 
would break at the real main() not _Dmain. To be expected I guess 
as QtCreator (aka GDB) knows nothing about D startup.



Now:
I haven't tried QtCreator for a while as the D compile time is so 
fast debugging with printfs seems to be quicker and stepping 
through code in the IDE.


Cheers,
Stewart


Re: iteration over a string

2013-05-28 Thread Timothee Cour
On Tue, May 28, 2013 at 3:20 AM, bearophile wrote:

> Timothee Cour:
>
>  string a="ΩΩab";
>>> auto b1=a.map!(a=>"<"d~a~">"d).**array;
>>> writeln(b1);//["<Ω>", "<Ω>", "", "", "", ""]
>>> Why are there 2 empty strings at the end? (one per Omega if you vary the
>>>
>> number of such symbols in the string).
>>
>> The above is just weird; is that a bug?
>>
>
> I think it's a bug, it's shown here, I will put it in Bugzilla:
>
> import std.stdio: writeln;
> import std.algorithm: map;
> import std.array: array;
> void main() {
> string a = "ΩΩab";
> a.map!(a => "<"d ~ a ~ ">"d).writeln;
> a.map!(a => "<"d ~ a ~ ">"d).array.writeln;
> }
>
>
> The output shows that maybe it's a problem of array():
>
> ["<Ω>", "<Ω>", "", ""]
>
> ["<Ω>", "<Ω>", "", "", "", ""]
>
>
>
>  For input ranges ranges, I don't understand why the compiler can't accept
>> the foreach(i,ai;a) syntax:
>>
>> it should behave as follows:
>> foreach(i , ai; a){expr}
>>
>> rewritten as:
>> for(size_t i=0, ai=a.front; !a.empty; a.popFront;){expr}
>>
>> but it doesn't compile (it only accepts foreach(ai;a){expr}
>>
>
> The idea must work in all cases. For opApply, built-in arrays, built-in
> associative arrays and for ranges. I think it causes some clashing. If you
> will find it causes no clashing, then it's a candidate to become an
> enhancement request.
>
> Bye,
> bearophile
>

thanks for filing 10191!

Let's dig more the indexed foreach proposal:

opApply => present with corresponding signature to foreach(i,ai;a) => use it
built-in arrays => its an randaccess iterator so already works
associative arrays => already works, compiler rewrites to key,value
ranges => if it's not an associative array, random access iterator, doesn't
have opApply with corresponding signature, then use the size_t index I
mentioned (existing code makes it compile error, this proposal allows it).

Where do you think it can cause clashing?


Re: iteration over a string

2013-05-28 Thread bearophile

I think it's a bug, it's shown here, I will put it in Bugzilla:


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

Bye,
bearophile


Re: iteration over a string

2013-05-28 Thread bearophile

Timothee Cour:


string a="ΩΩab";
auto b1=a.map!(a=>"<"d~a~">"d).array;
writeln(b1);//["<Ω>", "<Ω>", "", "", "", ""]
Why are there 2 empty strings at the end? (one per Omega if 
you vary the

number of such symbols in the string).

The above is just weird; is that a bug?


I think it's a bug, it's shown here, I will put it in Bugzilla:

import std.stdio: writeln;
import std.algorithm: map;
import std.array: array;
void main() {
string a = "ΩΩab";
a.map!(a => "<"d ~ a ~ ">"d).writeln;
a.map!(a => "<"d ~ a ~ ">"d).array.writeln;
}


The output shows that maybe it's a problem of array():

["<Ω>", "<Ω>", "", ""]
["<Ω>", "<Ω>", "", "", "", ""]



For input ranges ranges, I don't understand why the compiler 
can't accept

the foreach(i,ai;a) syntax:

it should behave as follows:
foreach(i , ai; a){expr}

rewritten as:
for(size_t i=0, ai=a.front; !a.empty; a.popFront;){expr}

but it doesn't compile (it only accepts foreach(ai;a){expr}


The idea must work in all cases. For opApply, built-in arrays, 
built-in associative arrays and for ranges. I think it causes 
some clashing. If you will find it causes no clashing, then it's 
a candidate to become an enhancement request.


Bye,
bearophile


Re: iteration over a string

2013-05-28 Thread Timothee Cour
2A)
Thanks for your answer;
You skipped over this one, which I don't understand:

> string a="ΩΩab";
> auto b1=a.map!(a=>"<"d~a~">"d).array;
> writeln(b1);//["<Ω>", "<Ω>", "", "", "", ""]
> Why are there 2 empty strings at the end? (one per Omega if you vary the
number of such symbols in the string).

The above is just weird; is that a bug?

2B)
> The reason that we don't do that is mostly because it makes pretty much
no sense to iterate over ranges of code units 99.99% of the time

And yet "ΩΩab".map!foo seems to operate on code units and in order to
operate on code points we need "ΩΩab".stride(1).map!foo, so isn't it
inconsistent with the fact that std.algorithm.find("ΩΩab") operates on code
points ?

2C)
> Remember that ranges don't provide indices unless they're random access,

For input ranges ranges, I don't understand why the compiler can't accept
the foreach(i,ai;a) syntax:

it should behave as follows:
foreach(i , ai; a){expr}

rewritten as:
for(size_t i=0, ai=a.front; !a.empty; a.popFront;){expr}

but it doesn't compile (it only accepts foreach(ai;a){expr}




On Tue, May 28, 2013 at 1:25 AM, Jonathan M Davis wrote:

> On Tuesday, May 28, 2013 00:26:03 Timothee Cour wrote:
> > Questions regarding iteration over code points of a utf8 string:
> >
> > In all that follows, I don't want to go through intermediate UTF32
> > representation by making a copy of my string, but I want to iterate over
> > its code points.
> >
> > say my string is declared as:
> > string a="Ωabc"; //if email reader screws this up, it's a 'Omega'
> followed
> > by abc
> >
> > A)
> > this doesn't work obviously:
> > foreach(i,ai; a){
> >   write(i,",",ai," ");
> > }
> > //prints 0,� 1,� 2,a 3,b 4,c (ie decomposes at the 'char' level, so 5
> > elements)
>
> Yes. I'd love it if it were a warning or error to not give an explicit
> iteration type for foreach with strings, but I don't think that Walter is
> willing to do that. He seems to think that everyone should understand
> Unicode
> and therefore have no problems with the fact that foreach iterates over
> code
> units rather than code points.
>
> > B)
> > foreach(i,dchar ai;a){
> >   write(i,",",ai," ");
> > }
> > // prints 0,Ω 2,a 3,b 4,c (ie decomposes at code points, so 4 elements)
> > But index i skips position 1, indicating the start index of code points;
> it
> > prints [0,2,3,4]
> > Is that a bug or a feature?
>
> Feature. It's the index of the array, so it's code units, and in general is
> more useful (at least for more advanced string processing).
>
> > C)
> > writeln(a.walkLength); // prints 4
> > for(size_t i;!a.empty;a.popFront,i++)
> >   write(i,",",a.front," ");
> >
> > // prints 0,Ω 1,a 2,b 3,c
> > This seems the most correct for interpreting a string as a range over
> code
> > points, where index i has positions [0,1,2,3]
> >
> > Is there a more idiomatic way?
>
> Not really (though maybe it could be done with zip and iota or something if
> you really wanted to), but it's also not something that you'd do normally.
> Remember that ranges don't provide indices unless they're random access,
> and
> narrow strings aren't random access as far as ranges are concerned. You
> have
> to count the elements for pretty much _any_ non-random-access range if you
> want to know which element you're on.
>
> > D)
> > How to make the standard algorithms (std.map, etc) work well with the
> > iteration over code points as in method C above ?
> >
> > For example this one is very confusing for me:
> > string a="ΩΩab";
> > auto b1=a.map!(a=>"<"d~a~">"d).array;
> > writeln(b1.length);//6
>
> For ranges, use walkLength, not length. length will _not_ be correct in the
> general case when strings are involved, because that's the number of code
> units rather than code points.
>
> > E)
> > The fact that there are 2 ways to iterate over strings is confusing:
> > For example reading at docs, ForeachType is different from ElementType
> and
> > ElementType is special cased for narrow strings;
> > foreach(i;ai;a){foo(i,ai);} doesn't behave as for(size_t
> > i;!a.empty;a.popFront,i++) {foo(i,a.front);}
> > walkLength != length for strings
> >
> > F)
> > Why can't we have the following design instead:
> > * no special case with isNarrowString scattered throughout phobos
> > * iteration with foreach behaves as iteration with popFront/empty/front,
> > and walkLength == length
> > * ForeachType == ElementType (ie one is redundant)
> > * require *explicit user syntax* to construct a range over code points
> from
> > a string:
> >
> > struct CodepointRange{
> >  this(string a){...}
> >  auto popFront(){}
> >  auto empty(){}
> >  auto length(){}//
> > }
> >
> > now the user can do:
> > a.map!foo => will iterate over char
> > a.CodepointRange.map!foo => will iterate over code points.
> >
> > Everything seems more orhogonal that way, and user has clear
> understanding
> > of complexity of each operation.
>
> The reason that we don't do that is mostly because it makes pretty much no
> sense to iterate ove

Re: iteration over a string

2013-05-28 Thread Jonathan M Davis
On Tuesday, May 28, 2013 00:26:03 Timothee Cour wrote:
> Questions regarding iteration over code points of a utf8 string:
> 
> In all that follows, I don't want to go through intermediate UTF32
> representation by making a copy of my string, but I want to iterate over
> its code points.
> 
> say my string is declared as:
> string a="Ωabc"; //if email reader screws this up, it's a 'Omega' followed
> by abc
> 
> A)
> this doesn't work obviously:
> foreach(i,ai; a){
>   write(i,",",ai," ");
> }
> //prints 0,� 1,� 2,a 3,b 4,c (ie decomposes at the 'char' level, so 5
> elements)

Yes. I'd love it if it were a warning or error to not give an explicit 
iteration type for foreach with strings, but I don't think that Walter is 
willing to do that. He seems to think that everyone should understand Unicode 
and therefore have no problems with the fact that foreach iterates over code 
units rather than code points.

> B)
> foreach(i,dchar ai;a){
>   write(i,",",ai," ");
> }
> // prints 0,Ω 2,a 3,b 4,c (ie decomposes at code points, so 4 elements)
> But index i skips position 1, indicating the start index of code points; it
> prints [0,2,3,4]
> Is that a bug or a feature?

Feature. It's the index of the array, so it's code units, and in general is 
more useful (at least for more advanced string processing).

> C)
> writeln(a.walkLength); // prints 4
> for(size_t i;!a.empty;a.popFront,i++)
>   write(i,",",a.front," ");
> 
> // prints 0,Ω 1,a 2,b 3,c
> This seems the most correct for interpreting a string as a range over code
> points, where index i has positions [0,1,2,3]
> 
> Is there a more idiomatic way?

Not really (though maybe it could be done with zip and iota or something if 
you really wanted to), but it's also not something that you'd do normally. 
Remember that ranges don't provide indices unless they're random access, and 
narrow strings aren't random access as far as ranges are concerned. You have 
to count the elements for pretty much _any_ non-random-access range if you 
want to know which element you're on.

> D)
> How to make the standard algorithms (std.map, etc) work well with the
> iteration over code points as in method C above ?
> 
> For example this one is very confusing for me:
> string a="ΩΩab";
> auto b1=a.map!(a=>"<"d~a~">"d).array;
> writeln(b1.length);//6

For ranges, use walkLength, not length. length will _not_ be correct in the 
general case when strings are involved, because that's the number of code 
units rather than code points.

> E)
> The fact that there are 2 ways to iterate over strings is confusing:
> For example reading at docs, ForeachType is different from ElementType and
> ElementType is special cased for narrow strings;
> foreach(i;ai;a){foo(i,ai);} doesn't behave as for(size_t
> i;!a.empty;a.popFront,i++) {foo(i,a.front);}
> walkLength != length for strings
> 
> F)
> Why can't we have the following design instead:
> * no special case with isNarrowString scattered throughout phobos
> * iteration with foreach behaves as iteration with popFront/empty/front,
> and walkLength == length
> * ForeachType == ElementType (ie one is redundant)
> * require *explicit user syntax* to construct a range over code points from
> a string:
> 
> struct CodepointRange{
>  this(string a){...}
>  auto popFront(){}
>  auto empty(){}
>  auto length(){}//
> }
> 
> now the user can do:
> a.map!foo => will iterate over char
> a.CodepointRange.map!foo => will iterate over code points.
>
> Everything seems more orhogonal that way, and user has clear understanding
> of complexity of each operation.

The reason that we don't do that is mostly because it makes pretty much no 
sense to iterate over ranges of code units 99.99% of the time. Very nearly the 
_only_ time that it makes sense is when you know that all of the characters 
that you're operating on are ASCII characters. By iterating over code points, 
the situation is far more correct (the not completely correct, due to the 
difference between code points and graphemes). If we did everything on code 
units by default, D code in general would not operate at all correctly on 
Unicode most of the time.

The difference between foreach and ranges for strings is most definitely 
unfortunate, but it really isn't all that complicated ultimately. Just 
remember that foreach itself operates on code units (so you have to use dchar 
explicitly if you want to iterate over code points) and that all of the range 
functions operate on code points. So, when you're operating on narrow strings 
as ranges, don't use any operations that the range API doesn't consider them 
to have (in particular, length, random access, and slicing). In general, this 
is quite easy to do, because you write range-based functions in a generic 
fashion using traits such as hasLength and hasSlicing to determine a range's 
capabilities. So, you really don't have to do anything special for strings - 
unless you want to optimize your code for strings. And if you want to do that, 
then you need t

Re: How do you guys debug large programs?

2013-05-28 Thread Timothee Cour
On Tue, May 28, 2013 at 12:32 AM, nazriel  wrote:

> On Monday, 27 May 2013 at 19:55:57 UTC, Gary Willoughby wrote:
>
>> This is quite an open ended question but i wondered how you guys debug
>> your D programs (i'm talking about stepping through code, setting
>> breakpoints, etc). The lack of nice IDE's with integrated debuggers is
>> worrying when working with D but up until now i haven't need one.
>>
>> Now i've started to write much larger programs, i'm wondering which
>> debuggers do you use? Especially using Linux.
>>
>
> If I suspect what block of code may be causing a problem:
>
> 1) printf's / asserts
> 2) comment out
> 3) Duck partner
>
> When it is getting worse:
> 4) GDB
>
>
> GDB plays nice with D so it is smooth.
>

not on OSX, where demangling doesn't work (but the OP mentioned linux).


Re: iteration over a string

2013-05-28 Thread Diggory
Most algorithms for strings need the offset rather than the 
character index, so:


foreach (i; dchar c; str)

Gives the offset into the string for "i"

If you really need the character index just count it:

int charIndex = 0;
foreach (dchar c; str) {
   // ...

   ++charIndex;
}

If strings were treated specially so that they looked like arrays 
of dchars but used UTF-8 internally it would hide all sorts of 
performance costs. Random access into a UTF-8 string by the 
character index is O(n) whereas index by the offset is O(1).


If you are using random access by character index heavily you 
should therefore convert to a dstring first and then you can get 
the O(1) random access time.


Re: iteration over a string

2013-05-28 Thread Ali Çehreli

On 05/28/2013 12:42 AM, Ali Çehreli wrote:

> The output:
>
> Ω a b c

Rather:

0,Ω 1,a 2,b 3,c

Ali



Re: iteration over a string

2013-05-28 Thread Ali Çehreli

On 05/28/2013 12:26 AM, Timothee Cour wrote:

> In all that follows, I don't want to go through intermediate UTF32
> representation by making a copy of my string, but I want to iterate over
> its code points.

Yes, the whole situation is a little messy. :)

There is also std.range.stride:

foreach (ai; a.stride(1)) {
// ...
}

If you need the index as well, and do not want to manage it explicitly, 
one way is to use zip and sequence:


import std.stdio;
import std.range;

void main()
{
string a="Ωabc";

foreach (i, ai; zip(sequence!"n", a.stride(1))) {
write(i,",",ai," ");
}
}

The output:

Ω a b c

Ali



Re: How do you guys debug large programs?

2013-05-28 Thread nazriel

On Monday, 27 May 2013 at 19:55:57 UTC, Gary Willoughby wrote:
This is quite an open ended question but i wondered how you 
guys debug your D programs (i'm talking about stepping through 
code, setting breakpoints, etc). The lack of nice IDE's with 
integrated debuggers is worrying when working with D but up 
until now i haven't need one.


Now i've started to write much larger programs, i'm wondering 
which debuggers do you use? Especially using Linux.


If I suspect what block of code may be causing a problem:

1) printf's / asserts
2) comment out
3) Duck partner

When it is getting worse:
4) GDB


GDB plays nice with D so it is smooth.


Re: How do you guys debug large programs?

2013-05-28 Thread Nathan M. Swan

On Monday, 27 May 2013 at 19:55:57 UTC, Gary Willoughby wrote:
This is quite an open ended question but i wondered how you 
guys debug your D programs (i'm talking about stepping through 
code, setting breakpoints, etc). The lack of nice IDE's with 
integrated debuggers is worrying when working with D but up 
until now i haven't need one.


Now i've started to write much larger programs, i'm wondering 
which debuggers do you use? Especially using Linux.


I know Alexander Bothe of Mono-D fame is working on debugging
support for it:

http://mono-d.alexanderbothe.com/?p=997

It's still in alpha, but getting there.

NMS


iteration over a string

2013-05-28 Thread Timothee Cour
Questions regarding iteration over code points of a utf8 string:

In all that follows, I don't want to go through intermediate UTF32
representation by making a copy of my string, but I want to iterate over
its code points.

say my string is declared as:
string a="Ωabc"; //if email reader screws this up, it's a 'Omega' followed
by abc

A)
this doesn't work obviously:
foreach(i,ai; a){
  write(i,",",ai," ");
}
//prints 0,� 1,� 2,a 3,b 4,c (ie decomposes at the 'char' level, so 5
elements)

B)
foreach(i,dchar ai;a){
  write(i,",",ai," ");
}
// prints 0,Ω 2,a 3,b 4,c (ie decomposes at code points, so 4 elements)
But index i skips position 1, indicating the start index of code points; it
prints [0,2,3,4]
Is that a bug or a feature?

C)
writeln(a.walkLength); // prints 4
for(size_t i;!a.empty;a.popFront,i++)
  write(i,",",a.front," ");

// prints 0,Ω 1,a 2,b 3,c
This seems the most correct for interpreting a string as a range over code
points, where index i has positions [0,1,2,3]

Is there a more idiomatic way?

D)
How to make the standard algorithms (std.map, etc) work well with the
iteration over code points as in method C above ?

For example this one is very confusing for me:
string a="ΩΩab";
auto b1=a.map!(a=>"<"d~a~">"d).array;
writeln(b1.length);//6
writeln(b1);//["<Ω>", "<Ω>", "", "", "", ""]
Why are there 2 empty strings at the end? (one per Omega if you vary the
number of such symbols in the string).


E)
The fact that there are 2 ways to iterate over strings is confusing:
For example reading at docs, ForeachType is different from ElementType and
ElementType is special cased for narrow strings;
foreach(i;ai;a){foo(i,ai);} doesn't behave as for(size_t
i;!a.empty;a.popFront,i++) {foo(i,a.front);}
walkLength != length for strings

F)
Why can't we have the following design instead:
* no special case with isNarrowString scattered throughout phobos
* iteration with foreach behaves as iteration with popFront/empty/front,
and walkLength == length
* ForeachType == ElementType (ie one is redundant)
* require *explicit user syntax* to construct a range over code points from
a string:

struct CodepointRange{
 this(string a){...}
 auto popFront(){}
 auto empty(){}
 auto length(){}//
}

now the user can do:
a.map!foo => will iterate over char
a.CodepointRange.map!foo => will iterate over code points.

Everything seems more orhogonal that way, and user has clear understanding
of complexity of each operation.


Re: Passing large or complex data structures to threads

2013-05-28 Thread Ali Çehreli

On 05/27/2013 06:55 PM, Joseph Rushton Wakeling wrote:

> On 05/27/2013 11:33 PM, Simen Kjaeraas wrote:

>> Short answer: If you will have mixed arrays, no. There's no way to make
>> that safe. If you don't have mixed arrays, there are ways.
>
> So you mean there's no way to have one member variable be immutable, 
the rest

> mutable, without hardcoding that into the class/struct design?

That is a difficult situation to manage though: What operations are 
valid under the 8 total mutable combinations of 3 members? The compiler 
must know what operations to be applied on what type of data so that it 
can both check the code and compile it accordingly.


void foo(MyDataStore my)
{
my.someData[0] = 1.5;// valid if someData is mutable
my.someMoreData[0] = 42; // valid if someMoreData is mutable
}

Clearly, the code above can be compiled only if the two members of 
MyDataStore are mutable. The compiler does not have anything other than 
the static definition of MyDataStore, which implies that the type 
qualifiers of the members must be known at compile time.


To have such a flexibility, the type must be templatized. When it is 
templatized though, different instantiations of the template are 
different types, which means that they cannot take part in a collection 
of a specific type, unless they implement a certain interface like 
DataStore below:


import std.typecons;

interface DataStore
{
void doWork();
}

class MyDataStoreImpl(SomeDataT,
  SomeMoreDataT,
  ImportedDataT) : DataStore
{
SomeDataT[] someData;
SomeMoreDataT[] someMoreData;
ImportedDataT[][] importedData;

this(SomeDataT[] sd, SomeMoreDataT[] smd, ImportedDataT[][] id)
{
someData = sd;
someMoreData = smd;
importedData = id;
}

void doWork()
{
// What can we do here?
// There are 8 combinations of type qualifiers.
}
}

auto makeMyDataStore(SomeDataT,
 SomeMoreDataT,
 ImportedDataT)(SomeDataT[] sd,
SomeMoreDataT[] smd,
ImportedDataT[][] id)
{
return new MyDataStoreImpl!(SomeDataT,
SomeMoreDataT,
ImportedDataT)(sd, smd, id);
}

void foo(DataStore[] store)
{
foreach (data; store) {
data.doWork();
}
}

void main()
{
DataStore[] store;

// The combination: mutable, const, immutable
store ~= makeMyDataStore(new float[1],
 new const(double)[3],
 [ [ immutable(Tuple!(size_t, size_t))() ] ]);

// Another combination: immutable, mutable, const
store ~= makeMyDataStore(new immutable(float)[2],
 new double[4],
 [ [ const(Tuple!(size_t, size_t))() ] ]);

foo(store);
}

There is the big question of how to implement MyDataStoreImpl.doWork(). 
How do we support every valid combination?


Conditional compilation is one way:

class MyDataStoreImpl(SomeDataT,
  SomeMoreDataT,
  ImportedDataT) : DataStore
{
// ...

void doWork()
{
static if (is (SomeMoreDataT == const) &&
   is (ImportedDataT == immutable)) {
// ...
writeln("case 1");

} else static if(is (SomeDataT == immutable) &&
 is (ImportedDataT == const)) {
// ...
writeln("case 2");

} else {
   // ...
}
}
}

Perhaps mixins can be used to inject different functionality depending 
on different type qualifiers if the functionality is as simple as in the 
following case:


import std.stdio;

// This template contains code for a mutable slice and the function that 
goes

// with it:
template Foo(T)
if (!is (T == immutable) &&
!is (T == const))
{
T data[];

void doWork()
{
writeln("called for mutable data");

if (data.length < 1) {
data.length = 1;
}

data[0] = T.init;
}
}

// This one is for immutable and const data:
template Foo(T)
if (is (T == immutable) ||
is (T == const))
{
T[] data;

void doWork()
{
// We cannot modify data[0] here...
writeln("called for immutable data");
}
}

interface DataStore
{
void doWork();
}

class MyDataStoreImpl(T) : DataStore
{
mixin Foo!T;
}

void main()
{
DataStore[] store;

store ~= new MyDataStoreImpl!(double)();
store ~= new MyDataStoreImpl!(immutable(double))();

foreach (data; store) {
data.doWork();
}
}

Ali