Jump to page: 1 2
Thread overview
Annoyance: 'Shadowing declaration is deprecated'+ mixins
Jul 24, 2007
Don Clugston
Jul 24, 2007
downs
Jul 24, 2007
downs
Jul 24, 2007
Bill Baxter
Jul 24, 2007
Tristam MacDonald
Jul 24, 2007
Pragma
Jul 24, 2007
BCS
Jul 25, 2007
Stewart Gordon
Jul 25, 2007
Don Clugston
Jul 25, 2007
Don Clugston
Jul 25, 2007
Don Clugston
July 24, 2007
Is there any chance of getting the 'shadowing declaration is deprecated' error message disabled, for code inserted via a mixin?

It means that if you inject a 'for' loop into the current function, it appears to work, but will fail if another variable with the same name already exists.

void main()
{
// double i=300.0;
   mixin("for (int i=0; i<10; ++i) { func(i); }");
}

When such code is generated by a mixin, the shadowing does not indicate a probable error.

This is proving to be quite annoying for my BLADE rewrite.
July 24, 2007
Don Clugston wrote:
> Is there any chance of getting the 'shadowing declaration is deprecated' error message disabled, for code inserted via a mixin?
> 
> It means that if you inject a 'for' loop into the current function, it appears to work, but will fail if another variable with the same name already exists.
> 
> void main()
> {
> // double i=300.0;
>    mixin("for (int i=0; i<10; ++i) { func(i); }");
> }
> 
> When such code is generated by a mixin, the shadowing does not indicate a probable error.
> 
> This is proving to be quite annoying for my BLADE rewrite.
There's a workaround, but it's slightly perverted.

void main()
{
	double i=300.0;
	() { mixin("for int i=0; i<10; ++i) { func(i); }"); }();
}

This declares and calls a delegate in the same line, thereby establishing a distinct scope.
Beware performance degredation though.
 --downs
July 24, 2007
downs wrote:
> Beware performance degredation though.

Ahem. Degr_a_dation. Sorry.
July 24, 2007
Don Clugston wrote:
> Is there any chance of getting the 'shadowing declaration is deprecated' error message disabled, for code inserted via a mixin?
> 
> It means that if you inject a 'for' loop into the current function, it appears to work, but will fail if another variable with the same name already exists.
> 
> void main()
> {
> // double i=300.0;
>    mixin("for (int i=0; i<10; ++i) { func(i); }");
> }
> 
> When such code is generated by a mixin, the shadowing does not indicate a probable error.
> 
> This is proving to be quite annoying for my BLADE rewrite.

I guess one obvious solution is to give your counter variables some names that are more likely to be unique:

    mixin("for (int __i8473=0; __i8473<10; ++__i8473) { func(__i8473); }");



--bb
July 24, 2007
Bill Baxter Wrote:
> Don Clugston wrote:
> > Is there any chance of getting the 'shadowing declaration is deprecated' error message disabled, for code inserted via a mixin?
> > 
> > It means that if you inject a 'for' loop into the current function, it appears to work, but will fail if another variable with the same name already exists.
> > 
> > void main()
> > {
> > // double i=300.0;
> >    mixin("for (int i=0; i<10; ++i) { func(i); }");
> > }
> > 
> > When such code is generated by a mixin, the shadowing does not indicate a probable error.
> > 
> > This is proving to be quite annoying for my BLADE rewrite.
> 
> I guess one obvious solution is to give your counter variables some names that are more likely to be unique:
> 
>      mixin("for (int __i8473=0; __i8473<10; ++__i8473) { func(__i8473); }");
>

Hmm... This looks like a prime candidate for something like Scheme's 'gensym' call (which basically alliases an unique, un-named, and un-nameable symbol). Does anyone know of a way to accomplish the same at compile time in D?
July 24, 2007
Tristam MacDonald wrote:
> Bill Baxter Wrote:
>> Don Clugston wrote:
>>> Is there any chance of getting the 'shadowing declaration is deprecated' error message disabled, for code inserted via a mixin?
>>>
>>> It means that if you inject a 'for' loop into the current function, it appears to work, but will fail if another variable with the same name already exists.
>>>
>>> void main()
>>> {
>>> // double i=300.0;
>>>    mixin("for (int i=0; i<10; ++i) { func(i); }");
>>> }
>>>
>>> When such code is generated by a mixin, the shadowing does not indicate a probable error.
>>>
>>> This is proving to be quite annoying for my BLADE rewrite.
>> I guess one obvious solution is to give your counter variables some names that are more likely to be unique:
>>
>>      mixin("for (int __i8473=0; __i8473<10; ++__i8473) { func(__i8473); }");
>>
> 
> Hmm... This looks like a prime candidate for something like Scheme's 'gensym' call (which basically alliases an unique, un-named, and un-nameable symbol). Does anyone know of a way to accomplish the same at compile time in D?

FWIW, there was a thread here a while back about generating unique values at compile time.  In short, it's not possible (using pure D anyway) to maintain a state extrinsic to a set of template evaluations or CTFE calls.  You need that property in order to guarantee uniqueness in your symbols by employing a counter variable to distinguish them.

You have to either adopt some template warts to explicitly pass this state to every template/CTFE or use something outside D for all generated symbols to be unique.  BCS (I think) suggested a rather elegant hack that uses a C preprocessor to work around this limitation.  Another suggestion was to couple __LINE__ and __FILE__ to get *some* measure of uniqueness per-line.  So it can be done, but it won't necessarily be pretty.

It kinda makes me wish D had a __UNIQUE__ symbol (reliably unique for a given module/compilation unit?) for this kind of stuff.

const char[] sym = __UNIQUE__;
mixin("for (int " ~ sym ~ "=0; " ~ sym ~ "<10; ++" ~ sym ~ ") { func(" ~ sym ~ "); }");

-- 
- EricAnderton at yahoo
July 24, 2007
Reply to Pragma,

> You have to either adopt some template warts to explicitly pass this
> state to every template/CTFE or use something outside D for all
> generated symbols to be unique.  BCS (I think) 

guilty

> suggested a rather
> elegant hack that uses a C preprocessor to work around this
> limitation.

actually I couldn't get it working because I couldn't fake ++ under the preprocessor

> Another suggestion was to couple __LINE__ and __FILE__ to
> get *some* measure of uniqueness per-line.  So it can be done, but it
> won't necessarily be pretty.
> 

The final solution that worked used that (and some other entropy sources as well)

|module uniq;
|
|const char[] prefix = "";
|pragma(msg, prefix~"module uniq;")
|
|/** use this template as a unique uint
|
|  make sure that each usage has a unique string (__FILE__":"~itoa!(__LINE__) is a good starting point)
|
|  compile the program once, filter the output for lines that start with prefix and then recompile with that output replacing this file.
|*/
|template UniqID(char[] str)
|{
|  const uint UniqID = 0;
|  pragma(msg, "template UniqID(char[] str : \""~str~"\") {const uint UniqID = __LINE__;}")
|}


> It kinda makes me wish D had a __UNIQUE__ symbol (reliably unique for
> a given module/compilation unit?) for this kind of stuff.
> 
> const char[] sym = __UNIQUE__;
> mixin("for (int " ~ sym ~ "=0; " ~ sym ~ "<10; ++" ~ sym ~ ") { func("
> ~ sym ~ "); }");

make it a GUID... and have fun debugging _e4f74de910de478b8a8c7f79b92f8459(int _53e2b8bd63534fafbf3a0fe5caa955b4, float _f1e57ba407ba4b4185cb41f6b902f1cd)


July 25, 2007
Bill Baxter wrote:
> Don Clugston wrote:
>> Is there any chance of getting the 'shadowing declaration is deprecated' error message disabled, for code inserted via a mixin?
>>
>> It means that if you inject a 'for' loop into the current function, it appears to work, but will fail if another variable with the same name already exists.
>>
>> void main()
>> {
>> // double i=300.0;
>>    mixin("for (int i=0; i<10; ++i) { func(i); }");
>> }
>>
>> When such code is generated by a mixin, the shadowing does not indicate a probable error.
>>
>> This is proving to be quite annoying for my BLADE rewrite.
> 
> I guess one obvious solution is to give your counter variables some names that are more likely to be unique:
> 
>     mixin("for (int __i8473=0; __i8473<10; ++__i8473) { func(__i8473); }");

Yes. Although I don't like "likely" <g>. More difficult is the situation when the mixin is recursive. Each nested level needs to use a different name.
July 25, 2007
Don Clugston wrote:

> Is there any chance of getting the 'shadowing declaration is deprecated' error message disabled, for code inserted via a mixin?
> 
> It means that if you inject a 'for' loop into the current function, it appears to work, but will fail if another variable with the same name already exists.
> 
> void main()
> {
> // double i=300.0;
>     mixin("for (int i=0; i<10; ++i) { func(i); }");
> }
> 
> When such code is generated by a mixin, the shadowing does not indicate a probable error.
> 
> This is proving to be quite annoying for my BLADE rewrite.

I hope that when macros come there will be a possibility to choose between hygienic and unhygienic versions. I've started to think string mixins are a big design mistake. Looking at those compile time unique id hacks from Lisp coder's POV it's amazing to see how badly you can implement something so obvious. I wrote about macros a while ago and noticed that by increasing the power of template mixins and alias parameters it would be possible to achieve the same things and more without sacrificing e.g. syntactical transparency.
July 25, 2007
Jari-Matti Mäkelä wrote:
> Don Clugston wrote:
> 
>> Is there any chance of getting the 'shadowing declaration is deprecated'
>> error message disabled, for code inserted via a mixin?
>>
>> It means that if you inject a 'for' loop into the current function, it
>> appears to work, but will fail if another variable with the same name
>> already exists.
>>
>> void main()
>> {
>> // double i=300.0;
>>     mixin("for (int i=0; i<10; ++i) { func(i); }");
>> }
>>
>> When such code is generated by a mixin, the shadowing does not indicate a
>> probable error.
>>
>> This is proving to be quite annoying for my BLADE rewrite.
> 
> I hope that when macros come there will be a possibility to choose between
> hygienic and unhygienic versions. I've started to think string mixins are a
> big design mistake. Looking at those compile time unique id hacks from Lisp
> coder's POV it's amazing to see how badly you can implement something so
> obvious. I wrote about macros a while ago and noticed that by increasing
> the power of template mixins and alias parameters it would be possible to
> achieve the same things and more without sacrificing e.g. syntactical
> transparency.

My post was actually to indicate that this lack of hygiene is a genuine nuisance
(not merely aesthetically undesirable). I wonder when an unhygienic macro would actually be useful.

« First   ‹ Prev
1 2