Re: Why doesn't this chain of ndslices work?

2016-05-14 Thread Seb via Digitalmars-d-learn

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

2016-05-14 Thread Ann W. Griffith via Digitalmars-d-learn

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()));
static void wrong(int){}
static assert(!__traits(compiles, foo()));
}



guard condition for a callable thingy, with THESE arguments

2016-05-14 Thread cy via Digitalmars-d-learn
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`.

2016-05-14 Thread cy via Digitalmars-d-learn

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?

2016-05-14 Thread Stiff via Digitalmars-d-learn

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`.

2016-05-14 Thread ciechowoj via Digitalmars-d-learn

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?

2016-05-14 Thread Jonathan M Davis via Digitalmars-d-learn
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?

2016-05-14 Thread Jacob Carlborg via Digitalmars-d-learn

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


Re: How to split a string/array with multiple separators?

2016-05-14 Thread Joel via Digitalmars-d-learn

On Wednesday, 16 December 2015 at 15:27:22 UTC, Marc Schütz wrote:
On Wednesday, 16 December 2015 at 14:47:26 UTC, Dragos Carp 
wrote:
On Wednesday, 16 December 2015 at 14:18:28 UTC, Borislav 
Kosharov wrote:
I want to split a string using multiple separators. In 
std.array the split function has a version where it takes a 
range as a separator, but it works differently than what I 
want. Say if I call it with " -> " it will search for the 
whole thing together. I want to pass split a list of 
separators say [":", ",", ";"] and if it finds any of those 
to split it.


Sorry if this questions is stupid but I cant find how to do 
it.



void main()
{

   import std.stdio: writeln;
   writeln("abc,def;ghi".splitter!(a => 
!":,;".find(a).empty).array);

}


The call to `array` is unnecessary in this example, and you can 
use the shorter `canFind`:


   writeln("abc,def;ghi".splitter!(a => ":,;".canFind(a)));


What about "abc,;;.. def" you get empty strings?

I've come up with this:

import std.stdio : writeln;
import std.algorithm : canFind, splitter, filter;

void main() {
writeln("abc,:def;ghi". // or "abc, def. Ghi"
splitter!(a => " .,:;".canFind(a)).
filter!(a => a.length));
}