<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>VBScript Terminators, Part Two</title><link>http://blogs.msdn.com/b/ericlippert/archive/2004/12/29/344074.aspx</link><description>You guys came up with good answers to three of my four questions, which is about what I expected; question 2 was pretty hard. To sum up: QUESTION #1: Why does the termination logic go terminate, terminate, terminate, clear, clear, clear, instead of terminate</description><dc:language>en-US</dc:language><generator>Telligent Evolution Platform Developer Build (Build: 5.6.50428.7875)</generator><item><title>re: VBScript Terminators, Part Two</title><link>http://blogs.msdn.com/b/ericlippert/archive/2004/12/29/344074.aspx#346292</link><pubDate>Tue, 04 Jan 2005 15:54:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:346292</guid><dc:creator>Eric Lippert</dc:creator><description>New Jersey Standard ML is that strange beast, the practical research language.  It's statically typed, has a very powerful type inference system (so you don't NEED to declare specific types when you declare, say, arguments to function, but you get the benefits of compile-time types).  It's garbage collected.  It supports both functional and imperative programming. It's designed for programming in the large.&lt;br&gt;&lt;br&gt;So far, that sounds like JScript .NET.  One of the interesting things that sets NJSML apart is that the language strongly encourages recursive solutions by providing a very natural syntax for pattern-matching recursive data structures.&lt;br&gt;&lt;br&gt;Anyway, one of the basic patterns for making types in NJSML is the tuple:&lt;br&gt;&lt;br&gt;val triple : int * real * string = (2, 3.14, &amp;quot;hello&amp;quot;)&lt;br&gt;&lt;br&gt;Here we have a variable &amp;quot;triple&amp;quot; of type &amp;quot;tuple of int, real and string&amp;quot; that is bound to a specific member of that tuple type.&lt;br&gt;&lt;br&gt;Tuples are like structs in C -- they have a strict hierarchical structure:&lt;br&gt;&lt;br&gt;val pair_pair : (int * real) * (string * string) = ((1,2.0), (&amp;quot;hello&amp;quot;, &amp;quot;goodbye&amp;quot;))&lt;br&gt;&lt;br&gt;This is not a quadruple, this is a pair of pairs.  The structure matters.&lt;br&gt;&lt;br&gt;Notice that, unlike C, the members of the structure can be anonymous -- you can drill down into the contents of the tuple via pattern matching.  We could name them if we wanted.  And we could also have a &amp;quot;names only&amp;quot; tuple which is called a &amp;quot;record&amp;quot;:&lt;br&gt;&lt;br&gt;type complex = { re : real, im : real }&lt;br&gt;val myComplex : complex = {re=1.2, im=2.1}&lt;br&gt;&lt;br&gt;A given tuple _always_ has the same number of members, and those members can be of any given type.  A NJSML list, by contrast, has any number of members all of the same type.  The empty list is written &amp;quot;nil&amp;quot;.&lt;br&gt;&lt;br&gt;Lists are specified recursively:  a list is either nil, or a head element followed by a tail list.  You can therefore define pattern matching overloads for functions that manipulate lists.  Suppose you want to compute the length of a list -- well, the length of the nil list is zero and the length of the list (h::t) -- that is, head followed by tail list is the length of the tail plus the 1 for the head:&lt;br&gt;&lt;br&gt;fun length nil = 0&lt;br&gt;  | length (h::t) = 1 + length t&lt;br&gt;&lt;br&gt;So if you then called the function&lt;br&gt;&lt;br&gt;length [2,4]&lt;br&gt;&lt;br&gt;the pattern matcher would say that's 2::[4], so add 1 to length 4::nil, so add one to length nil, that's zero, ok, 2.&lt;br&gt;&lt;br&gt;Notice that this function has only partially specified type.  It takes any list, and the compiler deduces that it always returns integers, so that + is well-defined.&lt;br&gt;&lt;br&gt;NJSML is a really neat language, and I've just barely touched on it.  There are lots of interesting things you can do with its type system.&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=346292" width="1" height="1"&gt;</description></item><item><title>re: VBScript Terminators, Part Two</title><link>http://blogs.msdn.com/b/ericlippert/archive/2004/12/29/344074.aspx#346255</link><pubDate>Tue, 04 Jan 2005 14:15:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:346255</guid><dc:creator>engima2e</dc:creator><description>What *are*  &amp;quot;ML-style lists and tuples&amp;quot;??? and what is an example of them?&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=346255" width="1" height="1"&gt;</description></item><item><title>re: VBScript Terminators, Part Two</title><link>http://blogs.msdn.com/b/ericlippert/archive/2004/12/29/344074.aspx#345939</link><pubDate>Mon, 03 Jan 2005 21:55:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:345939</guid><dc:creator>Anon</dc:creator><description>I admit that's a very tough call to make. It depends not just on the cost of testing the &amp;quot;more extensive&amp;quot; change, but also on the savings from not doing it until later (the &amp;quot;interest&amp;quot; accumulated on the unspent effort or from investing the effort elsewhere, if you will) vs. the risk that someone will take longer to understand the code next time.&lt;br&gt;&lt;br&gt;I was looking at it from another perspective though. Developers in general (myself included) are notorious for &amp;quot;solving the solution&amp;quot; when we really need to solve the problem. By thinking of it as you described (&amp;quot;how do we fix the case where ...&amp;quot;) the answer was &amp;quot;we have to check the reference count after the operation instead&amp;quot;. It would have helped to recognise that the problem was &amp;quot;We're running a method on an object that's effectively been deleted!&amp;quot; and reorder the code to avoid that. Maybe the distinction's only in my mind of course :)&lt;br&gt;&lt;br&gt;(When I first read the article, I wondered if the backstory was just artistic license - most people don't seem to write so fluently when they're recounting true stories instead of setting the scene for something fictional. Sorry for the unnecessary comments and thanks for clarifying.)&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=345939" width="1" height="1"&gt;</description></item><item><title>re: VBScript Terminators, Part Two</title><link>http://blogs.msdn.com/b/ericlippert/archive/2004/12/29/344074.aspx#345812</link><pubDate>Mon, 03 Jan 2005 15:25:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:345812</guid><dc:creator>Eric Lippert</dc:creator><description>Indeed, that would be a cleaner way to write this code.  Clearly what happened to this code was that it evolved exactly as I described -- it was written wrong several times and then patched up, and is now a little crufty as a result.&lt;br&gt;&lt;br&gt;Which illustrates a good point: when you fix a bug, consider not just whether the fix is locally correct, but also whether re-jigging the function to make the whole thing cleaner is warranted.  Sometimes it is, sometimes the added risk isn't worth it.&lt;br&gt;&lt;br&gt;In this particular case, the resulting code isn't so bad that it's an unreadable bug farm.  When I started on the VBScript team, the DateDiff code had a bug in it.  I investigated the history of changes to that function and discovered that there had been six bugs entered against it over the years (in the VB runtime library code base) and sure enough, the function had six special cases in it.  Every time someone found an anomaly, they just stuck an if-then in there to make it better.&lt;br&gt;&lt;br&gt;Rather than stick a seventh, I threw away all the code and started over with a completely different approach, reducing it to four lines of obviously correct code instead of a dozen lines of unreadable mess.  And now I ask how to implement that function as an interview question!&lt;br&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=345812" width="1" height="1"&gt;</description></item><item><title>re: VBScript Terminators, Part Two</title><link>http://blogs.msdn.com/b/ericlippert/archive/2004/12/29/344074.aspx#345592</link><pubDate>Mon, 03 Jan 2005 04:28:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:345592</guid><dc:creator>Anon</dc:creator><description>Ugh, what a funny way of thinking about it.&lt;br&gt;&lt;br&gt;// We run the terminator when the last object is released.&lt;br&gt;if (m_cRef == 1)&lt;br&gt;  RunTerminator();&lt;br&gt;&lt;br&gt;// Now release the object.&lt;br&gt;int refs = --m_cRef;&lt;br&gt;if (!refs)&lt;br&gt;  delete this;&lt;br&gt;return refs;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=345592" width="1" height="1"&gt;</description></item><item><title>re: VBScript Terminators, Part Two</title><link>http://blogs.msdn.com/b/ericlippert/archive/2004/12/29/344074.aspx#344926</link><pubDate>Fri, 31 Dec 2004 19:54:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:344926</guid><dc:creator>Eric Lippert</dc:creator><description>Enigma2e:  The finalizers are triggered when the engine is closed or reset.  That is, when:&lt;br&gt;&lt;br&gt;* IActiveScript::Close is called&lt;br&gt;&lt;br&gt;* SetScriptState to UNINITIALIZED&lt;br&gt;&lt;br&gt;* SetScriptState to INITIALIZED&lt;br&gt;&lt;br&gt;So there you go.  WScript.Quit closes the engine because of course it is not going to use it again.  If you want to re-use the engine you can do a full or partial reset of the engine and it will throw away the existing object state as best it can.&lt;br&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=344926" width="1" height="1"&gt;</description></item><item><title>re: VBScript Terminators, Part Two</title><link>http://blogs.msdn.com/b/ericlippert/archive/2004/12/29/344074.aspx#344920</link><pubDate>Fri, 31 Dec 2004 19:45:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:344920</guid><dc:creator>Eric Lippert</dc:creator><description>Well, like all language features, finalizers are tools.  You pick your tool based on what job you want to accomplish.&lt;br&gt;&lt;br&gt;The people who designed the .NET GC had the problem of designing a GC that would work well with any language, but were particularly interested in application implementation languages like C# and VB.&lt;br&gt;&lt;br&gt;The .NET logic isn't exactly the same as the VBScript logic -- finalizers for object Beta can run even in Beta has a ref on Alpha and Alpha has already been finalized.  But it is similar in several regards, including the fact that ressurrected objects are only finalized once.&lt;br&gt;&lt;br&gt;This page has lots of interesting information on .NET finalizers.&lt;br&gt;&lt;br&gt;&lt;a target="_new" href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemObjectClassFinalizeTopic.asp"&gt;http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemObjectClassFinalizeTopic.asp&lt;/a&gt;&lt;br&gt;&lt;br&gt;If I were designing a scripting language today, I wouldn't include object finalization at all.  You have a resource that needs cleaning up, script your own darn cleanup code.&lt;br&gt;&lt;br&gt;Heck, if I were designing a scripting language today it probably wouldn't even be object-based if I could help it.  ML-style lists and tuples are a pretty darn scripty way to write programs.&lt;br&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=344920" width="1" height="1"&gt;</description></item><item><title>re: VBScript Terminators, Part Two</title><link>http://blogs.msdn.com/b/ericlippert/archive/2004/12/29/344074.aspx#344858</link><pubDate>Fri, 31 Dec 2004 17:29:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:344858</guid><dc:creator>Nicholas Allen</dc:creator><description>So if you didn't have compatibility to worry about, how would you like to handle object resurrection in a scripting language?  Prohibit it entirely, finalizer called once per object, finalizer called every time object becomes unreachable?  Is there an alternative more &amp;quot;scripty&amp;quot; than the others?&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=344858" width="1" height="1"&gt;</description></item><item><title>re: VBScript Terminators, Part Two</title><link>http://blogs.msdn.com/b/ericlippert/archive/2004/12/29/344074.aspx#344084</link><pubDate>Thu, 30 Dec 2004 04:37:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:344084</guid><dc:creator>Enigma2e</dc:creator><description>But the question is, how do you trigger to the script engine in a host environment, like in WScript.Quit, that you want to cleanup all global variables by running their terminators and then freeing their memory?&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=344084" width="1" height="1"&gt;</description></item></channel></rss>