Explicit casting of enum -- intentional restriction?

2016-10-01 Thread rcorre via Digitalmars-d-learn

I just tried to compile an old project and the following failed:

---
enum Paths : string {
  bitmapDir = "content/image",
  fontDir   = "content/font",
  soundDir  = "content/sound",
...

if (Paths.preferences.exists)
...
---

It turns out members of Paths are no longer implicitly converted 
to string, and I needed to use


if ((cast(string)Paths.preferences).exists)

Is this an intentional limitation or a regression? I didn't see 
it in the last few changelogs but I'll admit I didn't check them 
rigorously.


Re: Privacy violation depending on who passes a compile-time argument?

2016-08-14 Thread rcorre via Digitalmars-d-learn

On Sunday, 14 August 2016 at 17:23:06 UTC, Basile B. wrote:


It is private: https://dpaste.dzfl.pl/83fcca84dde3, so the code 
you've posted in the first message could be a bug.


Ah, you're correct. I'm not able to use either of them in runtime 
code.




The deprecation message also since this case has nothing to do 
with the transition period due to fix 314 (because your import 
is not selective).


Makes sense. I still wonder whether using something like getUDAs 
on a symbol exposed like this is valid, but I guess that hasn't 
been decided yet 
(https://github.com/dlang/phobos/pull/4724#issuecomment-239424693).


Thanks for the insights!


Re: Privacy violation depending on who passes a compile-time argument?

2016-08-14 Thread rcorre via Digitalmars-d-learn

On Sunday, 14 August 2016 at 15:47:16 UTC, Basile B. wrote:
No it's the opposite, only mixins gets the scope of the 
instantiation's location.


Right, if it were a mixin, it would get the scope of the 
instantiation (the main

module) and `i` would be inacessible.

Since it isn't a mixin, I would expect the scope to be in module 
s, where it

_can_ access `i`.



Try to compile this:

struct S
{
private int i;
int j;
alias getMember(string name) = 
Identity!(__traits(getMember, S, name));

alias getMember_i = getMember!"i";

unittest
{
pragma(msg, __traits(getProtection, S.getMember!"i")); 
// private
pragma(msg, __traits(getProtection, S.getMember!"j")); 
// public

}
}

You'll see that this is even not a matter of module. Actually 
your "getMember" is not a member function, it's an alias to the 
source, i.e the same symbol with the same protection.


Ok, so S.getMember!"i" is really the same as S.i, so I get why 
it's private. But
getMember_i is just an alias to that, so shouldn't it also be 
private?


It makes sense if you accept the following:

struct S {
private int _i;
alias i = i;
}

Which I used to accept without thinking about it, but now I'm 
wondering why that

works.



Privacy violation depending on who passes a compile-time argument?

2016-08-14 Thread rcorre via Digitalmars-d-learn
Can someone help me understand why the first line is fine, but 
the second triggers a deprecation warning for access to a private 
variable?


---
import std.traits;
import s;

pragma(msg, hasUDA!(S.getMember_i, attr));   // fine
pragma(msg, hasUDA!(S.getMember!"i", attr)); // deprecated

/++ in module 's'
import std.traits;

struct attr { }

struct S {
  @attr private int i;
  alias getMember(string name) = Identity!(__traits(getMember, S, 
name));

  alias getMember_i = getMember!"i";
}
++/
---

getMember is not a mixin template, so it seems like 
__traits(getMember, S, "i") should be resolved within the 's' 
module in both cases. Why is passing the string "i" from another 
module a violation even when getMember_i is doing the same thing 
internally?


Re: Linker error for d.o: relocation R_X86_64_32 against `__dmd_personality_v0'

2016-04-23 Thread rcorre via Digitalmars-d-learn

On Saturday, 23 April 2016 at 00:55:07 UTC, rcorre wrote:

On Friday, 22 April 2016 at 10:25:34 UTC, Chris wrote:
On Friday, 22 April 2016 at 09:49:02 UTC, Rene Zwanenburg 
wrote:

On Thursday, 21 April 2016 at 16:29:14 UTC, rcorre wrote:
- What happens when you compile a binary without phobos and 
druntime, and with a custom entry point? I've never done 
that myself and don't remember how to do that off the top 
of my head, but the info should be somewhere on dlang.org.


I'll look into it.


Declaring a C-like main and the -defaultlib switch do the 
trick:


 cmain.d
extern(C) void main() nothrow {}
---

dmd cmain.d -defaultlib=""


If even that fails to link I honestly wouldn't know where to 
look next..


This seems odd. Have you tried to reinstall dmd? You could use 
dvm [1] to install different versions of dmd and see what 
happens. It seems as if there's something wrong with your 
installation. I have Ubuntu at work and ArchLinux at home. It 
works fine, there shouldn't be any problem with compiling your 
program.


[1] https://github.com/jacob-carlborg/dvm


No luck with cmain.d.
Its definitely an environmental problem -- I have an almost 
identical Archlinux desktop that is fine.
I thought I'd try my dev DMD, but realized I can't even compile 
it now that DMD is written in D >.<


Got it! I installed hardening-wrapper to build python34.
gcc was pointing to /usr/bin/hardening-wrapper/gcc.

I had to look up what hardening-wrapper even is -- and I found my 
way straight to the archwiki article describing exactly my 
problem:


https://wiki.archlinux.org/index.php/D_(programming_language)#hardening-wrapper

Thank you to everyone who tried to help!


Re: Linker error for d.o: relocation R_X86_64_32 against `__dmd_personality_v0'

2016-04-22 Thread rcorre via Digitalmars-d-learn

On Friday, 22 April 2016 at 10:25:34 UTC, Chris wrote:

On Friday, 22 April 2016 at 09:49:02 UTC, Rene Zwanenburg wrote:

On Thursday, 21 April 2016 at 16:29:14 UTC, rcorre wrote:
- What happens when you compile a binary without phobos and 
druntime, and with a custom entry point? I've never done 
that myself and don't remember how to do that off the top of 
my head, but the info should be somewhere on dlang.org.


I'll look into it.


Declaring a C-like main and the -defaultlib switch do the 
trick:


 cmain.d
extern(C) void main() nothrow {}
---

dmd cmain.d -defaultlib=""


If even that fails to link I honestly wouldn't know where to 
look next..


This seems odd. Have you tried to reinstall dmd? You could use 
dvm [1] to install different versions of dmd and see what 
happens. It seems as if there's something wrong with your 
installation. I have Ubuntu at work and ArchLinux at home. It 
works fine, there shouldn't be any problem with compiling your 
program.


[1] https://github.com/jacob-carlborg/dvm


No luck with cmain.d.
Its definitely an environmental problem -- I have an almost 
identical Archlinux desktop that is fine.
I thought I'd try my dev DMD, but realized I can't even compile 
it now that DMD is written in D >.<


Re: Linker error for d.o: relocation R_X86_64_32 against `__dmd_personality_v0'

2016-04-21 Thread rcorre via Digitalmars-d-learn

On Thursday, 21 April 2016 at 12:57:36 UTC, Rene Zwanenburg wrote:

On Thursday, 21 April 2016 at 11:54:27 UTC, rcorre wrote:


Thanks for the tip. Here's the linking code it shows:


cc d.o -o d -m64 -L/usr/lib -L/usr/lib32 -Xlinker 
--export-dynamic -Xlinker -Bstatic -lphobos2 -Xlinker 
-Bdynamic -lpthread -lm -lrt -ldl
/usr/bin/ld: d.o: relocation R_X86_64_32 against 
`__dmd_personality_v0' can not be used when making a shared 
object; recompile with -fPIC


I tried `cc d.o -o d -m64 -fPIC and still get the error.


Right, the -fPIC should be used while compiling the source 
code, but that's a gcc option. I think DMD is supposed to 
always generates position independent code.


Here are a few things you can try to narrow the problem down. 
I'm not too familiar with this stuff though, so I'm just 
shooting in the dark here and not all of it may make sense ^^


- What happens when you mark main() as nothrow? That 
personality symbol has to do with exception handling.


Nothing.

- Is it possible the linker is picking up 32 bit libraries? 
That -L/usr/lib32 switch is a bit suspicious.


Sure is. I tried manually linking without that but get the same 
error. As a matter of fact, I tried removing all the linker flags 
and still get that error (just `cc d.o -o d`).



- What happens when you compile for 32 bit?


/usr/bin/ld: skipping incompatible /usr/lib/libphobos2.a when 
searching for -lphobos2
/usr/bin/ld: skipping incompatible 
/usr/lib/gcc/x86_64-unknown-linux-gnu/5.3.0/../../../libphobos2.a 
when searching for -lphobos2
/usr/bin/ld: skipping incompatible /usr/lib/libphobos2.a when 
searching for -lphobos2

/usr/bin/ld: cannot find -lphobos2
/usr/bin/ld: skipping incompatible /usr/lib/libpthread.so when 
searching for -lpthread
/usr/bin/ld: skipping incompatible /usr/lib/libpthread.a when 
searching for -lpthread

collect2: error: ld returned 1 exit status

- What happens when you compile a binary without phobos and 
druntime, and with a custom entry point? I've never done that 
myself and don't remember how to do that off the top of my 
head, but the info should be somewhere on dlang.org.


I'll look into it.

- What happens when you compile some D code as a static lib, 
and link it with a main written in C?


Same error.

Oh, and I take it you've already tried to simply reinstall DMD? 
If you uninstall DMD, look if there are still sc.ini's and 
libphobos.a's floating around.


I did. /etc/dmd.conf looks normal, aside from the inclusion of 
32-bit libs:


[Environment]
DFLAGS=-I/usr/include/dlang/dmd -L-L/usr/lib -L-L/usr/lib32 
-L--export-dynamic


But that's how it gets set up after a fresh install.


Re: Linker error for d.o: relocation R_X86_64_32 against `__dmd_personality_v0'

2016-04-21 Thread rcorre via Digitalmars-d-learn

On Thursday, 21 April 2016 at 09:55:30 UTC, Rene Zwanenburg wrote:

On Thursday, 21 April 2016 at 01:20:27 UTC, rcorre wrote:

s/compile/link
I _can_ compile a D library, but as soon as I try to link 
anything compiled with DMD it falls over.


What is dmd's verbose output? (add -v switch)

Some of the things it outputs are the location of the config 
file it uses, you can inspect that file to see if it has been 
borked somehow.


Near the bottom you can find the used link command, that could 
also reveal the problem.


Thanks for the tip. Here's the linking code it shows:


cc d.o -o d -m64 -L/usr/lib -L/usr/lib32 -Xlinker 
--export-dynamic -Xlinker -Bstatic -lphobos2 -Xlinker -Bdynamic 
-lpthread -lm -lrt -ldl
/usr/bin/ld: d.o: relocation R_X86_64_32 against 
`__dmd_personality_v0' can not be used when making a shared 
object; recompile with -fPIC


I tried `cc d.o -o d -m64 -fPIC and still get the error.




Re: Linker error for d.o: relocation R_X86_64_32 against `__dmd_personality_v0'

2016-04-20 Thread rcorre via Digitalmars-d-learn

On Thursday, 21 April 2016 at 01:18:14 UTC, rcorre wrote:

On Wednesday, 20 April 2016 at 19:24:49 UTC, Chris wrote:

On Wednesday, 20 April 2016 at 12:04:45 UTC, rcorre wrote:

===
$ dmd /tmp/d.d
/usr/bin/ld: d.o: relocation R_X86_64_32 against 
`__dmd_personality_v0' can not be used when making a shared 
object; recompile with -fPIC

d.o: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
--- errorlevel 1
===

I'm seeing the above trying to compile a simple d program.

/tmp/d.d:
===
void main() { }
===

Any idea what this might be? I'm on dmd 2.071.0 on Archlinux.


I had a similar error. Could you show us the code? Do you 
refer/link to a dynamic library?


The code is shown above. Literally `void main() { }`. I can't 
compile anything.


s/compile/link
I _can_ compile a D library, but as soon as I try to link 
anything compiled with DMD it falls over.




Re: Linker error for d.o: relocation R_X86_64_32 against `__dmd_personality_v0'

2016-04-20 Thread rcorre via Digitalmars-d-learn

On Wednesday, 20 April 2016 at 19:24:49 UTC, Chris wrote:

On Wednesday, 20 April 2016 at 12:04:45 UTC, rcorre wrote:

===
$ dmd /tmp/d.d
/usr/bin/ld: d.o: relocation R_X86_64_32 against 
`__dmd_personality_v0' can not be used when making a shared 
object; recompile with -fPIC

d.o: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
--- errorlevel 1
===

I'm seeing the above trying to compile a simple d program.

/tmp/d.d:
===
void main() { }
===

Any idea what this might be? I'm on dmd 2.071.0 on Archlinux.


I had a similar error. Could you show us the code? Do you 
refer/link to a dynamic library?


The code is shown above. Literally `void main() { }`. I can't 
compile anything.




Re: Linker error for d.o: relocation R_X86_64_32 against `__dmd_personality_v0'

2016-04-20 Thread rcorre via Digitalmars-d-learn

On Wednesday, 20 April 2016 at 12:48:46 UTC, rcorre wrote:

On Wednesday, 20 April 2016 at 12:04:45 UTC, rcorre wrote:

===
$ dmd /tmp/d.d
/usr/bin/ld: d.o: relocation R_X86_64_32 against 
`__dmd_personality_v0' can not be used when making a shared 
object; recompile with -fPIC

d.o: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
--- errorlevel 1
===

I'm seeing the above trying to compile a simple d program.

/tmp/d.d:
===
void main() { }
===

Any idea what this might be? I'm on dmd 2.071.0 on Archlinux.


My desktop is fine (Archlinux, same DMD version, both recently 
updated). I'm guessing this is some weird misconfiguration on 
my laptop that happened fairly recently.


Compiling with -fPIC doesn't help.



Re: Linker error for d.o: relocation R_X86_64_32 against `__dmd_personality_v0'

2016-04-20 Thread rcorre via Digitalmars-d-learn

On Wednesday, 20 April 2016 at 12:04:45 UTC, rcorre wrote:

===
$ dmd /tmp/d.d
/usr/bin/ld: d.o: relocation R_X86_64_32 against 
`__dmd_personality_v0' can not be used when making a shared 
object; recompile with -fPIC

d.o: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
--- errorlevel 1
===

I'm seeing the above trying to compile a simple d program.

/tmp/d.d:
===
void main() { }
===

Any idea what this might be? I'm on dmd 2.071.0 on Archlinux.


My desktop is fine (Archlinux, same DMD version, both recently 
updated). I'm guessing this is some weird misconfiguration on my 
laptop that happened fairly recently.


Linker error for d.o: relocation R_X86_64_32 against `__dmd_personality_v0'

2016-04-20 Thread rcorre via Digitalmars-d-learn

===
$ dmd /tmp/d.d
/usr/bin/ld: d.o: relocation R_X86_64_32 against 
`__dmd_personality_v0' can not be used when making a shared 
object; recompile with -fPIC

d.o: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
--- errorlevel 1
===

I'm seeing the above trying to compile a simple d program.

/tmp/d.d:
===
void main() { }
===

Any idea what this might be? I'm on dmd 2.071.0 on Archlinux.



@nogc inconsistent for array comparison depending on mutability of elements

2016-04-07 Thread rcorre via Digitalmars-d-learn

@nogc unittest {
int[2] a = [1, 2];
assert(a == [1, 2]); // OK

immutable(int)[2] b = [1, 2];
assert(b == [1, 2]); // fail: array literal may cause 
allocation

}

Is there any logic behind allowing the comparison with `a` but 
not `b`, or is this a compiler bug?


Re: How to sort a range

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

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

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


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


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


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


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


Re: How to sort a range

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

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


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


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


Re: How to sort a range

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

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

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


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


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


I'd like to avoid allocating here.


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


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


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


I did try different SwapStrategies with no luck.


Re: How to sort a range

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

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

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


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


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


Yup, just noticed that >.<


Re: How to sort a range

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


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


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


I'd like to avoid allocating here.




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

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


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




How to sort a range

2016-03-08 Thread rcorre via Digitalmars-d-learn
I was in a situation where I wanted to remove duplicates from an 
OnlyResult.
To do this with uniq, I needed to sort it. OnlyResult doesn't 
satisfy the template constraints of sort, but this seems easy 
enough to fix. I made front, back, and opIndex return by ref. 
With this, the following compiles:


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

However, it fails with:

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


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


For reference, my two attempts were:

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

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


Re: Is this nogc? dmd and gdc disagree

2016-02-11 Thread rcorre via Digitalmars-d-learn

On Thursday, 11 February 2016 at 04:20:13 UTC, tsbockman wrote:

On Thursday, 11 February 2016 at 03:09:51 UTC, rcorre wrote:
I recently tried compiling enumap with GDC, and found that it 
disagrees with DMD on whether a function is @nogc. Here's a 
semi-reduced test-case:


Here's an @nogc version of `byKeyValue()`:

@nogc auto byKeyValue() const {
  static immutable keys = [EnumMembers!K];
  return zip(keys[], _store[]);
}

Using zip and slices guarantees that the structure returned 
will be only 5*size_t.sizeof bytes, regardless of the types of 
K and V.


I'm on the DMD 2.070 release, so maybe its fixed in master.
Either way, thanks for the suggestion!
Somehow I didn't realize what I was doing was an over-complicated 
zip :)




Re: Is this nogc? dmd and gdc disagree

2016-02-11 Thread rcorre via Digitalmars-d-learn

On Thursday, 11 February 2016 at 12:41:16 UTC, rcorre wrote:

On Thursday, 11 February 2016 at 04:20:13 UTC, tsbockman wrote:
Using zip and slices guarantees that the structure returned 
will be only 5*size_t.sizeof bytes, regardless of the types of 
K and V.


I'm on the DMD 2.070 release, so maybe its fixed in master.
Either way, thanks for the suggestion!
Somehow I didn't realize what I was doing was an 
over-complicated zip :)


Though it appears (in 2.070 at least) that zip's range primitives 
aren't nogc:


---
import std.range;

immutable a = [1,2,3];
immutable b = [1,2,3];

@nogc void main() {
foreach(x, y ; a[].zip(b[])) { }
}
---
other.d(7): Error: @nogc function 'D main' cannot call non-@nogc 
function 'std.range.Zip!(immutable(int)[], 
immutable(int)[]).Zip.empty'
other.d(7): Error: @nogc function 'D main' cannot call non-@nogc 
function 'std.range.Zip!(immutable(int)[], 
immutable(int)[]).Zip.popFront'

---



Is this nogc? dmd and gdc disagree

2016-02-10 Thread rcorre via Digitalmars-d-learn
I recently tried compiling enumap with GDC, and found that it 
disagrees with DMD on whether a function is @nogc. Here's a 
semi-reduced test-case:


---
import std.range;
import std.traits: EnumMembers;
import std.typecons  : tuple, staticIota;
import std.algorithm : map;

struct Enumap(K, V)
  if(EnumMembers!K == staticIota!(0, EnumMembers!K.length))
{
  enum length = EnumMembers!K.length;
  private V[length] _store;

  ref auto opIndex(K key) inout {
return _store[key];
  }

  @nogc auto byKeyValue() const {
return only(EnumMembers!K).map!(key => tuple(key, this[key]));
  }
}

@nogc void main() {
import std.typecons  : tuple;
import std.algorithm : map;

enum E { a, b, c, d };
immutable elements = Enumap!(E, int)([1,2,3,4]);

auto pairs = elements.byKeyValue.map!(pair => tuple(pair[0], 
pair[1] + 1));

}
---

GDC claims that byKeyValue() allocates a closure, but DMD is just 
fine with me calling it @nogc. I'm inclined to agree with GDC 
here, unless DMD is doing some magic so that actually doesn't 
allocate a closure.


UFCS assignment syntax for templated function

2016-01-01 Thread rcorre via Digitalmars-d-learn

The following works:

---
struct Foo { float x; }

auto val(Foo foo) { return foo.x; }
auto val(ref Foo foo, float val) { return foo.x = val; }

unittest {
  auto f = Foo();
  f.val = 5;
  assert(f.val == 5);
}
---

But the following fails to compile with 'val(b) is not an lvalue'.

---
struct Bar(T) { T x; }

auto val(T)(Bar!T bar) { return bar.x; }
auto val(T)(ref Bar!T bar, float val) { return bar.x = val; }

unittest {
  auto b = Bar!int();
  b.val = 5;
  assert(b.val == 5);
}
---

Is there a way to invoke a templated function using the UFCS 
assignment syntax?
That is, can `obj.fun = val` be translated to `fun(obj, val)` 
when fun is a templated function?


Re: UFCS assignment syntax for templated function

2016-01-01 Thread rcorre via Digitalmars-d-learn

On Friday, 1 January 2016 at 11:59:39 UTC, rcorre wrote:

auto val(T)(ref Bar!T bar, float val) { return bar.x = val; }


Uh, never mind. That `float` should have been `T`. Seems to work 
now.




Deducing a template argument from an aliased parameter

2015-12-31 Thread rcorre via Digitalmars-d-learn
In the following example, it seems like the signatures of fun1 
and fun2 should
be equivalent. Both accept a Vector!(T, 2), the only difference 
is that fun2

goes through an alias.

struct Vector(T, int N) { }
alias Vector2(T) = Vector!(T, 2);

void fun1(T)(Vector!(T, 2) vec) { }
void fun2(T)(Vector2!T vec) { }

unittest {
  fun1(Vector!(float, 2).init);
  fun2(Vector!(float, 2).init);
}

Why can fun1 deduce `T`, but fun2 can't?

Failure:
"template d.fun2 cannot deduce function from argument types 
!()(Vector!(float, 2))"?


Re: Massive linker error after upgrade to DMD 2.068.1-1

2015-09-15 Thread rcorre via Digitalmars-d-learn
On Sunday, 13 September 2015 at 00:21:22 UTC, Nicholas Wilson 
wrote:


there was talk of adding symbol name compression some time ago 
( to reduce lib size ( and maybe make ddemangle not fail on 
long syms?). This might be the cause of your problems i.e. the 
new compiler emitting references to compressed names but built 
with the old compiler using the not compressed ones. Try 
rebuilding everything and see if that fixes it.


I tried deleting ~/.dub and the .dub folder in every referenced 
project and rebuilding, but unfortunately no luck.


Massive linker error after upgrade to DMD 2.068.1-1

2015-09-12 Thread rcorre via Digitalmars-d-learn
After upgrading from DMD 2.068.0-1 to DMD 2.068.1-1, my project 
began producing a large linker error (when built using dub).


I was able to trace it down to a single line:

target = target.adjacent(Diagonals.yes).randomSample(1).front;

target is of type RowCol 
(https://github.com/rcorre/dtiled/blob/master/src/dtiled/coords.d#L36),
which has an `adjacent` property that leverages chain, only, and 
take.


When I comment this line out (or build on a system with DMD 
2.068.0-1), I can build fine. When uncommented, I see (post 
ddemangle):


http://dpaste.com/1PJB35V

I've tried to break this down into a reduced example to prove 
that I can call randomSample on the range returned by 
RowCol.adjacent (http://dpaste.com/13G9WDE). This runs fine, so 
it seems to be a deeper issue with my build environment (full 
project at https://github.com/rcorre/damage_control if you're 
curious).


I don't want to turn this into "please debug my project for me", 
but do people have general hints on how to track down issues like 
this?


Thanks!

Side note: I see src/transition.d in the output, but I don't see 
how it is relevant to the error (it isn't even imported by the 
file causing the error).


Re: Are Lua tables possible to do with D?

2015-07-17 Thread rcorre via Digitalmars-d-learn

On Thursday, 16 July 2015 at 07:20:16 UTC, Fusxfaranto wrote:


An associative array of Variant[string] ought to do the job 
well enough.


http://dlang.org/phobos/std_variant.html


For extra fun, you can implement the '.' style syntax pretty 
easily:


---
import std.variant;

struct LuaTable {
  Variant[string] _table;
  alias _table this;

  auto opDispatch(string s)() {
return _table[s];
  }

  void opDispatch(string s, T)(T val) {
_table[s] = Variant(val);
  }
}

unittest {
  LuaTable table;

  table.foo = 5;
  table.bar = s;

  assert(table.foo == 5);
  assert(table.bar == s);
}
---


Implicit conversion in constructor

2015-07-17 Thread rcorre via Digitalmars-d-learn
Is there any reason why implicit conversion from Foo to Thing is 
permitted in a regular method but not in a constructor?


Trying to figure out whether this is a bug or some sort of 
constructor-specific safety precaution.


struct Thing {
  Foo foo;
  alias foo this;
}

class Foo { }

class Bar {
  Thing thing;

  void fine() {
thing = new Foo(); // ok
  }

  this() {
thing = new Foo(); // nope!
  }
}



Re: Implicit conversion in constructor

2015-07-17 Thread rcorre via Digitalmars-d-learn

On Saturday, 18 July 2015 at 02:28:09 UTC, tcak wrote:


I even am not sure how in the world it allows implicit 
conversion from class to struct in fine at all.


The 'alias this' in the struct permits implicit conversion.
I _think_ that is intended behavior, though I admit I'm not 
actually sure now.

I've been taking it for granted for awhile...


Re: @property on free function for UFCS?

2015-06-14 Thread rcorre via Digitalmars-d-learn

On Sunday, 14 June 2015 at 12:36:43 UTC, Adam D. Ruppe wrote:
You can use @property there, but you don't have to because you 
can call it with optional parenthesis anyway.


Thanks.

Is there a good reference for the current state of @property?
I know it was hotly debated for awhile (and maybe still is?).
I'm just never sure when I should be using it (if at all).


@property on free function for UFCS?

2015-06-14 Thread rcorre via Digitalmars-d-learn

Suppose I have a function defined like so:

void foo(int i) { }

intended to be called like:

5.foo

Should it be labeled with @property?
Or is @property only for true member functions?


Re: Returning an empty range of a given type

2015-05-14 Thread rcorre via Digitalmars-d-learn

So I thought this might work:

struct MaybeEmpty(R) if (isInputRange!R) {
  private bool _isEmpty;
  private R_input;

  alias _input this;

  this(bool isEmpty, R input) {
_input = input;
_isEmpty = isEmpty;
  }

  @property bool empty() {
return _isEmpty || _input.empty;
  }
}

auto maybeEmpty(R)(bool empty, R input = R.init) if 
(isInputRange!R) {

  return MaybeEmpty!R(empty, input);
}

It's kind of ugly, but it can be used like:

  auto a = maybeEmpty!MyRange(true);
  auto b = maybeEmpty!MyRange(false, actualRange);
  static assert(is(typeof(a) == typeof(b)));

However, it fails the input range test:

static assert(isInputRange!MyRange); //pass
static assert(isInputRange!(typeof(a))); // fail

But it seems to be something weird with cross-module template 
instantiation. If I replace `import std.range` with a copy-paste 
of `isInputRange`, the above passes.


Either that or I'm doing something stupid because I'vebeen 
staring at this too long.


I'm wondering if the isInputRange thing is a bug, so here's a 
gist if anyone wants to play with it:

https://gist.github.com/rcorre/7a62395c53baf3c0bfbc


Re: Returning an empty range of a given type

2015-05-14 Thread rcorre via Digitalmars-d-learn

On Thursday, 14 May 2015 at 06:41:45 UTC, Ali Çehreli wrote:


I am lucky because although the returned type is opaque to me, 
I know that it is constructed by a void lambda.


Yeah, in this case I control the container so I may just add an 
emptySlice property, but it does seem like it might be a common 
need (to return an empty range of a given type without having 
that range constructed beforehand).


Re: Returning an empty range of a given type

2015-05-14 Thread rcorre via Digitalmars-d-learn

On Thursday, 14 May 2015 at 14:57:26 UTC, Idan Arye wrote:


How about a more flexible solution?

http://dpaste.dzfl.pl/2f99cc270651


Neat, thanks!

On Thursday, 14 May 2015 at 18:44:58 UTC, Steven Schveighoffer 
wrote:



It depends on the guts of MyContainer.Range.

I'm assuming MyContainer.Range has SOME sort of references 
(i.e. pointers) to the data in the container, so why not just 
have:


bool empty() { return someRef == null || yourCurrentTest; }

-Steve


In this case, I want to return an empty range when the container 
instance itself is null. I could have a static method 
MyContainer.emptySlice, but I feel like I've seen this general 
situation crop up a lot with small variations.


Re: Returning an empty range of a given type

2015-05-14 Thread rcorre via Digitalmars-d-learn

On Friday, 15 May 2015 at 03:22:43 UTC, rcorre wrote:

On Thursday, 14 May 2015 at 14:57:26 UTC, Idan Arye wrote:


How about a more flexible solution?

http://dpaste.dzfl.pl/2f99cc270651


Neat, thanks!



The range I don't pick may be an expression that would fail, so I 
tweaked it to:

SelectRange!T selectRange(T...)(size_t index, lazy T ranges)

Other than that, it seems to be just what I needed. Thanks again!


Returning an empty range of a given type

2015-05-13 Thread rcorre via Digitalmars-d-learn

I've run into this situation a lot:
I have a function that returns a range (in this case, a slice of 
a custom container).

In some cases, the function needs to return an empty range.

It sounded like takeNone was what I wanted:

@nogc auto fun() {
   return (some_condition) ? getRange() : getRange.takeNone;
}

but there is a return type ambiguity. I finally ended up doing 
this:


@nogc auto fun() {
   return (some_condition) ? getRange().take(size_t.max) : 
getRange.takeNone;

}

I'm not sure if this is clever or insane.
It works, but just looks a bit crazy to me.
Does anyone else run into this situation? Have any cool ways to 
solve it?
MyRange is an inputRange, and I can't use a wrapper (InputRange) 
and keep the @nogc.


Re: Returning an empty range of a given type

2015-05-13 Thread rcorre via Digitalmars-d-learn

Actually, this doesn't even seem to work with a custom range:

import std.range;
import std.stdio;
import std.algorithm;

struct MyContainer {
  @nogc auto opSlice() {
struct Range {
  @property bool empty() { return true; }
  @property int front() { return 9; }
  void popFront() { }
}

return Range();
  }
}

/// Return a slice of aa[key], or an empty slice if not found
@nogc auto maybeGetRange(MyContainer[string] aa, string key) {
  alias RangeType = typeof(MyContainer.init[]);
  auto val = key in aa;
  return (val is null) ? takeNone!RangeType : 
(*val)[].take(size_t.max);

}

Is there any way to create an empty MyContainer.Range() without 
creating a new container?


Private alias escaping -- is this a bug?

2015-04-25 Thread rcorre via Digitalmars-d-learn

I ran into this infuriatingly confusing situation just now:

static assert(is(typeof(Parent.init.new Child) == Parent.Child)); 
// fine


alias P = Parent;
alias T = Parent.Child;

static assert(is(typeof(P.init.new T) == T)); // nope!

Wat???

After much confusion, I finally discovered this in my class:

class Parent {
class Child { }
mixin MyMixin;
}

mixin Template MyMixin() {
private alias T = ...; // the culprit!
}

Should the private alias be able to escape? Is this a bug or 
expected behavior?


Also, is there a nice way to create template-level aliases in 
mixin templates that don't leak into the class? MyMixin generates 
multiple functions that all use T.


Re: std.json questions

2015-04-25 Thread rcorre via Digitalmars-d-learn

On Saturday, 25 April 2015 at 09:56:25 UTC, tired_eyes wrote:
A brief look at code.dlang.org gives us 7 (!) additional JSON 
libraries. Keeping in mind that D community isn't so huge, I 
think I'm not the only person struggling with std.json. Are 
there any plans on upgrading it?


See http://wiki.dlang.org/Review_Queue. std.data.json is the 
proposed replacement for the current phobos json implementation.

There is also supposedly std.serialization in the works.


Re: std.typecons.Flag -- public import for API users?

2015-03-26 Thread rcorre via Digitalmars-d-learn

On Tuesday, 24 March 2015 at 16:41:28 UTC, Rene Zwanenburg wrote:
Should not be necessary. privately import Flag and make a 
public alias:


module a;
import std.typecons : Flag;

alias SomeFlag = Flag!SomeFlag;

SomeFlag.Yes and SomeFlag.No should be usable in other modules 
without additional imports.


Nice idea Rene, thanks!


std.typecons.Flag -- public import for API users?

2015-03-21 Thread rcorre via Digitalmars-d-learn
If I am developing a library and some of my functinos take a 
std.typecons.Flag as an argument, should I 'public import 
std.typecons: Flag, Yes, No'?


It seems like it would be a pain for users of the library to have 
to import this separately whenever they use my library, but I'm 
not sure what the stance is on having your modules `public 
import` standard-library modules.


In general, is it considered bad form to 'public import' modules 
from phobos?