Re: How to sort a range
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.
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.
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.
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
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?
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?
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
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?
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
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
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?
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
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
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
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
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
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
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
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
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
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
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?
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
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
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?
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
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?
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
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
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
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?
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
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
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
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?
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?
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?
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?
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?
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
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