Re: Phobos: __FILE__ as template default parameter

2016-07-05 Thread Johan Engelen via Digitalmars-d

On Monday, 20 June 2016 at 08:10:19 UTC, Dicebot wrote:


How about defining semantics like "try inlining if possible, 
fallback to always emitting symbol to object file otherwise"? 
That would also allow compatible implementation in dmd.


My reasoning for proposing that is that for all legitimate 
cases I'd have to use __FILE__ as a template argument I'd also 
want the symbol inlined to prevent the bloat. After all CT 
computation such functions tend to contain 1-2 lines of runtime 
code only.


In LDC, Phobos functions with __FILE__ as default template 
parameter value are now marked with `pragma(inline, true)`, as a 
workaround for the larger issue of what to do with __FILE__ as 
template parameter.

https://github.com/ldc-developers/phobos/commit/8b2052cffe159be3db7debbe28ee967630cb4588

(the issue was preventing cross-module inlining, so a workaround 
was needed)


Re: Phobos: __FILE__ as template default parameter

2016-06-22 Thread Johan Engelen via Digitalmars-d

On Tuesday, 21 June 2016 at 10:39:52 UTC, David Nadlinger wrote:

On Monday, 20 June 2016 at 08:10:19 UTC, Dicebot wrote:
How about defining semantics like "try inlining if possible, 
fallback to always emitting symbol to object file otherwise"? 
That would also allow compatible implementation in dmd.


This would get rid of the undefined symbols, but there is a 
much more subtle problem here that nobody has brought up yet: 
If the template ends up being emitted twice with different 
mangled names, then, well, it ends up existing twice in the 
final executable.


This is not really an issue for functions, but very much so for 
data symbols (e.g. a static variable inside a function), where 
you could end up with the same alias referring to two different 
pieces of data depending on where it is used from.


The root of this issue is that __FILE__ introduces incidental 
environmental state into the otherwise pure module system.


+1



Re: Phobos: __FILE__ as template default parameter

2016-06-21 Thread ZombineDev via Digitalmars-d

On Tuesday, 21 June 2016 at 10:34:01 UTC, pineapple wrote:

On Tuesday, 21 June 2016 at 10:28:03 UTC, pineapple wrote:

On Tuesday, 21 June 2016 at 02:59:44 UTC, ZombineDev wrote:

I think it would be good idea to take this even further:

T4 foo(T4, T0, T1, Ts..., T2, T3)(T0 t0, T1 t1, Args args, T2 
t2, T3 t3)


In other words, I think that the limitation that variadic 
template parameter list must be at the end of the function 
parameters is arbitrary and just a deficiency of the current 
implementation.


I don't disagree with you, but this is a separate issue. If 
the arguments trailing Args have default values (as they would 
in the case of __FILE__, __LINE__) it will create ambiguity.


void foo(Args...)(Args args, int n = 1);

What happens if I do this? foo(1, 2, 3, 4); Is n 1 or 4?


Another thought: What if in this case the trailing arguments 
are always the default value? In this case n is /always/ 1, 
file and line would always be __FILE__ and __LINE__. This would 
be a more general solution and maybe not too intolerably ugly.


It should work just like the regular expression .*.? - if all 
parameters after the variadic list have default values, then the 
list should capture all arguments and the last parameters use 
their default values. E.g. args is (1, 2, 3, 4) and n is 1 in 
your example.
In general the strategy should be: the variadic list captures as 
much arguments as its constraints allow it to capture.


// regex: (\d*)(.)(.?)
// (pretend that \d means scalar type)
void foo(T1, T2, Args...)(Args args, T1 t1, T2 t2 = "default"w)
if (allSatisfy!(isScalarType, Args))
{
pragma (msg, Args, ", ", T1, ", ", T2);
}

foo(0, 0L, "asd");   // (int, long), string, wstring
foo("asd", "sdf");   // (), string, string
foo('c', new Object, 3); // (char), Object, int



Re: Phobos: __FILE__ as template default parameter

2016-06-21 Thread David Nadlinger via Digitalmars-d

On Monday, 20 June 2016 at 08:10:19 UTC, Dicebot wrote:
How about defining semantics like "try inlining if possible, 
fallback to always emitting symbol to object file otherwise"? 
That would also allow compatible implementation in dmd.


This would get rid of the undefined symbols, but there is a much 
more subtle problem here that nobody has brought up yet: If the 
template ends up being emitted twice with different mangled 
names, then, well, it ends up existing twice in the final 
executable.


This is not really an issue for functions, but very much so for 
data symbols (e.g. a static variable inside a function), where 
you could end up with the same alias referring to two different 
pieces of data depending on where it is used from.


The root of this issue is that __FILE__ introduces incidental 
environmental state into the otherwise pure module system.


 — David


Re: Phobos: __FILE__ as template default parameter

2016-06-21 Thread pineapple via Digitalmars-d

On Tuesday, 21 June 2016 at 10:28:03 UTC, pineapple wrote:

On Tuesday, 21 June 2016 at 02:59:44 UTC, ZombineDev wrote:

I think it would be good idea to take this even further:

T4 foo(T4, T0, T1, Ts..., T2, T3)(T0 t0, T1 t1, Args args, T2 
t2, T3 t3)


In other words, I think that the limitation that variadic 
template parameter list must be at the end of the function 
parameters is arbitrary and just a deficiency of the current 
implementation.


I don't disagree with you, but this is a separate issue. If the 
arguments trailing Args have default values (as they would in 
the case of __FILE__, __LINE__) it will create ambiguity.


void foo(Args...)(Args args, int n = 1);

What happens if I do this? foo(1, 2, 3, 4); Is n 1 or 4?


Another thought: What if in this case the trailing arguments are 
always the default value? In this case n is /always/ 1, file and 
line would always be __FILE__ and __LINE__. This would be a more 
general solution and maybe not too intolerably ugly.


Re: Phobos: __FILE__ as template default parameter

2016-06-21 Thread pineapple via Digitalmars-d

On Tuesday, 21 June 2016 at 02:59:44 UTC, ZombineDev wrote:

I think it would be good idea to take this even further:

T4 foo(T4, T0, T1, Ts..., T2, T3)(T0 t0, T1 t1, Args args, T2 
t2, T3 t3)


In other words, I think that the limitation that variadic 
template parameter list must be at the end of the function 
parameters is arbitrary and just a deficiency of the current 
implementation.


I don't disagree with you, but this is a separate issue. If the 
arguments trailing Args have default values (as they would in the 
case of __FILE__, __LINE__) it will create ambiguity.


void foo(Args...)(Args args, int n = 1);

What happens if I do this? foo(1, 2, 3, 4); Is n 1 or 4?



Re: Phobos: __FILE__ as template default parameter

2016-06-20 Thread ZombineDev via Digitalmars-d

On Tuesday, 21 June 2016 at 02:59:44 UTC, ZombineDev wrote:

On Monday, 20 June 2016 at 14:28:06 UTC, Jacob Carlborg wrote:

On 2016-06-19 12:43, Dicebot wrote:

Yes. It is necessary because runtime parameter list is 
variadic -
template bloat in such cases is usually eliminated by 
forwarding to
another private method immediately turning file/line into 
first runtime

argument instead.


Would it be a bad idea to allow this in the compiler:

void foo(Args...)(Args args, string file = __FILE__, size_t 
line = __LINE__);


It wouldn't be possible to pass "file" or "line" when calling 
"foo". But it's useful for the special default values, 
__FILE__ and __LINE__.


I think it would be good idea to take this even further:

T4 foo(T4, T0, T1, Ts..., T2, T3)(T0 t0, T1 t1, Args args, T2 
t2, T3 t3)


In other words, I think that the limitation that variadic 
template parameter list must be at the end of the function 
parameters is arbitrary and just a deficiency of the current 
implementation.
A fixed number of parameters proceeding or following a variadic 
list should all work equally well, even in combination with 
IFTI.


BTW, Ruby also allows to define methods with such parameters: 
foo(first_arg, *middle_arguments, last_arg)


I meant:

T4 foo(T4, T0, T1, Ts..., T2, T3)(T0 t0, T1 t1, Ts ts, T2 t2, T3 
t3)




Re: Phobos: __FILE__ as template default parameter

2016-06-20 Thread ZombineDev via Digitalmars-d

On Monday, 20 June 2016 at 14:28:06 UTC, Jacob Carlborg wrote:

On 2016-06-19 12:43, Dicebot wrote:

Yes. It is necessary because runtime parameter list is 
variadic -
template bloat in such cases is usually eliminated by 
forwarding to
another private method immediately turning file/line into 
first runtime

argument instead.


Would it be a bad idea to allow this in the compiler:

void foo(Args...)(Args args, string file = __FILE__, size_t 
line = __LINE__);


It wouldn't be possible to pass "file" or "line" when calling 
"foo". But it's useful for the special default values, __FILE__ 
and __LINE__.


I think it would be good idea to take this even further:

T4 foo(T4, T0, T1, Ts..., T2, T3)(T0 t0, T1 t1, Args args, T2 t2, 
T3 t3)


In other words, I think that the limitation that variadic 
template parameter list must be at the end of the function 
parameters is arbitrary and just a deficiency of the current 
implementation.
A fixed number of parameters proceeding or following a variadic 
list should all work equally well, even in combination with IFTI.


BTW, Ruby also allows to define methods with such parameters: 
foo(first_arg, *middle_arguments, last_arg)





Re: Phobos: __FILE__ as template default parameter

2016-06-20 Thread Simen Kjaeraas via Digitalmars-d

On Monday, 20 June 2016 at 14:28:06 UTC, Jacob Carlborg wrote:


Would it be a bad idea to allow this in the compiler:

void foo(Args...)(Args args, string file = __FILE__, size_t 
line = __LINE__);


It wouldn't be possible to pass "file" or "line" when calling 
"foo". But it's useful for the special default values, __FILE__ 
and __LINE__.


I very much agree with this idea. Like with the current system of 
forwarding to a function with explicit file and line run-time 
arguments, a function can be made accessible that has them as 
explicit parameters for those cases when you want to pretend to 
be somewhere you're not. :p


--
  Simen


Re: Phobos: __FILE__ as template default parameter

2016-06-20 Thread Jacob Carlborg via Digitalmars-d

On 2016-06-19 12:43, Dicebot wrote:


Yes. It is necessary because runtime parameter list is variadic -
template bloat in such cases is usually eliminated by forwarding to
another private method immediately turning file/line into first runtime
argument instead.


Would it be a bad idea to allow this in the compiler:

void foo(Args...)(Args args, string file = __FILE__, size_t line = 
__LINE__);


It wouldn't be possible to pass "file" or "line" when calling "foo". But 
it's useful for the special default values, __FILE__ and __LINE__.


--
/Jacob Carlborg


Re: Phobos: __FILE__ as template default parameter

2016-06-20 Thread Dicebot via Digitalmars-d
On 06/20/2016 01:13 AM, Johan Engelen wrote:
> On Sunday, 19 June 2016 at 21:40:20 UTC, David Nadlinger wrote:
>> On Sunday, 19 June 2016 at 21:13:00 UTC, Johan Engelen wrote:
>>> On Sunday, 19 June 2016 at 21:11:59 UTC, Johan Engelen wrote:
 (I think we can pretty much inline anything the user throws at us)
>>>
>>> (as long as it is not a naked asm function)
>>
>> Another example is `alloca`, which you might not want to inline.
> 
> And also variadic functions, for which Dicebot needs __FILE__ to be a
> template param..

It is template-based variadic list though in all Phobos cases. This is
one of logger examples I was referring to :
https://github.com/dlang/phobos/blob/master/std/experimental/logger/core.d#L202-L216

How about defining semantics like "try inlining if possible, fallback to
always emitting symbol to object file otherwise"? That would also allow
compatible implementation in dmd.

My reasoning for proposing that is that for all legitimate cases I'd
have to use __FILE__ as a template argument I'd also want the symbol
inlined to prevent the bloat. After all CT computation such functions
tend to contain 1-2 lines of runtime code only.


Re: Phobos: __FILE__ as template default parameter

2016-06-19 Thread Lass Safin via Digitalmars-d

On Saturday, 18 June 2016 at 18:13:22 UTC, Johan Engelen wrote:
An example of how __FILE__ as template parameter will break 
your library:


In library, distributed in binary+source form:
```
alias file_templ_alias = file_templ!bool;
T file_templ(T, string file = __FILE__, size_t line = __LINE__) 
(T value) {

return value;
}
```
In user code, linking to the library binary:
```
bool foo(bool b){
return file_templ_alias(b);
}
```
By calling the alias, both DMD and LDC will decide that the 
template does not need reinstantiation in the user object file 
and will try to link with the symbol in the library binary. So 
you have to be lucky to install the library source in the same 
path as where it was when the library was built on someone 
else's machine, otherwise you'll get a linker error and are 
left wondering what went wrong.


-Johan


Can't one just use __MODULE__ instead?

So:
T file_templ(T, string mod = __MODULE__, size_t line = __LINE__)
(T value) {
return value;
}



Re: Phobos: __FILE__ as template default parameter

2016-06-19 Thread Johan Engelen via Digitalmars-d

On Sunday, 19 June 2016 at 21:40:20 UTC, David Nadlinger wrote:

On Sunday, 19 June 2016 at 21:13:00 UTC, Johan Engelen wrote:

On Sunday, 19 June 2016 at 21:11:59 UTC, Johan Engelen wrote:
(I think we can pretty much inline anything the user throws 
at us)


(as long as it is not a naked asm function)


Another example is `alloca`, which you might not want to inline.


And also variadic functions, for which Dicebot needs __FILE__ to 
be a template param..


Re: Phobos: __FILE__ as template default parameter

2016-06-19 Thread David Nadlinger via Digitalmars-d

On Sunday, 19 June 2016 at 21:13:00 UTC, Johan Engelen wrote:

On Sunday, 19 June 2016 at 21:11:59 UTC, Johan Engelen wrote:
(I think we can pretty much inline anything the user throws at 
us)


(as long as it is not a naked asm function)


Another example is `alloca`, which you might not want to inline.

 — David


Re: Phobos: __FILE__ as template default parameter

2016-06-19 Thread Johan Engelen via Digitalmars-d

On Sunday, 19 June 2016 at 21:11:59 UTC, Johan Engelen wrote:
(I think we can pretty much inline anything the user throws at 
us)


(as long as it is not a naked asm function)




Re: Phobos: __FILE__ as template default parameter

2016-06-19 Thread Johan Engelen via Digitalmars-d

On Sunday, 19 June 2016 at 20:37:02 UTC, Dicebot wrote:

On 06/19/2016 11:33 AM, Johan Engelen wrote:

On Sunday, 19 June 2016 at 08:06:09 UTC, Dicebot wrote:
This important feature and can't be simply removed. For 
example, std.experimental.logger also relies on it.


Do you mean it relies on __FILE__ being a template parameter 
(instead of a runtime default parameter, like enforce)?



It needs to be fixed instead.

Two immediate workarounds that come to mmy mind:

1. Make __FILE__ relative to import path
2. Always emit new symbol to object file if __FILE__ is 
involved


I also thought about 2. It would fix the second (non-Phobos) 
example.


-Johan


Another option would be to treat functions relying on __FILE__ 
as template argument as force inline ones.


Yes, but it's a flaky solution I think.
For LDC that would work (I think we can pretty much inline 
anything the user throws at us). I don't know about DMD.


Re: Phobos: __FILE__ as template default parameter

2016-06-19 Thread Dicebot via Digitalmars-d
On 06/19/2016 11:33 AM, Johan Engelen wrote:
> On Sunday, 19 June 2016 at 08:06:09 UTC, Dicebot wrote:
>> This important feature and can't be simply removed. For example,
>> std.experimental.logger also relies on it.
> 
> Do you mean it relies on __FILE__ being a template parameter (instead of
> a runtime default parameter, like enforce)?
> 
>> It needs to be fixed instead.
>>
>> Two immediate workarounds that come to mmy mind:
>>
>> 1. Make __FILE__ relative to import path
>> 2. Always emit new symbol to object file if __FILE__ is involved
> 
> I also thought about 2. It would fix the second (non-Phobos) example.
> 
> -Johan

Another option would be to treat functions relying on __FILE__ as
template argument as force inline ones.



Re: Phobos: __FILE__ as template default parameter

2016-06-19 Thread Dicebot via Digitalmars-d

On Sunday, 19 June 2016 at 08:33:40 UTC, Johan Engelen wrote:

On Sunday, 19 June 2016 at 08:06:09 UTC, Dicebot wrote:
This important feature and can't be simply removed. For 
example, std.experimental.logger also relies on it.


Do you mean it relies on __FILE__ being a template parameter 
(instead of a runtime default parameter, like enforce)?


Yes. It is necessary because runtime parameter list is variadic - 
template bloat in such cases is usually eliminated by forwarding 
to another private method immediately turning file/line into 
first runtime argument instead.



It needs to be fixed instead.

Two immediate workarounds that come to mmy mind:

1. Make __FILE__ relative to import path
2. Always emit new symbol to object file if __FILE__ is 
involved


I also thought about 2. It would fix the second (non-Phobos) 
example.


-Johan





Re: Phobos: __FILE__ as template default parameter

2016-06-19 Thread Johan Engelen via Digitalmars-d

On Sunday, 19 June 2016 at 08:06:09 UTC, Dicebot wrote:
This important feature and can't be simply removed. For 
example, std.experimental.logger also relies on it.


Do you mean it relies on __FILE__ being a template parameter 
(instead of a runtime default parameter, like enforce)?



It needs to be fixed instead.

Two immediate workarounds that come to mmy mind:

1. Make __FILE__ relative to import path
2. Always emit new symbol to object file if __FILE__ is involved


I also thought about 2. It would fix the second (non-Phobos) 
example.


-Johan


Re: Phobos: __FILE__ as template default parameter

2016-06-19 Thread Dicebot via Digitalmars-d
This important feature and can't be simply removed. For example, 
std.experimental.logger also relies on it. It needs to be fixed 
instead.


Two immediate workarounds that come to mmy mind:

1. Make __FILE__ relative to import path
2. Always emit new symbol to object file if __FILE__ is involved


Re: Phobos: __FILE__ as template default parameter

2016-06-18 Thread Johan Engelen via Digitalmars-d
An example of how __FILE__ as template parameter will break your 
library:


In library, distributed in binary+source form:
```
alias file_templ_alias = file_templ!bool;
T file_templ(T, string file = __FILE__, size_t line = __LINE__) 
(T value) {

return value;
}
```
In user code, linking to the library binary:
```
bool foo(bool b){
return file_templ_alias(b);
}
```
By calling the alias, both DMD and LDC will decide that the 
template does not need reinstantiation in the user object file 
and will try to link with the symbol in the library binary. So 
you have to be lucky to install the library source in the same 
path as where it was when the library was built on someone else's 
machine, otherwise you'll get a linker error and are left 
wondering what went wrong.


-Johan