Re: how to declare an immutable class?

2016-08-11 Thread Mike Parker via Digitalmars-d-learn

On Friday, 12 August 2016 at 04:49:46 UTC, Charles Hixson wrote:

It works, it's just not the syntax that I'd prefer.  And it 
leaves me wondering exactly what

immutable class Msg {...}
was declaring.


This should demonstrate:

```
immutable class iMsg {
int getX() { return 10; }
}

class Msg {
int getX() { return 20; }
}

void main() {
auto msg1 = new immutable iMsg;
assert(msg1.getX() == 10);

auto msg2 = new immutable Msg;
assert(msg2.getX() == 20);
}
```

The line with msg2.getX() will fail to compile, because it's 
calling a non-immutable method on an immutable object. Change the 
declaration of Msg to the following and it compiles:


```
class Msg {
int getX() immutable { return 20; }
}
```

immutable class Foo { ... } is the same as declaring every member 
of Foo as immutable, just as final class Foo { ... } makes every 
method final.





Re: how to declare an immutable class?

2016-08-11 Thread Charles Hixson via Digitalmars-d-learn

On 08/11/2016 06:33 PM, Mike Parker via Digitalmars-d-learn wrote:

On Friday, 12 August 2016 at 00:44:31 UTC, Charles Hixson wrote:
A way around this, which may be the same as the approach used by 
string was:


alias immutable(Msg_)Msg;
classMsg_
{  ...



This is exactly what Jonathan suggested in the post above. And yes, 
it's how string is handled:


alias string = immutable(char)[];



This so far appears to do what I want.  The only problem is that it 
introduces an extraneous symbol, which I would prefer to avoid.


What problem do you want to avoid? This is a common D idiom. Alias 
names are very short-lived. Yes, it's another symbol in the namespace, 
but it will never make it to the object file. It won't even make it to 
error messages -- you'll see Msg_ there instead.

Yes, I saw his answer after I'd posted my resolution.
It works, it's just not the syntax that I'd prefer.  And it leaves me 
wondering exactly what

immutable class Msg {...}
was declaring.



Re: How to use std. packages in so files written in dlang

2016-08-11 Thread ketmar via Digitalmars-d-learn

On Friday, 12 August 2016 at 03:41:54 UTC, bachmeier wrote:

On Friday, 12 August 2016 at 03:31:37 UTC, ketmar wrote:

On Friday, 12 August 2016 at 03:20:59 UTC, grampus wrote:

Didn't realise the D community is such active.


yes, we are. while we may be not very huge in number, we are 
very passionate about our language of choice. ;-)


Currently there are about 40,000 DMD downloads a month, so the 
community isn't terribly small. The forums see activity from a 
lot of different posters.


sheer number of downloads doesn't say much. comparing to some 
other communities (let's talk about rust and go, for example, as 
relatively fresh performers on the stage) our community is small. 
but in the end it is quality that matters, not huge numbers, i 
believe. and signal/noise ratio of thing NG is great (especially 
when i'm not posting here).


Re: How to use std. packages in so files written in dlang

2016-08-11 Thread bachmeier via Digitalmars-d-learn

On Friday, 12 August 2016 at 03:31:37 UTC, ketmar wrote:

On Friday, 12 August 2016 at 03:20:59 UTC, grampus wrote:

Didn't realise the D community is such active.


yes, we are. while we may be not very huge in number, we are 
very passionate about our language of choice. ;-)


Currently there are about 40,000 DMD downloads a month, so the 
community isn't terribly small. The forums see activity from a 
lot of different posters.


Re: How to use std. packages in so files written in dlang

2016-08-11 Thread ketmar via Digitalmars-d-learn

On Friday, 12 August 2016 at 03:20:59 UTC, grampus wrote:

Didn't realise the D community is such active.


yes, we are. while we may be not very huge in number, we are very 
passionate about our language of choice. ;-)


Re: How to use std. packages in so files written in dlang

2016-08-11 Thread grampus via Digitalmars-d-learn

On Friday, 12 August 2016 at 02:31:29 UTC, ketmar wrote:

On Friday, 12 August 2016 at 01:36:34 UTC, grampus wrote:

[...]


then you have to check if runtime is initialized at the start 
of each function that can be called from C side. like this:


[...]


Understand, I will be careful here.
Thank you all for the quick feedback.
Didn't realise the D community is such active.
I hope D will be more popular

Cheers


Re: How to use std. packages in so files written in dlang

2016-08-11 Thread ketmar via Digitalmars-d-learn

On Friday, 12 August 2016 at 01:36:34 UTC, grampus wrote:
I can use dlang in this existing project as long as nothing can 
be changed on the C side.


then you have to check if runtime is initialized at the start of 
each function that can be called from C side. like this:



private void ensureRuntimeInited () {
  static bool tlsinited = false;
  __gshared bool inited = false;
  if (!tlsinited) {
synchronized(Object.classinfo) {
  if (!inited) {
import core.runtime : Runtime;
if (!Runtime.initialize) {
  import core.stdc.stdio : stderr, fprintf;
  import core.stdc.stdlib : abort;
  fprintf(stderr, "\nFATAL: failed to initialize 
druntime!\n");

  abort();
}
inited = true;
  }
}
tlsinited = true;
  }
}


extern(C) int myExtAPI () {
  ensureRuntimeInited();
  // your D code here
  return 0;
}


yes, you have to do that in each exported function.


as for your another question: if you won't call `rt_term()`, no 
module dtors will be called, no garbage will be collected at 
exit. there also may be problems with unregistering signal 
handlers, but i'm not sure.


if you C app routinely loads and unloads .so without notifying it 
about the fact that .so is being unloaded, you are in big 
troubles not only with D, but with .so written in any other 
language. you *may* hack around this, but it's *WAY* better to 
fix your C app in this case.


Re: mixin bug?

2016-08-11 Thread Engine Machine via Digitalmars-d-learn

On Thursday, 11 August 2016 at 21:25:20 UTC, sldkf wrote:
On Thursday, 11 August 2016 at 20:27:01 UTC, Engine Machine 
wrote:
This requires F2 to know the future. It also forces it to use 
a specific bar. I want inheritance like logic.


You are goind to hit a wall. Template programming is not OOP.
I'm not even sure that reflection would work in order to 
determine the most "recent" overload.


Well, duh, it is not oop, but that doesn't mean it doesn't have 
similar abstractions, you need to read between the lines a bit 
more.


Which is what we get when we mixin one deep, but when we go 
deeper, it breaks. I think this is a bug. It seems like D is 
trying to resolve things only after each mixin, rather than 
resolving after all nested mixins are evaluated.


This is the only issue I see: "It seems like D is trying 
to...". We need to know exactly what D does: 
https://issues.dlang.org/show_bug.cgi?id=16376.


It would be nice if D would bind the function calls lazily, so to 
speak, that is all I'm saying. This way we can get 
polymorphic/oop like behavior, if you will.


template A(T)
{
void Bark() { writeln("Ruff Ruff"); }
}

template B(T)
{
mixin A!T;
void Talk() { Bark(); }
}

template Duck(T)
{
mixin B!T;
private void Bark() { writeln("Quack"); }
}


this is a contrived and misleading example if you take it 
seriously.


But Duck.Talk(); should Quack. It would if D resolved Bark from 
Talk after the final "mixin". (In Duck, not in B). Else we are 
stuck with a barking duck.


What it seems to do is first evaluate the template A!T, then B!T, 
then Duck!T. Since B!T is evaluated first and plugged in to Duck, 
Talk is already resolved to use A!T.Bark. Rather, If Duck!T was 
evaluated first, D would understand that Bark was already defined 
and when Talk was added, it could have it use the bark defined in 
duck, rather than A.


This, would, of course, require a sort of Duck!T.B!T type, since 
B!T used inside of Duck would have a different Talk() than if it 
is not used in Duck.


Again, maybe the compiler is just to ignorant to do this as it is 
complex(might require flow analysis and all that stuff or just be 
an ill-defined problem in general).








Re: How to use std. packages in so files written in dlang

2016-08-11 Thread grampus via Digitalmars-d-learn

On Friday, 12 August 2016 at 01:45:29 UTC, Mike Parker wrote:

On Friday, 12 August 2016 at 01:36:34 UTC, grampus wrote:

On Friday, 12 August 2016 at 01:09:47 UTC, ketmar wrote:

On Friday, 12 August 2016 at 00:57:42 UTC, grampus wrote:

it's 'cause you didn't initialized druntime. you have to use 
dlsym to get "rt_init" function and call it right after 
loading your .so, but before calling any other API from it.


also, note that druntime is using SIGUSR1 and SIGUSR2 for 
it's internal housekeeping, so don't use this signals in your 
C++ code.


Thank you for the quick reply.
Do you mean that I have to do some changes on the C side?
I can use dlang in this existing project as long as nothing 
can be changed on the C side.

Do you think I can use dlang in our case?

Thank you


One way to handle this is to add initialize/terminate functions 
to your shared library. In that case, rather than rt_init, you 
can call the Runtime functions [1]:


import core.runtime;

extern(C) int initialize() { return Runtime.initialize(); }
extern(C) int terminate() { return Runtime.terminate(); }

From your C program, call initialize after loading the library 
and terminate before exiting.


[1] http://dlang.org/phobos/core_runtime.html#.Runtime


I will try this solution.
One more question, if Runtime.initialize(); is called but when 
sofile is unloaded without calling Runtime.terminate(); is it 
going to cause any problem? for example so file is loaded again 
and again, Runtime.initialize() is called many times without 
Runtime.terminate().


Re: mixin bug?

2016-08-11 Thread Engine Machine via Digitalmars-d-learn

On Thursday, 11 August 2016 at 21:03:36 UTC, Ali Çehreli wrote:

On 08/11/2016 01:27 PM, Engine Machine wrote:

> I see the mixin as a sort of copy and paste.

That's the case for string mixins. Template mixins bring a name 
resolution scope. My understanding of the topic:


  
http://ddili.org/ders/d.en/mixin.html#ix_mixin.name%20space,%20mixin


The spec:

  https://dlang.org/spec/template-mixin.html

Ali


"When a mixed-in name is the same as a name that is in the 
surrounding scope, then the name that is in the surrounding scope 
gets used:"


Which is my point, for "2nd order or higher" mixins, this does 
not occur.


The why I see it is that mixin template is sort of like a copy 
and paste, but only paste if the members do not exist 
already(i.e., the current behavior for "1st order" mixins. I 
would expect the same logic to hold for higher order mixins since 
a mixin of a mixin is still a mixin).


I realize why D behaves the way it does, but this is limiting. It 
simply greedily resolves referencing members rather than lazily. 
If the greedy method actually has some desired characteristic, 
then a lazy mixin would be nice.


lazy mixin T1!T;






Re: How to use std. packages in so files written in dlang

2016-08-11 Thread Mike Parker via Digitalmars-d-learn

On Friday, 12 August 2016 at 01:36:34 UTC, grampus wrote:

On Friday, 12 August 2016 at 01:09:47 UTC, ketmar wrote:

On Friday, 12 August 2016 at 00:57:42 UTC, grampus wrote:

it's 'cause you didn't initialized druntime. you have to use 
dlsym to get "rt_init" function and call it right after 
loading your .so, but before calling any other API from it.


also, note that druntime is using SIGUSR1 and SIGUSR2 for it's 
internal housekeeping, so don't use this signals in your C++ 
code.


Thank you for the quick reply.
Do you mean that I have to do some changes on the C side?
I can use dlang in this existing project as long as nothing can 
be changed on the C side.

Do you think I can use dlang in our case?

Thank you


One way to handle this is to add initialize/terminate functions 
to your shared library. In that case, rather than rt_init, you 
can call the Runtime functions [1]:


import core.runtime;

extern(C) int initialize() { return Runtime.initialize(); }
extern(C) int terminate() { return Runtime.terminate(); }

From your C program, call initialize after loading the library 
and terminate before exiting.


[1] http://dlang.org/phobos/core_runtime.html#.Runtime


Re: How to use std. packages in so files written in dlang

2016-08-11 Thread Mike Parker via Digitalmars-d-learn

On Friday, 12 August 2016 at 00:57:42 UTC, grampus wrote:

Hi,erveryone
I am trying to use dLang to make so file for existing c/c++ 
project.
I followed the examples on https://dlang.org/dll-linux.html, 
which works well.


but when I replaced import core.stdc.stdio; with import 
std.stdio;

to use writefln() instead of printf(), then things changed.



To expand on ketmar's answer, support for some language features 
exists in D Runtime. If you never use those features directly or 
indirectly (which means limiting yourself to the C API, avoiding 
anything that touches the GC, no associative arrays, and so on) 
then you don't need to initialize D runtime. That's why you don't 
see the problem when calling printf, but writeln uses features 
internally that require the D Runtime and so you get the error 
when you execute the program.


Re: How to use std. packages in so files written in dlang

2016-08-11 Thread grampus via Digitalmars-d-learn

On Friday, 12 August 2016 at 01:09:47 UTC, ketmar wrote:

On Friday, 12 August 2016 at 00:57:42 UTC, grampus wrote:

it's 'cause you didn't initialized druntime. you have to use 
dlsym to get "rt_init" function and call it right after loading 
your .so, but before calling any other API from it.


also, note that druntime is using SIGUSR1 and SIGUSR2 for it's 
internal housekeeping, so don't use this signals in your C++ 
code.


Thank you for the quick reply.
Do you mean that I have to do some changes on the C side?
I can use dlang in this existing project as long as nothing can 
be changed on the C side.

Do you think I can use dlang in our case?

Thank you


Re: how to declare an immutable class?

2016-08-11 Thread Mike Parker via Digitalmars-d-learn

On Friday, 12 August 2016 at 00:44:31 UTC, Charles Hixson wrote:
A way around this, which may be the same as the approach used 
by string was:


alias immutable(Msg_)Msg;
classMsg_
{  ...



This is exactly what Jonathan suggested in the post above. And 
yes, it's how string is handled:


alias string = immutable(char)[];



This so far appears to do what I want.  The only problem is 
that it introduces an extraneous symbol, which I would prefer 
to avoid.


What problem do you want to avoid? This is a common D idiom. 
Alias names are very short-lived. Yes, it's another symbol in the 
namespace, but it will never make it to the object file. It won't 
even make it to error messages -- you'll see Msg_ there instead.






Re: How to use std. packages in so files written in dlang

2016-08-11 Thread ketmar via Digitalmars-d-learn

On Friday, 12 August 2016 at 00:57:42 UTC, grampus wrote:

it's 'cause you didn't initialized druntime. you have to use 
dlsym to get "rt_init" function and call it right after loading 
your .so, but before calling any other API from it.


also, note that druntime is using SIGUSR1 and SIGUSR2 for it's 
internal housekeeping, so don't use this signals in your C++ code.


How to use std. packages in so files written in dlang

2016-08-11 Thread grampus via Digitalmars-d-learn

Hi,erveryone
I am trying to use dLang to make so file for existing c/c++ 
project.
I followed the examples on https://dlang.org/dll-linux.html, 
which works well.


but when I replaced import core.stdc.stdio; with import std.stdio;
to use writefln() instead of printf(), then things changed.

compiling was still fine. so file still can be loaded.
But writefln() generated a error: "Segmentation fault (core 
dumped)"


I tried to search for solutions everywhere but nothing works.

BTW, in the command "dmd -oflibdll.so dll.o -shared 
-defaultlib=libphobos2.so 
-L-rpath=/path/to/where/shared/library/is" which path should I 
use for "/path/to/where/shared/library/is"? Tried some possible 
paths, none of them works. I compiled so file without "-L-rpath". 
At least for the examples still works


I am new to dLang. I hope I get help here.

Thanks in advance.


Re: how to declare an immutable class?

2016-08-11 Thread Charles Hixson via Digitalmars-d-learn

A way around this, which may be the same as the approach used by string was:

alias immutable(Msg_)Msg;
classMsg_
{  ...

This so far appears to do what I want.  The only problem is that it 
introduces an extraneous symbol, which I would prefer to avoid.


OTOH, I did fix a few problems before this solution
On 08/11/2016 10:56 AM, Charles Hixson via Digitalmars-d-learn wrote:
I want to declare a class all instances of which will be immutable, 
and all references to which will be inherently immutable (so that I 
don't need to slip a huge number of "immutable" statements in my code).


This is surely possible, because string acts just that way, but I 
can't figure out how to do this.


immutable classMsg  {this(...) immutable{...} ... }

doesn't work that way, as when I do

Msg m = new Msg (...);

I get:

Error: incompatible types for ((this.m) - (m)): 'immutable(Msg)' and 
'cellram.Msg'


and

Error: immutable method cellram.Msg.this is not callable using a 
mutable object



Does anyone know the correct approach?






Re: mixin bug?

2016-08-11 Thread sldkf via Digitalmars-d-learn

On Thursday, 11 August 2016 at 20:27:01 UTC, Engine Machine wrote:
This requires F2 to know the future. It also forces it to use a 
specific bar. I want inheritance like logic.


You are goind to hit a wall. Template programming is not OOP.
I'm not even sure that reflection would work in order to 
determine the most "recent" overload.


Which is what we get when we mixin one deep, but when we go 
deeper, it breaks. I think this is a bug. It seems like D is 
trying to resolve things only after each mixin, rather than 
resolving after all nested mixins are evaluated.


This is the only issue I see: "It seems like D is trying to...". 
We need to know exactly what D does: 
https://issues.dlang.org/show_bug.cgi?id=16376.


Re: Retreive method given object, name and arguments

2016-08-11 Thread ketmar via Digitalmars-d-learn
On Thursday, 11 August 2016 at 20:27:51 UTC, Michael Coulombe 
wrote:


here is something for you to play with:


import std.stdio;

enum CallAllowed0;
enum CallAllowed1;

struct S {
  @CallAllowed0 void foo () { writeln("foo()"); }
  @CallAllowed1 void foo (int n) { writeln("foo(", n, ")"); }
}


bool hasGoodMethod(string methodName, UDA, C, Args...) () {
  import std.traits: hasUDA;
  bool res = false;
  alias Identity(T...) = T[0];
  foreach (string mem; __traits(allMembers, C)) {
static if (mem == methodName) {
  static if (is(typeof(__traits(getMember, C, mem {
alias mx = Identity!(__traits(getMember, C, mem));
foreach (auto t; __traits(getOverloads, C, mem)) {
  static if (hasUDA!(t, UDA)) {
static if (is(typeof((Args args) { auto dg = &t; 
dg(args); }))) {

  res = true;
  break;
}
  }
}
  }
}
  }
  return res;
}

auto doit(string methodName, UDA, C, Args...) (C c, Args args) {
  static if (hasGoodMethod!(methodName, UDA, C, Args)) {
mixin("return c."~methodName~"(args);");
  } else {
static assert(0, "can't call method '"~methodName~"' in type 
"~C.stringof);

  }
}


void main () {
  S s;
  version(v0) {
s.doit!("foo", CallAllowed0)(42);
  } else version(v1) {
s.doit!("foo", CallAllowed1)(42);
  } else version(v2) {
s.doit!("foo", CallAllowed0)();
  } else version(v3) {
s.doit!("foo", CallAllowed1)();
  } else {
static assert(0, "version?");
  }
}


% rdmd -version=v0 z02.d
z02.d(47): Error: static assert  "can't call method 'foo' in type 
S"
z02.d(55):instantiated from here: doit!("foo", 
CallAllowed0, S, int)


% rdmd -version=v1 z02.d
foo(42)

% rdmd -version=v2 z02.d
foo()

% rdmd -version=v3 z02.d
z02.d(47): Error: static assert  "can't call method 'foo' in type 
S"
z02.d(61):instantiated from here: doit!("foo", 
CallAllowed1, S)


Re: mixin bug?

2016-08-11 Thread Ali Çehreli via Digitalmars-d-learn

On 08/11/2016 01:27 PM, Engine Machine wrote:

> I see the mixin as a sort of copy and paste.

That's the case for string mixins. Template mixins bring a name 
resolution scope. My understanding of the topic:


  http://ddili.org/ders/d.en/mixin.html#ix_mixin.name%20space,%20mixin

The spec:

  https://dlang.org/spec/template-mixin.html

Ali



Re: Template parameters that don't affect template type

2016-08-11 Thread Meta via Digitalmars-d-learn

On Thursday, 11 August 2016 at 18:11:30 UTC, Engine Machine wrote:
I have the need, in some cases, to pass static information to a 
template class but don't want it to affect its type.


import std.algorithm, core.stdc.stdlib;
struct X(int defaultSize = 100)
{
   int Size;
   int* p;
   void foo(int size)
   {
Size = max(size, defaultSize);
p = cast(int*)malloc(Size);
   }
}

If I do

X!100 x;
X!100 y;
X!50 z;

then I can do

x = y;

but not

x = z;

but of course D things these are completely different types. 
The type it self does not depend on the default size.


While one could argue that it can be unsafe, in the my context, 
it is not.


Is there any way to get D to understand I want do not want a 
template parameter to be part of the type comparison?


I use several parameters to pass info to the type that does not 
change affect the type itself. It prevents the "same type" from 
being used with "itself".


another example:

struct s(T1, T2)
{
T1;
}

then

s!(int, double)

and

s!(int, float)

should really be the same type! The fact that T2 is not used is 
important!


I guess D just can't handle it though?


It can be done, but you have to be explicit and should think very 
carefully if this is really a good design.


struct X(int defaultSize = 100)
{
int size;
int* p;

void foo(int size)
{
size = max(size, defaultSize);
p = cast(int*)malloc(size);
}

X opAssign(X2: X!n, int n)(X2 other)
{
//Do whatever you want here
}

X2 changeDefaultSize(int n)()
{
auto newX = X!n(n, p);
p = null; //Release ownership of p

return newX;
}
}

void takesX50(X!50 x)
{
//...
}

void main()
{
X!100 n;
X!100 m;
X!50 o;

n = m;
o = m;

takesX50(n); //Error
takesX50(n.changeDefaultSize!50); //Okay
}

Really though this problem is properly solved by runtime 
polymorphism.


Re: Retreive method given object, name and arguments

2016-08-11 Thread ketmar via Digitalmars-d-learn

On Thursday, 11 August 2016 at 20:41:33 UTC, ketmar wrote:
ah, my bad, i missed UDA part of the question. sorry. ;-)


Re: Retreive method given object, name and arguments

2016-08-11 Thread ketmar via Digitalmars-d-learn
On Thursday, 11 August 2016 at 20:27:51 UTC, Michael Coulombe 
wrote:



import std.stdio;

struct S {
  void foo () { writeln("foo()"); }
  void foo (int n) { writeln("foo(", n, ")"); }
}


auto doit(string methodName, C, Args...) (C c, Args args) {
  static if (is(typeof(mixin("c."~methodName~"(args)" {
mixin("return c."~methodName~"(args);");
  } else {
throw new Exception("no method '"~methodName~"' in type 
"~C.stringof);

  }
}


void main () {
  S s;
  s.doit!"foo"(42);
  s.doit!"foo"();
  s.doit!"oops"(); // this throws
}


of course, you can replace `static if` with `static assert` to 
turn it into compile-time error.


Re: Template parameters that don't affect template type

2016-08-11 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/11/16 4:15 PM, Engine Machine wrote:

On Thursday, 11 August 2016 at 18:42:51 UTC, Steven Schveighoffer wrote:

On 8/11/16 2:11 PM, Engine Machine wrote:

I have the need, in some cases, to pass static information to a template
class but don't want it to affect its type.

import std.algorithm, core.stdc.stdlib;
struct X(int defaultSize = 100)
{
   int Size;
   int* p;
   void foo(int size)
   {
Size = max(size, defaultSize);
p = cast(int*)malloc(Size);
   }
}

If I do

X!100 x;
X!100 y;
X!50 z;

then I can do

x = y;

but not

x = z;

but of course D things these are completely different types. The type it
self does not depend on the default size.


And they should be different types. The code generated for the type is
different, in this case it's important to declare these are not the
same type.

For example, if x = y worked, then what should x.foo(5) do?


While one could argue that it can be unsafe, in the my context, it is
not.

Is there any way to get D to understand I want do not want a template
parameter to be part of the type comparison?


The type is part of the template, and the instantiations are
different. So no.


I use several parameters to pass info to the type that does not change
affect the type itself. It prevents the "same type" from being used with
"itself".


Then define how the compiler can convert from one to another. Or
redesign the type to specify the parameters at the right time.


another example:

struct s(T1, T2)
{
T1;
}

then

s!(int, double)

and

s!(int, float)

should really be the same type! The fact that T2 is not used is
important!


That's not how template types work.

your code is shorthand for:

template s(T1, T2)
{
   struct s
   {
  T1 t1; // I assume you wanted to put a member here?
   }
}

Two different instantiations of s create two different namespaces
where the structs are not the same.



I don't think this proves anything. You just rewrote the template. T2 is
still not used in either case and hence the type does not depend on it.


OK, I'll use a different example:

struct S(int N)
{
   int x;
}

S!1 s1;
S!2 s2 = s1; // error

This is very similar to what you are asking for.

This can be reimagined like so:

struct S1
{
   int x;
}

struct S2
{
   int x;
}

S1 s1;
S2 s2 = s1; // error

The names end in a different number. They have the same types and 
structure, but the compiler considers them to be different types.


Each instantiation of a template defines a DIFFERENT namespace. The only 
time the namespaces are identical are when the template parameters are 
identical. The reason templates are so useful is because I don't HAVE to 
write both S1 and S2. I can write it once and not have to repeat myself. 
But the template itself is not a namespace. Only the instantiated 
template is one.



Basically your logic is something like: A = 0*5 is different than B =
0*6. But both are the same, just because they look different doesn't
change that.


Not at all. This is way off.


You are misunderstanding what I am asking or saying.

The code may be different, but one reference can store the value of
another. The type itself does not depend on the parameter.


The namespace in which the type is declared depends on the parameter. 
Templates depend on this.


For instance:

template Foo(string name)
{
   static int x;
}

Foo!"blah".x = 5;

auto y = Foo!"blar".x;

The namespace I've declared depends on the name I've passed the 
template. I want to fetch a *different* x when I declare a *different* 
namespace. That's the point!


If the compiler said "hey, you aren't using the name string, so I'm just 
going to assume all these are the same", that's going to screw up the 
entire purpose of this construct.



X!100 x;
X!50 y;

50 for y does not change anything to the outside world about y.

So, for all practical purposes, we have

X x;
X y;


No, you have

X100 x;
X50 y;

Where X100 and X50 have the exact same structure. But they are different 
types because the names are different.



You are confusing the general case with the specific case. Sure, in
general, it doesn't work, we know that. But not all types are dependent
on their type parameter. Just because such parameters are specified does
not necessarily mean they should be different types.


Again, not how templates work. You are looking for a different mechanism.

-Steve


Re: Retreive method given object, name and arguments

2016-08-11 Thread Lodovico Giaretta via Digitalmars-d-learn
On Thursday, 11 August 2016 at 20:27:51 UTC, Michael Coulombe 
wrote:
Is there a way to implement "getSymbolOfCall" and 
"getDelegateOfCall" such that doit is functionally equivalent 
to calling the method directly?


auto doit(C, string methodName, Args...)(C c, Args args) {
alias methodSymbol = getSymbolOfCall!(c, methodName, Args);
pragma(msg, hasUDA!(methodSymbol, "my attr"));
auto dg = getDelegateOfCall!(c, methodName, Args);
return dg(args);
}

They should deal with getting the right overload, 
opDispatch-ing, and deducing template arguments from the real 
argument list to get a concrete delegate pointer. methodSymbol 
should give access to compile-time introspection like full 
signature and UDAs.


The ability to do this for non-member functions would be cool 
too, but is beyond my use case.


Maybe I'm not understanding correctly, but I think you can use 
string mixins:


auto doit(string methodName, C, Args...)(C c, Args args)
{
mixin("return c." ~ methodName ~ "(args);");
}


Retreive method given object, name and arguments

2016-08-11 Thread Michael Coulombe via Digitalmars-d-learn
Is there a way to implement "getSymbolOfCall" and 
"getDelegateOfCall" such that doit is functionally equivalent to 
calling the method directly?


auto doit(C, string methodName, Args...)(C c, Args args) {
alias methodSymbol = getSymbolOfCall!(c, methodName, Args);
pragma(msg, hasUDA!(methodSymbol, "my attr"));
auto dg = getDelegateOfCall!(c, methodName, Args);
return dg(args);
}

They should deal with getting the right overload, opDispatch-ing, 
and deducing template arguments from the real argument list to 
get a concrete delegate pointer. methodSymbol should give access 
to compile-time introspection like full signature and UDAs.


The ability to do this for non-member functions would be cool 
too, but is beyond my use case.


Re: mixin bug?

2016-08-11 Thread Engine Machine via Digitalmars-d-learn

On Thursday, 11 August 2016 at 19:05:58 UTC, sldkf wrote:
On Thursday, 11 August 2016 at 17:56:47 UTC, Engine Machine 
wrote:

template F1(T)
{
   void bar() { writeln("Bar0"); }
}

template F2(T)
{
   mixin F1!T;
   void foo() { bar(); }
}

template F3(T)
{
   mixin F2!T;
   void bar() { writeln("Bar1"); } // <- This bar should be 
used for F2's foo!


}

struct F4(T)
{
mixin F3!T;
}

(Or on can turn F3 in to a struct directly)


Then f3.foo() calls bar from F0, not F3's bar! This seems like 
a big bug! One expects the same behavior of mixins regardless 
of mixin nesting.


While you could argue that foo, when declared, is calling F0's 
bar, this is not consistent with the view that mixin templates 
only adds what is not there. I don't like the idea that calls 
are resolved first come first serve as it means one can't 
extend templates in a natural logical way.


I don't think it's a bug. F3's bar() doesn't exist yet in F2. 
Logically F1's one is called.


Yes, but when we "mixin" again, bar then does exist. I see the 
mixin as a sort of copy and paste. We only paste in what doesn't 
exist. So the first time bar gets inserted in to F2, but then 
that bar doesn't get inserted in to F3 because it already exists.


Basically a mixin of a mixin is not logically a mixin. That makes 
no sense to me.


A mixin is suppose to behave a certain way, but when we do a 
mixin of a mixin we get behavior that doesn't behave the same way 
as a single mixin.



The language allows to alias a mixin so that a particular 
overload can be called. In you case you can really target 
F1.bar without problem:




I don't want to target F1.bar, I want foo to target future bar's.

It is like overloading, but for templates.

If you were doing overloading, and it called the base function 
instead, it wouldn't be overloading, would it?



°°°
template F1(T){void bar() {writeln("Bar0");}}

template F2(T)
{
   mixin F1!T FF1;
   void foo() { FF3.bar; }
}



This requires F2 to know the future. It also forces it to use a 
specific bar. I want inheritance like logic. Which is what we get 
when we mixin one deep, but when we go deeper, it breaks. I think 
this is a bug. It seems like D is trying to resolve things only 
after each mixin, rather than resolving after all nested mixins 
are evaluated.







Re: Template parameters that don't affect template type

2016-08-11 Thread Engine Machine via Digitalmars-d-learn
On Thursday, 11 August 2016 at 18:42:51 UTC, Steven Schveighoffer 
wrote:

On 8/11/16 2:11 PM, Engine Machine wrote:
I have the need, in some cases, to pass static information to 
a template

class but don't want it to affect its type.

import std.algorithm, core.stdc.stdlib;
struct X(int defaultSize = 100)
{
   int Size;
   int* p;
   void foo(int size)
   {
Size = max(size, defaultSize);
p = cast(int*)malloc(Size);
   }
}

If I do

X!100 x;
X!100 y;
X!50 z;

then I can do

x = y;

but not

x = z;

but of course D things these are completely different types. 
The type it

self does not depend on the default size.


And they should be different types. The code generated for the 
type is different, in this case it's important to declare these 
are not the same type.


For example, if x = y worked, then what should x.foo(5) do?

While one could argue that it can be unsafe, in the my 
context, it is not.


Is there any way to get D to understand I want do not want a 
template

parameter to be part of the type comparison?


The type is part of the template, and the instantiations are 
different. So no.


I use several parameters to pass info to the type that does 
not change
affect the type itself. It prevents the "same type" from being 
used with

"itself".


Then define how the compiler can convert from one to another. 
Or redesign the type to specify the parameters at the right 
time.



another example:

struct s(T1, T2)
{
T1;
}

then

s!(int, double)

and

s!(int, float)

should really be the same type! The fact that T2 is not used 
is important!


That's not how template types work.

your code is shorthand for:

template s(T1, T2)
{
   struct s
   {
  T1 t1; // I assume you wanted to put a member here?
   }
}

Two different instantiations of s create two different 
namespaces where the structs are not the same.




I don't think this proves anything. You just rewrote the 
template. T2 is still not used in either case and hence the type 
does not depend on it.


Basically your logic is something like: A = 0*5 is different than 
B = 0*6. But both are the same, just because they look different 
doesn't change that.


I'd suggest if you don't use a template parameter, don't 
declare it. If you use it in a member function only (as in your 
first example), declare it in the member function as a template 
parameter.



I guess D just can't handle it though?


No, it doesn't handle incorrect assumptions very well ;)

-Steve


You are misunderstanding what I am asking or saying.

The code may be different, but one reference can store the value 
of another. The type itself does not depend on the parameter.


X!100 x;
X!50 y;

50 for y does not change anything to the outside world about y.

So, for all practical purposes, we have

X x;
X y;

in which case we can do

x = y; with no problem.

You are confusing the general case with the specific case. Sure, 
in general, it doesn't work, we know that. But not all types are 
dependent on their type parameter. Just because such parameters 
are specified does not necessarily mean they should be different 
types.



My example is not good because the types are different. If I did 
something like


void foo(int size)
   {
   Size = max(size, defaultSize, 100);
p = cast(int*)malloc(Size);
   }


Then it would be different.

in this case X!50 and X!100 would be the same. X!101 would not.



Re: Template parameters that don't affect template type

2016-08-11 Thread Engine Machine via Digitalmars-d-learn

Also, what if we use a class instead of a struct?

in this case they are both references to the same thing.

I see a problem with reflection though, as one could get the 
template parameter value and it would wrong on conversion. D 
takes the easy way out of just preventing complex and potentially 
ill-defined behavior, I guess that is ultimately a good thing, 
even if it makes it a pain in some cases.




Re: Template parameters that don't affect template type

2016-08-11 Thread Engine Machine via Digitalmars-d-learn
On Thursday, 11 August 2016 at 19:28:47 UTC, Lodovico Giaretta 
wrote:
On Thursday, 11 August 2016 at 18:11:30 UTC, Engine Machine 
wrote:

[...]


If, in your case, it is possible to use one type as the other, 
then specify it.
I mean, implement a templated opAssign that allows you to 
assign values of one instantiation to values of another. While 
doing so, remember that this will not change the behaviour of 
the assigned-to variable, but will only transfer the runtime 
state from one variable to the other.


struct S(T1, T2)
{
T1 t;
void opAssign(T)(auto ref S!(T1, T) other)
{
t = other.t;
}
}
unittest
{
S!(int, float) x(1);
S!(int, char) y(3);

x = y;
assert(x.t == 3);// the 
value of x is changed
static assert(is(typeof(x) == S!(int, float)))   // the 
type of x isn't changed

}


Ok, well, my point is that in some cases, the OpAssign is 
trivially since everything is copied. I guess being explicit is 
not a bad thing in this case though.





Re: how to declare an immutable class?

2016-08-11 Thread Jonathan M Davis via Digitalmars-d-learn
On Thursday, August 11, 2016 10:56:59 Charles Hixson via Digitalmars-d-learn 
wrote:
> I want to declare a class all instances of which will be immutable, and
> all references to which will be inherently immutable (so that I don't
> need to slip a huge number of "immutable" statements in my code).
>
> This is surely possible, because string acts just that way, but I can't
> figure out how to do this.
>
> immutable classMsg  {this(...) immutable{...} ... }
>
> doesn't work that way, as when I do
>
> Msg m = new Msg (...);
>
> I get:
>
> Error: incompatible types for ((this.m) - (m)): 'immutable(Msg)' and
> 'cellram.Msg'
>
> and
>
> Error: immutable method cellram.Msg.this is not callable using a mutable
> object
>
>
> Does anyone know the correct approach?

There is no such thing as an immutable class. You can have an instance of a
class that's immutable, and you can make it so that all of the members of a
class are immutable, but you're still going to need to use the keyword
immutable with the type to indicate that it's immutable. If you do

immutable class C
{
...
}

that's the same as

immutable
{
class C
{
...
}
}

It makes it so that all of the members of the class are immutable, but
if you use C in the code, it won't be immutable - only immutable C will be
immutable. Now, you could use an alias to reduce your typing. e.g.

alias IC = immutable C;

and then whenever you use IC, it will be replaced with immutable C by the
compiler, but anywhere you use C rather than the alias, you're going to need
to put immutable on it if you want it to be immutable. So, your code could
become something like

immutable class _Msg
{
// the immutable on the class made this immutable. There's no need
// to mark it with immutable.
this(...)
{
}

...
}

alias Msg = immutable _Msg;

and then when you do

auto msg = new Msg;

you'll get an immutable(_Msg).

- Jonathan M Davis



Re: Template parameters that don't affect template type

2016-08-11 Thread Lodovico Giaretta via Digitalmars-d-learn

On Thursday, 11 August 2016 at 18:11:30 UTC, Engine Machine wrote:

[...]


If, in your case, it is possible to use one type as the other, 
then specify it.
I mean, implement a templated opAssign that allows you to assign 
values of one instantiation to values of another. While doing so, 
remember that this will not change the behaviour of the 
assigned-to variable, but will only transfer the runtime state 
from one variable to the other.


struct S(T1, T2)
{
T1 t;
void opAssign(T)(auto ref S!(T1, T) other)
{
t = other.t;
}
}
unittest
{
S!(int, float) x(1);
S!(int, char) y(3);

x = y;
assert(x.t == 3);// the value 
of x is changed
static assert(is(typeof(x) == S!(int, float)))   // the type 
of x isn't changed

}




Re: mixin bug?

2016-08-11 Thread sldkf via Digitalmars-d-learn

On Thursday, 11 August 2016 at 17:56:47 UTC, Engine Machine wrote:

template F1(T)
{
   void bar() { writeln("Bar0"); }
}

template F2(T)
{
   mixin F1!T;
   void foo() { bar(); }
}

template F3(T)
{
   mixin F2!T;
   void bar() { writeln("Bar1"); } // <- This bar should be 
used for F2's foo!


}

struct F4(T)
{
mixin F3!T;
}

(Or on can turn F3 in to a struct directly)


Then f3.foo() calls bar from F0, not F3's bar! This seems like 
a big bug! One expects the same behavior of mixins regardless 
of mixin nesting.


While you could argue that foo, when declared, is calling F0's 
bar, this is not consistent with the view that mixin templates 
only adds what is not there. I don't like the idea that calls 
are resolved first come first serve as it means one can't 
extend templates in a natural logical way.


I don't think it's a bug. F3's bar() doesn't exist yet in F2. 
Logically F1's one is called.


The language allows to alias a mixin so that a particular 
overload can be called. In you case you can really target F1.bar 
without problem:


°°°
template F1(T){void bar() {writeln("Bar0");}}

template F2(T)
{
   mixin F1!T FF1;
   void foo() { FF3.bar; }
}

template F3(T)
{
   mixin F2!T FF2;
   void bar() { writeln("Bar1");}
}

struct F4(T){mixin F3!T FF3;}
°°°

See https://dlang.org/spec/template-mixin.html#mixin_scope

However the specification doesn't say what is the rule that's 
applied. Even if it look logical that F1.bar() is chosen it has 
to be written somewhere.


Re: Template parameters that don't affect template type

2016-08-11 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/11/16 2:42 PM, Steven Schveighoffer wrote:

On 8/11/16 2:11 PM, Engine Machine wrote:

I have the need, in some cases, to pass static information to a template
class but don't want it to affect its type.

import std.algorithm, core.stdc.stdlib;
struct X(int defaultSize = 100)
{
   int Size;
   int* p;
   void foo(int size)
   {
Size = max(size, defaultSize);
p = cast(int*)malloc(Size);
   }
}

If I do

X!100 x;
X!100 y;
X!50 z;

then I can do

x = y;

but not

x = z;

but of course D things these are completely different types. The type it
self does not depend on the default size.


And they should be different types. The code generated for the type is
different, in this case it's important to declare these are not the same
type.

For example, if x = y worked, then what should x.foo(5) do?


Of course, I meant x = z :)

-Steve


Re: Template parameters that don't affect template type

2016-08-11 Thread Ali Çehreli via Digitalmars-d-learn

On 08/11/2016 11:11 AM, Engine Machine wrote:
> I have the need, in some cases, to pass static information to a template
> class but don't want it to affect its type.
>
> import std.algorithm, core.stdc.stdlib;
> struct X(int defaultSize = 100)
> {
>int Size;
>int* p;
>void foo(int size)
>{
> Size = max(size, defaultSize);
> p = cast(int*)malloc(Size);
>}
> }
>
> If I do
>
> X!100 x;
> X!100 y;
> X!50 z;
>
> then I can do
>
> x = y;
>
> but not
>
> x = z;
>
> but of course D things these are completely different types.

The reason they are different types is the fact that the code generated 
for X!100 and X!50 are different. If x=z were allowed, which foo() would 
you expect to be executed for x.foo()? If it would change at run time 
depending on the actual type, we need a run-time expression, which 
cannot be a template parameter.


> The type it
> self does not depend on the default size.
>
> While one could argue that it can be unsafe, in the my context, it is 
not.


Understood but not possible with the template definition of D.

> Is there any way to get D to understand I want do not want a template
> parameter to be part of the type comparison?

It must involve runtime.

> I use several parameters to pass info to the type that does not change
> affect the type itself. It prevents the "same type" from being used with
> "itself".
>
> another example:
>
> struct s(T1, T2)
> {
> T1;
> }
>
> then
>
> s!(int, double)
>
> and
>
> s!(int, float)
>
> should really be the same type! The fact that T2 is not used is 
important!


It's not used in this module but another module may be using __traits 
(or std.traits) to inspect that second argument.


> I guess D just can't handle it though?

By design, no. (Another language that behaves this way is C++.)

Ali



Re: how to declare an immutable class?

2016-08-11 Thread sldkf via Digitalmars-d-learn

On Thursday, 11 August 2016 at 17:56:59 UTC, Charles Hixson wrote:

Does anyone know the correct approach?


I do:

°°
immutable class Foo
{
this() {}
}

void main()
{
auto foo = new immutable(Foo);
}
°°

But take care because you can't do much with an immutable class.


Re: Template parameters that don't affect template type

2016-08-11 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/11/16 2:11 PM, Engine Machine wrote:

I have the need, in some cases, to pass static information to a template
class but don't want it to affect its type.

import std.algorithm, core.stdc.stdlib;
struct X(int defaultSize = 100)
{
   int Size;
   int* p;
   void foo(int size)
   {
Size = max(size, defaultSize);
p = cast(int*)malloc(Size);
   }
}

If I do

X!100 x;
X!100 y;
X!50 z;

then I can do

x = y;

but not

x = z;

but of course D things these are completely different types. The type it
self does not depend on the default size.


And they should be different types. The code generated for the type is 
different, in this case it's important to declare these are not the same 
type.


For example, if x = y worked, then what should x.foo(5) do?


While one could argue that it can be unsafe, in the my context, it is not.

Is there any way to get D to understand I want do not want a template
parameter to be part of the type comparison?


The type is part of the template, and the instantiations are different. 
So no.



I use several parameters to pass info to the type that does not change
affect the type itself. It prevents the "same type" from being used with
"itself".


Then define how the compiler can convert from one to another. Or 
redesign the type to specify the parameters at the right time.



another example:

struct s(T1, T2)
{
T1;
}

then

s!(int, double)

and

s!(int, float)

should really be the same type! The fact that T2 is not used is important!


That's not how template types work.

your code is shorthand for:

template s(T1, T2)
{
   struct s
   {
  T1 t1; // I assume you wanted to put a member here?
   }
}

Two different instantiations of s create two different namespaces where 
the structs are not the same.


I'd suggest if you don't use a template parameter, don't declare it. If 
you use it in a member function only (as in your first example), declare 
it in the member function as a template parameter.



I guess D just can't handle it though?


No, it doesn't handle incorrect assumptions very well ;)

-Steve


Re: Template parameters that don't affect template type

2016-08-11 Thread sldkf via Digitalmars-d-learn

On Thursday, 11 August 2016 at 18:11:30 UTC, Engine Machine wrote:
Is there any way to get D to understand I want do not want a 
template parameter to be part of the type comparison?


No. Use a standard run-time parameter. Your problem can be solved 
by defining a constructor.


Re: Template parameters that don't affect template type

2016-08-11 Thread Engine Machine via Digitalmars-d-learn

On Thursday, 11 August 2016 at 18:11:30 UTC, Engine Machine wrote:
I have the need, in some cases, to pass static information to a 
template class but don't want it to affect its type.


import std.algorithm, core.stdc.stdlib;
struct X(int defaultSize = 100)
{
   int Size;
   int* p;
   void foo(int size)
   {
Size = max(size, defaultSize);
p = cast(int*)malloc(Size);
   }
}

If I do

X!100 x;
X!100 y;
X!50 z;

then I can do

x = y;

but not

x = z;

but of course D things these are completely different types. 
The type it self does not depend on the default size.


While one could argue that it can be unsafe, in the my context, 
it is not.


Is there any way to get D to understand I want do not want a 
template parameter to be part of the type comparison?


I use several parameters to pass info to the type that does not 
change affect the type itself. It prevents the "same type" from 
being used with "itself".


another example:

struct s(T1, T2)
{
T1;
}

then

s!(int, double)

and

s!(int, float)

should really be the same type! The fact that T2 is not used is 
important!


I guess D just can't handle it though?


Another good example is if something like

template X(bool ClearMemory = false)
{

}

ClearMemory would clearly not affect the type if it just clears 
memory that is malloc'ed, yet D would treat treat X!true from 
X!false.




Template parameters that don't affect template type

2016-08-11 Thread Engine Machine via Digitalmars-d-learn
I have the need, in some cases, to pass static information to a 
template class but don't want it to affect its type.


import std.algorithm, core.stdc.stdlib;
struct X(int defaultSize = 100)
{
   int Size;
   int* p;
   void foo(int size)
   {
Size = max(size, defaultSize);
p = cast(int*)malloc(Size);
   }
}

If I do

X!100 x;
X!100 y;
X!50 z;

then I can do

x = y;

but not

x = z;

but of course D things these are completely different types. The 
type it self does not depend on the default size.


While one could argue that it can be unsafe, in the my context, 
it is not.


Is there any way to get D to understand I want do not want a 
template parameter to be part of the type comparison?


I use several parameters to pass info to the type that does not 
change affect the type itself. It prevents the "same type" from 
being used with "itself".


another example:

struct s(T1, T2)
{
T1;
}

then

s!(int, double)

and

s!(int, float)

should really be the same type! The fact that T2 is not used is 
important!


I guess D just can't handle it though?







mixin bug?

2016-08-11 Thread Engine Machine via Digitalmars-d-learn

template F1(T)
{
   void bar() { writeln("Bar0"); }
}

template F2(T)
{
   mixin F1!T;
   void foo() { bar(); }
}

template F3(T)
{
   mixin F2!T;
   void bar() { writeln("Bar1"); } // <- This bar should be used 
for F2's foo!


}

struct F4(T)
{
mixin F3!T;
}

(Or on can turn F3 in to a struct directly)


Then f3.foo() calls bar from F0, not F3's bar! This seems like a 
big bug! One expects the same behavior of mixins regardless of 
mixin nesting.


While you could argue that foo, when declared, is calling F0's 
bar, this is not consistent with the view that mixin templates 
only adds what is not there. I don't like the idea that calls are 
resolved first come first serve as it means one can't extend 
templates in a natural logical way.











how to declare an immutable class?

2016-08-11 Thread Charles Hixson via Digitalmars-d-learn
I want to declare a class all instances of which will be immutable, and 
all references to which will be inherently immutable (so that I don't 
need to slip a huge number of "immutable" statements in my code).


This is surely possible, because string acts just that way, but I can't 
figure out how to do this.


immutable classMsg  {this(...) immutable{...} ... }

doesn't work that way, as when I do

Msg m = new Msg (...);

I get:

Error: incompatible types for ((this.m) - (m)): 'immutable(Msg)' and 
'cellram.Msg'


and

Error: immutable method cellram.Msg.this is not callable using a mutable 
object



Does anyone know the correct approach?



Re: Unexpected foreach lowering

2016-08-11 Thread Jonathan M Davis via Digitalmars-d-learn
On Thursday, August 11, 2016 08:42:27 Steven Schveighoffer via Digitalmars-d-
learn wrote:
> On 8/11/16 12:28 AM, Jonathan M Davis via Digitalmars-d-learn wrote:
> > On Wednesday, August 10, 2016 21:00:01 Lodovico Giaretta via
> > Digitalmars-d-
> >
> > learn wrote:
> >> Wow. Thanks. I didn't know the compiler would try opSlice. I will
> >> file it.
> >
> > It does that so that you can use foreach with containers without having to
> > call something on the container. The idea is that the container will
> > implement opSlice and make it return a range over the container, and
> > foreach will then use that range to iterate over the container.
>
> I get that. But it shouldn't try opSlice *first* if the item itself is a
> range (and it does do this). Many random-access ranges define opSlice,
> and most of the time range[] returns this. But in this case, it doesn't.
>
> But it's a no-op for ranges, why waste time calling it?

I was just explaining what the deal with opSlice and containers was, since
the OP wasn't familiar with it. I wasn't really saying anything about the
suggested change. However, I have to agree that the suggested change is
likely a good one. As it stands, no range should be implementing opSlice
with no arguments, since it's a container function, not a range function. No
range trait tests for it, and no range-based code should be using it. It's
just supposed to be used on containers to get a range not on the ranges
themselves. But some folks put it on ranges anyway (IIRC, there are even at
least a couple of cases in Phobos where opSlice is implemented on ranges
when it shouldn't be), and it causes problems. There might be a reason why
it would be a bad idea to change it so that opSlice is ignored by foreach if
the type is a range, but I can't think of any right now. Unfortunately,
ranges and foreach have a tendency to get a bit funny thanks to the
differing behavior between types (e.g. ranges that are implicitly saved when
used with foreach vs those that aren't), so mucking around with it should be
done with care, but it at least seems like your suggestion to skip opSlice
if the range primitives are there is a good one.

- Jonathan M Davis


Re: How to add nogc to delegate

2016-08-11 Thread Gary Willoughby via Digitalmars-d-learn

On Thursday, 11 August 2016 at 05:12:39 UTC, ag0aep6g wrote:

On 08/11/2016 06:15 AM, Engine Machine wrote:

void foo(@nogc void delegate())

doesn't work.


Put it after the parameter list, like so:

void foo(void delegate() @nogc)


You may also need to add the scope keyword too.

Reference:
http://forum.dlang.org/thread/zaxaqgeeenwypmijr...@forum.dlang.org


Re: Unexpected foreach lowering

2016-08-11 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/10/16 5:14 PM, ag0aep6g wrote:

On 08/10/2016 10:54 PM, Steven Schveighoffer wrote:

The issue is that it tries using [] on the item to see if it defines a
range-like thing. Since you don't define opSlice(), it automatically
goes to the subrange.

This breaks for int[] as well as Array.

If I add opSlice to your code (and return this) it works.

This is definitely a bug, it should try range functions before opSlice.
Please file.


Related:

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


That's the same issue. Thanks. Your case is even worse, because calling 
save could be unnecessary and costly.


Note that the compiler will turn this:

foreach(...; foo[]) into this: foreach(...; foo[][])

ugly...

-Steve


Re: Unexpected foreach lowering

2016-08-11 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/11/16 12:28 AM, Jonathan M Davis via Digitalmars-d-learn wrote:

On Wednesday, August 10, 2016 21:00:01 Lodovico Giaretta via Digitalmars-d-
learn wrote:

Wow. Thanks. I didn't know the compiler would try opSlice. I will
file it.


It does that so that you can use foreach with containers without having to
call something on the container. The idea is that the container will
implement opSlice and make it return a range over the container, and foreach
will then use that range to iterate over the container.


I get that. But it shouldn't try opSlice *first* if the item itself is a 
range (and it does do this). Many random-access ranges define opSlice, 
and most of the time range[] returns this. But in this case, it doesn't.


But it's a no-op for ranges, why waste time calling it?

-Steve



Re: minor question of the difference between " and '

2016-08-11 Thread pineapple via Digitalmars-d-learn

On Wednesday, 10 August 2016 at 23:32:54 UTC, WhatMeWorry wrote:
Afterall, isn't that the definition of a string?  So what's up 
with the two groupings of single quotes?


http://www.howtogeek.com/howto/29980/whats-the-difference-between-single-and-double-quotes-in-the-bash-shell/