Re: mutable pointers as associative array keys

2023-04-11 Thread John Colvin via Digitalmars-d-learn
On Monday, 10 April 2023 at 20:31:43 UTC, Steven Schveighoffer 
wrote:

On 4/10/23 4:25 PM, Steven Schveighoffer wrote:
It's also completely useless. Having const keys does nothing 
to guarantee unchanging keys. Another half-assed attempt to be 
encode correct semantics but fails completely in its goal.


In case you wonder how old this is:

https://issues.dlang.org/show_bug.cgi?id=11477
https://issues.dlang.org/show_bug.cgi?id=12491#c2

-Steve


Oh dear.


mutable pointers as associative array keys

2023-04-10 Thread John Colvin via Digitalmars-d-learn

It seems that it isn't possible, am I missing something?

alias Q = int[int*];
pragma(msg, Q); // int[const(int)*]

Also, is this documented somewhere?


Re: Objective C protocols

2020-05-17 Thread John Colvin via Digitalmars-d-learn

On Saturday, 16 May 2020 at 19:14:51 UTC, John Colvin wrote:

What's the best way to implement an Objective C protocol in D?

I see mention here 
https://dlang.org/changelog/2.085.0.html#4_deprecated_objc_interfaces but it's not clear where things are these days.


Based on some experimentation, I'm starting to wonder do 
protocols actually have any runtime component in Objective C? 
Because if I pass in an extern(Objective-C) class with the right 
interface to a function expecting a protocol everything just 
works.


Objective C protocols

2020-05-16 Thread John Colvin via Digitalmars-d-learn

What's the best way to implement an Objective C protocol in D?

I see mention here 
https://dlang.org/changelog/2.085.0.html#4_deprecated_objc_interfaces but it's not clear where things are these days.


Re: A proper WAT moment

2019-10-15 Thread John Colvin via Digitalmars-d-learn

On Monday, 14 October 2019 at 19:45:11 UTC, Paul Backus wrote:

On Monday, 14 October 2019 at 17:00:56 UTC, John Colvin wrote:
Different ability to access a property depending if I'm inside 
something else when I look?


[snip]


You're attempting to call one of S's member functions without 
an instance of S to call it on. Reduced version:


struct S
{
int a;
int e() @property { return a; }
}

void foo(S s)
{
pragma(msg, __LINE__, " ", __traits(compiles, S.e)); // 
true (???)

S.e; // Error: need `this` for `e` of type `@property int()`
}

struct C
{
void foo(S s)
{
pragma(msg, __LINE__, " ", __traits(compiles, S.e)); // 
false
S.e; // Error: `this` for `e` needs to be type `S` not 
type `C`

}
}

The real issue here is that the first `__traits(compiles)` 
check succeeds, even though the actual expression fails.


And all the other ones in my example that access members without 
an instance that also compile?


There's something pretty strange about the rules here.


A proper WAT moment

2019-10-14 Thread John Colvin via Digitalmars-d-learn
Different ability to access a property depending if I'm inside 
something else when I look?


struct S
{
int a;
static int b;
int c() { return a; }
static int d() { return 3; }
int e() @property { return a; }
static int f() @property { return 3; }
}

void foo(S s)
{
pragma(msg, __LINE__, " ", __traits(compiles, 
__traits(getMember, s, "a")));
pragma(msg, __LINE__, " ", __traits(compiles, 
__traits(getMember, S, "a")));


pragma(msg, __LINE__, " ", __traits(compiles, 
__traits(getMember, s, "b")));
pragma(msg, __LINE__, " ", __traits(compiles, 
__traits(getMember, S, "b")));


pragma(msg, __LINE__, " ", __traits(compiles, 
__traits(getMember, s, "c")));
pragma(msg, __LINE__, " ", __traits(compiles, 
__traits(getMember, S, "c")));


pragma(msg, __LINE__, " ", __traits(compiles, 
__traits(getMember, s, "d")));
pragma(msg, __LINE__, " ", __traits(compiles, 
__traits(getMember, S, "d")));


pragma(msg, __LINE__, " ", __traits(compiles, 
__traits(getMember, s, "e")));
pragma(msg, __LINE__, " ", __traits(compiles, 
__traits(getMember, S, "e")));


pragma(msg, __LINE__, " ", __traits(compiles, 
__traits(getMember, s, "f")));
pragma(msg, __LINE__, " ", __traits(compiles, 
__traits(getMember, S, "f")));

}

struct C(S)
{
void foo(S s)
{
pragma(msg, __LINE__, " ", __traits(compiles, 
__traits(getMember, s, "a")));
pragma(msg, __LINE__, " ", __traits(compiles, 
__traits(getMember, S, "a")));


pragma(msg, __LINE__, " ", __traits(compiles, 
__traits(getMember, s, "b")));
pragma(msg, __LINE__, " ", __traits(compiles, 
__traits(getMember, S, "b")));


pragma(msg, __LINE__, " ", __traits(compiles, 
__traits(getMember, s, "c")));
pragma(msg, __LINE__, " ", __traits(compiles, 
__traits(getMember, S, "c")));


pragma(msg, __LINE__, " ", __traits(compiles, 
__traits(getMember, s, "d")));
pragma(msg, __LINE__, " ", __traits(compiles, 
__traits(getMember, S, "d")));


pragma(msg, __LINE__, " ", __traits(compiles, 
__traits(getMember, s, "e")));

// ALL True except for this one:
pragma(msg, __LINE__, " ", __traits(compiles, 
__traits(getMember, S, "e")));


pragma(msg, __LINE__, " ", __traits(compiles, 
__traits(getMember, s, "f")));
pragma(msg, __LINE__, " ", __traits(compiles, 
__traits(getMember, S, "f")));

}
}

alias C0 = C!S;


How to find what is causing a closure allocation

2019-10-02 Thread John Colvin via Digitalmars-d-learn
I have a function that allocates a closure somewhere in it (as 
shown by the result of -profile=gc).


I can't make the function nogc as it calls a lot of other GC 
using code.


profilegc.log only gives me the line number of the function 
signature, which doesn't give me any hint as to where in the 
function the closure is allocated.


Anyone have any nice tricks to help narrow this down.


Re: Abstract classes vs interfaces, casting from void*

2019-08-11 Thread John Colvin via Digitalmars-d-learn

On Sunday, 11 August 2019 at 20:15:34 UTC, Alex wrote:

On Sunday, 11 August 2019 at 16:05:20 UTC, John Colvin wrote:
I'm trying to narrow down exactly what patterns work with each 
and how they overlap.


What I was trying to get at with the abstract method thing is 
that


abstract class C
{
void foo();
}

is an abstract class with a non-abstract method, whose 
implementation is going to come from somewhere else (not a 
common pattern in D).


class C
{
abstract void foo();
}

is an abstract class with an abstract method foo, which means 
you have to override it in a inheriting class to get a 
non-abstract class.


As I see this, everything you wrote is correct. :)

But you compared abstractness with interface usage, initially. 
So... I would say, interfaces are more like the abstract method 
case without any function body. But then, you will have to use 
"override" all across the inherited classes.


Ok. So that means the difference is pretty subtle, give or take a 
few extra keywords.


Which leaves multiple inheritance as the only significant 
difference?


From my perspective it looks like there are two massively 
overlapping features with some quite arbitrary feeling 
restrictions and differences. E.g. why can I not inherit from 
multiple 100% abstract empty classes? Wouldn't that be the same 
as inheriting from multiple interfaces?


Re: Abstract classes vs interfaces, casting from void*

2019-08-11 Thread John Colvin via Digitalmars-d-learn

On Sunday, 11 August 2019 at 15:16:03 UTC, Alex wrote:

On Sunday, 11 August 2019 at 13:09:43 UTC, John Colvin wrote:
Ok. What would go wrong (in D) if I just replaced every 
interface with an abstract class?


I think there's some confusion here, because B.foo is not 
abstract. abstract on a class is not inherited by its methods. 
https://dlang.org/spec/attribute.html#abstract


Now, I'm confused, as you asked about abstract classes. So, 
yes, you can define the abstractness of classes differently. 
And what is your point?


I'm trying to narrow down exactly what patterns work with each 
and how they overlap.


What I was trying to get at with the abstract method thing is that

abstract class C
{
void foo();
}

is an abstract class with a non-abstract method, whose 
implementation is going to come from somewhere else (not a common 
pattern in D).


class C
{
abstract void foo();
}

is an abstract class with an abstract method foo, which means you 
have to override it in a inheriting class to get a non-abstract 
class.


Re: Abstract classes vs interfaces, casting from void*

2019-08-11 Thread John Colvin via Digitalmars-d-learn

On Saturday, 10 August 2019 at 17:28:32 UTC, Alex wrote:


´´´
void main(){}
interface A { void fun(); }
abstract class B{ void fun(); }
class C : A{ void fun(){} }
class D : B{ /*override*/ void fun(){} }
´´´

case 1:
interface A and class C implementing interface A:
You don't need to "override" anything. You are forced to 
provide an implementation of the function inside the class.


case 2:
abstract class B and class D inheriting from it:
You can but not have to provide an implementation of a function 
inside the abstract class.
If I don't and do not provide any implementation inside D I get 
a linker error. Don't how this case behaves on your system.
If you provide an implementation inside the abstract class, you 
don't have to provide any in the derived one.
In any case, if you want to provide an implementation inside 
the derived class you have to literally "override", as in D 
implicit overrides are not allowed.


I think there's some confusion here, because B.foo is not 
abstract. abstract on a class is not inherited by its methods. 
https://dlang.org/spec/attribute.html#abstract




Re: Abstract classes vs interfaces, casting from void*

2019-08-11 Thread John Colvin via Digitalmars-d-learn

On Saturday, 10 August 2019 at 17:46:37 UTC, Timon Gehr wrote:

On 10.08.19 16:29, John Colvin wrote:


Ok. What would go wrong (in D) if I just replaced every 
interface with an abstract class?


interface A{}
interface B{}

class C: A,B{ }


Yes, I know, I guess it wasn't clear unless you read my previous 
question, I said "apart from multiple inheritance".


Re: Abstract classes vs interfaces, casting from void*

2019-08-10 Thread John Colvin via Digitalmars-d-learn

On Saturday, 10 August 2019 at 10:11:15 UTC, Alex wrote:

On Saturday, 10 August 2019 at 08:20:46 UTC, John Colvin wrote:

On Friday, 9 August 2019 at 13:39:53 UTC, Simen Kjærås wrote:




Thanks for the extra detail.

Is there a solid reason to ever use an interface over an 
abstract class? (Other than multiple inheritance).


I'm such a noob at anything related to OO.


The general question is tricky, as different languages differ 
in details what is forced and what is allowed for abstract 
classes and interfaces.


But roughly speaking, my opinion is: if you can/want to provide 
some default behavior than you are about to write an abstract 
class.
If you are about to provide information/restriction of 
behavior, then this is more like an interface.


Ok. What would go wrong (in D) if I just replaced every interface 
with an abstract class?


Re: Abstract classes vs interfaces, casting from void*

2019-08-10 Thread John Colvin via Digitalmars-d-learn

On Saturday, 10 August 2019 at 10:02:02 UTC, Antonio Corbi wrote:

On Saturday, 10 August 2019 at 08:20:46 UTC, John Colvin wrote:

On Friday, 9 August 2019 at 13:39:53 UTC, Simen Kjærås wrote:




Thanks for the extra detail.

Is there a solid reason to ever use an interface over an 
abstract class? (Other than multiple inheritance).


I'm such a noob at anything related to OO.


Hi John.

One reason could be data. Abstract classes can hold data, 
interfaces can't.


Antonio


That's a reason to use an abstract class, not a reason to use an 
interface.


Re: Abstract classes vs interfaces, casting from void*

2019-08-10 Thread John Colvin via Digitalmars-d-learn

On Friday, 9 August 2019 at 13:39:53 UTC, Simen Kjærås wrote:




Thanks for the extra detail.

Is there a solid reason to ever use an interface over an abstract 
class? (Other than multiple inheritance).


I'm such a noob at anything related to OO.


Re: Abstract classes vs interfaces, casting from void*

2019-08-10 Thread John Colvin via Digitalmars-d-learn

On Friday, 9 August 2019 at 13:39:53 UTC, Simen Kjærås wrote:
We're getting into somewhat advanced topics now. This is 
described in the Application Binary Interface page of the 
documentation[0]. In short: classes and interfaces both use a 
vtable[1] that holds pointers to each of their methods. When we 
cast a class instance to an interface, the pointer is adjusted, 
such that the interface's vtable is the first member. Casting 
via `void*` bypasses this adjustment.


Using `__traits(classInstanceSize)`, we can see that `C` has a 
size of 12 bytes, while `D` only is 8 bytes (24 and 16 on 
64-bit). This corresponds to the extra interface vtable as 
described above.


When we first cast to `void*`, no adjustment happens, because 
we're not casting to an interface. When we later cast the 
`void*` to an interface, again no adjustment happens - in this 
case because the compiler doesn't know what we're casting from.


If we use `__traits(allMembers, C)`, we can figure out which 
methods it actually has, and implement those with some extra 
debug facilities (printf):


class C : I
{
override void foo() { writeln("hi"); }
override string toString()   { writeln("toString"); 
return ""; }
override hash_t toHash() { debug printf("toHash"); 
return 0; }
override int opCmp(Object o) { writeln("opCmp"); return 
0; }
override bool opEquals(Object o) { writeln("opEquals"); 
return false; }

}

If we substitute the above in your program, we see that the 
`toString` method is the one being called. This is simply 
because it's at the same location in the vtable as `foo` is in 
`I`'s vtable.


When casting from a class to a superclass, no pointer 
adjustment is needed, as the vtable location is the same for 
both.


We can look closer at the vtable, and see that for a new 
subclass, additional entries are simply appended at the end:


class C {
void foo() {}
}

class D : C {
void bar() {}
}

unittest {
import std.stdio;

C c = new C();
D d = new D();

writeln("Pointer to foo(): ", ().funcptr);
writeln("Pointer to bar(): ", ().funcptr);

writeln("Pointer to foo() in C's vtable: ", c.__vptr[5]);

writeln("Pointer to foo() in D's vtable: ", d.__vptr[5]);
writeln("Pointer to bar() in D's vtable: ", d.__vptr[6]);
}

As we see, `foo()` has the position in the vtable for both `c` 
and `d`, while `D`'s new `bar()` method is added as the next 
entry.


--
  Simen

[0]: https://dlang.org/spec/abi.html
[1]: https://en.wikipedia.org/wiki/Virtual_method_table


Thanks for the extra detail.

Is there a solid reason to ever use an interface over an abstract 
class? (Other than multiple inheritance).


I'm such a noob at anything related to OO.


Re: Abstract classes vs interfaces, casting from void*

2019-08-09 Thread John Colvin via Digitalmars-d-learn

On Friday, 9 August 2019 at 13:19:14 UTC, kinke wrote:

On Friday, 9 August 2019 at 12:26:59 UTC, John Colvin wrote:

Why is there no "hi" between 0 and 1?


Because you are treating the unadjusted object pointer as 
interface pointer and then call the only virtual function of 
that interface, in the 2nd vtbl slot (after the TypeInfo ptr). 
Casting a class ref to an interface offsets the pointer, so 
that the interface ref points to the interface vptr for that 
object instance. This is missing in that line, and so you are 
invoking the first virtual function of class C, which is some 
base function in `Object`.


Ok, makes sense, thanks.


Abstract classes vs interfaces, casting from void*

2019-08-09 Thread John Colvin via Digitalmars-d-learn

import std.stdio;

interface I
{
void foo();
}

class C : I
{
override void foo() { writeln("hi"); }
}

abstract class AC
{
void foo();
}

class D : AC
{
override void foo() { writeln("hi"); }
}

void main()
{
auto c = new C();
writeln(0);
(cast(I)cast(void*)c).foo();
writeln(1);
(cast(C)cast(void*)c).foo();
writeln(2);
(cast(I)cast(C)cast(void*)c).foo();

auto d = new D();
writeln(3);
(cast(AC)cast(void*)d).foo();
writeln(4);
(cast(D)cast(void*)d).foo();
writeln(5);
(cast(AC)cast(D)cast(void*)d).foo();
}

This produces the output:

0
1
hi
2
hi
3
hi
4
hi
5
hi

Why is there no "hi" between 0 and 1?


Re: Compiler/Phobos/Types problem — panic level due to timing.

2019-05-09 Thread John Colvin via Digitalmars-d-learn

On Wednesday, 8 May 2019 at 11:53:34 UTC, Russel Winder wrote:
On Mon, 2019-05-06 at 15:53 +, John Colvin via 
Digitalmars-d-learn wrote:

[…]

pretty please show people it with UFCS:

recurrence!((a, n) => a[n-1] + a[n-2])(zero, one)
 .dropExactly(n)
 .front


Any particular reason for preferring this form over the 
original?


Not big benefit in this case, very big benefit with longer chains.

It reads in the order of operations, as opposed to inside out.


Re: Compiler/Phobos/Types problem — panic level due to timing.

2019-05-06 Thread John Colvin via Digitalmars-d-learn

On Monday, 6 May 2019 at 13:05:27 UTC, Russel Winder wrote:

On Sunday, 5 May 2019 at 19:34:05 UTC, Nicholas Wilson wrote:

On Sunday, 5 May 2019 at 19:18:47 UTC, lithium iodate wrote:

[...]


Yep https://run.dlang.io/is/XsLrRz works for me, 
https://run.dlang.io/is/KxY0e9 doesn't.


Thanks people. I now have a working code. :-)


pretty please show people it with UFCS:

recurrence!((a, n) => a[n-1] + a[n-2])(zero, one)
.dropExactly(n)
.front


Re: Idiomatic FFT(W) Wrapper

2017-07-13 Thread John Colvin via Digitalmars-d-learn

On Thursday, 13 July 2017 at 12:49:40 UTC, Per Nordlöw wrote:

Have anybody constructed an idiomatic D wrapper for FFTW?


No, sorry, although I have used the library quite a bit in D.


http://www.fftw.org/fftw3_doc/Tutorial.html#Tutorial

I'm specifically concerned about

- `RefCounted`-wrapping of the C structures `fftw_complex` and 
`fftw_plan`


Sounds useful perhaps for fftw_plan. fftw_complex is just 
`typedef double fftw_complex[2];` so I'm not sure what you're 
getting at there.


It's worth remembering that "wisdom" is separate from (and shared 
between) plans in fftw, so constructing and destroying plans can 
be very cheap and there's often no need to have multiple owners 
of a single plan.



- range semantics, lazy evaluation and caching of result in
  stream-based architectures; `fftw_plan`, `fftw_execute`


The discrete fourier transform is a global algorithm that can be 
lazy in input or output, but not both. I'm pretty sure the fast 
fourier transform algorithm for DFT cannot be lazy in either. Do 
you mean creating some sort of lazy short-time-fourier-transform 
(STFT or spectrogram or whatever other name people like)? Or are 
you thinking about 1-D transforms in multi-dimensional data 
(arguably the same thing actually)?



- slicing and scope


??

- seamless interoperability with Mir 
(https://github.com/libmir/mir)


This would definitely be nice to have

For most common use-cases I find fftw is dead simple to use with 
the C API though. So simple that I never even bother making 
bindings, I just declare what I need as I need it (which in a 
single application has never been more than about 10 
declarations).


Re: Finding the index of the maximum value in an associative array

2017-06-01 Thread John Colvin via Digitalmars-d-learn

On Tuesday, 30 May 2017 at 18:05:07 UTC, H. S. Teoh wrote:
On Tue, May 30, 2017 at 05:57:04PM +, Lyle via 
Digitalmars-d-learn wrote:

Hi,

I have an associative array of type int[ulong] and I'm trying 
to get the index of the maximum value, like this:


int[ulong] aa = [1UL: 2000,
 2UL: 5000,
 5UL: 1000];

writeln(aa.maxIndex); // should print 2

Can anyone help me out?

[...]

Try this:

void main() {
import std.algorithm.iteration : fold;
import std.array : byPair;
import std.stdio : writeln;

int[ulong] aa = [1UL: 2000,
2UL: 5000,
5UL: 1000];

writeln(aa.byPair
  .fold!((a,b) => a[1] < b[1] ? b : a)[0]);
}


writeln(aa.byPair.maxElement!(p => p[1])[0]);

or with https://github.com/dlang/phobos/pull/5436 :

writeln(aa.byPair.maxElement!(p => p.value).key);


Re: Access specifiers and visibility

2017-05-13 Thread John Colvin via Digitalmars-d-learn

On Wednesday, 10 May 2017 at 01:42:47 UTC, Andrew Edwards wrote:
Attempting to update a git repo to current D, I encounter the 
following deprecation messages:


src/glwtf/signals.d-mixin-256(256,2): Deprecation: 
glwtf.input.BaseGLFWEventHandler._on_key_down is not visible 
from module glwtf.signals
src/glwtf/signals.d-mixin-256(256,2): Deprecation: 
glwtf.input.BaseGLFWEventHandler._on_key_up is not visible from 
module glwtf.signals
src/glwtf/signals.d-mixin-256(256,2): Deprecation: 
glwtf.input.BaseGLFWEventHandler._on_mouse_button_down is not 
visible from module glwtf.signals
src/glwtf/signals.d-mixin-256(256,2): Deprecation: 
glwtf.input.BaseGLFWEventHandler._on_mouse_button_up is not 
visible from module glwtf.signals


Those error messages are often misleading. The name of the symbol 
alone is (often, always?) right but the module/package it says 
it's from is often nonsense. I often get deprecation messages 
saying things like "myPackage.myModule.to is not visible from 
module myPackage.myOtherModule", when the real problem is I 
forgot to import std.conv in myPackage.myOtherModule.


Re: List Comprehension equivalent

2017-03-17 Thread John Colvin via Digitalmars-d-learn

On Friday, 17 March 2017 at 19:08:36 UTC, Russel Winder wrote:
On Fri, 2017-03-17 at 17:51 +, Jerry via 
Digitalmars-d-learn wrote:

On Friday, 17 March 2017 at 17:13:48 UTC, Russel Winder wrote:
> I have a bit of code:
> 
> 	string[] returnValue;

>foreach(string key, string[] value; groups) {
>returnValue ~=
> value.sort!debianPackageNumberComparator()[0..$-1].array;
>}
>return returnValue;
> 
> [...]


You forgot a ! on the map call.

.map!((Tuple!(string, string[]) a) =>
a[1].sort!debianPackageNumberComparator()[0..$-1])


How embarrassed am I? :-)

However, the result of the map appears to be untransformable to
anything related to a sequence of string. The result is some 
type that
renders as a sequence of sequence using writeln but how to 
reduce it to
a sequence? reduce isn't defined on MapResult and if I 
transform to an
array reduce is not defined on SortedRange[]. Rust ownership 
problems

seem to be a doddle compared to this problem.


reduce is a free function in std.algorithm. Just import it and 
you're away. Anyway, is this what you wanted?


string[] blah(string[][string] groups)
{
import std.algorithm : map, joiner;
import std.array : array, byPair;
return groups.byPair()
.map!(a => 
a[1].sort!debianPackageNumberComparator()[0..$-1])

.joiner
.array;
}


Re: In Expressions

2017-03-04 Thread John Colvin via Digitalmars-d-learn

On Saturday, 4 March 2017 at 17:11:46 UTC, Andrey wrote:
Hello, is there any way to using in expression like in python, 
e.g.

if 4 in [1, 3, 4]:
do something


My code in D

if (regionAlign in [RegionAlign.top, RegionAlign.bottom]) {
   ...
}


throws an error:
incompatible types for (((cast(Widget)this).regionAlign()) in 
([top, bottom])): 'RegionAlign' and 'RegionAlign[]'


The in operator is defined for associative arrays, but not for 
normal arrays/slices.


You could do this:

import std.algorithm : canFind;
if ([RegionAlign.top, RegionAlign.bottom].canFind(regionAlign)) {
}

Consider using only(RegionAlign.top, RegionAlign.bottom) instead 
of [] to avoid allocating a temporary array.


import std.algorithm : canFind;
if (only(RegionAlign.top, 
RegionAlign.bottom).canFind(regionAlign)) {

}

but to be honest, I would just repeat myself a bit and write

if (regionAlign == RegionAlign.top ||
regionAlign == RegionAlign.bottom) {
}

If you *really* must have `in`, you could wrap your arrays (or 
other ranges) in this:


import std.range : isInputRange;

struct WithInOp(alias eqPred = "a == b", Range)
if (isInputRange!Range)
{
Range range;
alias range this;
bool opBinaryRight(string op : "in", T)(T rhs)
{
import std.algorithm.searching : canFind;
return range.canFind!eqPred(rhs);
}
}

auto withInOp(alias eqPred = "a == b", Range)(Range range)
{
return WithInOp!(eqPred, Range)(range);
}

unittest
{
auto r = withInOp([1, 2, 4]);
assert(1 in r);
assert(3 !in r);
assert([1, 2] in r);
assert([2, 2] !in r);

struct S
{
int main, extra;
}

auto r2 = withInOp!"a.main == b.main"([S(1, 3), S(2, 4), S(4, 
1)]);

assert(S(1, 7) in r2);
assert(S(3, 4) !in r2);
assert([S(2, -42), S(4, 3)] in r2);
assert([S(2, -42), S(3, 3)] !in r2);
}


Re: template parameter inference and introspection

2017-02-24 Thread John Colvin via Digitalmars-d-learn

On Friday, 24 February 2017 at 14:06:22 UTC, Meta wrote:

On Friday, 24 February 2017 at 11:17:46 UTC, John Colvin wrote:
Unfortunately that only works by accident of my example. A 
counterexample:


T foo(Q = float, T = short)(T t) { return t; }

alias Typeof(alias v) = typeof(v);

template getInstantiation(alias f, T...)
{
import std.meta;

alias getInstantiation = f!(staticMap!(Typeof, T));
}

static assert(is(typeof(foo(3)) == int)); // ok
static assert(is(typeof(getInstantiation!(foo, 3)(3)) == 
int)); // fails


This looks like VRP is kicking in when it shouldn't, or maybe 
it's a different bug. 3 should be typed as int by default 
unless we explicitly ask for something else.


VRP propagation is what makes the call possible, but that's a 
distraction. The problem is that getInstantiation is setting Q to 
int and leaving T to be it's default type of short, which is not 
the same as if you just call with an int (which infers T from t 
and leaves Q as it's default float. Fundamentally, you can't 
assume the same order of runtime and template arguments.


Re: template parameter inference and introspection

2017-02-24 Thread John Colvin via Digitalmars-d-learn

On Thursday, 23 February 2017 at 18:33:33 UTC, Meta wrote:

On Thursday, 23 February 2017 at 18:21:51 UTC, Meta wrote:
On Thursday, 23 February 2017 at 16:01:44 UTC, John Colvin 
wrote:
Is there any way to get a reference/alias to the 
instantiation of a template function that would be called, 
given certain parameters? I.e. to get the result of whatever 
template parameter inference (and overload resolution) has 
occurred?


E.g. for some arbitrarily complex foo:

static assert(__traits(compiles, foo(3)));
alias fooWithInt = someMagic(foo(3));

so if foo was `void foo(T)(T t) {}` then `fooWithInt` would 
be `foo!int`, but if it was `void foo(Q = float, T = long)(T 
t)` then `fooWithInt` would be `foo!(float, int)`


I don't believe so, because foo(3) is a value (void), not a 
type like foo!int would be. You can't get it back after you've 
called the function. You would have to do something like:


alias fooWithInt = someMagic!foo(3);

Where someMagic constructs the alias to foo!int based on the 
type of arguments passed, or something like that.


A quick and rough example I threw together. Annoyingly, I can't 
figure out a way to tell the compiler that I want to printout 
the symbol of fooWithInt, not call it without parens. The best 
I can do is print out its type.


void foo(T)(T t) {}
void foo(Q = float, T = long)(T t) {}

alias Typeof(alias v) = typeof(v);

template getInstantiation(alias f, T...)
{
import std.meta;

alias getInstantiation = f!(staticMap!(Typeof, T));
}

alias fooWithInt = getInstantiation!(foo, 3);
alias fooWithLong = getInstantiation!(foo, 3L);

void main()
{
pragma(msg, typeof(fooWithInt));
pragma(msg, typeof(fooWithLong));
}


Unfortunately that only works by accident of my example. A 
counterexample:


T foo(Q = float, T = short)(T t) { return t; }

alias Typeof(alias v) = typeof(v);

template getInstantiation(alias f, T...)
{
import std.meta;

alias getInstantiation = f!(staticMap!(Typeof, T));
}

static assert(is(typeof(foo(3)) == int)); // ok
static assert(is(typeof(getInstantiation!(foo, 3)(3)) == int)); 
// fails




template parameter inference and introspection

2017-02-23 Thread John Colvin via Digitalmars-d-learn
Is there any way to get a reference/alias to the instantiation of 
a template function that would be called, given certain 
parameters? I.e. to get the result of whatever template parameter 
inference (and overload resolution) has occurred?


E.g. for some arbitrarily complex foo:

static assert(__traits(compiles, foo(3)));
alias fooWithInt = someMagic(foo(3));

so if foo was `void foo(T)(T t) {}` then `fooWithInt` would be 
`foo!int`, but if it was `void foo(Q = float, T = long)(T t)` 
then `fooWithInt` would be `foo!(float, int)`


Re: Alias type with different initialiser.

2017-02-14 Thread John Colvin via Digitalmars-d-learn
On Tuesday, 14 February 2017 at 11:34:22 UTC, Bastiaan Veelo 
wrote:

On Monday, 13 February 2017 at 22:59:11 UTC, John Colvin wrote:

Why not use a constructor instead of static opCall?


I don't know, this comes from 
http://dlang.org/spec/struct.html#dynamic_struct_init. Your 
constructor looks a lot better. Am I missing a test case where 
static opCall would be called, but not the constructor? Why do 
the docs use static opCall?


The docs are just trying to illustrate that opCall is only used 
for initialisation if the initialiser is of a different type. 
Constructors are always used for initialisation if they are 
there, they completely hide static opCall in that context. static 
opCall can return anything of any type, constructors implicitly 
return a reference to `this`. A constructor is the way to 
initialise a type and some code - such as std.conv.emplace - 
actually calls the constructor manually (it's accessible via 
.__ctor) to do so. static opCall doesn't necessarily represent an 
initialiser function, so generic code won't necessarily know to 
use it.


Overall, static opCall is rarely the solution you need.

Also, it's generally a bad idea to define `.init` for any type 
as code generally expects this to be the compiler-generated 
property (e.g. a value of type Initial!(int, 1) not of type 
int).


Thanks. I can't remember what confused me to think that 
typeof(int1.init) had to be int.



enum initial = val;

[...]
static assert(int1.initial == 1); // typeof(int1.initial) 
== int


These lines have no purpose beyond illustration, right?


they check that the implementation does have a member .initial 
and that it is equal to the value we requested as the 
initialiser. It also enforces that it is accessible at 
compile-time.




I now have the following, featuring the novel Scherkl-Nielsen 
self-important lookup:


/**
Creates an type that is mostly $(PARAM T), only with a 
different initial value of $(PARAM val).

*/
struct Initial(T, T val)
{
private T _payload = val;
alias _payload this;

this(T v)
{
_payload = v;
}

// https://dlang.org/blog/2017/02/13/a-new-import-idiom/
private template from(string moduleName)
{
  mixin("import from = " ~ moduleName ~ ";");
}

void toString(scope void delegate(const(char)[]) sink, 
from!"std.format".FormatSpec!char fmt)

{
import std.array : appender;
import std.format : formatValue;
auto w = appender!string();
formatValue(w, _payload, fmt);
sink(w.data);
}
}

unittest
{
alias int1 = Initial!(int, 1);
static assert(int1.init == 1); // typeof(int1.init) == int1

int1 i;
assert(i == 1);
int1 ii = 2;
assert(ii == 2);
assert(ii.init == 1);
assert(int1.init == 1);

void f(int val)
{
assert(val == 1);
}
f(i);

int i0;
assert(i0 == 0);
i = i0;
assert(i == 0);
assert(i.init == 1);
i0 = ii;
assert(i0 == 2);
assert(i0.init == 0);

import std.string;
assert(format("%6d", ii) == " 2");
}


I would recommend making `template from(string moduleName)` 
global (maybe in a utils module?), there's no reason for it to be 
a member of Initial.


Re: Alias type with different initialiser.

2017-02-14 Thread John Colvin via Digitalmars-d-learn
On Tuesday, 14 February 2017 at 10:49:19 UTC, Bastiaan Veelo 
wrote:

On Tuesday, 14 February 2017 at 01:31:10 UTC, John Colvin wrote:

On Monday, 13 February 2017 at 22:59:11 UTC, John Colvin wrote:

[ snip ]


sorry, made a typo, that should have been


alias int1 = Initial!(int, 1);
static assert(int1.initial == 1); // typeof(int1.initial) 
== int
static assert(int1.init == 1); // typeof(int1.init) == 
int1


What is the difference between

  alias Initial!(int, 1) int1;

and

  alias int1 = Initial!(int, 1);

? Or was the typo in the comments alone?

Thanks.


just a more modern style. I think the old style would have been 
deprecated if it wasn't for how much old code used it.


Re: Alias type with different initialiser.

2017-02-13 Thread John Colvin via Digitalmars-d-learn

On Monday, 13 February 2017 at 22:59:11 UTC, John Colvin wrote:

[ snip ]


sorry, made a typo, that should have been


alias int1 = Initial!(int, 1);
static assert(int1.initial == 1); // typeof(int1.initial) 
== int

static assert(int1.init == 1); // typeof(int1.init) == int1




Re: Alias type with different initialiser.

2017-02-13 Thread John Colvin via Digitalmars-d-learn

On Monday, 13 February 2017 at 22:16:36 UTC, Bastiaan Veelo wrote:

On Monday, 13 February 2017 at 16:40:02 UTC, Daniel Kozak wrote:

https://dlang.org/phobos/std_typecons.html#.Typedef


Thanks for the pointers. Both Typedef and Proxy create types 
that don't mix with the base type, which I want to the 
contrary. So I guess I'll go with


Why not use a constructor instead of static opCall? Also, it's 
generally a bad idea to define `.init` for any type as code 
generally expects this to be the compiler-generated property 
(e.g. a value of type Initial!(int, 1) not of type int). So, 
perhaps like this:


struct Initial(T, T val)
{
private T _payload = val;
alias _payload this;
this(T v)
{
_payload = v;
}
enum initial = val;
}

unittest
{
alias Initial!(int, 1) int1;
static assert(int1.initial == 1); // typeof(int1.initial) == 
int
static assert(int1.init == 1); // typeof(int1.init) == 
typeof(int1)

int1 i;
assert(i == 1);
int1 ii = 2;
assert(ii == 2);
assert(ii.init == 1);
assert(int1.init == 1);

void f(int val)
{
assert(val == 1);
}
f(i);

int i0;
assert(i0 == 0);
i = i0;
assert(i == 0);
assert(i.init == 1);
i0 = ii;
assert(i0 == 2);
assert(i0.init == 0);
}


Re: Associative array literal: length wrong when duplicate keys found

2017-01-31 Thread John Colvin via Digitalmars-d-learn

On Tuesday, 31 January 2017 at 14:15:58 UTC, Ivan Kazmenko wrote:

Hi.

I wanted to check whether a few variables of the same type are 
all distinct, in a quick and dirty way.  I tried to do it 
similar to Python's "len(set(value_list)) == len(value_list)" 
idiom by using an associative array (AA).  At this point, I 
found out that when initializing the AA with a literal, the 
length is the number of keys given, regardless of whether some 
of them were the same.


A minimized example:

-
import std.stdio;
void main () {
auto aa = [1 : 2, 1 : 3];
writeln (aa.length, " ", aa); // 2 [1:3, ]
}
-

See, the length is 2, but iteration over aa yields only one 
key:value pair.  Also, note the comma which is a sign of 
internal confusion as well.


My question is, what's the state of this?  Is this a bug?  Or 
should it be forbidden to have such an initializer?  Or maybe 
it is a feature with some actual merit?


Ivan Kazmenko.


It's a bug, please report it. The initializer should be 
statically disallowed.


Adding a .dup works around the problem.

By the way, you can do sets like this, avoiding storing any dummy 
values, only keys:


struct Set(T)
{
void[0][T] data;

void insert(T x)
{
data[x] = (void[0]).init;
}

void remove(T x)
{
data.remove(x);
}

bool opBinaryRight(string op : "in")(T e)
{
return !!(e in data);
}

// other things like length, etc.
}

unittest
{
Set!int s;
s.insert(4);
assert(4 in s);
s.remove(4);
assert(4 !in s);
}


Re: non-constant expression ["foo":5, "bar":10, "baz":2000]

2016-11-27 Thread John Colvin via Digitalmars-d-learn
On Saturday, 26 November 2016 at 17:37:57 UTC, Paolo Invernizzi 
wrote:

This is stated in documentation [1]:

immutable long[string] aa = [
  "foo": 5,
  "bar": 10,
  "baz": 2000
];

unittest
{
assert(aa["foo"] == 5);
assert(aa["bar"] == 10);
assert(aa["baz"] == 2000);
}

But results to:

   Error: non-constant expression ["foo":5L, "bar":10L, 
"baz":2000L]


Known bug?
If yes, Is there the need to emend the documentation, till the 
bug is open?

---
/Paolo


Known bug.

If you need a workaround, initialising the variable at load-time 
with `static this` should help in some cases.


Re: Updated D then undefined symbols in vibed

2016-11-24 Thread John Colvin via Digitalmars-d-learn

On Thursday, 24 November 2016 at 09:52:32 UTC, Jot wrote:
Using vibe D. designed to update dmd to latest and then I now 
get the following errors:


.dub\obj\debug\dev\source\app.obj(app)
 Error 42: Symbol Undefined 
_D3std6format12arrayPtrDiffFNaNbNiNexAvxAvZi

.dub\obj\debug\dev\source\app.obj(app)
 Error 42: Symbol Undefined 
_D3std5stdio4File17LockingTextWriter7handle_MFNdNeZPS4core4stdc5stdio6_iobuf (@property @trusted core.stdc.stdio._iobuf* std.stdio.File.LockingTextWriter.handle_())

.dub\obj\debug\dev\source\app.obj(app)
 Error 42: Symbol Undefined 
_D3std8datetime7SysTime6toHashMxFNaNbNiNfZk


when I clean the solution I eventually end up with a bunch more 
errors.


Symbol Undefined 
_D3std6random109__T21MersenneTwisterEngineTkVki32Vki624Vki397Vki31Vki2567483615Vki11Vki7Vki263691417EDFC9546C199E5D72A199057D68B


Symbol Undefined 
_D3std5regex8internal6parser7CodeGen8popFixupMFZk (uint 
std.regex.internal.parser.CodeGen.popFixup())


Symbol Undefined 
_D3std5regex8internal6parser7CodeGen13genNamedGroupMFAyaZv 
(void 
std.regex.internal.parser.CodeGen.genNamedGroup(immutable(char)[]))


Symbol Undefined 
_D3std5regex8internal6parser7CodeGen6lengthMFNdZk (@property 
uint std.regex.internal.parser.CodeGen.length())


etc...

Seems like someone decided to screw up a lot of people by 
removing a lot of stuff ;/ I guess I should learn my lesson 
about assuming a "stable" dmd release won't completely kill my 
project.


those are internal symbols, meaning that it's very (like 99% 
certain, unless you or one of your dependencies is manually 
redeclaring those symbols using their mangled names) likely that 
the cause is that something, somewhere, hasn't been cleaned 
properly.


Re: Array operations with multidimensional arrays

2016-11-19 Thread John Colvin via Digitalmars-d-learn

On Saturday, 19 November 2016 at 19:36:50 UTC, Marduk wrote:
On Saturday, 19 November 2016 at 17:37:58 UTC, John Colvin 
wrote:

On Saturday, 19 November 2016 at 10:20:16 UTC, Marduk wrote:
Additionally, I would like to assign 2D sub-arrays of a 3D 
array, i.e. something like the following:


int[3][2][2] a;

a[0] = [[2,2], [2,2]];


You have the dimensions the wrong way around. a is a 2 element 
array of 2 element arrays of 3 element arrays.


int[3][2][2] a;
a[0] = [[2,2,2], [2,2,2]];

works fine.


Thanks a lot! Now I get what it means that array declarations 
are read from right to left.


The way I think about it is this:

int is a type. int[3] is an array of 3 ints. Similarly, int[3] is 
a type, so an array of 2 int[3]s is int[3][2] and so on...


Re: Array operations with multidimensional arrays

2016-11-19 Thread John Colvin via Digitalmars-d-learn

On Saturday, 19 November 2016 at 10:20:16 UTC, Marduk wrote:
Additionally, I would like to assign 2D sub-arrays of a 3D 
array, i.e. something like the following:


int[3][2][2] a;

a[0] = [[2,2], [2,2]];


You have the dimensions the wrong way around. a is a 2 element 
array of 2 element arrays of 3 element arrays.


int[3][2][2] a;
a[0] = [[2,2,2], [2,2,2]];

works fine.


Re: splitter trouble

2016-11-01 Thread John Colvin via Digitalmars-d-learn

On Sunday, 30 October 2016 at 23:57:11 UTC, Ali Çehreli wrote:
While working on a solution for Alfred Newman's thread, I came 
up with the following interim solution, which compiled but 
failed:


auto parse(R, S)(R range, S separators) {
import std.algorithm : splitter, filter, canFind;
import std.range : empty;

static bool pred(E, S)(E e, S s) {
return s.canFind(e);
}

return range.splitter!pred(separators).filter!(token => 
!token.empty);

}

unittest {
import std.algorithm : equal;
import std.string : format;
auto parsed = parse("_My   input.string", " _,.");
assert(parsed.equal([ "My", "input", "string" ]), 
format("%s", parsed));

}

void main() {
}

The unit test fails and prints

["put", "ing"]

not the expected

["My", "input", "string"].

How is that happening? Am I unintentionally hitting a weird 
overload of splitter?


Ali


As usual, auto-decoding has plumbed the sewage line straight in 
to the drinking water...


Splitter needs to know how far to skip when it hits a match. 
Normally speaking - for the pred(r.front, s) overload that you're 
using here - the answer to that question is always 1. Except in 
the case of narrow strings, where it's whatever the encoded 
length of the separator is in the encoding of the source range 
(in this case utf-8), in order to skip e.g. a big dchar.* But in 
your case, your separator is more than one character, but you 
only want to skip forward one, because your separator isn't 
really a separator.


* see 
https://github.com/dlang/phobos/blob/d6572c2a44d69f449bfe2b07461b2f0a1d6503f9/std/algorithm/iteration.d#L3710


Basically, what you're doing isn't going to work. A separator is 
considered to be a separator, i.e. something to be skipped over 
and twisting the definition causes problems.


This will work, but I can't see any way to make it @nogc:

auto parse(R, S)(R range, S separators) {
import std.algorithm : splitter, filter, canFind;
import std.range : save, empty;

return range
.splitter!(e => separators.save.canFind(e))
.filter!(token => !token.empty);
}


Re: Draw math formulas with ggplotd

2016-09-17 Thread John Colvin via Digitalmars-d-learn
On Saturday, 17 September 2016 at 12:09:04 UTC, Edwin van Leeuwen 
wrote:
On Saturday, 17 September 2016 at 11:57:17 UTC, John Colvin 
wrote:
On Saturday, 17 September 2016 at 11:45:07 UTC, Edwin van 
Leeuwen wrote:

But I assumed he meant adding the formula onto the plot.


Hah, yes, I should have read the question better.


Rereading the question I am actually not sure which of us 
interpreted the question correctly :)


Do you support embedding outside images? When I wanted nice 
mathematical notation generated quickly in D I have used pyd 
to call matplotlib's builtin math rendering (much quicker than 
a full latex roundtrip).


You can draw onto any cairo surface, so this should be 
possible. You'd just need to figure out how to cast/convert a 
matplotlib image to a cairo image.


You just get back an alpha mask as an array of arrays, so it 
should be straightforward from there. What would be useful would 
be integration with ggplotd so it could be placed appropriately. 
Would be even better if e.g. the user could specify a function to 
render text and ggplotd would call it with tick label strings etc.


Re: Draw math formulas with ggplotd

2016-09-17 Thread John Colvin via Digitalmars-d-learn
On Saturday, 17 September 2016 at 11:45:07 UTC, Edwin van Leeuwen 
wrote:
On Saturday, 17 September 2016 at 11:22:04 UTC, John Colvin 
wrote:

On Saturday, 17 September 2016 at 02:41:15 UTC, brocolis wrote:
How do I draw math formulas programmatically? I want to do on 
screen what latex does on .pdf.


And I want to draw a math formula in the image generated with 
ggplotd.


Generate data from those formulas (I like to do this with 
something like iota(0, 10, 0.05).map!(x => sqrt(x) / (1 + 
sin(x)^^2)) and then plot that.


For this part ggplotd does have a helper function:

http://blackedder.github.io/ggplotd/ggplotd/stat.html#statFunction

auto gg = statFunction(x => sqrt(x) / (1 +
  sin(x)^^2), 0.0, 10).geomLine().putIn(GGPlotD());

But I assumed he meant adding the formula onto the plot.


Hah, yes, I should have read the question better. Do you support 
embedding outside images? When I wanted nice mathematical 
notation generated quickly in D I have used pyd to call 
matplotlib's builtin math rendering (much quicker than a full 
latex roundtrip).


Re: Draw math formulas with ggplotd

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

On Saturday, 17 September 2016 at 02:41:15 UTC, brocolis wrote:
How do I draw math formulas programmatically? I want to do on 
screen what latex does on .pdf.


And I want to draw a math formula in the image generated with 
ggplotd.


Generate data from those formulas (I like to do this with 
something like iota(0, 10, 0.05).map!(x => sqrt(x) / (1 + 
sin(x)^^2)) and then plot that.


If you want to use actual latex you would need a program to 
convert it to code. Mathematica can convert latex to C, which 
would then be easy to port to D.


Either way, if I remember correctly there is a simple line plot 
example in ggplotd's README.md


Re: Compile Tango for DMD2 - Any instructions how to do it?

2016-05-18 Thread John Colvin via Digitalmars-d-learn

On Wednesday, 18 May 2016 at 12:24:06 UTC, TheDGuy wrote:

On Wednesday, 18 May 2016 at 03:15:25 UTC, Mike Parker wrote:

That should get your library.


Thanks for your answer. I tried that on my windows console and 
i got the error that the command 'dub' can't be found.


http://code.dlang.org/download


Re: opDispatch and UFCS

2016-05-11 Thread John Colvin via Digitalmars-d-learn

On Thursday, 12 May 2016 at 00:04:43 UTC, Adam D. Ruppe wrote:

On Wednesday, 11 May 2016 at 23:46:48 UTC, John Colvin wrote:
Bug? Or am I misunderstanding how these two features are 
supposed to interact?


I'm not sure what you actually expected there, but I'd note 
that in general, opDispatch will always be preferred over UFCS, 
just like any other member access, so if you have an 
unrestricted opDispatch, you basically disable ufcs on the type.


I think I was hoping that the opDispatch wouldn't compile in the 
second case and it would therefore fail-over to UFCS.


std.typecons.Proxy (and therefore Typedef) seems to get around 
this:


import std.typecons;

alias Blah = Typedef!(int);

void foo(Blah a){}

void main()
{
Blah.init.foo;
}

work fine.


opDispatch and UFCS

2016-05-11 Thread John Colvin via Digitalmars-d-learn

struct S
{
int a;
template opDispatch(string s)
{
template opDispatch(T...)
{
auto ref opDispatch(Args ...)(auto ref Args args)
{
return S(mixin(`a.` ~ s ~ (T.length ? `!T` : ``) 
~ `(args)`));

}
}
}
}

int foo(int a, int b)
{
return a + b;
}

S bar(S s, int b)
{
return S(s.a - b);
}

unittest
{
auto s = S(3);
s = s.bar(1);
assert(s.a == 2);
s = s.foo(1);
assert(s.a == 3);
}

this gives me:

test.d-mixin-10(10): Error: function opdispatchtest.bar (S s, int 
b) is not callable using argument types (int, int)
test.d(29): Error: template instance 
test.S.opDispatch!"bar".opDispatch!().opDispatch!int error 
instantiating


Bug? Or am I misunderstanding how these two features are supposed 
to interact?


Re: Chaining opIndex

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

On Monday, 9 May 2016 at 20:14:25 UTC, deed wrote:

struct Foo {
Bars bars;
...
}

struct Foos {
Foo[] arr;
Foo opIndex (size_t idx) { return arr[idx]; }
...
}

struct Bar {
// No Car[] cars;
...
}

struct Bars {
Bar[] arr;
Bar opIndex (size_t idx) { return arr[idx]; }
...
}

struct Car {
...
}

Foos foos;
Foo foo = foos[1];  // Works
Bar bar = foos[1].bars[2];  // Works
Car car = foos[1].bars[2].cars[3];  // Desired abstraction.

For any Bar there are some Cars, but Bar doesn't hold any Cars. 
In other words, there could be a function Car cars (Bar bar, 
size_t idx) { ... }, but that would be called with parens;


Car car = foos[i].bars[j].cars(k);

which would be inconsistent and confusing. Defining

struct Cars {
Car opIndex (Bar bar, size_t idx) {}
}

and

struct Bar {
Cars cars;
...
}

doesn't enable chaining and then would have to be used like 
this, AFAIK:


Car car = cars[foos[i].bars[j], k];

Which is out of the question. Any suggestions to achieve the 
desired abstraction in a clean manner?


There are lots of ways to approach this. Here's one possibility:

auto cars(Bar bar)
{
static struct Res
{
Bar bar;
Car opIndex(size_t i)
{
return /* e.g. getCar(bar, i); */
}
}
return Res(bar);
}


Re: No aa.byKey.length?

2016-04-04 Thread John Colvin via Digitalmars-d-learn

On Monday, 4 April 2016 at 02:32:56 UTC, Yuxuan Shui wrote:

On Monday, 4 April 2016 at 00:50:27 UTC, Jonathan M Davis wrote:
On Sunday, April 03, 2016 23:46:10 John Colvin via 
Digitalmars-d-learn wrote:
On Saturday, 2 April 2016 at 16:00:51 UTC, Jonathan M Davis 
wrote:

> [...]

Maybe

aa.byKey().takeExactly(aa.length)


Yeah, that's a clever workaround.

- Jonathan M Davis


So should we not add length to byKey?


Yes. But until that happens, my workaround allows you to carry on 
getting work done :)


Re: No aa.byKey.length?

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

On Saturday, 2 April 2016 at 16:00:51 UTC, Jonathan M Davis wrote:
On Saturday, April 02, 2016 15:38:30 Ozan via 
Digitalmars-d-learn wrote:

On Friday, 1 April 2016 at 20:50:32 UTC, Yuxuan Shui wrote:
> Why?
>
> This is annoying when I need to feed it into a function that 
> requires hasLength.


aa.keys.length


That allocates an array. Doing that would be like doing
aa.byKeys().array().length. And associate arrays already have 
length. You

can do

auto len = aa.length;

The problem is when you want to operate on a range, and the 
function that you want to pass it to wants length on the range. 
If byKeys returned a range with length, then that would work, 
but since it doesn't, it doesn't. Having other ways to get the 
length doesn't help.


- Jonathan M Davis


Maybe

aa.byKey().takeExactly(aa.length)


Re: Is D a good choice for embedding python/octave/julia

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

On Sunday, 13 March 2016 at 13:02:16 UTC, Bastien wrote:

Hi, apologies for what may be a fairly obvious question to some.

## The background:
I have been tasked with building software to process data 
output by scientific instruments for non-experts - basically 
with GUI, menus, easy config files (JSON or similar) - and the 
ability to do some serious number crunching.


[...]


If the other language has some C api that can be called to 
interpret code then you can do so from D as well. See also e.g. 
https://github.com/ariovistus/pyd to make this easier for python.


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 .


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: Calling python code from D

2016-02-26 Thread John Colvin via Digitalmars-d-learn

On Friday, 26 February 2016 at 17:15:02 UTC, Wyatt wrote:

On Thursday, 25 February 2016 at 22:28:52 UTC, jmh530 wrote:

I think PyD is really your best option.


That's what I figured, but I wanted to be sure because, well...


http://pyd.readthedocs.org/en/latest/embed.html


...these are some sparse docs.

I did stumble into them, but it feels like a bit of a 
work-in-progress or second-class citizen, so I was kind of 
hoping someone else had taken the torch and run with it.


Maybe I'll have to shave a yak. :/

-Wyatt


Docs are quite sparse, but it mostly works as expected.

I have a WIP cleanup of the library in my fork. It won't help 
with docs of course...


Re: Installing DUB on OSX

2016-02-19 Thread John Colvin via Digitalmars-d-learn

On Thursday, 18 February 2016 at 23:28:43 UTC, Joel wrote:
On Thursday, 18 February 2016 at 16:33:51 UTC, John Colvin 
wrote:

[...]


I don't think I put 'sudo brew' at any point (I can't 
remember). I hope I haven't broken my OSX!


[...]


Did you recently upgrade OS X? Anyway, you should probably work 
through the suggestions from brew doctor, then brew update, then 
brew upgrade.


Re: Installing DUB on OSX

2016-02-18 Thread John Colvin via Digitalmars-d-learn

On Thursday, 18 February 2016 at 07:52:11 UTC, Joel wrote:

On Thursday, 18 February 2016 at 07:11:23 UTC, Joel wrote:
I had dub installed in a folder that meant I had to put 'sudo 
dub' to run it. I've tried to fix the problem, but where do 
you put it (also I tried one place, but couldn't put it in 
that folder)?


I've now tried 'brew install dub' and 'brew upgrade dub', but 
they come up with, 'Warning: dub-0.9.22 already installed', or 
'Error: dub 0.9.22 already installed'.


Sounds like you have some problems with your homebrew. What does 
`brew doctor` give? Did you accidentally use `sudo brew` at some 
point?


Re: Procedural drawing using ndslice

2016-02-11 Thread John Colvin via Digitalmars-d-learn

On Thursday, 11 February 2016 at 13:05:41 UTC, Claude wrote:

Hello,

I come from the C world and try to do some procedural terrain 
generation, and I thought ndslice would help me to make things 
look clean, but I'm very new to those semantics and I need help.


Here's my problem: I have a C-style rough implementation of a 
function drawing a disk into a 2D buffer. Here it is:



import std.math;
import std.stdio;

void draw(ref float[16][16] buf, int x0, int y0, int x1, int y1)
{
float xc = cast(float)(x0 + x1) / 2;
float yc = cast(float)(y0 + y1) / 2;
float xr = cast(float)(x1 - x0) / 2;
float yr = cast(float)(y1 - y0) / 2;

float disk(size_t x, size_t y)
{
float xx, yy;
xx = (x - xc) / xr;
yy = (y - yc) / yr;
return 1.0 - sqrt(xx * xx + yy * yy);
}

for (int y = 0; y < 16; y++)
{
for (int x = 0; x < 16; x++)
{
buf[x][y] = disk(x, y);
writef(" % 3.1f", buf[x][y]);
}
writeln("");
}
}

void main()
{
float[16][16] buf;

draw(buf, 2, 2, 10, 10);
}


The final buffer contains values where positive floats are the 
inside of the disk, negative are outside, and 0's represents 
the perimeter of the disk.


I would like to simplify the code of draw() to make it look 
more something like:


Slice!(stuff) draw(int x0, int y0, int x1, int y1)
{
float disk(size_t x, size_t y)
{
// ...same as above
}

return Slice!stuff.something!disk.somethingElseMaybe;
}

Is it possible?

Do I need to back-up the slice with an array, or could the 
slice be used lazily and modified as I want using some other 
drawing functions.


auto diskNoiseSlice = diskSlice.something!AddNoiseFunction;

... until I do a:

auto buf = mySlice.array;

... where the buffer would be allocated in memory and filled 
with the values according to all the drawing primitives I used 
on the slice.


I had a go at trying the sort of thing you are talking about: 
http://dpaste.dzfl.pl/8f9da4f4cc34


That won't work with std.experimental.ndslice in 2.070.0, so 
either use dmd git master or use the latest version of ndslice in 
mir (https://github.com/DlangScience/mir).


Re: noob in c macro preprocessor hell converting gsl library header files

2016-01-06 Thread John Colvin via Digitalmars-d-learn
On Wednesday, 6 January 2016 at 13:36:03 UTC, data pulverizer 
wrote:
I have been converting C numeric libraries and depositing them 
here: https://github.com/dataPulverizer. So far I have glpk and 
nlopt converted on a like for like c function basics. I am now 
stuck on the gsl library, primarily because of the preprocessor 
c code which I am very new to. The following few are 
particularly baffling to me:


#define INLINE_FUN extern inline // used in gsl_pow_int.h: 
INLINE_FUN double gsl_pow_2(const double x) { return x*x;   }


Could I just ignore the INLINE_FUN and use alias for function 
pointer declaration? For example ...


alias gsl_pow_2 = double gsl_pow_2(const(double) x);


Yes, you should be able to ignore INLINE_FUN

double gsl_pow_2(const double x);

is the correct declaration.

#define INLINE_DECL // used in interpolation/gsl_interp.h: 
INLINE_DECL size_t gsl_interp_bsearch(const double x_array[], 
double x, size_t index_lo, size_t index_hi);


I would guess the same as for INLINE_FUN?


yes

#define GSL_VAR extern // used in rng/gsl_rng.h:GSL_VAR const 
gsl_rng_type *gsl_rng_borosh13;


perhaps GSL_VAR can be ignored and I could use:

gsl_rng_borosh13 const(gsl_rng_type)*;


It should be

extern gsl_rng_type* gsl_rng_borosh13;

I have been using these kind of fixes and have not been able to 
get the rng module to recognise the ported functions, meaning 
that something has been lost in translation.


I am currently getting the following error:

$ gsl_rng_print_state

rng_example.o: In function `_Dmain':
rng_example.d:(.text._Dmain+0x13): undefined reference to 
`gsl_rng_print_state'

collect2: error: ld returned 1 exit status

I can't seem to call any of the functions but the types are 
recognized.


Thanks in advance


I think you might have some confusion between function 
declarations:


T myFunction(Q myArg);

function pointer type declarations:

alias MyFunctionPointerType = T function(Q myArg);

and function pointer declarations:

MyFunctionPointerType myFunctionPointer;


Re: immutable promise broken in unions?

2016-01-02 Thread John Colvin via Digitalmars-d-learn
On Saturday, 2 January 2016 at 10:04:47 UTC, Shriramana Sharma 
wrote:

import std.stdio;
union EarthLocation
{
struct { immutable double lon, lat, alt; }
double[3] data;
}
void main()
{
EarthLocation d = {data: [4, 5, 6]};
writeln(d.data);
d.data = [1, 2, 3];
writeln(d.data);
}

I get the output:

[4, 5, 6]
[1, 2, 3]

I thought the promise of `immutable` was: never changes, 
whether via this interface or otherwise. How does then the 
above work?


Using DMD 2.0.69.2 on Kubuntu 64 bit.


You are manually breaking immutable by making a union of 
immutable and mutable data and then writing to the mutable 
reference. This is roughly equivalent to casting away immutable 
and then writing to the reference. It's a bug in your code.


All references to the same data should be
1) either immutable or const
or all the references should be
2) either mutable or const (assuming the data was never 
immutable).

Anything else is dangerous.


Re: immutable promise broken in unions?

2016-01-02 Thread John Colvin via Digitalmars-d-learn

On Saturday, 2 January 2016 at 12:08:48 UTC, Meta wrote:

On Saturday, 2 January 2016 at 12:07:31 UTC, John Colvin wrote:
You are manually breaking immutable by making a union of 
immutable and mutable data and then writing to the mutable 
reference. This is roughly equivalent to casting away 
immutable and then writing to the reference. It's a bug in 
your code.


All references to the same data should be
1) either immutable or const
or all the references should be
2) either mutable or const (assuming the data was never 
immutable).

Anything else is dangerous.


Surely the compiler should disallow this. It makes it trivial 
to break the type system otherwise.


Casting away immutable can sometimes be necessary (e.g. when 
talking to other languages), so I'm not sure it should be 
disallowed, but it'd be great if it was somehow easier to catch 
these bugs.


Re: Why isn't field-wise constructor automatic for structs and not classes?

2016-01-02 Thread John Colvin via Digitalmars-d-learn
On Saturday, 2 January 2016 at 02:12:19 UTC, Shriramana Sharma 
wrote:

If I have:

struct TimeSpan { double start, end; }

Then both the following automatically work:

auto s = TimeSpan();
auto t = TimeSpan(1, 2);

But if I make it a class (I need to) then I have to explicitly 
define a field-wise constructor else only a constructor with no 
args is automatically defined. Why can't the field-wise 
functionality be automatic for classes too?


Strictly speaking you aren't calling a constructor there, you're 
writing a struct literal.


Re: Why isn't field-wise constructor automatic for structs and not classes?

2016-01-02 Thread John Colvin via Digitalmars-d-learn
On Saturday, 2 January 2016 at 14:57:58 UTC, Shriramana Sharma 
wrote:

John Colvin wrote:

Strictly speaking you aren't calling a constructor there, 
you're writing a struct literal.


Why do you say I'm not calling a constructor?


https://dlang.org/spec/struct.html#struct-literal

And that still doesn't answer the question of why can't we have 
an automatic field-wise constructor for classes...


Classes aren't as simple as structs, they have hidden members, 
inherited members... Technically speaking the compiler is even 
allowed to change the ordering. They may be other reasons I'm not 
aware of / aren't thinking of right now.


Re: Segfault while compiling simple program

2015-12-16 Thread John Colvin via Digitalmars-d-learn

On Wednesday, 16 December 2015 at 10:15:49 UTC, Saurabh Das wrote:
On Wednesday, 16 December 2015 at 10:07:38 UTC, Saurabh Das 
wrote:
On Wednesday, 16 December 2015 at 09:38:24 UTC, Ali Çehreli 
wrote:

On 12/16/2015 01:26 AM, Saurabh Das wrote:

struct xlref
{
 ushort rwFirst;
 ushort rwLast;
 ubyte colFirst;
 ubyte colLast;
}

struct xlmref
{
 ushort count;
 xlref reflist;
}

Mac OS X (dmd 2.069.0)
===
dmd  dprob.d
Segmentation fault: 11


Compiler bug. Please report at

  https://issues.dlang.org/

Changing the order of the members of xlmref seems to be a 
workaround:


struct xlmref
{
xlref reflist;
ushort count;
}

Ali


We are using it to communicate with Excel, so swapping it is 
not an option.


I'll report it as a compiler bug. In the meantime, this is a 
workaround worked for me:


struct xlref
{
 ushort rwFirst;
 ushort rwLast;
 ubyte[2] cols;
}


Filed: https://issues.dlang.org/show_bug.cgi?id=15455

Under OS, I've selected Mac OS X since only 1 OS selection is 
allowed. Is the convention to select 'Other' in cases where 
ICEs are observed in multiple OSes?


Thanks,
Saurabh


I think it's more normal to select 'all' once it affects more 
than one. OS X only bugs are likely to get less attention because 
developers don't necessarily have the necessary machines to 
quickly test on. 'other' might be interpreted as something 
obscure. I'd say list it as 'all', chances are it crashes the 
same on linux as well.


Re: I Did It! Calling D Library from Objective C in XCode on OSX

2015-12-16 Thread John Colvin via Digitalmars-d-learn
On Wednesday, 16 December 2015 at 07:46:53 UTC, Jacob Carlborg 
wrote:

On 2015-12-15 15:43, John Colvin wrote:

I have no idea how you got something in /Library/D, but it 
doubt it

was from homebrew.


The native installer installs into /Library/D.


Well that probably explains the problem then.

Possible, but more likely a leftover from installing dmd some 
other way.
Seems to be the case in 90% of "I installed dmd using X and it 
didn't

work".


Shouldn't an installer make sure the files it installed is the 
files being used?


How exactly would it do that? I guess it could parse some output 
from dmd to check that it's looking in the right directories, 
that would be a nice enhancement.


I wouldn't want it to try and do much to fix the situation if it 
didn't work, that would be too intrusive.


The important thing is not to mix and match installers unless 
you know

how they work.


DVM will take precedence :)


How does it do that?

DVM seems useful if you really need multiple versions of DMD 
installed, but in general I don't like having a special installer 
tool for each piece of software, each with its own way of doing 
things.


Re: Segfault while compiling simple program

2015-12-16 Thread John Colvin via Digitalmars-d-learn

On Wednesday, 16 December 2015 at 09:26:33 UTC, Saurabh Das wrote:

struct xlref
{
ushort rwFirst;
ushort rwLast;
ubyte colFirst;
ubyte colLast;
}

struct xlmref
{
ushort count;
xlref reflist;
}

Mac OS X (dmd 2.069.0)
===
dmd  dprob.d
Segmentation fault: 11

Windows (dmd 2.069.2)
==
dmd -v -m64 dprob.d
binary C:\D\dmd2\windows\bin\dmd.exe
version v2.069.2
config C:\D\dmd2\windows\bin\sc.ini
parse xlcall_wrap2
importall xlcall_wrap2
import object 
(C:\D\dmd2\windows\bin\src\druntime\import\object.d)

semantic xlcall_wrap2

object.Error@(0): assert(0) or HLT instruction

0x0040496F
0x00404CF8
0x004CF2B6
0x004565A7
0x0044EAB0
0x004BF99E
0x74F757F9 in MultiByteToWideChar
0x76F2139E in RtlQueryProcessDebugInformation
0x76F21340 in RtlQueryProcessDebugInformation
0x76F21190 in RtlQueryProcessDebugInformation

What gives?

Saurabh


Any compiler crash is a bug, please report at issues.dlang.org

While you wait for it to be fixed, try swapping reflist and count 
and you should find it doesn't crash. You should probably do 
anyway to avoid wasting space in the struct 
(http://www.catb.org/esr/structure-packing/)


Re: I Did It! Calling D Library from Objective C in XCode on OSX

2015-12-14 Thread John Colvin via Digitalmars-d-learn

On Monday, 14 December 2015 at 11:12:03 UTC, Ali Çehreli wrote:

On 12/14/2015 02:09 AM, Mike McKee wrote:

I finally managed to get it working


Congratulations! But this is not the right medium for this blog 
post. ;) Please polish and publish it somewhere before someone 
puts it on Reddit now. :)


Ali


+1 It's great you've achieved this, it would make a good blog 
post.


P.S. Of course posting here is better than not telling anyone at 
all, but blog posts about D are somewhat in short supply.


Re: static array crashes my program

2015-12-05 Thread John Colvin via Digitalmars-d-learn

On Saturday, 5 December 2015 at 09:49:06 UTC, ref2401 wrote:
I want to create a static array large enough to store 1MB of 
float values.

What am I doing wrong?
Here is a sample code with notes:

void main(string[] args) {
enum size_t COUNT = 1024 * 512 / float.sizeof; // works OK :)
	//enum size_t COUNT = 1024 * 512 * 2 / float.sizeof; // 
constantly crashes :(

float[COUNT] arr;
writeln(arr.length);
}

DMD: 2069.2
OS: Win 8.1 Pro


The default stack size is probably 1MB, which means your 1MB 
array plus a few local variables is too much. Arrays that large 
should be allocated on the heap in most circumstances.


Watch out for this:
static assert(is(typeof(new float[3]) == float[]));
because `new T[n]` is a special case in the grammar. If you 
really must have a static array on the heap (as opposed to a 
dynamic array / slice T[]), you can use something like this, but 
i wouldn't recommend it:


T[N]* heapStaticArray(T, size_t N)()
{
return cast(T[N]*)((new T[N]).ptr);
}

void main()
{
int[4]* a = heapStaticArray!(int, 4)();
(*a)[] = 3;
}


Re: Exit with code xx

2015-11-25 Thread John Colvin via Digitalmars-d-learn

On Wednesday, 25 November 2015 at 16:11:09 UTC, Ozan wrote:

Hi

Is there any overview, list, wiki about what's behind runtime 
errors like

"Program exited with code -11"?

Okay, I made a mistake...but it's better to know where and what 
kind?


Thanks & Regards,
Ozan


That's just normal exit-code stuff, same as in C . Could be a 
segfault of some sort.


If you've compiled with -release and/or no bounds checks (can be 
hidden behind -O flags with ldc/gdc), try dropping those options 
and you might get a more useful error.


Alternatively, fire up a debugger and find where things went 
wrong the old-fashioned way, e.g.


$ gdb ./myProgram
(gdb) run
segfault, some information 
(gdb) bt full
full stack trace


Re: Is it a bug?

2015-11-25 Thread John Colvin via Digitalmars-d-learn
On Wednesday, 25 November 2015 at 08:10:03 UTC, Jack Applegame 
wrote:

This doesn't compile:

import std.range;
import std.algorithm;

void main() {
char[64] arr;
copy(chain("test1", "test2"), arr[0..10]);
}

http://dpaste.dzfl.pl/24230ac02e6e


Essentially this comes down to the question: 'Should output 
ranges auto-encode like input ranges auto-decode'. The code above 
suggests the answer is currently "no".


Workarounds:

Either do `dchar[64] arr;` or

import std.range;
import std.algorithm;
import std.utf;

void main() {
char[64] arr;
copy(chain("test1", "test2").byCodeUnit, arr[0..10].byCodeUnit);
}

ranges iterate over strings by code-point (i.e. dchar). 
byCodeUnit forces iteration by code-unit i.e. char. You could 
also do


import std.range;
import std.algorithm;

void main() {
char[64] arr;
	copy(chain(cast(immutable(ubyte)[])"test1", 
cast(immutable(ubyte)[])"test2"), cast(ubyte[])arr[0..10]);

}

or any other method that means you deal in ubyte[] instead of 
char[].


Re: dataframe implementations

2015-11-19 Thread John Colvin via Digitalmars-d-learn

On Thursday, 19 November 2015 at 06:33:06 UTC, Jay Norwood wrote:

On Wednesday, 18 November 2015 at 22:46:01 UTC, jmh530 wrote:
My sense is that any data frame implementation should try to 
build on the work that's being done with n-dimensional slices.


I've been watching that development, but I don't have a feel 
for where it could be applied in this case, since it appears to 
be focused on multi-dimensional slices of the same data type, 
slicing up a single range.


The dataframes often consist of different data types by column.

How did you see the nd slices being used?

Maybe the nd slices could be applied if you considered each row 
to be the same structure, and slice by rows rather than 
operating on columns.  Pandas supports a multi-dimension panel.

 Maybe this would be the application for nd slices by row.


You might not build on the nd slice type itself, but implementing 
the same API (where possible/appropriate) would be good.


Re: Arty of Constructor

2015-11-19 Thread John Colvin via Digitalmars-d-learn

On Thursday, 19 November 2015 at 06:20:28 UTC, Andrew wrote:
The documentation gives plenty of examples of how to use a 
static if with the arity trait, but how do I specify the 
constructor of an object as the parameter to arity?


Thanks


Ugly but works:

import std.traits;

struct A
{
this(int a, int b){}
}

pragma(msg, arity!(A.__ctor)); // prints 2

You may have to experiment with __traits(getOverloads, ...) if 
you have multiple constructors and want to look at all of them.


Re: Unable to call each on a lockstep range containing 2 or more ranges

2015-11-18 Thread John Colvin via Digitalmars-d-learn

On Wednesday, 18 November 2015 at 14:11:45 UTC, maik klein wrote:
On Wednesday, 18 November 2015 at 13:51:59 UTC, John Colvin 
wrote:
On Wednesday, 18 November 2015 at 12:20:42 UTC, maik klein 
wrote:

[...]


I think this is a bug, please report it at issues.dlang.org 
and perhaps there will be an explanation or it will be fixed.

In the mean time, something like this should work:

  auto arange2 = zip(ai[],ai1[],ai2[]);

  arange2.each!((t) => writeln(t[0], t[1], t[2]));
  // or if you really must have the names:
  arange2.each!((t) => (a,b,c){ writeln(a, b, c); }(t.expand));


Thanks, but the problem I have with zip is that it doesn't work 
with "ref".



for example

auto arange3 = zip(ai[],ai1[],ai2[]);
foreach(ref a; arange3){
  a[0] = 42;
}
Won't change anything. Is this another bug?


Unfortunately, yes: https://issues.dlang.org/show_bug.cgi?id=10541

Note that

while(!arange3.empty)
{
arange3.front[0] = 42;
arange3.popFront();
}

should work as expected.


Re: Unable to call each on a lockstep range containing 2 or more ranges

2015-11-18 Thread John Colvin via Digitalmars-d-learn

On Wednesday, 18 November 2015 at 12:20:42 UTC, maik klein wrote:

https://stackoverflow.com/questions/33779822/unable-to-call-each-on-a-lockstep-range-containing-2-or-more-ranges

http://dpaste.dzfl.pl/76c79f1f12ab

void main(){
  import std.container;
  import std.stdio;
  import std.algorithm.iteration;
  import std.range;
  Array!int ai = [1,2,3,4];
  Array!int ai1 = [1,2,3,4];
  Array!int ai2 = [1,2,3,4];

  auto arange = lockstep(ai[],ai1[]);
  arange.each!((a,b) => writeln(a, b));

  auto arange2 = lockstep(ai[],ai1[],ai2[]);
  arange2.each!((a,b,c) => writeln(a, b, c));
}

Error: template std.algorithm.iteration.each cannot deduce 
function from argument types !((a, b, c) => writeln(a, b, 
c))(Lockstep!(RangeT!(Array!int), RangeT!(Array!int), 
RangeT!(Array!int))), candidates are: 
/opt/compilers/dmd2/include/std/algorithm/iteration.d(820):

std.algorithm.iteration.each(alias pred = "a")


"arange" works but "arange2" doesn't because the compiler is 
unable to deduce the the function. The error even appears if I 
explicitly add the argument types.


I think this is a bug, please report it at issues.dlang.org and 
perhaps there will be an explanation or it will be fixed.

In the mean time, something like this should work:

  auto arange2 = zip(ai[],ai1[],ai2[]);

  arange2.each!((t) => writeln(t[0], t[1], t[2]));
  // or if you really must have the names:
  arange2.each!((t) => (a,b,c){ writeln(a, b, c); }(t.expand));


Re: Compiler doesn't complain with multiple definitions

2015-11-12 Thread John Colvin via Digitalmars-d-learn

On Thursday, 12 November 2015 at 15:06:26 UTC, ric maicle wrote:

On Thursday, 12 November, 2015 07:50 PM, anonymous wrote:
__traits has special syntax. The first "argument" must be from 
a list of
special keywords that only have special meaning in that place. 
You can't
put the name of a struct there, and you can't put the special 
keyword
anywhere else. So there's no ambiguity, and you're not 
redefining

anything. Everything's fine.


Thanks for clarifying __traits.

On another thing. I'm wondering why the compiler didn't issue a 
warning
on struct isPOD and byte isPOD? Isn't this called 'shadowing' 
or have I

misunderstood the term?


If I remember correctly:

Shadowing globals is allowed, all other instances of shadowing 
are not.


Re: Capturing __FILE__ and __LINE in a variadic templated function

2015-11-02 Thread John Colvin via Digitalmars-d-learn

On Monday, 2 November 2015 at 09:16:09 UTC, Nordlöw wrote:
On Monday, 2 November 2015 at 09:02:28 UTC, Gary Willoughby 
wrote:

On Monday, 2 November 2015 at 08:23:16 UTC, Nordlöw wrote:

I need `T` to be an alias in order for .stringof to work.


typeof(T).stringof


No, I want the variable name from the calling scope.

This works for a single argument.

void show(alias arg, string file = __FILE__, uint line = 
__LINE__, string fun = __FUNCTION__)()

{
import std.stdio: writeln;
try
{
debug writeln(file, ":",line, ":" /* , ": in ",fun */, 
" debug: ", arg.stringof, " is ", arg);

}
catch (Exception) { }
}

unittest
{
int x = 11;
show!x;
}

Prints

dbg.d:80: debug: x is 11

My try at variadic

template show(Args...)
{
void show(string file = __FILE__, uint line = __LINE__, 
string fun = __FUNCTION__)()

{
import std.stdio: write, writeln;
try
{
debug write(file, ":",line, ":" /* , ": in ",fun 
*/, " debug: ");

foreach (const i, Arg; Args)
{
if (i) debug write(", "); // separator
debug write(Arg.stringof, " is ", Arg);
}
debug writeln();
}
catch (Exception) { }
}
}

fails with compilation error

dbg.d(83,5): Error: variable x cannot be read at compile time

Why can't I make Args a sequence of aliases?


Works for me on multiple compilers. To be precise, this worked:

template show(Args...)
{
void show(string file = __FILE__, uint line = __LINE__, 
string fun = __FUNCTION__)()

{
import std.stdio: write, writeln;
try
{
debug write(file, ":",line, ":" /* , ": in ",fun */, 
" debug: ");

foreach (const i, Arg; Args)
{
if (i) debug write(", "); // separator
debug write(Arg.stringof, " is ", Arg);
}
debug writeln();
}
catch (Exception) { }
}
}

unittest
{
int x = 11;
show!x;
}



Re: `clear`ing a dynamic array

2015-10-24 Thread John Colvin via Digitalmars-d-learn
On Saturday, 24 October 2015 at 13:18:26 UTC, Shriramana Sharma 
wrote:
Hello. I had first expected that dynamic arrays (slices) would 
provide a `.clear()` method but they don't seem to. Obviously I 
can always effectively clear an array by assigning an empty 
array to it, but this has unwanted consequences that `[]` 
actually seems to allocate a new dynamic array and any other 
identifiers initially pointing to the same array will still 
show the old contents and thus it would no longer test true for 
`is` with this array. See the following code:


import std.stdio;
void main()
{
  int a[] = [1,2,3,4,5];
  int b[] = a;
  writeln(a);
  writeln(b);
  //a.clear();
  a = [];
  writeln(a);
  writeln(b);
}

which outputs:

[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
[]
[1, 2, 3, 4, 5]

How to make it so that after clearing `a`, `b` will also point 
to the same empty array? IOW the desired output is:


[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
[]
[]

... and any further items added to `a` should also reflect in 
`b`.


D's arrays are not pure reference types, they work like `struct 
Array(T) { size_t length; T* ptr; }` with some extra methods and 
operators. If you think of them like that it should be clear what 
is/isn't possible.


If you want to have two references to the same array, including 
the length, use T[]* or a ref argument to a function or wrap it 
in a class.


Re: Mixin template parameter that is an undefined variable

2015-10-23 Thread John Colvin via Digitalmars-d-learn

On Friday, 23 October 2015 at 12:22:49 UTC, tcak wrote:

[code]
mixin template Test(alias a){
int a;
}

void main(){
mixin Test!blah;
}
[/code]

Compiler says it doesn't know about "blah". My purpose is to
define the parameter as a variable. Is that possible?


you would have to use a string.

mixin template Test(string a)
{
mixin(`int ` ~ a ~ `;`);
}

void main()
{
mixin Test!"blah";
mixin Test!q{blah2};
}


Re: Using C's fread/fwrite with File objects

2015-10-22 Thread John Colvin via Digitalmars-d-learn

On Thursday, 22 October 2015 at 18:20:07 UTC, pineapple wrote:
I'd like to use fread and fwrite in place of File.rawRead and 
File.rawWrite which force the creation of an array where I'd 
rather specify a buffer location and length.


D's arrays *are* just buffer locations and lengths with a few 
extra properties, methods and operators.


T* ptrToBuffer = /* ... */;
size_t lengthOfBuffer = /* ... */;
T[] buffer = ptrToBuffer[0 .. lengthOfBuffer];
File f = /* ... */;
T[] filledPartOfBuffer = f.rawRead(buffer);

Note that at no point in the above is a new buffer allocated.


Re: Allowing arbitrary types for a function's argument and return type

2015-10-22 Thread John Colvin via Digitalmars-d-learn

On Thursday, 22 October 2015 at 13:53:33 UTC, pineapple wrote:
I'm just starting to hammer D's very pleasant syntax into my 
head. After "Hello world", the first thing I do when learning 
any language is to write a simple program which generates and 
outputs the Collatz sequence for an arbitrary number. (I also 
like to golf it.) This is what I wrote in D:


import std.stdio;void main(){int i;readf(" 
%d",);while(i>1){writeln(i=i%2?i*3+1:i/2);}}


Any ways I could shorten it further?

Anyway, then I thought I should try something that was less of 
a mess, too, and wrote this:


import std.concurrency;
Generator!int sequence(int i){
return new Generator!int({
yield(i);
while(i > 1){
yield(i = (i % 2) ? (i * 3 + 1) : (i >> 1));
}
});
}

Which can be used like so:

import std.stdio;
void main(){
foreach(i; sequence(11)){
writeln(i);
}
}

And now I'd like to make one more improvement, but this I 
haven't been able to figure out. What if I wanted the argument 
and output types to be longs instead of ints? Or some other, 
arbitrary discrete numeric type? Is there any template-like 
syntax I can use here instead of just copypasting for each 
numeric type I can think of? I've been spoiled by the likes of 
Python to be thinking in this duck-typing way.


Thanks!


Using ranges instead of threads or fibers, slightly 
over-engineered to show off features:


import std.traits : isIntegral;

auto collatzStep(T)(T i)
if(isIntegral!T)
{
return (i % 2) ? (i * 3 + 1) : (i >> 1);
}

auto collatz(T)(T a)
if(isIntegral!T)
{
import std.range : recurrence;
import std.algorithm : until, OpenRight;
return a.recurrence!((a, n) => collatzStep(a[n-1]))
.until!(n => n == 1)(OpenRight.no);
}

unittest
{
import std.algorithm : equal;
import std.range : only;
assert(collatz(6L).equal(only(6, 3, 10, 5, 16, 8, 4, 2, 1)));
}


Re: Allowing arbitrary types for a function's argument and return type

2015-10-22 Thread John Colvin via Digitalmars-d-learn

On Thursday, 22 October 2015 at 15:10:58 UTC, pineapple wrote:

On Thursday, 22 October 2015 at 14:36:52 UTC, John Colvin wrote:
Using ranges instead of threads or fibers, slightly 
over-engineered to show off features:


What does if(isIntegral!T) do? It looks like it would verify 
that the template type is a discrete number? If I were to 
create my own class, say a BigNum as an example, how could I 
specify that the isIntegral condition should be met for it?


Only with builtin types: 
http://dlang.org/phobos/std_traits.html#isIntegral
However there are a variety of ways you could mark special 
properties of types and have your own isIntegral-like template 
that recognised them. user-defined-attributes are one 
possibility, adding an `enum isIntegral = true;` is another.


Apart from the aesthetics, what are the functional differences 
between using recurrence and using a Generator? Will one be 
more efficient than the other?


ranges are likely to be more efficient because, apart from 
anything else, they are easier for the compiler to reason about 
and optimise. Both are good tools, but ranges are more widespread 
in D.


It's not fair how easy it is to incorporate unit tests in D. 
Now what excuse will I have when my code is buggy?


:)


Re: D serialization temporary fixup?

2015-10-22 Thread John Colvin via Digitalmars-d-learn
On Thursday, 22 October 2015 at 16:15:23 UTC, Shriramana Sharma 
wrote:
I wanted a D equivalent to: 
http://doc.qt.io/qt-5/qdatastream.html 
https://docs.python.org/3/library/pickle.html


and saw that one is under construction: 
http://wiki.dlang.org/Review/std.serialization


But till it's finalized, I'd just like to have a quick but 
reliable way to store real and int data types into a binary 
data file and read therefrom. Is there such a solution? The 
size of the data is fixed, but especially since I have real 
values, I'd like to not write to limited fixed decimal text 
format.


Simple lumps of binary data can just be written directly using 
http://dlang.org/phobos/std_file.html#.write or 
http://dlang.org/phobos/std_stdio.html#.File.rawWrite

and there are corresponding functions for reading.


Re: Overloading an imported function

2015-10-21 Thread John Colvin via Digitalmars-d-learn
On Wednesday, 21 October 2015 at 12:05:27 UTC, Shriramana Sharma 
wrote:

import std.math;
real round(real val, int prec)
{
real pow = 10 ^^ prec;
return round(val * pow) / pow;
}

Trying to compile this I get:

foo.d(5): Error: function foo.round (real val, int prec) is not 
callable using argument types (real)


When I've imported std.math which contains round(real), why is 
the compiler complaining about not being able to call the 
overload function defined in *this* module?


I don't see anything in http://dlang.org/module.html that says 
I cannot define an overload of an imported function. Did I miss 
something?


You might find something useful in section 2 of 
https://github.com/DlangScience/design/blob/master/design.pdf and 
also somewhat related: 
http://arsdnet.net/this-week-in-d/sep-27.html


Re: Just one time

2015-10-20 Thread John Colvin via Digitalmars-d-learn

On Tuesday, 20 October 2015 at 15:48:47 UTC, Andrea Fontana wrote:
It happens I need to perform an operation just one time (inside 
a function, a loop...)


I wonder if doing this it's a good idea or not.

bool isFirstTime(alias T)()
{
static val = true;

if (val)
{
val = false;
return true;
}

return false;
}

So:

void my_func()
{
if (isFirstTime!my_func) writeln("First call!");
else writeln("Just another call");
}

myfunc(); // Print First call!
myfunc(); // Print Just another call;

Or (for example inside a for loop):

assert(isFirstTime!"blah" == true);
assert(isFirstTime!"blah" == false);

Does it work as expected?


I think that's ok, because each unique (i.e. with a different 
parameter) instantiation of isFirstTime will have its own static 
val.


Be aware that there will be one instance of val per thread, so 
you are detecting the first run in each thread, not in the 
program overall.


Re: Just one time

2015-10-20 Thread John Colvin via Digitalmars-d-learn

On Tuesday, 20 October 2015 at 16:01:58 UTC, Andrea Fontana wrote:

On Tuesday, 20 October 2015 at 15:55:47 UTC, John Colvin wrote:
Be aware that there will be one instance of val per thread, so 
you are detecting the first run in each thread, not in the 
program overall.


This is the kind of thing I'm interested in.
What happens if I call  isFirstTime!"test" across different 
modules? Does instatiation works in the same way for all 
compilers/platform?


Other things to consider?


It should work exactly the same across modules, just one instance 
per thread. Same on all platforms and compilers.


Re: Idiomatic adjacent_difference

2015-10-16 Thread John Colvin via Digitalmars-d-learn
On Friday, 16 October 2015 at 11:11:28 UTC, Guillaume Chatelet 
wrote:

Is there an idiomatic way to do:

int[] numbers = [0, 1, 2, 3];
assert(adjacent_diff(numbers) == [1, 1, 1]);

I can't find something useful in the std library.


import std.range, std.algorithm;

auto slidingWindow(R)(R r, size_t n)
if(isForwardRange!R)
{
//you could definitely do this with less overhead
return roundRobin(r.chunks(n), r.save.drop(1).chunks(n))
.filter!(p => p.length == n);
}

auto adjacentDiff(R)(R r)
{
return r.slidingWindow(2).map!"a[1] - a[0]";
}

unittest
{
import std.stdio;
int[] numbers = [0, 1, 2, 3];
writeln(numbers.slidingWindow(2));
writeln(adjacentDiff(numbers));
assert(adjacentDiff(numbers).equal([1, 1, 1]));
}


Re: Idiomatic adjacent_difference

2015-10-16 Thread John Colvin via Digitalmars-d-learn

On Friday, 16 October 2015 at 12:03:56 UTC, Per Nordlöw wrote:
On Friday, 16 October 2015 at 11:48:19 UTC, Edwin van Leeuwen 
wrote:

zip(r, r[1..$]).map!((t) => t[1]-t[0]);


And for InputRanges (not requiring random-access):

zip(r, r.dropOne).map!((t) => t[1]-t[0]);


We should have a good implementation of slidingWindow in 
std.range, it's a useful iteration pattern (although it does 
sometimes encourage inefficient algorithms).


Re: Frequent cannot deduce function from argument types

2015-10-16 Thread John Colvin via Digitalmars-d-learn
On Friday, 16 October 2015 at 15:48:59 UTC, Edwin van Leeuwen 
wrote:
Just wondering if anyone has any tips on how to solve/avoid 
"cannot deduce function from argument types" when relying on 
template programming.


I run into these problems all the time. Current one was when I 
tried:


```
auto ys = NumericLabel(groupedAes.front.map!((t)=>t.y));
```

NumericLabel is a pretty minimal templated InputRange, with as 
only requirement on the argument that it is also an InputRange. 
I then get the following compile error:


```
source/ggplotd/geom.d(83,35): Error: struct 
ggplotd.aes.NumericLabel cannot ded
uce function from argument types !()(MapResult!(__lambda2, 
FilterResult!(__lamb
da2, Aes!(double[], "x", double[], "y", string[], "colour", 
candidates are:
source/ggplotd/aes.d(515,1):ggplotd.aes.NumericLabel(T) 
if (isInputRang

e!T)
```

As far as I know MapResult always returns an input range and as 
you can see there is only one candidate of NumericLabel, so to 
be honest it looks relatively straightforward to me.


Now I can define the type specifically (and/or typeof) but it 
seems like there should be a better way.


In this case typeof isn't even happy:
```
source/ggplotd/geom.d(84,17): Error: constructor 
ggplotd.aes.NumericLabel!(MapResult!(__lambda2, 
FilterResult!(__lambda2, Aes!(string[], "x", string[], "y", 
string[], "colour".NumericLabel.this (MapResult!(__lambda2, 
FilterResult!(__lambda2, Aes!(string[], "x", string[], "y", 
string[], "colour"))) range) is not callable using argument 
types (MapResult!(__lambda3, FilterResult!(__lambda2, 
Aes!(string[], "x", string[], "y", string[], "colour"

```

If we look closely, it expects a __lambda2 as the MapResult 
argument, but it gets a __lambda3.



I am able to work around it by converting the mapresult to an 
array, but I'd rather use a lazy solution.


My first steps would be to try

pragma(msg, 
isInputRange!(typeof(groupedAes.front.map!((t)=>t.y;

followed by
pragma(msg, isInputRange!(typeof(groupedAes.front)));
then
pragma(msg, typeof(groupedAes.front));

to see at what level it's going wrong.


Re: Frequent cannot deduce function from argument types

2015-10-16 Thread John Colvin via Digitalmars-d-learn
On Friday, 16 October 2015 at 15:48:59 UTC, Edwin van Leeuwen 
wrote:
Just wondering if anyone has any tips on how to solve/avoid 
"cannot deduce function from argument types" when relying on 
template programming.


I run into these problems all the time. Current one was when I 
tried:


```
auto ys = NumericLabel(groupedAes.front.map!((t)=>t.y));
```

NumericLabel is a pretty minimal templated InputRange, with as 
only requirement on the argument that it is also an InputRange. 
I then get the following compile error:


```
source/ggplotd/geom.d(83,35): Error: struct 
ggplotd.aes.NumericLabel cannot ded
uce function from argument types !()(MapResult!(__lambda2, 
FilterResult!(__lamb
da2, Aes!(double[], "x", double[], "y", string[], "colour", 
candidates are:
source/ggplotd/aes.d(515,1):ggplotd.aes.NumericLabel(T) 
if (isInputRang

e!T)
```

As far as I know MapResult always returns an input range and as 
you can see there is only one candidate of NumericLabel, so to 
be honest it looks relatively straightforward to me.


Without seeing more code I can't be 100% sure, but I think it's 
just that you're expecting explicit function template 
instantiation (IFTI) for work for constructors, but it doesn't. 
you have to explicitly provide the template arguments or use a 
free function that forwards to the constructor.


Now I can define the type specifically (and/or typeof) but it 
seems like there should be a better way.


In this case typeof isn't even happy:
```
source/ggplotd/geom.d(84,17): Error: constructor 
ggplotd.aes.NumericLabel!(MapResult!(__lambda2, 
FilterResult!(__lambda2, Aes!(string[], "x", string[], "y", 
string[], "colour".NumericLabel.this (MapResult!(__lambda2, 
FilterResult!(__lambda2, Aes!(string[], "x", string[], "y", 
string[], "colour"))) range) is not callable using argument 
types (MapResult!(__lambda3, FilterResult!(__lambda2, 
Aes!(string[], "x", string[], "y", string[], "colour"

```

If we look closely, it expects a __lambda2 as the MapResult 
argument, but it gets a __lambda3.



I am able to work around it by converting the mapresult to an 
array, but I'd rather use a lazy solution.


Sadly lambdas aren't currently comparable for equality. Maybe on 
day...


If you use the string lambda "a.y" it will probably work.

The more general workaround is to create a temporary variable and 
then use typeof on that, then use that temporary variable.


The idiomatic solution in this case though is to use a function 
as mentioned above.


Re: Why isn't global operator overloading allowed in D?

2015-10-15 Thread John Colvin via Digitalmars-d-learn
On Thursday, 15 October 2015 at 15:45:00 UTC, Shriramana Sharma 
wrote:

John Colvin wrote:

On Wednesday, 14 October 2015 at 15:02:02 UTC, Shriramana 
Sharma

wrote:
What binary arithmetic operators do you need that real[] 
doesn't

already support?


OMG silly me! I can already do a[] /= b[]... D is great! :-D 
Thanks a lot!


Also:

a[] = b[] + c[] * d[] - 42;

and so on... All that's required is that there is pre-allocated 
memory for the result to go in i.e. there has to be enough space 
in a[].


You should be aware that with DMD these array operations should 
be much faster than a straightforward loop, as they are done in 
handwritten asm using vector instructions. Be wary of using them 
on very small arrays, there is some overhead.


With LDC/GDC you probably wont see much difference either way, if 
I remember correctly they rely on the optimiser instead.


Re: OT: why do people use python when it is slow?

2015-10-14 Thread John Colvin via Digitalmars-d-learn

On Wednesday, 14 October 2015 at 14:32:00 UTC, jmh530 wrote:
On Tuesday, 13 October 2015 at 23:26:14 UTC, Laeeth Isharc 
wrote:

https://www.quora.com/Why-is-Python-so-popular-despite-being-so-slow
Andrei suggested posting more widely.


I was just writing some R code yesterday after playing around 
with D for a couple weeks. I accomplished more in an afternoon 
of R coding than I think I had in like a month's worth of 
playing around with D. The same is true for python.


As someone who uses both D and Python every day, I find that - 
once you are proficient in both - initial productivity is higher 
in Python and then D starts to overtake as a project gets larger 
and/or has stricter requirements. I hope never to have to write 
anything longer than a thousand lines in Python ever again.


Re: Why isn't global operator overloading allowed in D?

2015-10-14 Thread John Colvin via Digitalmars-d-learn
On Wednesday, 14 October 2015 at 15:02:02 UTC, Shriramana Sharma 
wrote:
Hello. I just came upon a need in my program to make binary 
arithmetic operators valid between two real[] in my programs


What binary arithmetic operators do you need that real[] doesn't 
already support?


Re: OT: why do people use python when it is slow?

2015-10-14 Thread John Colvin via Digitalmars-d-learn

On Wednesday, 14 October 2015 at 15:25:22 UTC, David DeWitt wrote:
On Wednesday, 14 October 2015 at 14:48:22 UTC, John Colvin 
wrote:

On Wednesday, 14 October 2015 at 14:32:00 UTC, jmh530 wrote:
On Tuesday, 13 October 2015 at 23:26:14 UTC, Laeeth Isharc 
wrote:

https://www.quora.com/Why-is-Python-so-popular-despite-being-so-slow
Andrei suggested posting more widely.


I was just writing some R code yesterday after playing around 
with D for a couple weeks. I accomplished more in an 
afternoon of R coding than I think I had in like a month's 
worth of playing around with D. The same is true for python.


As someone who uses both D and Python every day, I find that - 
once you are proficient in both - initial productivity is 
higher in Python and then D starts to overtake as a project 
gets larger and/or has stricter requirements. I hope never to 
have to write anything longer than a thousand lines in Python 
ever again.


That's true until you need to connect to other systems.  There 
are countless clients built for other systems thats are used in 
real world applications.  With web development the Python code 
really just becomes glue nowadays and api's.  I understand D is 
faster until you have to build the clients for systems to 
connect.  We have an application that uses Postgres, 
ElasticSearch, Kafka, Redis, etc. This is plenty fast and the 
productivity of Python is more than D as the clients for 
Elasticsearch, Postgres and various other systems are 
unavailable or incomplete.  Sure D is faster but when you have 
other real world systems to connect to and time constraints on 
projects how can D be more productive or faster?  Our python 
code essentially becomes the API and usage of clients to other 
systems which handle a majority of the hardcore processing.  
Once D gets established with those clients and they are battle 
tested then I will agree.  To me productivity is more than the 
language itself but also building real world applications in a 
reasonable time-frame.  D will get there but is nowhere near 
where Python is.


Python is inherently quite good for glue and has great library 
support, so if that's the majority of your work then Python is a 
good choice. On the other hand, there's plenty of programming out 
there that isn't like that.


Re: Regarding std.array.Appender

2015-10-13 Thread John Colvin via Digitalmars-d-learn

On Tuesday, 13 October 2015 at 13:21:54 UTC, Suliman wrote:
I tried to use map! but it's look like it do not work with 
string, becouse I got error: Error: no property 'map' for type 
'ByLine!(char, char)'


I suspect you don't have it imported.

import std.algorithm;

or

import std.algorithm : map;


Re: Array of BitArrays definition compiles in DMD but not in GDC.

2015-10-09 Thread John Colvin via Digitalmars-d-learn

On Thursday, 8 October 2015 at 21:40:02 UTC, TheGag96 wrote:
In my code I'm passing an array of BitArrays to a constructor 
like this (though mostly as a placeholder):


  Terrain t = new Terrain(1, 15, [
BitArray([1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]),
BitArray([1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1]),
BitArray([0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1]),
BitArray([0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1]),
BitArray([0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1]),
BitArray([1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1]),
  ]);

The code compiles fine when using DMD 2.068.1 but GDC 5.2.1, I 
get this error for every line:


error: cannot implicityly convert expression ([stuff]) of type 
int[] to ulong


Why does this compiler difference exist and how do I get around 
it? Thanks!


gdc is a bit out of date at the moment. If you do something like 
this:


auto bitArray(bool[] ba) pure nothrow
{
BitArray tmp;
tmp.init(ba);
return tmp;
}

auto bitArray(void[] v, size_t numbits) pure nothrow
{
BitArray tmp;
tmp.init(v, numbits);
return tmp;
}

then replace all your calls to the constructor BitArray with 
bitArray, things should work OK for you.


Re: Check template parameter whether it has "length"

2015-10-08 Thread John Colvin via Digitalmars-d-learn

On Thursday, 8 October 2015 at 09:29:30 UTC, tcak wrote:
I am "trying" to write a function that takes an array of items, 
and returns the length of longest item.


[code]
size_t maxLength(A)( const A[] listOfString ) if( __traits( 
hasMember, A, "length" ) )

{
return 0; // not implemented yet
}
[/code]

I tried it with

if( __traits( compiles, A.length ) )

as well. But compiler doesn't match it.

writeln("Max Length: ", maxLength( ["foo", "123456789"] ));

Compilers says it cannot deduce function from argument types ...

I do not want to check whether the type "A" is string, char[], 
etc. As long as it has length (please do not put me into 
ranges, library functions etc as much as possible), I want the 
function to accept it.


I'm 99% sure something like __traits(hasMember, int[], "length" ) 
should evaluate to true. Please file a bug at issues.dlang.org   
I notice it also doesn't work for "ptr".


The correct workaround:
__traits(compiles, A.init.length ));
or
__traits(compiles, listOfStrings.length ));

A.length doesn't work because length is not a static member, so 
it's only accessible from an instance.


The __traits(compiles, ...) solution is actually more general 
because it will work if .length is implemented via UFCS and 
opDispatch.


FYI:
If you want to check whether a statement will compile, as opposed 
to an expression, make a function/delegate out of it, e.g.:

__traits(compiles, { size_t n = A.init.length; });
to check that A has a member length that can be assigned to 
size_t.


P.S. always check std.traits for solutions all your static 
reflection problems, there's a lot of good stuff in there.


Re: Check template parameter whether it has "length"

2015-10-08 Thread John Colvin via Digitalmars-d-learn

On Thursday, 8 October 2015 at 15:22:02 UTC, tcak wrote:

BTW, there is nothing like std.traits.hasLength.


yeah, that's because __traits(hasMember, ...) should be good 
enough, but obviously not in this case at the moment.


Re: Online Phobos Prerelease Docs

2015-10-05 Thread John Colvin via Digitalmars-d-learn

On Monday, 5 October 2015 at 08:19:26 UTC, Per Nordlöw wrote:
Is there an (official or unoffical) prerelease version of the 
Phobos docs, typically for studying std.allocator?


It would be nice to have the D servers auto-generate this every 
time a PR is merged into druntime/phobos.


http://dlang.org/phobos/index.html it's on the sidebar


Re: Online Phobos Prerelease Docs

2015-10-05 Thread John Colvin via Digitalmars-d-learn

On Monday, 5 October 2015 at 09:53:09 UTC, Per Nordlöw wrote:

On Monday, 5 October 2015 at 08:45:54 UTC, John Colvin wrote:

http://dlang.org/phobos/index.html it's on the sidebar


I can't find allocator there (yet) in tree.

http://dlang.org/phobos-prerelease/std_experimental_allocator.html

Why?


because the website needs updating.

In the mean-time, `digger build --with=website`


Re: std.functional:partial - disambiguating templated functions

2015-10-04 Thread John Colvin via Digitalmars-d-learn

On Sunday, 4 October 2015 at 15:45:55 UTC, Laeeth Isharc wrote:
How do I persuade partial to tie itself to the appropriate 
overload?

I have:

alias 
bars=partial!(slurpBars!BarType,filename,startDate,endDate);


where there are two overloads of slurpBars:

SomeBar[] slurpBars(SomeBar)(string filename,string 
datasetName, typeof(SomeBar.date) startDate, 
typeof(SomeBar.date) endDate)
SomeBar[] slurpBars(SomeBar)(hid_t filehandle,string 
datasetName, typeof(SomeBar.date) startDate, 
typeof(SomeBar.date) endDate)


And I receive the following error:
 Error: template kprop.marketdata.retrievebars.slurpBars 
matches more than one template declaration:


Thanks.


Laeeth.


As far as I can see std.functional.partial only does one argument 
at a time.


bars=partial!(partial!(partial!(slurpBars!BarType, filename), 
startDate), endDate);


or maybe, I'm not sure, but maybe you can do:

bars=partial!(slurpBars!BarType, AliasSeq!(filename, startDate, 
endDate));


If you find you really need to manually mess with overloads, use 
http://dlang.org/traits.html#getOverloads. You may have to wrap 
it in AliasSeq in some situations due to grammar/parser 
constraints.


Re: std.functional:partial - disambiguating templated functions

2015-10-04 Thread John Colvin via Digitalmars-d-learn

On Sunday, 4 October 2015 at 19:12:51 UTC, Laeeth Isharc wrote:

On Sunday, 4 October 2015 at 18:24:08 UTC, John Colvin wrote:

On Sunday, 4 October 2015 at 18:08:55 UTC, Laeeth Isharc wrote:
On Sunday, 4 October 2015 at 17:17:14 UTC, Laeeth Isharc 
wrote:

On Sunday, 4 October 2015 at 16:37:34 UTC, John Colvin wrote:
On Sunday, 4 October 2015 at 15:45:55 UTC, Laeeth Isharc 
wrote:
How do I persuade partial to tie itself to the appropriate 
overload?

---
As far as I can see std.functional.partial only does one 
argument at a time.


bars=partial!(partial!(partial!(slurpBars!BarType, 
filename), startDate), endDate);


or maybe, I'm not sure, but maybe you can do:

bars=partial!(slurpBars!BarType, AliasSeq!(filename, 
startDate, endDate));


If you find you really need to manually mess with 
overloads, use http://dlang.org/traits.html#getOverloads. 
You may have to wrap it in AliasSeq in some situations due 
to grammar/parser constraints.
fwiw - still doesn't work (whether I use alias or auto, 
trying each of your solutions).  I'll look at getOverloads.


How do I distinguish between two overloads that return the 
same type but have different arguments?  It looks like 
getOverloads only deals with cases where the return type is 
different, judging by the docs.


getOverloads should give you all the overloads of a function, 
whether they return the same or different types.  The example 
in the docs just happens to have different types.


In general, return types are not considered when talking about 
overloads. For example, two functions that take the same 
arguments but have different return types are not overloaded, 
they are in conflict.


Thanks for this.  The only problem then is how to manipulate 
what getOverloads returns.  (No need to do this now as it's not 
worth it - I just wanted to try using partial if it wasn't too 
much work.  easier just to make an alternate declaration with 
the type in its name).


Is this not a bug in the implementation of partial?

import std.functional;
import std.stdio;

void bish(T)(string arg, string barg)
{
writefln("bishs: %s, %s",arg,barg,to!T);
}
void bish(T)(int argi, string barg)
{
writefln("bishi: %s, %s",argi,barg.to!T);
}

void main(string[] args)
{
	alias b=partial!(bish!string,"hello"); // this line does not 
compile

alias c=partial!(b,"therex");
b("there");
c();
}

[laeeth@engine marketdata]$ dmd partial.d
partial.d(15): Error: template partial.bish matches more than 
one template declaration:

partial.d(4): bish(T)(string arg, string barg)
and
partial.d(8): bish(T)(int argi, string barg)


partial knows which overload to call - I told it!


The problem happens before partial. Something like

alias b = bish!string;

is an error, because it matches both templates. For some reason 
if you call it directly, e.g.


bish!string("","");

that's ok, but I have no idea why.


What you can do, is this:

template bish(T)
{
void bish(string arg, string barg)
{
writefln("bishs: %s, %s",arg,barg.to!T);
}
void bish(int argi, string barg)
{
writefln("bishi: %s, %s",argi,barg.to!T);
}
}

which is just a template containing an overload set, which is no 
problem.


Or:

void bish0(T)(string arg, string barg)
{
writefln("bishs: %s, %s",arg,barg.to!T);
}
void bish1(T)(int argi, string barg)
{
writefln("bishi: %s, %s",argi,barg.to!T);
}

alias bishStr = bish0!string;
alias bishStr = bish1!string;

void main(string[] args)
{
alias b=partial!(bishStr,"hello");
alias c=partial!(b,"therex");
b("there");
c();
}

Or:

void bish0(T)(string arg, string barg)
{
writefln("bishs: %s, %s",arg,barg.to!T);
}
void bish1(T)(int argi, string barg)
{
writefln("bishi: %s, %s",argi,barg.to!T);
}

template bish(T)
{
alias tmp = bish0!T;
alias tmp = bish1!T;
alias bish = tmp;
}

void main(string[] args)
{
alias b=partial!(bish!string, "hello");
alias c=partial!(b,"therex");
b("there");
c();
}


Re: std.functional:partial - disambiguating templated functions

2015-10-04 Thread John Colvin via Digitalmars-d-learn

On Sunday, 4 October 2015 at 20:26:51 UTC, John Colvin wrote:

template bish(T)
{
alias tmp = bish0!T;
alias tmp = bish1!T;
alias bish = tmp;
}


https://issues.dlang.org/show_bug.cgi?id=15156


Re: std.functional:partial - disambiguating templated functions

2015-10-04 Thread John Colvin via Digitalmars-d-learn

On Sunday, 4 October 2015 at 18:08:55 UTC, Laeeth Isharc wrote:

On Sunday, 4 October 2015 at 17:17:14 UTC, Laeeth Isharc wrote:

On Sunday, 4 October 2015 at 16:37:34 UTC, John Colvin wrote:
On Sunday, 4 October 2015 at 15:45:55 UTC, Laeeth Isharc 
wrote:
How do I persuade partial to tie itself to the appropriate 
overload?

---
As far as I can see std.functional.partial only does one 
argument at a time.


bars=partial!(partial!(partial!(slurpBars!BarType, filename), 
startDate), endDate);


or maybe, I'm not sure, but maybe you can do:

bars=partial!(slurpBars!BarType, AliasSeq!(filename, 
startDate, endDate));


If you find you really need to manually mess with overloads, 
use http://dlang.org/traits.html#getOverloads. You may have 
to wrap it in AliasSeq in some situations due to 
grammar/parser constraints.
fwiw - still doesn't work (whether I use alias or auto, trying 
each of your solutions).  I'll look at getOverloads.


How do I distinguish between two overloads that return the same 
type but have different arguments?  It looks like getOverloads 
only deals with cases where the return type is different, 
judging by the docs.


getOverloads should give you all the overloads of a function, 
whether they return the same or different types.  The example in 
the docs just happens to have different types.


In general, return types are not considered when talking about 
overloads. For example, two functions that take the same 
arguments but have different return types are not overloaded, 
they are in conflict.


Re: Linker error with dmd

2015-10-02 Thread John Colvin via Digitalmars-d-learn

On Friday, 2 October 2015 at 09:43:54 UTC, Chris wrote:
Why do I get this error msg with dmd 2.067.1 and 2.068.0 in 
release mode:


$ dub --build=release

(.data._D65TypeInfo_xC3std5range10interfaces18__T10InputRangeTiZ10InputRange6__initZ+0x10):
 undefined reference to 
`_D64TypeInfo_C3std5range10interfaces18__T10InputRangeTiZ10InputRange6__initZ'
collect2: error: ld returned 1 exit status
--- errorlevel 1
dmd failed with exit code 1.

It works fine with the latest version of ldc2.


What is it that you are building?


Re: Checking that a template parameter is an enum

2015-10-02 Thread John Colvin via Digitalmars-d-learn

On Friday, 2 October 2015 at 08:13:00 UTC, John Colvin wrote:

On Thursday, 1 October 2015 at 22:26:39 UTC, Nordlöw wrote:

On Thursday, 1 October 2015 at 02:06:48 UTC, Fusxfaranto wrote:

[...]


Thanks!

BTW: Is there some way to turn the recursive definition of 
`allSame`


template allSame(V...)
if (isExpressions!(V))
{
static if (V.length <= 1)
enum allSame = true;
else
enum allSame = V[0] == V[1] && allSame!(V[1..$]);
}

into an iterative definition?


Why? To avoid slowing down compilation with all those template 
instantiations?


How about a O(log2(N)) depth recursive version, something like 
this:


template allSame(V ...)
if (isExpressions!V)
{
static if (V.length <= 1)
enum allSame = true;
else static if(V.length & 1)
enum allSame = V[$-1] == V[0]
&& V[0 .. $/2] == V[$/2 .. $-1]
&& allSame!(V[0 .. $/2]);
else
enum allSame = V[0..$/2] == V[$/2 .. $]
&& allSame!(V[0 .. $/2]);
}


Although you should consider that isExpressions is instantiating 
V.length templates anyway (it uses a binary split to avoid 
excessive template recursion depth, but it ends up checking them 
all one-per-template in the end anyway.


  1   2   3   4   5   6   >