<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>
<channel>
	<title>Comments on: D2009 Generics and Type Constraints</title>
	<atom:link href="http://blogs.teamb.com/craigstuntz/2008/08/29/37832/feed/" rel="self" type="application/rss+xml" />
	<link>http://blogs.teamb.com/craigstuntz/2008/08/29/37832/</link>
	<description>C# • Delphi • Entity Framework • Functional Programming • InterBase • MVC • .NET • Web</description>
	<pubDate>Tue, 07 Sep 2010 10:36:15 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.2</generator>
		<item>
		<title>By: Craig Stuntz</title>
		<link>http://blogs.teamb.com/craigstuntz/2008/08/29/37832/#comment-4391</link>
		<dc:creator>Craig Stuntz</dc:creator>
		<pubDate>Tue, 27 Jan 2009 06:18:05 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/2008/08/29/37832#comment-4391</guid>
		<description>&lt;i&gt;why, in a *compiled* language which produces compiled, typefree, static asm code do we have to pay a *runtime* overhead for static type constrains?&lt;/i&gt;

False premise. Constraints aren't casts, and you don't pay a runtime cost. Constraints are checked at compile time.

The cost you &lt;i&gt;do&lt;/i&gt; pay for using an interface is due to (1) the virtual methods and (2) the reference counting, not the generic constraint. You can use a base object type as the generic constraint to avoid it. You will have exactly the same performance characteristics when using interfaces without generics.

I will say, though, that the performance problems associated with virtual method dispatch may be fixable in some future, improved version of the compiler. As an example, look at what the V8 JavaScript engine does.</description>
		<content:encoded><![CDATA[<p><i>why, in a *compiled* language which produces compiled, typefree, static asm code do we have to pay a *runtime* overhead for static type constrains?</i></p>
<p>False premise. Constraints aren&#8217;t casts, and you don&#8217;t pay a runtime cost. Constraints are checked at compile time.</p>
<p>The cost you <i>do</i> pay for using an interface is due to (1) the virtual methods and (2) the reference counting, not the generic constraint. You can use a base object type as the generic constraint to avoid it. You will have exactly the same performance characteristics when using interfaces without generics.</p>
<p>I will say, though, that the performance problems associated with virtual method dispatch may be fixable in some future, improved version of the compiler. As an example, look at what the V8 JavaScript engine does.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Georges V</title>
		<link>http://blogs.teamb.com/craigstuntz/2008/08/29/37832/#comment-4390</link>
		<dc:creator>Georges V</dc:creator>
		<pubDate>Tue, 27 Jan 2009 06:11:09 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/2008/08/29/37832#comment-4390</guid>
		<description>Adding yet another point on generics, in a cold post :

for the record, some sort of template coding was already possible in previous versions of Delphi :
-the "{$INCLUDE }" directive allows you to paste verbatim source code from some other file,
-Delphi allows you to give any name to any existing type.

So you can write :

UNIT MappingIntegerString;

INTERFACE

TYPE
  _TEMPLATE_KEY_TYPE_ = Integer;
  _TEMPLATE_ITEM_TYPE_ = String;

{$INCLUDE 'GenericMappingInterface.inc'} //&#60;- file where you write declarations using references to types names _TEMPLATE_KEY_TYPE_ and _TEMPLATE_ITEM_TYPE_

  TMappingIntegerString = _TEMPLATE_MAPPING_TYPE_ //&#60;- likewise, you choose in GenericMappingInterface.inc the convention for the name of the resulting class/record/...

IMPLEMENTATION

{$INCLUDE 'GenericMappingImplementation.inc'} //&#60;- file containing your template ipmplementation, using the same name conventions as above

END.

We are making extensive use of this feature with our Delphi projects.
The gain is pretty straightforward.
The main drawback with this method is that you have to explicitly create a separate Unit file for each instance of your template, since declaring 2 different versions of a template -e.g. MappingIntegerString and MappingIntegerInteger- in the same unit would result in a name conflict with the types.
With this method, you have the same debugging issues as templates in C++ : you potentially have different bugs for different instances of your template, caused for various reasons, and the compiler is obviously not adapted to check types and coherence in partial source files (in this case : the two .inc files used).


We are currently moving to Delphi 2009, and are pretty excited with the Generic type features for win32 (our projects are all for win32 platform).
However, we already saw several drawbacks :
-first, the CodeGear team did a terrific job at including generic types in a compiled language, but there are still too many bugs in the implementation (the first released version prevented to use pointers on generic types, there are still some strange compiling issues with method declaration...) ;
-second, we made some performance test, and going through *runtime* interfaces for generic types just doesn't make it - we will still have to use our home brewed templates for performance issues in computation intensive parts.

Though I am really looking forward to use the neat genric syntax, I will go with Sergey : why, in a *compiled* language which produces compiled, typefree, static asm code do we have to pay a *runtime* overhead for static type constrains?</description>
		<content:encoded><![CDATA[<p>Adding yet another point on generics, in a cold post :</p>
<p>for the record, some sort of template coding was already possible in previous versions of Delphi :<br />
-the "{$INCLUDE }" directive allows you to paste verbatim source code from some other file,<br />
-Delphi allows you to give any name to any existing type.</p>
<p>So you can write :</p>
<p>UNIT MappingIntegerString;</p>
<p>INTERFACE</p>
<p>TYPE<br />
  _TEMPLATE_KEY_TYPE_ = Integer;<br />
  _TEMPLATE_ITEM_TYPE_ = String;</p>
<p>{$INCLUDE &#8216;GenericMappingInterface.inc&#8217;} //&lt;- file where you write declarations using references to types names _TEMPLATE_KEY_TYPE_ and _TEMPLATE_ITEM_TYPE_</p>
<p>  TMappingIntegerString = _TEMPLATE_MAPPING_TYPE_ //&lt;- likewise, you choose in GenericMappingInterface.inc the convention for the name of the resulting class/record/&#8230;</p>
<p>IMPLEMENTATION</p>
<p>{$INCLUDE &#8216;GenericMappingImplementation.inc&#8217;} //&lt;- file containing your template ipmplementation, using the same name conventions as above</p>
<p>END.</p>
<p>We are making extensive use of this feature with our Delphi projects.<br />
The gain is pretty straightforward.<br />
The main drawback with this method is that you have to explicitly create a separate Unit file for each instance of your template, since declaring 2 different versions of a template -e.g. MappingIntegerString and MappingIntegerInteger- in the same unit would result in a name conflict with the types.<br />
With this method, you have the same debugging issues as templates in C++ : you potentially have different bugs for different instances of your template, caused for various reasons, and the compiler is obviously not adapted to check types and coherence in partial source files (in this case : the two .inc files used).</p>
<p>We are currently moving to Delphi 2009, and are pretty excited with the Generic type features for win32 (our projects are all for win32 platform).<br />
However, we already saw several drawbacks :<br />
-first, the CodeGear team did a terrific job at including generic types in a compiled language, but there are still too many bugs in the implementation (the first released version prevented to use pointers on generic types, there are still some strange compiling issues with method declaration&#8230;) ;<br />
-second, we made some performance test, and going through *runtime* interfaces for generic types just doesn&#8217;t make it - we will still have to use our home brewed templates for performance issues in computation intensive parts.</p>
<p>Though I am really looking forward to use the neat genric syntax, I will go with Sergey : why, in a *compiled* language which produces compiled, typefree, static asm code do we have to pay a *runtime* overhead for static type constrains?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: David M</title>
		<link>http://blogs.teamb.com/craigstuntz/2008/08/29/37832/#comment-3821</link>
		<dc:creator>David M</dc:creator>
		<pubDate>Mon, 08 Sep 2008 05:39:32 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/2008/08/29/37832#comment-3821</guid>
		<description>"David, the constructor constraint specifies the signature of the constructor which the passed type argument must have. If memory serves, records can have constructors now, as well, so it’s not the same as a class constraint. In this case, I’m specifying a parameter less constructor."

Thanks, Craig.  I didn't know that was possible.  I can think of a number of ways that would be very useful.

"OK, I see that I’m going to have to write some more posts on this subject in order to cover some of the questions and assertions in comments."

I'd find another post interesting, and it would be great to have more information about some of this.  Thanks for this one, though!</description>
		<content:encoded><![CDATA[<p>"David, the constructor constraint specifies the signature of the constructor which the passed type argument must have. If memory serves, records can have constructors now, as well, so it’s not the same as a class constraint. In this case, I’m specifying a parameter less constructor."</p>
<p>Thanks, Craig.  I didn&#8217;t know that was possible.  I can think of a number of ways that would be very useful.</p>
<p>"OK, I see that I’m going to have to write some more posts on this subject in order to cover some of the questions and assertions in comments."</p>
<p>I&#8217;d find another post interesting, and it would be great to have more information about some of this.  Thanks for this one, though!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Sergey Antonov</title>
		<link>http://blogs.teamb.com/craigstuntz/2008/08/29/37832/#comment-3817</link>
		<dc:creator>Sergey Antonov</dc:creator>
		<pubDate>Tue, 02 Sep 2008 19:11:48 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/2008/08/29/37832#comment-3817</guid>
		<description>Craing, I am very thankful to you.

Thank you again.</description>
		<content:encoded><![CDATA[<p>Craing, I am very thankful to you.</p>
<p>Thank you again.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Craig Stuntz</title>
		<link>http://blogs.teamb.com/craigstuntz/2008/08/29/37832/#comment-3816</link>
		<dc:creator>Craig Stuntz</dc:creator>
		<pubDate>Tue, 02 Sep 2008 19:09:59 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/2008/08/29/37832#comment-3816</guid>
		<description>I disagree that .NET and Win32 Delphi are different WRT generic type safety.</description>
		<content:encoded><![CDATA[<p>I disagree that .NET and Win32 Delphi are different WRT generic type safety.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Sergey Antonov</title>
		<link>http://blogs.teamb.com/craigstuntz/2008/08/29/37832/#comment-3815</link>
		<dc:creator>Sergey Antonov</dc:creator>
		<pubDate>Tue, 02 Sep 2008 19:06:27 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/2008/08/29/37832#comment-3815</guid>
		<description>Craig, I try to answer your question.

If your list of type constraints starts looking like a class definition, and I would question how "generic" your type really is?

The class parametrization is just the way to define generic behaviour. 

So, the expression 
(U+T*Z-V*10*(cast to V) (U))/U is still generalized.

But for code generation there must be a guarantee to accomplish compilation process successfully.

For intermediate platforms, for generic IL code there is needs for additional info(constraints) to guarantee safe code.
At compile time that analysis of course may be carried out by compiler on source code. 
So instantiation may valid. But at run time instantiation without constraints results in needs for reverse engineering of IL code to deduce constraints violation(an code of course). 
But instantiation of .NET generics occurs at run time so no constraints, no safe code.

So for native platforms, there is no needs in any constraints, because all may be infered at compile time. But with one restriction there are no way to instantiate Generic class at run time with rational effort of course.</description>
		<content:encoded><![CDATA[<p>Craig, I try to answer your question.</p>
<p>If your list of type constraints starts looking like a class definition, and I would question how "generic" your type really is?</p>
<p>The class parametrization is just the way to define generic behaviour. </p>
<p>So, the expression<br />
(U+T*Z-V*10*(cast to V) (U))/U is still generalized.</p>
<p>But for code generation there must be a guarantee to accomplish compilation process successfully.</p>
<p>For intermediate platforms, for generic IL code there is needs for additional info(constraints) to guarantee safe code.<br />
At compile time that analysis of course may be carried out by compiler on source code.<br />
So instantiation may valid. But at run time instantiation without constraints results in needs for reverse engineering of IL code to deduce constraints violation(an code of course).<br />
But instantiation of .NET generics occurs at run time so no constraints, no safe code.</p>
<p>So for native platforms, there is no needs in any constraints, because all may be infered at compile time. But with one restriction there are no way to instantiate Generic class at run time with rational effort of course.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Craig Stuntz</title>
		<link>http://blogs.teamb.com/craigstuntz/2008/08/29/37832/#comment-3814</link>
		<dc:creator>Craig Stuntz</dc:creator>
		<pubDate>Tue, 02 Sep 2008 18:42:54 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/2008/08/29/37832#comment-3814</guid>
		<description>Sergey, the "barrier" is the internal design of the Delphi compiler, written in the 90s without thought of inlining or generics, not a logical limitation on what could theoretically be done, outside of that specific design.</description>
		<content:encoded><![CDATA[<p>Sergey, the "barrier" is the internal design of the Delphi compiler, written in the 90s without thought of inlining or generics, not a logical limitation on what could theoretically be done, outside of that specific design.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Sergey Antonov</title>
		<link>http://blogs.teamb.com/craigstuntz/2008/08/29/37832/#comment-3813</link>
		<dc:creator>Sergey Antonov</dc:creator>
		<pubDate>Tue, 02 Sep 2008 18:31:36 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/2008/08/29/37832#comment-3813</guid>
		<description>Craig, thank you for you opinion. :)

&#62; In short, it’s a limitation of the compiler, and one &#62;which isn’t likely to go away soon. 

The key words here is the limitation of the compiler. I think that the inner representation
of parse tree is only the inner representation. 

Suppose the next code

SomeClassA=class(Some)
procedure abc;
end;

Why I can not write? 

procedure SomeClassA.abc;
asm
end;

No dependency.
Where and what is the barrier?
What do you think about the relocable asm code representation in dcu?

Or the next one 

procedure SomeClassA.abc;
var a,b:T;
begin
...
a:=b;

{relocable code.}
asm
lea eax,[a];               
end;
...
b:=a;
..
end;

But!!! I think
Problem is that generics in native Delphi is a satelite of generics in Delphi.NET. 
Resriction of using operators on T is just  restriction of .NET.</description>
		<content:encoded><![CDATA[<p>Craig, thank you for you opinion. <img src='http://blogs.teamb.com/craigstuntz/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>&gt; In short, it’s a limitation of the compiler, and one &gt;which isn’t likely to go away soon. </p>
<p>The key words here is the limitation of the compiler. I think that the inner representation<br />
of parse tree is only the inner representation. </p>
<p>Suppose the next code</p>
<p>SomeClassA=class(Some)<br />
procedure abc;<br />
end;</p>
<p>Why I can not write? </p>
<p>procedure SomeClassA.abc;<br />
asm<br />
end;</p>
<p>No dependency.<br />
Where and what is the barrier?<br />
What do you think about the relocable asm code representation in dcu?</p>
<p>Or the next one </p>
<p>procedure SomeClassA.abc;<br />
var a,b:T;<br />
begin<br />
&#8230;<br />
a:=b;</p>
<p>{relocable code.}<br />
asm<br />
lea eax,[a];<br />
end;<br />
&#8230;<br />
b:=a;<br />
..<br />
end;</p>
<p>But!!! I think<br />
Problem is that generics in native Delphi is a satelite of generics in Delphi.NET.<br />
Resriction of using operators on T is just  restriction of .NET.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Craig Stuntz</title>
		<link>http://blogs.teamb.com/craigstuntz/2008/08/29/37832/#comment-3812</link>
		<dc:creator>Craig Stuntz</dc:creator>
		<pubDate>Tue, 02 Sep 2008 17:48:14 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/2008/08/29/37832#comment-3812</guid>
		<description>Sergey, in Jim McKeeth's interview with Barry Kelly, Barry comments that generics are implemented in a part of the compiler which was originally developed for method inlining.  As you may know, ASM cannot be used in an inlined method, either.  Barry doesn't discuss why in this specific interview, explicitly, but if you read between the lines of his comments about storing the parse tree of inlined methods in the DCU, I think you'll figure it out.  In short, it's a limitation of the compiler, and one which isn't likely to go away soon.  To be honest, I think you'd have a pretty difficult time writing truly generic code in ASM anyway, but that's a separate issue from the fact that you cannot do it at all right now.

How many generic type constraints must a programmer declare?  As many as you need, for the code you have to write.  If your list of type constraints starts looking like a class definition, and I would question how "generic" your type really is.  Generally, one uses interfaces for such "heavily constrained" type arguments, but in Delphi we have to work around that for types which cannot use interfaces, i.e., primitive types.</description>
		<content:encoded><![CDATA[<p>Sergey, in Jim McKeeth&#8217;s interview with Barry Kelly, Barry comments that generics are implemented in a part of the compiler which was originally developed for method inlining.  As you may know, ASM cannot be used in an inlined method, either.  Barry doesn&#8217;t discuss why in this specific interview, explicitly, but if you read between the lines of his comments about storing the parse tree of inlined methods in the DCU, I think you&#8217;ll figure it out.  In short, it&#8217;s a limitation of the compiler, and one which isn&#8217;t likely to go away soon.  To be honest, I think you&#8217;d have a pretty difficult time writing truly generic code in ASM anyway, but that&#8217;s a separate issue from the fact that you cannot do it at all right now.</p>
<p>How many generic type constraints must a programmer declare?  As many as you need, for the code you have to write.  If your list of type constraints starts looking like a class definition, and I would question how "generic" your type really is.  Generally, one uses interfaces for such "heavily constrained" type arguments, but in Delphi we have to work around that for types which cannot use interfaces, i.e., primitive types.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Sergey Antonov</title>
		<link>http://blogs.teamb.com/craigstuntz/2008/08/29/37832/#comment-3811</link>
		<dc:creator>Sergey Antonov</dc:creator>
		<pubDate>Tue, 02 Sep 2008 17:21:51 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/2008/08/29/37832#comment-3811</guid>
		<description>Good evening, Craig! 

First of all about bug, 

procedure Some"T".DoSomething(aParam: T);
var a:integer;
begin
a:=integer((@aParam)^);          //  Bug here, hello  to the EDX register
....
end;

Asm code equavalent of assign op 
...
Inner SEH FRAME

push $0046c650
push dword ptr fs:[eax]
mov fs:[eax],esp

 a:=integer((@aParam)^);          //  Bug here, hello to the EDX register

Problem instruction - Assign OP

After this one we catch an Exception.

lea eax,quiet_dl                 

This instruction isn't  executed.
mov ebx,[eax]

Second.

Today I was trying to improve my implementation of C# Yield operator implementation in native Delphi.
You can find my free time research on santonov.blogspot.com.

But I encountered a problem that is an unabitility to use any asm chunks in parameterized classes.

Third. Recall to operators in parameterized classes.

You suggest an interestring solution. 

Implicit(T):integer;

Or may be even Implicit(T):U.

And what about  +,-,*,/ .... with different combination of all parameterized types.

That about the expression?

(U+T*Z-V*10*(cast to V) (U))/U

Class implementer may to be at a loss by this expression.

How many operator constraints has programmer to declare?

Why would not this responsibility move to compiler?

It is a power of native code. 

And constraints is necessity of .Net to generate safe code.

But, in any case your idea  is very good.</description>
		<content:encoded><![CDATA[<p>Good evening, Craig! </p>
<p>First of all about bug, </p>
<p>procedure Some"T".DoSomething(aParam: T);<br />
var a:integer;<br />
begin<br />
a:=integer((@aParam)^);          //  Bug here, hello  to the EDX register<br />
&#8230;.<br />
end;</p>
<p>Asm code equavalent of assign op<br />
&#8230;<br />
Inner SEH FRAME</p>
<p>push $0046c650<br />
push dword ptr fs:[eax]<br />
mov fs:[eax],esp</p>
<p> a:=integer((@aParam)^);          //  Bug here, hello to the EDX register</p>
<p>Problem instruction - Assign OP</p>
<p>After this one we catch an Exception.</p>
<p>lea eax,quiet_dl                 </p>
<p>This instruction isn&#8217;t  executed.<br />
mov ebx,[eax]</p>
<p>Second.</p>
<p>Today I was trying to improve my implementation of C# Yield operator implementation in native Delphi.<br />
You can find my free time research on santonov.blogspot.com.</p>
<p>But I encountered a problem that is an unabitility to use any asm chunks in parameterized classes.</p>
<p>Third. Recall to operators in parameterized classes.</p>
<p>You suggest an interestring solution. </p>
<p>Implicit(T):integer;</p>
<p>Or may be even Implicit(T):U.</p>
<p>And what about  +,-,*,/ &#8230;. with different combination of all parameterized types.</p>
<p>That about the expression?</p>
<p>(U+T*Z-V*10*(cast to V) (U))/U</p>
<p>Class implementer may to be at a loss by this expression.</p>
<p>How many operator constraints has programmer to declare?</p>
<p>Why would not this responsibility move to compiler?</p>
<p>It is a power of native code. </p>
<p>And constraints is necessity of .Net to generate safe code.</p>
<p>But, in any case your idea  is very good.</p>
]]></content:encoded>
	</item>
</channel>
</rss>
