Re: How to sort a range

2016-03-09 Thread Ali Çehreli via Digitalmars-d-learn

On 03/09/2016 06:50 PM, rcorre wrote:

> sort calls to quicksort (for unstable, at least) which uses
> swapAt. swapAt takes the range by value, so it just swaps the values in
> its local copy.

Remembering that a range is not the collection, swapAt takes the range 
by value but it does not copy the elements. So, sort() does sort the 
original array:


import std.algorithm;

void main() {
auto a = [ 9, -1, 2, 0 ];
a.sort();
assert(a == [ -1, 0, 2, 9 ]);
}

> The original OnlyResult is untouched. I guess a static
> array slice maintains a pointer to the underlying array (which is why
> returning one from a function errors with 'escaping reference to local
> variable').

Yes: A static array is just a collection of elements, which implicitly 
converts to a slice and a slice is nothing but a pair of "pointer to the 
first element" and "number of elements".


Ali



Re: How to import for mixin contents only.

2016-03-09 Thread Taylor Hillegeist via Digitalmars-d-learn

On Thursday, 10 March 2016 at 04:56:52 UTC, Mike Parker wrote:
On Thursday, 10 March 2016 at 04:07:54 UTC, Taylor Hillegeist 
wrote:
So i want bitfields for just a little bit. but i dont want its 
dependencies. How is it done. I have tried this. but it doesnt 
seem to work on gdc. :(


struct Color_t {
static if(__ctfe){
import std.bitmanip:bitfields;
}
mixin(bitfields!(
uint, "R",8,
uint, "G",   8,
uint, "B",8,
uint, "A", 8));
}


__ctfe is a runtime construct, not compile-time. It cannot be 
used with static if. More over, it's only available *inside* a 
function that is currently being executed in a compile-time 
context. It has no role outside of that.


What problem are you trying to solve here? I mean, what is the 
problem with whatever dependencies std.bitmanip:bitfields has 
that makes you only want to import it during compilation?


I am running on a MKL25Z development board. The output of the 
mixin works fine. but the dependencies of the 
std.bitmanip:bitfields are quite extensive. including 
std.format..etc


Re: How to import for mixin contents only.

2016-03-09 Thread Mike Parker via Digitalmars-d-learn
On Thursday, 10 March 2016 at 04:07:54 UTC, Taylor Hillegeist 
wrote:
So i want bitfields for just a little bit. but i dont want its 
dependencies. How is it done. I have tried this. but it doesnt 
seem to work on gdc. :(


struct Color_t {
static if(__ctfe){
import std.bitmanip:bitfields;
}
mixin(bitfields!(
uint, "R",8,
uint, "G",   8,
uint, "B",8,
uint, "A", 8));
}


__ctfe is a runtime construct, not compile-time. It cannot be 
used with static if. More over, it's only available *inside* a 
function that is currently being executed in a compile-time 
context. It has no role outside of that.


What problem are you trying to solve here? I mean, what is the 
problem with whatever dependencies std.bitmanip:bitfields has 
that makes you only want to import it during compilation?


How to import for mixin contents only.

2016-03-09 Thread Taylor Hillegeist via Digitalmars-d-learn
So i want bitfields for just a little bit. but i dont want its 
dependencies. How is it done. I have tried this. but it doesnt 
seem to work on gdc. :(


struct Color_t {
static if(__ctfe){
import std.bitmanip:bitfields;
}
mixin(bitfields!(
uint, "R",8,
uint, "G",   8,
uint, "B",8,
uint, "A", 8));
}


Re: How to sort a range

2016-03-09 Thread rcorre via Digitalmars-d-learn

On Wednesday, 9 March 2016 at 16:53:08 UTC, Xinok wrote:

On Wednesday, 9 March 2016 at 15:39:55 UTC, rcorre wrote:
Still curious as to why it fails; maybe the range is getting 
copied at some point? I guess I need to step through it.


That's my suspicion as well. It seems that OnlyResult is 
pass-by-value so every time it gets passed to another function, 
it creates a copy of all the elements. A simple solution is to 
provide a wrapper type which refers to the elements in the 
original container.


However, I'm going to argue that the sort function is fine but 
the modifications you made to OnlyResult are incorrect. I tried 
running your example of only(...).sort but got a compilation 
error. Similarly, trying to sort a static array also gives a 
compilation error. However, if I slice the static array before 
passing it to sort (thus passing by reference), then it works 
just fine.


Got it. sort calls to quicksort (for unstable, at least) which 
uses swapAt. swapAt takes the range by value, so it just swaps 
the values in its local copy. The original OnlyResult is 
untouched. I guess a static array slice maintains a pointer to 
the underlying array (which is why returning one from a function 
errors with 'escaping reference to local variable').


Meanwhile, I've realized my code probably doensn't need to remove 
duplicates anyways, so its a moot point, but still an interesting 
discovery :)


Re: Is it safe to use 'is' to compare types?

2016-03-09 Thread H. S. Teoh via Digitalmars-d-learn
On Thu, Mar 10, 2016 at 01:33:41AM +, Yuxuan Shui via Digitalmars-d-learn 
wrote:
> On Wednesday, 9 March 2016 at 22:26:38 UTC, Ali Çehreli wrote:
> >On 03/09/2016 07:05 AM, Yuxuan Shui wrote:
> >
> >> Can we left TypeInfo symbol undefined in the shared libraries? i.e.
> >> D compiler will strip out TypeInfo definition when creating .so.
> >> (Alternatively, we can have TypeInfo always undefined in .o, and
> >> generate them in linking stage only when creating executables)
> >
> >That would require a linker that's aware of D but as far as I know,
> >all system languages use the system linker.
> >
> >Ali
> 
> Hmm, how about this:
> 
> During compilation, D generate undefined TypeInfo symbols, but it also
> embed type information in the object file (like what Rust does). And
> then, when dmd/ldc/gdc/whatever is called for linking executables, it
> will scan object files and generate another object file containing the
> TypeInfos, and link them together with the system linker. If the
> compiler is called for linking shared libraries, it doesn't.

You can't rely on invoking the compiler to link these objects, because
if you're using shared libraries, it will be the OS's dynamic linker
that will get invoked to resolve the references, and different versions
of shared libraries may have a different set of TypeInfo's, and the
compiler may not be able to generate the required TypeInfo's.

A better way is to use the OS linker's "weak symbol" feature, where a
symbol is allowed to be defined multiple times (with identical content),
and the linker (both dynamic and static) will choose the first
definition that it finds.


T

-- 
Маленькие детки - маленькие бедки.


Re: Is it safe to use 'is' to compare types?

2016-03-09 Thread Yuxuan Shui via Digitalmars-d-learn

On Wednesday, 9 March 2016 at 22:26:38 UTC, Ali Çehreli wrote:

On 03/09/2016 07:05 AM, Yuxuan Shui wrote:

> Can we left TypeInfo symbol undefined in the shared
libraries? i.e. D
> compiler will strip out TypeInfo definition when creating .so.
> (Alternatively, we can have TypeInfo always undefined in .o,
and
> generate them in linking stage only when creating executables)

That would require a linker that's aware of D but as far as I 
know, all system languages use the system linker.


Ali


Hmm, how about this:

During compilation, D generate undefined TypeInfo symbols, but it 
also embed type information in the object file (like what Rust 
does). And then, when dmd/ldc/gdc/whatever is called for linking 
executables, it will scan object files and generate another 
object file containing the TypeInfos, and link them together with 
the system linker. If the compiler is called for linking shared 
libraries, it doesn't.


Re: Memory Efficient HashSet

2016-03-09 Thread Nordlöw via Digitalmars-d-learn
On Tuesday, 8 March 2016 at 12:25:36 UTC, Ola Fosheim Grøstad 
wrote:

On Tuesday, 8 March 2016 at 08:12:04 UTC, Nordlöw wrote:

sparse_hash_set<> contained in

https://github.com/sparsehash/sparsehash


It appears to be very slow?
What do you need it for?


My knowledge database engine I'm building cannot afford the 
memory overhead of D's builtin associative arrays.


For instance the following program

void main(string[] args)
{
alias T = uint;
bool[T] x; // emulates a HashSet with significant memory 
overhead

import std.range : iota;
const n = 10_000_000;
foreach (const i; iota(0, n))
{
x[i] = true; // indicate that it's stored
}

import std.stdio : writeln, readln;
writeln("Press return: ");
readln;
}

consumes 842.m MiB on my Ubuntu.

The consumption with Google's sparsehash unordered_set is about 
50 MiB.


Re: Is it safe to use 'is' to compare types?

2016-03-09 Thread Ali Çehreli via Digitalmars-d-learn

On 03/09/2016 07:05 AM, Yuxuan Shui wrote:

> Can we left TypeInfo symbol undefined in the shared libraries? i.e. D
> compiler will strip out TypeInfo definition when creating .so.
> (Alternatively, we can have TypeInfo always undefined in .o, and
> generate them in linking stage only when creating executables)

That would require a linker that's aware of D but as far as I know, all 
system languages use the system linker.


Ali



Re: Use of GUID constants

2016-03-09 Thread Ali Çehreli via Digitalmars-d-learn

On 03/09/2016 10:35 AM, KlausO wrote:

>  IUnknown pUnk;
>
>  //
>  // Does not compile:
>  //
>  //  Error: function
> core.sys.windows.unknwn.IUnknown.QueryInterface(const(GUID)* riid,
> void** pvObject) is not callable using argument types (const(GUID), 
void**)

>  //
>  hr = storage.QueryInterface(IID_IUnknown, cast(void**));

Without any experience with COM or (current) Windows programming, just 
by looking at that error message, the following may work:


IID unknown = IID_IUnknown;
// (Apparently, IID is an alias for const(GUID).)

storage.QueryInterface(, /* ... */);

Ali



Re: Trying to build a Scheme interpreter in D

2016-03-09 Thread Guillaume Piolat via Digitalmars-d-learn

On Tuesday, 8 March 2016 at 18:11:24 UTC, John wrote:


* For this kind of implementation, is the Algebraic type a good 
choice ? Is a simple union perhaps better ?


You can go with Algebraic. I used to do that in scheme-d. Then I 
switched to a tagged union by hand to avoid a compiler 
regression. Algebraic was OK.



* I've defined the (recursive) Fibonacci function, for which 
DMD takes 30sec to calculate Fibonacci(30) and LDC takes 10sec. 
Is this a reasonable difference between the two compilers?


2x speed difference between DMD and LDC is common.


* I find it very difficult (actually impossible) to profile 
code in Mac OS X. There is no output for options -profile. Are 
there any other profiling/debugging tools for the Mac OS X ? My 
other ports (C++, Scala) run interpret the same example in 
under 2sec, so I would like to detect where my bottlenecks are.


Thanks.


You can build with -g and use Instruments.


Re: What can _not_ be marked pure?

2016-03-09 Thread H. S. Teoh via Digitalmars-d-learn
On Wed, Mar 09, 2016 at 05:12:18AM -0800, Jonathan M Davis via 
Digitalmars-d-learn wrote:
[...]
> So, in general, you can slap pure on most anything, though it will
> rarely buy you anything in terms of performance.

IMO, this is an area where the compiler could be improved to take better
advantage of pure annotations. The currently-implemented optimizations
based on pure, while nice, are also relatively rare, and don't seem to
outweigh the cost of having to annotate large numbers of functions by
hand.

I think one area where pure could potentially have a large gain is in
loop optimization, where pure annotations may help in increasing the
amount of code that can be hoisted out of the loop. Contrived example:

long veryExpensiveFunction(T)(T arg) pure { ... }
long func(long x) {
long accum;
foreach (i; 0 .. 1_000_000) {
accum += i*veryExpensiveFunction(x);
}
return accum;
}

If veryExpensiveFunction() is not pure, we cannot hoist it out of the
loop, since it may change the program's semantics. However, if it's
pure, we can potentially have a large performance gain by hoisting it
outside the loop.

(One may argue that a good programmer would already do this manually, of
course, but the thing about these kinds of loop optimizations is that
they often exhibit domino-effects, where the above code snippet isn't
what the programmer actually wrote, but the result of a previous
optimization on the original code, say an inlining, or some such. Having
the compiler detect this case may then lead to more optimization
opportunities downstream. While dmd is, IME, rather poor at following
these optimization domino chains, gdc's optimizer has a lot of
aggressive loop optimizations, and may be able to do much better than it
can now if the frontend can feed this kind of information about purity
to it.)


[...]
> The reason to avoid pure with templated functions is that whether a
> templated function can really be pure or not usually depends on its
> arguments.

I think a useful pattern that has emerged in Phobos code is that all
template functions, in general, should have no attributes -- it should
be left to the compiler to infer them. To ensure that the code itself
doesn't break purity (etc.), use a pure (etc.) unittest:

auto func(T)(T args)
// N.B.: no attributes
{
...
}

pure unittest
{
// We know that int will not introduce impurity to
// func(), so this unittest will break if func itself
// contains impure code aside from its template
// arguments.
func(1);
}

This way, we ensure that the compiler will infer func as pure whenever
it can, yet we don't restrict T to be also pure (in the case where T is
impure, the compiler will correctly infer func!T as impure).

Attribute inference is the way of the future.


T

-- 
Let's eat some disquits while we format the biskettes.


Use of GUID constants

2016-03-09 Thread KlausO via Digitalmars-d-learn

Dear list,

I use DMD 2.070.0 I try to access COM Interfaces via the declarations in 
core.sys.windows.*

I have some problems and maybe someone could give me a usage hint.
Have a look at the following (relatively meaningless) sample program 
which demonstrates the problem.


IMHO the problem is that GUID constants are declared as enums in the
winapi bindings (see src\druntime\import\core\sys\windows\uuid.d).
Within the dclient.d sample which comes with dmd they are explicitely
defined as GUIDs:

GUID IID_IHello  = { 0x00421140, 0, 0, [0xC0, 0, 0, 0, 0, 0, 0, 0x46] };

So maybe they should be declared as "extern GUID ..." because they also 
seem to be defined in windows\lib\uuid.lib which comes with DMD.

What do you think ?

Thanks

-- KlausO


Sample program:


import std.stdio;
import std.utf;
import core.stdc.stdlib;

import core.sys.windows.windows;
import core.sys.windows.com;
import core.sys.windows.objidl;

bool CreateCompoundDoc(const wstring filename)
{
IStorage storage;

HRESULT hr = StgCreateDocfile( toUTF16z(filename),
   STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_DIRECT | 
STGM_CREATE,

   0,
  );

if (S_OK == hr)
{
IUnknown pUnk;

//
// Does not compile:
//
		//  Error: function 
core.sys.windows.unknwn.IUnknown.QueryInterface(const(GUID)* riid, 
void** pvObject) is not callable using argument types (const(GUID), void**)

//
hr = storage.QueryInterface(IID_IUnknown, cast(void**));

//
// Does not compile either:
//
		// Error: GUID(0u, cast(ushort)0u, cast(ushort)0u, [cast(ubyte)192u, 
cast(ubyte)0u, cast(ubyte)0u, cast(ubyte)0u, cast(ubyte)0u, 
cast(ubyte)0u, cast(ubyte)0u, cast(ubyte)70u]) is not an lvalue

//
hr = storage.QueryInterface(_IUnknown, cast(void**));
}
}

int main(string[] argv)
{
HRESULT hr=CoInitialize(null); // Initialize OLE
if (FAILED(hr))
{
printf("OLE 2 failed to initialize\n");
return EXIT_FAILURE;
}

CreateCompoundDoc("hello.doc");

// Only call this if CoInitialize worked
CoUninitialize();
return EXIT_SUCCESS;
}



Re: GC scan for pointers

2016-03-09 Thread Chris Wright via Digitalmars-d-learn
On Wed, 09 Mar 2016 15:50:43 +, Adam D. Ruppe wrote:
> Or static
> arrays of int on the stack will also be scanned, since the GC doesn't
> actually know much about local variables

It's especially tricky because compilers can reuse memory on the stack 
--  for instance, if I use one variable in the first half of a function, 
stop using that variable, and start using another one, the compiler can 
save me some stack space by putting them at the same address.

Plus it's a bit more straightforward to make a performant check for 
whether a type might be a pointer than for whether a stackframe might 
have a pointer. With types, it takes one pointer dereference. With 
stackframes, you have to look through some dictionary stored somewhere.


Re: How to sort a range

2016-03-09 Thread Chris Wright via Digitalmars-d-learn
On Wed, 09 Mar 2016 14:28:11 +, cym13 wrote:

> Note that an input range isn't even remotely a container

Which is why sort() has template constraints beyond isInputRange. The 
constraints ensure that it is possible to swap values in the range.


Re: How to sort a range

2016-03-09 Thread Xinok via Digitalmars-d-learn

On Wednesday, 9 March 2016 at 15:39:55 UTC, rcorre wrote:
Still curious as to why it fails; maybe the range is getting 
copied at some point? I guess I need to step through it.


That's my suspicion as well. It seems that OnlyResult is 
pass-by-value so every time it gets passed to another function, 
it creates a copy of all the elements. A simple solution is to 
provide a wrapper type which refers to the elements in the 
original container.


However, I'm going to argue that the sort function is fine but 
the modifications you made to OnlyResult are incorrect. I tried 
running your example of only(...).sort but got a compilation 
error. Similarly, trying to sort a static array also gives a 
compilation error. However, if I slice the static array before 
passing it to sort (thus passing by reference), then it works 
just fine.


Re: Cannot compile program with DMD built from source

2016-03-09 Thread Minas Mina via Digitalmars-d-learn

On Wednesday, 9 March 2016 at 16:13:38 UTC, Minas Mina wrote:
Hello, I have followed the instructions here 
(http://wiki.dlang.org/Starting_as_a_Contributor#POSIX) to 
install DMD, druntime and phobos from source.


My platform is Ubuntu 15.10 x64.

This is the error I get:
http://pastebin.com/kWCv0ymn


Sorry I didn't explain well. All 3 components (DMD, druntime and 
phobos) were built successfully. The error I posted above is when 
trying to compile this code:


import std.stdio;
import std.experimental.logger;

void main()
{
auto logger = new FileLogger("log");
logger.info("test");
}


Cannot compile program with DMD built from source

2016-03-09 Thread Minas Mina via Digitalmars-d-learn
Hello, I have followed the instructions here 
(http://wiki.dlang.org/Starting_as_a_Contributor#POSIX) to 
install DMD, druntime and phobos from source.


My platform is Ubuntu 15.10 x64.

This is the error I get:
http://pastebin.com/kWCv0ymn


Re: How to sort a range

2016-03-09 Thread rcorre via Digitalmars-d-learn

On Wednesday, 9 March 2016 at 14:28:11 UTC, cym13 wrote:


Note that an input range isn't even remotely a container, it's 
a way to iterate on a container. As you don't have all elements 
at hand you can't sort them, that's why you have to use array 
here.


Oh, I think it just clicked. I was thinking 'sort takes a range, 
so it must be used for sorting ranges', but I should have thought 
'sort takes a range so it can sort a container via a range over 
that container'.


Re: GC scan for pointers

2016-03-09 Thread Adam D. Ruppe via Digitalmars-d-learn

On Wednesday, 9 March 2016 at 15:14:02 UTC, Gerald Jansen wrote:
will the large memory blocks allocated for a, b and/or c 
actually be scanned for pointers to GC-allocated memory during 
a garbage collection? If so, why?


No. It knows that the type has no pointers in it, so it will not 
scan it for them.


If it was a struct with a pointer, it might be scanned though. Or 
static arrays of int on the stack will also be scanned, since the 
GC doesn't actually know much about local variables - it 
conservatively assumes anything on the stack might be a pointer.


But large arrays are rarely on the stack so I think it is an ok 
situation.


See the GC block attr flags:

http://dpldocs.info/experimental-docs/core.memory.GC.BlkAttr.html


Re: How to sort a range

2016-03-09 Thread Edwin van Leeuwen via Digitalmars-d-learn

On Wednesday, 9 March 2016 at 15:39:55 UTC, rcorre wrote:

On Wednesday, 9 March 2016 at 14:28:11 UTC, cym13 wrote:

Still curious as to why it fails; maybe the range is getting 
copied at some point? I guess I need to step through it.


I did try different SwapStrategies with no luck.


Since you are adapting phobos anyway you could try commenting out 
the assert and see what the result of the sort is. That might 
give you some clue:


//assert(isSorted!lessFun(r), "Failed to sort range of type " ~ 
Range.stringof);



Also I notice the line numbering is different in my sorted.d 
file. Did you test the latest version of dmd/phobos?





Re: How to sort a range

2016-03-09 Thread rcorre via Digitalmars-d-learn

On Wednesday, 9 March 2016 at 14:28:11 UTC, cym13 wrote:

On Wednesday, 9 March 2016 at 12:21:55 UTC, rcorre wrote:
On Wednesday, 9 March 2016 at 09:15:01 UTC, Edwin van Leeuwen 
wrote:


I'm not sure why your fix didn't work, but generally I work 
around this by converting the OnlyResult into an array:


import std.array : array;
assert(only(3,1,2).array.sort.equal(only(1,2,3)));


I'd like to avoid allocating here.


Note that an input range isn't even remotely a container, it's 
a way to iterate on a container. As you don't have all elements 
at hand you can't sort them, that's why you have to use array 
here.


In the general case, yes. However only is a range wrapper around 
a static array, and does have all elements at hand. Maybe I 
should just be using a static array...


Still curious as to why it fails; maybe the range is getting 
copied at some point? I guess I need to step through it.


I did try different SwapStrategies with no luck.


Re: Is it safe to use 'is' to compare types?

2016-03-09 Thread Yuxuan Shui via Digitalmars-d-learn

On Tuesday, 8 March 2016 at 23:13:32 UTC, Anon wrote:

On Tuesday, 8 March 2016 at 20:26:04 UTC, Yuxuan Shui wrote:

[...]


[Note: I phrase my answer in terms of Linux shared libraries 
(*.so) because D doesn't actually have proper Windows DLL 
support yet. The same would apply to DLLs, it just feels wrong 
describing functionality that doesn't exist.]


[...]


Can we left TypeInfo symbol undefined in the shared libraries? 
i.e. D compiler will strip out TypeInfo definition when creating 
.so. (Alternatively, we can have TypeInfo always undefined in .o, 
and generate them in linking stage only when creating executables)




GC scan for pointers

2016-03-09 Thread Gerald Jansen via Digitalmars-d-learn
I've studied [1] and [2] but don't understand everything there. 
Hence these dumb questions:


Given

  enum n = 100_000_000; // some big number
  auto a = new ulong[](n);
  auto b = new char[8][](n);
  struct S { ulong x; char[8] y; }
  auto c = new S[](n);

will the large memory blocks allocated for a, b and/or c actually 
be scanned for pointers to GC-allocated memory during a garbage 
collection? If so, why?


[1] 
http://p0nce.github.io/d-idioms/#How-the-D-Garbage-Collector-works

[2] http://dlang.org/garbage.html



Re: How to sort a range

2016-03-09 Thread cym13 via Digitalmars-d-learn

On Wednesday, 9 March 2016 at 12:21:55 UTC, rcorre wrote:
On Wednesday, 9 March 2016 at 09:15:01 UTC, Edwin van Leeuwen 
wrote:


I'm not sure why your fix didn't work, but generally I work 
around this by converting the OnlyResult into an array:


import std.array : array;
assert(only(3,1,2).array.sort.equal(only(1,2,3)));


I'd like to avoid allocating here.


Note that an input range isn't even remotely a container, it's a 
way to iterate on a container. As you don't have all elements at 
hand you can't sort them, that's why you have to use array here. 
If you don't want to allocate using the GC just allocate your own 
memory and store your range elements in it before sorting but 
sort has to have access to all elements one way or another.


Re: What can _not_ be marked pure?

2016-03-09 Thread Guillaume Piolat via Digitalmars-d-learn
On Wednesday, 9 March 2016 at 13:12:18 UTC, Jonathan M Davis 
wrote:


In general though, you should use pure wherever possible.

- Jonathan M Davis


Thanks for the detailed answer and gotchas.
It thought compilers would use pure in alias analysis to ensure 
everything did not mutate during a pure function call.


This topic is much more involved than it first seemed!

Reminds me of the quote: "I have yet to see any problem, however 
complicated, which, when you looked at it in the right way, did 
not become still more complicated."





Re: How to sort a range

2016-03-09 Thread Edwin van Leeuwen via Digitalmars-d-learn

On Wednesday, 9 March 2016 at 13:04:31 UTC, rcorre wrote:
On Wednesday, 9 March 2016 at 12:31:18 UTC, Edwin van Leeuwen 
wrote:

On Wednesday, 9 March 2016 at 12:21:55 UTC, rcorre wrote:
If you are looking for a lazy uniq that works on non sorted 
ranges, I implemented one not to long ago:

http://github.com/BlackEdder/ggplotd/blob/master/source/ggplotd/range.d


That sounds like the kind of thing I was looking for. I'll 
take a look, thanks!


Well that one does allocate, because it keeps track of which 
values have already been seen.


Yup, just noticed that >.<


Of course it only allocates when the actual result is used, so 
this will probably be more efficient if you only need a small 
number of unique results or need to keep the unsorted range 
around/intact. Sorting without allocating and then using uniq 
should indeed be more efficient in other cases.


Did you try different SwapStrategy values in your original?


Re: What can _not_ be marked pure?

2016-03-09 Thread Jonathan M Davis via Digitalmars-d-learn
On Wednesday, March 09, 2016 09:56:05 Guillaume Piolat via Digitalmars-d-learn 
wrote:
> If I understand purity correctly
> (http://klickverbot.at/blog/2012/05/purity-in-d/), every function
> out there can be marked pure as long as it doesn't modify
> globals, shared variables or do I/O?
>
> It seems more function can be marked pure that I previously
> thought.

Basically, a pure function cannot call a function which is not pure, and it
can't access any global or static variables which are mutable (or const if
the type has indirections - the variable has to be completely unchangeable
to be accessible). And that's it. shared has nothing to do with it one way
or the other, and I/O isn't explicitly forbidden, but not being able to
access mutable globals or non-pure functions naturally kills I/O. The
exception is that inside of debug{} blocks, purity is ignored, so you can do
I/O there, but it's intended purely for debugging purposes.

So, in general, you can slap pure on most anything, though it will rarely
buy you anything in terms of performance. What it primarily buys you is the
knowledge that you're not messing with global variables unless the
function's arguments give you access to them. The second major gain is that
in many cases, a pure function's return type can have its constancy
inferred, making it possible to allocate a mutable object inside of a pure
function, do whatever needs to be done to it to set it up, and then have it
implicitly converted to immutable when it's returned (for that to work
though, the compiler has to be able to guarantee that the return value
didn't come from any of the function arguments).

The main place where performance gains could take place would be in cases
where a pure function is called multiple times in the same expression with
the same arguments, and the compiler is able to determine that it's
impossible for those arguments to have been mutated between calls, allowing
the compiler to just make the call once and reuse the result. AFAIK, that
currently requires that the function parameters be immutable or implicitly
convertible to immutable, though in theory, it should be possible for const
parameters when the arguments are immutable. Regardless, it's occasionally
useful but not very often. Having lots of pure functions makes it easier to
have useful functions with immutable arguments, whereas when pure functions
always required that the parameters be immutable (or implicitly convertible
to immutable), the really couldn't do much. But the result is that most pure
functions can't really be optimized base on their purity.

The two places that you need to be careful with pure though are virtual
functions and templated functions. If a base class function is pure, then
the derived class overrides also have to be pure, whereas if the base class
function isn't pure, then the derived class function can't normally be pure
(it _might_ be able to be pure if it doesn't call the base class function).
So, when dealing with virtual functions, you have to be careful about
whether you want to avoid restricting virtual functions from being used in
pure code (by not marking the base class function pure) or whether you want
to restrict what derived class functions can do (by marking the base class
function pure).

The reason to avoid pure with templated functions is that whether a
templated function can really be pure or not usually depends on its
arguments. If the types it's instantiated with use pure functions, then it
can be pure, whereas if they don't, then it can't be. So, you'd have a
similar problem to that of virtual functions except that pure, nothrow, and
@safe are inferred for template functions, so if the function doesn't do
anything which makes it so that it can't be pure, the compiler should infer
it to be pure without you needing to mark it as pure.

In general though, you should use pure wherever possible.

- Jonathan M Davis



Re: How to sort a range

2016-03-09 Thread rcorre via Digitalmars-d-learn
On Wednesday, 9 March 2016 at 12:31:18 UTC, Edwin van Leeuwen 
wrote:

On Wednesday, 9 March 2016 at 12:21:55 UTC, rcorre wrote:
If you are looking for a lazy uniq that works on non sorted 
ranges, I implemented one not to long ago:

http://github.com/BlackEdder/ggplotd/blob/master/source/ggplotd/range.d


That sounds like the kind of thing I was looking for. I'll 
take a look, thanks!


Well that one does allocate, because it keeps track of which 
values have already been seen.


Yup, just noticed that >.<


Re: How to sort a range

2016-03-09 Thread Edwin van Leeuwen via Digitalmars-d-learn

On Wednesday, 9 March 2016 at 12:21:55 UTC, rcorre wrote:
If you are looking for a lazy uniq that works on non sorted 
ranges, I implemented one not to long ago:

http://github.com/BlackEdder/ggplotd/blob/master/source/ggplotd/range.d


That sounds like the kind of thing I was looking for. I'll take 
a look, thanks!


Well that one does allocate, because it keeps track of which 
values have already been seen.


Re: How to sort a range

2016-03-09 Thread rcorre via Digitalmars-d-learn
On Wednesday, 9 March 2016 at 09:15:01 UTC, Edwin van Leeuwen 
wrote:


I'm not sure why your fix didn't work, but generally I work 
around this by converting the OnlyResult into an array:


import std.array : array;
assert(only(3,1,2).array.sort.equal(only(1,2,3)));


I'd like to avoid allocating here.




If you are looking for a lazy uniq that works on non sorted 
ranges, I implemented one not to long ago:

http://github.com/BlackEdder/ggplotd/blob/master/source/ggplotd/range.d


That sounds like the kind of thing I was looking for. I'll take a 
look, thanks!




Re: What can _not_ be marked pure?

2016-03-09 Thread Daniel Kozak via Digitalmars-d-learn



Dne 9.3.2016 v 11:26 Guillaume Piolat via Digitalmars-d-learn napsal(a):

On Wednesday, 9 March 2016 at 10:08:33 UTC, ag0aep6g wrote:

On 09.03.2016 10:56, Guillaume Piolat wrote:

If I understand purity correctly
(http://klickverbot.at/blog/2012/05/purity-in-d/), every function out
there can be marked pure as long as it doesn't modify globals, shared
variables or do I/O?


Pure functions also can't *read* mutable globals. But then that's it, 
I think.


Thanks. Now I'm excited to spam it over my codebase and see the kind 
of speedup one can achieve.


I am not sure, but my guess is there will be no speed up :-).



Re: RAII and classes

2016-03-09 Thread John Colvin via Digitalmars-d-learn

On Wednesday, 9 March 2016 at 10:48:30 UTC, cym13 wrote:

On Wednesday, 9 March 2016 at 10:28:06 UTC, John Colvin wrote:
Potential for leaking references from alias this aside, is 
there some reason that I shouldn't do this for all my C++-like 
RAII needs:


class A
{
~this(){ import std.stdio; writeln("hello"); }
}

auto RAII(T)()
if (is(T == class))
{
struct Inner
{
private ubyte[__traits(classInstanceSize, T)] buff;
T c;
alias c this;

~this()
{
destroy(c);
}
}
Inner tmp;
import std.conv : emplace;
tmp.c = tmp.buff.emplace!T;
return tmp;
}

void main()
{
auto a = RAII!A;
}


That's almost literally what std.typecons.scoped does.


Ok, I forgot std.typecons.scoped, nothing to see here .


Re: RAII and classes

2016-03-09 Thread cym13 via Digitalmars-d-learn

On Wednesday, 9 March 2016 at 10:28:06 UTC, John Colvin wrote:
Potential for leaking references from alias this aside, is 
there some reason that I shouldn't do this for all my C++-like 
RAII needs:


class A
{
~this(){ import std.stdio; writeln("hello"); }
}

auto RAII(T)()
if (is(T == class))
{
struct Inner
{
private ubyte[__traits(classInstanceSize, T)] buff;
T c;
alias c this;

~this()
{
destroy(c);
}
}
Inner tmp;
import std.conv : emplace;
tmp.c = tmp.buff.emplace!T;
return tmp;
}

void main()
{
auto a = RAII!A;
}


That's almost literally what std.typecons.scoped does.


RAII and classes

2016-03-09 Thread John Colvin via Digitalmars-d-learn
Potential for leaking references from alias this aside, is there 
some reason that I shouldn't do this for all my C++-like RAII 
needs:


class A
{
~this(){ import std.stdio; writeln("hello"); }
}

auto RAII(T)()
if (is(T == class))
{
struct Inner
{
private ubyte[__traits(classInstanceSize, T)] buff;
T c;
alias c this;

~this()
{
destroy(c);
}
}
Inner tmp;
import std.conv : emplace;
tmp.c = tmp.buff.emplace!T;
return tmp;
}

void main()
{
auto a = RAII!A;
}


Re: What can _not_ be marked pure?

2016-03-09 Thread Guillaume Piolat via Digitalmars-d-learn

On Wednesday, 9 March 2016 at 10:08:33 UTC, ag0aep6g wrote:

On 09.03.2016 10:56, Guillaume Piolat wrote:

If I understand purity correctly
(http://klickverbot.at/blog/2012/05/purity-in-d/), every 
function out
there can be marked pure as long as it doesn't modify globals, 
shared

variables or do I/O?


Pure functions also can't *read* mutable globals. But then 
that's it, I think.


Thanks. Now I'm excited to spam it over my codebase and see the 
kind of speedup one can achieve.


Re: What can _not_ be marked pure?

2016-03-09 Thread ag0aep6g via Digitalmars-d-learn

On 09.03.2016 10:57, Guillaume Piolat wrote:

Another question that ensues is: will the compiler prevent incorrect use
of pure, so that it's safe to spam it in your code?


The compiler should catch wrong usage of `pure`, yes. Function 
declarations without implementation are an exception, of course. Same 
with `nothrow`, `@safe`, and `@nogc`. The compiler can't check 
`@trusted` for correctness, obviously.


Re: What can _not_ be marked pure?

2016-03-09 Thread ag0aep6g via Digitalmars-d-learn

On 09.03.2016 10:56, Guillaume Piolat wrote:

If I understand purity correctly
(http://klickverbot.at/blog/2012/05/purity-in-d/), every function out
there can be marked pure as long as it doesn't modify globals, shared
variables or do I/O?


Pure functions also can't *read* mutable globals. But then that's it, I 
think.


Re: What can _not_ be marked pure?

2016-03-09 Thread Guillaume Piolat via Digitalmars-d-learn
On Wednesday, 9 March 2016 at 09:56:05 UTC, Guillaume Piolat 
wrote:
If I understand purity correctly 
(http://klickverbot.at/blog/2012/05/purity-in-d/), every 
function out there can be marked pure as long as it doesn't 
modify globals, shared variables or do I/O?


It seems more function can be marked pure that I previously 
thought.


Another question that ensues is: will the compiler prevent 
incorrect use of pure, so that it's safe to spam it in your code?


What can _not_ be marked pure?

2016-03-09 Thread Guillaume Piolat via Digitalmars-d-learn
If I understand purity correctly 
(http://klickverbot.at/blog/2012/05/purity-in-d/), every function 
out there can be marked pure as long as it doesn't modify 
globals, shared variables or do I/O?


It seems more function can be marked pure that I previously 
thought.


Re: How to sort a range

2016-03-09 Thread Edwin van Leeuwen via Digitalmars-d-learn

On Wednesday, 9 March 2016 at 03:05:52 UTC, rcorre wrote:
I was in a situation where I wanted to remove duplicates from 
an OnlyResult.
To do this with uniq, I needed to sort it. OnlyResult doesn't 
satisfy the template constraints of sort, but this seems easy 
enough to fix. I made front, back, and opIndex return by ref. 
With this, the following compiles:


assert(only(3,1,2).sort.equal(only(1,2,3)));

However, it fails with:

core.exception.AssertError@std/algorithm/sorting.d(1052): 
Failed to sort range of type OnlyResult!(int, 3LU)


So, if you have a range for which sort compiles, what does it 
take to make sorting actually work?


For reference, my two attempts were:

https://github.com/rcorre/phobos/commit/d89b3cfab7a0938e178a506b4ceb8faae6ecbfe2

https://github.com/rcorre/phobos/commit/512d9b8db6f311db6a9b6ccb077a691cec66ce70


I'm not sure why your fix didn't work, but generally I work 
around this by converting the OnlyResult into an array:


import std.array : array;
assert(only(3,1,2).array.sort.equal(only(1,2,3)));


If you are looking for a lazy uniq that works on non sorted 
ranges, I implemented one not to long ago:

http://github.com/BlackEdder/ggplotd/blob/master/source/ggplotd/range.d