Re: Sociomantic

2014-03-20 Thread Mengu

On Tuesday, 18 March 2014 at 16:06:41 UTC, Sociomantic wrote:


http://translate.google.com/translate?sl=detl=enjs=nprev=_thl=enie=UTF-8u=http%3A%2F%2Fwww.welt.de%2Fwirtschaft%2Fwebwelt%2Farticle125913260%2FBriten-kaufen-Berliner-Start-up-fuer-200-Millionen.html


damn.

was gonna apply for a job in 3 years. :)


Re: Emacs users: flycheck-dmd-dub

2014-03-20 Thread Sönke Ludwig

Am 19.03.2014 00:16, schrieb Atila Neves:

V0.0.4 now supports both package.json and dub.json

Atila



There is one change that I would highly recommend - using the output of 
dub describe instead of directly reading dub.json:


 - It's planned to add an SDL based format, which otherwise then would
   also have to be supported

 - Properly determining the right dependency versions/paths,
   configurations and platform specific values is not easy, but vital
   to get the correct results

 - Parts of the format may get extended in the future, requiring
   constant maintenance of the elisp package

dub describe always outputs a JSON document* and has everything 
resolved down to bare compiler settings, so it's trivial to handle.


Regards,
Sönke


* There is currently a bug where sometimes a non-JSON preamble is output 
before the actual contents, so it's necessary to skip until the first 
'{' before interpreting the output. This will be resolved in the next 
version.





Re: 1st draft of complete class-based std.random successor

2014-03-20 Thread ponce
On Wednesday, 19 March 2014 at 23:49:41 UTC, Joseph Rushton 
Wakeling wrote:
   * std.random2.distribution, random distributions such as 
uniform,

 normal, etc.;


Related: please consider using parts of SimpleRNG the excellent 
work of John D. Cook which provides many random distributions in 
a compact and documented way.


https://github.com/p0nce/gfm/blob/master/math/gfm/math/simplerng.d 
(here a port)


Re: 1st draft of complete class-based std.random successor

2014-03-20 Thread monarch_dodra

On Thursday, 20 March 2014 at 01:32:41 UTC, Chris Williams wrote:
On Wednesday, 19 March 2014 at 23:49:41 UTC, Joseph Rushton 
Wakeling wrote:

Hello all,

As some of you may already know, monarch_dodra and I have 
spent quite a lot of time over the last year discussing the 
state of std.random.  To cut a long story short, there are 
significant problems that arise because the current RNGs are 
value types rather than reference types.


Any chance that you could describe them? I was about to resume 
porting the dcrypt library into Phobos, and had intended to 
flip the classes into structs, to match what the rest of the 
library was doing.


The issue isn't class vs struct, but rather value semantic vs 
reference semantic (classes are always ref, but structs can be 
either). Basically, if you make a copy, and modify the copy, will 
the original range be modified?


The problem with value semantics is that it always un-expected 
duplication of the range, which is a critical blocker problem as 
far as random goes.


The tell-tale usecase is:

//
auto g = rndGen();
g.take(10).writeln();
g.take(10).writeln();
//

This will write the same sequence... TWICE!


Re: 1st draft of complete class-based std.random successor

2014-03-20 Thread monarch_dodra

On Thursday, 20 March 2014 at 00:09:51 UTC, bearophile wrote:

Joseph Rushton Wakeling:
  * std.random2.adaptor, random adaptors such as 
randomShuffle,

randomSample, etc.


Please don't use stuttering names like 
std.random2.randomShuffle. std.random2.shuffle is enough.


Agreed.

`randomShuffle` can be made a deprecated alias: This way, 
random2 should still be mostly drop in replacement, but we 
won't drag along the bad names.


My own feeling is that ultimately it is a responsibility of 
the language to offer nice ways to allocate classes without 
necessarily relying on new or the GC.


I don't think the language is yet there. So I think currently 
this is not a good idea.


I think there is 0 doubt that reference semantics is the way to 
go. An advantage of using class is that it is still *possible* to 
place them on the stack with Scoped, or with some future language 
mechanic. On the other hand, if we implement as reference 
structs, then that's that.


Furthermore, even in terms of performance, I think a heap 
allocated PRNG will still flat-out beat the value based one, if 
only because of the size of the damn thing.


That said, being able to allocate them on the malloc heap, and 
not the GC heap, would be (IMO) also a valid design.


A simple and dumb design might be to still implement them with 
value semantic but:

1. Disable postblit.
2. Make .save() return a Random*
This would mean
1. No dangers of accidental copy.
2. Range* is a ForwardRange.
3. Trivially allows GC/malloc/stack allocation.
With good aliases (alias Random = RadomImpl*;), and a make! 
template we could make the default useage transparent to this 
mechanism yet make it easy to get our hands under the hood.


But at this point, we are really beating around the bush on this 
issue. There are two things for sure:

1. Reference semantics by default.
2. There comes a point where we have to move forward.

I didn't check the code yet, but a middle ground could be to 
make all constructors private, and disable T.init. Then, we force 
construction through a make! template.


This might not be what's most convenient, but it would allow us 
to potentially change the design at a later stage, without 
breaking user code.


Do you have a simple but very fast function that generates 
uniforms in [0.0, 1.0]? :-)


AFAIK, the allocation issue is only for ranges? uniform is just 
a function, I don't think it affected by the issue. Even if you 
are operating on a passed range, either ranges are reference 
semantics, and you take by value, or they are value semantic, and 
you take by ref. Either way, you have to pay for the indirection.


Re: Emacs users: flycheck-dmd-dub

2014-03-20 Thread Jonas Drewsen

On Thursday, 20 March 2014 at 07:17:04 UTC, Sönke Ludwig wrote:

Am 19.03.2014 00:16, schrieb Atila Neves:

V0.0.4 now supports both package.json and dub.json

Atila



There is one change that I would highly recommend - using the 
output of dub describe instead of directly reading dub.json:


 - It's planned to add an SDL based format, which otherwise 
then would

   also have to be supported


I currently have a tool that read and writes the dub.json files. 
What would you suggest for this tool since describe would only 
solve the reading part and not the writing. Furthermore adding 
SDL format as well doubles the effort for this. Is dub usable as 
a library so that this wouldn't be a problem?


/Jonas


Re: Emacs users: flycheck-dmd-dub

2014-03-20 Thread Atila Neves

Ah, ok. I'll wait for the bug to be fixed.

In the meanwhile, the package is now on MELPA and can be 
installed as any other emacs package.


Atila

On Thursday, 20 March 2014 at 07:17:04 UTC, Sönke Ludwig wrote:

Am 19.03.2014 00:16, schrieb Atila Neves:

V0.0.4 now supports both package.json and dub.json

Atila



There is one change that I would highly recommend - using the 
output of dub describe instead of directly reading dub.json:


 - It's planned to add an SDL based format, which otherwise 
then would

   also have to be supported

 - Properly determining the right dependency versions/paths,
   configurations and platform specific values is not easy, but 
vital

   to get the correct results

 - Parts of the format may get extended in the future, requiring
   constant maintenance of the elisp package

dub describe always outputs a JSON document* and has 
everything resolved down to bare compiler settings, so it's 
trivial to handle.


Regards,
Sönke


* There is currently a bug where sometimes a non-JSON preamble 
is output before the actual contents, so it's necessary to skip 
until the first '{' before interpreting the output. This will 
be resolved in the next version.




Re: D-Scanner 0.1.0-beta3 and DCD 0.3.0-beta4

2014-03-20 Thread Jussi Jumppanen
The latest Zeus IDE beta adds support for DCD document comment 
completion.


Zeus already has support for DCD goto definition, brace and dot 
completion.


For more details refer to this link:

http://www.zeusedit.com/zforum/viewtopic.php?p=10795

NOTE: Zeus is shareware, runs natively on the Windows and can run 
on Linux using Wine.


Jussi Jumppanen
Author: Zeus Editor


Re: 1st draft of complete class-based std.random successor

2014-03-20 Thread bearophile

monarch_dodra:

I think there is 0 doubt that reference semantics is the way to 
go.


I agree.


Furthermore, even in terms of performance, I think a heap 
allocated PRNG will still flat-out beat the value based one, if 
only because of the size of the damn thing.


OK.


Do you have a simple but very fast function that generates 
uniforms in [0.0, 1.0]? :-)


AFAIK, the allocation issue is only for ranges?


Here I was not talking about allocations:
https://d.puremagic.com/issues/show_bug.cgi?id=5240

Bye,
bearophile


Re: 1st draft of complete class-based std.random successor

2014-03-20 Thread Chris Williams

On Thursday, 20 March 2014 at 08:22:37 UTC, monarch_dodra wrote:
The issue isn't class vs struct, but rather value semantic vs 
reference semantic (classes are always ref, but structs can 
be either).


That's only completely true if structs are referred to by 
pointer. ref parameters/returns aren't quite sufficient to keep a 
struct acting as a reference for all purposes.


But good example. I'll have to consider that when I port the 
cryptographic prngs.


Re: 1st draft of complete class-based std.random successor

2014-03-20 Thread Andrea Fontana
On Wednesday, 19 March 2014 at 23:49:41 UTC, Joseph Rushton 
Wakeling wrote:

Hello all,

As some of you may already know, monarch_dodra and I have spent 
quite a lot of time over the last year discussing the state of 
std.random.  To cut a long story short, there are significant 
problems that arise because the current RNGs are value types 
rather than reference types.  We had quite a lot of back and 
forth on different design ideas, with a lot of helpful input 
from others in the community, but at the end of the day there 
are really only two broad approaches: create structs that 
implement reference semantics internally, or use classes.  So, 
as an exercise, I decided to create a class-based std.random.


The preliminary (but comprehensive) results of this are now 
available here:

https://github.com/WebDrake/std.random2

Besides re-implementing random number generators as classes 
rather than structs, the new code splits std.random2 into a 
package of several different modules:


   * std.random2.generator, pseudo-random number generators;

   * std.random2.device, non-deterministic random sources;

   * std.random2.distribution, random distributions such as 
uniform,

 normal, etc.;

   * std.random2.adaptor, random adaptors such as 
randomShuffle,

 randomSample, etc.

   * std.random2.traits, RNG-specific traits such as 
isUniformRNG

 and isSeedable.

A package.d file groups them together so one can still import 
all together via import std.random2.  I've also taken the 
liberty of following the new guideline to place import 
statements as locally as possible; it was striking how easy and 
clean this made things, and it should be easy to port that 
particular change back to std.random.


The new package implements all of the functions, templates and 
range objects from std.random except for the old 
std.random.uniformDistribution, whose name I have cannibalized 
for better purposes.  Some have been updated: the 
MersenneTwisterEngine has been tweaked to match the 
corresponding code from Boost.Random, and this in turn has 
allowed the definition of a 64-bit Mersenne Twister 
(Mt19937_64) and an alternative 32-bit one (Mt11213b).


There are also a number of entirely new entries.  
std.random2.distribution contains not just existing functions 
such as dice and uniform, but also range-based random 
distribution classes UniformDistribution, NormalDistribution 
and DiscreteDistribution; the last of these is effectively a 
range-based version of dice, and is based on Chris Cain's 
excellent work here: 
https://github.com/D-Programming-Language/phobos/pull/1702


The principal weak point in terms of functionality is 
std.random2.device, where the implemented random devices (based 
on Posix' /std/random and /std/urandom) are really very 
primitive and just there to illustrate the principle.  However, 
since their API is pretty simple (they're just input ranges 
with min and max defined) there should be plenty of opportunity 
to improve and extend the internals in future.  Advice and 
patches are welcome for everything, but particularly here :-)


What's become quite apparent in the course of writing this 
package is how much more natural it is for ranges implementing 
randomness to be class objects.  The basic fact that another 
range can store a copy of an RNG internally without creating a 
copy-by-value is merely the start: for example, in the case of 
the class implementation of RandomSample, we no longer need to 
have complications like,


@property auto ref front()
{
assert(!empty);
// The first sample point must be determined here to 
avoid
// having it always correspond to the first element of 
the
// input.  The rest of the sample points are determined 
each

// time we call popFront().
if (_skip == Skip.None)
{
initializeFront();
}
return _input.front;
}

that were necessary to avoid bugs like 
https://d.puremagic.com/issues/show_bug.cgi?id=7936; because 
the class-based implementation copies by reference, we can just 
initialize everything in the constructor.  Similarly, issues 
like https://d.puremagic.com/issues/show_bug.cgi?id=7067 and 
https://d.puremagic.com/issues/show_bug.cgi?id=8247 just vanish.


Obvious caveats about the approach include the fact that 
classes need to be new'd, and questions over whether allocation 
on the heap might create speed issues.  The benchmarks I've run 
(code available in the repo) seem to suggest that at least the 
latter is not a worry, but these are obviously things that need 
to be considered.  My own feeling is that ultimately it is a 
responsibility of the language to offer nice ways to allocate 
classes without necessarily relying on new or the GC.


A few remarks on design and other factors:

   * The new range objects have been implemented as final 
classes for
 speed purposes.  However, I tried another approach where 
the RNG

 class 

Re: Soon Nick will be $75 richer...

2014-03-20 Thread Brad Anderson
On Wednesday, 19 March 2014 at 05:40:22 UTC, Nick Sabalausky 
wrote:

On 3/18/2014 4:28 PM, Andrei Alexandrescu wrote:

... pending Martin's approval.

https://d.puremagic.com/issues/show_bug.cgi?id=3490

https://www.bountysource.com/issues/1327154-dmd-never-inlines-functions-that-could-throw



Heh, cool, thanks all :)

Speaking of, I learned a lot about DMD's inliner while doing 
that, so I've posted an explanation of it on the Wiki:


http://wiki.dlang.org/DMD_Source_Guide#Inliner

Since it's based mainly on what I sussed out from looking at 
the source, it could probably use a look-over by a DMD guru in 
case I've misunderstood anything.


Awesome write-up. Very informative.


Re: Soon Nick will be $75 richer...

2014-03-20 Thread John Colvin

On Thursday, 20 March 2014 at 19:12:29 UTC, Brad Anderson wrote:
On Wednesday, 19 March 2014 at 05:40:22 UTC, Nick Sabalausky 
wrote:

On 3/18/2014 4:28 PM, Andrei Alexandrescu wrote:

... pending Martin's approval.

https://d.puremagic.com/issues/show_bug.cgi?id=3490

https://www.bountysource.com/issues/1327154-dmd-never-inlines-functions-that-could-throw



Heh, cool, thanks all :)

Speaking of, I learned a lot about DMD's inliner while doing 
that, so I've posted an explanation of it on the Wiki:


http://wiki.dlang.org/DMD_Source_Guide#Inliner

Since it's based mainly on what I sussed out from looking at 
the source, it could probably use a look-over by a DMD guru in 
case I've misunderstood anything.


Awesome write-up. Very informative.


+1

Imagine if the whole of the compiler/runtime was documented this 
well...


Re: 1st draft of complete class-based std.random successor

2014-03-20 Thread monarch_dodra

On Thursday, 20 March 2014 at 19:04:01 UTC, Andrea Fontana wrote:
Still no cmwc rng... IMO cmwc should replace mt as default RNG. 
Faster. Longer period. More passed tests (if i'm right MT 
didn't pass testu01). And it is parametric to get faster result 
or longer period.


http://en.wikipedia.org/wiki/Multiply-with-carry#Complementary-multiply-with-carry_generators


Would a Lagged Fibonacci generator instead fit your needs? I 
wrote one, but it was held of until `random` was updated.


It's goal, first, is to replace the old module. It'll add new 
stuff once it has achieved that goal.


Re: Soon Nick will be $75 richer...

2014-03-20 Thread Andrej Mitrovic
On 3/19/14, Nick Sabalausky seewebsitetocontac...@semitwist.com wrote:
 Speaking of, I learned a lot about DMD's inliner while doing that, so
 I've posted an explanation of it on the Wiki:

 http://wiki.dlang.org/DMD_Source_Guide#Inliner

I was really impressed by the write-up. I never touched the inliner
before so these docs come in very handy. Thanks a bunch for this!


Re: 1st draft of complete class-based std.random successor

2014-03-20 Thread Joseph Rushton Wakeling

On Thursday, 20 March 2014 at 01:07:54 UTC, bearophile wrote:
In Bugzilla probably there are many bug reports/enhancement 
requests about std.random, so I suggest you to read them. Some 
of them can be useful, while other are probably already 
addressed in the current (or planned) std.random2.


Yes, indeed.  Quite a few of them _are_ addressed, I think, but 
now that I've got the essentials of the design laid out, I should 
be systematic and go through them.



Another random one that was just commented by Infiltrator:
https://d.puremagic.com/issues/show_bug.cgi?id=5901


Well, you already have the NormalDistribution in 
std.random2.distribution ;-)  I clearly can also implement 
function-only Box-Muller variant that spends 2 random variates to 
generate a single normally-distributed value, as this doesn't 
have the problem of needing to store state or allocate memory, so 
I will add that at some stage.


I'm reluctant to add a specific fastRandom because I think here 
the better option is a really nice range-based algorithm that can 
generate high quality variates at speed (e.g. the Ziggurat 
algorithm is a good candidate here).  There's a quite good review 
of different algorithms here:

http://www.cse.cuhk.edu.hk/~phwl/mt/public/archives/papers/grng_acmcs07.pdf

But of course I'm open to arguments here :-)


Re: 1st draft of complete class-based std.random successor

2014-03-20 Thread Joseph Rushton Wakeling

On Thursday, 20 March 2014 at 01:32:41 UTC, Chris Williams wrote:
Any chance that you could describe them? I was about to resume 
porting the dcrypt library into Phobos, and had intended to 
flip the classes into structs, to match what the rest of the 
library was doing.


I think there's a good case for a std.random2.crypto module that 
contains RNGs that are specifically suitable for cryptography.  
That said I think the bar here has to be set VERY high, which is 
why I didn't even begin working on it yet.  It has been argued by 
some that where crypto in Phobos is concerned, we shouldn't take 
community contributions but we should hire security experts to 
write the functionality for us.


Anyway, let's keep in touch about this and discuss how we could 
support one another's efforts.


About the issues with value-type RNGs (as monarch_dodra says, 
it's not structs vs. classes per se, as you can implement 
reference types via structs; it's just more finnicky to do so), 
probably the best starting point is to read through the various 
bugs that have been reported as a result of this:

https://d.puremagic.com/issues/show_bug.cgi?id=7067
https://d.puremagic.com/issues/show_bug.cgi?id=7936
https://d.puremagic.com/issues/show_bug.cgi?id=8247
https://d.puremagic.com/issues/show_bug.cgi?id=10322

Although some of these are marked as fixed, the fixes are pretty 
unpleasant and are workarounds rather than solutions of the 
underlying problem.  It may look like only a few issues, but the 
implications are nasty.  We had extensive discussions about this 
over the last year:

http://forum.dlang.org/thread/mailman.259.1357667544.22503.digitalmar...@puremagic.com
http://forum.dlang.org/thread/mailman.1017.1370879340.13711.digitalmar...@puremagic.com
http://forum.dlang.org/thread/mailman.1157.1371497540.13711.digitalmar...@puremagic.com
http://forum.dlang.org/thread/mailman.1209.1371565034.13711.digitalmar...@puremagic.com
http://forum.dlang.org/thread/mailman.443.1377369357.1719.digitalmar...@puremagic.com
http://forum.dlang.org/thread/5218fd04.8040...@webdrake.net

The bottom line is that implementing your RNGs as classes 
automatically gets you out of the worst of these traps by giving 
you reference semantics from the get-go.  Whether there are other 
problems that arise from this that make you prefer another design 
is a question you'll have to answer for yourself -- someone may 
yet come up with an objection that shows my current design is a 
Very Bad Idea ;-)


Anyway, the example with rndGen.take(10).writeln that 
monarch_dodra gave is probably the best argument one can make.  
Imagine a cryptographic application where you're generating 
(supposedly) two different sets of random data, and because of an 
unintended value-type copy like this they turn out to be 
identical.  Insecure much? :-)


Re: 1st draft of complete class-based std.random successor

2014-03-20 Thread Joseph Rushton Wakeling

On Thursday, 20 March 2014 at 08:30:09 UTC, ponce wrote:
Related: please consider using parts of SimpleRNG the excellent 
work of John D. Cook which provides many random distributions 
in a compact and documented way.


https://github.com/p0nce/gfm/blob/master/math/gfm/math/simplerng.d 
(here a port)


Good call, I'll take a close look at that.  Can you provide me 
with a link to the original project too?  (Yes, I can just Google 
it, I'm being lazy:-)


Re: 1st draft of complete class-based std.random successor

2014-03-20 Thread Chris Williams

On Thursday, 20 March 2014 at 21:16:27 UTC, Joseph Rushton
Wakeling wrote:
I think there's a good case for a std.random2.crypto module 
that contains RNGs that are specifically suitable for 
cryptography.  That said I think the bar here has to be set 
VERY high, which is why I didn't even begin working on it yet.  
It has been argued by some that where crypto in Phobos is 
concerned, we shouldn't take community contributions but we 
should hire security experts to write the functionality for us.


To be certain that the implementation doesn't have any security
holes?


Re: Emacs users: flycheck-dmd-dub

2014-03-20 Thread Sönke Ludwig

Am 20.03.2014 10:10, schrieb Jonas Drewsen:

On Thursday, 20 March 2014 at 07:17:04 UTC, Sönke Ludwig wrote:

Am 19.03.2014 00:16, schrieb Atila Neves:

V0.0.4 now supports both package.json and dub.json

Atila



There is one change that I would highly recommend - using the output
of dub describe instead of directly reading dub.json:

 - It's planned to add an SDL based format, which otherwise then would
   also have to be supported


I currently have a tool that read and writes the dub.json files. What
would you suggest for this tool since describe would only solve the
reading part and not the writing. Furthermore adding SDL format as well
doubles the effort for this. Is dub usable as a library so that this
wouldn't be a problem?

/Jonas


Yes, it has been built to be usable as a library, although there are 
certain parts of the API that are not yet considered full quality. But 
package file reading and writing using the Package class works fine 
and is already used by some other projects, such as the package registry.


Having said that, there are of course cases where processing the JSON 
file directly isn't really problematic. It just may not be the best idea 
to rebuild the dependency and platform logic as long as the package 
format isn't fully stable.


Re: 1st draft of complete class-based std.random successor

2014-03-20 Thread Joseph Rushton Wakeling

On Thursday, 20 March 2014 at 08:51:08 UTC, monarch_dodra wrote:

Agreed.


There is consensus it seems.  I will make the fix ;-)

I think there is 0 doubt that reference semantics is the way to 
go. An advantage of using class is that it is still *possible* 
to place them on the stack with Scoped, or with some future 
language mechanic. On the other hand, if we implement as 
reference structs, then that's that.


I suppose the one concern I have is whether these reference-type 
RNGs might generate unpleasant unintended effects with other 
range objects in Phobos.  One thing that I really must do now 
that the basic design is in place is to systematically go through 
all the different ways in which these ranges could interact with 
deterministic ranges, and whether there are any issues to address.


Furthermore, even in terms of performance, I think a heap 
allocated PRNG will still flat-out beat the value based one, if 
only because of the size of the damn thing.


I don't know if you or anyone else has run the simple benchmark 
programs I created, but my impression was that for the RNGs and 
other functions here there is no significant speed difference 
between the std.random2 class implementations and their 
std.random struct predecessors.  Where there _is_ a difference it 
seems more likely to be down to algorithm rather than 
class/struct or heap/stack.


For example, my new Mersenne Twister is slightly slower, but 
probably because it's carrying extra parameters compared to that 
of std.random.  On the other hand, generating random numbers by 
foreach'ing over uniform() calls does not seem to have any speed 
difference with popFrontN()'ing over a Uniform Distribution.


That said, being able to allocate them on the malloc heap, and 
not the GC heap, would be (IMO) also a valid design.


A simple and dumb design might be to still implement them with 
value semantic but:

1. Disable postblit.
2. Make .save() return a Random*
This would mean
1. No dangers of accidental copy.
2. Range* is a ForwardRange.
3. Trivially allows GC/malloc/stack allocation.
With good aliases (alias Random = RadomImpl*;), and a make! 
template we could make the default useage transparent to this 
mechanism yet make it easy to get our hands under the hood.


One strict objection here: .save returning a Random* would mean 
that this kind of unittest will fail, no?


auto rng1 = someRandomGenType;
auto rng2 = rng1.save;
rng1.popFrontN(10);
rng2.popFrontN(10);
assert(rng1.front == rng2.front);

More generally, I think that, while I don't object to doing 
complicated stuff behind the scenes to get things simple and easy 
for the user, the problem I have with the above is that it really 
seems to require so much effort to create something which comes 
naturally with the current std.random2 design.


I didn't check the code yet, but a middle ground could be to 
make all constructors private, and disable T.init. Then, we 
force construction through a make! template.


This might not be what's most convenient, but it would allow us 
to potentially change the design at a later stage, without 
breaking user code.


The idea of making constructors private and forcing the user to 
use the convenience functions is a very interesting one.  As long 
as they provide an adequate interface to completely control all 
implementation parameters, it could provide a way to have 
significant leeway in controlling exactly how RNG instances are 
initialized.


On the other hand it really feels obnoxious to cut users off from 
being able to use objects directly :-(


Do you have a simple but very fast function that generates 
uniforms in [0.0, 1.0]? :-)


AFAIK, the allocation issue is only for ranges? uniform is 
just a function, I don't think it affected by the issue. Even 
if you are operating on a passed range, either ranges are 
reference semantics, and you take by value, or they are value 
semantic, and you take by ref. Either way, you have to pay for 
the indirection.


I think the issue here is just that it's possible to implement a 
really fast high-quality algorithm for uniformly-distributed 
floating point numbers in [0, 1).  That has all sorts of uses not 
just for Phobos users but also internally in e.g. random 
distributions (for example, it'll give a significant speed boost 
to NormalDistribution).


Re: 1st draft of complete class-based std.random successor

2014-03-20 Thread Joseph Rushton Wakeling

On Thursday, 20 March 2014 at 21:42:13 UTC, Chris Williams wrote:

To be certain that the implementation doesn't have any security
holes?


Yes.  Of course, in the current climate one might fear that
they'd be the ones introducing them ... :-)


Re: 1st draft of complete class-based std.random successor

2014-03-20 Thread Joseph Rushton Wakeling

On Thursday, 20 March 2014 at 18:43:49 UTC, Chris Williams wrote:
That's only completely true if structs are referred to by 
pointer. ref parameters/returns aren't quite sufficient to keep 
a struct acting as a reference for all purposes.


As far as I can tell, you're thinking of _passing_ struct 
parameters, and here, indeed, passing by ref is sufficient.


The problem comes when you want to _store_ them.  It's not safe 
to just store a pointer, because the (value type) struct that's 
being pointed to might go out of scope and be deleted.


However, you can make structs behave like reference types behave 
like reference types, simply by making them contain (safe) 
references to the actual data they contain.  E.g. (stupidly 
simple example):


struct Foo
{
  private:
int *_a;

  public:
this(int val)
{
_a = new int;
*_a = val;
}

ref int a() @property
{
return *_a;
}
}

unittest
{
auto foo1 = Foo(23);
auto foo2 = foo1;

foo2.a = 4;

writeln(foo1.a);
}

Most of the discussion over RNGs in the last year is about 
whether we need to take a (more sophisticated) variant of this 
kind of approach to implement reference-type semantics for RNGs, 
or whether we should do something different.  std.random2 is ... 
something different ;-)


Re: Soon Nick will be $75 richer...

2014-03-20 Thread Nick Sabalausky

On 3/20/2014 3:27 PM, John Colvin wrote:

On Thursday, 20 March 2014 at 19:12:29 UTC, Brad Anderson wrote:

On Wednesday, 19 March 2014 at 05:40:22 UTC, Nick Sabalausky wrote:


Speaking of, I learned a lot about DMD's inliner while doing that, so
I've posted an explanation of it on the Wiki:

http://wiki.dlang.org/DMD_Source_Guide#Inliner

Since it's based mainly on what I sussed out from looking at the
source, it could probably use a look-over by a DMD guru in case I've
misunderstood anything.


Awesome write-up. Very informative.


+1

Imagine if the whole of the compiler/runtime was documented this well...


Glad to hear it's well-received!

I highly encourage anyone who's first diving into an unfamiliar section 
of DMD or druntime to post what they've learned to the Wiki:


I think that's a prime time to do so, when the new knowledge is still 
fresh in your mind. It really helps you digest all of it and identify 
any unexpected gaps in your own knowledge. Plus, others can help correct 
any misunderstandings, and any aspects of the code that turn out to be 
difficult for newcomers to grasp can be better identified.




Re: Ruby-style each in D?

2014-03-20 Thread monarch_dodra

On Wednesday, 19 March 2014 at 23:00:08 UTC, Walter Bright wrote:
I don't have a solid enough experience with this style of 
programming, but one opportunity of 'each' could be that it 
could be specialized and achieve greater speed for some 
arguments.


Speaking of which, it would be nice to have a compiler default 
iteration scheme that is optimal for any range.


The current status is:
for ( ; !r.empty ; r.popFront ) is sub-optimal for string 
types, and sometimes arrays.


alias E = ElementEncodingType!Range;

foreach(E e; range); will create copies of elements

foreach(ref E e; range); will always work, but is arguably 
wrong for RValue ranges


foreach(auto ref E e; range); is not legal, but there is an ER 
requesting it, and I think it would make perfect sense to have 
this.


Finally: The hand written library code
while ( decode(s, i)  s.length )
{ ... }

Is faster for strings, than the compiler's/druntime's foreach(E 
e; range);.


It would be awesome if:
foreach(auto ref E e; range);
Worked, *and* was always optimal.

The current scheme makes those who care jump through hoops, such 
as in `find`'s implementation.


Re: inlining...

2014-03-20 Thread Ola Fosheim Grøstad
I just want to add these reasons for having inlining despite 
having compiler heuristics:


1. If you compile for embedded or PNACL on the web, you want a 
small executable. That means the heuristics should not inline if 
it increase the code size unless the programmer specified it in 
the code. (Or that you specify a target size, and do compiler 
re-runs until it fits.)


2. If you use profile guided opimization you should inline based 
on call frequency, but the input set might have missed some 
scenarios and you should be able to overrule the profile by 
explicit inlining in code where you know that it matters. (e.g. 
tight loop in an exception handler)


Re: Good name for f.byLine.map!(x = x.idup)?

2014-03-20 Thread monarch_dodra
On Thursday, 20 March 2014 at 01:38:38 UTC, Andrei Alexandrescu 
wrote:

On 3/19/14, 4:53 PM, Meta wrote:
On Wednesday, 19 March 2014 at 22:30:55 UTC, Peter Alexander 
wrote:
On Sunday, 16 March 2014 at 16:58:36 UTC, Andrei Alexandrescu 
wrote:
A classic idiom for reading lines and keeping them is 
f.byLine.map!(x

= x.idup) to get strings instead of the buffer etc.


f.readLines


What about a simpler f.iter() or f.lineIter()?


Ideally it would be a variation of byLine. -- Andrei


What about simply templatizing (*) it?

byLine() = implicit char[]
byLine!string() = dupes

This has the double advantage that:
* Does not introduce a new symbol
* Can be customized for wchar/dchar

In particular, the wchar thing could be of interest to those that 
are reading a file they now is UTF16/UCS2.


(*) Technically, it's already a template, but the parameters are 
inferred. We could make it so that we can use explicitly defined 
parameters. In particular, so that the output type is specified 
before the terminator type. AFAIK, the transition can be made 
seemlessly with no breakage.


Re: inlining...

2014-03-20 Thread Ola Fosheim Grøstad

On Thursday, 20 March 2014 at 02:08:16 UTC, Manu wrote:
The problem is upside down. If you want to inline multiple 
levels, you
start from the leaves and move downwards, not from the root 
moving upwards


Yes, that is true in cases where leaves are frequently visited. 
Good point. I am most interested in full inlining, but the 
heuristics should probably start with the leaves for people not 
interested in that. Agree.


Anyway, in the case of ray tracing (or any search structure) I 
could see the value of having the opposite in combination with 
CTFE/partial evaluation.


Example: Define a static scene (of objects) and let the compiler 
turn it into a state machine of code.


Another example: Define an array of data, use partial evaluation 
to turn it into a binary tree, then turn the binary tree into 
code.


Inlining should be strictly deliberate, there's nothing to say 
that every
function called in a tree should be inlined. There's a high 
probability

there's one/some that shouldn't be among a few that should.


In the case of a long running loop it does not really matter. 
What it does get you is a chance to use generic code (or 
libraries) and then do a first-resort optimization. I basically 
see it as a time-saving feature (programmers time). A tool for 
cutting development costs.


Remember too, that call-site inlining isn't the only method, 
there would

also be always-inline...


Yes, that is the first. I have in another thread some time ago 
suggested a solution that use weighted inlining to aid compiler 
heuristics:


http://forum.dlang.org/thread/szjkyfpnachnnyknn...@forum.dlang.org#post-szjkyfpnachnnyknnfwp:40forum.dlang.org

As you can see I also suggested call-site inlining, so I am fully 
behind you in this. :-) Lack of inlining and GC are my main 
objections to D.



I think always-inline is what you want for some
decidedly trivial functions (although these will probably be 
heuristically

inlined anyway), not call-site inlining.


I agree. Compiler heuristics can change. It is desirable to be 
able to express intent no matter what the current heuristics are.



I just don't see how recursive
call-site inlining is appropriate, considering that call trees 
are often
complex, subject to change, and may even call functions that 
you don't have

source for.


You should not use it blindly.

You can cascade the mixin keyword if you want to, that's very 
simple.


Not if you build the innerloop using generic components. I want 
this


inline_everything while(conditon){
statement;
statement;
}

I'd be highly surprised if you ever encountered a call tree 
where
you wanted to inline everything (and the optimiser didn't do it 
for you).


Not if you move to high-level programming using prewritten code 
and only go low level after profiling.


As soon as you encounter a single function in the tree that 
shouldn't be
inlined, then you'll be forced to do it one level at a time 
anyway.


But then you have to change the libraries you are using!?

Nothing prevents you to introduce exceptions as an extension 
though. I want inline(0.5) as default, but also be able to write 
inline(1) for inline always and inline(0) for inline never.


func1(){} // implies inline(0.5) weighting
inline func2(){} // same as inline(1) weighting, inline always
inline(0.75) fun31(){} // increase the heuristics weighting
inline(0) func4(){} // never-ever inline

Ola.


[Proposal] Add module for C-strings support in Phobos

2014-03-20 Thread Denis Shelomovskij

It's filed as enhancement 12418 [2]:

C-strings processing is a special and common case so:
1. C-strings should be supported with both performance and usability.
2. There should be a dedicated module for C-strings (instead of adding 
such functions here and there in other modules).


Current state: there is no good support for C-strings in Phobos, there 
is slow and broken `toStringz` (Issue 12417 [3]), and no standard way to 
make many common operations, like converting returned C-string to string 
and releasing its memory or creating a C-string from string using an 
allocation function.


So I propose to add `unstd.c.string` [1] module to Phobos which include 
all use-cases I have seen implementing (correct and fast in contrast to 
existing ones like GtkD (yes, it's both incorrect and slow because of 
tons of GC allocations)) C library wrappers.



[1] http://denis-sh.bitbucket.org/unstandard/unstd.c.string.html
[2] https://d.puremagic.com/issues/show_bug.cgi?id=12418
[3] https://d.puremagic.com/issues/show_bug.cgi?id=12417

--
Денис В. Шеломовский
Denis V. Shelomovskij


Re: [Proposal] Add module for C-strings support in Phobos

2014-03-20 Thread Rikki Cattermole
On Thursday, 20 March 2014 at 08:24:30 UTC, Denis Shelomovskij 
wrote:

It's filed as enhancement 12418 [2]:

C-strings processing is a special and common case so:
1. C-strings should be supported with both performance and 
usability.
2. There should be a dedicated module for C-strings (instead of 
adding such functions here and there in other modules).


Current state: there is no good support for C-strings in 
Phobos, there is slow and broken `toStringz` (Issue 12417 [3]), 
and no standard way to make many common operations, like 
converting returned C-string to string and releasing its memory 
or creating a C-string from string using an allocation function.


So I propose to add `unstd.c.string` [1] module to Phobos which 
include all use-cases I have seen implementing (correct and 
fast in contrast to existing ones like GtkD (yes, it's both 
incorrect and slow because of tons of GC allocations)) C 
library wrappers.



[1] http://denis-sh.bitbucket.org/unstandard/unstd.c.string.html
[2] https://d.puremagic.com/issues/show_bug.cgi?id=12418
[3] https://d.puremagic.com/issues/show_bug.cgi?id=12417


Looks like it wouldn't be really useful with Windows API. Given 
that wstrings are more common there.


Another thing that would be nice to have is a wrapper struct for 
the pointer that allows accessing via e.g. opIndex and opSlice. 
Ext.
Use case: Store the struct on D side to make sure GC doesn't 
clean it up and still be able to access and modify it like a 
normal string easily.


Re: [Proposal] Add module for C-strings support in Phobos

2014-03-20 Thread Denis Shelomovskij

20.03.2014 13:20, Rikki Cattermole пишет:

On Thursday, 20 March 2014 at 08:24:30 UTC, Denis Shelomovskij wrote:

It's filed as enhancement 12418 [2]:

C-strings processing is a special and common case so:
1. C-strings should be supported with both performance and usability.
2. There should be a dedicated module for C-strings (instead of adding
such functions here and there in other modules).

Current state: there is no good support for C-strings in Phobos, there
is slow and broken `toStringz` (Issue 12417 [3]), and no standard way
to make many common operations, like converting returned C-string to
string and releasing its memory or creating a C-string from string
using an allocation function.

So I propose to add `unstd.c.string` [1] module to Phobos which
include all use-cases I have seen implementing (correct and fast in
contrast to existing ones like GtkD (yes, it's both incorrect and slow
because of tons of GC allocations)) C library wrappers.


[1] http://denis-sh.bitbucket.org/unstandard/unstd.c.string.html
[2] https://d.puremagic.com/issues/show_bug.cgi?id=12418
[3] https://d.puremagic.com/issues/show_bug.cgi?id=12417


Looks like it wouldn't be really useful with Windows API. Given that
wstrings are more common there.


You misunderstand the terminology. C string is a zero-terminated string. 
Also looks like you didn't even go to docs page as the second example is 
WinAPI one.



Another thing that would be nice to have is a wrapper struct for the
pointer that allows accessing via e.g. opIndex and opSlice. Ext.
Use case: Store the struct on D side to make sure GC doesn't clean it up
and still be able to access and modify it like a normal string easily.


I don't understand the use-case. If you did implemented some C library 
wrappers and have a personal experience, I'd like to hear your opinion 
on C functions calling problem and your proposal to solve it, if you 
dislike mine. Also with examples, please, where my solution fails and 
your one rocks. )



--
Денис В. Шеломовский
Denis V. Shelomovskij


Re: Finally full multidimensional arrays support in D

2014-03-20 Thread Denis Shelomovskij

18.03.2014 1:35, Christof Schardt пишет:

I looked to the doku-page and expected to see, how some basic
matrix-operations could be performed.
Like e.g. (basic syntax) this:

  Dim  a(10,12)
  a(3,4) = 7
  a(i,j) = a(j,i) * 12

Instead I found exotic assignments and calculations.
Did I expect the wrong thing?


Sorry for that. Do you mead there is a lack of simple indexing examples 
or lack of some matrix functionality? The latter case is if you meant 
transpose and multiply by 12 with `a(i,j) = a(j,i) * 12`.


--
Денис В. Шеломовский
Denis V. Shelomovskij


Re: Appropriateness of posts

2014-03-20 Thread Chris

On Wednesday, 19 March 2014 at 23:18:55 UTC, H. S. Teoh wrote:


Sometimes, the only way to win is to not play.


T


+1. You should add this to your list of quotes.


Re: [Proposal] Add module for C-strings support in Phobos

2014-03-20 Thread Rikki Cattermole
On Thursday, 20 March 2014 at 09:32:33 UTC, Denis Shelomovskij 
wrote:

20.03.2014 13:20, Rikki Cattermole пишет:
On Thursday, 20 March 2014 at 08:24:30 UTC, Denis Shelomovskij 
wrote:

It's filed as enhancement 12418 [2]:

C-strings processing is a special and common case so:
1. C-strings should be supported with both performance and 
usability.
2. There should be a dedicated module for C-strings (instead 
of adding

such functions here and there in other modules).

Current state: there is no good support for C-strings in 
Phobos, there
is slow and broken `toStringz` (Issue 12417 [3]), and no 
standard way
to make many common operations, like converting returned 
C-string to
string and releasing its memory or creating a C-string from 
string

using an allocation function.

So I propose to add `unstd.c.string` [1] module to Phobos 
which
include all use-cases I have seen implementing (correct and 
fast in
contrast to existing ones like GtkD (yes, it's both incorrect 
and slow

because of tons of GC allocations)) C library wrappers.


[1] 
http://denis-sh.bitbucket.org/unstandard/unstd.c.string.html

[2] https://d.puremagic.com/issues/show_bug.cgi?id=12418
[3] https://d.puremagic.com/issues/show_bug.cgi?id=12417


Looks like it wouldn't be really useful with Windows API. 
Given that

wstrings are more common there.


You misunderstand the terminology. C string is a 
zero-terminated string. Also looks like you didn't even go to 
docs page as the second example is WinAPI one.
I understand how c strings work. It would be nice to have more 
unittests for dstring/wstring, because it looks more geared 
towards char/string. Which is why it looks on the offset that it 
is less going to work.


Another thing that would be nice to have is a wrapper struct 
for the
pointer that allows accessing via e.g. opIndex and opSlice. 
Ext.
Use case: Store the struct on D side to make sure GC doesn't 
clean it up
and still be able to access and modify it like a normal string 
easily.


I don't understand the use-case. If you did implemented some C 
library wrappers and have a personal experience, I'd like to 
hear your opinion on C functions calling problem and your 
proposal to solve it, if you dislike mine. Also with examples, 
please, where my solution fails and your one rocks. )


I don't dislike your approach at all. I just feel that it needs 
to allow for a little more use cases. Given the proposal is for 
phobos.


What you have done looks fine for most cases to c libraries. I'm 
just worried that it has less use cases then it could have.

I'm just nitpicking so don't mind me too much :)


Re: Appropriateness of posts

2014-03-20 Thread Ola Fosheim Grøstad
On Wednesday, 19 March 2014 at 07:51:06 UTC, Nick Sabalausky 
wrote:
I find that interesting. This is the first I've ever heard of 
caucasian being even potentially offensive.


Well, I am not offended by the term, I dislike it. I am offended 
by having to provide racial information. I am not sure what other 
norwegians feel about that, though. After 2WW where we lost over 
1/3 of our jewish population (which was small already, jews were 
barred from entry until 1851) laws were established that banned 
registration of race, sexuality etc (unless where it has a very 
clear function of necessity). So my main objection is to having 
race and sexuality registered.


But there is a bias in terms like nordic to race, even though 
it formally isn't a racial expression. And when we talk about 
north Europe, east Europe, southern Europe we refer to culture, 
but there is also a bias towards genetic traits if the context is 
about what people look like. Like, americans is more likely to 
evoke stereotypical images of middle class white americans than 
multi cultural america or the native americans.


I think talking about white norwegians, or white swedes is 
somewhat weird and makes me a bit uneasy, either because it is 
too close or because the labels norwegian and swede already 
have a white bias, so making it explicit makes it overly racial? 
But talking about white americans, the whites in Africa etc 
is no problem at all and is politically correct. Perhaps because 
the usual context for those expressions is to talk about unfair 
treatment of minorities and lack of distribution of wealth.


So that uncertainty leads americans to use caucasion 
(apparently derived from the extremely academic term 
caucasoid, or so I've been told) just out of paranoia, since 
it's seen as far too pedantic and technical to possibly be 
offensive.


And this technical focus is what I object to since the nazis did 
take a rather scientific approach to this by measuring skulls 
etc to identify pure genes.


Besides, how many third generation non-white american in the US 
have an actual ethnicity that makes sense? Like 1/4 african, 1/8 
german, etc…


But that said, I still find both examples as completely 
insufficient justification for bans on nudity. Fact of the 
matter is, I like to use both as shining examples of Just 
because you don't want to see something doesn't mean it should 
be banned.


:-) Well, we are all coloured by the taboos that we were taught 
as kids. Getting over those is a challenge. I would personally 
not be offended by any cussing in a foreign language, I think. 
Though there probably are some vulgar cussing in norwegian that 
I'd rather not be affiliated with.


part of the country.) I've heard of a court case (IANAL, of 
course) in San Fransisco where non-disruptive, non-sexualized 
public nudity was ruled legal. And it's either there or maybe 
Portland that has an annual non-clothed bicycling event. And 
I've heard that some court case in New York City ruled 
non-disruptive toplessness legal. Something similar in Canada 
too, IIRC. It's still nothing like certain other parts of the 
world, but still, baby steps.


In the 80s the feminist movement made a big point of top less sun 
bathing, so you would find it everywhere (also in parks 
sometimes). But then it became less common outside beaches. Not 
sure why, probably partially because of breast cancer news 
reports and a lack of interest after the point had been made? I 
think it is difficult to uphold in cold region where you have to 
wear lots of cloths most of the year. I think it sends signals of 
being self-indulgent if you do it in your face in a park these 
days, but if you find your own spot then it is no problem.


Of course, the population density of my country is low and the 
water front is accessible to the public even on private land (by 
law), so if you want to be nude you can always find your own spot 
somewhere.


Re: [Proposal] Add module for C-strings support in Phobos

2014-03-20 Thread Denis Shelomovskij

20.03.2014 13:52, Rikki Cattermole пишет:

On Thursday, 20 March 2014 at 09:32:33 UTC, Denis Shelomovskij wrote:

20.03.2014 13:20, Rikki Cattermole пишет:

On Thursday, 20 March 2014 at 08:24:30 UTC, Denis Shelomovskij wrote:

It's filed as enhancement 12418 [2]:

C-strings processing is a special and common case so:
1. C-strings should be supported with both performance and usability.
2. There should be a dedicated module for C-strings (instead of adding
such functions here and there in other modules).

Current state: there is no good support for C-strings in Phobos, there
is slow and broken `toStringz` (Issue 12417 [3]), and no standard way
to make many common operations, like converting returned C-string to
string and releasing its memory or creating a C-string from string
using an allocation function.

So I propose to add `unstd.c.string` [1] module to Phobos which
include all use-cases I have seen implementing (correct and fast in
contrast to existing ones like GtkD (yes, it's both incorrect and slow
because of tons of GC allocations)) C library wrappers.


[1] http://denis-sh.bitbucket.org/unstandard/unstd.c.string.html
[2] https://d.puremagic.com/issues/show_bug.cgi?id=12418
[3] https://d.puremagic.com/issues/show_bug.cgi?id=12417


Looks like it wouldn't be really useful with Windows API. Given that
wstrings are more common there.


You misunderstand the terminology. C string is a zero-terminated
string. Also looks like you didn't even go to docs page as the second
example is WinAPI one.

I understand how c strings work. It would be nice to have more unittests
for dstring/wstring, because it looks more geared towards char/string.
Which is why it looks on the offset that it is less going to work.


I'd say must unittests do test UTF-16  UTF-32 versions. As for 
documentation, function signatures contain template parameter for 
character but probably there is a lack of ddoc unittests and/or 
documentation.





Another thing that would be nice to have is a wrapper struct for the
pointer that allows accessing via e.g. opIndex and opSlice. Ext.
Use case: Store the struct on D side to make sure GC doesn't clean it up
and still be able to access and modify it like a normal string easily.


I don't understand the use-case. If you did implemented some C library
wrappers and have a personal experience, I'd like to hear your opinion
on C functions calling problem and your proposal to solve it, if you
dislike mine. Also with examples, please, where my solution fails and
your one rocks. )


I don't dislike your approach at all. I just feel that it needs to allow
for a little more use cases. Given the proposal is for phobos.

What you have done looks fine for most cases to c libraries. I'm just
worried that it has less use cases then it could have.
I'm just nitpicking so don't mind me too much :)


Thanks. So the algorithm is like this: find C library which needs more 
love and file me an issue [1]. As I just added all common use-cases I 
have seen.


[1] https://bitbucket.org/denis-sh/unstandard/issues

--
Денис В. Шеломовский
Denis V. Shelomovskij


DDT in Eclipse

2014-03-20 Thread Russel Winder
I am finding that I have to remove DDT from Eclipse in order to get the
latest CDT. Is this to be expected?

Thanks.

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



Re: Most basic nothrow, pure, @safe functions?

2014-03-20 Thread Simen Kjærås

On 2014-03-19 08:59, Joseph Rushton Wakeling wrote:

On 19/03/14 00:20, Steven Schveighoffer wrote:

I think we all agree that there are some things that the compiler
simply cannot
prove are nothrow, but to be able to write useful nothrow code, we
have to paste
nothrow on there anyway.


Just to clarify my understanding here: exactly how much compiler
checking _is_ done of nothrow?  Is it simply to confirm that whatever is
called by the function contains no throw statements (hopefully all the
way down ...), or is there more ... ?


It checks that any exceptions thrown in the function body are caught in 
a try/catch, and that any functions not marked nothrow are similarly 
handled in a try/catch. I believe that is all.


For templated functions, the compiler does the same to figure out if the 
instantiation is nothrow. Thus a function can call a templated function 
that's not marked nothrow if its body can be compiled as such.


--
  Simen


Re: inlining...

2014-03-20 Thread Manu
On 20 March 2014 18:35,
7d89a89974b0ff40.invalid@internationalized.invalidwrote:

 On Thursday, 20 March 2014 at 02:08:16 UTC, Manu wrote:

 The problem is upside down. If you want to inline multiple levels, you
 start from the leaves and move downwards, not from the root moving upwards


 Yes, that is true in cases where leaves are frequently visited. Good
 point. I am most interested in full inlining, but the heuristics should
 probably start with the leaves for people not interested in that. Agree.

 Anyway, in the case of ray tracing (or any search structure) I could see
 the value of having the opposite in combination with CTFE/partial
 evaluation.

 Example: Define a static scene (of objects) and let the compiler turn it
 into a state machine of code.

 Another example: Define an array of data, use partial evaluation to turn
 it into a binary tree, then turn the binary tree into code.


  Inlining should be strictly deliberate, there's nothing to say that every
 function called in a tree should be inlined. There's a high probability
 there's one/some that shouldn't be among a few that should.


 In the case of a long running loop it does not really matter. What it does
 get you is a chance to use generic code (or libraries) and then do a
 first-resort optimization. I basically see it as a time-saving feature
 (programmers time). A tool for cutting development costs.

  Remember too, that call-site inlining isn't the only method, there would
 also be always-inline...


 Yes, that is the first. I have in another thread some time ago suggested a
 solution that use weighted inlining to aid compiler heuristics:

 http://forum.dlang.org/thread/szjkyfpnachnnyknn...@forum.dlang.org#post-
 szjkyfpnachnnyknnfwp:40forum.dlang.org

 As you can see I also suggested call-site inlining, so I am fully behind
 you in this. :-) Lack of inlining and GC are my main objections to D.


  I think always-inline is what you want for some
 decidedly trivial functions (although these will probably be heuristically
 inlined anyway), not call-site inlining.


 I agree. Compiler heuristics can change. It is desirable to be able to
 express intent no matter what the current heuristics are.


  I just don't see how recursive
 call-site inlining is appropriate, considering that call trees are often
 complex, subject to change, and may even call functions that you don't
 have
 source for.


 You should not use it blindly.


  You can cascade the mixin keyword if you want to, that's very simple.


 Not if you build the innerloop using generic components. I want this

 inline_everything while(conditon){
 statement;
 statement;

 }

  I'd be highly surprised if you ever encountered a call tree where
 you wanted to inline everything (and the optimiser didn't do it for you).


 Not if you move to high-level programming using prewritten code and only
 go low level after profiling.


  As soon as you encounter a single function in the tree that shouldn't be
 inlined, then you'll be forced to do it one level at a time anyway.


 But then you have to change the libraries you are using!?

 Nothing prevents you to introduce exceptions as an extension though. I
 want inline(0.5) as default, but also be able to write inline(1) for inline
 always and inline(0) for inline never.

 func1(){} // implies inline(0.5) weighting
 inline func2(){} // same as inline(1) weighting, inline always
 inline(0.75) fun31(){} // increase the heuristics weighting
 inline(0) func4(){} // never-ever inline

 Ola.


I'm sorry. I really can't support any of these wildly complex ideas. I just
don't feel they're useful, and they're not very well founded.
A numeric weight? What scale is it in? I'm not sure of any
'standard-inline-weight-measure' that any programmer would be able to
intuitively gauge the magic number against. That will simply never be
agreed by the devs.
It also doesn't make much sense... different platforms will assign very
different weights and different heuristics at the inliner. It's not a
numeric quantity; it's a complex determination whether a function is a good
candidate or not.
The value you specify is likely highly context sensitive and probably not
portable. Heuristic based Inlining should be left to the optimiser to
decide.

And I totally object to recursive inlining. It has a kind of absolute
nature that removes control all the way down the call tree, and I don't
feel it's likely that you would often (ever?) want to explicitly inline an
entire call tree.
If you want to inline a second level, then write mixin in the second level.
Recurse.
You are talking about generic code as if this isn't appropriate, but I
specifically intend to use this in generic code very similar to what you
suggest; so I don't see the incompatibility.
I think you're saying like manually specifying it all the way down the call
tree is inconvenient, but I would argue that manually specifying
*exclusions* throughout the call tree after specifying a recursive inline
is even 

Re: Ruby-style each in D?

2014-03-20 Thread w0rp
'each' sounds like a good idea for supporting component 
programming a little more. As bearophile as already stated, you 
can do something like this...


someRange.filter!foo.frobulate.each!doSomethingWithIt;

For Walter's question about parallel execution, I imagine 
something like this.


// std.parallelism parallel function here.
someRange.whatever.parallel(numberOfUnits).each!doSomething

Basically it just removes a little foreach boilerplate. I don't 
think the implementation needs to be much more complicated than 
what Andrei wrote already, I would just pull that pretty much 
as-is.


I also don't think an argument like you can already do this with 
foreach is valid. You don't *have* to use it, and some people 
might like it. I know I would appreciate having it in 
std.algorithm. (I'm kind of a range fanboy.)


Re: Most basic nothrow, pure, @safe functions?

2014-03-20 Thread w0rp
I'd just like to toss one in there. .dup and .idup for slices and 
associative arrays. I've seen a few cases where these functions 
are not nothrow when they could be. (Because OutOfMemoryError is 
an Error, not an Exception.)


Re: A simple sieve in Phobos?

2014-03-20 Thread Dicebot
On Wednesday, 19 March 2014 at 17:40:50 UTC, Andrei Alexandrescu 
wrote:

On 3/19/14, 10:01 AM, Dicebot wrote:
I avoid it too but it is my personal problem to deal with. dub 
is
de-facto standard in D tool chain and I am pretty sure 
eventually will

be distributed with dmd.


It may be time to look into this. Who wants to champion this 
effort? -- Andrei


I think it is _tiny_ bit to early - there are some relatively big 
intrusive changes planned for dub (like switching to SDL as 
default description grammar) and it is better to start 
distributing it once this stuff stabilizes. I'll keep it in my 
notes though and start poking people once it looks feasible :)


Do you have any personal requirements in mind that need to be met 
before legitimization of dub?


Re: inlining...

2014-03-20 Thread Ola Fosheim Grøstad

On Thursday, 20 March 2014 at 12:31:33 UTC, Manu wrote:
I'm sorry. I really can't support any of these wildly complex 
ideas.


They aren't actually complex, except tail-call optimization (but 
that is well understood).


If you want to inline a second level, then write mixin in the 
second level.


You might as well do copy-paste then. You cannot add inlining to 
an imported library without modifying it.


at all, which is annoying, because I REALLY need this (I've 
been trying to
motivate inline support for over 3 years), and I get the 
feeling you're

just throwing hypotheticals around.


You need inlining, agree, but not 1 level mixin. Because you can 
do that with regular inlining.


Re: Most basic nothrow, pure, @safe functions?

2014-03-20 Thread monarch_dodra

On Thursday, 20 March 2014 at 12:51:35 UTC, w0rp wrote:
I'd just like to toss one in there. .dup and .idup for slices 
and associative arrays. I've seen a few cases where these 
functions are not nothrow when they could be. (Because 
OutOfMemoryError is an Error, not an Exception.)


The reasons it's not nothrow is because because dup causes 
postblit, and postblit could throw.


Of course, by that same token, postblit could be unsafe and 
impure. It's terribly inconsistent.


Which is another big problem of druntime: Mostly everything in it 
is done at run-time using typeid, so there is no static inference.


Re: inlining...

2014-03-20 Thread Ola Fosheim Grøstad
Please note that 1 level mixin is not sufficient in the case of 
libraries. In too many cases you will not inline the function 
that does the work, only the interface wrapper.


Re: Ruby-style each in D?

2014-03-20 Thread Andrea Fontana

On Thursday, 20 March 2014 at 12:32:49 UTC, w0rp wrote:

// std.parallelism parallel function here.
someRange.whatever.parallel(numberOfUnits).each!doSomething


+1

This works:
foreach(i; [0,1,2,3,4,5].parallel) i.writeln;

This works:
[0,1,2,3,4,5].each!writeln;

This won't compile:
[0,1,2,3,4,5].parallel.each!writeln;

Error: template tmp.each cannot deduce function from argument 
types !(writeln)(ParallelForeach!(int[])), candidates are:
/tmp/tmp.d(9):tmp.each(alias fun, Range)(Range range) if 
(isInputRange!Range)


Re: Appropriateness of posts

2014-03-20 Thread Steven Schveighoffer

On Thu, 20 Mar 2014 05:35:53 -0400, Chris wend...@tcd.ie wrote:


On Wednesday, 19 March 2014 at 23:18:55 UTC, H. S. Teoh wrote:


Sometimes, the only way to win is to not play.


T


+1. You should add this to your list of quotes.


-WOPR, War Games


Re: inlining...

2014-03-20 Thread Manu
On 21 March 2014 00:10,
7d89a89974b0ff40.invalid@internationalized.invalidwrote:

 Please note that 1 level mixin is not sufficient in the case of libraries.
 In too many cases you will not inline the function that does the work, only
 the interface wrapper.


I don't think I would ever want to inline the whole call tree of a library.
I've certainly never wanted to do anything like that in 20 years or so, and
I've worked on some really performance critical systems, like amiga,
dreamcast, ps2.
It still sounds really sketchy. If the function that does the work is a few
levels deep, then there is probably a good reason for that. What if there's
an error check that writes log output or something? Or some branch that
leads to other uncommon paths?

I think you're making this problem up. Can you demonstrate where this has
been a problem for you in the past?
The call tree would have to be so very particular for this to be
appropriate, and then you say this is a library, which you have no control
over... so the call tree is just perfect by chance? What if the library
changes?


Re: Ruby-style each in D?

2014-03-20 Thread Simen Kjærås

On 2014-03-20 14:16, Andrea Fontana wrote:

On Thursday, 20 March 2014 at 12:32:49 UTC, w0rp wrote:

// std.parallelism parallel function here.
someRange.whatever.parallel(numberOfUnits).each!doSomething


+1

This works:
foreach(i; [0,1,2,3,4,5].parallel) i.writeln;

This works:
[0,1,2,3,4,5].each!writeln;

This won't compile:
[0,1,2,3,4,5].parallel.each!writeln;

Error: template tmp.each cannot deduce function from argument types
!(writeln)(ParallelForeach!(int[])), candidates are:
/tmp/tmp.d(9):tmp.each(alias fun, Range)(Range range) if
(isInputRange!Range)



It could be made to work, though:

template isIterable(T) {
enum isIterable = is(typeof((T t){foreach (e; t){}}));
}

template isRefIterable(T) {
enum isRefIterable = is(typeof((T t){foreach (ref e; t){}}));
}

void each(alias fun, Range)(Range range)
if (isInputRange!Range)
{
while (!range.empty)
{
unaryFun!fun(range.front);
range.popFront();
}
}

void each(alias fun, Range)(Range range)
if (!isInputRange!Range  isRefIterable!Range)
{
foreach (ref e; range) {
unaryFun!fun(e);
}
}

void each(alias fun, Range)(Range range)
if (!isInputRange!Range  isIterable!Range  !isRefIterable!Range)
{
foreach (e; range) {
unaryFun!fun(e);
}
}

void main() {
[0,1,2,3,4,5].parallel.each!writeln;
}

--
  Simen


Re: inlining...

2014-03-20 Thread ponce
On Thursday, 20 March 2014 at 08:35:22 UTC, Ola Fosheim Grøstad 
wrote:
Nothing prevents you to introduce exceptions as an extension 
though. I want inline(0.5) as default, but also be able to 
write inline(1) for inline always and inline(0) for inline 
never.


func1(){} // implies inline(0.5) weighting
inline func2(){} // same as inline(1) weighting, inline always
inline(0.75) fun31(){} // increase the heuristics weighting
inline(0) func4(){} // never-ever inline



It looks promising when seen like that, but introducing explicit 
inlining/deinlining to me correspond to a precise process:


1. Bottleneck is identified.
2. we could {inline|deinline} this call at this particular place 
and see what happens
3. Apply inline directive for this call. Only always or never 
is ever wanted for me, and for 1 level only.

4. Measure and validate like all optimizations.

Now after this, even if the inlining become harmful for other 
reasons, I want this inlining to be maintained, whatever the 
cost, not subject to random rules I don't know of. When you tweak 
inlining, you are supposed to know what you are doing, and it's 
not just an optimization, it's an essential tool that enables 
other optimizations, help disambiguate aliasing, help the 
auto-vectorizer, help constant propagation...


In the large majority of cases it can be left to the compiler, 
and in the 1% cases that matters I want to do it explicitely full 
stop.




Re: Ruby-style each in D?

2014-03-20 Thread Andrea Fontana

On Thursday, 20 March 2014 at 15:02:46 UTC, Simen Kjærås wrote:

On 2014-03-20 14:16, Andrea Fontana wrote:

On Thursday, 20 March 2014 at 12:32:49 UTC, w0rp wrote:

// std.parallelism parallel function here.
someRange.whatever.parallel(numberOfUnits).each!doSomething


+1

This works:
foreach(i; [0,1,2,3,4,5].parallel) i.writeln;

This works:
[0,1,2,3,4,5].each!writeln;

This won't compile:
[0,1,2,3,4,5].parallel.each!writeln;

Error: template tmp.each cannot deduce function from argument 
types

!(writeln)(ParallelForeach!(int[])), candidates are:
/tmp/tmp.d(9):tmp.each(alias fun, Range)(Range range) 
if

(isInputRange!Range)



It could be made to work, though:

template isIterable(T) {
enum isIterable = is(typeof((T t){foreach (e; t){}}));
}

template isRefIterable(T) {
enum isRefIterable = is(typeof((T t){foreach (ref e; 
t){}}));

}

void each(alias fun, Range)(Range range)
if (isInputRange!Range)
{
while (!range.empty)
{
unaryFun!fun(range.front);
range.popFront();
}
}

void each(alias fun, Range)(Range range)
if (!isInputRange!Range  isRefIterable!Range)
{
foreach (ref e; range) {
unaryFun!fun(e);
}
}

void each(alias fun, Range)(Range range)
if (!isInputRange!Range  isIterable!Range  
!isRefIterable!Range)

{
foreach (e; range) {
unaryFun!fun(e);
}
}

void main() {
[0,1,2,3,4,5].parallel.each!writeln;
}

--
  Simen


I think that pull request should be updated.

Why isn't ParallelForEach implemented as Range, instead?



Re: Most basic nothrow, pure, @safe functions?

2014-03-20 Thread Sean Kelly
On Tuesday, 18 March 2014 at 23:56:15 UTC, Steven Schveighoffer 
wrote:
On Tue, 18 Mar 2014 19:48:45 -0400, Walter Bright 
newshou...@digitalmars.com wrote:



On 3/18/2014 4:20 PM, Steven Schveighoffer wrote:
In a recent (well, recently pulled anyway) pull request that 
Monarch Dodra
brought up, we debated what should be considered nothrow in 
the depths of druntime.


There's a lot of low hanging nothrow fruit in druntime that 
doesn't need analysis, it just needs to get done:


https://d.puremagic.com/issues/show_bug.cgi?id=12389


Can we mark _d_monitorenter and _d_monitorexit nothrow and have 
the compiler see that when using synchronized? This was the 
hurdle we couldn't overcome in the referenced pull request.


Should those be marked nothrow? What about pure and @safe?


I'd be inclined to say yes.  Although monitors use lazy 
initialization, I think the failure to initialize a monitor 
should probably be considered an Error.


Re: A simple sieve in Phobos?

2014-03-20 Thread Andrei Alexandrescu

On 3/20/14, 6:07 AM, Dicebot wrote:

On Wednesday, 19 March 2014 at 17:40:50 UTC, Andrei Alexandrescu wrote:

On 3/19/14, 10:01 AM, Dicebot wrote:

I avoid it too but it is my personal problem to deal with. dub is
de-facto standard in D tool chain and I am pretty sure eventually will
be distributed with dmd.


It may be time to look into this. Who wants to champion this effort?
-- Andrei


I think it is _tiny_ bit to early - there are some relatively big
intrusive changes planned for dub (like switching to SDL as default
description grammar) and it is better to start distributing it once this
stuff stabilizes. I'll keep it in my notes though and start poking
people once it looks feasible :)

Do you have any personal requirements in mind that need to be met before
legitimization of dub?


I think it should be pig easy to use, battle tested, and have some 
security mechanism in place.


Andrei


Re: inlining...

2014-03-20 Thread Jacob Carlborg

On 2014-03-19 09:35, Manu wrote:


I don't already have it, otherwise I'd be making use of it. D has no
control over the inliner. GDC/LDC offer attributes, but then it's really
annoying that D has no mechanism to make use of compiler-specific
attributes in a portable way (ie, attribute aliasing), so I can't make
use of those without significantly interfering with my code.


Can't you create a tuple with different attributes depending on which 
compiler is currently compiling? Something like this:


version (LDC)
alias attributes = TypeTuple!(@attribute(forceinline);

else version (GDC)
alias attributes = TypeTuple!(@attribute(forceinline));

else version (DigitalMars)
alias attributes = TypeTuple!();

else
static assert(false);

@(attributes) void foo () { } // This assume that attributes will be 
expanded


--
/Jacob Carlborg


Re: Cannot cast X to Y at compile time...?

2014-03-20 Thread dnspies

On Wednesday, 19 March 2014 at 20:43:59 UTC, Frustrated wrote:

On Wednesday, 19 March 2014 at 16:57:38 UTC, dnspies wrote:

I have a function called at CTFE which includes the lines:

97  if(conjunction exp = cast(conjunction)this_exp) {
98  inner_substitutions!(first,conjunction)(exp, map);
99  } else if(disjunction exp = cast(disjunction)this_exp) {
100 inner_substitutions!(first,disjunction)(exp, map);
101 }

Here, this_exp is a reference of type expression to an 
object whose CTFE-runtime-type is of type disjunction.  
conjunction and disjunction are both descendent classes of 
expression.

This code produces the following compilation error:

source/cfgparse.d(97): Error: cannot cast [...] to 
cfgparse.conjunction at compile time.


([...] stands in for a very long string which I think is some 
sort of representation of this_exp)


Just for the hell of it, I tried moving the assignment out of 
the conditional, and something very strange happens.


97  if(cast(conjunction)this_exp) {
98  conjunction exp = cast(conjunction)this_exp;
99  inner_substitutions!(first,conjunction)(exp, map);
100 } else if(cast(disjunction)this_exp) {
101 disjunction exp = cast(disjunction)this_exp;
102 inner_substitutions!(first,disjunction)(exp, map);
103 }

source/cfgparse.d(101): Error: cannot cast [...] to 
cfgparse.disjunction at compile time


Both the conditions compile properly, and now only the 
assignment fails.  Why  is this happening and how can I avoid 
it?


I ran up to a similar situation when the thing trying to be 
cast was not what I thought it was. I.e., the error is exactly 
what it means. Try to create a this_exp that is a conjunction 
explicitly to see if that is the problem.


Sorry, I don't understand.  When I cast something to the wrong
type, I should just get a null reference, shouldn't I?  It
shouldn't throw an error.


Re: Most basic nothrow, pure, @safe functions?

2014-03-20 Thread Walter Bright

On 3/18/2014 5:49 PM, Walter Bright wrote:

On 3/18/2014 4:56 PM, Steven Schveighoffer wrote:

Can we mark _d_monitorenter and _d_monitorexit nothrow and have the compiler see
that when using synchronized? This was the hurdle we couldn't overcome in the
referenced pull request.

Should those be marked nothrow? What about pure and @safe?


Good question. I don't have an answer at the moment.



I'm pretty sure they can't be pure. After all, monitors affect global state, can 
result in deadlocks, etc.


Re: A simple sieve in Phobos?

2014-03-20 Thread Gary Willoughby
On Wednesday, 19 March 2014 at 17:40:50 UTC, Andrei Alexandrescu 
wrote:

On 3/19/14, 10:01 AM, Dicebot wrote:
I avoid it too but it is my personal problem to deal with. dub 
is
de-facto standard in D tool chain and I am pretty sure 
eventually will

be distributed with dmd.


It may be time to look into this. Who wants to champion this 
effort? -- Andrei


I'd support inclusion into the official Dlang package but it has 
to be ready for distribution. I'm a big fan of it but it doesn't 
seem 100% stable yet.


For experimental libs i'd rather they were kept out of phobos and 
placed within the dub registry. We can load and use them at 
leisure from there without expecting any sort of support from the 
language maintainers. If included in phobos i can almost 
guarantee that even though they will be marked experimental devs 
will moan when they change because they will have an official 
stamp.


Dub should be more embraced by the official language maintainers 
especially moving the Deimos repo's into there. I myself have had 
to duplicate and package a deimos repo and add it just to move on 
with a project.


Re: A simple sieve in Phobos?

2014-03-20 Thread David Eagen

On Thursday, 20 March 2014 at 21:31:13 UTC, Gary Willoughby wrote:
For experimental libs i'd rather they were kept out of phobos 
and placed within the dub registry. We can load and use them at 
leisure from there without expecting any sort of support from 
the language maintainers. If included in phobos i can almost 
guarantee that even though they will be marked experimental 
devs will moan when they change because they will have an 
official stamp.


+1


Re: Ruby-style each in D?

2014-03-20 Thread monarch_dodra
On Wednesday, 19 March 2014 at 15:06:40 UTC, Andrei Alexandrescu 
wrote:

Pros and cons are already being discussed. Destroy!

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


Andrei


User Ali Çehreli has posted in learn what I think is an 
interesting problem:

http://forum.dlang.org/thread/lgfmbf$v7c$1...@digitalmars.com
//
This is a somewhat common little exercise: Write a function that 
takes

the size of a diamond and produces a diamond of that size.

When printed, here is the output for size 11:

 *
***
   *
  ***
 *
***
 *
  ***
   *
***
 *

What interesting, boring, efficient, slow, etc. ways are there?

Ali
//

The reason I bring it up is that this usually leads to a 
competition of whoever thinks up the most creative/concise UFCS 
chain.


So here's what I'm thinking: Let's do this, but also using 
each/tee/tap/consume/walk (and others?)!


I think this real world scenario is a good bench for seeing the 
effects of mixing imperative-style statements into a 
functional-style wrapper.


Maybe the result will reveal that something is awesome, or that 
it is useless? That maybe something that looks like it works, is 
actually subtly buggy? That maybe each turns out to be useful 
past our wildest dreams?


Who knows?


Handling invalid UTF sequences

2014-03-20 Thread Walter Bright

Currently we do it by throwing a UTFException. This has problems:

1. about anything that deals with UTF cannot be made nothrow

2. turns innocuous errors into major problems, such as DOS attack vectors
http://en.wikipedia.org/wiki/UTF-8#Invalid_byte_sequences

One option to fix this is to treat invalid sequences as:

1. the .init value (0xFF for UTF8, 0x for UTF16 and UTF32)

2. U+FFFD

I kinda like option 1.

What do you think?


Re: Handling invalid UTF sequences

2014-03-20 Thread monarch_dodra

On Thursday, 20 March 2014 at 22:39:47 UTC, Walter Bright wrote:
Currently we do it by throwing a UTFException. This has 
problems:


1. about anything that deals with UTF cannot be made nothrow

2. turns innocuous errors into major problems, such as DOS 
attack vectors

http://en.wikipedia.org/wiki/UTF-8#Invalid_byte_sequences

One option to fix this is to treat invalid sequences as:

1. the .init value (0xFF for UTF8, 0x for UTF16 and UTF32)

2. U+FFFD

I kinda like option 1.

What do you think?


I had thought of this before, and had an idea along the lines of:
1. strings inside the program are always valid.
2. encountering invalid strings inside the program  is an Error.
3. strings from the outside world must be validated before use.

The advantage is *more* than just a nothrow guarantee, but also a 
performance guarantee in release. And it *is* a pretty sane 
approach to the problem:

- User data: validate before use.
- Internal data: if its bad, your program is in a failure state.



As for your proposal, I can't really say. Silently accepting 
invalid sequences sounds nice at first, but its kind of just 
squelching the problem, isn't it?




In any case, both proposals would be major breaking changes...


Re: Handling invalid UTF sequences

2014-03-20 Thread deadalnix

On Thursday, 20 March 2014 at 22:39:47 UTC, Walter Bright wrote:
Currently we do it by throwing a UTFException. This has 
problems:


1. about anything that deals with UTF cannot be made nothrow

2. turns innocuous errors into major problems, such as DOS 
attack vectors

http://en.wikipedia.org/wiki/UTF-8#Invalid_byte_sequences

One option to fix this is to treat invalid sequences as:

1. the .init value (0xFF for UTF8, 0x for UTF16 and UTF32)

2. U+FFFD

I kinda like option 1.

What do you think?


Hiding errors under the carpet is not a good strategy. These 
sequences are invalid, and doomed to explode at some point. I'm 
not sure what the solution is, but the .init one do not seems 
like the right one to me.


Re: Handling invalid UTF sequences

2014-03-20 Thread Nick Sabalausky

On 3/20/2014 6:39 PM, Walter Bright wrote:

Currently we do it by throwing a UTFException. This has problems:

1. about anything that deals with UTF cannot be made nothrow

2. turns innocuous errors into major problems, such as DOS attack vectors
http://en.wikipedia.org/wiki/UTF-8#Invalid_byte_sequences

One option to fix this is to treat invalid sequences as:

1. the .init value (0xFF for UTF8, 0x for UTF16 and UTF32)

2. U+FFFD

I kinda like option 1.

What do you think?


I'd have to give some thought to have an opinion on the right solution, 
however I do want to say the current UTFException throwing is something 
I've always been unhappy with. So it definitely should get addressed in 
some way.




Re: Handling invalid UTF sequences

2014-03-20 Thread Chris Williams
To the extent possible, it should try to retain the data. But if 
ever the character is actually needed for something (like parsing 
JSON or displaying a glyph), the bad region should be replaced 
with a series of replacement characters:


http://en.wikipedia.org/wiki/Replacement_character#Replacement_character


Re: Handling invalid UTF sequences

2014-03-20 Thread Walter Bright

On 3/20/2014 3:51 PM, monarch_dodra wrote:

In any case, both proposals would be major breaking changes...


Or we could do this as alternate names, leaving the originals as throwing.

 Silently accepting invalid sequences sounds nice at first, but its kind of 
just squelching the problem, isn't it?


Not exactly. The decoded/encoded string will still have invalid code units in 
it. It'd be like floating point nan, the invalid bits will still be propagated 
onwards to the output.


I'm also of the belief that UTF sequences should be validated on input, not 
necessarily on every operation on them.


Re: Handling invalid UTF sequences

2014-03-20 Thread Brad Anderson

On Thursday, 20 March 2014 at 22:51:27 UTC, monarch_dodra wrote:

On Thursday, 20 March 2014 at 22:39:47 UTC, Walter Bright wrote:
Currently we do it by throwing a UTFException. This has 
problems:


1. about anything that deals with UTF cannot be made nothrow

2. turns innocuous errors into major problems, such as DOS 
attack vectors

http://en.wikipedia.org/wiki/UTF-8#Invalid_byte_sequences

One option to fix this is to treat invalid sequences as:

1. the .init value (0xFF for UTF8, 0x for UTF16 and UTF32)

2. U+FFFD

I kinda like option 1.

What do you think?


I had thought of this before, and had an idea along the lines 
of:

1. strings inside the program are always valid.
2. encountering invalid strings inside the program  is an 
Error.
3. strings from the outside world must be validated before 
use.


The advantage is *more* than just a nothrow guarantee, but also 
a performance guarantee in release. And it *is* a pretty sane 
approach to the problem:

- User data: validate before use.
- Internal data: if its bad, your program is in a failure state.



I'm a fan of this approach but Timon pointed out when I wrote 
about it once that it's rather trivial to get an invalid string 
through slicing mid-code point so now I'm not so sure. I think 
I'm still in favor of it because you've obviously got a logic 
error if that happens so your program isn't correct anyway (it's 
not a matter of bad user input).


Re: Ruby-style each in D?

2014-03-20 Thread bearophile

monarch_dodra:

I have just given some solutions in D.learn.


So here's what I'm thinking: Let's do this, but also using 
each/tee/tap/consume/walk (and others?)!


I think this real world scenario is a good bench for seeing 
the effects of mixing imperative-style statements into a 
functional-style wrapper.


As I explained in a precedent post in this thread it's hard to 
design something if you don't try to use it, even something 
simple as a each(). So I approve such exercises.


Bye,
bearophile


Re: Ruby-style each in D?

2014-03-20 Thread Walter Bright

On 3/20/2014 5:33 PM, bearophile wrote:

As I explained in a precedent post in this thread it's hard to design something
if you don't try to use it, even something simple as a each().


Right on.



Re: inlining...

2014-03-20 Thread Ola Fosheim Grøstad

On Thursday, 20 March 2014 at 15:26:35 UTC, ponce wrote:
Now after this, even if the inlining become harmful for other 
reasons, I want this inlining to be maintained, whatever the 
cost, not subject to random rules I don't know of. When you


The rules aren't random. The inliner conceptually use weighting 
anyway, you just increase the threshold for a specific call-tree. 
E.g. if a function is on the borderline of being inlined the 
probability is 50% if you add some noise to the selection with a 
magnitude that equals the typical approximation error of the 
heuristics. inline(0.75) should increase the probability to 
75%. Today all functions have an implied inline(0.5). I think 
you should have this kind of control for all compiler heuristics 
thresholds that are arbitrary, not only inlining.


Call site inlining is primarily useful for inlining external 
code. The alternative is usually to replace libraries with your 
own version.


Re: Handling invalid UTF sequences

2014-03-20 Thread Steven Schveighoffer
On Thu, 20 Mar 2014 18:39:50 -0400, Walter Bright  
newshou...@digitalmars.com wrote:



Currently we do it by throwing a UTFException. This has problems:

1. about anything that deals with UTF cannot be made nothrow

2. turns innocuous errors into major problems, such as DOS attack vectors
http://en.wikipedia.org/wiki/UTF-8#Invalid_byte_sequences

One option to fix this is to treat invalid sequences as:

1. the .init value (0xFF for UTF8, 0x for UTF16 and UTF32)

2. U+FFFD

I kinda like option 1.

What do you think?


Can't say I like it. Especially since current code expects a throw.

I understand the need. What about creating a different type which decodes  
into a known invalid code, and doesn't throw? This leaves the selection of  
throwing or not up to the type, which is generally decided on declaration,  
instead of having to change all your calls.


-Steve


Re: Most basic nothrow, pure, @safe functions?

2014-03-20 Thread Steven Schveighoffer
On Thu, 20 Mar 2014 17:32:01 -0400, Walter Bright  
newshou...@digitalmars.com wrote:



On 3/18/2014 5:49 PM, Walter Bright wrote:

On 3/18/2014 4:56 PM, Steven Schveighoffer wrote:
Can we mark _d_monitorenter and _d_monitorexit nothrow and have the  
compiler see
that when using synchronized? This was the hurdle we couldn't overcome  
in the

referenced pull request.

Should those be marked nothrow? What about pure and @safe?


Good question. I don't have an answer at the moment.



I'm pretty sure they can't be pure. After all, monitors affect global  
state, can result in deadlocks, etc.


How do they affect global state?

Resulting in deadlocks does not make them impure. This is also a pure  
function:


pure int foo()
{
   while(1) {}
   return 0;
}

Pure doesn't mean bug free.

-Steve


Re: Most basic nothrow, pure, @safe functions?

2014-03-20 Thread bearophile

Steven Schveighoffer:


This is also a pure function:

pure int foo()
{
   while(1) {}
   return 0;
}

Pure doesn't mean bug free.


Thankfully the D compiler catches the bug :-)

test.d(3,4): Warning: statement is not reachable

Bye,
bearophile


Re: Most basic nothrow, pure, @safe functions?

2014-03-20 Thread Steven Schveighoffer
On Thu, 20 Mar 2014 21:44:38 -0400, bearophile bearophileh...@lycos.com  
wrote:



Steven Schveighoffer:


This is also a pure function:

pure int foo()
{
   while(1) {}
   return 0;
}

Pure doesn't mean bug free.


Thankfully the D compiler catches the bug :-)

test.d(3,4): Warning: statement is not reachable


I can make it not catch that error, but that is not the bug. The bug is  
that it never returns, effectively deadlocking. The sample is  
intentionally short to demonstrate my point, I (obviously) didn't try to  
compile it.


-Steve


Re: Most basic nothrow, pure, @safe functions?

2014-03-20 Thread deadalnix

On Friday, 21 March 2014 at 02:00:11 UTC, Walter Bright wrote:

On 3/20/2014 6:40 PM, Steven Schveighoffer wrote:

How do they affect global state?


Mutexes implicitly share state. It's the reason they exist. 
They can't be pure, because pure functions don't share state.


If you got that road, you can't allow memory allocators to be
used in pure code. That isn't a good argument.


Re: Most basic nothrow, pure, @safe functions?

2014-03-20 Thread Walter Bright

On 3/20/2014 6:40 PM, Steven Schveighoffer wrote:

How do they affect global state?


Mutexes implicitly share state. It's the reason they exist. They can't be pure, 
because pure functions don't share state.




Re: Most basic nothrow, pure, @safe functions?

2014-03-20 Thread Steven Schveighoffer
On Thu, 20 Mar 2014 22:00:15 -0400, Walter Bright  
newshou...@digitalmars.com wrote:



On 3/20/2014 6:40 PM, Steven Schveighoffer wrote:

How do they affect global state?


Mutexes implicitly share state. It's the reason they exist. They can't  
be pure, because pure functions don't share state.


I view it differently. I feel like locking and unlocking a mutex is pure.  
After calling lock, the same thing *always* happens. After unlocking, the  
same thing *always* happens. It's a weird thing -- when you lock a mutex,  
you own it after it's locked. It's no longer shared. It can be thought of  
as pulling memory out of the heap to temporarily own, and then putting it  
back, just like memory allocation (which is considered pure).


This is quite different from actual global state, which is accessed via  
globals.


trylock I don't think should be pure. I'm not sure about read/write locks.

-Steve


Re: Most basic nothrow, pure, @safe functions?

2014-03-20 Thread Andrei Alexandrescu

On 3/20/14, 6:52 PM, Steven Schveighoffer wrote:

On Thu, 20 Mar 2014 21:44:38 -0400, bearophile
bearophileh...@lycos.com wrote:


Steven Schveighoffer:


This is also a pure function:

pure int foo()
{
   while(1) {}
   return 0;
}

Pure doesn't mean bug free.


Thankfully the D compiler catches the bug :-)

test.d(3,4): Warning: statement is not reachable


I can make it not catch that error, but that is not the bug. The bug is
that it never returns, effectively deadlocking. The sample is
intentionally short to demonstrate my point, I (obviously) didn't try to
compile it.

-Steve


My dream: pure @safe functions never cause deadlock.

Andrei



Re: Most basic nothrow, pure, @safe functions?

2014-03-20 Thread Steven Schveighoffer
On Thu, 20 Mar 2014 22:14:59 -0400, Steven Schveighoffer  
schvei...@yahoo.com wrote:


On Thu, 20 Mar 2014 22:00:15 -0400, Walter Bright  
newshou...@digitalmars.com wrote:



On 3/20/2014 6:40 PM, Steven Schveighoffer wrote:

How do they affect global state?


Mutexes implicitly share state. It's the reason they exist. They can't  
be pure, because pure functions don't share state.


I view it differently. I feel like locking and unlocking a mutex is  
pure. After calling lock, the same thing *always* happens. After  
unlocking, the same thing *always* happens. It's a weird thing -- when  
you lock a mutex, you own it after it's locked. It's no longer shared.  
It can be thought of as pulling memory out of the heap to temporarily  
own, and then putting it back, just like memory allocation (which is  
considered pure).


Thinking about it some more, I see what you mean -- an unshared mutex is  
useless.


But at the same time, some logically pure functions cannot be so without  
mutexes. E.g. memory allocation.


-Steve


Re: Cannot cast X to Y at compile time...?

2014-03-20 Thread Kapps

On Thursday, 20 March 2014 at 21:32:08 UTC, dnspies wrote:

Sorry, I don't understand.  When I cast something to the wrong
type, I should just get a null reference, shouldn't I?  It
shouldn't throw an error.


If the compiler can statically determine that the cast is invalid 
you get an error instead. You can use something like 'static 
if(is(T : Foo))' to test at compile-time if T is implicitly 
convertible to Foo (I'm not certain the exact semantics) or 
'static if(is(typeof(cast(Foo)T.init)))'.


There's probably better ways to do it, and I recommend asking on 
D.learn to figure out how to do what you're looking for.




Re: D as A Better C?

2014-03-20 Thread Rel

On Wednesday, 19 February 2014 at 15:46:38 UTC, Tim Krimm wrote:

On Tuesday, 18 February 2014 at 12:20:52 UTC, Rel wrote:
On Tuesday, 11 February 2014 at 19:43:00 UTC, Walter Bright 
wrote:

The subset would disallow use of any features that rely on:

1. moduleinfo
2. exception handling
3. gc
4. Object

I've used such a subset before when bringing D up on a new 
platform, as the new platform didn't have a working phobos.


What do you think?
So may I ask, what is official decision on the subject? Quite 
a lot of people were begging for it for a long time. Obviously 
I'd like to have this feature in D because it would finally 
allow game, embedded, system (and operating system) developers 
to use good, modern and beautiful language for their needs. As 
for me I've been waiting for this for a long time. Hacking on 
compiler and phobos in order to make it generate 
stdlib-indepentent code may be interesting from time to time, 
but keeping such kind of project up-to-date with each new 
version of the compiler can be quite hard. Supporting a subset 
of D language features suitable for system/embedded 
programming and porting seems to be the best decision in this 
case.


I have also been waiting for something like this for a long 
time.
Well in my opinion the language should be started with a fixed 
number of features, that are not dependent on runtime, then 
improve the language by adding features supported by runtime 
library. Too bad that D doesn't officially support a subset 
without runtime depemdencies, so we have to either use C/C++ or 
keep on trying to hack on of D compilers. On the other hand Rust 
can be used without runtime libraries.


Re: dmd v2.065 compatibility

2014-03-20 Thread Sönke Ludwig

Am 14.03.2014 11:43, schrieb Chris:

[1]
Yesterday I tried to build a project with dub. dub had downloaded and
installed dmd v2.065. The project and accompanying library had been
built with dmd v2.064. dub said that the project was up to date and
didn't need compiling. However, I got a long long error message
informing me that there were undefined references (see below). I
recompiled the library with dmd v2.065 and everything worked fine. Yet I
wonder, is this behavior normal, i.e. dub says its alright but not really?


DUB currently doesn't take the compiler version into account when 
generating the hash value used to cache the intermediate build results 
(in .dub/build/*), which is the reason it thought everything was up to 
date. This will get fixed for the next version.




Template with template?

2014-03-20 Thread Chris
How can I instantiate Person with Trait, i.e. a template with a 
template?


struct Trait(T0, T1) {
  T0 name;
  T1 value;
  T1[T0] map;

  this(T0 name, T1 value) {
this.name = name;
this.value = value;
map[name] = value;
  }
}

class Person(T) {
  T traits[];

  void addTrait(T trait) {
traits ~= trait;
  }
}


void main()
{
  auto trait1 = Trait!(string, string)(Name, John);
  auto trait2 = Trait!(string, int)(Age, 42);
  writefln(%s, trait1.map);
  writefln(%s, trait2.map);
  // above code compiles and works
}


Re: Template with template?

2014-03-20 Thread Vladimir Panteleev

On Thursday, 20 March 2014 at 16:28:46 UTC, Chris wrote:
How can I instantiate Person with Trait, i.e. a template with a 
template?


struct Trait(T0, T1) {
  T0 name;
  T1 value;
  T1[T0] map;

  this(T0 name, T1 value) {
this.name = name;
this.value = value;
map[name] = value;
  }
}

class Person(T) {
  T traits[];

  void addTrait(T trait) {
traits ~= trait;
  }
}


void main()
{
  auto trait1 = Trait!(string, string)(Name, John);
  auto trait2 = Trait!(string, int)(Age, 42);
  writefln(%s, trait1.map);
  writefln(%s, trait2.map);
  // above code compiles and works
}


Person!(Trait!(string, string)) person;

-- or --

alias MyTrait = Trait!(string, string);
Person!MyTrait person;

Note that this approach won't let you have traits with different 
parameters within the same Person type.


Re: Template with template?

2014-03-20 Thread John Colvin

On Thursday, 20 March 2014 at 16:28:46 UTC, Chris wrote:
How can I instantiate Person with Trait, i.e. a template with a 
template?


struct Trait(T0, T1) {
  T0 name;
  T1 value;
  T1[T0] map;

  this(T0 name, T1 value) {
this.name = name;
this.value = value;
map[name] = value;
  }
}

class Person(T) {
  T traits[];

  void addTrait(T trait) {
traits ~= trait;
  }
}


void main()
{
  auto trait1 = Trait!(string, string)(Name, John);
  auto trait2 = Trait!(string, int)(Age, 42);
  writefln(%s, trait1.map);
  writefln(%s, trait2.map);
  // above code compiles and works
}


templates can be passed to templates as alias parameters, or as 
part of a TemplateArgumentTuple. See 
http://dlang.org/template.html#aliasparameters


Re: Template with template?

2014-03-20 Thread Chris
On Thursday, 20 March 2014 at 16:32:34 UTC, Vladimir Panteleev 
wrote:

On Thursday, 20 March 2014 at 16:28:46 UTC, Chris wrote:
How can I instantiate Person with Trait, i.e. a template with 
a template?


struct Trait(T0, T1) {
 T0 name;
 T1 value;
 T1[T0] map;

 this(T0 name, T1 value) {
   this.name = name;
   this.value = value;
   map[name] = value;
 }
}

class Person(T) {
 T traits[];

 void addTrait(T trait) {
   traits ~= trait;
 }
}


void main()
{
 auto trait1 = Trait!(string, string)(Name, John);
 auto trait2 = Trait!(string, int)(Age, 42);
 writefln(%s, trait1.map);
 writefln(%s, trait2.map);
 // above code compiles and works
}


Person!(Trait!(string, string)) person;

-- or --

alias MyTrait = Trait!(string, string);
Person!MyTrait person;

Note that this approach won't let you have traits with 
different parameters within the same Person type.


Yep, I've already tried this (sorry I should've mentioned it!). 
But I don't want this restriction.


bool Associative Array Synchronized

2014-03-20 Thread Etienne

I'd like to cowboy it on an AA that looks like this:

__gshared bool[string] m_mutex;

I think it'll be much faster for my code because this AA could need to 
be checked and switched possibly millions of times per second and I 
wouldn't want to slow it down with a mutex protecting it.


I'm thinking the bool would be synchronized at the hardware level 
anyway, since it's just a bit being flipped or returned. Am I right to 
assume this and (maybe an assembly guru can answer) it safe to use?


Thanks


Re: Template with template?

2014-03-20 Thread John Colvin

On Thursday, 20 March 2014 at 16:40:50 UTC, Chris wrote:
On Thursday, 20 March 2014 at 16:32:34 UTC, Vladimir Panteleev 
wrote:

On Thursday, 20 March 2014 at 16:28:46 UTC, Chris wrote:
How can I instantiate Person with Trait, i.e. a template with 
a template?


struct Trait(T0, T1) {
T0 name;
T1 value;
T1[T0] map;

this(T0 name, T1 value) {
  this.name = name;
  this.value = value;
  map[name] = value;
}
}

class Person(T) {
T traits[];

void addTrait(T trait) {
  traits ~= trait;
}
}


void main()
{
auto trait1 = Trait!(string, string)(Name, John);
auto trait2 = Trait!(string, int)(Age, 42);
writefln(%s, trait1.map);
writefln(%s, trait2.map);
// above code compiles and works
}


Person!(Trait!(string, string)) person;

-- or --

alias MyTrait = Trait!(string, string);
Person!MyTrait person;

Note that this approach won't let you have traits with 
different parameters within the same Person type.


Yep, I've already tried this (sorry I should've mentioned it!). 
But I don't want this restriction.


Arrays are homogeneous. All the elements must be of the same 
type. Different instantiations of templates are different types.


You could use an array of std.variant.Variant


Re: bool Associative Array Synchronized

2014-03-20 Thread Steven Schveighoffer

On Thu, 20 Mar 2014 13:43:58 -0400, Etienne etci...@gmail.com wrote:


I'd like to cowboy it on an AA that looks like this:

__gshared bool[string] m_mutex;

I think it'll be much faster for my code because this AA could need to  
be checked and switched possibly millions of times per second and I  
wouldn't want to slow it down with a mutex protecting it.


I'm thinking the bool would be synchronized at the hardware level  
anyway, since it's just a bit being flipped or returned. Am I right to  
assume this and (maybe an assembly guru can answer) it safe to use?


No, it's not safe. With memory reordering, there is no safe unless you  
use mutexes or low-level atomics.


Long story short, the compiler, the processor, or the memory cache can  
effectively reorder operations, making one thread see things happen in a  
different order than they are written/executed on another thread. There  
are no guarantees.


-Steve


Re: bool Associative Array Synchronized

2014-03-20 Thread John Colvin

On Thursday, 20 March 2014 at 17:43:58 UTC, Etienne wrote:

I'd like to cowboy it on an AA that looks like this:

__gshared bool[string] m_mutex;

I think it'll be much faster for my code because this AA could 
need to be checked and switched possibly millions of times per 
second and I wouldn't want to slow it down with a mutex 
protecting it.


I'm thinking the bool would be synchronized at the hardware 
level anyway, since it's just a bit being flipped or returned. 
Am I right to assume this and (maybe an assembly guru can 
answer) it safe to use?


Thanks


On x86 only?

If all you do is read/write from/to each location then you are 
guaranteed atomicity. Adding/removing members? Forget it


Also, atomicity is not a strong enough guarantee for implementing 
a mutex, which is what I assume you are trying to do. You need 
ordering guarantees as well.


Watch both of these:

http://channel9.msdn.com/Shows/Going+Deep/Cpp-and-Beyond-2012-Herb-Sutter-atomic-Weapons-1-of-2
http://channel9.msdn.com/Shows/Going+Deep/Cpp-and-Beyond-2012-Herb-Sutter-atomic-Weapons-2-of-2

and then look at core.atomic

and then give up and use a lock :p


Re: Template with template?

2014-03-20 Thread Adam D. Ruppe
Or make trait a class, storing the interface and passing the 
trait to the new Person in the constructor.


Re: bool Associative Array Synchronized

2014-03-20 Thread Etienne

On 2014-03-20 1:52 PM, Steven Schveighoffer wrote:

On Thu, 20 Mar 2014 13:43:58 -0400, Etienne etci...@gmail.com wrote:


I'd like to cowboy it on an AA that looks like this:

__gshared bool[string] m_mutex;

I think it'll be much faster for my code because this AA could need to
be checked and switched possibly millions of times per second and I
wouldn't want to slow it down with a mutex protecting it.

I'm thinking the bool would be synchronized at the hardware level
anyway, since it's just a bit being flipped or returned. Am I right to
assume this and (maybe an assembly guru can answer) it safe to use?


No, it's not safe. With memory reordering, there is no safe unless you
use mutexes or low-level atomics.

Long story short, the compiler, the processor, or the memory cache can
effectively reorder operations, making one thread see things happen in a
different order than they are written/executed on another thread. There
are no guarantees.

-Steve


Right, I was assuming it was always ordered, but modern processor 
pipelines are different I guess.


Re: bool Associative Array Synchronized

2014-03-20 Thread Etienne

On 2014-03-20 1:58 PM, John Colvin wrote:


Also, atomicity is not a strong enough guarantee for implementing a
mutex, which is what I assume you are trying to do. You need ordering
guarantees as well.


Heh. Will do!


Re: bool Associative Array Synchronized

2014-03-20 Thread Chris Williams

On Thursday, 20 March 2014 at 18:06:18 UTC, Etienne wrote:
Right, I was assuming it was always ordered, but modern 
processor pipelines are different I guess.


Even without rearranging the order of your code, your bit exists 
in RAM but all the logic takes place in a CPU register, meaning 
that any time you operate with the bit, there's at least two 
copies. When the CPU switches threads (which could be at any 
point), it empties the CPU into RAM. If the thread it's switching 
to then tries to interact with the bit, it's going to create a 
third copy. Now whichever of the two threads is slower to write 
back to the original location is going to smash the other's.


Re: Template with template?

2014-03-20 Thread Chris

On Thursday, 20 March 2014 at 17:49:52 UTC, John Colvin wrote:

On Thursday, 20 March 2014 at 16:40:50 UTC, Chris wrote:
On Thursday, 20 March 2014 at 16:32:34 UTC, Vladimir Panteleev 
wrote:

On Thursday, 20 March 2014 at 16:28:46 UTC, Chris wrote:
How can I instantiate Person with Trait, i.e. a template 
with a template?


struct Trait(T0, T1) {
T0 name;
T1 value;
T1[T0] map;

this(T0 name, T1 value) {
 this.name = name;
 this.value = value;
 map[name] = value;
}
}

class Person(T) {
T traits[];

void addTrait(T trait) {
 traits ~= trait;
}
}


void main()
{
auto trait1 = Trait!(string, string)(Name, John);
auto trait2 = Trait!(string, int)(Age, 42);
writefln(%s, trait1.map);
writefln(%s, trait2.map);
// above code compiles and works
}


Person!(Trait!(string, string)) person;

-- or --

alias MyTrait = Trait!(string, string);
Person!MyTrait person;

Note that this approach won't let you have traits with 
different parameters within the same Person type.


Yep, I've already tried this (sorry I should've mentioned 
it!). But I don't want this restriction.


Arrays are homogeneous. All the elements must be of the same 
type. Different instantiations of templates are different types.


You could use an array of std.variant.Variant


The elements are all of type Trait. However, Type itself might be
of different types. That's why it is not possible? I've come
across this restriction before when using templates, which is a
big disappointment because it restricts the templatization /
generalization of data structures somewhat.


Re: bool Associative Array Synchronized

2014-03-20 Thread H. S. Teoh
On Thu, Mar 20, 2014 at 06:39:10PM +, Chris Williams wrote:
 On Thursday, 20 March 2014 at 18:06:18 UTC, Etienne wrote:
 Right, I was assuming it was always ordered, but modern processor
 pipelines are different I guess.
 
 Even without rearranging the order of your code, your bit exists in
 RAM but all the logic takes place in a CPU register, meaning that
 any time you operate with the bit, there's at least two copies. When
 the CPU switches threads (which could be at any point), it empties
 the CPU into RAM. If the thread it's switching to then tries to
 interact with the bit, it's going to create a third copy. Now
 whichever of the two threads is slower to write back to the original
 location is going to smash the other's.

Furthermore, the CPU does not access bits directly; it processes them as
(at least) bytes. To set/clear a bit in memory location X, the CPU has
to first read X into a register (at least 8 bits long), update the bit,
and write it back into memory. If two threads are simultaneously
operating on different bits that resides in the same byte, whichever CPU
runs last will smash whatever the first CPU wrote.

Let's say you start with b in location X, and CPU1 wants to set
the first bit and CPU2 wants to set the second bit. Both CPU's initially
reads b into their registers, then the first CPU sets the first
bit, so it becomes 0001b (in register) and the second CPU sets the
second bit so it becomes 0010b (in register). Now CPU1 writes
0001b back to memory, followed by CPU2 writing 0010b back to
memory. Now what CPU1 did has been smashed by CPU2's write.

Now, the current AA implementation doesn't actually pack bits like this,
so this particular problem doesn't actually happen, but other similar
problems will occur if you add/remove keys from the AA -- two CPU's will
try to update internal AA pointers simultaneously, and end up trashing
it.


T

-- 
What doesn't kill me makes me stranger.


Re: Template with template?

2014-03-20 Thread John Colvin

On Thursday, 20 March 2014 at 18:39:32 UTC, Chris wrote:

On Thursday, 20 March 2014 at 17:49:52 UTC, John Colvin wrote:

On Thursday, 20 March 2014 at 16:40:50 UTC, Chris wrote:
On Thursday, 20 March 2014 at 16:32:34 UTC, Vladimir 
Panteleev wrote:

On Thursday, 20 March 2014 at 16:28:46 UTC, Chris wrote:
How can I instantiate Person with Trait, i.e. a template 
with a template?


struct Trait(T0, T1) {
T0 name;
T1 value;
T1[T0] map;

this(T0 name, T1 value) {
this.name = name;
this.value = value;
map[name] = value;
}
}

class Person(T) {
T traits[];

void addTrait(T trait) {
traits ~= trait;
}
}


void main()
{
auto trait1 = Trait!(string, string)(Name, John);
auto trait2 = Trait!(string, int)(Age, 42);
writefln(%s, trait1.map);
writefln(%s, trait2.map);
// above code compiles and works
}


Person!(Trait!(string, string)) person;

-- or --

alias MyTrait = Trait!(string, string);
Person!MyTrait person;

Note that this approach won't let you have traits with 
different parameters within the same Person type.


Yep, I've already tried this (sorry I should've mentioned 
it!). But I don't want this restriction.


Arrays are homogeneous. All the elements must be of the same 
type. Different instantiations of templates are different 
types.


You could use an array of std.variant.Variant


The elements are all of type Trait. However, Type itself might 
be

of different types. That's why it is not possible? I've come
across this restriction before when using templates, which is a
big disappointment because it restricts the templatization /
generalization of data structures somewhat.


Trait is not a type. Trait is a template. An instantiation of the 
Trait template is a type.



Arrays are contiguous, homogeneous data. This is fundamental to 
their design and their performance characteristics.
Workarounds use at least one of the following: indirection, 
tagging* and padding. Variant uses tagging and padding. 
Interface/base-class arrays use indirection (and tagging, 
ultimately).


*inline or external, or even compile-time.

This is true in *every* programming language, just with different 
names.


Re: Template with template?

2014-03-20 Thread Chris

On Thursday, 20 March 2014 at 18:54:30 UTC, John Colvin wrote:

On Thursday, 20 March 2014 at 18:39:32 UTC, Chris wrote:

On Thursday, 20 March 2014 at 17:49:52 UTC, John Colvin wrote:

On Thursday, 20 March 2014 at 16:40:50 UTC, Chris wrote:
On Thursday, 20 March 2014 at 16:32:34 UTC, Vladimir 
Panteleev wrote:

On Thursday, 20 March 2014 at 16:28:46 UTC, Chris wrote:
How can I instantiate Person with Trait, i.e. a template 
with a template?


struct Trait(T0, T1) {
T0 name;
T1 value;
T1[T0] map;

this(T0 name, T1 value) {
this.name = name;
this.value = value;
map[name] = value;
}
}

class Person(T) {
T traits[];

void addTrait(T trait) {
traits ~= trait;
}
}


void main()
{
auto trait1 = Trait!(string, string)(Name, John);
auto trait2 = Trait!(string, int)(Age, 42);
writefln(%s, trait1.map);
writefln(%s, trait2.map);
// above code compiles and works
}


Person!(Trait!(string, string)) person;

-- or --

alias MyTrait = Trait!(string, string);
Person!MyTrait person;

Note that this approach won't let you have traits with 
different parameters within the same Person type.


Yep, I've already tried this (sorry I should've mentioned 
it!). But I don't want this restriction.


Arrays are homogeneous. All the elements must be of the same 
type. Different instantiations of templates are different 
types.


You could use an array of std.variant.Variant


The elements are all of type Trait. However, Type itself might 
be

of different types. That's why it is not possible? I've come
across this restriction before when using templates, which is a
big disappointment because it restricts the templatization /
generalization of data structures somewhat.


Trait is not a type. Trait is a template. An instantiation of 
the Trait template is a type.



Arrays are contiguous, homogeneous data. This is fundamental to 
their design and their performance characteristics.
Workarounds use at least one of the following: indirection, 
tagging* and padding. Variant uses tagging and padding. 
Interface/base-class arrays use indirection (and tagging, 
ultimately).


*inline or external, or even compile-time.

This is true in *every* programming language, just with 
different names.


I thought the array T[] traits could hold any _type_ the template 
Trait is instantiated into. That's where I got it wrong. I 
understand the practical aspects of this restriction (homogeneous 
data, performance and the work around involved etc.). However, 
this makes templates less universal and rather cumbersome to work 
with in certain circumstances. Take for example the Person class. 
If I want to do numerical operations with the age of the person, 
I will have to convert the age to an int (or whatever) later on 
instead of just doing it once at the beginning (when loading 
data). So everytime I access Trait.map[age] I will have to 
convert it to a number before I can calculate anything. This, or 
I store it in a field of its own when instantiating Trait. 
Whatever workaround I choose it will make it less elegant and 
less simple.


Maybe I expect(ed) to much of templates. Mea culpa.


Re: Template with template?

2014-03-20 Thread Philippe Sigaud



 I thought the array T[] traits could hold any _type_ the template Trait is
 instantiated into.


Different instantiations of a template could become totally unrelated types
(heck, even things that are *not* types: function definitions, values, code
blocks, ...). So there is now way for an array could hold them all, in
general.

At their core, templates are just parameterized code blocks, that become
whatever strikes your fancy.


Re: Template with template?

2014-03-20 Thread Meta

On Thursday, 20 March 2014 at 19:38:25 UTC, Chris wrote:
I thought the array T[] traits could hold any _type_ the 
template Trait is instantiated into. That's where I got it 
wrong.


This is the best explanation for this restriction that I can 
think of:


struct Person(T)
{
static if (is(T == int))
{
int age;
@property int age() { return age; }
@property int age(int val) { return age = val; }

@property bool isMiddleAge() { return age = 30  age = 
50); }

}
else static if (is(T == string))
{
string name;
//Etc...
}
}

Depending on what type T is, Person could have an age and 
associated methods, or a name and associated methods, but never 
both. If T is neither int nor string, it will completely empty. 
Therefore, Person!int MUST be a completely different type from 
Person!string or Person!float. It just doesn't make any sense 
otherwise.


Re: Template with template?

2014-03-20 Thread John Colvin

On Thursday, 20 March 2014 at 19:38:25 UTC, Chris wrote:

On Thursday, 20 March 2014 at 18:54:30 UTC, John Colvin wrote:

On Thursday, 20 March 2014 at 18:39:32 UTC, Chris wrote:

On Thursday, 20 March 2014 at 17:49:52 UTC, John Colvin wrote:

On Thursday, 20 March 2014 at 16:40:50 UTC, Chris wrote:
On Thursday, 20 March 2014 at 16:32:34 UTC, Vladimir 
Panteleev wrote:

On Thursday, 20 March 2014 at 16:28:46 UTC, Chris wrote:
How can I instantiate Person with Trait, i.e. a template 
with a template?


struct Trait(T0, T1) {
T0 name;
T1 value;
T1[T0] map;

this(T0 name, T1 value) {
this.name = name;
this.value = value;
map[name] = value;
}
}

class Person(T) {
T traits[];

void addTrait(T trait) {
traits ~= trait;
}
}


void main()
{
auto trait1 = Trait!(string, string)(Name, John);
auto trait2 = Trait!(string, int)(Age, 42);
writefln(%s, trait1.map);
writefln(%s, trait2.map);
// above code compiles and works
}


Person!(Trait!(string, string)) person;

-- or --

alias MyTrait = Trait!(string, string);
Person!MyTrait person;

Note that this approach won't let you have traits with 
different parameters within the same Person type.


Yep, I've already tried this (sorry I should've mentioned 
it!). But I don't want this restriction.


Arrays are homogeneous. All the elements must be of the same 
type. Different instantiations of templates are different 
types.


You could use an array of std.variant.Variant


The elements are all of type Trait. However, Type itself 
might be

of different types. That's why it is not possible? I've come
across this restriction before when using templates, which is 
a

big disappointment because it restricts the templatization /
generalization of data structures somewhat.


Trait is not a type. Trait is a template. An instantiation of 
the Trait template is a type.



Arrays are contiguous, homogeneous data. This is fundamental 
to their design and their performance characteristics.
Workarounds use at least one of the following: indirection, 
tagging* and padding. Variant uses tagging and padding. 
Interface/base-class arrays use indirection (and tagging, 
ultimately).


*inline or external, or even compile-time.

This is true in *every* programming language, just with 
different names.


I thought the array T[] traits could hold any _type_ the 
template Trait is instantiated into. That's where I got it 
wrong. I understand the practical aspects of this restriction 
(homogeneous data, performance and the work around involved 
etc.). However, this makes templates less universal and rather 
cumbersome to work with in certain circumstances. Take for 
example the Person class. If I want to do numerical operations 
with the age of the person, I will have to convert the age to 
an int (or whatever) later on instead of just doing it once at 
the beginning (when loading data). So everytime I access 
Trait.map[age] I will have to convert it to a number before I 
can calculate anything. This, or I store it in a field of its 
own when instantiating Trait. Whatever workaround I choose it 
will make it less elegant and less simple.


Maybe I expect(ed) to much of templates. Mea culpa.


Try this:

import std.stdio;
import std.variant;

enum maxTraitSize = 64;

struct Trait(T0, T1)
{
T0 name;
T1 value;
T1[T0] map;

	static assert(T0.sizeof + T1.sizeof + (T1[T0]).sizeof = 
maxTraitSize);


this(T0 name, T1 value)
{
this.name = name;
this.value = value;
map[name] = value;
}
}

class Person
{
alias ElT = VariantN!maxTraitSize;
ElT[] traits;

void addTrait(T)(T trait)
if(is(T == Trait!Q, Q...))
{
traits ~= ElT(trait);
}
}

void main()
{
auto trait1 = Trait!(string, string)(Name, John);
auto trait2 = Trait!(string, int)(Age, 42);
writefln(%s, trait1.map);
writefln(%s, trait2.map);

auto p = new Person;
p.addTrait(trait1);
p.addTrait(trait2);
writeln(p.traits);
}


  1   2   >