Re: Just a reminder, I'll be at GOTO next week!

2012-10-02 Thread Paulo Pinto

On Friday, 28 September 2012 at 16:07:51 UTC, deadalnix wrote:

Le 28/09/2012 07:43, Walter Bright a écrit :

talking about Component Programming in D on Oct. 2.

http://gotocon.com/aarhus-2012/schedule/tuesday.jsp

See you there! (use promotion code brig1000 when registering 
and you'll

get a discount)


I couldn't come. But Aarhus is a really nice city. It has the 
most horrible city hall ever built, but otherwise this is 
beautiful.


Been there once, visiting some friends at the university, they 
used to complain that the city is quite boring to live on, at 
least as a student.


Re: Just a reminder, I'll be at GOTO next week!

2012-10-02 Thread Paulo Pinto

On Tuesday, 2 October 2012 at 09:22:12 UTC, Jonas Drewsen wrote:

On Tuesday, 2 October 2012 at 06:24:13 UTC, Paulo Pinto wrote:

On Friday, 28 September 2012 at 16:07:51 UTC, deadalnix wrote:

Le 28/09/2012 07:43, Walter Bright a écrit :

talking about Component Programming in D on Oct. 2.

http://gotocon.com/aarhus-2012/schedule/tuesday.jsp

See you there! (use promotion code brig1000 when registering 
and you'll

get a discount)


I couldn't come. But Aarhus is a really nice city. It has the 
most horrible city hall ever built, but otherwise this is 
beautiful.


Been there once, visiting some friends at the university, they 
used to complain that the city is quite boring to live on, at 
least as a student.


Go to Copenhagen instead - I'll buy you a beer and talk some D. 
That goes for Walter as well ;)


/Jonas


Thanks. Next time I'm in Denmark. After all I'm living in a 
neighbor country, in Düsseldorf. :)


Copenhagen is quite nice actually. I also did visit it during the 
same trip.


--
Paulo




Released vibe.d 0.7.8 and improved online API documentation

2012-10-02 Thread Sönke Ludwig
The new version adds support for UDP sockets and a lot of smaller
improvements and fixes, for example in the Diet parser and the REST
interface generator (see http://vibed.org/blog/posts/vibe-release-0.7.8
for details). Thanks for all contributions!

I've also done some improvements to the API documentation*, which is
generated from DMDs JSON output (with some additional processing). The
documentation has full cross-linking for types. I'm planning to break
this out into a separate project with support for offline documentation
generation.

It should be noted that the documentation processor contains a crude D
type parser, because the types in DMD's JSON always come out
stringified. This is necessary to get the type links and some other
things working - getting an additional detailed type AST in the original
JSON would be very helpful here (and much more robust).

Sönke

* http://vibed.org/api/


Re: Released vibe.d 0.7.8 and improved online API documentation

2012-10-02 Thread Lubos Pintes

Hi,
I am very new to this, but cannot compile/run this under Windows 7 
64-bit. I tried to run an http_example with this result:


c:\vibe\bin\..\source\vibe\vpm\dependency.d(117): Error: undefined 
identifier HEAD
c:\vibe\bin\..\source\vibe\vpm\dependency.d(117): Error: constructor 
vibe.vpm.dependency.Version.this (string vers) is not callable using 
argument types (_error_)
'C:\Users\pintes\AppData\Local\Temp\.rdmd\source\vibe.cmd' is not 
recognized as an internal or external command,

operable program or batch file.

Dňa 2. 10. 2012 18:31 Sönke Ludwig  wrote / napísal(a):

The new version adds support for UDP sockets and a lot of smaller
improvements and fixes, for example in the Diet parser and the REST
interface generator (see http://vibed.org/blog/posts/vibe-release-0.7.8
for details). Thanks for all contributions!

I've also done some improvements to the API documentation*, which is
generated from DMDs JSON output (with some additional processing). The
documentation has full cross-linking for types. I'm planning to break
this out into a separate project with support for offline documentation
generation.

It should be noted that the documentation processor contains a crude D
type parser, because the types in DMD's JSON always come out
stringified. This is necessary to get the type links and some other
things working - getting an additional detailed type AST in the original
JSON would be very helpful here (and much more robust).

Sönke

* http://vibed.org/api/





Re: Released vibe.d 0.7.8 and improved online API documentation

2012-10-02 Thread Sönke Ludwig
Am 10/2/2012 8:26 PM, schrieb Lubos Pintes:
 Hi,
 I am very new to this, but cannot compile/run this under Windows 7
 64-bit. I tried to run an http_example with this result:
 

Sorry, I think you checked out a bad commit on master. We just made some
changes to the VPM system. Should compile again now.


Re: Component Programming in D

2012-10-02 Thread Rene Zwanenburg

On Tuesday, 2 October 2012 at 21:51:45 UTC, Rene Zwanenburg wrote:
On Tuesday, 2 October 2012 at 21:27:42 UTC, Andrei Alexandrescu 
wrote:

http://www.reddit.com/r/programming/comments/10u6sk/component_programming_in_d/

Andrei


John D. Cook mentions Walter's talk in his blog post at
http://www.johndcook.com/blog/2012/10/02/pipelines-and-whirlpools/comment-page-1/#comment-249100

I've posted a link to this article in the comments, but it's 
awaiting moderation.


Oops, link should of course be
http://www.johndcook.com/blog/2012/10/02/pipelines-and-whirlpools/


Re: Component Programming in D

2012-10-02 Thread Paulo Pinto
On Tuesday, 2 October 2012 at 21:27:42 UTC, Andrei Alexandrescu 
wrote:

http://www.reddit.com/r/programming/comments/10u6sk/component_programming_in_d/

Andrei


Nice article!


Re: Component Programming in D

2012-10-02 Thread Andrej Mitrovic
On 10/2/12, Rene Zwanenburg renezwanenb...@gmail.com wrote:
 John D. Cook mentions Walter's talk in his blog post at
 http://www.johndcook.com/blog/2012/10/02/pipelines-and-whirlpools/comment-page-1/#comment-249100

He also mentions there might be a video coming up of the event. If
that's true, yay!

Nice article, too!


Re: Component Programming in D

2012-10-02 Thread Andrei Alexandrescu

On 10/2/12 6:14 PM, Paulo Pinto wrote:

On Tuesday, 2 October 2012 at 21:27:42 UTC, Andrei Alexandrescu wrote:

http://www.reddit.com/r/programming/comments/10u6sk/component_programming_in_d/


Andrei


Nice article!


I liked it the most of all I've read from Walter.

Andrei


Re: Component Programming in D

2012-10-02 Thread deadalnix

Le 03/10/2012 00:45, Andrei Alexandrescu a écrit :

On 10/2/12 6:14 PM, Paulo Pinto wrote:

On Tuesday, 2 October 2012 at 21:27:42 UTC, Andrei Alexandrescu wrote:

http://www.reddit.com/r/programming/comments/10u6sk/component_programming_in_d/



Andrei


Nice article!


I liked it the most of all I've read from Walter.

Andrei


Same here, this article is shared and loved as it must be !


Re: Just a reminder, I'll be at GOTO next week!

2012-10-02 Thread Nick Sabalausky
On Tue, 02 Oct 2012 08:24:27 +0200
Paulo Pinto pj...@progtools.org wrote:
 
 Been there once, visiting some friends at the university, they 
 used to complain that the city is quite boring to live on, at 
 least as a student.

Students will say that about any city. It's the standard college excuse
for getting drunk every day. Ask them what they'd like to have in the
city and it's always I dunno



Re: Component Programming in D

2012-10-02 Thread Nick Sabalausky
On Tue, 02 Oct 2012 17:27:55 -0400
Andrei Alexandrescu seewebsiteforem...@erdani.org wrote:

 http://www.reddit.com/r/programming/comments/10u6sk/component_programming_in_d/
 

Excellent article!



Re: Component Programming in D

2012-10-02 Thread Jonathan M Davis
On Tuesday, October 02, 2012 17:27:55 Andrei Alexandrescu wrote:
 http://www.reddit.com/r/programming/comments/10u6sk/component_programming_in
 _d/

It's definitely the sort of article that we've needed to show what we're trying 
to do with ranges.

- Jonathan M Davis


Re: Component Programming in D

2012-10-02 Thread ixid
On Tuesday, 2 October 2012 at 21:27:42 UTC, Andrei Alexandrescu 
wrote:

http://www.reddit.com/r/programming/comments/10u6sk/component_programming_in_d/

Andrei


The article contains a bug due to the pernicious behaviour of 
seedless reduce.


This section:

Just to show how flexible algorithms can be, reduce can also 
compute multiple values with one pass through the data (which is 
pretty useful for streaming data and would be expensive to save 
for a second pass through it). Multiple lambdas produce a tuple 
result, here the sum and sum of squares is computed:


int[] arr = [1,2,3,4,5];
auto r = arr.reduce!((a,b) = a + b, (a,b) = a + b * b);
writefln(sum = %s, sum of squares = %s, r[0], r[1]);
Which prints: sum = 15, sum of squares = 55

That is the correct answer for the squares but only because 1*1 
is 1. The first element of a seedless reduce does not have any 
operation carried out on it.


If we change the array to [2,2,2,2,2] we would expect the squares 
sum to be 20. It's 18 because the seed element at arr[0] has no 
operation carried out on it.


Re: Component Programming in D

2012-10-02 Thread Nick Sabalausky
On Wed, 03 Oct 2012 03:05:08 +0200
Jonathan M Davis jmdavisp...@gmx.com wrote:

 On Tuesday, October 02, 2012 17:27:55 Andrei Alexandrescu wrote:
  http://www.reddit.com/r/programming/comments/10u6sk/component_programming_in
  _d/
 
 It's definitely the sort of article that we've needed to show what
 we're trying to do with ranges.
 

Yes, and also why a lot of D's features, esp its metaprogramming
features, are so significant. And why most other languages, including
dynamic languages, don't even come close.

I think I'm starting to get a sense of the next big step, though. There
are other misc improvements I'd like to see, but I think the biggest
weakness our range approach faces now (even as far ahead as we are) is
the effort and, arguably, boilerplate to actually create the ranges.

Especially input/forward ranges: It's pretty well known and accepted
(esp. to those who have created input/forward ranges) that the easiest
way to make a generator is with a straight imperative function. But
ranges turn the whole logic inside-out. Walking a tree can get
particularly convoluted.

So I think the next *big* step from here, in D3 or some other D-derived
language, would be easing the creation of ranges. For example, a
special low-boilerplate syntax for creating bidirectional and
random-access ranges. Or for input (or maybe even forward) ranges, a
C#-style compile-time transformation of a generator function into a
range (With input ranges, you can technically get around needing source
transformation right now in D2 using fibers, but that has too
much runtime overhead to be used as a general solution).



Re: Component Programming in D

2012-10-02 Thread ixid
On Tuesday, 2 October 2012 at 21:27:42 UTC, Andrei Alexandrescu 
wrote:

http://www.reddit.com/r/programming/comments/10u6sk/component_programming_in_d/

Andrei


The article contains a bug due to the pernicious behaviour of 
seedless reduce.


This section:

Just to show how flexible algorithms can be, reduce can also 
compute multiple values with one pass through the data (which is 
pretty useful for streaming data and would be expensive to save 
for a second pass through it). Multiple lambdas produce a tuple 
result, here the sum and sum of squares is computed:


int[] arr = [1,2,3,4,5];
auto r = arr.reduce!((a,b) = a + b, (a,b) = a + b * b);
writefln(sum = %s, sum of squares = %s, r[0], r[1]);

Which prints: sum = 15, sum of squares = 55

That is the correct answer for the squares sum but only because 
1*1 is 1, what it's really doing here is 1 + (2 * 2) + (3 * 3) + 
(4 * 4) + (5 * 5) which happens to work in this case and for a + 
b and a - b but is otherwise broken. The first element of a 
seedless reduce does not have any operation carried out on it.


If we change the array to [2,2,2,2,2] we would expect the squares 
sum to be 20. It's 18 because the seed element at arr[0] has no 
operation carried out on it other than the addition of the other 
elements to it.


Re: core.simd woes

2012-10-02 Thread Dmitry Olshansky

On 02-Oct-12 06:28, F i L wrote:


D has a big
advantage over C/C++ here because of UFCS, in that we can write external
functions that appear no different to encapsulated object methods. That
combined with public-aliasing means the end-user only sees our pretty
functions, but we're not sacrificing performance at all.


Yeah, but it won't cover operators. If only opBinary could be defined at 
global scope... I think I've seen an enhancement to that end though. But 
even then simd types are built-in and operator overloading only works 
with user-defined types.


--
Dmitry Olshansky


Re: It seems pure ain't so pure after all

2012-10-02 Thread foobar

On Monday, 1 October 2012 at 22:47:48 UTC, Timon Gehr wrote:



A D compiler is also a D interpreter. I wouldn't even bother 
with D if this wasn't the case.


A D compiler _contains_ a limited interpreter for constant 
expression evaluation. This has limitations such as not being 
able to perform IO at compile-time (there's a special pragma for 
that). This is merely an outgrowth of a compiler optimization 
technique.


Now, back on topic:
I agree with Jonathan - in general the compiler can't evaluate 
_all_ functions at-compile time due these limitations of CTFE and 
adding a compiler flag will make compilation times far worse than 
c++. Adding a function attribute adds marginal benefit over 
simply assigning to a static/enum variable.


Re: It seems pure ain't so pure after all

2012-10-02 Thread Don Clugston

On 01/10/12 07:40, Tommi wrote:

import std.stdio;

int pow2(int val) pure
{
 if (__ctfe)
 return 6;
 else
 return val * val;
}

void main()
{
assert(pow2(3) == 9);
 static assert(pow2(3) == 6);

 writeln(9 = 6 ... I knew it! '6' was faking it all along);
 readln();
}


You don't need the if (__ctfe) to show this behaviour. Nor do you even 
need CTFE at all (though it would be a bit less obvious). You could 
demonstrate it in C++ too.


Any code that behaves differently when compiled with -O, will do this as 
well. Constant folding of floating point numbers does the same thing, if 
the numbers are represented in the compiler in a different precision to 
how the machine calculates them. I believe that GCC, for example, uses 
very much higher precision (hundreds of bits) at compile time.








Re: __ctfe

2012-10-02 Thread Jonathan M Davis
On Tuesday, October 02, 2012 09:45:10 Don Clugston wrote:
 On 01/10/12 21:30, Adam D. Ruppe wrote:
  On Monday, 1 October 2012 at 19:22:37 UTC, Philippe Sigaud wrote:
  Something I wanted to ask for a long time: is there any runtime speed
  penalty in using __ctfe?
  
  No. What happens is when it goes to the compile the runtime code, __ctfe
  is a constant false, so then the optimizer can see it is obviously dead
  code and eliminate the branch entirely. You don't even have to use the
 
  -O switch to get this:
 Yes, I was VERY careful about this. The if (__ctfe) branch gets
 discarded at the end of the front-end. The backend never sees it.

By the way, why is it not used in static if? That's what most of us would have 
expected (and it frequently seems to trip people up). I assume that it's due 
to some implementation detail of CTFE (like it doesn't really compile any 
functions differently for CTFE)?

- Jonathan M Davis


Re: Idea: Introduce zero-terminated string specifier

2012-10-02 Thread Walter Bright

On 10/1/2012 7:22 PM, Steven Schveighoffer wrote:

However, we can't require an import to use a bizarre
specifier, and you can't link un@safe code to a specifier, so the zstr
concept is far superior in requiring the user to know what he is doing,
and having the compiler enforce that.


Yup.



Does it make sense for Phobos to provide such a shortcut in an obscure
header somewhere? Like std.cstring? Or should we just say roll your own
if you need it?


As a matter of principle, I really don't like gobs of Phobos functions 
that are literally one liners. Phobos should not become a mile wide but 
inch deep library of trivia. It should consist of non-trivial, useful, 
and relatively deep functions.


Re: dynamic library building and loading

2012-10-02 Thread Johannes Pfau
Am Mon, 01 Oct 2012 19:18:46 +0200
schrieb Jacob Carlborg d...@me.com:

 On 2012-10-01 17:06, Johannes Pfau wrote:
 
  the problem is that we don't want the C main function in a shared
  libgdruntime.so, because you might want to use libgdruntime.so in a
  C/C++ app which has it's own main function.
 
  So we currently don't link in dmain2.o into the shared library and
  it must be included manually when linking an application.
  (But dmain2 also contains some stuff that really should be in
  libdruntime.so, so this source file should probably be split up at
  some time.)
 
 I'm not sure if I follow this correctly or not, but why is this
 needed to be handled manually? If you pass -shared to the compiler
 just skip linking dmain2.o, otherwise link with it. Would that work?
 

Yes something similar would work, it's just not yet implemented.

GDC should detect if we're linking against a shared druntime and then
it should automatically add dmain2.o to the linker command.


Re: core.simd woes

2012-10-02 Thread Manu
On 7 August 2012 16:56, jerro a...@a.com wrote:


  That said, almost all simd opcodes are directly accessible in std.simd.
 There are relatively few obscure operations that don't have a representing
 function.
 The unpck/shuf example above for instance, they both effectively perform a
 sort of swizzle, and both are accessible through swizzle!().


 They aren't. Swizzle only takes one argument, so you cant use it to select
 elements from two vectors. Both unpcklps and shufps take two arguments.
 Writing a swizzle with two arguments would be much harder.


Any usages I've missed/haven't thought of; I'm all ears.

 The swizzle
 mask is analysed by the template, and it produces the best opcode to match
 the pattern. Take a look at swizzle, it's bloody complicated to do that
 the
 most efficient way on x86.


 Now imagine how complicated it would be to write a swizzle with to vector
 arguments.


I can imagine, I'll have a go at it... it's something I considered, but not
all architectures can do it efficiently.
That said, a most-efficient implementation would probably still be useful
on all architectures, but for cross platform code, I usually prefer to
encourage people taking another approach rather than supply a function that
is not particularly portable (or not efficient when ported).

 The reason I didn't write the DMD support yet is because it was incomplete,
 and many opcodes weren't yet accessible, like shuf for instance... and I
 just wasn't finished. Stopped to wait for DMD to be feature complete.
 I'm not opposed to this idea, although I do have a concern that, because
 there's no __forceinline in D (or macros), adding another layer of
 abstraction will make maths code REALLY slow in unoptimised builds.
 Can you suggest a method where these would be treated as C macros, and not
 produce additional layers of function calls?


 Unfortunately I can't, at least not a clean one. Using string mixins would
 be one way but I think no one wants that kind of API in Druntime or Phobos.


Yeah, absolutely not.
This is possibly the most compelling motivation behind a __forceinline
mechanism that I've seen come up... ;)

 I'm already unhappy that
 std.simd produces redundant function calls.

 rant please  please please can haz __forceinline! /rant


 I agree that we need that.


Huzzah! :)


Re: Idea: Introduce zero-terminated string specifier

2012-10-02 Thread Piotr Szturmaj

Andrej Mitrovic wrote:

On 10/1/12, Piotr Szturmaj bncr...@jadamspam.pl wrote:

For example C binding writers may change:

extern(C) char* getstr();

to

extern(C) cstring getstr();


I don't think you can reliably do that because of semantics w.r.t.
passing parameters on the stack vs in registers based on whether a
type is a pointer or not. I've had this sort of bug when wrapping C++
where the C++ compiler was passing a parameter in one way but the D
compiler expected the parameters to be passed, simply because I tried
to be clever and fake a return type. See:
http://forum.dlang.org/thread/mailman.1547.1346632732.31962.d@puremagic.com#post-mailman.1557.1346690320.31962.d.gnu:40puremagic.com


I think that align(1) structs that wrap a single value should be treated 
as its type. After all they have the same size and representation. I 
don't know how this works now, though.


Re: __ctfe

2012-10-02 Thread Daniel Murphy
Jonathan M Davis jmdavisp...@gmx.com wrote in message 
news:mailman.477.1349164468.5162.digitalmar...@puremagic.com...

 By the way, why is it not used in static if? That's what most of us would 
 have
 expected (and it frequently seems to trip people up). I assume that it's 
 due
 to some implementation detail of CTFE (like it doesn't really compile any
 functions differently for CTFE)?

 - Jonathan M Davis

Code inside static if blocks does not have to be semantically valid if it is 
not selected, and is discarded well before the interpreter could be invoked 
on it.  It could be done using static if or version, but that would require 
duplicating the function and re-running semantic, which is less elegant and 
not really what you want.
There is a little bit of explanation in the original bug report: 
http://d.puremagic.com/issues/show_bug.cgi?id=3556 




Re: core.simd woes

2012-10-02 Thread Manu
On 8 August 2012 04:45, F i L witte2...@gmail.com wrote:

 Manu wrote:

 I'm not sure why the performance would suffer when placing it in a struct.
 I suspect it's because the struct causes the vectors to become unaligned,
 and that impacts performance a LOT. Walter has recently made some changes
 to expand the capability of align() to do most of the stuff you expect
 should be possible, including aligning structs, and propogating alignment
 from a struct member to its containing struct. This change might actually
 solve your problems...


 I've tried all combinations with align() before and inside the struct,
 with no luck. I'm using DMD 2.060, so unless there's a new syntax I'm
 unaware of, I don't think it's been adjusted to fix any alignment issues
 with SIMD stuff. It would be great to be able to wrap float4 into a struct,
 but for now I've come up with an easy and understandable alternative using
 SIMD types directly.


I actually haven't had time to try out the new 2.60 alignment changes in
practise yet. As a Win64 D user, I'm stuck with compilers that are forever
3-6 months out of date (2.58). _
The use cases I required to do this stuff efficiently were definitely
agreed though by Walter, and to my knowledge, implemented... so it might be
some other subtle details.
It's possible that the intrinsic vector code-gen is hard-coded to use
unaligned loads too. You might need to assert appropriate alignment, and
then issue the movaps intrinsics directly, but I'm sure DMD can be fixed to
emit movaps when it detects the vector is aligned = 16 bytes.


[*clip* portability and cross-lane efficiency *clip*]


 Okay, that makes a lot of sense and is inline with what I was reading last
 night about FPU/SSE assembly code. However I'm also a bit confused. At some
 point, like in your hightmap example, I'm going to need to do arithmetic
 work on single vector components. Is there some sort of SSE
 arithmetic/shuffle instruction which uses masking that I should use to
 isolate and manipulate components?


Well, actually, height maps are one thing that hardware SIMD units aren't
intrinsically good at, because they do specifically require component-wise
access.
That said, there are still lots of interesting possibilities.

If you're operating on a height map, for instance, rather than looping over
the position vectors, fetching y from it, doing something with y (which I
presume involves foreign data?), then putting it back, and repeating over
the next vector...

Do something like:

  align(16) float[as-many-as-there-are-verts] height_offsets;
  foreach(h; height_offsets)
  {
// do some work to generate deltas for each vertex...
  }

Now what you can probably do is unpack them and apply them directly to the
vertex stream in a single pass:

  for(i = 0; i  numVerts; i += 4)
  {
four_heights = loadaps(height_offsets[i]);

float4[4] heights;
// do some shuffling/unpacking to result: four_heights.xyzw -
height[0].y, height[1].y, height[2].y, height[3].y (fiddly, but simple
enough)

vertices[i + 0] += height[0];
vertices[i + 1] += height[1];
vertices[i + 2] += height[2];
vertices[i + 3] += height[3];
  }

... I'm sure that could be improved, but you get the idea..? This approach
should pipeline well, have reasonably low bandwidth, make good use of
registers, and you can see there is no interaction between the FPU and SIMD
unit.

Disclaimer: I just made that up off the top of my head ;), but that
illustrates the kind of approach you would usually take in efficient (and
portable) SIMD code.


If not, and manipulating components is just bad for performance reasons,
 then I've figured out a solution to my original concern. By using this code:

 @property @trusted pure nothrow
 {
   auto ref x(T:float4)(auto ref T v) { return v.ptr[0]; }
   auto ref y(T:float4)(auto ref T v) { return v.ptr[1]; }
   auto ref z(T:float4)(auto ref T v) { return v.ptr[2]; }
   auto ref w(T:float4)(auto ref T v) { return v.ptr[3]; }

   void x(T:float4)(ref float4 v, float val) { v.ptr[0] = val; }
   void y(T:float4)(ref float4 v, float val) { v.ptr[1] = val; }
   void z(T:float4)(ref float4 v, float val) { v.ptr[2] = val; }
   void w(T:float4)(ref float4 v, float val) { v.ptr[3] = val; }
 }


This is fine if your vectors are in memory to begin with. But if you're
already doing work on them, and they are in registers/local variables, this
is the worst thing you can do.
It's a generally bad practise, and someone who isn't careful with their
usage will produce very slow code (on some platforms).


Re: core.simd woes

2012-10-02 Thread Manu
On 8 August 2012 07:54, F i L witte2...@gmail.com wrote:

 F i L wrote:

 Okay, that makes a lot of sense and is inline with what I was reading
 last night about FPU/SSE assembly code. However I'm also a bit confused. At
 some point, like in your hightmap example, I'm going to need to do
 arithmetic work on single vector components. Is there some sort of SSE
 arithmetic/shuffle instruction which uses masking that I should use to
 isolate and manipulate components?

 If not, and manipulating components is just bad for performance reasons,
 then I've figured out a solution to my original concern. By using this code:

 @property @trusted pure nothrow
 {
   auto ref x(T:float4)(auto ref T v) { return v.ptr[0]; }
   auto ref y(T:float4)(auto ref T v) { return v.ptr[1]; }
   auto ref z(T:float4)(auto ref T v) { return v.ptr[2]; }
   auto ref w(T:float4)(auto ref T v) { return v.ptr[3]; }

   void x(T:float4)(ref float4 v, float val) { v.ptr[0] = val; }
   void y(T:float4)(ref float4 v, float val) { v.ptr[1] = val; }
   void z(T:float4)(ref float4 v, float val) { v.ptr[2] = val; }
   void w(T:float4)(ref float4 v, float val) { v.ptr[3] = val; }
 }

 I am able to perform arithmetic on single components:

 auto vec = Vectors.float4(x, y, 0, 1); // factory
 vec.x += scalar; // += components

 again, I'll abandon this approach if there's a better way to manipulate
 single components, like you mentioned above. I'm just not aware of how to
 do that using SSE instructions alone. I'll do more research, but would
 appreciate any insight you can give.



 Okay, disregard this. I see you where talking about your function in
 std.simd (setY), and I'm referring to that for an example of the
 appropriate vector functions.


_


Re: core.simd woes

2012-10-02 Thread Manu
On 8 August 2012 14:14, F i L witte2...@gmail.com wrote:

 David Nadlinger wrote:

 objdump, otool – depending on your OS.


 Hey, nice tools. Good to know, thanks!


 Manu:

 Here's the disassembly for my benchmark code earlier, isolated between
 StopWatch .start()/.stop()

 https://gist.github.com/**3294283 https://gist.github.com/3294283


 Also, I noticed your std.simd.setY() function uses _blendps() op, but
 DMD's core.simd doesn't support this op (yet? It's there but commented
 out). Is there an alternative operation I can use for setY() ?


I haven't considered/written an SSE2 fallback yet, but I expect some trick
using shuf and/or shifts to blend the 2 vectors together will do it.


Re: core.simd woes

2012-10-02 Thread Manu
On 2 October 2012 05:28, F i L witte2...@gmail.com wrote:

 Not to resurrect the dead, I just wanted to share an article I came across
 concerning SIMD with Manu..

 http://www.gamasutra.com/view/**feature/4248/designing_fast_**
 crossplatform_simd_.phphttp://www.gamasutra.com/view/feature/4248/designing_fast_crossplatform_simd_.php

 QUOTE:

 1. Returning results by value

 By observing the intrisics interface a vector library must imitate that
 interface to maximize performance. Therefore, you must return the results
 by value and not by reference, as such:

 //correct
 inline Vec4 VAdd(Vec4 va, Vec4 vb)
 {
 return(_mm_add_ps(va, vb));
 };

 On the other hand if the data is returned by reference the interface will
 generate code bloat. The incorrect version below:

 //incorrect (code bloat!)
 inline void VAddSlow(Vec4 vr, Vec4 va, Vec4 vb)
 {
 vr = _mm_add_ps(va, vb);
 };

 The reason you must return data by value is because the quad-word
 (128-bit) fits nicely inside one SIMD register. And one of the key factors
 of a vector library is to keep the data inside these registers as much as
 possible. By doing that, you avoid unnecessary loads and stores operations
 from SIMD registers to memory or FPU registers. When combining multiple
 vector operations the returned by value interface allows the compiler to
 optimize these loads and stores easily by minimizing SIMD to FPU or memory
 transfers.

 2. Data Declared Purely

 Here, pure data is defined as data declared outside a class or
 struct by a simple typedef or define. When I was researching various
 vector libraries before coding VMath, I observed one common pattern among
 all libraries I looked at during that time. In all cases, developers
 wrapped the basic quad-word type inside a class or struct instead of
 declaring it purely, as follows:

 class Vec4
 {
 ...
 private:
 __m128 xyzw;
 };

 This type of data encapsulation is a common practice among C++ developers
 to make the architecture of the software robust. The data is protected and
 can be accessed only by the class interface functions. Nonetheless, this
 design causes code bloat by many different compilers in different
 platforms, especially if some sort of GCC port is being used.

 An approach that is much friendlier to the compiler is to declare the
 vector data purely, as follows:

 typedef __m128 Vec4;

 ENDQUOTE;




 The article is 2 years old, but It appears my earlier performance issue
 wasn't D related at all, but an issue with C as well. I think in this
 situation, it might be best (most optimized) to handle simd the C way by
 creating and alias or union of a simd intrinsic. D has a big advantage over
 C/C++ here because of UFCS, in that we can write external functions that
 appear no different to encapsulated object methods. That combined with
 public-aliasing means the end-user only sees our pretty functions, but
 we're not sacrificing performance at all.


These are indeed common gotchas. But they don't necessarily apply to D, and
if they do, then they should be bugged and hopefully addressed. There is no
reason that D needs to follow these typical performance patterns from C.
It's worth noting that not all C compilers suffer from this problem. There
are many (most actually) compilers that can recognise a struct with a
single member and treat it as if it were an instance of that member
directly when being passed by value.
It only tends to be a problem on older games-console compilers.

As I said earlier. When I get back to finishing srd.simd off (I presume
this will be some time after Walter has finished Win64 support), I'll go
through and scrutinise the code-gen for the API very thoroughly. We'll see
what that reveals. But I don't think there's any reason we should suffer
the same legacy C by-value code-gen problems in D... (hopefully I won't eat
those words ;)


Re: core.simd woes

2012-10-02 Thread jerro

On Tuesday, 2 October 2012 at 08:17:33 UTC, Manu wrote:

On 7 August 2012 16:56, jerro a...@a.com wrote:



 That said, almost all simd opcodes are directly accessible in 
std.simd.
There are relatively few obscure operations that don't have a 
representing

function.
The unpck/shuf example above for instance, they both 
effectively perform a

sort of swizzle, and both are accessible through swizzle!().



They aren't. Swizzle only takes one argument, so you cant use 
it to select
elements from two vectors. Both unpcklps and shufps take two 
arguments.

Writing a swizzle with two arguments would be much harder.



Any usages I've missed/haven't thought of; I'm all ears.


I don't think it is possible to think of all usages of this, but 
for every simd instruction there are valid usages. At least for 
writing pfft, I found shuffling two vectors very useful. For, 
example, I needed a function that takes a small, square, power of 
two number of elements stored in vectors and bit-reverses them - 
it rearanges them so that you can calculate the new index of each 
element by reversing bits of the old index (for 16 elements using 
4 element vectors this can actually be done using 
std.simd.transpose, but for AVX it was more efficient to make 
this function work on 64 elements). There are other places in 
pfft where I need to select elements from two vectors (for 
example, here 
https://github.com/jerro/pfft/blob/sine-transform/pfft/avx_float.d#L141 
is the platform specific code for AVX).


I don't think this are the kind of things that should be 
implemented in std.simd. If you wanted to implement all such 
operations (for example bit reversing a small array) that 
somebody may find useful at some time, std.simd would need to be 
huge, and most of it would never be used.


I can imagine, I'll have a go at it... it's something I 
considered, but not

all architectures can do it efficiently.
That said, a most-efficient implementation would probably still 
be useful
on all architectures, but for cross platform code, I usually 
prefer to
encourage people taking another approach rather than supply a 
function that

is not particularly portable (or not efficient when ported).


One way to do it would be to do the following for every set of 
selected indices: go through all the two element one instruction 
operations, and check if any of them does exactly what you need, 
and use it if it does. Otherwise do something that will always 
work although it may not always be optimal. One option would be 
to use swizzle on both vectors to get each of the elements to 
their final index and then blend the two vectors together. For 
sse 1, 2 and 3 you would need to use xorps to blend them, so I 
guess this is one more place where you would need vector literals.


Someone who knows which two element shuffling operations the 
platform supports could still write optimal platform specific 
(but portable across compilers) code this way and for others this 
would still be useful to some degree (the documentation should 
mention that it may not be very efficient, though). But I think 
that it would be better to have platform specific APIs for 
platform specific code, as I said earlier in this thread.


Unfortunately I can't, at least not a clean one. Using string 
mixins would
be one way but I think no one wants that kind of API in 
Druntime or Phobos.



Yeah, absolutely not.
This is possibly the most compelling motivation behind a 
__forceinline

mechanism that I've seen come up... ;)

 I'm already unhappy that

std.simd produces redundant function calls.

rant please  please please can haz __forceinline! /rant



I agree that we need that.



Huzzah! :)


Walter opposes this, right? I wonder how we could convince him.

There's one more thing that I wanted to ask you. If I were to add 
LDC support to std.simd, should I just add version(LDC) blocks to 
all the functions? Sounds like a lot of duplicated code...


Proposal: clean up semantics of array literals vs string literals

2012-10-02 Thread Don Clugston

The problem
---

String literals in D are a little bit magical; they have a trailing \0. 
This means that is possible to write,


printf(Hello, World!\n);

without including a trailing \0. This is important for compatibility 
with C. This trailing \0 is mentioned in the spec but only incidentally, 
and generally in connection with printf.


But the semantics are not well defined.

printf(Hello, W ~ orld!\n);

Does this have a trailing \0 ? I think it should, because it improves 
readability of string literals that are longer than one line. Currently 
DMD adds a \0, but it is not in the spec.


Now consider array literals.

printf(['H','e', 'l', 'l','o','\n']);

Does this have a trailing \0 ? Currently DMD does not put one in.
How about ['H','e', 'l', 'l','o'] ~  World!\n  ?

And Hello  ~ ['W','o','r','l','d','\n']   ?

And Hello World! ~ '\n' ?
And  null ~ Hello World!\n ?

Currently DMD puts \0 in some cases but not others, and it's rather random.

The root cause is that this trailing zero is not part of the type, it's 
part of the literal. There are no rules for how literals are propagated 
inside expressions, they are just literals. This is a mess.


There is a second difference.
Array literals of char type, have completely different semantics from 
string literals. In module scope:


char[] x = ['a'];  // OK -- array literals can have an implicit .dup
char[] y = b;// illegal

This is a big problem for CTFE, because for CTFE, a string is just a 
compile-time value, it's neither string literal nor array literal!


See bug 8660 for further details of the problems this causes.


A proposal to clean up this mess


Any compile-time value of type immutable(char)[] or const(char)[], 
behaves a string literals currently do, and will have a \0 appended when 
it is stored in the executable.


ie,

enum hello = ['H', 'e', 'l', 'l', 'o', '\n'];
printf(hello);

will work.

Any value of type char[], which is generated at compile time, will not 
have the trailing \0, and it will do an implicit dup (as current array 
literals do).


char [] foo()
{
return abc;
}

char [] x = foo();

// x does not have a trailing \0, and it is implicitly duped, even 
though it was not declared with an array literal.


---
So that the difference between string literals and char array literals 
would simply be that the latter are polysemous. There would be no 
semantics associated with the form of the literal itself.



We still have this oddity:


void foo(char qqq = 'b') {

   string x = abc;// trailing \0
   string y = ['a', 'b', 'c'];  // trailing \0
   string z = ['a', qqq, 'c'];  // no trailing \0
}

This is because we made the (IMHO mistaken) decision to allow variables 
inside array literals.
This is the reason why I listed _compile time value_ in the requirement 
for having a \0, rather than entirely basing it on the type.


We could fix that with a language change: an array literal which 
contains a variable should not be of immutable type. It should be of 
mutable type (or const, in the case where it contains other, immutable 
values).


So char [] w = ['a', qqq, 'c']; should compile (it currently doesn't, 
even though w is allocated on the heap).


But that's a separate proposal from the one I'm making here. I just need 
a decision on the main proposal so that I can fix a pile of CTFE bugs.


Re: Proposal: clean up semantics of array literals vs string literals

2012-10-02 Thread Tobias Pankrath

On Tuesday, 2 October 2012 at 11:10:46 UTC, Don Clugston wrote:

The problem
---

String literals in D are a little bit magical; they have a 
trailing \0. This means that is possible to write,


printf(Hello, World!\n);

without including a trailing \0. This is important for 
compatibility with C. This trailing \0 is mentioned in the spec 
but only incidentally, and generally in connection with printf.


But the semantics are not well defined.

printf(Hello, W ~ orld!\n);

If every string literal is \0-terminated, then there should be 
two \0 in the final string. I guess that's not the case and 
that's actually my preferred behaviour, but the spec should make 
it crystal clear in which situations a

string literal gets a terminator and in which not.



Re: Proposal: clean up semantics of array literals vs string literals

2012-10-02 Thread deadalnix
Well the whole mess come from the fact that D conflate C string and D 
string.


The first problem come from the fact that D array are implicitly 
convertible to pointer. So calling D function that expect a char* is 
possible with D string even if it is unsafe and will not work in the 
general case.


The fact that D provide tricks that will make it work in special cases 
is armful as previous discussion have shown (many D programmer assume 
that this will always work because of toy tests they have made, where in 
case it won't and toStringz must be used).


The only sane solution I can think of is to :
 - disallow slice to convert implicitly to pointer. .ptr is made for that.
 - Do not put any trailing 0 in string literal, unless it is specified 
explicitly ( foobar\0 ).
 - Except if a const(char)* is expected from the string literal. In 
case it becomes a Cstring literal, with a trailing 0. This is made to 
allow uses like printf(foobar);


In other terms, the receiver type is used to decide if the compiler 
generate a string literal or a Cstring literal.


Other addition of 0 are just confusing, and will make incorrect code 
work in special cases, which is something you usually don't want. Code 
that work by accident often backfire in spectacular ways at the least 
expected moment.


Re: Proposal: clean up semantics of array literals vs string literals

2012-10-02 Thread Andrej Mitrovic
On 10/2/12, Don Clugston d...@nospam.com wrote:
 A proposal to clean up this mess
 

 Any compile-time value of type immutable(char)[] or const(char)[],
 behaves a string literals currently do, and will have a \0 appended when
 it is stored in the executable.

 ie,

 enum hello = ['H', 'e', 'l', 'l', 'o', '\n'];
 printf(hello);

 will work.

What about these, will these pass?:

enum string x = foo;
assert(x.length == 3);

void test(string x) { assert(x.length == 3); }
test(x);

If these don't pass the proposal will break code.


Re: Getting started with D - Phobos documentation sucks

2012-10-02 Thread Gary Willoughby
On Saturday, 29 September 2012 at 16:34:41 UTC, Andrei 
Alexandrescu wrote:

On 9/29/12 11:30 AM, Mr. Anonymous wrote:
I think documentation is really important, and something has 
to be done
about it. How can a newcomer get started with D when he 
doesn't have a

readable documentation of Phobos?


Agree. It's high time we replace the silly litany of names at 
the top with a more sensible index (or, indeed, nothing at all!)


Andrei


That sounds great. I'm an experience developer new to D and i 
find the documentation quite frustrating to navigate and use. 
Things are kind of all over the place at the minute.


Re: Idea: Introduce zero-terminated string specifier

2012-10-02 Thread Andrei Alexandrescu

On 10/2/12 4:09 AM, Walter Bright wrote:

On 10/1/2012 7:22 PM, Steven Schveighoffer wrote:

Does it make sense for Phobos to provide such a shortcut in an obscure
header somewhere? Like std.cstring? Or should we just say roll your own
if you need it?


As a matter of principle, I really don't like gobs of Phobos functions
that are literally one liners. Phobos should not become a mile wide but
inch deep library of trivia. It should consist of non-trivial, useful,
and relatively deep functions.


Well there are some possible reasons. Clearly useful functionality 
that's nontrivial deserves being abstracted in a function. On the other 
hand, even a short function is valuable if frequent enough and deserving 
of a name. We have e.g. s.strip even though it's equivalent to 
s.stripLeft.stripRight.


Andrei


Re: Idea: Introduce zero-terminated string specifier

2012-10-02 Thread deadalnix

Le 01/10/2012 22:33, Vladimir Panteleev a écrit :

On Monday, 1 October 2012 at 12:12:52 UTC, deadalnix wrote:

Le 01/10/2012 13:29, Vladimir Panteleev a écrit :

On Monday, 1 October 2012 at 10:56:36 UTC, deadalnix wrote:

How does to!string know that the string is 0 terminated ?


By convention (it doesn't).


It is unsafe as hell oO


Forcing the programmer to put strlen calls everywhere in his code is not
any safer.


I make the library safer. If the programmer manipulate unsafe construct 
(like c strings) it is up to the programmer to ensure safety, not the lib.


Re: Proposal: clean up semantics of array literals vs string literals

2012-10-02 Thread Don Clugston

On 02/10/12 14:02, Andrej Mitrovic wrote:

On 10/2/12, Don Clugston d...@nospam.com wrote:

A proposal to clean up this mess


Any compile-time value of type immutable(char)[] or const(char)[],
behaves a string literals currently do, and will have a \0 appended when
it is stored in the executable.

ie,

enum hello = ['H', 'e', 'l', 'l', 'o', '\n'];
printf(hello);

will work.


What about these, will these pass?:

enum string x = foo;
assert(x.length == 3);

void test(string x) { assert(x.length == 3); }
test(x);

If these don't pass the proposal will break code.


Yes, they pass. The \0 is not included in the string length. It's 
effectively in the data segment, not in the string.





Re: Idea: Introduce zero-terminated string specifier

2012-10-02 Thread deadalnix

Le 02/10/2012 03:13, Walter Bright a écrit :

On 9/30/2012 11:31 AM, deadalnix wrote:

If you know that a string is 0 terminated, you can easily create a slice
from it as follow :

char* myZeroTerminatedString;
char[] myZeroTerminatedString[0 .. strlen(myZeroTerminatedString)];

It is clean and avoid to modify the stdlib in an unsafe way.



Of course, using strlen() is always going to be unsafe. But having %zs
is equally unsafe for the same reason.

deadalnix's example shows that adding a new format specifier %zs adds
little value, but it gets much worse. Since %zs is inherently unsafe, it
hides such unsafety in a commonly used library function, which will
infect everything else that transitively calls writefln with unsafety.

This makes %zs an unacceptable feature.


Exactly my point.


Re: Proposal: clean up semantics of array literals vs string literals

2012-10-02 Thread Don Clugston

On 02/10/12 13:26, deadalnix wrote:

Well the whole mess come from the fact that D conflate C string and D
string.

The first problem come from the fact that D array are implicitly
convertible to pointer. So calling D function that expect a char* is
possible with D string even if it is unsafe and will not work in the
general case.

The fact that D provide tricks that will make it work in special cases
is armful as previous discussion have shown (many D programmer assume
that this will always work because of toy tests they have made, where in
case it won't and toStringz must be used).

The only sane solution I can think of is to :
  - disallow slice to convert implicitly to pointer. .ptr is made for that.
  - Do not put any trailing 0 in string literal, unless it is specified
explicitly ( foobar\0 ).
  - Except if a const(char)* is expected from the string literal. In
case it becomes a Cstring literal, with a trailing 0. This is made to
allow uses like printf(foobar);

In other terms, the receiver type is used to decide if the compiler
generate a string literal or a Cstring literal.


This still doesn't solve the problem of the difference between array 
literals and string literals (the magical implicit .dup), which is the 
key problem I'm trying to solve.




Re: Setting defaults to variadic template args

2012-10-02 Thread Jacob Carlborg

On 2012-10-02 15:15, Manu wrote:

Is it possible?

Eg:
   struct Event(T... = (int, float))
   {
 void F(T...); // - should default to F(int, float)
   }

Does anyone have any clever tricks that will work in this scenario? Some
magic tuple syntax?


struct Event
{
static if (T.length == 0)
void F(int, float);

else
void F(T);
}

Perhaps?

--
/Jacob Carlborg


Re: Proposal: clean up semantics of array literals vs string literals

2012-10-02 Thread Don Clugston

On 02/10/12 13:18, Tobias Pankrath wrote:

On Tuesday, 2 October 2012 at 11:10:46 UTC, Don Clugston wrote:

The problem
---

String literals in D are a little bit magical; they have a trailing
\0. This means that is possible to write,

printf(Hello, World!\n);

without including a trailing \0. This is important for compatibility
with C. This trailing \0 is mentioned in the spec but only
incidentally, and generally in connection with printf.

But the semantics are not well defined.

printf(Hello, W ~ orld!\n);


If every string literal is \0-terminated, then there should be two \0 in
the final string. I guess that's not the case and that's actually my
preferred behaviour, but the spec should make it crystal clear in which
situations a
string literal gets a terminator and in which not.


The \0 is *not* part of the string, it lies after the string.
It's as if all memory is cleared, then the string literals are copied 
into it, with a gap of at least one byte between each. The 'trailing 0' 
is not part of the literal, it's the underlying cleared memory.


At least, that's how I understand it. The spec is very vague.



IndexType for ranges

2012-10-02 Thread monarch_dodra
If you've ever worked on a template that needs to index a range, 
you may have run into this problem: What is the type you should 
use to index an RA range?


The problem may not sound like much, but it is a royal pain in 
the ass when trying to write wrapper ranges, such as 
std.algorithm.map.


Shoot to low, and you may en up failing to compile code such as 
r[r.length - 1], because r.length is of type ulong, making the 
implicit down-cast illegal.


Shoot to high, and the implementation itself will fail to compile:
auto opIndex(ulong n)
return r[n]; //cannot cast ulong to size_t

You might think just use typeof(length) BUT:
*you aren't even guaranteed that typeof(length) will be 
correct! Certain ranges, such as iota, will return a length 
usually of type uint, but be indexed with ulong... :/

*Infinite ranges don't have length...


I'd like to propose a trait called IndexType or IndexingType. 
This trait would be defined as A type that can be used to safely 
index (or slice) a range.


Here is how I would define and implement this trait:
If R is a RandomAccessRange, then IndexType is the type used by 
opIndex.


Simple enough, and I got it done and working locally, but there 
are 2 issues I'd like to share and inquire here:


*First, if R also verifies hasLength, then writing r[r.length] 
should be a compile time legality: The type returned by Length 
must fit inside opIndex. This might sound obvious, but this 
restriction is .
**I propose adding this extra restriction to isRandomAccess: if 
the range verifies $(D hasLength), then it must also be 
index-able by the type returned by length


*Second, the idea is that IndexType should *also* be useable to 
slice a range. Because of this, I'd like to add two extra 
restrictions to isSliceable:
**A sliceable range must also be indexable(RA). A range that is 
sliceable but not indexeable is kind of retarded anyways, since 
you can index doing r[n, n+1].front;
**Given that R must be indexable, the type used to index the 
range must be compatible with slicing.



These are not big changes I'm proposing, but they *may* break 
some existing ranges. Those ranges are arguably retarded, and 
these changes would enforce correctness, but they'd break none 
the less. I'd like some feedback if you think this trait is worth 
pushing?




For illustration, here are three examples:
//
struct S1
{
  //Other primitives here...
  @property ushort length();
  auto opIndex(uint);
  auto opSlice(ulong, ulong);
}
struct S2
{
  //Other primitives here...
  @property ulong length();
  auto opIndex(ushort);
}
struct S3
{
  //Other primitives here...
  @property ushort length();
  auto opIndex(ulong);
  auto opSlice(ushort, ushort);
}
//
Here:
*S1 would have a IndexType equal to uint. S1 would be a 
RandomAccessRange and verify isSliceable.
*S2 would NOT be a random access range, because its length can't 
index it.
*S3 would be a RandomAccess. it's IndexType would be ulong. It 
would not verify hasSlicing because it can't be sliced using 
IndexType.


Re: core.simd woes

2012-10-02 Thread Manu
On 2 October 2012 13:49, jerro a...@a.com wrote:


 I don't think it is possible to think of all usages of this, but for every
 simd instruction there are valid usages. At least for writing pfft, I found
 shuffling two vectors very useful. For, example, I needed a function that
 takes a small, square, power of two number of elements stored in vectors
 and bit-reverses them - it rearanges them so that you can calculate the new
 index of each element by reversing bits of the old index (for 16 elements
 using 4 element vectors this can actually be done using std.simd.transpose,
 but for AVX it was more efficient to make this function work on 64
 elements). There are other places in pfft where I need to select elements
 from two vectors (for example, here https://github.com/jerro/pfft/**
 blob/sine-transform/pfft/avx_**float.d#L141https://github.com/jerro/pfft/blob/sine-transform/pfft/avx_float.d#L141is
  the platform specific code for AVX).

 I don't think this are the kind of things that should be implemented in
 std.simd. If you wanted to implement all such operations (for example bit
 reversing a small array) that somebody may find useful at some time,
 std.simd would need to be huge, and most of it would never be used.


I was referring purely to your 2-vector swizzle idea (or useful high-level
ideas in general). Not to hyper-context-specific functions :P


 I can imagine, I'll have a go at it... it's something I considered, but not
 all architectures can do it efficiently.
 That said, a most-efficient implementation would probably still be useful
 on all architectures, but for cross platform code, I usually prefer to
 encourage people taking another approach rather than supply a function
 that
 is not particularly portable (or not efficient when ported).


 One way to do it would be to do the following for every set of selected
 indices: go through all the two element one instruction operations, and
 check if any of them does exactly what you need, and use it if it does.
 Otherwise do something that will always work although it may not always be
 optimal. One option would be to use swizzle on both vectors to get each of
 the elements to their final index and then blend the two vectors together.
 For sse 1, 2 and 3 you would need to use xorps to blend them, so I guess
 this is one more place where you would need vector literals.

 Someone who knows which two element shuffling operations the platform
 supports could still write optimal platform specific (but portable across
 compilers) code this way and for others this would still be useful to some
 degree (the documentation should mention that it may not be very efficient,
 though). But I think that it would be better to have platform specific APIs
 for platform specific code, as I said earlier in this thread.


Yeah, I have some ideas. Some permutations are obvious, the worst-case
fallback is also obvious, but there are a lot of semi-efficient in-between
cases which could take a while to identify and test. It'll be a massive
block of static-if code to be sure ;)


 Unfortunately I can't, at least not a clean one. Using string mixins would
 be one way but I think no one wants that kind of API in Druntime or
 Phobos.



 Yeah, absolutely not.
 This is possibly the most compelling motivation behind a __forceinline
 mechanism that I've seen come up... ;)

  I'm already unhappy that

 std.simd produces redundant function calls.

 rant please  please please can haz __forceinline! /rant


 I agree that we need that.


 Huzzah! :)


 Walter opposes this, right? I wonder how we could convince him.


I just don't think he's seen solid undeniable cases where it's necessary.


There's one more thing that I wanted to ask you. If I were to add LDC
 support to std.simd, should I just add version(LDC) blocks to all the
 functions? Sounds like a lot of duplicated code...


Go for it. And yeah, just add another version(). I don't think it can be
done without blatant duplication. Certainly not without __forceinline
anyway, and even then I'd be apprehensive to trust the code-gen of
intrinsics wrapped in inline wrappers.

That file will most likely become a nightmarish bloated mess... but that's
the point of libraries ;) .. It's best all that horrible munge-ing for
different architectures/compilers is put in one place and tested
thoroughly, than to not provide it and allow an infinite variety of
different implementations to appear.

What we may want to do in the future is to split the different
compilers/architectures into readable sub-modules, and public include the
appropriate one based on version logic from std.simd... but I wouldn't want
to do that until the API has stabilised.


Re: Setting defaults to variadic template args

2012-10-02 Thread luka8088


module program;

import std.stdio;
import std.traits;
import std.typetuple;

struct Event (T...) {

  alias EraseAll!(void, TypeTuple!(T,
Select!(T.length  1, int, void),
Select!(T.length  2, float, void),
  )) T2;

  void F (T2 args) {
writeln(typeid(typeof(args)));
  }

}

void main () {

  Event!() e1;

  e1.F(5, 6);

}


On Tuesday, 2 October 2012 at 13:15:08 UTC, Manu wrote:

Is it possible?

Eg:
  struct Event(T... = (int, float))
  {
void F(T...); // - should default to F(int, float)
  }

Does anyone have any clever tricks that will work in this 
scenario? Some

magic tuple syntax?





Re: Setting defaults to variadic template args

2012-10-02 Thread Manu
On 2 October 2012 16:24, Andrej Mitrovic andrej.mitrov...@gmail.com wrote:

 On 10/2/12, Manu turkey...@gmail.com wrote:
  Does anyone have any clever tricks that will work in this scenario? Some
  magic tuple syntax?

 Without resorting to helper templates I only know of using this internal
 trick:

 struct Event(Args...)
 {
 static if (Args.length)
 alias Args T;
 else
 alias TypeTuple!(int, float) T;

 void F(T t) { }
 }

 Also there's a somewhat related bug but for variadic template
 functions with default arguments:
 http://d.puremagic.com/issues/show_bug.cgi?id=8687


I think this is fine for my needs. Thanks!


Re: LDC blacklisted in Ubuntu

2012-10-02 Thread Joseph Rushton Wakeling

On 09/27/2012 12:02 PM, Joseph Rushton Wakeling wrote:

I'd love to, but it would be irresponsible to commit to it as (right now
especially) I don't have a very good idea of what time I'll be able to offer.


Just to follow up here -- a couple of days ago I pulled LDC from GitHub and 
built it.  First time I've tried LDC in a while as up until fairly recently I 
was not aware of the work on GitHub.


Very nice and friendly build process -- I like the inclusion of druntime and 
phobos as submodules.  The executables produced are nice and fast -- maybe about 
10-15% slower than GDC for the number-crunching code I tested, but much faster 
than dmd-compiled programs, and the compilation process itself is super-fast.


I'll try and follow up in about 6 weeks' time by which time I should be settled 
in new job.  If it's all all right time-wise, and if someone can mentor me in 
production of good-quality deb files, I'd be willing to reconsider the 
maintainer issue. :-)


Re: Setting defaults to variadic template args

2012-10-02 Thread luka8088

Or maybe... This seems like a much better solution:


module program;

import std.stdio;
import std.traits;
import std.typetuple;

template SelectTrue (bool condition, T) {
  static if (condition)
alias T SelectTrue;
}

struct Event (T...) {

  alias TypeTuple!(T,
SelectTrue!(T.length  1, int),
SelectTrue!(T.length  2, float),
  ) T2;

  void F (T2 args) {
writeln(typeid(typeof(args)));
  }

}

void main () {

  Event!() e1;

  e1.F(5, 6);

}



On Tuesday, 2 October 2012 at 13:44:10 UTC, luka8088 wrote:


module program;

import std.stdio;
import std.traits;
import std.typetuple;

struct Event (T...) {

  alias EraseAll!(void, TypeTuple!(T,
Select!(T.length  1, int, void),
Select!(T.length  2, float, void),
  )) T2;

  void F (T2 args) {
writeln(typeid(typeof(args)));
  }

}

void main () {

  Event!() e1;

  e1.F(5, 6);

}


On Tuesday, 2 October 2012 at 13:15:08 UTC, Manu wrote:

Is it possible?

Eg:
 struct Event(T... = (int, float))
 {
   void F(T...); // - should default to F(int, float)
 }

Does anyone have any clever tricks that will work in this 
scenario? Some

magic tuple syntax?





Re: Proposal: clean up semantics of array literals vs string literals

2012-10-02 Thread kenji hara
2012/10/2 Don Clugston d...@nospam.com:
 The problem
 ---

 String literals in D are a little bit magical; they have a trailing \0. This
 means that is possible to write,

 printf(Hello, World!\n);

 without including a trailing \0. This is important for compatibility with C.
 This trailing \0 is mentioned in the spec but only incidentally, and
 generally in connection with printf.

 But the semantics are not well defined.

 printf(Hello, W ~ orld!\n);

 Does this have a trailing \0 ? I think it should, because it improves
 readability of string literals that are longer than one line. Currently DMD
 adds a \0, but it is not in the spec.

 Now consider array literals.

 printf(['H','e', 'l', 'l','o','\n']);

 Does this have a trailing \0 ? Currently DMD does not put one in.
 How about ['H','e', 'l', 'l','o'] ~  World!\n  ?

 And Hello  ~ ['W','o','r','l','d','\n']   ?

 And Hello World! ~ '\n' ?
 And  null ~ Hello World!\n ?

 Currently DMD puts \0 in some cases but not others, and it's rather random.

 The root cause is that this trailing zero is not part of the type, it's part
 of the literal. There are no rules for how literals are propagated inside
 expressions, they are just literals. This is a mess.

 There is a second difference.
 Array literals of char type, have completely different semantics from string
 literals. In module scope:

 char[] x = ['a'];  // OK -- array literals can have an implicit .dup
 char[] y = b;// illegal

 This is a big problem for CTFE, because for CTFE, a string is just a
 compile-time value, it's neither string literal nor array literal!

 See bug 8660 for further details of the problems this causes.


 A proposal to clean up this mess
 

 Any compile-time value of type immutable(char)[] or const(char)[], behaves a
 string literals currently do, and will have a \0 appended when it is stored
 in the executable.

 ie,

 enum hello = ['H', 'e', 'l', 'l', 'o', '\n'];
 printf(hello);

 will work.

 Any value of type char[], which is generated at compile time, will not have
 the trailing \0, and it will do an implicit dup (as current array literals
 do).

 char [] foo()
 {
 return abc;
 }

 char [] x = foo();

 // x does not have a trailing \0, and it is implicitly duped, even though it
 was not declared with an array literal.

 ---
 So that the difference between string literals and char array literals would
 simply be that the latter are polysemous. There would be no semantics
 associated with the form of the literal itself.


 We still have this oddity:


 void foo(char qqq = 'b') {

string x = abc;// trailing \0
string y = ['a', 'b', 'c'];  // trailing \0
string z = ['a', qqq, 'c'];  // no trailing \0
 }

 This is because we made the (IMHO mistaken) decision to allow variables
 inside array literals.
 This is the reason why I listed _compile time value_ in the requirement for
 having a \0, rather than entirely basing it on the type.

 We could fix that with a language change: an array literal which contains a
 variable should not be of immutable type. It should be of mutable type (or
 const, in the case where it contains other, immutable values).

 So char [] w = ['a', qqq, 'c']; should compile (it currently doesn't, even
 though w is allocated on the heap).

 But that's a separate proposal from the one I'm making here. I just need a
 decision on the main proposal so that I can fix a pile of CTFE bugs.

Maybe your proposal is correct.
I think the key idea is *polysemous typed string literal*.

When based on the Ideal D Interpreter in my brain, the organized rule
will become like follows.

1-1) In semantic level, D should have just one polysemous string
literal, which is an array of char.
1-2) In token level, D has two represents for the polysemous string
literal, they are str and ['s','t','r'].

2) The polysemous string literl is implicitly convertible to
[wd]?char[] and immutable([wd]?char)[] (I think const([wd]?char)[] is
not need, because immutable([wd]?char)[] is implicitly convertible to
them).

3) The concatenation result between polysemous literals is still
polysemous, but its representation is different based on the both side
of the operator.

   str ~ str; // strstr
   str ~ ['s','t','r']; // ['s','t','r','s','t','r']
   str ~ 's';   // strs
   ['s','t','r'] ~ 's';   // ['s','t','r','s']
   str ~ null;  // str
   ['s','t','r'] ~ null;  // ['s','t','r']

4) After semantics _and_ optimization, polysemous string literal which
represented as like
 4-1) str is typed as immutable([wd]?char)[] (The char type is
depends on the literal suffix).
 4-2) ['s','t','r'] is typed as ([wd]?char)[] (The char type is
depends on the common type of its elements).

5) In object file generating phase, string literal which typed as
  5-1) immutable([wd]?)char[] is stored in the executable and
implicitly terminated with \0.
  5-2) [wd]?char[] are stored in the executable as the 

Re: Setting defaults to variadic template args

2012-10-02 Thread luka8088

And the simplest solution wins:

module program;

import std.stdio;
import std.traits;
import std.typetuple;

struct Event (T1 = int, T2 = float, Telse...) {

  alias TypeTuple!(T1, T2, Telse) T;

  void F (T args) {
writeln(typeid(typeof(args)));
  }

}

void main () {

  Event!() e1;

  e1.F(5, 6);

}

I hope that you found the solution that you where looking for.

On Tuesday, 2 October 2012 at 13:49:56 UTC, luka8088 wrote:

Or maybe... This seems like a much better solution:


module program;

import std.stdio;
import std.traits;
import std.typetuple;

template SelectTrue (bool condition, T) {
  static if (condition)
alias T SelectTrue;
}

struct Event (T...) {

  alias TypeTuple!(T,
SelectTrue!(T.length  1, int),
SelectTrue!(T.length  2, float),
  ) T2;

  void F (T2 args) {
writeln(typeid(typeof(args)));
  }

}

void main () {

  Event!() e1;

  e1.F(5, 6);

}



On Tuesday, 2 October 2012 at 13:44:10 UTC, luka8088 wrote:


module program;

import std.stdio;
import std.traits;
import std.typetuple;

struct Event (T...) {

 alias EraseAll!(void, TypeTuple!(T,
   Select!(T.length  1, int, void),
   Select!(T.length  2, float, void),
 )) T2;

 void F (T2 args) {
   writeln(typeid(typeof(args)));
 }

}

void main () {

 Event!() e1;

 e1.F(5, 6);

}


On Tuesday, 2 October 2012 at 13:15:08 UTC, Manu wrote:

Is it possible?

Eg:
struct Event(T... = (int, float))
{
  void F(T...); // - should default to F(int, float)
}

Does anyone have any clever tricks that will work in this 
scenario? Some

magic tuple syntax?





Re: Proposal: clean up semantics of array literals vs string literals

2012-10-02 Thread monarch_dodra

On Tuesday, 2 October 2012 at 11:10:46 UTC, Don Clugston wrote:

[SNIP]
A proposal to clean up this mess
[SNIP]


While I think it is convenient to be able to write 
'printf(world);', as you point out, I think that the fact that 
it works inconsistently (and by that, I mean there are rules 
and exceptions), is even more dangerous.


If at all possible, I'd rather side with consistency, then the 
we got your back... except when we don't approach: IE: strings 
are NEVER null terminated.


In theory, how often do you *really* need null terminated 
strings? And when you do, wouldn't it be safer to just write 
'printf(world\0)'? or 'printf(str ~ world ~ '\0');' rather 
than Am I in a case where it is null terminated? Yeah... 90% 
confident I am...


If you want 0 termination, then make it explicit, that's my 
opinion.


Besides, as you said, the null termination is not documented, so 
anything relying on it is a bug really. Just an observation of an 
implementation detail.


Re: Setting defaults to variadic template args

2012-10-02 Thread Manu
On 2 October 2012 16:45, Manu turkey...@gmail.com wrote:

 On 2 October 2012 16:24, Andrej Mitrovic andrej.mitrov...@gmail.comwrote:

 On 10/2/12, Manu turkey...@gmail.com wrote:
  Does anyone have any clever tricks that will work in this scenario? Some
  magic tuple syntax?

 Without resorting to helper templates I only know of using this internal
 trick:

 struct Event(Args...)
 {
 static if (Args.length)
 alias Args T;
 else
 alias TypeTuple!(int, float) T;

 void F(T t) { }
 }

 Also there's a somewhat related bug but for variadic template
 functions with default arguments:
 http://d.puremagic.com/issues/show_bug.cgi?id=8687


 I think this is fine for my needs. Thanks!


Actually, this leaves a problem...
Distinction between:
  Event x; // using defaults
and
  Event!() x; // explicitly selecting none (which would fall back to the
defaults)

Is such a distinction possible? I presume not...


Re: A study on immutability usage

2012-10-02 Thread renoX
Interesting, I vaguely remember that Eiffel has a 'once' keyword, 
but I'm not sure if it could help here.





zero-terminated strings, string literals, etc

2012-10-02 Thread Regan Heath
Recent discussions on the zero terminated string problems and  
inconsistency of string literals has me, again, wondering why D doesn't  
have a 'type' to represent C's zero terminated strings.  It seems to me  
that having a type, and typing C functions with it would solve a lot of  
problems.


The compiler could/would then error if people attempted to pass a D string  
without converting it correctly.


The compiler would create literals with or without \0 as required by the  
'type' being assigned, parameter passed, etc.


The conversion function from a D string to a C string would return the new  
type.


A %sz format specifier could be added to writef which would be able to  
type check the argument.


As the only way to get a variable of the new type would be from a literal,  
conversion or C function call so we could be sure it was in fact \0  
terminated(*), and so..


An implicit conversion between a C string and a D string (slice using  
strlen) would be possible, and safe.  (Though, not at zero runtime cost)


Existing (correct) code would continue to compile, by this I mean:
 - passing literals
 - calling a conversion function for each D string argument

But code which passes D string variables to C functions without conversion  
would start to fail to compile, so the change will 'break' existing code.


There would be several solutions in these cases:

1) add a call to a conversion function.  Introducing a conversion cost  
which was not previously present.


2) re-type the variable as a C string.  If it's not used for anything else  
then this is more correct.  If it's passed to other code then because a  
C string will implicitly converts (with a slice/strlen) to a D string this  
substitution will work in most cases, however that act of conversion will  
incur a cost (but it can/should be one off if the result is assigned/kept).


I am probably missing something obvious, or I have forgotten one of the  
array/slice complexities which makes this a nightmare.


Thoughts?

Regan

(*) Ignoring buggy/broken C functions returning non-zero terminated  
strings.. as we will crash on these no matter what in any case.


--
Using Opera's revolutionary email client: http://www.opera.com/mail/


Re: Proposal: clean up semantics of array literals vs string literals

2012-10-02 Thread deadalnix

Le 02/10/2012 15:12, Don Clugston a écrit :

On 02/10/12 13:26, deadalnix wrote:

Well the whole mess come from the fact that D conflate C string and D
string.

The first problem come from the fact that D array are implicitly
convertible to pointer. So calling D function that expect a char* is
possible with D string even if it is unsafe and will not work in the
general case.

The fact that D provide tricks that will make it work in special cases
is armful as previous discussion have shown (many D programmer assume
that this will always work because of toy tests they have made, where in
case it won't and toStringz must be used).

The only sane solution I can think of is to :
- disallow slice to convert implicitly to pointer. .ptr is made for that.
- Do not put any trailing 0 in string literal, unless it is specified
explicitly ( foobar\0 ).
- Except if a const(char)* is expected from the string literal. In
case it becomes a Cstring literal, with a trailing 0. This is made to
allow uses like printf(foobar);

In other terms, the receiver type is used to decide if the compiler
generate a string literal or a Cstring literal.


This still doesn't solve the problem of the difference between array
literals and string literals (the magical implicit .dup), which is the
key problem I'm trying to solve.



OK, infact we have 2 different and unrelated problems here. I have to 
say I have no idea for the second one.


Re: Proposal: clean up semantics of array literals vs string literals

2012-10-02 Thread Andrei Alexandrescu

On 10/2/12 7:11 AM, Don Clugston wrote:

The problem
---

String literals in D are a little bit magical; they have a trailing \0.

[snip]

I don't mean to be Debbie Downer on this because I reckon it addresses 
an issue that some have, although I never do. With that warning, a few 
candid opinions follow.


First, I think zero-terminated strings shouldn't be needed frequently 
enough in D code to make this necessary.


Second, a simple and workable solution to this would be to address the 
matter dynamically: make toStringz opportunistically look whether 
there's a \0 beyond the end of the string, EXCEPT when the string 
happens to end exactly at a page boundary (in which case accessing 
memory beyond the end of the string may produce a page fault). With this 
simple dynamic test we don't need precise and stringent rules for the 
implementation.


Third, the complex set of rules proposed pushes the number of cases in 
which the \0 is guaranteed, but doesn't make for a clear and easy to 
remember boundary. Therefore people will need to remember some more 
rules to make sure they can, well, avoid a call to toStringz.


On 10/2/12 10:55 AM, Regan Heath wrote:

Recent discussions on the zero terminated string problems and
inconsistency of string literals has me, again, wondering why D
doesn't have a 'type' to represent C's zero terminated strings.  It
seems to me that having a type, and typing C functions with it would
solve a lot of problems.

[snip]

I am probably missing something obvious, or I have forgotten one of
the array/slice complexities which makes this a nightmare.


You're not missing anything and defining a zero-terminated type is 
something I considered doing and have been highly interested in. My 
interest is motivated by the fact that sentinel-terminated structures 
are a very interesting example of forward ranges that are also 
contiguous. That sets them apart from both singly-linked lists and 
simple arrays, and gives them interesting properties.


I'd be interested in defining the more general:

struct SentinelTerminatedSlice(T, T terminator)
{
private T* data;
...
}

That would be a forward range and the instantiation 
SentinelTerminatedSlice!(char, 0) would be CString.


However, so far I held off of defining such a range because C-strings 
are seldom useful in D code and there are not many other compelling 
examples of sentinel-terminated ranges. Maybe it's time to dust off that 
idea, I'd love it if we gathered enough motivation for it.



Andrei


Re: zero-terminated strings, string literals, etc

2012-10-02 Thread David

Am 02.10.2012 16:55, schrieb Regan Heath:

Recent discussions on the zero terminated string problems and
inconsistency of string literals has me, again, wondering why D doesn't
have a 'type' to represent C's zero terminated strings.  It seems to me
that having a type, and typing C functions with it would solve a lot of
problems.


You have basically a type only used for 0-terminated strings, char*, in 
D you use normally string, and if you wanna represent binary data you 
use ubyte[], I've never used char* except for interfacing with C. I 
would prefer a library soulution, some kind of Struct which is 
implicitly convertable to char* (0-terminates) and also to string (not 
0-terminated), not sure how to implement that though.




Re: Proposal: clean up semantics of array literals vs string literals

2012-10-02 Thread Peter Alexander
On Tuesday, 2 October 2012 at 15:14:10 UTC, Andrei Alexandrescu 
wrote:
However, so far I held off of defining such a range because 
C-strings are seldom useful in D code [...]


I think your view of what is common in D code is not 
representative. You are primarily a library writer, which means 
you rarely have to interface with other code. Please correct me 
if I'm wrong, but I don't believe you've written much 
application-level D code.


For people that write applications, we have the unfortunate chore 
of having to call lots of C APIs to get things done. There's a 
long list of things for which there is no D interface (graphics, 
audio, input, GUI, database, platform APIs, various 3rd party 
libs). Invariably these interfaces require C strings. In short, 
if you write applications in D, you need C strings.


I don't know what the right decision is here, but please do not 
say that C-strings are seldom useful in D code.






Re: Setting defaults to variadic template args

2012-10-02 Thread Andrej Mitrovic
On 10/2/12, Manu turkey...@gmail.com wrote:
 Actually, this leaves a problem...
 Distinction between:
   Event x; // using defaults
 and
   Event!() x; // explicitly selecting none (which would fall back to the
 defaults)

 Is such a distinction possible? I presume not...


Well actually you can't use the first syntax at all with templates or
templated types. :/


Re: Setting defaults to variadic template args

2012-10-02 Thread Manu
On 2 October 2012 18:56, Andrej Mitrovic andrej.mitrov...@gmail.com wrote:

 On 10/2/12, Manu turkey...@gmail.com wrote:
  Actually, this leaves a problem...
  Distinction between:
Event x; // using defaults
  and
Event!() x; // explicitly selecting none (which would fall back to the
  defaults)
 
  Is such a distinction possible? I presume not...
 

 Well actually you can't use the first syntax at all with templates or
 templated types. :/


Errr, really? If the template has default args, surely you don't need to
specify any template args?
I'm sure I've done that before... :/


Re: core.simd woes

2012-10-02 Thread F i L

Manu wrote:
These are indeed common gotchas. But they don't necessarily 
apply to D, and
if they do, then they should be bugged and hopefully addressed. 
There is no
reason that D needs to follow these typical performance 
patterns from C.
It's worth noting that not all C compilers suffer from this 
problem. There
are many (most actually) compilers that can recognise a struct 
with a
single member and treat it as if it were an instance of that 
member

directly when being passed by value.
It only tends to be a problem on older games-console compilers.

As I said earlier. When I get back to finishing srd.simd off (I 
presume
this will be some time after Walter has finished Win64 
support), I'll go
through and scrutinise the code-gen for the API very 
thoroughly. We'll see
what that reveals. But I don't think there's any reason we 
should suffer
the same legacy C by-value code-gen problems in D... (hopefully 
I won't eat

those words ;)



Thanks for the insight (and the code examples, though I've been 
researching SIMD best-practice in C recently). It's good to know 
that D should (hopefully) be able to avoid these pitfalls.


On a side note, I'm not sure how easy LLVM is to build on Windows 
(I think I built it once a long time ago), but recent performance 
comparisons between DMD, LDC, and GDC show that LDC (with LLVM 
3.1 auto-vectorization and not using GCC -ffast-math) actually 
produces on-par-or-faster binary compared to GDC, at least in my 
code on Linux64. SIMD in LDC is currently broken, but you might 
consider using that if you're having trouble keeping a D release 
compiler up-to-date.


Re: IndexType for ranges

2012-10-02 Thread Peter Alexander

On Tuesday, 2 October 2012 at 13:17:45 UTC, monarch_dodra wrote:
If you've ever worked on a template that needs to index a 
range, you may have run into this problem: What is the type you 
should use to index an RA range?


Forgive my ignorance. What's wrong with size_t?



Re: A study on immutability usage

2012-10-02 Thread Peter Alexander

On Monday, 1 October 2012 at 12:28:33 UTC, bearophile wrote:
Our results from 14 Java applications indicates that 72-82% of 
fields are stationary


programmers are sometimes forced (or voluntarily choose) to 
initialise fields late (i.e. after the constructor has 
completed). This prevents such fields from being marked final 
even when they are designed to be immutable.


[snip]

The programmer intends that every Parent has a Child and 
vice-versa and, furthermore, that these do not change for the 
life of the program. He/she has marked the eld Parent.child as 
nal in an eort to enforce this. However, he/she is unable to 
mark the eld Child.parent as nal because one object must be 
constructed before the other.


I have noticed this myself.

While the cyclic reference thing does cause this every now and 
then, I actually find that the main cause (in large programs) is 
the unavailability of the constructor arguments.


For example, you want to construct system X, which needs system 
Y, but system Y hasn't been constructed or initialised yet. In a 
small program, you just pull the construction of Y before X. In a 
large program, construction of these things is all indirect, 
through factories, driven by data files, which in turn is driven 
by some other system. The easiest thing to do is just to make the 
system Y reference mutable, and set it later when you know 
they're both around.


I also find that a lot of it is simply because it's easier to not 
type 'final' or 'const' :-)  Immutability by default would 
certainly make things interesting.




Re: Setting defaults to variadic template args

2012-10-02 Thread Andrej Mitrovic
On 10/2/12, Manu turkey...@gmail.com wrote:
 Are you sure it's not fixed? I'm sure I do it all the time... :/
 Or I'm smoking some really good stuff.

I'd really like to see how you do it. If not, I'll have some of that
stuff you're having, thanks. :p


Re: LDC blacklisted in Ubuntu

2012-10-02 Thread David Nadlinger
On Tuesday, 2 October 2012 at 13:46:58 UTC, Joseph Rushton 
Wakeling wrote:
The executables produced are nice and fast -- maybe about 
10-15% slower than GDC for the number-crunching code I tested, 
[…]


Is any of the code public, in the sense that you could give e.g. 
me access for benchmarking purposes? We are currently using a 
presumably suboptimal optimization pass schedule, which for 
example doesn't include the auto vectorizer, but are going to 
switch to a new built-in pass manager soon (which uses the same 
pass schedule as Clang), and it would be very interesting to see 
its impact on performance-critical code.


David


Re: LDC blacklisted in Ubuntu

2012-10-02 Thread Joseph Rushton Wakeling

On 10/02/2012 06:14 PM, David Nadlinger wrote:

Is any of the code public, in the sense that you could give e.g. me access for
benchmarking purposes? We are currently using a presumably suboptimal
optimization pass schedule, which for example doesn't include the auto
vectorizer, but are going to switch to a new built-in pass manager soon (which
uses the same pass schedule as Clang), and it would be very interesting to see
its impact on performance-critical code.


Here you go. :-)
https://github.com/WebDrake/Dregs

It's surely not the best D code ever written (it possibly inherits too much from 
C++ in design terms), but hopefully it's still useful for your purposes.


Re: IndexType for ranges

2012-10-02 Thread Simen Kjaeraas

On 2012-10-02, 18:09, Peter Alexander wrote:


On Tuesday, 2 October 2012 at 13:17:45 UTC, monarch_dodra wrote:
If you've ever worked on a template that needs to index a range, you  
may have run into this problem: What is the type you should use to  
index an RA range?


Forgive my ignorance. What's wrong with size_t?


That not all ranges use it? If the range uses int, short, byte
(I wonder why they'd do it, though), using size_t will not even
compile.

--
Simen


Re: IndexType for ranges

2012-10-02 Thread monarch_dodra

On Tuesday, 2 October 2012 at 16:09:16 UTC, Peter Alexander wrote:

On Tuesday, 2 October 2012 at 13:17:45 UTC, monarch_dodra wrote:
If you've ever worked on a template that needs to index a 
range, you may have run into this problem: What is the type 
you should use to index an RA range?


Forgive my ignorance. What's wrong with size_t?


This is what happens when you use size_t:

//
import std.range;
import std.algorithm;

struct ZeroToTen
{
ushort first = 0;
ushort last = 10;
@property bool empty(){return first == last;}
@property ushort front(){return first;}
void popFront(){++first;}
@property ushort back(){return last;}
void popBack(){--last;}
@property ZeroToTen save(){return this;}
@property ushort length(){return cast(ushort)(last - first);}
ushort opIndex(ushort n){return cast(ushort)(first + n);}
}

void main()
{
ZeroToTen ztt;

static assert(hasLength!ZeroToTen);  //OK: normal
static assert(isRandomAccess!ZeroToTen); //Ok... But I don't 
like where this is going...


auto r = assumeSorted(ztt); //DERP!
}
//
\src\phobos\std\range.d(6909): Error: function 
main.ZeroToTen.opIndex (ushort n) is not callable using argument 
types (uint)
\src\phobos\std\range.d(6909): Error: cannot implicitly convert 
expression (i) of type uint to ushort
\src\phobos\std\range.d(7346): Error: template instance 
std.range.SortedRange!(ZeroToTen,a  b) error instantiating

//


Re: IndexType for ranges

2012-10-02 Thread Peter Alexander

On Tuesday, 2 October 2012 at 16:29:28 UTC, Simen Kjaeraas wrote:

On 2012-10-02, 18:09, Peter Alexander wrote:

On Tuesday, 2 October 2012 at 13:17:45 UTC, monarch_dodra 
wrote:
If you've ever worked on a template that needs to index a 
range, you may have run into this problem: What is the type 
you should use to index an RA range?


Forgive my ignorance. What's wrong with size_t?


That not all ranges use it? If the range uses int, short, byte
(I wonder why they'd do it, though), using size_t will not even
compile.


That's kind of my point. Unless there's a compelling reason not 
to, I'd suggest we standardise on size_t indexing (and length) 
and avoid this issue altogether.


C++ containers have a size_type typedef. No one uses it.

Let's keep things simple instead of complicating things for the 
sake of unwanted flexibility.


Re: IndexType for ranges

2012-10-02 Thread monarch_dodra

On Tuesday, 2 October 2012 at 16:44:48 UTC, monarch_dodra wrote:
On Tuesday, 2 October 2012 at 16:09:16 UTC, Peter Alexander 
wrote:
On Tuesday, 2 October 2012 at 13:17:45 UTC, monarch_dodra 
wrote:
If you've ever worked on a template that needs to index a 
range, you may have run into this problem: What is the type 
you should use to index an RA range?


Forgive my ignorance. What's wrong with size_t?


This is what happens when you use size_t:



http://dpaste.dzfl.pl/d95ccb14

On a side note, SortedRange is pretty bold at assuming the range 
is slice-able. Gonna fix that.


Re: IndexType for ranges

2012-10-02 Thread Peter Alexander

On Tuesday, 2 October 2012 at 16:44:48 UTC, monarch_dodra wrote:
On Tuesday, 2 October 2012 at 16:09:16 UTC, Peter Alexander 
wrote:
On Tuesday, 2 October 2012 at 13:17:45 UTC, monarch_dodra 
wrote:
If you've ever worked on a template that needs to index a 
range, you may have run into this problem: What is the type 
you should use to index an RA range?


Forgive my ignorance. What's wrong with size_t?


This is what happens when you use size_t:

[snip]


Then don't create ranges that use ushort for indexing and length. 
There's no need to.


To be clear, I'm suggesting that all random access ranges should 
use size_t, and they will not be random access ranges if they use 
anything else. Unless someone can give a compelling reason not to 
do this, I cannot see anything but benefits.




Re: IndexType for ranges

2012-10-02 Thread Piotr Szturmaj

monarch_dodra wrote:

On Tuesday, 2 October 2012 at 16:09:16 UTC, Peter Alexander wrote:

On Tuesday, 2 October 2012 at 13:17:45 UTC, monarch_dodra wrote:

If you've ever worked on a template that needs to index a range, you
may have run into this problem: What is the type you should use to
index an RA range?


Forgive my ignorance. What's wrong with size_t?


This is what happens when you use size_t:

//
import std.range;
import std.algorithm;

struct ZeroToTen
{
 ushort first = 0;
 ushort last = 10;
 @property bool empty(){return first == last;}
 @property ushort front(){return first;}
 void popFront(){++first;}
 @property ushort back(){return last;}
 void popBack(){--last;}
 @property ZeroToTen save(){return this;}
 @property ushort length(){return cast(ushort)(last - first);}
 ushort opIndex(ushort n){return cast(ushort)(first + n);}
}


Why not use size_t or ulong as parameter? This way all smaller types 
will be implicitly converted.


   ushort opIndex(size_t n){return cast(ushort)(first + n);}



Re: IndexType for ranges

2012-10-02 Thread Jonathan M Davis
On Tuesday, October 02, 2012 18:45:50 Peter Alexander wrote:
 On Tuesday, 2 October 2012 at 16:29:28 UTC, Simen Kjaeraas wrote:
  On 2012-10-02, 18:09, Peter Alexander wrote:
  On Tuesday, 2 October 2012 at 13:17:45 UTC, monarch_dodra
  
  wrote:
  If you've ever worked on a template that needs to index a
  range, you may have run into this problem: What is the type
  you should use to index an RA range?
  
  Forgive my ignorance. What's wrong with size_t?
  
  That not all ranges use it? If the range uses int, short, byte
  (I wonder why they'd do it, though), using size_t will not even
  compile.
 
 That's kind of my point. Unless there's a compelling reason not
 to, I'd suggest we standardise on size_t indexing (and length)
 and avoid this issue altogether.
 
 C++ containers have a size_type typedef. No one uses it.
 
 Let's keep things simple instead of complicating things for the
 sake of unwanted flexibility.

In general, all ranges _should_ use size_t for both length and indexing, but 
for a few range types in Phobos specifically use ulong (e.g. IIRC iota does in 
order to work properly with ranges or long and ulong on 32-bit systems). I see 
_zero_ reason to support lengths or indices smaller than size_t. Types that do 
that are badly designed IMHO. But we already have a precedent that you can't 
always assume size_t (at least for length - I'm not sure about indices - but 
if length can be specifically ulong and the type is random access, then its 
indices will need to be ulong), so unfortunately, the situation is not so 
simple that you can always assume size_t (even you should arguably be able 
to).

- Jonathan M Davis


Re: IndexType for ranges

2012-10-02 Thread monarch_dodra

On Tuesday, 2 October 2012 at 16:48:34 UTC, Peter Alexander wrote:
Then don't create ranges that use ushort for indexing and 
length. There's no need to.


To be clear, I'm suggesting that all random access ranges 
should use size_t, and they will not be random access ranges if 
they use anything else. Unless someone can give a compelling 
reason not to do this, I cannot see anything but benefits.


I don't know, forcing an implementer on size_t is pretty 
gratuitous. Why can't he be free to choose his own index type?


Besides, you'll still run into the problem for ranges that use 
ulong, such as iota.


Then what about ranges that use ulong? As those wrong too? What 
about iota? Wrong?


//
import std.range;
import std.algorithm;

void main()
{
auto r = assumeSorted(iota(0L, 1L)); //Still DERP!
}
//
src\phobos\std\range.d(6925): Error: cannot implicitly convert 
expression (this._input.length()) of type ulong to uint
src\phobos\std\range.d(7346): Error: template instance 
std.range.SortedRange!(Result,a  b) error instantiating

//

And this time, you can't blame me for doing fishy code, it's all 
in phobos.


The end problem is this.

//
struct S(R)
{
//...
auto opIndex(some_type n)
{
return r[r];
}
}
//
Regardless of what you do, you will encounter problems at the 
boundaries or S.opIndex. Either for calling it, because 
some_type is too small, either for implementing it, because 
some_type is too big.


The fact that both uint, ulong and size_t are valid indexers for 
range means ANYTHING in Phobos can break.


The trait I'm proposing should enable support for uint, ulong and 
size_t, and every other type as an added bonus.


Re: IndexType for ranges

2012-10-02 Thread Piotr Szturmaj

Jonathan M Davis wrote:

if length can be specifically ulong and the type is random access, then its
indices will need to be ulong), so unfortunately, the situation is not so
simple that you can always assume size_t (even you should arguably be able
to).


It seems that isRandomAccessRange doesn't check that opIndex parameter 
type and length() return type are the same. Do you think it should?




Re: IndexType for ranges

2012-10-02 Thread Jonathan M Davis
On Tuesday, October 02, 2012 15:17:58 monarch_dodra wrote:
 You might think just use typeof(length) BUT:
 *you aren't even guaranteed that typeof(length) will be
 correct! Certain ranges, such as iota, will return a length
 usually of type uint, but be indexed with ulong... :/
 *Infinite ranges don't have length...

I'd argue that that's a bug in iota. iota's length even specifically returns 
_IndexType_.

It makes no sense for length, opIndex, or opSlice to vary in type at all. They 
should all use the same type (ideally size_t). The fact that it's not outright 
required to be size_t is bad enough (though IIRC iota had some good reasons 
for using ulong).

 These are not big changes I'm proposing, but they *may* break
 some existing ranges. Those ranges are arguably retarded, and
 these changes would enforce correctness, but they'd break none
 the less. I'd like some feedback if you think this trait is worth
 pushing?

Requiring that length, opIndex, and opSlice all use the same index type would 
be very much the right way to go IMHO. If that's done however, I don't know if 
we'll really need IndexType (though it may still be a good idea to add it).

In addition, I'd argue that they should require that they all be at least as 
large as size_t (ideally, they'd even have to be either size_t or ulong and 
that's it - no signed types allowed), but that may be too strict at this point 
given that it could break existing code that did stupid stuff like use int 
(which _way_ too many people seem inclined to do).

- Jonathan M Davis


Re: IndexType for ranges

2012-10-02 Thread monarch_dodra
On Tuesday, 2 October 2012 at 16:59:38 UTC, Jonathan M Davis 
wrote:

On Tuesday, October 02, 2012 18:45:50 Peter Alexander wrote:
On Tuesday, 2 October 2012 at 16:29:28 UTC, Simen Kjaeraas 
wrote:

 On 2012-10-02, 18:09, Peter Alexander wrote:
 On Tuesday, 2 October 2012 at 13:17:45 UTC, monarch_dodra
 
 wrote:

 If you've ever worked on a template that needs to index a
 range, you may have run into this problem: What is the type
 you should use to index an RA range?
 
 Forgive my ignorance. What's wrong with size_t?
 
 That not all ranges use it? If the range uses int, short, 
 byte
 (I wonder why they'd do it, though), using size_t will not 
 even

 compile.

That's kind of my point. Unless there's a compelling reason not
to, I'd suggest we standardise on size_t indexing (and length)
and avoid this issue altogether.

C++ containers have a size_type typedef. No one uses it.

Let's keep things simple instead of complicating things for the
sake of unwanted flexibility.


In general, all ranges _should_ use size_t for both length and 
indexing, but
for a few range types in Phobos specifically use ulong (e.g. 
IIRC iota does in
order to work properly with ranges or long and ulong on 32-bit 
systems). I see
_zero_ reason to support lengths or indices smaller than 
size_t. Types that do
that are badly designed IMHO. But we already have a precedent 
that you can't
always assume size_t (at least for length - I'm not sure about 
indices - but
if length can be specifically ulong and the type is random 
access, then its
indices will need to be ulong), so unfortunately, the situation 
is not so
simple that you can always assume size_t (even you should 
arguably be able

to).

- Jonathan M Davis


Given your stance of I see _zero_ reason to support lengths or 
indices smaller than size_t and Types that do that are badly 
designed IMHO:


Are you agreeing with my proposed type tightening? If anything, 
it weeds out the bad designs for which you had no wish to 
support, while allowing better support for those that do.




Re: IndexType for ranges

2012-10-02 Thread Jonathan M Davis
On Tuesday, October 02, 2012 19:10:53 monarch_dodra wrote:
 Given your stance of I see _zero_ reason to support lengths or
 indices smaller than size_t and Types that do that are badly
 designed IMHO:
 
 Are you agreeing with my proposed type tightening? If anything,
 it weeds out the bad designs for which you had no wish to
 support, while allowing better support for those that do.

Ideally, only size_t would be allowed. Reality makes it so that we need ulong 
in some cases (e.g. iota). Given that fact, you'd ideally restrict it to 
size_t or ulong specfically (or at least IndexType.sizeof = size_t.sizeof). 
The problem is that I'm quite sure that there are plenty of programmers out 
there who have been using int for length and indices even though it's a 
horribly bad idea. It's a classic mistake. So, while requiring size_t or ulong 
would be great, I'd be very surprised if it didn't break a fair bit of code 
out there. Given that fact that and Andrei's increased resistance to potential 
code breakage, I don't know that we can make that change.

Still, I'd try to push for it though. It's bad enough that length and indices 
are allowed to be something other than size_t at all, but anything smaller 
than size_t (including using int specifically) _will_ cause problems for those 
who do that, if nothing else because size_t is ulong on 64-bit systems and 
using int will therefore mean that code using int for length will likely break 
when compiled on 64-bit systems (particularly when interacting with arrays). 
That's probably even a good argument for why we could restrict length and 
indices to size_t or greater even if it might break code (since it'll 
generally break when compiled on 64-bit systems anyway). This sort of change 
is going to have to get passed Andrei though, so we'll need his buy-in no 
matter what we do.

- Jonathan M Davis


Re: IndexType for ranges

2012-10-02 Thread Andrei Alexandrescu

On 10/2/12 12:45 PM, Peter Alexander wrote:

On Tuesday, 2 October 2012 at 16:29:28 UTC, Simen Kjaeraas wrote:

On 2012-10-02, 18:09, Peter Alexander wrote:


On Tuesday, 2 October 2012 at 13:17:45 UTC, monarch_dodra wrote:

If you've ever worked on a template that needs to index a range, you
may have run into this problem: What is the type you should use to
index an RA range?


Forgive my ignorance. What's wrong with size_t?


That not all ranges use it? If the range uses int, short, byte
(I wonder why they'd do it, though), using size_t will not even
compile.


That's kind of my point. Unless there's a compelling reason not to, I'd
suggest we standardise on size_t indexing (and length) and avoid this
issue altogether.


Yes. Unfortunately there are few, few cases in which size_t is 
insufficient (e.g. an input range from a file or a large iota, both on 
32-bit builds). I personally think these are too few to need formal support.



C++ containers have a size_type typedef. No one uses it.


Agreed.


Let's keep things simple instead of complicating things for the sake of
unwanted flexibility.


Yes. We should curb some corner cases of current range design in the 
direction of simplifying things.



Andrei


Re: IndexType for ranges

2012-10-02 Thread monarch_dodra
On Tuesday, 2 October 2012 at 17:13:48 UTC, Jonathan M Davis 
wrote:

On Tuesday, October 02, 2012 15:17:58 monarch_dodra wrote:

You might think just use typeof(length) BUT:
*you aren't even guaranteed that typeof(length) will be
correct! Certain ranges, such as iota, will return a length
usually of type uint, but be indexed with ulong... :/
*Infinite ranges don't have length...


I'd argue that that's a bug in iota. iota's length even 
specifically returns

_IndexType_.

It makes no sense for length, opIndex, or opSlice to vary in 
type at all. They
should all use the same type (ideally size_t). The fact that 
it's not outright
required to be size_t is bad enough (though IIRC iota had some 
good reasons

for using ulong).


To be honest, I think I may have put too much stress on the 
details. I agree we may want to enforce they have matching 
types (or at least, a smart hierarchy). That wasn't the root if 
the reason for IndexType.


The big picture issue here is writing wrapper ranges, such as 
AssumeSorted. Or take, or every other sweet-ass range 
adaptors we have in std.range. If take doesn't know how to 
index the sub-range, how can it properly work with ranges that 
always use ulong, AND at the same time, support that ranges that 
always use size_t (uint on x86)? Answer: It CAN'T.


CAN'T CAN'T CAN'T.

Keep in mind, infinite ranges don't have length, so that's out of 
the equation...



These are not big changes I'm proposing, but they *may* break
some existing ranges. Those ranges are arguably retarded, and
these changes would enforce correctness, but they'd break none
the less. I'd like some feedback if you think this trait is 
worth

pushing?


Requiring that length, opIndex, and opSlice all use the same 
index type would
be very much the right way to go IMHO. If that's done however, 
I don't know if
we'll really need IndexType (though it may still be a good idea 
to add it).


In addition, I'd argue that they should require that they all 
be at least as
large as size_t (ideally, they'd even have to be either size_t 
or ulong and
that's it - no signed types allowed), but that may be too 
strict at this point
given that it could break existing code that did stupid stuff 
like use int

(which _way_ too many people seem inclined to do).

- Jonathan M Davis


You'd still need IndexType for the reasons mentioned above, 
unless you wanted to write auto 
opIndex(ParameterTypeTuple(R.opIndex)[1] n) in all your ranges. 
AND, you'd require the array specialization (which would default 
to size_t).


The actual support of things smaller than size_t, at that point, 
would become a non-issue. Just:


//
static if (isRandomAccessRange!R)
auto opIndex(IndexType!R n)
{
return r[n];
}
//

Clean, concise. Supports both size_t and ulong (and others).


Re: IndexType for ranges

2012-10-02 Thread Andrei Alexandrescu

On 10/2/12 1:07 PM, monarch_dodra wrote:

I don't know, forcing an implementer on size_t is pretty gratuitous.
Why can't he be free to choose his own index type?


Too much freedom can be detrimental (as is in this case).

Andrei


Re: IndexType for ranges

2012-10-02 Thread Jonathan M Davis
On Tuesday, October 02, 2012 19:08:59 Piotr Szturmaj wrote:
 Jonathan M Davis wrote:
  if length can be specifically ulong and the type is random access, then
  its
  indices will need to be ulong), so unfortunately, the situation is not so
  simple that you can always assume size_t (even you should arguably be able
  to).
 
 It seems that isRandomAccessRange doesn't check that opIndex parameter
 type and length() return type are the same. Do you think it should?

Definitely. It makes no sense to be able to have a length greater than you can 
index (beyond the fact that the last index is length - 1), and it makes no 
sense to be able to index anything greater than length as far as the size of 
types go.

- Jonathan M Davis


Re: IndexType for ranges

2012-10-02 Thread monarch_dodra

On Tuesday, 2 October 2012 at 17:07:19 UTC, monarch_dodra wrote:

[SNIP]


You know what, I think I have a better. Idea. All of this came up 
because I've had iota break my compiles WAY more often then I'd 
have liked. But I think I know of another solution.


I think it would be nice if we enforced that all ranges used 
size_t. Everywhere. And it was enforced.


I'm sorry, I like extremes.


Re: IndexType for ranges

2012-10-02 Thread Jonathan M Davis
On Tuesday, October 02, 2012 19:37:18 monarch_dodra wrote:
 On Tuesday, 2 October 2012 at 17:07:19 UTC, monarch_dodra wrote:
  [SNIP]
 
 You know what, I think I have a better. Idea. All of this came up
 because I've had iota break my compiles WAY more often then I'd
 have liked. But I think I know of another solution.
 
 I think it would be nice if we enforced that all ranges used
 size_t. Everywhere. And it was enforced.
 
 I'm sorry, I like extremes.

Personally, I'd love that. The problem is that iota was specifically changed to 
use ulong to support handling long and ulong properly on 32-bit systems. 
Without it, you can't actually use long or ulong with a step of 1 beyond 
uint.max (at least, I _think_ that that was the issue). Requiring that the 
length and indices be size_t undermines that.

Now, I have no idea how much of a problem that realistically is. After all, 
you can't have an array of length  uint.max or 32-bit systems, so restricting 
iota to a length of uint.max isn't necessarily all than unreasonable IMHO. And 
per that argument, we _could_ change iota to use size_t again and just 
outright require that length and indices be size_t. 

- Jonathan M Davis


Re: Setting defaults to variadic template args

2012-10-02 Thread Jacob Carlborg

On 2012-10-02 18:10, Manu wrote:


Are you sure it's not fixed? I'm sure I do it all the time... :/
Or I'm smoking some really good stuff.


It's not needed for functions templates. But it is needed for type 
templates.


--
/Jacob Carlborg


Re: IndexType for ranges

2012-10-02 Thread David Nadlinger
On Tuesday, 2 October 2012 at 17:24:32 UTC, Andrei Alexandrescu 
wrote:
Yes. Unfortunately there are few, few cases in which size_t is 
insufficient (e.g. an input range from a file or a large iota, 
both on 32-bit builds). I personally think these are too few to 
need formal support.


I'd throw bit arrays into the mix, where 32 bit can also be quite 
small. There might also be some other clever hacks using custom 
index types for representing non-linear data structures as ranges.


The question is whether such ranges are likely to be used as 
random access ranges. I can't come up with a compelling use case 
right now, but I'd rather think twice before throwing support for 
them out of the window and later regretting it. Also, one of the 
simplest ranges (iota) not fitting the range concept has somewhat 
of an odd aftertaste.


David


Re: Idea: Introduce zero-terminated string specifier

2012-10-02 Thread Steven Schveighoffer
On Tue, 02 Oct 2012 04:09:43 -0400, Walter Bright  
newshou...@digitalmars.com wrote:



On 10/1/2012 7:22 PM, Steven Schveighoffer wrote:

Does it make sense for Phobos to provide such a shortcut in an obscure
header somewhere? Like std.cstring? Or should we just say roll your own
if you need it?


As a matter of principle, I really don't like gobs of Phobos functions  
that are literally one liners. Phobos should not become a mile wide but  
inch deep library of trivia. It should consist of non-trivial, useful,  
and relatively deep functions.


This, arguably, is one of the most important aspects of C to support.   
There are lots of C functions which provide C strings.  Yes, we don't want  
to promote using C strings, but to have one point of conversion so you  
*can* use safe strings is a good thing.  In other words, the sooner you  
convert your zero-terminated strings to char slices, the better off you  
are.  And if we label it system code, it can't be misused in @safe code.


Why support zero-terminated strings as literals if it wasn't important?   
You could argue that things like system calls which return zero-terminated  
strings are as safe to use as string literals which you know have zero  
terminated values.


The only other alternative is to wrap those C functions with D ones that  
convert to char[].  I don't find this any more appealing.


-Steve


Re: Idea: Introduce zero-terminated string specifier

2012-10-02 Thread David Nadlinger
On Tuesday, 2 October 2012 at 02:22:33 UTC, Steven Schveighoffer 
wrote:

@system char[] zstr(char *s) { return s[0..strlen(s)]; }

[…]

Does it make sense for Phobos to provide such a shortcut in an 
obscure header somewhere?  Like std.cstring?  Or should we just 
say roll your own if you need it?


I didn't look it up, so I could be making quite a fool of myself 
right now, but doesn't to!string(char*) provide exactly that?


David


openMP

2012-10-02 Thread Farmer

Hi,
I am tempted to start D programming but for me it is crucrial to 
be able to parallelize for-loops as can be done with openMP for 
C/C++ (mainly @pragma omp parallel for, @pragma omp critical).
I have already seen the std.parallelism library but I'm unsure 
whether it can provide me with the same functionality.


Thanks


Re: IndexType for ranges

2012-10-02 Thread Peter Alexander

On Tuesday, 2 October 2012 at 18:45:24 UTC, David Nadlinger wrote:
On Tuesday, 2 October 2012 at 17:24:32 UTC, Andrei Alexandrescu 
wrote:
Yes. Unfortunately there are few, few cases in which size_t is 
insufficient (e.g. an input range from a file or a large iota, 
both on 32-bit builds). I personally think these are too few 
to need formal support.


I'd throw bit arrays into the mix, where 32 bit can also be 
quite small. There might also be some other clever hacks using 
custom index types for representing non-linear data structures 
as ranges.


The question is whether such ranges are likely to be used as 
random access ranges. I can't come up with a compelling use 
case right now, but I'd rather think twice before throwing 
support for them out of the window and later regretting it. 
Also, one of the simplest ranges (iota) not fitting the range 
concept has somewhat of an odd aftertaste.


It's easy to think of random access ranges that could easily need 
more than size_t:


- The cartesian product of several smaller ranges
- a permutationsOf(r) range
- a subsetsOf(r) range

Any combinatoric range would easily use up 32-bit and 64-bit 
indexing. If 32-bit sometimes isn't enough, then neither is 
64-bit.


So, the question is, do we want to allow the use of BigInt 
indexing?




Re: Getting started with D - Phobos documentation sucks

2012-10-02 Thread JN

http://forum.dlang.org/thread/k4f4tp$8p4$1...@digitalmars.com#post-k4fdsc:24v9u:241:40digitalmars.com

vibe.d got clickable types in documentation, perhaps this could 
be somehow integrated into phobos docs?


Re: Setting defaults to variadic template args

2012-10-02 Thread Timon Gehr

On 10/02/2012 03:15 PM, Manu wrote:

   struct Event(T... = (int, float))
   {
 void F(T...); // - should default to F(int, float)
   }


template Event(){alias Event!(int,float) Event;}
struct Event(T...){
void F(T...);
}



Re: Idea: Introduce zero-terminated string specifier

2012-10-02 Thread Steven Schveighoffer
On Tue, 02 Oct 2012 15:17:42 -0400, David Nadlinger s...@klickverbot.at  
wrote:



On Tuesday, 2 October 2012 at 02:22:33 UTC, Steven Schveighoffer wrote:

@system char[] zstr(char *s) { return s[0..strlen(s)]; }

[…]

Does it make sense for Phobos to provide such a shortcut in an obscure  
header somewhere?  Like std.cstring?  Or should we just say roll your  
own if you need it?


I didn't look it up, so I could be making quite a fool of myself right  
now, but doesn't to!string(char*) provide exactly that?


string is immutable.  Must allocate.

You fool :)  just kidding, honest mistake.

-Steve


Re: Idea: Introduce zero-terminated string specifier

2012-10-02 Thread David Nadlinger
On Tuesday, 2 October 2012 at 19:31:33 UTC, Steven Schveighoffer 
wrote:
On Tue, 02 Oct 2012 15:17:42 -0400, David Nadlinger 
s...@klickverbot.at wrote:


On Tuesday, 2 October 2012 at 02:22:33 UTC, Steven 
Schveighoffer wrote:

@system char[] zstr(char *s) { return s[0..strlen(s)]; }

[…]

Does it make sense for Phobos to provide such a shortcut in 
an obscure header somewhere?  Like std.cstring?  Or should we 
just say roll your own if you need it?


I didn't look it up, so I could be making quite a fool of 
myself right now, but doesn't to!string(char*) provide exactly 
that?


string is immutable.  Must allocate.

You fool :)


Well, make it to!char(char*) then! ;)

David


Re: Idea: Introduce zero-terminated string specifier

2012-10-02 Thread David Nadlinger

On Tuesday, 2 October 2012 at 19:34:31 UTC, David Nadlinger wrote:

Well, make it to!char(char*) then! ;)


Oh dear, this doesn't get better: Of course, I've meant to write 
»to!(char[])(char*)«.


David



Re: openMP

2012-10-02 Thread Peter Alexander

On Tuesday, 2 October 2012 at 19:15:19 UTC, Farmer wrote:

Hi,
I am tempted to start D programming but for me it is crucrial 
to be able to parallelize for-loops as can be done with openMP 
for C/C++ (mainly @pragma omp parallel for, @pragma omp 
critical).
I have already seen the std.parallelism library but I'm unsure 
whether it can provide me with the same functionality.


Thanks


It can. Here's an example from the docs of parallelising a simple 
for loop:


auto logs = new double[10_000_000];
foreach(i, ref elem; taskPool.parallel(logs, 100))
{
elem = log(i + 1.0);
}

This creates a pool of workers that each perform 100 iterations 
of the loop body in parallel.


Re: IndexType for ranges

2012-10-02 Thread Jonathan M Davis
On Tuesday, October 02, 2012 20:45:36 David Nadlinger wrote:
 On Tuesday, 2 October 2012 at 17:24:32 UTC, Andrei Alexandrescu
 
 wrote:
  Yes. Unfortunately there are few, few cases in which size_t is
  insufficient (e.g. an input range from a file or a large iota,
  both on 32-bit builds). I personally think these are too few to
  need formal support.
 
 I'd throw bit arrays into the mix, where 32 bit can also be quite
 small. There might also be some other clever hacks using custom
 index types for representing non-linear data structures as ranges.
 
 The question is whether such ranges are likely to be used as
 random access ranges. I can't come up with a compelling use case
 right now, but I'd rather think twice before throwing support for
 them out of the window and later regretting it. Also, one of the
 simplest ranges (iota) not fitting the range concept has somewhat
 of an odd aftertaste.

If it were restricted to size_t, it would just mean that those types would be 
restricted to 32-bits for their length and index on 32-bit machines if you 
would want them to function as ranges (as iota would - if size_t is required, 
then it's going to use size_t, not become incompatible as a range).

But it's types like this which muddy things a bit. Ideally, we'd insist that 
all ranges use size_t. It simplifies things and certainly using smaller than 
that doesn't really make sense. But if we really need to support ulong, then 
unfortunately, we really need to support ulong - in which case presumably 
length and indices would have to be size_t or ulong (either that or 
IndexType.sizeof = size_t.sizeof, but allowing signed types also complicates 
things in nasty ways).

It _would_ be great to be able to just insist on size_t though. The
question is whether we can reasonably get away with that.

- Jonathan M Davis


Re: Idea: Introduce zero-terminated string specifier

2012-10-02 Thread Steven Schveighoffer
On Tue, 02 Oct 2012 15:35:47 -0400, David Nadlinger s...@klickverbot.at  
wrote:



On Tuesday, 2 October 2012 at 19:34:31 UTC, David Nadlinger wrote:

Well, make it to!char(char*) then! ;)


Oh dear, this doesn't get better: Of course, I've meant to write  
»to!(char[])(char*)«.


Right.  I agree, this should not allocate (I think someone said it does,  
but it's probably not necessary to).


But still, what looks better?

auto x = SomeSystemCallThatReturnsACString();

writefln(%s, to!(char[])(x));
writefln(%s, zstr(x));

I want something easy to type, and not too difficult to visually parse.

In fact, a better solution would be to define a C string type (other than  
char *), and just pretend those system calls return that.  Then support  
that C string type in writef.


-Steve


Re: core.simd woes

2012-10-02 Thread jerro

On Tuesday, 2 October 2012 at 13:36:37 UTC, Manu wrote:

On 2 October 2012 13:49, jerro a...@a.com wrote:



I don't think it is possible to think of all usages of this, 
but for every
simd instruction there are valid usages. At least for writing 
pfft, I found
shuffling two vectors very useful. For, example, I needed a 
function that
takes a small, square, power of two number of elements stored 
in vectors
and bit-reverses them - it rearanges them so that you can 
calculate the new
index of each element by reversing bits of the old index (for 
16 elements
using 4 element vectors this can actually be done using 
std.simd.transpose,
but for AVX it was more efficient to make this function work 
on 64
elements). There are other places in pfft where I need to 
select elements
from two vectors (for example, here 
https://github.com/jerro/pfft/**
blob/sine-transform/pfft/avx_**float.d#L141https://github.com/jerro/pfft/blob/sine-transform/pfft/avx_float.d#L141is 
the platform specific code for AVX).


I don't think this are the kind of things that should be 
implemented in
std.simd. If you wanted to implement all such operations (for 
example bit
reversing a small array) that somebody may find useful at some 
time,
std.simd would need to be huge, and most of it would never be 
used.



I was referring purely to your 2-vector swizzle idea (or useful 
high-level

ideas in general). Not to hyper-context-specific functions :P


My point was that those context specific functions can be 
implemented using a 2 vector swizzle. LLVM, for example, actually 
provides access to most vector shuffling instruction through 
shufflevector, which is basically a 2 vector swizzle.




Re: core.simd woes

2012-10-02 Thread Manu
On 2 October 2012 23:52, jerro a...@a.com wrote:

 On Tuesday, 2 October 2012 at 13:36:37 UTC, Manu wrote:

 On 2 October 2012 13:49, jerro a...@a.com wrote:


 I don't think it is possible to think of all usages of this, but for
 every
 simd instruction there are valid usages. At least for writing pfft, I
 found
 shuffling two vectors very useful. For, example, I needed a function that
 takes a small, square, power of two number of elements stored in vectors
 and bit-reverses them - it rearanges them so that you can calculate the
 new
 index of each element by reversing bits of the old index (for 16 elements
 using 4 element vectors this can actually be done using
 std.simd.transpose,
 but for AVX it was more efficient to make this function work on 64
 elements). There are other places in pfft where I need to select elements
 from two vectors (for example, here 
 https://github.com/jerro/pfft/https://github.com/jerro/pfft/**
 blob/sine-transform/pfft/avx_float.d#L141https://github.**
 com/jerro/pfft/blob/sine-**transform/pfft/avx_float.d#**L141https://github.com/jerro/pfft/blob/sine-transform/pfft/avx_float.d#L141is
 the platform specific code for AVX).


 I don't think this are the kind of things that should be implemented in
 std.simd. If you wanted to implement all such operations (for example bit
 reversing a small array) that somebody may find useful at some time,
 std.simd would need to be huge, and most of it would never be used.



 I was referring purely to your 2-vector swizzle idea (or useful high-level
 ideas in general). Not to hyper-context-specific functions :P


 My point was that those context specific functions can be implemented
 using a 2 vector swizzle. LLVM, for example, actually provides access to
 most vector shuffling instruction through shufflevector, which is
 basically a 2 vector swizzle.


Yeah, I understand. And it's a good suggestion. I'll add support for
2-vector swizzling next time I'm working on it.


  1   2   >