Re: Speed up `dub`.
On Sat, 2016-05-14 at 16:36 +, ciechowoj via Digitalmars-d-learn wrote: > On Monday, 7 March 2016 at 21:56:11 UTC, Seb wrote: > > > > Use ld.gold - it will speed up your linking quite dramatically! > > > > https://code.dawg.eu/reducing-vibed-turnaround-time-part-1-faster-l > > inking.html > Thanks, it improves things a little. However I've just had idea > that it should be possible to implement 'speculative dependency > checking' for dub. What I mean by that is to start build process > and dependency checking in parallel and then if something changes > (with dependencies), apply the changes and restart the build > process, and if dependencies are OK continue. Anecdotal evidence from SCons, Gant, Gradle, Rant, and indeed Make, seems to indicate that full dependency resolution in the ADG of the build is the right thing to do for consistent and repeatable builds. Various debates have been had in the SCons and Gradle communities over the years about slow builds, and always, in the end, dependency resolution up front has always won out. Interestingly though "dependency resolution" actually has slightly different meanings in different contexts. In the SCons context it is about ensuring the ADG of the source → object → executable|library and the presence of any referenced libraries. In the Ant/Maven/Gant/Gradle context is is about downloading references libraries and ensuring the ADG of build tasks is right. In all cases building the ADG and constructing the resolution list is not the big problem except in very, very large builds. For example folk at Intel created Parts as a layer over SCons so as to parallelize and create partial caches for the build, a bit along the lines of Vesta but far better. I cannot be certain, but I am not sure there are any D codebases quite the same size as the Intel C++ ones. With SCons and Gradle there were various algorithmic and implementation speedups to ameliorate things and that has helped a lot. I wonder if there are opportunities to do the same for Dub. There are many functionality things that need to be added to Dub to get it into the Cargo and Gradle end of functionality mayhap performance can be improved along the way. I am not sure about DStep build, but for the two projects I have (using GtkD) build times using Dub were sufficiently long that I switched to SCons and it is OK and allows for a reasonable development rhythm. -- 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 signature.asc Description: This is a digitally signed message part
Re: Why doesn't this chain of ndslices work?
On Saturday, 14 May 2016 at 21:59:48 UTC, Stiff wrote: Here's the code that doesn't compile: import std.stdio, std.experimental.ndslice, std.range, std.algorithm; void main() { auto alloslice = [1, 2, 3, 4].sliced(1,4); auto sandwich = chain(alloslice, (0).repeat(8).sliced(2,4), alloslice); writeln(sandwich); } If I comment out the line with the repeat, or allocate the repeat with .array(), everything is fine. I get that the types are incompatible in some way, but it seems like I should be able to lazily instantiate those zeros whenever I need to (later). Should this work? Is there a different way to set up all of the ranges without allocating everything up front? And yeah, resources aren't particularly limited for my application, so allocating everything wouldn't hurt, but I'm trying to really understand all of these little details about ranges. I love them when they work, but the learning curve has been steep. Your problem is that the slices don't have the same type. If you allocate the array, the slice has the type int*, whereas iota and repeat are different types - see this example: ``` auto a = iota(1, 8).sliced(2,4); auto b = (0).repeat(8).sliced(2,4); pragma(msg, CommonType!(typeof(a), typeof(b))); // void ``` ``` auto a = iota(1, 8).array.sliced(2,4); auto b = (0).repeat(8).array.sliced(2,4); pragma(msg, CommonType!(typeof(a), typeof(b))); // Slice!(2LU, int*) ``` Is there a different way to set up all of the ranges without allocating everything up front? The newest version of mir (dev version of ndslice) supports sparse slices - see e.g.: http://docs.mir.dlang.io/latest/mir_sparse.html I also opened an issue to support chain/concatenate for normal slices (https://github.com/libmir/mir/issues/213). Feel free to post further questions about mir directly on our issue tracker on Github or on the Gitter chat.
Re: guard condition for a callable thingy, with THESE arguments
On Sunday, 15 May 2016 at 01:59:15 UTC, cy wrote: I take callbacks on occasion, and I don't really care if they're a delegate, or a function, or a callable object, and I can assert that in a template: void foo(Callable)(Callable callback) if(isSomeFunction!Callable || isCallable!Callable) { ... } That works, but it doesn't show you what arguments the callable will take, or how many, or what its return type should be. You can of course read the body of the `foo` function to spy out where the text "callable(" might be, but it'd be really nice if I could put that information in my guard condition somehow. What I want is something like this. bool default_callback(int foo, string bar, Something baz) { ... } void foo(Callable)(Callable callback) if(calledTheSameAs!(Callable,default_callback)) { ... } or void foo(Callable)(Callable callback) if(calledTheSameAs!(Callable,bool function(int,string,Something)) { ... } Is that possible to do? Has it already been done? use "Parameters" in the constraint or make a template that you can reeuse. import std.traits; alias Model = void function(int, string); void foo(Callable)(Callable callback) if(is(Parameters!Callable == Parameters!Model)) {} void main(string[] args) { static void right(int,string){} static assert(__traits(compiles, foo(&right))); static void wrong(int){} static assert(!__traits(compiles, foo(&wrong))); }
guard condition for a callable thingy, with THESE arguments
I take callbacks on occasion, and I don't really care if they're a delegate, or a function, or a callable object, and I can assert that in a template: void foo(Callable)(Callable callback) if(isSomeFunction!Callable || isCallable!Callable) { ... } That works, but it doesn't show you what arguments the callable will take, or how many, or what its return type should be. You can of course read the body of the `foo` function to spy out where the text "callable(" might be, but it'd be really nice if I could put that information in my guard condition somehow. What I want is something like this. bool default_callback(int foo, string bar, Something baz) { ... } void foo(Callable)(Callable callback) if(calledTheSameAs!(Callable,default_callback)) { ... } or void foo(Callable)(Callable callback) if(calledTheSameAs!(Callable,bool function(int,string,Something)) { ... } Is that possible to do? Has it already been done?
Re: Speed up `dub`.
On Monday, 7 March 2016 at 09:18:37 UTC, ciechowoj wrote: I'm using `dub` to build project. And every time I run `dub` it seems to check if dependencies are up to date, which takes some time. Is there a way to switch of that checking? Or any other way to speed up building process? It really slows down my modify-compile-check iteration time. dub build --nodeps It's amazing. dub has a few uh, issues with dependencies. It pulls all dependencies, even for disabled configurations, even for unselected optional dependencies, then just... leaves them pulled I guess, and doesn't link with them? https://github.com/dlang/dub/issues/844 I don't know exactly what's going wrong. But after you run `dub build` the first time, everything will be downloaded and installed now, so you can recompile by specifying --nodeps and it just jumps straight past all those buggy issues. ld.gold also will vastly speed up modify-compile-check cycles. dmd is fast at compiling, but linking it all up is really slow with vanilla ld.
Why doesn't this chain of ndslices work?
Here's the code that doesn't compile: import std.stdio, std.experimental.ndslice, std.range, std.algorithm; void main() { auto alloslice = [1, 2, 3, 4].sliced(1,4); auto sandwich = chain(alloslice, (0).repeat(8).sliced(2,4), alloslice); writeln(sandwich); } If I comment out the line with the repeat, or allocate the repeat with .array(), everything is fine. I get that the types are incompatible in some way, but it seems like I should be able to lazily instantiate those zeros whenever I need to (later). Should this work? Is there a different way to set up all of the ranges without allocating everything up front? And yeah, resources aren't particularly limited for my application, so allocating everything wouldn't hurt, but I'm trying to really understand all of these little details about ranges. I love them when they work, but the learning curve has been steep.
Re: Speed up `dub`.
On Monday, 7 March 2016 at 21:56:11 UTC, Seb wrote: Use ld.gold - it will speed up your linking quite dramatically! https://code.dawg.eu/reducing-vibed-turnaround-time-part-1-faster-linking.html Thanks, it improves things a little. However I've just had idea that it should be possible to implement 'speculative dependency checking' for dub. What I mean by that is to start build process and dependency checking in parallel and then if something changes (with dependencies), apply the changes and restart the build process, and if dependencies are OK continue.
Re: Defining member fuctions of a class or struct out side of the class/struct body?
On Friday, May 13, 2016 18:41:16 Jamal via Digitalmars-d-learn wrote: > Warning D newb here. > > Is it possible to define a member function outside of the > class/struct like in C++; > > class x { body > void foo(int* i); > }; > > void x::foo(int* i){ > *i++; > } > > Or is it just D-like to define everything inside the class/struct > body? The language is designed with the idea that you're going to define all of the functions inline and not have prototypes. So, if you're trying to do it differently, you're going to have a lot of problems. That being said, you have two options: 1. Write a D interface file. Its extension is .di, and it's intended to be similar to a C/C++ header file for the purpose of hiding implementation when distributing a library without the source code. However, you still need to write the .d file exactly like you would normally. The .di file is just for other folks that you don't want to give the source to. So, it generates a lot more work for you with arguably no benefit if you're just looking to separate interface and implementation. And any templated types and auto-return functions will still have to have their full source in the .di file, and any functions that you want to be inlined will need their source in the .di file. So, a lot of stuff is likely going to need to be in the .di file anyway (especially in range-based code, since that tends to be _very_ template-heavy). To save effort in generating a .di file, you can use the compiler to generate one for you (I think that the flags that start with -H are for that), but last I heard, it's pretty conservative in removing stuff, so a lot of the implementation is going to be left in there even if it doesn't need to be. So, you're likely going to have to edit it manually. I think that the general consensus in the D community has been that .di files really aren't worth it. If you _need_ them, because you want to keep your source hidden, then they're what you need, but they're a pain otherwise. 2. You can use UFCS (Universal Function Call Syntax). Ali's book talks about it here: http://ddili.org/ders/d.en/ufcs.html but basically what it comes down to is that you call call a free function as if it were a member function of its first argument. e.g. auto foo(MyClass m, int i) {..} auto result = myClass.foo(42); This allows you to essentially add member functions without them having to be member functions. You don't end up with prototypes or with them being listed as member functions in your struct or class, but the functions are then separate from the struct or class, and you don't need their implementation inside the struct or class. Where UFCS is truly useful though is it allows generic code to call functions without caring whether they're member functions or free functions. For instance, if you use std.algorith.find with UFCS inside of a templated function, and you call it with UFCS, and the type that you call it on has a member function called find which is more efficient for it than the generic find would be, then the member function will be called, whereas for all of those types that don't define find, the generic one will work just fine. So, your code doesn't have to care whether the function is actually a member function or not. But a lot of folks like to use UFCS just because it allows them to chain functions left-to-right rather than using the classical, functional style with parens, which chains right-to-left and ends up with a lot of parens. e.g. auto arr = [1, 7, 19, 42, 9]; auto result = arr.filter!(a => a < 20)().map!(a => to!string(a))().array(); assert(result == ["1", "7", "19", "9"]); or auto arr = [1, 7, 19, 42, 9]; auto result = arr.filter!(a => a < 20)() .map!(a => to!string(a))() .array(); assert(result == ["1", "7", "19", "9"]); instead of auto arr = [1, 7, 19, 42, 9]; auto result = array(map!(a => to!string(a))(filter!(a => a < 20)(arr))); assert(result == ["1", "7", "19", "9"]); In any case, D is set up so that you don't normally separate declarations and definitons like you would in C/C++, and its compilation model is _far_ more efficient than C/C++, so it's not really necessary to do it in quite the same way that it is in C/C++. It is occasionally annoying when you just want to see which member functions and member functions are declared on a type, but you get used to it, and you can always generate documentation to if you just want to see the declarations. We're in basically the same boat as Java with this sort of thing. - Jonathan M Davis
Re: Defining member fuctions of a class or struct out side of the class/struct body?
On 2016-05-13 20:41, Jamal wrote: Or is it just D-like to define everything inside the class/struct body? Yes, the D-way is to define everything directly inside the class/struct. -- /Jacob Carlborg