<?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"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments for Kfitzat Ha'derech</title>
	<atom:link href="http://blogs.umass.edu/egottlie/comments/feed/" rel="self" type="application/rss+xml" />
	<link>http://blogs.umass.edu/egottlie</link>
	<description>Programming languages, operating systems, politics, and other religious matters.</description>
	<lastBuildDate>Tue, 02 Dec 2008 15:34:03 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
	<item>
		<title>Comment on Lambda Signatures as Interfaces or Abstract Superclasses by Edward Kmett</title>
		<link>http://blogs.umass.edu/egottlie/2008/12/01/lambda-signatures-as-interfaces-or-abstract-superclasses/comment-page-1/#comment-13</link>
		<dc:creator>Edward Kmett</dc:creator>
		<pubDate>Tue, 02 Dec 2008 15:34:03 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.umass.edu/egottlie/2008/12/01/lambda-signatures-as-interfaces-or-abstract-superclasses/#comment-13</guid>
		<description>As a devil&#039;s advocate you could always allocate the closure out on the heap when you need to pass it in an interchangeable way. 

Then you could pass around a reference to it that has linear ownership semantics, so that when your reference goes out of scope you can delete the target object. This requires that copying the reference copies the object on the heap, keeping the system of closures acyclic. 

With suitable optimizations, you should be able to avoid constructing that heap based closure most of the time.

Copying costs become proportional to the size of the environment this way, and while you could go with a lame reference counting solution, that blows up in your face when you want fast multithreaded performance and start dealing with cache thrashing and may inject cycles and space-leaks if you aren&#039;t careful.</description>
		<content:encoded><![CDATA[<p>As a devil&#8217;s advocate you could always allocate the closure out on the heap when you need to pass it in an interchangeable way. </p>
<p>Then you could pass around a reference to it that has linear ownership semantics, so that when your reference goes out of scope you can delete the target object. This requires that copying the reference copies the object on the heap, keeping the system of closures acyclic. </p>
<p>With suitable optimizations, you should be able to avoid constructing that heap based closure most of the time.</p>
<p>Copying costs become proportional to the size of the environment this way, and while you could go with a lame reference counting solution, that blows up in your face when you want fast multithreaded performance and start dealing with cache thrashing and may inject cycles and space-leaks if you aren&#8217;t careful.</p>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on Lambda Signatures as Interfaces or Abstract Superclasses by Sandro Magi</title>
		<link>http://blogs.umass.edu/egottlie/2008/12/01/lambda-signatures-as-interfaces-or-abstract-superclasses/comment-page-1/#comment-12</link>
		<dc:creator>Sandro Magi</dc:creator>
		<pubDate>Tue, 02 Dec 2008 15:18:00 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.umass.edu/egottlie/2008/12/01/lambda-signatures-as-interfaces-or-abstract-superclasses/#comment-12</guid>
		<description>The system programming language you&#039;re looking for is &lt;a href=&quot;http://www.bitc-lang.org/&quot; rel=&quot;nofollow&quot;&gt;BitC&lt;/a&gt;, and it sounds like BitC is further along than your own effort at the moment. Their design docs are worth looking at, and they discuss the GC issues.

&quot;Downward&quot; closures are possible to compile without GC (Ada 2005 now has them), but upward closures cannot without some tradeoffs. For instance, copying closure environments instead of passing by reference, and distinguishing function pointers without an environment from closures. As for how to implement this copying, well you compile your higher-order language to a first-order intermediate language which exposes representation for the code generation phase.

Another alternative is to give closures linear types, such that the client is forced to free them at the appropriate time.

Barry Kelly, reference counting is garbage collection, so your implementation was GC&#039;d.</description>
		<content:encoded><![CDATA[<p>The system programming language you&#8217;re looking for is <a href="http://www.bitc-lang.org/" rel="nofollow">BitC</a>, and it sounds like BitC is further along than your own effort at the moment. Their design docs are worth looking at, and they discuss the GC issues.</p>
<p>&#8220;Downward&#8221; closures are possible to compile without GC (Ada 2005 now has them), but upward closures cannot without some tradeoffs. For instance, copying closure environments instead of passing by reference, and distinguishing function pointers without an environment from closures. As for how to implement this copying, well you compile your higher-order language to a first-order intermediate language which exposes representation for the code generation phase.</p>
<p>Another alternative is to give closures linear types, such that the client is forced to free them at the appropriate time.</p>
<p>Barry Kelly, reference counting is garbage collection, so your implementation was GC&#8217;d.</p>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on Lambda Signatures as Interfaces or Abstract Superclasses by somejan</title>
		<link>http://blogs.umass.edu/egottlie/2008/12/01/lambda-signatures-as-interfaces-or-abstract-superclasses/comment-page-1/#comment-11</link>
		<dc:creator>somejan</dc:creator>
		<pubDate>Tue, 02 Dec 2008 11:16:43 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.umass.edu/egottlie/2008/12/01/lambda-signatures-as-interfaces-or-abstract-superclasses/#comment-11</guid>
		<description>A &#039;simple&#039; solution (at least not requiring too much type theory) would be to allow to declare the maximum size of a variable separately from it&#039;s type. So adding to the example in the post:

Parent p;
p = baz(-1.0);

would become something like

Parent __size__(sizeof(Child)) p;  /*I&#039;ll leave it to you to think of better syntax*/
p = baz(-1.0)

Something like this should then inform the compiler to reserve enough space on the stack for Child objects. You could probably call this &#039;manual polymorphism&#039; :)
This would probably require the compiler to track separately the interface and max size of every variable, so it would require quite a bit of rewriting in the typechecker. Also, it makes using inheritance more difficult and less modular than a fully general solution. You could end up with an error that &#039;variable x cannot hold objects with size of DerivedClass&#039; when you change the definition of DerivedClass, forcing you to recompile all kinds of unrelated modules for which you may not have the source code (well, assuming Deca will actually be used in the wild).


Or an other way would be to have each activation record start with a table of pointers to variables, followed by those variables taking as much space as they need. The space needed by the variables would grow dynamically. But this would require indirection for all local variable accesses.</description>
		<content:encoded><![CDATA[<p>A &#8216;simple&#8217; solution (at least not requiring too much type theory) would be to allow to declare the maximum size of a variable separately from it&#8217;s type. So adding to the example in the post:</p>
<p>Parent p;<br />
p = baz(-1.0);</p>
<p>would become something like</p>
<p>Parent __size__(sizeof(Child)) p;  /*I&#8217;ll leave it to you to think of better syntax*/<br />
p = baz(-1.0)</p>
<p>Something like this should then inform the compiler to reserve enough space on the stack for Child objects. You could probably call this &#8216;manual polymorphism&#8217; <img src='http://blogs.umass.edu/egottlie/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
This would probably require the compiler to track separately the interface and max size of every variable, so it would require quite a bit of rewriting in the typechecker. Also, it makes using inheritance more difficult and less modular than a fully general solution. You could end up with an error that &#8216;variable x cannot hold objects with size of DerivedClass&#8217; when you change the definition of DerivedClass, forcing you to recompile all kinds of unrelated modules for which you may not have the source code (well, assuming Deca will actually be used in the wild).</p>
<p>Or an other way would be to have each activation record start with a table of pointers to variables, followed by those variables taking as much space as they need. The space needed by the variables would grow dynamically. But this would require indirection for all local variable accesses.</p>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on Lambda Signatures as Interfaces or Abstract Superclasses by Marijn Haverbeke</title>
		<link>http://blogs.umass.edu/egottlie/2008/12/01/lambda-signatures-as-interfaces-or-abstract-superclasses/comment-page-1/#comment-10</link>
		<dc:creator>Marijn Haverbeke</dc:creator>
		<pubDate>Tue, 02 Dec 2008 10:59:42 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.umass.edu/egottlie/2008/12/01/lambda-signatures-as-interfaces-or-abstract-superclasses/#comment-10</guid>
		<description>Also notice that *if* you manage to find some way to reliably copy closures around, you&#039;ll either have to make the closed-over variables read-only, or deal with some very weird behaviour -- assigning to them in one copy of the closure will not affect other copies.</description>
		<content:encoded><![CDATA[<p>Also notice that *if* you manage to find some way to reliably copy closures around, you&#8217;ll either have to make the closed-over variables read-only, or deal with some very weird behaviour &#8212; assigning to them in one copy of the closure will not affect other copies.</p>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on Lambda Signatures as Interfaces or Abstract Superclasses by egottlie</title>
		<link>http://blogs.umass.edu/egottlie/2008/12/01/lambda-signatures-as-interfaces-or-abstract-superclasses/comment-page-1/#comment-9</link>
		<dc:creator>egottlie</dc:creator>
		<pubDate>Tue, 02 Dec 2008 07:45:32 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.umass.edu/egottlie/2008/12/01/lambda-signatures-as-interfaces-or-abstract-superclasses/#comment-9</guid>
		<description>Will write up ideas in a full blog-post tomorrow.</description>
		<content:encoded><![CDATA[<p>Will write up ideas in a full blog-post tomorrow.</p>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on Lambda Signatures as Interfaces or Abstract Superclasses by egottlie</title>
		<link>http://blogs.umass.edu/egottlie/2008/12/01/lambda-signatures-as-interfaces-or-abstract-superclasses/comment-page-1/#comment-8</link>
		<dc:creator>egottlie</dc:creator>
		<pubDate>Tue, 02 Dec 2008 07:45:15 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.umass.edu/egottlie/2008/12/01/lambda-signatures-as-interfaces-or-abstract-superclasses/#comment-8</guid>
		<description>Yeah, I&#039;m actually using run-time polymorphism.  I thought that was implied in the original post -- run-time polymorphism based on the representation of every object/function (since this works nicely for both) carrying some kind of &quot;class ID&quot; that identifies its run-time type in some fashion sufficient to tell the size of the object at run-time.

And as to the issue of state capture due to lexical scoping, I must admit that since my lambdas have copy semantics for closure construction, they Are Not True Lexical Closures in the case that one returns multiple closures over the same state.  However, in that case I believe that an object (ie: instance of a class) will work well enough.  It may not be The Right Thing sometimes, but it will work and it lets me have a somewhat functional language without GC (and therefore usable for low-level programming).</description>
		<content:encoded><![CDATA[<p>Yeah, I&#8217;m actually using run-time polymorphism.  I thought that was implied in the original post &#8212; run-time polymorphism based on the representation of every object/function (since this works nicely for both) carrying some kind of &#8220;class ID&#8221; that identifies its run-time type in some fashion sufficient to tell the size of the object at run-time.</p>
<p>And as to the issue of state capture due to lexical scoping, I must admit that since my lambdas have copy semantics for closure construction, they Are Not True Lexical Closures in the case that one returns multiple closures over the same state.  However, in that case I believe that an object (ie: instance of a class) will work well enough.  It may not be The Right Thing sometimes, but it will work and it lets me have a somewhat functional language without GC (and therefore usable for low-level programming).</p>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on Lambda Signatures as Interfaces or Abstract Superclasses by Barry Kelly</title>
		<link>http://blogs.umass.edu/egottlie/2008/12/01/lambda-signatures-as-interfaces-or-abstract-superclasses/comment-page-1/#comment-7</link>
		<dc:creator>Barry Kelly</dc:creator>
		<pubDate>Tue, 02 Dec 2008 07:26:07 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.umass.edu/egottlie/2008/12/01/lambda-signatures-as-interfaces-or-abstract-superclasses/#comment-7</guid>
		<description>Egottlie, you *must* either use compile-time polymorphism or runtime polymorphism in order to write code that works generally with lambdas of a particular arity and type signature. There is no other way out (apart from C++, i.e. discarding the troublesome data).

If you don&#039;t use generics or templates, then you must use polymorphism. Whether you describe the lump of data being referred to as being POD or not, it will conceptually be a type, because in order for it to act as a lambda, it must be invokable and contain state; since the state may vary in size depending on the amount of captured data, the very minimum of type description - size - is necessary. (Size is also the only type known by assembler. Perhaps you would be more comfortable with that?)</description>
		<content:encoded><![CDATA[<p>Egottlie, you *must* either use compile-time polymorphism or runtime polymorphism in order to write code that works generally with lambdas of a particular arity and type signature. There is no other way out (apart from C++, i.e. discarding the troublesome data).</p>
<p>If you don&#8217;t use generics or templates, then you must use polymorphism. Whether you describe the lump of data being referred to as being POD or not, it will conceptually be a type, because in order for it to act as a lambda, it must be invokable and contain state; since the state may vary in size depending on the amount of captured data, the very minimum of type description &#8211; size &#8211; is necessary. (Size is also the only type known by assembler. Perhaps you would be more comfortable with that?)</p>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on Lambda Signatures as Interfaces or Abstract Superclasses by egottlie</title>
		<link>http://blogs.umass.edu/egottlie/2008/12/01/lambda-signatures-as-interfaces-or-abstract-superclasses/comment-page-1/#comment-6</link>
		<dc:creator>egottlie</dc:creator>
		<pubDate>Tue, 02 Dec 2008 05:58:44 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.umass.edu/egottlie/2008/12/01/lambda-signatures-as-interfaces-or-abstract-superclasses/#comment-6</guid>
		<description>Also, I&#039;m assuming that class instances carry with them a *very* basic level of RTTI, such as their own size in bytes.  This gives me an idea...</description>
		<content:encoded><![CDATA[<p>Also, I&#8217;m assuming that class instances carry with them a *very* basic level of RTTI, such as their own size in bytes.  This gives me an idea&#8230;</p>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on Lambda Signatures as Interfaces or Abstract Superclasses by egottlie</title>
		<link>http://blogs.umass.edu/egottlie/2008/12/01/lambda-signatures-as-interfaces-or-abstract-superclasses/comment-page-1/#comment-5</link>
		<dc:creator>egottlie</dc:creator>
		<pubDate>Tue, 02 Dec 2008 05:56:05 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.umass.edu/egottlie/2008/12/01/lambda-signatures-as-interfaces-or-abstract-superclasses/#comment-5</guid>
		<description>Well shit, slicing is downright EVIL.  Way to reinforce my opinion about you, C++!

Now as to the issue of garbage collection and memory management for the lambdas... that issue is solved through a bondage-and-discipline approach.  I could write another whole post detailing how Deca alias types and anonymous variables work, but suffice to say that the language enforces a semantics which enables it to treat aliases as Plain Old Data for closure-variable-capture purposes without creating aliasing bugs.  Think of uniqueness types, but done at runtime to avoid the need for a huge type-inference engine.  Since aliases, the only reference type in the language, are Plain Old Data and everything that isn&#039;t a reference type is either Plain Old Data or recursively defined in terms of aliases and Plain Old Data... everything is Plain Old Data for variable-capture purposes.  Just copy it into a closure-object and go, basically.  The closure-object then gets deleted manually later on.  Like I said, the exact weird bondage-and-discipline I enforce on aliasing to make this work is worth its own post some other day.

And don&#039;t nobody go telling me that this kind of thing is impossible or senseless.

I suppose I *could* simply outlaw returning functions from functions and require that they be passed as out arguments, but that ends up running into the same problem of either A) slicing or B) passing by reference, which requires allocating all my closure-objects on the heap (NOT a pleasant thing to do in a manual-allocation language, particularly for the perceived syntax and semantics of lambdas).  There should be *some* way to return a covariantly-typed value on the stack!</description>
		<content:encoded><![CDATA[<p>Well shit, slicing is downright EVIL.  Way to reinforce my opinion about you, C++!</p>
<p>Now as to the issue of garbage collection and memory management for the lambdas&#8230; that issue is solved through a bondage-and-discipline approach.  I could write another whole post detailing how Deca alias types and anonymous variables work, but suffice to say that the language enforces a semantics which enables it to treat aliases as Plain Old Data for closure-variable-capture purposes without creating aliasing bugs.  Think of uniqueness types, but done at runtime to avoid the need for a huge type-inference engine.  Since aliases, the only reference type in the language, are Plain Old Data and everything that isn&#8217;t a reference type is either Plain Old Data or recursively defined in terms of aliases and Plain Old Data&#8230; everything is Plain Old Data for variable-capture purposes.  Just copy it into a closure-object and go, basically.  The closure-object then gets deleted manually later on.  Like I said, the exact weird bondage-and-discipline I enforce on aliasing to make this work is worth its own post some other day.</p>
<p>And don&#8217;t nobody go telling me that this kind of thing is impossible or senseless.</p>
<p>I suppose I *could* simply outlaw returning functions from functions and require that they be passed as out arguments, but that ends up running into the same problem of either A) slicing or B) passing by reference, which requires allocating all my closure-objects on the heap (NOT a pleasant thing to do in a manual-allocation language, particularly for the perceived syntax and semantics of lambdas).  There should be *some* way to return a covariantly-typed value on the stack!</p>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on Lambda Signatures as Interfaces or Abstract Superclasses by Adrian Quark</title>
		<link>http://blogs.umass.edu/egottlie/2008/12/01/lambda-signatures-as-interfaces-or-abstract-superclasses/comment-page-1/#comment-4</link>
		<dc:creator>Adrian Quark</dc:creator>
		<pubDate>Tue, 02 Dec 2008 05:55:35 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.umass.edu/egottlie/2008/12/01/lambda-signatures-as-interfaces-or-abstract-superclasses/#comment-4</guid>
		<description>To answer your question: lexical scoping is fundamentally incompatible with static memory management. Lexical scoping implies that values can escape their dynamic scope (via closures), and the abstraction power of closures comes from the fact that you can use one without knowing its free variables. But you must know a closure&#039;s free variables in order to manage their memory explicitly.

If you feel like this won&#039;t be a problem (maybe you only need so-called &quot;downward funargs&quot;), then it seems like you can just use a special stack discipline to handle variable-sized values: include the size of the function object somewhere in its representation, and respect this when pushing or popping the stack.</description>
		<content:encoded><![CDATA[<p>To answer your question: lexical scoping is fundamentally incompatible with static memory management. Lexical scoping implies that values can escape their dynamic scope (via closures), and the abstraction power of closures comes from the fact that you can use one without knowing its free variables. But you must know a closure&#8217;s free variables in order to manage their memory explicitly.</p>
<p>If you feel like this won&#8217;t be a problem (maybe you only need so-called &#8220;downward funargs&#8221;), then it seems like you can just use a special stack discipline to handle variable-sized values: include the size of the function object somewhere in its representation, and respect this when pushing or popping the stack.</p>
]]></content:encoded>
	</item>
</channel>
</rss>

