<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-10770855</id><updated>2012-01-28T05:54:23.376-05:00</updated><category term='ecmascript'/><category term='scope in logic'/><category term='news'/><category term='development cycle'/><category term='tribute'/><category term='UI'/><category term='web monad'/><category term='bisimulations'/><category term='time management'/><category term='environments'/><category term='first-class stores'/><category term='error recovery'/><category term='stack traces'/><category term='with'/><category term='lexical syntax'/><category term='modal web programming'/><category term='learning process'/><category term='debuggers'/><category term='evaluation contexts'/><category term='eureka'/><category term='makefile'/><category term='email'/><category term='semantics'/><category term='fold'/><category term='empty string'/><category term='builders and defenders'/><category term='non-termination'/><category term='substitution'/><category term='CSP'/><category term='announcements'/><category term='obituary'/><category term='hygiene'/><category term='names'/><category term='Subversion'/><category term='unsafe optimizations'/><category term='first-class heaps'/><category term='rants'/><category term='plt-scheme'/><category term='F#'/><category term='concurrency'/><category term='lexical scope'/><category term='figures'/><category term='term rewriting'/><category term='invariants'/><category term='cool technology'/><category term='contractive'/><category term='ninja-patching'/><category term='homomorphism'/><category term='Mac porn'/><category term='design'/><category term='hoas'/><category term='forall'/><category term='call/cc'/><category term='visitor pattern'/><category term='svn'/><category term='silly'/><category term='passport'/><category term='education'/><category term='es4'/><category term='notational definitions'/><category term='semi-persistent data structures'/><category term='imperative programming'/><category term='planet'/><category term='comfort coding'/><category term='actors'/><category term='ADT'/><category term='eval'/><category term='paging'/><category term='hacking'/><category term='diagnostics'/><category term='zippers'/><category term='recursive types'/><category term='tracing'/><category term='superfluous abstraction'/><category term='soundness'/><category term='compilation'/><category term='systems'/><category term='overloading'/><category term='GHC'/><category term='backus'/><category term='JSON'/><category term='Scheme'/><category term='Futamura projections'/><category term='true unions'/><category term='union types'/><category term='generators'/><category term='gdb'/><category term='finally'/><category term='lambda calculus'/><category term='fortran'/><category term='interoperability'/><category term='modules'/><category term='RAII'/><category term='HUnit'/><category term='harmony'/><category term='coding style'/><category term='informal notation'/><category term='publishing'/><category term='operator overloading'/><category term='mutation'/><category term='control flow'/><category term='namespace'/><category term='option type'/><category term='bleg'/><category term='regular trees'/><category term='conditional exception handling'/><category term='quoting'/><category term='typedef'/><category term='corner cases'/><category term='xor'/><category term='continuation marks'/><category term='curriculum'/><category term='module name resolver'/><category term='C'/><category term='nominal logic'/><category term='epiphany'/><category term='JavaScript 1.7'/><category term='Clojure'/><category term='top level'/><category term='termination'/><category term='syntax'/><category term='units of measure'/><category term='fexprs'/><category term='postel&apos;s law'/><category term='exceptions'/><category term='rethrowing'/><category term='encryption'/><category term='infinite trees'/><category term='type soundness'/><category term='parameterized types'/><category term='non-disjoint unions'/><category term='case analysis'/><category term='resource contention'/><category term='proof techniques'/><category term='fail-soft'/><category term='not-a-number'/><category term='foodforthought'/><category term='heap dumping'/><category term='refactoring'/><category term='point-free style'/><category term='ad-hoc unions'/><category term='macros'/><category term='TAPL'/><category term='typed scheme'/><category term='monads'/><category term='Mitchfest'/><category term='logical operators'/><category term='API design'/><category term='printf'/><category term='code is data'/><category term='SIGPLAN'/><category term='first-class continuations'/><category term='Haskell'/><category term='dynamic analysis'/><category term='game programming'/><category term='javadot'/><category term='dynamic languages'/><category term='redex'/><category term='value restriction'/><category term='budapest'/><category term='proper tail recursion'/><category term='fun'/><category term='mutable globals'/><category term='testing'/><category term='JavaScript'/><category term='architecture'/><category term='capture'/><category term='pearls'/><category term='message-passing'/><category term='literate code'/><category term='dissertation'/><category term='correctness'/><category term='rules'/><category term='porous abstractions'/><category term='obfuscation'/><category term='esop'/><category term='debugging'/><category term='unhygienic-macros'/><category term='nancy'/><category term='existential types'/><category term='terminology'/><category term='completion value'/><category term='brain damage'/><category term='mathematical notation'/><category term='types'/><category term='C++'/><category term='effects'/><category term='namespaces'/><category term='NaN'/><category term='auto-currying'/><category term='higher-rank polymorphism'/><category term='closure conversion'/><category term='equirecursive types'/><category term='eta'/><category term='traversal'/><category term='science'/><category term='backtracking'/><category term='lambda renaissance'/><category term='research progress'/><category term='tail calls'/><category term='hm'/><category term='JVM'/><category term='netiquette'/><category term='open recursion'/><category term='cygwin'/><category term='records'/><category term='brands'/><category term='declarative programming'/><category term='web continuations'/><category term='OO'/><category term='Java'/><category term='naming conventions'/><category term='delimited continuations'/><category term='StopIteration'/><category term='research landscape'/><category term='Termite'/><category term='maybe type'/><category term='equivalence'/><category term='hacks'/><category term='roc'/><category term='generics'/><category term='abstraction'/><category term='expression closures'/><category term='FFI'/><category term='history'/><category term='operators'/><category term='quotes'/><category term='fail'/><category term='failure'/><category term='effect masking'/><category term='plt-dev'/><category term='LaTeX'/><category term='metadata'/><category term='reader'/><category term='REPL'/><title type='text'>The Little Calculist</title><subtitle type='html'>Dave Herman's research blog.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default?start-index=101&amp;max-results=100'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>324</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-10770855.post-5687575459827351417</id><published>2011-12-06T00:28:00.000-05:00</published><updated>2011-12-06T00:29:21.972-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='announcements'/><title type='text'>I've moved!</title><content type='html'>This blog has a new home:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;a href="http://calculist.org"&gt;http://calculist.org&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Hope to see you there!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-5687575459827351417?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/5687575459827351417/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=5687575459827351417' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/5687575459827351417'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/5687575459827351417'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2011/12/ive-moved.html' title='I&apos;ve moved!'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-8388635786444299944</id><published>2010-06-12T11:07:00.003-04:00</published><updated>2010-06-12T11:15:07.928-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='RAII'/><category scheme='http://www.blogger.com/atom/ns#' term='finally'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>RAII vs finally</title><content type='html'>Since I'm pretty new to C++, I wasn't too deeply familiar with &lt;a href="http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization"&gt;RAII&lt;/a&gt;; like most Schemers I just thought of it as "C++'s version of &lt;span style="font-family: courier new;"&gt;dynamic-wind&lt;/span&gt;."&lt;br /&gt;&lt;br /&gt;This week I learned an important distinction between C++ destructors and Java's &lt;span style="font-family: courier new;"&gt;finally&lt;/span&gt;. The latter, of course, unilaterally executes when the body terminates, regardless of how or when it terminates. The thing that gives destructors more expressiveness for dealing with cleanup is that they only execute for the objects that have been initialized. This means that if control exits a block after only half of the stack-local objects have been constructed, only those half of the objects have their destructors invoked. With &lt;span style="font-family: courier new;"&gt;finally&lt;/span&gt;, all that bookkeeping is the responsibility of the programmer.&lt;br /&gt;&lt;br /&gt;(That said, I still see RAII used all over the place to construct awkward, special-purpose classes whose sole purpose is to run some cleanup code. In these cases, having to create a named object &lt;span style="font-style: italic;"&gt;and&lt;/span&gt; a named class to go along with it is pretty perverse.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-8388635786444299944?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/8388635786444299944/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=8388635786444299944' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/8388635786444299944'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/8388635786444299944'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2010/06/raii-vs-finally.html' title='RAII vs finally'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-1034848879571728096</id><published>2010-05-03T16:40:00.002-04:00</published><updated>2010-05-03T16:43:07.739-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='dissertation'/><category scheme='http://www.blogger.com/atom/ns#' term='announcements'/><title type='text'>A Theory of Typed Hygienic Macros</title><content type='html'>&lt;a href="http://www.ccs.neu.edu/home/dherman/research/papers/dissertation.pdf"&gt;A Theory of Typed Hygienic Macros&lt;/a&gt;&lt;br /&gt;PhD Dissertation, 2010&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;We present the λ&lt;span style="font-size:78%;"&gt;&lt;sub&gt;m&lt;/sub&gt;&lt;/span&gt;-calculus, a semantics for a language of hygienic macros with a non-trivial theory. Unlike Scheme, where programs must be macro-expanded to be analyzed, our semantics admits reasoning about programs &lt;span style="font-style: italic;"&gt;as they appear to programmers&lt;/span&gt;. Our contributions include a semantics of hygienic macro expansion, a formal definition of α-equivalence that is independent of expansion, and a proof that expansion preserves α-equivalence. The key technical component of our language is a type system similar to Culpepper and Felleisen’s “shape types,” but with the novel contribution of &lt;span style="font-style: italic;"&gt;binding signature types&lt;/span&gt;, which specify the bindings and scope of a macro’s arguments.&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-1034848879571728096?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/1034848879571728096/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=1034848879571728096' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/1034848879571728096'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/1034848879571728096'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2010/05/theory-of-typed-hygienic-macros.html' title='A Theory of Typed Hygienic Macros'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-484767823441204277</id><published>2010-04-23T13:11:00.004-04:00</published><updated>2010-04-23T13:18:15.230-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='invariants'/><title type='text'>Effective ML</title><content type='html'>Yaron Minsky has giving great advice on &lt;a href="http://ocaml.janestcapital.com/?q=node/75"&gt;effective ML&lt;/a&gt; lately. For my money, the single most important lesson is #3: &lt;span style="font-style: italic;"&gt;make illegal states unrepresentable&lt;/span&gt;. There are so many benefits-- and I've seen the awful drawbacks of not following it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-484767823441204277?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/484767823441204277/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=484767823441204277' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/484767823441204277'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/484767823441204277'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2010/04/effective-ml.html' title='Effective ML'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-7454237299713959099</id><published>2010-04-22T17:59:00.002-04:00</published><updated>2010-04-22T18:03:18.674-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='announcements'/><title type='text'>Cyclic reference graphs FTW</title><content type='html'>I've just created &lt;a href="http://blog.mozilla.com/dherman"&gt;my new Mozilla-hosted blog&lt;/a&gt;! I don't have intention of stopping this one here, but I'm moving my Mozilla-related (and consequently ECMAScript-related) thoughts to that space.&lt;br /&gt;&lt;br /&gt;Also, um, I should hopefully have some pretty good news in a couple weeks.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-7454237299713959099?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/7454237299713959099/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=7454237299713959099' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/7454237299713959099'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/7454237299713959099'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2010/04/cyclic-reference-graphs-ftw.html' title='Cyclic reference graphs FTW'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-2099703879751519423</id><published>2010-04-14T11:27:00.004-04:00</published><updated>2010-04-14T12:02:00.528-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='generators'/><category scheme='http://www.blogger.com/atom/ns#' term='ecmascript'/><category scheme='http://www.blogger.com/atom/ns#' term='delimited continuations'/><category scheme='http://www.blogger.com/atom/ns#' term='first-class continuations'/><category scheme='http://www.blogger.com/atom/ns#' term='harmony'/><title type='text'>Single-frame continuations for Harmony, ctd</title><content type='html'>Continuing last week's &lt;a href="http://calculist.blogspot.com/2010/04/delimited-continuations-in-ecmascript.html"&gt;series&lt;/a&gt; of &lt;a href="http://calculist.blogspot.com/2010/04/design-space-of-continuations.html"&gt;posts&lt;/a&gt; on &lt;a href="http://calculist.blogspot.com/2010/04/thinking-about-continuations.html"&gt;single-frame&lt;/a&gt; &lt;a href="http://calculist.blogspot.com/2010/04/harmony-first-class-activations.html"&gt;continuations&lt;/a&gt; for ECMAScript Harmony:&lt;br /&gt;&lt;br /&gt;The inimitable &lt;a href="https://mail.mozilla.org/pipermail/es-discuss/2010-April/010900.html"&gt;Waldemar Horwat points out the flaw&lt;/a&gt; in my strawman proposal (strawman strawman?):&lt;br /&gt;&lt;blockquote&gt;Since in the final expression you have A(... A(x)), you'll just end up executing the same finally block twice under certain circumstances.&lt;br /&gt;&lt;/blockquote&gt;This program demonstrates the bug:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;function captured() {&lt;br /&gt;   try {&lt;br /&gt;       handler-&gt;();&lt;br /&gt;       throw "throw";&lt;br /&gt;   }&lt;br /&gt;   finally {&lt;br /&gt;       alert("finally!");&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function handler(k) {&lt;br /&gt;   k();&lt;br /&gt;}&lt;/pre&gt;&lt;/blockquote&gt;The &lt;span style="font-family:courier new;"&gt;captured&lt;/span&gt; function calls &lt;span style="font-family:courier new;"&gt;handler&lt;/span&gt;, with the &lt;span style="font-family:courier new;"&gt;finally&lt;/span&gt; clause on the stack. Then &lt;span style="font-family:courier new;"&gt;handler&lt;/span&gt; invokes the captured continuation, which places the &lt;span style="font-family:courier new;"&gt;finally&lt;/span&gt; clause on the stack &lt;span style="font-style: italic;"&gt;again&lt;/span&gt;. So after throwing an exception, unwinding the stack passes through two copies of the &lt;span style="font-family:courier new;"&gt;finally&lt;/span&gt; clause.&lt;br /&gt;&lt;br /&gt;The takeaway for me is that a capturing mechanism that involves a call to a user function has a pigeonhole problem: the suspended continuation ought to capture the &lt;span style="font-family:courier new;"&gt;catch&lt;/span&gt; and &lt;span style="font-family:courier new;"&gt;finally&lt;/span&gt; clauses of the function activation, but the call to the handler &lt;span style="font-style: italic;"&gt;also&lt;/span&gt; ought to be protected by those same &lt;span style="font-family:courier new;"&gt;catch&lt;/span&gt; and &lt;span style="font-family:courier new;"&gt;finally&lt;/span&gt; clauses. And yet the &lt;span style="font-family:courier new;"&gt;finally&lt;/span&gt; block should only executed once per activation. Note that generators do not suffer from this problem, since &lt;span style="font-family:courier new;"&gt;yield&lt;/span&gt; immediately suspends and  aborts the activation, without calling user code in the middle.&lt;br /&gt;&lt;br /&gt;For what it's worth, I tried the above program with &lt;a href="http://www.neilmix.com/narrativejs/doc/"&gt;NarrativeJS&lt;/a&gt; and it died with an internal error. But I didn't investigate further, so that may have been a mistake on my part. (It's difficult to tell what NJS should do since the docs don't really specify its semantics.) Nonetheless, I'm starting to think that &lt;span style="font-family:courier new;"&gt;finally&lt;/span&gt; (and in particular, the intended invariant that finally happens at most once per activation) renders unworkable any attempt to combine continuation-capture with a function call.&lt;br /&gt;&lt;br /&gt;Actually, there are two more takeaways: 1) the notation of evaluation contexts is a nice way to describe and demonstrate the bug--notice Waldemar's wording!--and 2) thank goodness for Waldemar.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-2099703879751519423?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/2099703879751519423/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=2099703879751519423' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/2099703879751519423'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/2099703879751519423'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2010/04/single-frame-continuations-for-harmony.html' title='Single-frame continuations for Harmony, ctd'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-681608784853858608</id><published>2010-04-07T14:50:00.004-04:00</published><updated>2010-04-07T15:10:42.963-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='generators'/><category scheme='http://www.blogger.com/atom/ns#' term='ecmascript'/><category scheme='http://www.blogger.com/atom/ns#' term='delimited continuations'/><category scheme='http://www.blogger.com/atom/ns#' term='first-class continuations'/><category scheme='http://www.blogger.com/atom/ns#' term='harmony'/><title type='text'>Harmony first-class activations</title><content type='html'>This morning I've been blogging about &lt;a href="http://calculist.blogspot.com/2010/04/delimited-continuations-in-ecmascript.html"&gt;single-function activations for Harmony&lt;/a&gt;, the &lt;a href="http://calculist.blogspot.com/2010/04/design-space-of-continuations.html"&gt;history and design space of continuations&lt;/a&gt;, and &lt;a href="http://calculist.blogspot.com/2010/04/thinking-about-continuations.html"&gt;informal models and design sketches&lt;/a&gt; for control operators. A few more thoughts here.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;One-shot continuations&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="" id="magicdomid131"&gt;&lt;span class="author-g-hz122z3qsttw90ct9shy"&gt;(I won't try to model this in the framework I sketched earlier, because it introduces mutation, and then we have to add  a heap to the model, and it gets mucky enough not to be worth it here.)&lt;/span&gt;&lt;/div&gt;&lt;div class="" id="magicdomid132"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="" id="magicdomid133"&gt;&lt;span class="author-g-hz122z3qsttw90ct9shy"&gt;You can limit the expressivity of  continuations to only allow control to enter them at most once. This is  totally compatible with most any design we pick along the other  dimensions. For example, in the &lt;a href="http://calculist.blogspot.com/2010/04/thinking-about-continuations.html"&gt;semantics I sketched earlier&lt;/a&gt;, if the callee throws  an exception, we throw back into the activation, and it becomes marked as un-reusable. So if the callee saved the captured continuation, invoking it later would  be an error. But if the callee calls the captured continuation before returning and then returns normally, the caller skips past the continuation and returns normally.&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="" id="magicdomid134"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="" id="magicdomid135"&gt;&lt;span class="author-g-hz122z3qsttw90ct9shy"&gt;There's  one very subtle aspect of multi-shot continuations that is probably  their single biggest liability: &lt;span style="font-family:courier new;"&gt;finally&lt;/span&gt;. In ES, when you execute a &lt;span style="font-family:courier new;"&gt;try&lt;/span&gt; block with a &lt;span style="font-family:courier new;"&gt;finally&lt;/span&gt; block, the &lt;span style="font-family:courier new;"&gt;finally&lt;/span&gt; block is  guaranteed to be executed exactly once (assuming the body of the &lt;span style="font-family:courier new;"&gt;try&lt;/span&gt;  block completes without an infinite loop and the program isn't abruptly  terminated). Now, even with one-shot continuations, it's possible that  you'll suspend the continuation before the &lt;span style="font-family:courier new;"&gt;try&lt;/span&gt; block completes and  never resume it. But if you do resume it and the &lt;span style="font-family:courier new;"&gt;try&lt;/span&gt; block  completes, it'll still execute the &lt;span style="font-family:courier new;"&gt;finally&lt;/span&gt; block exactly once.&lt;/span&gt;&lt;/div&gt;&lt;div class="" id="magicdomid136"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="" id="magicdomid137"&gt;&lt;span class="author-g-hz122z3qsttw90ct9shy"&gt;With multi-shot continuations,  you can resume that code as many times as you like, and that &lt;span style="font-family:courier new;"&gt;finally&lt;/span&gt;  block will get executed again and again. (This is analogous to Common  Lisp's &lt;a href="http://www.ai.mit.edu/projects/iiip/doc/CommonLISP/HyperSpec/Body/speope_unwind-protect.html"&gt;&lt;span style="font-family:courier new;"&gt;unwind-protect&lt;/span&gt;&lt;/a&gt; and Scheme's &lt;a href="http://www.r6rs.org/final/html/r6rs/r6rs-Z-H-14.html#node_idx_764"&gt;&lt;span style="font-family:courier new;"&gt;dynamic-wind&lt;/span&gt;&lt;/a&gt;.) This is pretty subtle,  and makes it harder to write correct "clean-up" code.&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Implementing JS1.7 generators&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="" id="magicdomid145"&gt;&lt;span class="author-g-hz122z3qsttw90ct9shy"&gt;One-shot, single frame  continuations should be expressive enough to implement  &lt;a href="https://developer.mozilla.org/en/New_in_JavaScript_1.7"&gt;JS1.7 generators&lt;/a&gt; pretty easily. I sent a draft implementation of &lt;a href="https://mail.mozilla.org/pipermail/es-discuss/2010-April/010872.html"&gt;generators via one-frame continuations&lt;/a&gt; to the es-discuss list. As soon as there's a prototype  implementation of single-frame continuations somewhere, it should be  possible to test that code (mutatis mutandis).&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;My current preference&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="author-g-hz122z3qsttw90ct9shy"&gt;So far I sort of prefer the &lt;a href="http://calculist.blogspot.com/2010/04/thinking-about-continuations.html"&gt;semantics I described earlier today&lt;/a&gt;, with one-shot continuations. But I need to  implement and experiment before I trust my opinion. There are certainly  questions of API and syntax design that aren't addressed by my design sketches. For that I'd really  prefer to look at real callback-heavy DOM code and see what would fit  the most smoothly.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-681608784853858608?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/681608784853858608/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=681608784853858608' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/681608784853858608'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/681608784853858608'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2010/04/harmony-first-class-activations.html' title='Harmony first-class activations'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-1988935318374238099</id><published>2010-04-07T13:57:00.005-04:00</published><updated>2010-04-07T15:15:35.380-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='generators'/><category scheme='http://www.blogger.com/atom/ns#' term='ecmascript'/><category scheme='http://www.blogger.com/atom/ns#' term='delimited continuations'/><category scheme='http://www.blogger.com/atom/ns#' term='first-class continuations'/><category scheme='http://www.blogger.com/atom/ns#' term='harmony'/><title type='text'>Thinking about continuations</title><content type='html'>Following up on my &lt;a href="http://calculist.blogspot.com/2010/04/delimited-continuations-in-ecmascript.html"&gt;previous&lt;/a&gt; &lt;a href="http://calculist.blogspot.com/2010/04/design-space-of-continuations.html"&gt;posts&lt;/a&gt; about continuations and Harmony, I want to show how I use the modeling tools of evaluation contexts and operational semantics to sketch out informal designs. I'll use a plausible syntax for a new Harmony operator (based on Neil Mix's &lt;a href="http://www.neilmix.com/narrativejs/doc/"&gt;NarrativeJS&lt;/a&gt;) and start with a reasonably simple semantics based on the well-known shift/reset operators, and sort of work out from there.&lt;br /&gt;&lt;br /&gt;I'll keep this as light and informal as possible. To stay on point, I'll ignore most of the ES features-- no mutation (so we don't have to model the heap / object graph), and not even scope chains. For a faithful and precise model, we'd need all of these things. But for design sketches, I can afford to be sloppier.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Stacks and activations&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I'll model the stack as a non-empty sequence of function activations:&lt;br /&gt;&lt;blockquote&gt;S ::= A | S(A)&lt;/blockquote&gt;&lt;span class="author-g-hz122z3qsttw90ct9shy"&gt;An activation is a function  body, but we want to highlight the current statement being executed or  expression being evaluated (aka the code pointer). So I'll model the  activation as two things: the next bit of code to execute (a statement  or expression), and the function body &lt;span style="font-style: italic;"&gt;without&lt;/span&gt; that bit of code. If  the code pointer is at an expression, the activation is a function body  with a placeholder that I'll spell &lt;span style="font-family:courier new;"&gt;()&lt;/span&gt; (an "expression hole"); if it's a  statement, the activation is a function body with &lt;span style="font-family:courier new;"&gt;{()}&lt;/span&gt; (a  "statement hole") in place of the current statement.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;For the curious, what I just did was -- informally -- define &lt;span style="font-style: italic;"&gt;evaluation contexts&lt;/span&gt; for ES.&lt;br /&gt;&lt;br /&gt;If that was a little too opaque, here's an example. Let's say we have a function&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;function foo(x) { f(x); g(x, 2 * x, null); return x + 4; }&lt;/pre&gt;&lt;/blockquote&gt;If we call &lt;span style="font-family:courier new;"&gt;foo(42)&lt;/span&gt;, then at first, our current code is &lt;span style="font-family:courier new;"&gt;f(42)&lt;/span&gt;; and our activation is&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;{ {()} g(42, 2 * 42, null); return 42 + 4; }&lt;/pre&gt;&lt;/blockquote&gt;When we're about to evaluate the second argument to g, then the current code is &lt;span style="font-family:courier new;"&gt;2 * 42&lt;/span&gt; and the current activation is&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;{ g(42, (), null); return 42 + 4; }&lt;/pre&gt;&lt;/blockquote&gt;When we get to the return statement, current code is return &lt;span style="font-family:courier new;"&gt;42 + 4;&lt;/span&gt; and the current activation is&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;{ {()} }&lt;/pre&gt;&lt;/blockquote&gt;Notice how after we execute some code, it's gone from the activation; the activation just needs to keep track of the code we have left to run.&lt;br /&gt;&lt;br /&gt;For talking about the activation and the current code together, I'll write A&lt;span style="font-family:courier new;"&gt;(&lt;/span&gt;&lt;span style="font-style: italic;"&gt;expr&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;)&lt;/span&gt; or A&lt;span style="font-family:courier new;"&gt;{&lt;/span&gt;&lt;span style="font-style: italic;"&gt;stmt&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;. This is what people call "plugging" code into the hole of a context. Essentially, it's just a modeling trick that makes it convenient to call out where the current code pointer is, but it also turns out to be really natural for talking about first-class control operators-- because it explicitly models the very things we want to manipulate.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Operational semantics&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The above is more or less enough to start writing simple transition rules that describe how programs run, e.g.:&lt;br /&gt;&lt;blockquote&gt;S&lt;span style="font-family:courier new;"&gt;(&lt;/span&gt;A&lt;span style="font-family:courier new;"&gt;{return&lt;/span&gt; &lt;span style="font-style: italic;"&gt;val&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;;})&lt;/span&gt; → S(&lt;span style="font-style: italic;"&gt;val&lt;/span&gt;)&lt;br /&gt;&lt;/blockquote&gt;In English, this rule says: "in a stack starting with S and with activation A on top, when the next code to execute is the statement &lt;span style="font-family:courier new;"&gt;return&lt;/span&gt; &lt;span style="font-style: italic;"&gt;val&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;;&lt;/span&gt; (for some value &lt;span style="font-style: italic;"&gt;val&lt;/span&gt;), then remove the current activation and place &lt;span style="font-style: italic;"&gt;val&lt;/span&gt; in the expression hole of the stack."&lt;br /&gt;&lt;br /&gt;One thing to make clear: this transition arrow describes a runtime state transition of the program, not a compile-time transformation.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Starting with shift and reset&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Here's how a design based on shift and reset might work, specified in one line:&lt;br /&gt;&lt;blockquote&gt;S&lt;span style="font-family:courier new;"&gt;(&lt;/span&gt;A&lt;span style="font-family:courier new;"&gt;(&lt;/span&gt;&lt;span style="font-style: italic;"&gt;val&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;-&gt;(&lt;/span&gt;&lt;span style="font-style: italic;"&gt;val1&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;,&lt;/span&gt; ...&lt;span style="font-family:courier new;"&gt;,&lt;/span&gt; &lt;span style="font-style: italic;"&gt;valn&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;)))&lt;/span&gt; → S&lt;span style="font-family:courier new;"&gt;(&lt;/span&gt;&lt;span style="font-style: italic;"&gt;val&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;(&lt;/span&gt;&lt;span style="font-style: italic;"&gt;val1&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;,&lt;/span&gt; ...&lt;span style="font-family:courier new;"&gt;,&lt;/span&gt; &lt;span style="font-style: italic;"&gt;valn&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;,&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;function(&lt;/span&gt;&lt;span style="font-style: italic;"&gt;x&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;)&lt;/span&gt; A&lt;span style="font-family:courier new;"&gt;(&lt;/span&gt;&lt;span style="font-style: italic;"&gt;x&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;)))&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;The special syntax of a capturing function call comes is from NarrativeJS. The transition rule describes several things:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;After evaluating the callee and its arguments, the operator immediately aborts the current activation and saves it in a function.&lt;/li&gt;&lt;li&gt;Next, it calls the callee with its arguments along with the captured continuation value as an additional argument.&lt;/li&gt;&lt;li&gt;If the captured continuation is called, it executes the captured function activation, with its new argument plugged into the hole of that activation.&lt;/li&gt;&lt;/ol&gt;There's a serious problem with this semantics for ECMAScript: exception handlers. Aborting A will discard any try or finally blocks in A before we call the function. So you'd get surprising behavior like:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;function mightFail(k) {&lt;br /&gt;  // ...&lt;br /&gt;  throw "boo!";&lt;br /&gt;}&lt;br /&gt;function main() {&lt;br /&gt;  try {&lt;br /&gt;      mightFail-&gt;()&lt;br /&gt;  }&lt;br /&gt;  catch (x) {&lt;br /&gt;      return 42&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;main() // uncaught exception: "boo!"&lt;/pre&gt;&lt;/blockquote&gt;A pretty clear violation of principle of least astonishment.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;When to abort&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Having the semantics in such a concise format makes it easy to tweak and experiment with. Let me modify the above semantics in the following way: instead of aborting &lt;span style="font-style: italic;"&gt;before&lt;/span&gt; we call the callee, let's abort the activation &lt;span style="font-style: italic;"&gt;after&lt;/span&gt; we return from the call. That way, if it throws exceptions, they'll be caught by any handlers in A.&lt;br /&gt;&lt;br /&gt;We'll have to invent an expression form that aborts the current function activation after evaluating an expression. This is pretty much just like &lt;span style="font-family:courier new;"&gt;return&lt;/span&gt;, exception it's an expression form.&lt;br /&gt;&lt;blockquote&gt;S&lt;span style="font-family:courier new;"&gt;(&lt;/span&gt;A&lt;span style="font-family:courier new;"&gt;(&lt;/span&gt;&lt;span style="font-style: italic;"&gt;val&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;-&gt;(&lt;/span&gt;&lt;span style="font-style: italic;"&gt;val1&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;,&lt;/span&gt; ...&lt;span style="font-family:courier new;"&gt;,&lt;/span&gt;  &lt;span style="font-style: italic;"&gt;valn&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;)))&lt;/span&gt;&lt;br /&gt;   → S&lt;span style="font-family:courier new;"&gt;(&lt;/span&gt;A&lt;span style="font-family:courier new;"&gt;(&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;RETURN&lt;/span&gt; val&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;(&lt;/span&gt;&lt;span style="font-style: italic;"&gt;val1&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;,&lt;/span&gt; ...&lt;span style="font-family:courier new;"&gt;,&lt;/span&gt; &lt;span style="font-style: italic;"&gt;valn&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;,&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;function(&lt;/span&gt;&lt;span style="font-style: italic;"&gt;x&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;)&lt;/span&gt; A&lt;span style="font-family:courier new;"&gt;(&lt;/span&gt;&lt;span style="font-style: italic;"&gt;x&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;))))&lt;/span&gt;&lt;/blockquote&gt;Actually, we could do this without positing a magic &lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;RETURN&lt;/span&gt;&lt;/span&gt; operator if we have something like the newly-proposed &lt;a href="http://wiki.ecmascript.org/doku.php?id=strawman:let_expressions"&gt;let expressions&lt;/a&gt;, which allow you to execute statements inside an expression. Then we'd have:&lt;br /&gt;&lt;blockquote&gt;S&lt;span style="font-family:courier new;"&gt;(&lt;/span&gt;A&lt;span style="font-family:courier new;"&gt;(&lt;/span&gt;&lt;span style="font-style: italic;"&gt;val&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;-&gt;(&lt;/span&gt;&lt;span style="font-style: italic;"&gt;val1&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;,&lt;/span&gt; ...&lt;span style="font-family:courier new;"&gt;,&lt;/span&gt;  &lt;span style="font-style: italic;"&gt;valn&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;)))&lt;br /&gt;&lt;/span&gt;     → S&lt;span style="font-family:courier new;"&gt;(&lt;/span&gt;A&lt;span style="font-family:courier new;"&gt;(let (x = &lt;/span&gt;&lt;span style="font-style: italic;"&gt;val&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;(&lt;/span&gt;&lt;span style="font-style: italic;"&gt;val1&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;,&lt;/span&gt;...&lt;span style="font-family:courier new;"&gt;,&lt;/span&gt; &lt;span style="font-style: italic;"&gt;valn&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;,&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;function(&lt;/span&gt;&lt;span style="font-style: italic;"&gt;x&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;)&lt;/span&gt; A&lt;span style="font-family:courier new;"&gt;(&lt;/span&gt;&lt;span style="font-style: italic;"&gt;x&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;))) {return x;}))&lt;/span&gt;&lt;/blockquote&gt;So that's a brief demo of using evaluation contexts and operational transition rules to sketch the semantics of continuation operators.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Edit:&lt;/span&gt; I forgot to mention, it's easy enough to specify the behavior of &lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;RETURN&lt;/span&gt;&lt;/span&gt;:&lt;br /&gt;&lt;blockquote&gt;S&lt;span style="font-family: courier new;"&gt;(&lt;/span&gt;A&lt;span style="font-family: courier new;"&gt;(&lt;/span&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;RETURN&lt;/span&gt; &lt;span style="font-style: italic;"&gt;val&lt;/span&gt;&lt;span style="font-family: courier new;"&gt;))&lt;/span&gt; &amp;rarr; S&lt;span style="font-family: courier new;"&gt;(&lt;/span&gt;&lt;span style="font-style: italic;"&gt;val&lt;/span&gt;&lt;span style="font-family: courier new;"&gt;)&lt;/span&gt;&lt;/blockquote&gt;As I say, just like &lt;span style="font-family: courier new;"&gt;return&lt;/span&gt; statements, but as an expression form. To be clear, this is just a specification mechanism, not something I'd suggest as a language feature.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-1988935318374238099?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/1988935318374238099/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=1988935318374238099' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/1988935318374238099'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/1988935318374238099'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2010/04/thinking-about-continuations.html' title='Thinking about continuations'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-8746049086966504751</id><published>2010-04-07T13:10:00.007-04:00</published><updated>2010-04-07T13:55:42.450-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='generators'/><category scheme='http://www.blogger.com/atom/ns#' term='ecmascript'/><category scheme='http://www.blogger.com/atom/ns#' term='delimited continuations'/><category scheme='http://www.blogger.com/atom/ns#' term='first-class continuations'/><category scheme='http://www.blogger.com/atom/ns#' term='harmony'/><title type='text'>The design space of continuations</title><content type='html'>&lt;a href="http://calculist.blogspot.com/2010/04/delimited-continuations-in-ecmascript.html"&gt;I mentioned earlier&lt;/a&gt; that the design space for first-class continuations has a lot of historical research behind it. This &lt;a href="http://library.readscheme.org/page6.html"&gt;list of papers on continuations&lt;/a&gt; up to around 2005 is a start, but by no means complete. (The history of continuations is actually pretty astoundingly far-reaching. Apparently my &lt;a href="http://www.ccs.neu.edu/home/wand"&gt;PhD advisor&lt;/a&gt;'s &lt;a href="http://cs-www.cs.yale.edu/homes/fischer/"&gt;PhD advisor&lt;/a&gt; was one of a number of people who &lt;a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.40.237"&gt;independently discovered continuations&lt;/a&gt; in different research programs and under different guises.)&lt;br /&gt;&lt;br /&gt;The research literature has been helpful to me in understanding the design space of control operators better, particularly because it gives me good models for reasoning, formally or informally, about control effects.&lt;br /&gt;&lt;br /&gt;Here are some of the design questions raised by the research literature and good modeling frameworks. This isn't a complete list, and it isn't the place to cite adequately. All I'm interested in is highlighting some of the takeaways&lt;span style="font-style: italic;"&gt;.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;How much of the continuation can be captured?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Scheme's &lt;span style="font-family:courier new;"&gt;call/cc&lt;/span&gt; allows you to capture the "whole" continuation, up to wherever the language implementor decides is the limit. But delimited continuations make this boundary more explicit, which has a couple benefits. First, by installing a delimiter, you can prevent code that you call from capturing parts of your continuation that you want to keep private. Second, when you capture a continuation, you have a clearer picture of what you're capturing.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;What elements of the continuation are captured?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The answer at first seems obvious: you capture the control context and the environment (aka scope chain). But it gets trickier when you have things like exception handlers and other information associated with the dynamic state of the control context.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;What kinds of delimiters do you give to users?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In our case, we're only interested in an implicit delimiter at function boundaries. But there are a number of different designs of control delimiters.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;What kinds of control-abort operators do you give to users?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Turns out there's at least one in every C-like language: &lt;span style="font-family:courier new;"&gt;return&lt;/span&gt;. That's probably enough for our purposes. But there are several possibilities there, too, and they can get surprisingly subtle.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Does executing a captured continuation install a new delimiter?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This is the key difference between &lt;a href="http://portal.acm.org/citation.cfm?id=73560.73576"&gt;Felleisen's &lt;span style="font-style: italic;"&gt;F&lt;/span&gt;/# operators&lt;/a&gt; [*] and &lt;a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.43.8753"&gt;Danvy and Filinski's &lt;span style="font-family:courier new;"&gt;shift&lt;/span&gt;/&lt;span style="font-family:courier new;"&gt;reset&lt;/span&gt; operators&lt;/a&gt;. With the former, you capture a continuation up to the nearest delimiter, but when you invoke the captured continuation, there's no new delimiter. With the latter, a captured continuation reinstalls a new delimiter every time you invoke it.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;How many times can you enter a continuation?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The most general design allows a captured continuation to be used any number of times. With "one-shot" continuations, you can only enter a continuation once. Notice that "entering a continuation" could mean a number of things: returning normally, unwinding it by throwing exceptions, or calling into it later via a captured continuation.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;When do we abort the current continuation?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This one is really, really variable. There are many plausible points in the semantics where an exit can occur, and many of them lead to plausible but distinct designs.&lt;br /&gt;&lt;br /&gt;[*] That's pronounced "eff" and "prompt" -- no relation to &lt;a href="http://msdn.microsoft.com/en-us/fsharp/default.aspx"&gt;F#&lt;/a&gt;. I just noticed that!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-8746049086966504751?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/8746049086966504751/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=8746049086966504751' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/8746049086966504751'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/8746049086966504751'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2010/04/design-space-of-continuations.html' title='The design space of continuations'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-5134201122741469288</id><published>2010-04-07T12:22:00.004-04:00</published><updated>2010-04-07T12:37:40.783-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='generators'/><category scheme='http://www.blogger.com/atom/ns#' term='ecmascript'/><category scheme='http://www.blogger.com/atom/ns#' term='delimited continuations'/><category scheme='http://www.blogger.com/atom/ns#' term='first-class continuations'/><category scheme='http://www.blogger.com/atom/ns#' term='harmony'/><title type='text'>Delimited continuations? In ECMAScript?</title><content type='html'>Well, no.&lt;br /&gt;&lt;br /&gt;Besides breaking a lot of language invariants, first-class continuations would be a nightmare for portability, since different implementations implement different API's natively. Either you mandate capturing continuations across native frames, which is a hardship for implementers and a performance-killer, or you don't, which causes observably different behavior across browsers when they place native delimiters at different points in the continuations-- leading to lots of painful bug reports and nasty market dynamics where everyone has to tailor their implementations to track the most popular.&lt;br /&gt;&lt;br /&gt;So that won't happen. But!&lt;br /&gt;&lt;br /&gt;&lt;a href="https://developer.mozilla.org/en/New_in_JavaScript_1.7"&gt;JS 1.7&lt;/a&gt; introduced &lt;a href="http://www.python.org/dev/peps/pep-0255/"&gt;Pythonic generators&lt;/a&gt;, which allow you to suspend a single function activation. This alleviates some of the painful CPS patterns people have to use on the web to interact with the event-loop-concurrent, single-thread-of-control semantics of JavaScript on the web. But it's also a little ad hoc. And &lt;a href="https://mail.mozilla.org/pipermail/es-discuss/2010-March/010865.html"&gt;Kris Zyp&lt;/a&gt; recently made the helpful suggestion that we could explore a design for a simpler, more general single-frame continuation-capture operation for &lt;a href="http://calculist.blogspot.com/2008/08/ecmascript-harmony.html"&gt;Harmony&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;What we're talking about here is a restricted version of delimited continuations: the delimiters are implicit--they're at function boundaries. But otherwise it's very much in that space. And there's a loooot of prior work on this topic. I'll post later with a little background and some notes about the design space of delimited continuations for ES.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-5134201122741469288?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/5134201122741469288/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=5134201122741469288' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/5134201122741469288'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/5134201122741469288'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2010/04/delimited-continuations-in-ecmascript.html' title='Delimited continuations? In ECMAScript?'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-168027357775888332</id><published>2010-02-27T21:10:00.003-05:00</published><updated>2010-02-27T21:19:47.484-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='typedef'/><category scheme='http://www.blogger.com/atom/ns#' term='lexical syntax'/><category scheme='http://www.blogger.com/atom/ns#' term='lexical scope'/><category scheme='http://www.blogger.com/atom/ns#' term='javadot'/><title type='text'>Generalizing Javadot</title><content type='html'>The idea of &lt;a href="http://jscheme.sourceforge.net/jscheme/doc/javadot.html"&gt;Javadot&lt;/a&gt; is to allow the rich lexical syntax of Lisp and Scheme with the elegance of the dot-notation from the C tradition by simply allowing scope to trump lexical splitting: if &lt;span style="font-family: courier new;"&gt;foo.bar&lt;/span&gt; is in scope as an identifier, then it parses as a variable reference; otherwise it parses as &lt;span style="font-family: courier new;"&gt;"foo"&lt;/span&gt; &lt;span style="font-family: courier new;"&gt;"."&lt;/span&gt; &lt;span style="font-family: courier new;"&gt;"bar"&lt;/span&gt;. It's a simple compromise, it's easy to understand, it plays well with lexical scope, and (in an infix language) you can always circumvent it with whitespace. (I don't &lt;span style="font-style: italic;"&gt;think&lt;/span&gt; it needs to complicate parsing too much, either, since you can do a post-hoc splitting of the lexeme, rather than forcing the lexer to understand scope the way you're forced to with the &lt;a href="http://calculist.blogspot.com/2009/02/c-typedef-parsing-problem.html"&gt;C &lt;span style="font-family: courier new;"&gt;typedef&lt;/span&gt; ambiguity&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;My question is: couldn't you use this idea in an infix language, and generalize it to work for all infix operators? This would allow the use of other common operators such as -, +, *, /, &lt;, and &gt;, all of which I've loved being able to use in identifier names in Scheme, and all of which I also really like being able to use as infix operators.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-168027357775888332?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/168027357775888332/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=168027357775888332' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/168027357775888332'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/168027357775888332'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2010/02/generalizing-javadot.html' title='Generalizing Javadot'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-9102943144231959961</id><published>2010-02-12T13:19:00.002-05:00</published><updated>2010-02-12T13:27:05.943-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='types'/><category scheme='http://www.blogger.com/atom/ns#' term='API design'/><category scheme='http://www.blogger.com/atom/ns#' term='postel&apos;s law'/><title type='text'>Eich's Law</title><content type='html'>Found this gem in a C++ comment while &lt;a href="http://mxr.mozilla.org/mozilla-central/source/js/src/jsscan.cpp#1464"&gt;digging in the SpiderMonkey codebase&lt;/a&gt;:&lt;br /&gt;&lt;blockquote&gt;After much testing, it's clear that Postel's advice to protocol designers ("be liberal in what you accept, and conservative in what you send") invites a natural-law repercussion for JS as "protocol":&lt;br /&gt;&lt;br /&gt;"If you are liberal in what you accept, others will utterly fail to be conservative in what they send."&lt;/blockquote&gt;The comment is unsigned, but it sounds like Brendan.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-9102943144231959961?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/9102943144231959961/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=9102943144231959961' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/9102943144231959961'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/9102943144231959961'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2010/02/eichs-law.html' title='Eich&apos;s Law'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-7296263527385694986</id><published>2010-01-25T22:29:00.002-05:00</published><updated>2010-01-25T22:40:10.355-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C'/><category scheme='http://www.blogger.com/atom/ns#' term='gdb'/><category scheme='http://www.blogger.com/atom/ns#' term='hacking'/><category scheme='http://www.blogger.com/atom/ns#' term='macros'/><title type='text'>Wading into the C</title><content type='html'>No time for deep thoughts these days; too much hacking, dissertating, designing, and committeefying going on. Just a couple notes based on recent experiences hacking in C/C++:&lt;br /&gt;&lt;br /&gt;1. Not being able to rely on recursion makes me sad.&lt;br /&gt;&lt;br /&gt;2. "Downwards macro-args" in C:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;#define MY_ENUM_LIST(m) \&lt;br /&gt;   m(RED, 0), \&lt;br /&gt;   m(GREEN, 1), \&lt;br /&gt;   m(BLUE, 2)&lt;br /&gt;&lt;br /&gt;#define DEF_ENUM_ENTRY(c, v) c = v&lt;br /&gt;#define QUOTE_ENUM_ENTRY(c, v) #c&lt;br /&gt;&lt;br /&gt;typedef enum rgb {&lt;br /&gt;   MY_ENUM_LIST(DEF_ENUM_ENTRY)&lt;br /&gt;} rgb;&lt;br /&gt;&lt;br /&gt;const char *rgb_names[] = {&lt;br /&gt;   MY_ENUM_LIST(QUOTE_ENUM_ENTRY)&lt;br /&gt;};&lt;/pre&gt;&lt;/blockquote&gt;3. I am fast becoming acquainted with &lt;span style="font-family:courier new;"&gt;gdb&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;4. And a few choice command-line shortcuts really save extraordinary amounts of time. My new fav: the &lt;a href="http://www.gnu.org/software/bash/manual/bashref.html#Event-Designators"&gt;&lt;span style="font-family:courier new;"&gt;!?&lt;/span&gt; bash-history shortcut&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-7296263527385694986?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/7296263527385694986/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=7296263527385694986' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/7296263527385694986'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/7296263527385694986'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2010/01/wading-into-c.html' title='Wading into the C'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-4601668236253617109</id><published>2009-12-11T14:26:00.003-05:00</published><updated>2009-12-11T14:30:31.132-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='education'/><category scheme='http://www.blogger.com/atom/ns#' term='curriculum'/><title type='text'>Computer Science Education Week</title><content type='html'>In honor of &lt;a href="http://www.acm.org/press-room/news-releases/cs-education-week"&gt;Computer Science Education Week&lt;/a&gt;, I'll just cite &lt;a href="http://www.htdp.org/2003-09-26/Book/curriculum-Z-H-2.html"&gt;a passage I find inspirational&lt;/a&gt; about the role of computer science education:&lt;br /&gt;&lt;p&gt; &lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Yet programming is more than just a vocational skill. Indeed, &lt;em&gt;good programming&lt;/em&gt; is a fun activity, a creative outlet, and a way to express abstract ideas in a tangible form. And designing programs teaches a variety of skills that are important in all kinds of professions: critical reading, analytical thinking, creative synthesis, and attention to detail.&lt;/p&gt; &lt;p&gt; We therefore believe that the study of program design deserves the same central role in general education as mathematics and English. Or, put more succinctly, &lt;/p&gt; &lt;div align="center"&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;   &lt;strong&gt;everyone should learn how to design programs.&lt;/strong&gt; &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;  On one hand, program design teaches the same analytical skills as mathematics. But, unlike mathematics, working with programs is an active approach to learning. Interacting with software provides immediate feedback and thus leads to exploration, experimentation, and self-evaluation. Furthermore, designing programs produces useful and fun things, which vastly increases the sense of accomplishment when compared to drill exercises in mathematics. On the other hand, program design teaches the same analytical reading and writing skills as English.  Even the smallest programming tasks are formulated as word problems. Without critical reading skills, a student cannot design programs that match the specification. Conversely, good program design methods force a student to articulate thoughts about programs in proper English.&lt;/blockquote&gt;From "&lt;a href="http://www.htdp.org"&gt;How to Design Programs&lt;/a&gt;," by Felleisen, Findler, Flatt and Krishnamurthi.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-4601668236253617109?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/4601668236253617109/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=4601668236253617109' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/4601668236253617109'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/4601668236253617109'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/12/computer-science-education-week.html' title='Computer Science Education Week'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-8842011133021018323</id><published>2009-11-04T16:30:00.003-05:00</published><updated>2009-11-04T16:35:13.722-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tail calls'/><category scheme='http://www.blogger.com/atom/ns#' term='proper tail recursion'/><title type='text'>Ezra: Function calls are not stack frames</title><content type='html'>I don't have much to add to this but &lt;a href="http://ezrakilty.net/research/"&gt;Ezra&lt;/a&gt;'s saying &lt;a href="http://ezrakilty.net/research/2009/11/function_calls_are_not_stack_frames.html"&gt;things that are true&lt;/a&gt;:&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Tim Bray is spreading more misinformation about tail recursion. He describes it this way:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;It looks like a subroutine call, but in the case where it occurs as the last thing in the routine, it magically, silently, and automatically gets turned into, now how did I put it? “A highly controlled and structured GOTO.”&lt;/p&gt; &lt;/blockquote&gt;  A tail-call &lt;em&gt;is&lt;/em&gt; a subroutine call. The efficient implementation does not magically transformed into something else; if it doesn't create a stack frame on such a call, it's because one simply isn't relevant.&lt;/blockquote&gt;It's worth reading &lt;a href="http://ezrakilty.net/research/2009/11/function_calls_are_not_stack_frames.html"&gt;Ezra's whole post&lt;/a&gt;. I especially appreciate his point about confusing semantics with cost model.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-8842011133021018323?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/8842011133021018323/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=8842011133021018323' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/8842011133021018323'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/8842011133021018323'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/11/ezra-function-calls-are-not-stack.html' title='Ezra: Function calls are not stack frames'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-8639237185709279396</id><published>2009-09-08T10:49:00.004-04:00</published><updated>2009-09-08T14:39:48.589-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSON'/><title type='text'>Proposed json.plt change</title><content type='html'>I'm not sure how many users I have of my &lt;a href="http://planet.plt-scheme.org/display.ss?package=json.plt&amp;amp;owner=dherman"&gt;json.plt PLaneT package&lt;/a&gt;, nor how many of them read my blog. But I thought I'd see if I could take a straw poll here. I'm thinking about changing the data definition in a backwards-incompatible way. What if I said:&lt;br /&gt;&lt;blockquote&gt;A &lt;span style="font-style: italic;"&gt;jsexpr &lt;/span&gt;is one of:&lt;br /&gt;&lt;ul&gt;&lt;li style="font-family: courier new;"&gt;'null&lt;/li&gt;&lt;li&gt;boolean&lt;/li&gt;&lt;li&gt;string&lt;/li&gt;&lt;li&gt;integer&lt;/li&gt;&lt;li&gt;inexact-real&lt;/li&gt;&lt;li&gt;(vectorof &lt;span style="font-style: italic;"&gt;jsexpr&lt;/span&gt;)&lt;/li&gt;&lt;li&gt;(listof (cons symbol &lt;span style="font-style: italic;"&gt;jsexpr&lt;/span&gt;))&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;The nice thing about this representation is that it's easier to quote and quasiquote. The down-sides are that array manipulation is a little less convenient, and table lookup is slower.&lt;br /&gt;&lt;br /&gt;Another alternative is:&lt;br /&gt;&lt;blockquote&gt;A &lt;span style="font-style: italic;"&gt;jsexpr &lt;/span&gt;is one of:&lt;br /&gt;&lt;ul&gt;&lt;li style="font-family: courier new;"&gt;#:null&lt;/li&gt;&lt;li&gt; boolean&lt;/li&gt;&lt;li&gt; string&lt;/li&gt;&lt;li&gt; integer&lt;/li&gt;&lt;li&gt; inexact-real&lt;/li&gt;&lt;li&gt; (listof &lt;span style="font-style: italic;"&gt;jsexpr&lt;/span&gt;)&lt;/li&gt;&lt;li&gt; (listof (cons symbol &lt;span style="font-style: italic;"&gt;jsexpr&lt;/span&gt;))&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;The nice thing about this is that both arrays and tables are conveniently represented as lists. But it's a little uglier for representing &lt;span style="font-family:courier new;"&gt;null&lt;/span&gt;, which is necessary to avoid ambiguity between the JSON strings &lt;span style="font-family:courier new;"&gt;{ "null" : [] }&lt;/span&gt; and &lt;span style="font-family:courier new;"&gt;[[null]]&lt;/span&gt;. Note that it's also a little more subtle to distinguish between arrays and tables.&lt;br /&gt;&lt;br /&gt;Other possible unambiguous representations of &lt;span style="font-family:courier new;"&gt;null&lt;/span&gt; include &lt;span style="font-family:courier new;"&gt;#\null&lt;/span&gt;, &lt;span style="font-family:courier new;"&gt;#"null"&lt;/span&gt;, or &lt;span style="font-family:courier new;"&gt;#&amp;amp;0&lt;/span&gt;. Yech.&lt;br /&gt;&lt;br /&gt;If you have any opinions, feel free to comment here or email me privately.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Update:&lt;/span&gt; Whoops, can't have them both be lists, because of the ambiguity between the empty object and empty array.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-8639237185709279396?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/8639237185709279396/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=8639237185709279396' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/8639237185709279396'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/8639237185709279396'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/09/proposed-jsonplt-change.html' title='Proposed json.plt change'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-4557403269616946743</id><published>2009-09-03T17:07:00.002-04:00</published><updated>2009-09-03T17:08:54.998-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Mitchfest'/><title type='text'>Mitchfest blog</title><content type='html'>We've created a &lt;a href="http://mitchfest.wordpress.com"&gt;Mitchfest blog&lt;/a&gt; where we'll be posting updates on new material as it becomes available, including presentation slides, videos, and publication of issues of the Festschrift.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-4557403269616946743?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/4557403269616946743/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=4557403269616946743' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/4557403269616946743'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/4557403269616946743'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/09/mitchfest-blog.html' title='Mitchfest blog'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-223456751683680621</id><published>2009-08-17T12:52:00.003-04:00</published><updated>2009-08-17T12:55:27.512-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rules'/><title type='text'>Quote of the day</title><content type='html'>&lt;blockquote&gt;"What's surprising to me is that this language ever managed to achieve widespread use - but I guess it's just another example of how you can break a whole bunch of precious rules and the sky doesn't necessarily fall in. Software is full of people declaiming their 'thou shalt not' lists, and right across the street there's another bunch of people breaking those very rules quite profitably."&lt;br /&gt;         -- &lt;a href="http://lambda-the-ultimate.org/node/3564#comment-50626"&gt;Daniel Earwicker&lt;/a&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-223456751683680621?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/223456751683680621/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=223456751683680621' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/223456751683680621'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/223456751683680621'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/08/quote-of-day.html' title='Quote of the day'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-3328016333347489110</id><published>2009-08-11T16:28:00.001-04:00</published><updated>2009-08-11T16:28:58.529-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='announcements'/><title type='text'>Mitchfest program</title><content type='html'>We've posted the &lt;a href="http://www.ccs.neu.edu/events/wand-symposium"&gt;Mitchfest&lt;/a&gt; &lt;a href="http://www.ccs.neu.edu/events/wand-symposium/program.html"&gt;schedule and program&lt;/a&gt;!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-3328016333347489110?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/3328016333347489110/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=3328016333347489110' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/3328016333347489110'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/3328016333347489110'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/08/mitchfest-program.html' title='Mitchfest program'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-1403978149452762668</id><published>2009-08-10T07:26:00.004-04:00</published><updated>2009-08-10T07:37:12.217-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='announcements'/><title type='text'>Call for Participation: Scheme Workshop 2009</title><content type='html'>&lt;div style="text-align: center;"&gt;&lt;div style="text-align: left;"&gt;[&lt;span style="font-weight: bold;"&gt;Note: &lt;/span&gt;only one day left to register! --Dave]&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style="font-weight: bold;"&gt;2009 Workshop on Scheme and Functional Programming&lt;/span&gt;&lt;br /&gt;    Co-Located with the &lt;a href="http://www.ccs.neu.edu/events/wand-symposium"&gt;Symposium in Honor of Mitchell Wand&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;                         August 22, 2009&lt;br /&gt;                  Boston, Massachusetts, USA&lt;br /&gt;               &lt;a href="http://www.schemeworkshop.org/2009"&gt;http://www.schemeworkshop.org/2009&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;                     &lt;span style="font-weight: bold;"&gt;CALL FOR PARTICIPATION&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To the delight of all and sundry, the 2009 Scheme and Functional Programming Workshop will be held on August 22nd at Northeastern University, and it is a signal honor for me to be able to invite YOU to the WORLD'S FOREMOST WORKSHOP on the marvelous Scheme language, and to present a program PACKED with contributions from familiar faces and new ones, certain to amaze, delight, and edify. Lend us your ears, and we will widen the space between them.&lt;br /&gt;&lt;br /&gt;- John Clements&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;IMPORTANT DATES&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;August 11, 2009 - Registration deadline&lt;br /&gt;August 22, 2009 - &lt;a href="http://www.schemeworkshop.org/2009"&gt;Workshop on Scheme and Functional Programming&lt;/a&gt;&lt;br /&gt;August 23-24, 2009 - &lt;a href="http://www.ccs.neu.edu/events/wand-symposium"&gt;Symposium in Honor of Mitchell Wand&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;VENUE&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Northeastern University&lt;br /&gt;Boston Massachusetts&lt;br /&gt;&lt;a href="http://www.northeastern.edu/campusmap/map/qad5.html"&gt;Curry Student Center&lt;/a&gt; Ballroom (Building 50)&lt;br /&gt;&lt;a href="http://maps.google.com/maps?q=346+Huntington+Ave,+Boston,+MA+02115"&gt;346 Huntington Ave&lt;/a&gt;&lt;br /&gt;Boston, MA 02115&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;ACCOMMODATION&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A limited block of hotel rooms has been reserved for participants of the Scheme Workshop and/or the Mitchell Wand Symposium at hotels in Cambridge and Boston.  See the &lt;a href="http://www.schemeworkshop.org/2009"&gt;workshop web site&lt;/a&gt; for more information, and please note that some of these special rates have already expired.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;REGISTRATION&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The registration fee will be $40 to help cover the operating costs and lunch accommodations. Please register by &lt;span style="font-weight: bold;"&gt;August 11, 2009&lt;/span&gt; so that we will have an accurate head count. To register, please send an email to &lt;a href="mailto:aoeuswreg@brinckerhoff.org"&gt;aoeuswreg@brinckerhoff.org&lt;/a&gt; with your name and any dietary restrictions for lunch.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;PROGRAM COMMITTEE&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;John Clements (Cal Poly State University (organizer &amp;amp; chair))&lt;/li&gt;&lt;li&gt;Dominique Boucher (Nu Echo)&lt;/li&gt;&lt;li&gt;Abdulaziz Ghuloum (Indiana University)&lt;/li&gt;&lt;li&gt;David Herman (Northeastern University)&lt;/li&gt;&lt;li&gt;Shriram Krishnamurthi (Brown University)&lt;/li&gt;&lt;li&gt;Matthew Might (University of Utah)&lt;/li&gt;&lt;li&gt;David Van Horn (Northeastern University)&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;PRELIMINARY PROGRAM&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Invited: If programming is like math, why don't math teachers teach programming?&lt;/span&gt;&lt;br /&gt;Emmanuel Schanzer&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Invited Talk on Future Directions for the Scheme Language&lt;/span&gt;&lt;br /&gt;The Newly Elected Scheme Language Steering Committee&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;The Scribble Reader: An Alternative to S-expressions for Textual Content&lt;/span&gt;&lt;br /&gt;Eli Barzilay&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;World With Web: A compiler from world applications to JavaScript&lt;/span&gt;&lt;br /&gt;Remzi Emre Başar, Caner Derici, Çağdaş Şenol&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Scalable Garbage Collection with Guaranteed MMU&lt;/span&gt;&lt;br /&gt;William D Clinger, Felix S. Klock II&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Distributed Software Transactional Memory&lt;/span&gt;&lt;br /&gt;Anthony Cowley&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Sequence Traces for Object-Oriented Executions&lt;/span&gt;&lt;br /&gt;Carl Eastlund, Matthias Felleisen&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Keyword and Optional Arguments in PLT Scheme&lt;/span&gt;&lt;br /&gt;Matthew Flatt, Eli Barzilay&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Fixing Letrec (reloaded)&lt;/span&gt;&lt;br /&gt;Abdulaziz Ghuloum, R. Kent Dybvig&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Descot: Distributed Code Repository Framework&lt;/span&gt;&lt;br /&gt;Aaron W. Hsu&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;A pattern-matcher for miniKanren -or- How to get into trouble with CPS macros&lt;/span&gt;&lt;br /&gt;Andrew W. Keep, Michael D. Adams, Lindsey Kuper, William E. Byrd, Daniel P. Friedman&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Randomized Testing in PLT Redex&lt;/span&gt;&lt;br /&gt;Casey Klein, Robert Bruce Findler&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Screen-Replay: A Session Recording and Analysis Tool for DrScheme&lt;/span&gt;&lt;br /&gt;Mehmet Fatih Köksal, Remzi Emre Başar, Suzan Üsküdarlı&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Interprocedural Dependence Analysis of Higher-Order Programs via Stack Reachability&lt;/span&gt;&lt;br /&gt;Matthew Might, Tarun Prabhu&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Get stuffed: Tightly packed abstract protocols in Scheme&lt;/span&gt;&lt;br /&gt;John Moore&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Higher-Order Aspects in Order&lt;/span&gt;&lt;br /&gt;Eric Tanter&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Peter J Landin (1930-2009)&lt;/span&gt;&lt;br /&gt;Olivier Danvy&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-1403978149452762668?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/1403978149452762668/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=1403978149452762668' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/1403978149452762668'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/1403978149452762668'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/08/call-for-participation-scheme-workshop.html' title='Call for Participation: Scheme Workshop 2009'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-7546292339180325449</id><published>2009-08-06T23:41:00.006-04:00</published><updated>2009-08-07T18:21:52.586-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='diagnostics'/><category scheme='http://www.blogger.com/atom/ns#' term='proper tail recursion'/><category scheme='http://www.blogger.com/atom/ns#' term='stack traces'/><category scheme='http://www.blogger.com/atom/ns#' term='debugging'/><category scheme='http://www.blogger.com/atom/ns#' term='macros'/><title type='text'>Selectively disabling tail recursion</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/__OULbbSCQyc/SnunDG0XyyI/AAAAAAAAADQ/XPfbHvd3-TQ/s1600-h/partial-trace.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 200px; height: 78px;" src="http://1.bp.blogspot.com/__OULbbSCQyc/SnunDG0XyyI/AAAAAAAAADQ/XPfbHvd3-TQ/s200/partial-trace.png" alt="" id="BLOGGER_PHOTO_ID_5367067052753799970" border="0" /&gt;&lt;/a&gt;The anti-tail-recursion crowd often complains about loss of information in stack traces. In DrScheme, if you raise an exception after a sequence of tail calls:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;(define (fact-iter n acc)&lt;br /&gt;  (if (zero? n)&lt;br /&gt;      (error 'fact "stop!")&lt;br /&gt;      (fact-iter (sub1 n) (* n acc))))&lt;br /&gt;(fact-iter 3 1)&lt;/pre&gt;&lt;/blockquote&gt;the stack trace you get back has very little information in it.&lt;br /&gt;&lt;br /&gt;One argument you'll sometimes hear from people like me is that in a properly tail calling language, you can always turn a tail position into a non-tail-position, whereas the reverse is impossible. But in practice, when you want broadly better diagnostics, manually converting lots of individual function calls throughout a program is too hard to be practical, and you then have to go and undo it afterward.&lt;br /&gt;&lt;br /&gt;So in the spirit of &lt;a href="http://calculist.blogspot.com/2009/07/linguistic-tools-for-diagnostics.html"&gt;linguistic tools for diagnostics&lt;/a&gt;, I've discovered a dirt-simple trick for improving the information in stack traces while debugging.&lt;br /&gt;&lt;br /&gt;PLT Scheme lets you hijack the normal meaning of function application by rebinding the &lt;a style="font-family: courier new; font-weight: bold;" href="http://docs.plt-scheme.org/reference/application.html"&gt;#%app&lt;/a&gt; macro. So I defined a utility called &lt;a style="font-family: courier new; font-weight: bold;" href="http://planet.plt-scheme.org/package-source/dherman/tail.plt/5/0/planet-docs/tail/index.html"&gt;trace-app&lt;/a&gt; that wraps its function application in (roughly) the identity function, forcing the given function call out of tail position. Then all you have to do is add to the top of a module:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;(require (planet dherman/tail:4))&lt;br /&gt;(define-syntax #%app trace-app)&lt;/pre&gt;&lt;/blockquote&gt;and suddenly, all function applications that occur syntactically within the current module body are non-tail calls, and &lt;span style="font-style: italic;"&gt;voilà&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/__OULbbSCQyc/SnunNeeawfI/AAAAAAAAADY/aLKKtP9JDoY/s1600-h/full-trace.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 200px; height: 146px;" src="http://1.bp.blogspot.com/__OULbbSCQyc/SnunNeeawfI/AAAAAAAAADY/aLKKtP9JDoY/s200/full-trace.png" alt="" id="BLOGGER_PHOTO_ID_5367067230902862322" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Update:&lt;/span&gt; I've posted a &lt;a href="http://planet.plt-scheme.org/display.ss?package=tail.plt&amp;amp;owner=dherman"&gt;new version of the package&lt;/a&gt;, which exports &lt;a style="font-weight: bold; font-family: courier new;" href="http://planet.plt-scheme.org/package-source/dherman/tail.plt/5/0/planet-docs/tail/index.html"&gt;trace-app&lt;/a&gt; in a slightly different way. The initial version had a hazard that client modules which used&lt;blockquote&gt;&lt;pre&gt;(provide (all-defined-out))&lt;/pre&gt;&lt;/blockquote&gt;would inadvertently re-provide &lt;span style="font-family: courier new;"&gt;#%app&lt;/span&gt;, which would then disable tail recursion for its client modules.&lt;br /&gt;&lt;br /&gt;The new way to use it is&lt;blockquote&gt;&lt;pre&gt;(require (rename-in (planet dherman/tail:5) [trace-app #%app]))&lt;/pre&gt;&lt;/blockquote&gt;or&lt;blockquote&gt;&lt;pre&gt;(require (only-in (planet dherman/tail:5) [trace-app #%app]))&lt;/pre&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-7546292339180325449?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/7546292339180325449/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=7546292339180325449' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/7546292339180325449'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/7546292339180325449'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/08/selectively-disabling-tail-recursion.html' title='Selectively disabling tail recursion'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/__OULbbSCQyc/SnunDG0XyyI/AAAAAAAAADQ/XPfbHvd3-TQ/s72-c/partial-trace.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-2397896808716575435</id><published>2009-07-22T23:09:00.006-04:00</published><updated>2009-07-23T07:21:58.406-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='diagnostics'/><category scheme='http://www.blogger.com/atom/ns#' term='tail calls'/><category scheme='http://www.blogger.com/atom/ns#' term='proper tail recursion'/><category scheme='http://www.blogger.com/atom/ns#' term='stack traces'/><category scheme='http://www.blogger.com/atom/ns#' term='tracing'/><title type='text'>Linguistic tools for diagnostics</title><content type='html'>I've written before about how &lt;a href="http://calculist.blogspot.com/2006/03/call-stack-is-not-history.html"&gt;the stack gets misunderstood as a history&lt;/a&gt; thanks to non-tail-recursive languages. Of course, stack traces are indispensable: they're essential for debugging, and they're also useful for reporting crash information from live applications.&lt;br /&gt;&lt;br /&gt;But this conflates two very different language requirements in one feature: the need for nested (unbounded, if your language isn't broken) function application, and the need for diagnostics of dynamic errors.&lt;br /&gt;&lt;br /&gt;The first is what continuations and stacks are all about, of course: &lt;del&gt;functions can't call each other&lt;/del&gt; function calls can't be nested in compound expressions without the language runtime keeping track of the work it has left to do. But the second is an independent need: there's all sorts of diagnostic information that's potentially useful, and the stack just happens to be one source of information that's already there.&lt;br /&gt;&lt;br /&gt;Now, as it turns out, it's a pretty useful source of information. And if you happen &lt;span style="font-style: italic;"&gt;not&lt;/span&gt; to have proper tail recursion, it's even more useful, since it provides a path through the function call graph. But I've been finding stack traces in Scheme less informative, because with proper tail calls, there's less function-call history in the continuation.&lt;br /&gt;&lt;br /&gt;I recognize that sometimes the "complexity budget" in language design necessitates using one feature to satisfy multiple requirements. But I'd like to see more investigation of &lt;span style="font-style: italic;"&gt;linguistic diagnostics&lt;/span&gt; designed independently of existing language features. For example, it might be useful to provide configurable tracing facilities that record program history during runtime, where the tuning of how much gets recorded is completely independent of the space semantics of the evaluator. So you have a properly tail recursive semantics with a flexible tracing facility grafted on top.&lt;br /&gt;&lt;br /&gt;What classifies a language feature as "purely diagnostic" might be that it is designed not to &lt;span style="font-style: italic;"&gt;change&lt;/span&gt; the observable behavior of the program, but merely to &lt;span style="font-style: italic;"&gt;report&lt;/span&gt; some additional information. &lt;a href="http://www.ece.northwestern.edu/%7Erobby/pubs/papers/fb-tr2006-01.pdf"&gt;Contracts-as-projections&lt;/a&gt; is an example.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Update:&lt;/span&gt; rephrased my rookie characterization of continuations.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-2397896808716575435?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/2397896808716575435/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=2397896808716575435' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/2397896808716575435'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/2397896808716575435'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/07/linguistic-tools-for-diagnostics.html' title='Linguistic tools for diagnostics'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-3086355391832421729</id><published>2009-07-13T23:03:00.004-04:00</published><updated>2009-07-13T23:07:04.712-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='regular trees'/><category scheme='http://www.blogger.com/atom/ns#' term='infinite trees'/><category scheme='http://www.blogger.com/atom/ns#' term='contractive'/><title type='text'>Contractiveness not required for regularity</title><content type='html'>&lt;a href="http://calculist.blogspot.com/2009/07/regular-subtree-set-finiteness.html"&gt;Yesterday&lt;/a&gt; I wrote about ensuring termination of subtyping for equirecursive types that I thought contractiveness ensures that the (potentially) infinite tree corresponding to a recursive type is regular. That was wrong. Contractiveness just ensures that you can't represent types that don't have a corresponding tree, such as &amp;mu;&lt;span style="font-style: italic;"&gt;A&lt;/span&gt;.&lt;span style="font-style: italic;"&gt;A&lt;/span&gt;. The fact that the tree is regular comes from the fact that the syntactic representation is finite and substitution doesn't add anything new.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-3086355391832421729?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/3086355391832421729/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=3086355391832421729' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/3086355391832421729'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/3086355391832421729'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/07/contractiveness-not-required-for.html' title='Contractiveness not required for regularity'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-7623564499261486112</id><published>2009-07-12T17:13:00.004-04:00</published><updated>2009-07-12T17:26:36.435-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='termination'/><category scheme='http://www.blogger.com/atom/ns#' term='equirecursive types'/><category scheme='http://www.blogger.com/atom/ns#' term='TAPL'/><category scheme='http://www.blogger.com/atom/ns#' term='recursive types'/><title type='text'>Regular =&gt; Subtree set finiteness =&gt; Termination of memoized algorithm</title><content type='html'>The termination argument behind the &lt;a href="http://www.cis.upenn.edu/%7Ebcpierce/tapl/"&gt;TAPL&lt;/a&gt; algorithm for subtyping of equirecursive types is not as scary as it sounds (or as it sounded to me, anyway). It's as simple as this: even though the subtyping rules generate bigger types when they substitute a recursive type into its own body, the fact that the types are &lt;span style="font-style: italic;"&gt;regular&lt;/span&gt; means that there are only a finite number of distinct subterms in the infinite type tree--that's the definition of regular trees. So as long as you keep a cache of types you've looked at before and never have to look at the same pair of types twice, you can't do an infinite number of checks.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.boston.com/ae/theater_arts/exhibitionist/Great%20Depression%20Unemployment%20Line.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 358px; height: 263px;" src="http://www.boston.com/ae/theater_arts/exhibitionist/Great%20Depression%20Unemployment%20Line.JPG" alt="" border="0" /&gt;&lt;/a&gt;&lt;span style="font-style: italic;font-size:85%;" &gt;(Eventually, you run out of work.)&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;If I'm not mistaken, the syntactic restriction that types are &lt;span style="font-style: italic;"&gt;contractive&lt;/span&gt;, i.e., recursive type variables have to appear under constructors, is sufficient to guarantee that the corresponding type trees are regular.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-7623564499261486112?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/7623564499261486112/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=7623564499261486112' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/7623564499261486112'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/7623564499261486112'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/07/regular-subtree-set-finiteness.html' title='Regular =&gt; Subtree set finiteness =&gt; Termination of memoized algorithm'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-5833831425202675245</id><published>2009-07-09T00:04:00.005-04:00</published><updated>2009-07-09T02:15:07.149-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='announcements'/><title type='text'>Call for Participation: Symposium in Honor of Mitchell Wand</title><content type='html'>&lt;div style="text-align: center;"&gt;&lt;span style="font-weight: bold;"&gt;Symposium in Honor of Mitchell Wand&lt;/span&gt;&lt;br /&gt;In Cooperation with ACM SIGPLAN&lt;br /&gt;Coordinated with &lt;a href="http://www.schemeworkshop.org/2009"&gt;Scheme Workshop 2009&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;August 23-24, 2009&lt;br /&gt;Boston, Massachusetts, USA&lt;br /&gt;&lt;a href="http://www.ccs.neu.edu/events/wand-symposium"&gt;http://www.ccs.neu.edu/events/wand-symposium&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-weight: bold;"&gt;CALL FOR PARTICIPATION&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;IMPORTANT DATES&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;August 1, 2009 - Registration deadline&lt;br /&gt;August 22, 2009 - &lt;a href="http://www.schemeworkshop.org/2009"&gt;Scheme Workshop&lt;/a&gt;&lt;br /&gt;August 23-24, 2009 - &lt;a href="http://www.ccs.neu.edu/events/wand-symposium"&gt;Symposium in Honor of Mitchell Wand&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;VENUE&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Northeastern University&lt;br /&gt;346 Huntington Ave&lt;br /&gt;Boston, MA 02115 USA&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;ACCOMMODATION&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A limited block of hotel rooms will be reserved for participants of the Symposium and/or the Scheme Workshop at hotels in Boston and Cambridge. More information will be available soon; please check back on the event web site.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;REGISTRATION&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Registration is free. Please register by &lt;span style="font-weight: bold;"&gt;August 1, 2009&lt;/span&gt; so that we will have an accurate head count. To register, please send an email to &lt;a href="mailto:mitchfest-registration@ccs.neu.edu"&gt;mitchfest-registration@ccs.neu.edu&lt;/a&gt; with your name and any dietary restrictions for lunch.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;SCOPE&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Northeastern University is hosting a special Symposium in celebration of Dr. Mitchell Wand's 60th birthday and honoring his pioneering work in the field of programming languages. For over 30 years Mitch has made important contributions to many areas of programming languages, including semantics, continuations, type theory, hygienic macros, compiler correctness, static analysis and formal verification.&lt;br /&gt;&lt;br /&gt;Please join us at Northeastern on August 23rd and 24th as we celebrate this personal milestone and pay tribute to a great computer scientist, researcher, teacher and colleague, Dr. Mitchell (Mitch) Wand.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;STEERING COMMITTEE&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;* Olivier Danvy (University of Aarhus)&lt;br /&gt;* David Herman (Northeastern University)&lt;br /&gt;* Dino Oliva (Bloomberg L.P.)&lt;br /&gt;* Olin Shivers (Northeastern University)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;PRELIMINARY PROGRAM&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Functional un|unparsing&lt;/span&gt;&lt;br /&gt;  Kenichi Asai and Oleg Kiselyov and Chung-chieh Shan&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;A mechanized bisimulation for the nu-calculus&lt;/span&gt;&lt;br /&gt;  Nick Benton and Vasileios Koutavas&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;A shallow Scheme embedding of bottom-avoiding streams&lt;/span&gt;&lt;br /&gt;  William E. Byrd and Daniel P. Friedman and Ramana Kumar and Joseph P. Near&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;A model of functional traversal-based generic programming&lt;/span&gt;&lt;br /&gt;  Bryan Chadwick and Karl Lieberherr&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;The MacScheme compiler: using denotational semantics to prove correctness &lt;/span&gt;&lt;br /&gt;  William D. Clinger&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Eliminating the middle man: Learning garbage collection without interpreters&lt;/span&gt;&lt;br /&gt;  Gregory H. Cooper and Arjun Guha and Shriram Krishnamurthi&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Specializing continuations&lt;/span&gt;&lt;br /&gt;  Christopher Dutchyn&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;A Scheme for native threads&lt;/span&gt;&lt;br /&gt;  R. Kent Dybvig&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Trampolining architectures&lt;/span&gt;&lt;br /&gt;  Steven E. Ganz and Daniel P. Friedman&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Finding everything that can happen: Solving authentication tests by computer&lt;/span&gt;&lt;br /&gt;  Joshua D. Guttman and John D. Ramsdell&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;A theory of typed hygienic macros&lt;/span&gt;&lt;br /&gt;  David Herman&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;The MzScheme machine and bytecode verifier&lt;/span&gt;&lt;br /&gt;  Casey L. Klein and Matthew Flatt and Robert Bruce Findler&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Featherweight X10: A core calculus for async-finish parallelism&lt;/span&gt;&lt;br /&gt;  Jonathan K. Lee and Jens Palsberg&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Subcubic control-flow analysis algorithms&lt;/span&gt;&lt;br /&gt;  Jan Midtgaard and David Van Horn&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;A simplified multi-tier semantics for Hop&lt;/span&gt;&lt;br /&gt;  Manuel Serrano and Christian Queinnec&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;DDP for CFA&lt;/span&gt;&lt;br /&gt;  Olin Shivers and Dimitrios Vardoulakis and Alexander Spoon&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;The design and implementation of Typed Scheme&lt;/span&gt;&lt;br /&gt;  Sam Tobin-Hochstadt and Matthias Felleisen&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-5833831425202675245?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/5833831425202675245/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=5833831425202675245' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/5833831425202675245'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/5833831425202675245'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/07/call-for-participation-symposium-in.html' title='Call for Participation: Symposium in Honor of Mitchell Wand'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-8122399154020718605</id><published>2009-05-15T11:20:00.004-04:00</published><updated>2009-05-15T11:26:56.973-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lexical syntax'/><category scheme='http://www.blogger.com/atom/ns#' term='mathematical notation'/><title type='text'>Lexical syntax thought</title><content type='html'>We reserve the single-quote character (&lt;span style="font-family:courier new;"&gt;#\'&lt;/span&gt;) in the Scheme lexical syntax so that it can't be used anywhere in an identifier. If you stick it in the middle of an identifier (e.g., &lt;span style="font-family:courier new;"&gt;foo'bar&lt;/span&gt;) it lexes as three tokens (&lt;span style="font-family:courier new;"&gt;"foo"&lt;/span&gt;, &lt;span style="font-family:courier new;"&gt;"'"&lt;/span&gt;, &lt;span style="font-family:courier new;"&gt;"bar"&lt;/span&gt;). But I don't recall ever seeing anyone make use of this fact; they always stick a space before the quote.&lt;br /&gt;&lt;br /&gt;I really miss my precious "prime" character in ML and Haskell identifiers (&lt;span style="font-family:courier new;"&gt;let val state' = munge state ...&lt;/span&gt;). Scheme prides itself on a permissive lexical syntax for identifiers. Why couldn't we allow quote characters in all positions of an identifier other than the first?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;P.S.&lt;/span&gt; I know I can use the &lt;a href="http://www.fileformat.info/info/unicode/char/2032/index.htm"&gt;Unicode prime character&lt;/a&gt; (U+2032). Sorry, not till I get &lt;a href="http://calculist.blogspot.com/2008/12/i-want-my-unicode-keyboard.html"&gt;my Unicode keyboard&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-8122399154020718605?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/8122399154020718605/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=8122399154020718605' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/8122399154020718605'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/8122399154020718605'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/05/lexical-syntax-thought.html' title='Lexical syntax thought'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-3559153625089435367</id><published>2009-05-15T07:42:00.003-04:00</published><updated>2009-05-15T07:50:59.725-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='semi-persistent data structures'/><category scheme='http://www.blogger.com/atom/ns#' term='backtracking'/><title type='text'>Follow-up on effect masking and backtracking</title><content type='html'>A follow-up on yesterday's post about &lt;a href="http://calculist.blogspot.com/2009/05/effect-masking-vs-purity.html"&gt;backtracking with state&lt;/a&gt;: an anonymous commenter &lt;a href="http://calculist.blogspot.com/2009/05/effect-masking-vs-purity.html?showComment=1242378540000#c2131052140250737829"&gt;reminded me&lt;/a&gt; that persistent data structures are a useful and lightweight (compared to e.g. first-class stores) approach. In fact, probably my favorite paper from &lt;a href="http://esop2008.doc.ic.ac.uk/"&gt;ESOP 2008&lt;/a&gt; was Conchon and Filli&amp;acirc;tre's &lt;a href="http://www.lri.fr/%7Efilliatr/ftp/publis/spds-esop08.pdf"&gt;Semi-Persistent Data Structures&lt;/a&gt;, which was addressing exactly this problem. Rather than introducing an entirely transactional semantics for the language, it's just a data structure with a transactional interface.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-3559153625089435367?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/3559153625089435367/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=3559153625089435367' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/3559153625089435367'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/3559153625089435367'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/05/follow-up-on-effect-masking-and.html' title='Follow-up on effect masking and backtracking'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-220758637591513836</id><published>2009-05-15T07:25:00.004-04:00</published><updated>2009-05-15T07:40:15.442-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rethrowing'/><category scheme='http://www.blogger.com/atom/ns#' term='stack traces'/><category scheme='http://www.blogger.com/atom/ns#' term='continuation marks'/><category scheme='http://www.blogger.com/atom/ns#' term='conditional exception handling'/><category scheme='http://www.blogger.com/atom/ns#' term='exceptions'/><title type='text'>Continuation marks in exceptions</title><content type='html'>Rethrowing caught exceptions is an important idiom. In particular, there are lots of cases where it's important to &lt;span style="font-style: italic;"&gt;conditionally&lt;/span&gt; handle an exception by handling it and then rethrowing it. In ML, I believe it's the actual definition of pattern matching on particular exception types: the pattern matching is syntactic sugar for inspecting the caught exception and conditionally rethrowing it. In standard JavaScript it's the &lt;span style="font-style: italic;"&gt;only&lt;/span&gt; way to catch particular exception types, because there is no standard conditional handling form.&lt;br /&gt;&lt;br /&gt;But a useful feature of some exception systems, like in Java, is the association of a stack trace with an exception. But when you rethrow an exception, this involves a choice: do you want a stack trace to be associated with the original continuation that threw the exception, or the one that rethrew it? There are genuine use cases for both. But in Java, the implementers have to choose one or the other for you.&lt;br /&gt;&lt;br /&gt;PLT Scheme gives you the flexibility to choose for yourself. Exceptions are not special values in Scheme; there's an orthogonal way of reifying the control state. The PLT runtime stores stack trace information in a special continuation mark, so if you grab the &lt;a href="http://docs.plt-scheme.org/reference/contmarks.html#%28def._%28%28quote._%7E23%7E25kernel%29._current-continuation-marks%29%29"&gt;current continuation mark set&lt;/a&gt;, you've got your hands on a value that provides DrScheme's IDE with all the information it needs to visualize the continuation.&lt;br /&gt;&lt;br /&gt;The standard exception types in PLT Scheme are records with a field for the current continuation mark set. So when you conditionally rethrow an exception, you can either keep its version of the continuation marks, or functionally update it with the current continuation marks and throw that instead.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Afterthought:&lt;/span&gt; I think Java might have chosen something like a policy where an exception value saves its stack trace at the point where it's created. This gives you the ability to do both by either rethrowing the same exception (to keep the original stack trace) or wrapping the exception with a new one (to use the new stack trace). I still prefer the PLT Scheme approach, which makes the stack trace a first-class value and consequently more explicit.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-220758637591513836?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/220758637591513836/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=220758637591513836' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/220758637591513836'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/220758637591513836'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/05/continuation-marks-in-exceptions.html' title='Continuation marks in exceptions'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-5944780798443551725</id><published>2009-05-14T20:48:00.003-04:00</published><updated>2009-05-14T21:31:00.410-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mutation'/><category scheme='http://www.blogger.com/atom/ns#' term='monads'/><category scheme='http://www.blogger.com/atom/ns#' term='effect masking'/><category scheme='http://www.blogger.com/atom/ns#' term='effects'/><title type='text'>Effect masking vs. purity</title><content type='html'>I've been working for a while on an algorithm that involves two effects: mutation and backtracking. Implementation strategies for the two effects seem to have different economics. I'm working in the context of PLT Scheme, here, but I suspect my observations would be similar in other non-pure languages.&lt;br /&gt;&lt;br /&gt;For backtracking, I could implement the algorithm in a pure way using &lt;a href="ftp://ftp.ccs.neu.edu/pub/people/wand/papers/icfp-04.pdf"&gt;two continuations or the list monad&lt;/a&gt;. Or I could just use the built-in exceptions and exception handlers of PLT Scheme. For mutation, the choice is between store-passing or the built-in mutation of Scheme.&lt;br /&gt;&lt;br /&gt;I've tried abstracting these two effects out into a single monad for a completely pure implementation. There are downsides to this approach, though. For example, debuggers and stack traces are completely useless since most of the program control flow goes through &lt;span style="font-family:courier new;"&gt;unit&lt;/span&gt;, &lt;span style="font-family:courier new;"&gt;bind&lt;/span&gt;, and the myriad intermediate closures created by such a higher-order style of programming. Besides, an excessively higher-order style imposes real readability costs on a program. So for implementing backtracking, I find exceptions to be a more straightforward approach.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.dday.com/blog/wp-content/uploads/2009/02/man-on-wire.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 321px; height: 176px;" src="http://www.dday.com/blog/wp-content/uploads/2009/02/man-on-wire.jpg" alt="" border="0" /&gt;&lt;/a&gt;But as it turns out, the algorithm also needs to roll back mutations when it backtracks. So I simply &lt;span style="font-style: italic;"&gt;can't&lt;/span&gt; use mutation. I think this is one of the things that make mutation so unwieldy--there's typically no corresponding "masking" operation for a destructive update. Exceptions have handlers, continuations (sometimes) have delimiters-- even some I/O features come with effect masks: for example, in PLT Scheme you can override the &lt;a href="http://docs.plt-scheme.org/reference/port-ops.html#%28def._%28%28quote._%7E23%7E25kernel%29._current-output-port%29%29"&gt;&lt;span style="font-family:courier new;"&gt;current-output-port&lt;/span&gt;&lt;/a&gt; with a &lt;a href="http://docs.plt-scheme.org/reference/stringport.html"&gt;string port&lt;/a&gt; and capture a program's output. All of these allow you to bound the effects a computation can have, to put a sort of dynamic safety net around it. Not so for &lt;span style="font-family: courier new;"&gt;set!&lt;/span&gt;, &lt;span style="font-family: courier new;"&gt;vector-set!&lt;/span&gt;, &lt;span style="font-family: courier new;"&gt;set-box!&lt;/span&gt;, or &lt;span style="font-family: courier new;"&gt;set-&lt;/span&gt;&lt;span style="font-style: italic;"&gt;record&lt;/span&gt;&lt;span style="font-family: courier new;"&gt;-&lt;/span&gt;&lt;span style="font-style: italic;"&gt;field&lt;/span&gt;&lt;span style="font-family: courier new;"&gt;!&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;So for mutation, I'm sticking with explicit store-passing-- not in monadic style. That seems to be the reasonable middle ground for my purposes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-5944780798443551725?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/5944780798443551725/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=5944780798443551725' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/5944780798443551725'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/5944780798443551725'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/05/effect-masking-vs-purity.html' title='Effect masking vs. purity'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-7036401118033907358</id><published>2009-05-11T17:17:00.003-04:00</published><updated>2009-05-11T17:22:52.845-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='control flow'/><category scheme='http://www.blogger.com/atom/ns#' term='backtracking'/><category scheme='http://www.blogger.com/atom/ns#' term='debugging'/><title type='text'>Representing failure</title><content type='html'>I'm working on an algorithm that uses backtracking implemented with exceptions and handlers (rather than, say, explicit continuations). I just noticed that, for debugging, it's nice to represent the failure exceptions as records that contain not just the data about the operation that failed but also an optional list of other failure exceptions. In the disjunction cases, I can save the intermediate failures and, if they all fail, include them in the resulting failure record. This provides me with a nice data structure representing the control flow of the failed search tree. It only required modifying about 3 lines of code and the resulting data structure is easier to analyze than a manual debugging sequence. (I hate working with debuggers, even good ones.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-7036401118033907358?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/7036401118033907358/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=7036401118033907358' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/7036401118033907358'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/7036401118033907358'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/05/representing-failure.html' title='Representing failure'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-7554904258800209317</id><published>2009-04-29T23:04:00.004-04:00</published><updated>2009-04-30T14:51:49.008-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='closure conversion'/><category scheme='http://www.blogger.com/atom/ns#' term='existential types'/><title type='text'>Typed closure conversion</title><content type='html'>&lt;a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.47.86"&gt;Typed closure conversion&lt;/a&gt; is a really lovely explanation of the structure of a closure-converted function. Every closure has its own particular environment structure that binds the particular set of free variables that occur in its body. But this means that if you represent a closure directly as a pair of an environment record and a closed procedure (which is explicitly parameterized over the environment record), then the representations of functions that are supposed to have the same type can end up with incompatible environment types. For example, the program&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;let val y = 1&lt;br /&gt;in&lt;br /&gt;  if true then&lt;br /&gt;      λx.x+y&lt;br /&gt;  else&lt;br /&gt;      λz.z&lt;br /&gt;end&lt;/pre&gt;&lt;/blockquote&gt;converts naively to the transparent representation&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;let val y = 1&lt;br /&gt;in&lt;br /&gt;  if true then&lt;br /&gt;      (λ(env, x).x+#y(env), {y=y})&lt;br /&gt;  else&lt;br /&gt;      (λ(env,z).z, {})&lt;br /&gt;end&lt;/pre&gt;&lt;/blockquote&gt;The problem here is the type of the environment has leaked information about the internals of the procedure into the external interface. So &lt;a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.47.86"&gt;Minamide et al&lt;/a&gt; use existential types as a nice, lightweight type abstraction for hiding the environment layout as an abstract type. So you instead get the opaque representation&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;let val y = 1&lt;br /&gt;in&lt;br /&gt;  if true then&lt;br /&gt;      pack {y:int} with (λ(env,x).x+#y(env), {y=y})&lt;br /&gt;      as ∃t.((t × int) → int) × t&lt;br /&gt;  else&lt;br /&gt;      pack {} with (λ(env,z).z, {})&lt;br /&gt;      as ∃t.((t × int) → int) × t&lt;br /&gt;end&lt;/pre&gt;&lt;/blockquote&gt;&lt;span style="font-weight: bold;"&gt;Update:&lt;/span&gt; fixed the types in the existentials-- since I'm using an uncurried representation the argument type is a pair, not an arrow type.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-7554904258800209317?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/7554904258800209317/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=7554904258800209317' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/7554904258800209317'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/7554904258800209317'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/04/typed-closure-conversion.html' title='Typed closure conversion'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-8513542986195310812</id><published>2009-04-18T15:59:00.004-04:00</published><updated>2009-04-18T16:10:30.563-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='systems'/><category scheme='http://www.blogger.com/atom/ns#' term='module name resolver'/><category scheme='http://www.blogger.com/atom/ns#' term='plt-scheme'/><title type='text'>PLT System Facilities (Software Components): Module name resolvers</title><content type='html'>Because of &lt;a style="font-family: courier new;" href="http://docs.plt-scheme.org/reference/Evaluation_and_Compilation.html#%28def._%28%28quote._%7E23%7E25kernel%29._eval%29%29"&gt;eval&lt;/a&gt;, one program's "compile time" is another program's run-time. Even though they are not first-class, this also applies to &lt;a href="http://calculist.blogspot.com/2009/02/plt-system-facilities-software_19.html"&gt;PLT Scheme modules&lt;/a&gt;, since they too can be dynamically compiled, loaded and linked. As I've described before, &lt;a href="http://calculist.blogspot.com/2009/03/plt-system-facilities-software.html"&gt;namespaces&lt;/a&gt; are the general construct for managing multiple instances of modules and maintaining their top-level bindings. But I still haven't described how dynamic invocation of modules happens.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/__OULbbSCQyc/SeozI7VfblI/AAAAAAAAADA/--888YIXyis/s1600-h/800-yellow-pages.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 200px; height: 106px;" src="http://3.bp.blogspot.com/__OULbbSCQyc/SeozI7VfblI/AAAAAAAAADA/--888YIXyis/s200/800-yellow-pages.jpg" alt="" id="BLOGGER_PHOTO_ID_5326125737778835026" border="0" /&gt;&lt;/a&gt;Module loading is managed by the system's &lt;a href="http://docs.plt-scheme.org/reference/Module_Names_and_Loading.html#%28tech._module._name._resolver%29"&gt;&lt;span style="font-style: italic;"&gt;module name resolver&lt;/span&gt;&lt;/a&gt;. The primary responsibility of the module name resolver is to map distinct but equivalent &lt;span style="font-style: italic;"&gt;references&lt;/span&gt; to modules into canonical forms. For example, it's possible to refer to the PLT Scheme &lt;a href="http://docs.plt-scheme.org/reference/strings.html#%28mod-path._scheme/string%29"&gt;string library&lt;/a&gt; with either of the two forms:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;(lib "string.ss" "scheme")&lt;br /&gt;scheme/string&lt;/pre&gt;&lt;/blockquote&gt;The standard module name resolver translates these to an absolute path to the module's source file in the filesystem.&lt;br /&gt;&lt;br /&gt;The other responsibilities of the standard module name resolver are:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;to ensure that a module is only loaded once,&lt;/li&gt;&lt;li&gt;to make sure each module is loaded the first time it is needed, and&lt;/li&gt;&lt;li&gt;to check for and prevent cyclic loading dependencies between modules.&lt;/li&gt;&lt;/ul&gt;The module name resolver is a pretty low-level part of the PLT system. For the most part, programmers stick to using &lt;a href="http://docs.plt-scheme.org/reference/Module_Names_and_Loading.html#%28def._%28%28quote._%7E23%7E25kernel%29._dynamic-require%29%29"&gt;dynamic-require&lt;/a&gt; to interact with modules dynamically. This dynamically ensures a module is loaded and optionally selects one of its exports by name (by querying its &lt;a href="http://calculist.blogspot.com/2009/03/plt-system-facilities-software.html"&gt;namespace&lt;/a&gt;). But the module name resolver is directly accessible and can be dynamically invoked to ensure a module is loaded and resolve its name to canonical form. The module name resolver is even &lt;a href="http://docs.plt-scheme.org/reference/Module_Names_and_Loading.html#%28def._%28%28quote._%7E23%7E25kernel%29._current-module-name-resolver%29%29"&gt;configurable&lt;/a&gt;, and can be swapped out with a custom resolver--though I have not seen this done in user code.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-8513542986195310812?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/8513542986195310812/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=8513542986195310812' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/8513542986195310812'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/8513542986195310812'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/04/plt-system-facilities-software.html' title='PLT System Facilities (Software Components): Module name resolvers'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/__OULbbSCQyc/SeozI7VfblI/AAAAAAAAADA/--888YIXyis/s72-c/800-yellow-pages.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-4409130016126504439</id><published>2009-04-15T17:03:00.001-04:00</published><updated>2009-04-15T17:05:58.923-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SIGPLAN'/><category scheme='http://www.blogger.com/atom/ns#' term='publishing'/><title type='text'>Matthew Flatt running for SIGPLAN member-at-large</title><content type='html'>I like &lt;a href="http://www.acm.org/sigs/elections/SIGPLAN/MFlatt-MemberatLarge.pdf"&gt;Matthew's statement&lt;/a&gt;, so I want to call it out here:&lt;br /&gt;&lt;blockquote&gt;As a SIGPLAN member at large, I would be a voice for those who believe that conferences have become too important relative to journals. Our conferences have taken over the prestige that other disciplines reserve for journals, so that our conferences tend toward more conservative acceptances and more complex reviewing processes (including double-blind submission and author-response periods), which work against the goal of broadcasting new research directions and ambitious new ideas. In comparison, our journal system, which offers the time and expertise needed for the careful review of enduring results, is left under-used and under-supported (especially by paper referees) despite the admirable efforts of journal editors. I have no easy fixes, nor do I think that immediate radical change is appropriate, but I think we should do all we can to nudge the balance back in favor of journals.&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-4409130016126504439?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/4409130016126504439/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=4409130016126504439' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/4409130016126504439'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/4409130016126504439'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/04/matthew-flatt-running-for-sigplan.html' title='Matthew Flatt running for SIGPLAN member-at-large'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-2798746552429273469</id><published>2009-04-07T19:22:00.002-04:00</published><updated>2009-04-07T19:31:17.642-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Subversion'/><category scheme='http://www.blogger.com/atom/ns#' term='svn'/><title type='text'>Memo to myself: directions for `svn unfail'</title><content type='html'>Sorry for this-- I keep losing this information so I'm just sticking this note to myself up here. Who knows, if other people run into this it might be of use to them, too.&lt;br /&gt;&lt;br /&gt;If you find you're inexplicable being asked to authenticate when doing an &lt;span style="font-family: courier new;"&gt;svn up&lt;/span&gt; and it won't accept your password, (particularly after renaming or moving a file in the repository), &lt;a href="http://subversion.tigris.org/issues/show_bug.cgi?id=3242#desc20"&gt;here's the solution&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;blockquote style="font-family: courier new;"&gt;...if "svn up" doesn't work, you can make "svn switch" to the same url, it will update all with no problems.&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-2798746552429273469?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/2798746552429273469/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=2798746552429273469' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/2798746552429273469'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/2798746552429273469'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/04/memo-to-myself-directions-for-svn.html' title='Memo to myself: directions for `svn unfail&apos;'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-1474089686207967311</id><published>2009-04-01T20:14:00.003-04:00</published><updated>2009-04-01T20:22:23.420-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='email'/><category scheme='http://www.blogger.com/atom/ns#' term='resource contention'/><title type='text'>Dear David Herman</title><content type='html'>Dear David Herman,&lt;br /&gt;&lt;br /&gt;We have the same name. You seem to think you have my gmail address. Periodically I get email intended for you. It may be that you're giving out my address to people--or so I imagine, because every so often, I also get a message from Google saying that someone is initiating the process to reset my password. Naturally, I don't proceed. I don't want to reset my password. I'd prefer you stopped trying to.&lt;br /&gt;&lt;br /&gt;I have no particular way of contacting you, because all I know is that your name is my name too, and I think you live in San Francisco (based on your mail that I've received). Which is all the more confusing, given that I spend a lot of time in the Bay Area. But I digress.&lt;br /&gt;&lt;br /&gt;Mr. Herman, I'm afraid we can't share this gmail account. You seem to like the version without a dot, whereas I prefer the version with a dot, but either way, &lt;a href="http://mail.google.com/support/bin/answer.py?hl=en&amp;amp;answer=10313#"&gt;Google says it's mine&lt;/a&gt;. Sorry. I got there first.&lt;br /&gt;&lt;br /&gt;Best regards,&lt;br /&gt;David Herman&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-1474089686207967311?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/1474089686207967311/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=1474089686207967311' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/1474089686207967311'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/1474089686207967311'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/04/dear-david-herman.html' title='Dear David Herman'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-8733462885121739958</id><published>2009-03-31T12:11:00.003-04:00</published><updated>2009-03-31T12:17:58.934-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='equivalence'/><category scheme='http://www.blogger.com/atom/ns#' term='research landscape'/><category scheme='http://www.blogger.com/atom/ns#' term='figures'/><title type='text'>Your lambda-cube is puny.</title><content type='html'>&lt;a href="http://www.ccs.neu.edu/home/turon/"&gt;Aaron&lt;/a&gt; just showed me this mind-blowing figure from a paper by &lt;a href="http://theory.stanford.edu/%7Ervg/"&gt;van Glabbeek&lt;/a&gt; that attempts to &lt;a href="http://theory.stanford.edu/%7Ervg/abstracts.html#26"&gt;abstract the wide variety of notions of equivalence&lt;/a&gt; in the concurrency literature:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/__OULbbSCQyc/SdJB6JXcDlI/AAAAAAAAAC4/1GsrP7WuDFE/s1600-h/map2.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 240px; height: 320px;" src="http://1.bp.blogspot.com/__OULbbSCQyc/SdJB6JXcDlI/AAAAAAAAAC4/1GsrP7WuDFE/s320/map2.png" alt="" id="BLOGGER_PHOTO_ID_5319386577080421970" border="0" /&gt;&lt;/a&gt;A moment of respectful silence, please.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-8733462885121739958?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/8733462885121739958/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=8733462885121739958' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/8733462885121739958'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/8733462885121739958'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/03/your-lambda-cube-is-puny.html' title='Your lambda-cube is puny.'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/__OULbbSCQyc/SdJB6JXcDlI/AAAAAAAAAC4/1GsrP7WuDFE/s72-c/map2.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-7746762400087139154</id><published>2009-03-31T10:20:00.005-04:00</published><updated>2009-03-31T10:39:25.939-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='informal notation'/><title type='text'>Hand-writing derivations</title><content type='html'>I've come to prefer one particular approach to writing out a derivation tree by hand. I used to try to draw the tree by stacking up rules with horizontal separators à la Gentzen, but I could never judge how much space I would need--I'm not accustomed to filling a page bottom to top--and one page never seemed to be enough anyway.&lt;br /&gt;&lt;br /&gt;I've found that writing judgments top to bottom, indenting to represent nesting, is much more scalable. E.g.:&lt;br /&gt;&lt;blockquote&gt;⊢ (λ f.f 1) (λ x.x) : int&lt;br /&gt;&amp;emsp;&amp;emsp;⊢ (λ f.f 1) : (int → int) → int&lt;br /&gt;&amp;emsp;&amp;emsp;&amp;emsp;&amp;emsp;f : int → int ⊢ f 1 : int&lt;br /&gt;&amp;emsp;&amp;emsp;&amp;emsp;&amp;emsp;&amp;emsp;&amp;emsp;f : int → int ⊢ f : int → int&lt;br /&gt;&amp;emsp;&amp;emsp;&amp;emsp;&amp;emsp;&amp;emsp;&amp;emsp;f : int → int ⊢ 1 : int&lt;br /&gt;&amp;emsp;&amp;emsp;⊢ (λ x.x) : int → int&lt;br /&gt;&amp;emsp;&amp;emsp;&amp;emsp;&amp;emsp;x : int ⊢ x : int&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-7746762400087139154?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/7746762400087139154/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=7746762400087139154' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/7746762400087139154'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/7746762400087139154'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/03/hand-writing-derivations.html' title='Hand-writing derivations'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-980317439121248698</id><published>2009-03-31T10:15:00.005-04:00</published><updated>2009-03-31T10:19:31.187-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='research progress'/><title type='text'>Make a miniature model first</title><content type='html'>I've been taught this time and time again, I've seen &lt;a href="http://www.soe.ucsc.edu/%7Ecormac/"&gt;Cormac&lt;/a&gt; do it repeatedly in the ECMAScript design process, I've been told by &lt;a href="http://www.ccs.neu.edu/home/wand"&gt;Mitch&lt;/a&gt; repeatedly to do it, but it still hasn't become instinct for me: when you're facing a dauntingly large system, it's incredibly helpful to start by extracting coherent but manageably small subsets of the design and model them first. It's amazing how well that works to make a system less terrifying to work with.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-980317439121248698?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/980317439121248698/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=980317439121248698' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/980317439121248698'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/980317439121248698'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/03/make-miniature-model-first.html' title='Make a miniature model first'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-5041265152359618442</id><published>2009-03-16T20:12:00.004-04:00</published><updated>2009-03-16T21:18:26.439-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='systems'/><category scheme='http://www.blogger.com/atom/ns#' term='namespace'/><category scheme='http://www.blogger.com/atom/ns#' term='plt-scheme'/><title type='text'>PLT System Facilities (Software Components): Namespaces</title><content type='html'>So far I've described PLT Scheme's &lt;a href="http://calculist.blogspot.com/2009/02/plt-system-facilities-software.html"&gt;first-class component systems&lt;/a&gt;, as well as the second-class, static &lt;a href="http://calculist.blogspot.com/2009/02/plt-system-facilities-software_19.html"&gt;module system&lt;/a&gt;.  Of course, Scheme is a reflective language. Where there's &lt;a href="http://docs.plt-scheme.org/reference/Evaluation_and_Compilation.html#%28def._%28%28quote._%7E23%7E25kernel%29._eval%29%29"&gt;&lt;span style="font-family: courier new;"&gt;eval&lt;/span&gt;&lt;/a&gt;, there's not just one "compile time." Code can be compiled and evaluated at any time during the execution of a PLT Scheme virtual environment.&lt;br /&gt;&lt;br /&gt;Moreover, considering that one of the most important applications written in PLT Scheme--&lt;a href="http://www.plt-scheme.org/software/drscheme/"&gt;DrScheme&lt;/a&gt;--is an IDE, it's clearly important to be able to load and reload a single module multiple times. Users have to be able to edit a module and re-evaluate it without restarting the Scheme image. (In fact, it's even possible to run DrScheme from DrScheme, so it must even be possible to have multiple instances of the same module running concurrently!)&lt;br /&gt;&lt;br /&gt;Every instance of a module in a running PLT Scheme environment has associated with it a &lt;a href="http://docs.plt-scheme.org/reference/syntax-model.html#%28part._namespace-model%29"&gt;&lt;span style="font-style: italic;"&gt;namespace&lt;/span&gt;&lt;/a&gt;. Namespaces serve two somewhat orthogonal purposes. The first is to store top-level bindings. A module's namespace contains the mapping of its global definitions (some of which may be made available to other modules via &lt;a href="http://docs.plt-scheme.org/guide/module-provide.html"&gt;&lt;span style="font-family: courier new;"&gt;provide&lt;/span&gt;&lt;/a&gt;). There is also a namespace associated with the REPL, which can be dynamically modified; in DrScheme, that namespace is typically just the one associated with the current running instance of the module being edited. In a sense, this role of namespaces is to mediate between the static, segmented architecture of modules and the dynamic, global nature of the Scheme top-level. This is an interesting tension that comes in whenever designing a lexically scoped language with dynamic code evaluation such as with &lt;a href="http://docs.plt-scheme.org/reference/Evaluation_and_Compilation.html#%28def._%28%28quote._%7E23%7E25kernel%29._eval%29%29"&gt;&lt;span style="font-family: courier new;"&gt;eval&lt;/span&gt;&lt;/a&gt; or a REPL.&lt;br /&gt;&lt;br /&gt;The second purpose of namespaces is to maintain an internal &lt;a href="http://docs.plt-scheme.org/reference/syntax-model.html#%28tech._module._registry%29"&gt;&lt;span style="font-style: italic;"&gt;module registry&lt;/span&gt;&lt;/a&gt;, which keeps track of running instances of modules. Every namespace has its own registry, but registries may share instances. This is how it's possible both to create multiple, isolated instances of modules and to share module instances and their associated state.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-5041265152359618442?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/5041265152359618442/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=5041265152359618442' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/5041265152359618442'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/5041265152359618442'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/03/plt-system-facilities-software.html' title='PLT System Facilities (Software Components): Namespaces'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-2254527288779123295</id><published>2009-03-07T16:59:00.003-05:00</published><updated>2009-03-07T17:11:25.916-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='invariants'/><category scheme='http://www.blogger.com/atom/ns#' term='correctness'/><category scheme='http://www.blogger.com/atom/ns#' term='learning process'/><title type='text'>Cognitive dissonance and correctness</title><content type='html'>I don't pretend to be a psychologist, but I find the mental process of getting a program correct fascinating. It feels like the process goes something like this:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Cognitive dissonance ("this can't possibly always work, can it?")&lt;/li&gt;&lt;li&gt;Confronting the danger ("what might go wrong?")&lt;/li&gt;&lt;li&gt;Questioning assumptions ("what am I assuming, and why do I need to assume it?")&lt;/li&gt;&lt;li&gt;Codifying assumptions as invariants ("&lt;span style="font-style: italic;"&gt;P&lt;/span&gt;")&lt;/li&gt;&lt;li&gt;Pushing invariants through the program ("&amp;forall;&lt;span style="font-style: italic;"&gt;x&lt;/span&gt;. &lt;span style="font-style: italic;"&gt;P&lt;/span&gt;(&lt;span style="font-style: italic;"&gt;x&lt;/span&gt;)")&lt;/li&gt;&lt;/ol&gt;There are lots of techniques for #5, of course, and modularity helps make it manageable; e.g., defensively add in checks to enforce &lt;span style="font-style: italic;"&gt;P&lt;/span&gt; so it's safe to assume.&lt;br /&gt;&lt;br /&gt;But the interesting part to me is really the fact that, if you have the discipline to follow it through, it's precisely that queasy feeling that something might go wrong that eventually leads you to discover the program's invariants and ultimately to get the program right.&lt;br /&gt;&lt;br /&gt;I mentioned this to Mitch, and he added "it's that recognition of danger (#1) that keeps us honest."&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-2254527288779123295?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/2254527288779123295/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=2254527288779123295' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/2254527288779123295'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/2254527288779123295'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/03/cognitive-dissonance-and-correctness.html' title='Cognitive dissonance and correctness'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-6951076299821437971</id><published>2009-03-05T07:20:00.002-05:00</published><updated>2009-03-05T07:24:52.820-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='empty string'/><category scheme='http://www.blogger.com/atom/ns#' term='corner cases'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><title type='text'>'s Birthday is Coming Up...</title><content type='html'>I wonder if early in life, 's parents used to call him/her little baby epsilon.&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/__OULbbSCQyc/Sa_EOqFvraI/AAAAAAAAACw/eV1iOQCUqkc/s1600-h/blank.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 359px;" src="http://3.bp.blogspot.com/__OULbbSCQyc/Sa_EOqFvraI/AAAAAAAAACw/eV1iOQCUqkc/s400/blank.png" alt="" id="BLOGGER_PHOTO_ID_5309678241788702114" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-6951076299821437971?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/6951076299821437971/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=6951076299821437971' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/6951076299821437971'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/6951076299821437971'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/03/s-birthday-is-coming-up.html' title='&apos;s Birthday is Coming Up...'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/__OULbbSCQyc/Sa_EOqFvraI/AAAAAAAAACw/eV1iOQCUqkc/s72-c/blank.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-93742989448011178</id><published>2009-02-20T16:36:00.004-05:00</published><updated>2009-02-20T16:41:03.913-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cool technology'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><title type='text'>Whoa</title><content type='html'>This is a really neat new feature of the &lt;a href="http://www.lib.neu.edu/"&gt;Northeastern University library&lt;/a&gt; catalog:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/__OULbbSCQyc/SZ8jJtD8e2I/AAAAAAAAACc/Rdcq0j1VuI8/s1600-h/txt.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 244px;" src="http://4.bp.blogspot.com/__OULbbSCQyc/SZ8jJtD8e2I/AAAAAAAAACc/Rdcq0j1VuI8/s400/txt.png" alt="" id="BLOGGER_PHOTO_ID_5304997535687670626" border="0" /&gt;&lt;/a&gt;Unless you spend the next 10 minutes taking screen shots and blogging about it, this is really convenient. And it saves our precious reserves of little scraps of paper.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-93742989448011178?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/93742989448011178/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=93742989448011178' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/93742989448011178'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/93742989448011178'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/02/whoa.html' title='Whoa'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/__OULbbSCQyc/SZ8jJtD8e2I/AAAAAAAAACc/Rdcq0j1VuI8/s72-c/txt.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-3094097007881235656</id><published>2009-02-19T14:38:00.002-05:00</published><updated>2009-02-20T09:49:51.239-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='systems'/><category scheme='http://www.blogger.com/atom/ns#' term='modules'/><category scheme='http://www.blogger.com/atom/ns#' term='plt-scheme'/><title type='text'>PLT System Facilities (Software Components): Modules</title><content type='html'>&lt;a href="http://calculist.blogspot.com/2009/02/plt-system-facilities-software.html"&gt;Lexical scope&lt;/a&gt; in general and &lt;span style="font-family:courier new;"&gt;lambda&lt;/span&gt; in particular go a long way towards supporting modular, separate development. As I mentioned before, PLT Scheme builds a number of first-class, module-like component systems on top of &lt;span style="font-family:courier new;"&gt;lambda&lt;/span&gt;. But it also contains a more primitive &lt;a href="http://docs.plt-scheme.org/reference/module.html"&gt;module system&lt;/a&gt; in which modules are &lt;span style="font-style: italic;"&gt;not&lt;/span&gt; first-class. This serves a number of purposes.&lt;br /&gt;&lt;br /&gt;First of all, static modules provide systematic support for packaging, compiling, and deploying code. First-class modules are flexible and expressive, but they don't have anything to say about compilation and deployment. Somewhere along the line there has to be a notion of what the compiler takes as input, and when you have separate development, you need separate deployment and ideally separate compilation.&lt;br /&gt;&lt;br /&gt;Another critical purpose of static modules is the ability to modularize static entities in a language. In ML, for example, modules can import and export types. Scheme is of course more [&lt;span style="font-style: italic;"&gt;ed:&lt;/span&gt; dynamic] than ML, but it still has its own crucial compile-time abstractions: macros. With dynamic modules, there's no straightforward way to import and export static entities like macros. A secondary benefit of static modules is that you can import all the bindings from another module at once without having to spell them all out; this is admittedly less important but still very convenient.&lt;br /&gt;&lt;br /&gt;Finally, PLT Scheme was designed to support multiple languages. For pedagogical purposes, this has allowed them to design multiple, concentric subsets of the language tailored to the &lt;a href="http://www.htdp.org/"&gt;How to Design Programs&lt;/a&gt; curriculum. This has also facilitated language research by making it easy to design and implement new languages (by macro-compiling them to Scheme) and to research language interactions in a multi-language environment. The relevant piece of the module system is a single hook at the beginning of a module definition: the grammar of a module is an S-expression containing the symbol &lt;span style="font-family:courier new;"&gt;module&lt;/span&gt;, a symbol naming the module, and an S-expression indicating the language of the body:&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-family:courier new;"&gt;(module foo scheme &lt;/span&gt;&lt;span style="font-style: italic;"&gt;body ...&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;)&lt;/span&gt;&lt;/blockquote&gt;Typically the language chosen is the special built-in language &lt;a href="http://docs.plt-scheme.org/reference/index.html"&gt;&lt;span style="font-family:courier new;"&gt;scheme&lt;/span&gt;&lt;/a&gt;, as above, or the somewhat leaner &lt;span style="font-family:courier new;"&gt;scheme/base&lt;/span&gt;. But the language position works by simply importing another module that implements the required macros for compiling the body. In place of &lt;span style="font-family:courier new;"&gt;scheme&lt;/span&gt;, you can put in a &lt;a href="http://docs.plt-scheme.org/reference/Module_Names_and_Loading.html#%28tech._module._path%29"&gt;module path&lt;/a&gt; for any module installed on the system.&lt;br /&gt;&lt;br /&gt;It's also possible to specify a custom reader for a PLT language so it doesn't even have to be restricted to an S-expression syntax. The initial reader allows you to specify a language with the special shebang-like &lt;span style="font-family:courier new;"&gt;#lang&lt;/span&gt; syntax:&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-family:courier new;"&gt;#lang scheme/base&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;body ...&lt;/span&gt;&lt;/blockquote&gt;From that point on, the language's reader has access to the input stream to parse it any way it likes.&lt;br /&gt;&lt;br /&gt;Anyone can implement a language module, which means people have developed PLT implementations of Algol, Java, ML, and JavaScript, to name a few.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Update:&lt;/span&gt; Added in the missing word "dynamic" above. Also, this is a better link for &lt;a href="http://docs.plt-scheme.org/guide/module-paths.html"&gt;module paths&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Also, Sam is right in the comments: the &lt;span style="font-family:courier new;"&gt;scheme&lt;/span&gt; language really isn't special or built-in in any significant way. It's simply another module provided in the standard PLT collections.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-3094097007881235656?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/3094097007881235656/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=3094097007881235656' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/3094097007881235656'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/3094097007881235656'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/02/plt-system-facilities-software_19.html' title='PLT System Facilities (Software Components): Modules'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-5561961447162325995</id><published>2009-02-18T20:38:00.002-05:00</published><updated>2009-02-18T20:40:13.328-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Mac porn'/><title type='text'>Ooh, that's pretty</title><content type='html'>OS X calculator "programmer" view:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/__OULbbSCQyc/SZy4TabAoLI/AAAAAAAAACM/9FqdKFfvA6A/s1600-h/calc.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 320px;" src="http://4.bp.blogspot.com/__OULbbSCQyc/SZy4TabAoLI/AAAAAAAAACM/9FqdKFfvA6A/s320/calc.png" alt="" id="BLOGGER_PHOTO_ID_5304317104785236146" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-5561961447162325995?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/5561961447162325995/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=5561961447162325995' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/5561961447162325995'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/5561961447162325995'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/02/ooh-thats-pretty.html' title='Ooh, that&apos;s pretty'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/__OULbbSCQyc/SZy4TabAoLI/AAAAAAAAACM/9FqdKFfvA6A/s72-c/calc.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-7113357753892047977</id><published>2009-02-18T15:57:00.000-05:00</published><updated>2009-02-18T15:57:29.648-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='systems'/><category scheme='http://www.blogger.com/atom/ns#' term='lexical scope'/><category scheme='http://www.blogger.com/atom/ns#' term='plt-scheme'/><title type='text'>PLT System Facilities (Software Components): Lexical scope</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/__OULbbSCQyc/SZxuQKv-_OI/AAAAAAAAACE/8c9-z47TunY/s1600-h/yertle.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 141px; height: 320px;" src="http://1.bp.blogspot.com/__OULbbSCQyc/SZxuQKv-_OI/AAAAAAAAACE/8c9-z47TunY/s320/yertle.png" alt="" id="BLOGGER_PHOTO_ID_5304235685178178786" border="0" /&gt;&lt;/a&gt;Like any programming system, PLT Scheme involves multiple people and a lot of code. So managing software components is a primary concern. And of course, as a Scheme, PLT uses lexical scope as the linguistic linchpin for managing software. The importance of lexical scope in a component architecture is that it allows code to be shared and mixed while guaranteeing the internal integrity of components.&lt;br /&gt;&lt;br /&gt;With the power of macros, PLT has developed a number of software component abstractions on top of little &lt;span style="font-family: courier new;"&gt;lambda&lt;/span&gt;. One of these is a single-inheritance, class- and interface-based &lt;a href="http://docs.plt-scheme.org/reference/mzlib_class.html"&gt;OOP system&lt;/a&gt;. Classes are first-class values, which means it's easy to implement &lt;a href="http://docs.plt-scheme.org/reference/mixins.html"&gt;mixins&lt;/a&gt; (i.e., classes parameterized over their superclass) as functions that return classes. More recently, they've introduced &lt;a href="http://docs.plt-scheme.org/reference/trait.html"&gt;traits&lt;/a&gt;, which are like fragments of classes that can be more freely and flexibly combined than mixins. Also built with macros is the &lt;a href="http://docs.plt-scheme.org/reference/mzlib_unit.html"&gt;unit system&lt;/a&gt;, which is a first-class, parameterized, recursive module system.&lt;br /&gt;&lt;br /&gt;All of these abstractions admit modular and separate development because they protect the internal integrity of their local bindings and definitions. You can hand out a component into an untrusted context and know that it won't be able to modify or even inspect the component's internals. And you can reason locally about your code knowing that no context can change its behavior based on these internals.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-7113357753892047977?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/7113357753892047977/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=7113357753892047977' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/7113357753892047977'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/7113357753892047977'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/02/plt-system-facilities-software.html' title='PLT System Facilities (Software Components): Lexical scope'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/__OULbbSCQyc/SZxuQKv-_OI/AAAAAAAAACE/8c9-z47TunY/s72-c/yertle.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-6122949856958015862</id><published>2009-02-17T16:36:00.001-05:00</published><updated>2009-02-17T16:39:56.130-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='systems'/><category scheme='http://www.blogger.com/atom/ns#' term='plt-scheme'/><title type='text'>The PLT Scheme Operating System</title><content type='html'>Back in the day, programming languages were considered a systems concern. These days a lot of PL research is done in a vacuum, with abstract models and stand-alone prototypes. But programming languages rise and fall by their applications, and the deployment of a language always involves interesting and non-trivial systems challenges.&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://www.plt-scheme.org"&gt;PLT&lt;/a&gt; group has done a ton of work in this area. A decade ago, &lt;a href="http://www.cs.utah.edu/%7Emflatt/"&gt;Matthew&lt;/a&gt;, &lt;a href="http://www.ece.northwestern.edu/%7Erobby/"&gt;Robby&lt;/a&gt;, &lt;a href="http://www.cs.brown.edu/%7Esk/"&gt;Shriram&lt;/a&gt; and &lt;a href="http://www.ccs.neu.edu/home/matthias/"&gt;Matthias&lt;/a&gt; wrote an ICFP paper on &lt;a href="http://www.ccs.neu.edu/scheme/pubs/index.html#icfp99-ffkf"&gt;Programming Languages as Operating Systems&lt;/a&gt;, sketching a few of the highlights of the PLT virtual machine. They focused on MrEd, the GUI engine. But taking a step back, there are many more systems-y facilities in PLT Scheme than just the UI infrastructure. And of course, that paper is a decade old and beginning to show its age.&lt;br /&gt;&lt;br /&gt;I'm planning to write a series of posts on some of the myriad systems facilities in PLT Scheme and how they fit together.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-6122949856958015862?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/6122949856958015862/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=6122949856958015862' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/6122949856958015862'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/6122949856958015862'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/02/plt-scheme-operating-system.html' title='The PLT Scheme Operating System'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-8800208286755053577</id><published>2009-02-16T13:05:00.004-05:00</published><updated>2009-02-16T13:12:11.876-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C'/><category scheme='http://www.blogger.com/atom/ns#' term='brain damage'/><category scheme='http://www.blogger.com/atom/ns#' term='syntax'/><title type='text'>I feel much better about myself</title><content type='html'>I'd always felt stupid for being stymied by the syntax of C declarations. But I think I get it now.&lt;br /&gt;&lt;br /&gt;First of all, you have to understand that a C declaration starts with one single base type followed by a sequence of fragments of declarations; you essentially can interpret this as a sequence of separate declarations, each created by plugging the base type into each separate fragment. Syntactically, the "hole" inside each fragment actually contains the name of the identifier being bound; conceptually, you pull out that identifier and bind it to the type you get by plugging the base type into the position where you found the identifier.&lt;br /&gt;&lt;br /&gt;For example:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;int x, *y, z[3];&lt;/pre&gt;&lt;/blockquote&gt;declares an &lt;span style="font-family: courier new;"&gt;int&lt;/span&gt; &lt;span style="font-style: italic;"&gt;x&lt;/span&gt;, an &lt;span style="font-family: courier new;"&gt;int&lt;/span&gt; pointer &lt;span style="font-style: italic;"&gt;y&lt;/span&gt;, and an &lt;span style="font-family: courier new;"&gt;int&lt;/span&gt; array &lt;span style="font-style: italic;"&gt;z&lt;/span&gt;. Now for function types, the base type is interpreted as the return type; in other words, a fragment of a declaration of function type has its "hole" in the return type position. So:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;int x, f(char);&lt;/pre&gt;&lt;/blockquote&gt;declares an integer &lt;span style="font-style: italic;"&gt;x&lt;/span&gt; and a function &lt;span style="font-style: italic;"&gt;f&lt;/span&gt; of type &lt;span style="font-family: courier new;"&gt;char&lt;/span&gt; &amp;rarr; &lt;span style="font-family: courier new;"&gt;int&lt;/span&gt;. Next we have to worry about pointer types. Oh, pointer types. First of all, you have to know that pointer types in the declaration are associated with the fragments, not the base type. So:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;int *p, x;&lt;/pre&gt;&lt;/blockquote&gt;declares an &lt;span style="font-family: courier new;"&gt;int&lt;/span&gt; pointer &lt;span style="font-style: italic;"&gt;p&lt;/span&gt; and a plain &lt;span style="font-family: courier new;"&gt;int&lt;/span&gt; &lt;span style="font-style: italic;"&gt;x&lt;/span&gt;. Now, notice that the asterisk is a prefix operator, whereas the function and array type constructors are postfix operators. So now we get to worry about precedence. You just have to remember that the asterisk binds loosest. So:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;int *f(char);&lt;/pre&gt;&lt;/blockquote&gt;is a function that returns an &lt;span style="font-family: courier new;"&gt;int&lt;/span&gt; pointer, whereas&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;int (*f)(char);&lt;/pre&gt;&lt;/blockquote&gt;is a pointer to a function that returns an &lt;span style="font-family: courier new;"&gt;int&lt;/span&gt;. (You can throw in parentheses most anywhere in these things; forgot to mention that.) Okay, but here's the kicker: the nesting of type constructors is interpreted inside-out. Consider:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;int (*(foo[3]))(char);&lt;/pre&gt;&lt;/blockquote&gt;((Not that it helps, but I've over-parenthesized to avoid precedence issues.)) If you're still trying, you might be tempted to read this as declaring a function that returns an array of &lt;span style="font-family: courier new;"&gt;int&lt;/span&gt; pointers, or maybe a pointer to an array of &lt;span style="font-family: courier new;"&gt;int&lt;/span&gt;s. But the &lt;span style="font-style: italic;"&gt;inner-most&lt;/span&gt; syntactically nested type constructor is interpreted as the &lt;span style="font-style: italic;"&gt;outer-most&lt;/span&gt; semantically nested type constructor. So &lt;span style="font-family: courier new;"&gt;foo&lt;/span&gt; is in fact an array of pointers to functions.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-8800208286755053577?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/8800208286755053577/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=8800208286755053577' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/8800208286755053577'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/8800208286755053577'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/02/i-feel-much-better-about-myself.html' title='I feel much better about myself'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-5543310257503569107</id><published>2009-02-13T13:44:00.002-05:00</published><updated>2009-02-13T13:52:07.998-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='plt-dev'/><category scheme='http://www.blogger.com/atom/ns#' term='plt-scheme'/><title type='text'>My first PLT patch</title><content type='html'>I've submitted my first patch to the internals of PLT Scheme. It's a tiny thing: the ability to unquote inside a quasiquoted hash-table literal, e.g.:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&amp;gt; `#hash((x . ,(+ 1 2)))&lt;br /&gt;#hash((x . 3))&lt;/pre&gt;&lt;/blockquote&gt;And Matthew had to fix up some issues with it.&lt;br /&gt;&lt;br /&gt;But anyway, making contributions to PLT is easier these days due to a couple of factors. First, the creation of &lt;a href="http://list.cs.brown.edu/mailman/listinfo/plt-dev"&gt;plt-dev&lt;/a&gt;, a public mailing list for discussing the development of PLT Scheme, means that there's better support for people who want to contribute. Second, I'm told that more of the internals of PLT Scheme are self-hosted than apparently they used to be, i.e. a lot of PLT Scheme is itself implemented in PLT Scheme. This makes it a lot less scary to dive into the code.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-5543310257503569107?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/5543310257503569107/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=5543310257503569107' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/5543310257503569107'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/5543310257503569107'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/02/my-first-plt-patch.html' title='My first PLT patch'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-3114285557828140580</id><published>2009-02-13T09:40:00.003-05:00</published><updated>2009-02-13T10:03:06.437-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C'/><title type='text'>The C Typedef Parsing Problem</title><content type='html'>The well-known "&lt;a href="http://groups.google.com/group/comp.compilers/msg/c0797b5b668605b4"&gt;&lt;span style="font-family: courier new;"&gt;&lt;/span&gt;typedef problem&lt;/a&gt;" with &lt;a href="http://groups.google.com/group/comp.compilers/msg/9d8a968f346d24c0"&gt;parsing C&lt;/a&gt; is that the standard C grammar is ambiguous unless the lexer distinguishes identifiers bound by &lt;span style="font-family: courier new;"&gt;typedef&lt;/span&gt; and other identifiers as two separate lexical classes. This means that the parser needs to feed scope information to the lexer during parsing. One upshot is that lexing must be done concurrently with parsing. That's standard, although because parser generators usually allow fixed lookahead, you have to pay very close attention to making sure the lexer stays properly in synch with the parser, even when it gets ahead. For example:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;typedef int my_int;&lt;br /&gt;my_int x;&lt;/pre&gt;&lt;/blockquote&gt;At the semicolon, the type environment needs to be updated with an entry for &lt;span style="font-family: courier new;"&gt;my_int&lt;/span&gt;. But if the lexer has already looked ahead to &lt;span style="font-family: courier new;"&gt;my_int&lt;/span&gt;, it will have lexed it as an identifier rather than a type name. But this is just a small matter of heroic hacking.&lt;br /&gt;&lt;br /&gt;The real problem is a larger engineering one. Just to &lt;span style="font-style: italic;"&gt;parse&lt;/span&gt; a program, you need to have the full type environment. And the program you're parsing may have included other programs. So if you want to write tools that perform analyses on fragments of C, you still have to feed them the entire environment one way or another. Either that becomes a requirement you foist onto the user ("this tool takes two inputs: a fragment of C and an initial type environment"), or you only allow whole programs instead of fragments, or you use an ambiguous grammar with, say, a GLR parser and divine some clever disambiguation heuristics.&lt;br /&gt;&lt;br /&gt;And of course, C's braindead non-module-system is just a preprocessor directive (&lt;span style="font-family: courier new;"&gt;#include&lt;/span&gt;). So if you punt and require whole programs, that means you have to implement the C preprocessor, too. Or at least feed it through an existing implementation of the C preprocessor. And then process &lt;span style="font-family: courier new;"&gt;stdio.h&lt;/span&gt;, &lt;span style="font-family: courier new;"&gt;stdlib.h&lt;/span&gt;, etc. etc. every time you analyze just about any C program. So &lt;span style="font-style: italic;"&gt;then&lt;/span&gt; you start thinking about caching results of &lt;span style="font-family: courier new;"&gt;#include&lt;/span&gt; for efficiency...&lt;br /&gt;&lt;br /&gt;All this because of one silly grammar ambiguity.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-3114285557828140580?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/3114285557828140580/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=3114285557828140580' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/3114285557828140580'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/3114285557828140580'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/02/c-typedef-parsing-problem.html' title='The C Typedef Parsing Problem'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-4068251265695022866</id><published>2009-02-09T10:25:00.004-05:00</published><updated>2009-02-09T10:31:04.897-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='semantics'/><category scheme='http://www.blogger.com/atom/ns#' term='lambda calculus'/><category scheme='http://www.blogger.com/atom/ns#' term='history'/><title type='text'>History lesson</title><content type='html'>A &lt;a href="http://list.cs.brown.edu/pipermail/plt-scheme/2009-February/030312.html"&gt;history and semantics lesson&lt;/a&gt; from &lt;a href="http://www.ccs.neu.edu/home/matthias"&gt;Matthias&lt;/a&gt; on &lt;a href="http://list.cs.brown.edu/mailman/listinfo/plt-scheme/"&gt;plt-scheme&lt;/a&gt;:&lt;br /&gt;&lt;blockquote&gt;Normal order and applicative order are failed attempts to explain the nature of call-by-name programming languages and call-by-value programming languages as models of the lambda calculus. Each describes a so-called &lt;span style="font-style: italic;"&gt;reduction strategy&lt;/span&gt;, which is an algorithm that picks the position of next redex BETA that should be reduced. By 1972, it was clear that instead you want different kind of calculi for different calling conventions and evaluation strategies (to the first outermost lambda, not inside).  That is, you always reduce at the leftmost-outermost point in a program but you use either BETA-NAME or BETA-VALUE. Non-PL people were confused (and still are) because BETA-NAME looks like BETA but nearly 40 years later, everyone should figure this out. SICP was written when the majority of people were still confused. -- Matthias&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-4068251265695022866?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/4068251265695022866/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=4068251265695022866' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/4068251265695022866'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/4068251265695022866'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/02/history-lesson.html' title='History lesson'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-7481570864778114232</id><published>2009-02-07T07:30:00.003-05:00</published><updated>2009-02-07T07:35:22.558-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='reader'/><category scheme='http://www.blogger.com/atom/ns#' term='Scheme'/><title type='text'>A funny reader context</title><content type='html'>Trivia time: find a place in the Scheme reader where &lt;span style="font-family: courier new; color: rgb(0, 102, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;,&lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;expr&lt;/span&gt;&lt;/span&gt; is not equivalent to &lt;span style="font-family: courier new;"&gt;&lt;span style="color: rgb(102, 0, 0);"&gt;(&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;unquote&lt;/span&gt; &lt;span style="color: rgb(0, 0, 153);"&gt;expr&lt;/span&gt;&lt;span style="color: rgb(102, 0, 0);"&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Answer:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&amp;gt; (define ls '(1 2 3))&lt;br /&gt;&amp;gt; `#(unquote ls)&lt;br /&gt;#(1 2 3)&lt;br /&gt;&amp;gt; `#,ls&lt;br /&gt;#,ls&lt;/pre&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-7481570864778114232?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/7481570864778114232/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=7481570864778114232' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/7481570864778114232'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/7481570864778114232'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/02/funny-reader-context.html' title='A funny reader context'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-377830853805263652</id><published>2009-02-04T19:18:00.004-05:00</published><updated>2009-02-04T19:25:01.372-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='planet'/><category scheme='http://www.blogger.com/atom/ns#' term='C'/><category scheme='http://www.blogger.com/atom/ns#' term='FFI'/><title type='text'>Using C to talk to C</title><content type='html'>I've released the first version of a &lt;a href="http://planet.plt-scheme.org/package-source/dherman/c.plt/1/0/planet-docs/c/index.html"&gt;PLaneT package for working with C&lt;/a&gt;. It's based on an idea I got from &lt;a href="http://www.ccs.neu.edu/home/pnkfelix/Published/klock-ffi-schemeworkshop-2008.html"&gt;Felix Klock's Scheme Workshop 2008 paper&lt;/a&gt;: rather than try to do manual pointer arithmetic based on the current architecture's ABI, you can find out byte offsets of data structures by creating a C program that tells you what they should be. So that's what c.plt allows you to do; using a system-installed C compiler, you can generate a representation of the binary layouts of data structures. Here's a sample interaction:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&amp;gt; (define time.h&lt;br /&gt;   (make-header&lt;br /&gt;     #reader (planet dherman/c/reader) {&lt;br /&gt;         struct tm {&lt;br /&gt;             int tm_sec;&lt;br /&gt;             int tm_min;&lt;br /&gt;             int tm_hour;&lt;br /&gt;             int tm_mday;&lt;br /&gt;             int tm_mon;&lt;br /&gt;             int tm_year;&lt;br /&gt;             int tm_wday;&lt;br /&gt;             int tm_yday;&lt;br /&gt;             int tm_isdst;&lt;br /&gt;         };&lt;br /&gt;     }))&lt;br /&gt;&amp;gt; (define time-abi&lt;br /&gt;   (compile-header time.h&lt;br /&gt;     (system-compiler #:include&lt;&gt; '("time.h") gcc)))&lt;br /&gt;&amp;gt; (layout-size (time-abi 'tm))&lt;br /&gt;36&lt;br /&gt;&amp;gt; (layout-offset (time-abi 'tm) 'tm_sec)&lt;br /&gt;0&lt;br /&gt;&amp;gt; (layout-offset (time-abi 'tm) 'tm_year)&lt;br /&gt;20&lt;/pre&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-377830853805263652?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/377830853805263652/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=377830853805263652' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/377830853805263652'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/377830853805263652'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/02/using-c-to-talk-to-c.html' title='Using C to talk to C'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-3969437969302028030</id><published>2009-01-30T17:36:00.004-05:00</published><updated>2009-01-30T17:52:29.088-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='systems'/><category scheme='http://www.blogger.com/atom/ns#' term='code is data'/><category scheme='http://www.blogger.com/atom/ns#' term='paging'/><category scheme='http://www.blogger.com/atom/ns#' term='architecture'/><title type='text'>Quiz answer</title><content type='html'>Reader Mitch (not my advisor, apparently) comes closest to the answer to my &lt;a href="http://calculist.blogspot.com/2009/01/quiz-question.html"&gt;quiz question&lt;/a&gt;:&lt;br /&gt;&lt;blockquote&gt;Some kind of alignment thing?  I can't think of how code would be affected by that, though.&lt;/blockquote&gt;As it happens, changing the code was affecting the particular size of the activation record allocated by the GCC-generated code.  Somehow the extra code ended up with a slightly smaller activation record. And &lt;span style="font-style: italic;"&gt;then&lt;/span&gt; it turned out that the slight difference (something like 8 or 16 bytes) was pushing the activation record over the edge of a page boundary. Boom!&lt;br /&gt;&lt;br /&gt;It's still a mystery to me exactly how throwing in an &lt;span style="font-family: courier new;"&gt;asm("noop\n")&lt;/span&gt; can affect the size of the activation record. Such are the arcane mysteries of GCC code generation. I had to catch my flight home before &lt;a href="http://blog.mozilla.com/dmandelin/"&gt;Dave&lt;/a&gt; had worked out all the details but by now I bet he has an even better understanding of it. It was fun and inspiring to watch Dave's detective skills in action.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-3969437969302028030?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/3969437969302028030/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=3969437969302028030' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/3969437969302028030'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/3969437969302028030'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/01/quiz-answer.html' title='Quiz answer'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-5588608401352295865</id><published>2009-01-30T09:17:00.002-05:00</published><updated>2009-01-30T09:23:41.966-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='systems'/><category scheme='http://www.blogger.com/atom/ns#' term='architecture'/><title type='text'>Quiz question</title><content type='html'>Here's a fun puzzle I watched &lt;a href="http://blog.mozilla.com/dmandelin/"&gt;Dave Mandelin&lt;/a&gt; track down yesterday. Why would adding a guaranteed no-op such as&lt;br /&gt;&lt;blockquote style="font-family: courier new;"&gt;if (FALSE) { printf("can't happen\n"); }&lt;/blockquote&gt;or even&lt;br /&gt;&lt;blockquote style="font-family: courier new;"&gt;asm("noop\n");&lt;/blockquote&gt;to the body of a procedure cause a program to run measurably and consistently &lt;span style="font-style: italic;"&gt;faster&lt;/span&gt;? I'll post the answer later today. (Or as much as I understand, anyway.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-5588608401352295865?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/5588608401352295865/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=5588608401352295865' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/5588608401352295865'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/5588608401352295865'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/01/quiz-question.html' title='Quiz question'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-3948779096701916182</id><published>2009-01-13T10:52:00.002-05:00</published><updated>2009-01-13T11:02:48.932-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='UI'/><category scheme='http://www.blogger.com/atom/ns#' term='brands'/><title type='text'>Java, we don't care about you</title><content type='html'>Joel Spolsky pretty much &lt;a href="http://www.joelonsoftware.com/items/2009/01/12.html"&gt;nails it&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I actually grabbed a screen shot of this very same dialog box some time last year because it was so absurd. The part that always amazes me is why people think customers are going to care about their product as much as they do. It seems to me that I'm more likely to be loyal to a technology brand that shows a little humility and restraint.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-3948779096701916182?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/3948779096701916182/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=3948779096701916182' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/3948779096701916182'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/3948779096701916182'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/01/java-we-dont-care-about-you.html' title='Java, we don&apos;t care about you'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-7950063753287709301</id><published>2009-01-09T08:08:00.003-05:00</published><updated>2009-01-09T08:14:14.918-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='dissertation'/><category scheme='http://www.blogger.com/atom/ns#' term='research progress'/><title type='text'>A page of the dissertation</title><content type='html'>&lt;a href="http://www.cs.rice.edu/%7Erg11/"&gt;Ron Garcia&lt;/a&gt; suggested that I should get in the practice of writing a little bit for my dissertation each day, so that when crunch time comes, I'll already have a lot of material to work with. This being New Year's, I should also go to the gym, eat healthier, clean my home and my office, make a budget, fix more bugs, and organize my time.&lt;br /&gt;&lt;br /&gt;But I just wrote my first page of content for the dissertation, and that feels pretty good. There's even a lemma!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-7950063753287709301?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/7950063753287709301/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=7950063753287709301' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/7950063753287709301'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/7950063753287709301'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/01/page-of-dissertation.html' title='A page of the dissertation'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-6291124763449894232</id><published>2009-01-08T07:53:00.006-05:00</published><updated>2009-01-08T08:38:02.655-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='top level'/><category scheme='http://www.blogger.com/atom/ns#' term='fexprs'/><category scheme='http://www.blogger.com/atom/ns#' term='Scheme'/><title type='text'>Fexprs? in Scheme?</title><content type='html'>&lt;blockquote&gt;&amp;ldquo;The top level is hopeless.&amp;rdquo;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-- Matthew Flatt [&lt;a href="http://www.cs.brown.edu/pipermail/plt-scheme/2005-August/009481.html"&gt;1&lt;/a&gt;] [&lt;a href="http://www.cs.brown.edu/pipermail/plt-scheme/2005-November/010348.html"&gt;2&lt;/a&gt;] [&lt;a href="http://www.cs.brown.edu/pipermail/plt-scheme/2006-June/013816.html"&gt;3&lt;/a&gt;] [&lt;a href="http://www.cs.brown.edu/pipermail/plt-scheme/2006-December/015604.html"&gt;4&lt;/a&gt;] [&lt;a href="http://www.cs.brown.edu/pipermail/plt-scheme/2007-February/016390.html"&gt;5&lt;/a&gt;] [&lt;a href="http://list.cs.brown.edu/pipermail/plt-scheme/2008-January/022308.html"&gt;6&lt;/a&gt;] [&lt;a href="http://list.cs.brown.edu/pipermail/plt-scheme/2008-March/023846.html"&gt;7&lt;/a&gt;] [&lt;a href="https://webmail.iro.umontreal.ca/pipermail/gambit-list/2008-June/002394.html"&gt;8&lt;/a&gt;] [&lt;a href="http://list.cs.brown.edu/pipermail/plt-scheme/2008-September/027468.html"&gt;9&lt;/a&gt;]&lt;/blockquote&gt;Scheme's top level allows for interactive evaluation such as at the REPL, where global definitions can be dynamically evaluated one by one. To allow for forward references, free variables are not a static error at the top level. But global definitions may be macros, and there's no way to know whether a forward reference is eventually going to turn out to be a value binding or a macro binding. So one simple semantics is just to assume that forward references are always value bindings and compile them as such. But then you get unsatisfying interactions like this:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&amp;gt; (define (f) (display (g 42)))&lt;br /&gt;&amp;gt; (define-syntax g (syntax-rules () ((g x) (quote x))))&lt;br /&gt;&amp;gt; (f)&lt;/pre&gt;&lt;span style="font-style: italic;"&gt;reference to an identifier before its definition: g&lt;/span&gt;&lt;/blockquote&gt;It's worse with macro-defining macro&lt;span style="font-family: courier new;"&gt;&lt;/span&gt;s. For example, a &lt;span style="font-family: courier new;"&gt;define/inline&lt;/span&gt; form would bind its definition as a macro, but the user could generally treat it as a value binding. But you'd still run into the same problem:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&amp;gt; (define/inline (f) (g 42))&lt;br /&gt;&amp;gt; (define/inline (g n) (add1 n))&lt;br /&gt;&amp;gt; (f)&lt;/pre&gt;&lt;span style="font-style: italic;"&gt;reference to an identifier before its definition: g&lt;/span&gt;&lt;/blockquote&gt;What's in conflict in Scheme is the desire for macros to be a static, compile-time entity and the REPL to allow dynamic, incremental update to the global environment. In fact, the top level seems to be the one place in Scheme where programmers expect behavior something like Lisp's antiquated &lt;a href="http://www.nhplace.com/kent/Papers/Special-Forms.html"&gt;fexprs&lt;/a&gt;. Bear with me...&lt;br /&gt;&lt;br /&gt;Imagine if the compiler treated any form &lt;span style="font-family: courier new;"&gt;(x . s)&lt;/span&gt; where &lt;span style="font-family: courier new;"&gt;x&lt;/span&gt; is a top-level variable reference--bound or unbound--as an uninterpreted syntax object waiting to be parsed. Then only when the form is evaluated would &lt;span style="font-family: courier new;"&gt;x&lt;/span&gt; be looked up in the global environment to determine how to compile the form. If &lt;span style="font-family: courier new;"&gt;x&lt;/span&gt; is unbound, it's a dynamic error; if it's a value, it's compiled and evaluated as a function application; if it's a macro, it's macro-expanded, compiled, and evaluated. This would accomodate any sequence of definitions and redefinitions of top-level bindings, either as value bindings, macro bindings, or both. For example:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&amp;gt; (define (foo x) (f x))&lt;br /&gt;&amp;gt; (define (f x) (add1 x))&lt;br /&gt;&amp;gt; (foo 41)&lt;br /&gt;42&lt;br /&gt;&amp;gt; (define-syntax f (syntax-rules () ((f e) (quote e))))&lt;br /&gt;&amp;gt; (foo 41)&lt;br /&gt;x&lt;/pre&gt;&lt;/blockquote&gt;This has a lot of the similarities to fexprs; it means a function like &lt;span style="font-family: courier new;"&gt;foo&lt;/span&gt; is subject to dynamic re&lt;span style="font-style: italic;"&gt;parsing&lt;/span&gt;: at one point it calls a function on &lt;span style="font-family: courier new;"&gt;x&lt;/span&gt; and at another point it applies a macro. But whereas with fexprs, &lt;a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.44.9264"&gt;&lt;span style="font-style: italic;"&gt;any&lt;/span&gt; application expression may be dynamically reparsed&lt;/a&gt;, here this would only be the case for applications of top-level variables.&lt;br /&gt;&lt;br /&gt;Fexprs are bad for two reasons: they make the language hard to compile efficiently and they make programs hard to understand by subjecting the basic program definition to dynamic reinterpretation. To be sure, making Scheme's top-level fexpr-like would make efficient compilation harder. But the top-level is the part of Scheme where programs are dynamically defined. Users are constantly surprised at the behavior of top-level forward references and macro definitions. What they seem to naturally expect is, in some sense, fexprs.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-6291124763449894232?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/6291124763449894232/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=6291124763449894232' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/6291124763449894232'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/6291124763449894232'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2009/01/fexprs-in-scheme.html' title='Fexprs? in Scheme?'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-5721383759237843427</id><published>2008-12-21T08:32:00.001-05:00</published><updated>2008-12-21T08:34:58.216-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='netiquette'/><title type='text'>I want my Unicode keyboard</title><content type='html'>&lt;blockquote&gt;"You see the typographical limitations we're still saddled with? The mock-wounded &lt;span style="font-family: courier new;"&gt;:(&lt;/span&gt; and the actually-wounded &lt;span style="font-family: courier new;"&gt;:(&lt;/span&gt; aren't slated to have distinct code points until Unicode 17."&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-- &lt;a href="https://mail.mozilla.org/pipermail/es-discuss/2008-December/008373.html"&gt;Jon Zeppieri&lt;/a&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-5721383759237843427?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/5721383759237843427/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=5721383759237843427' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/5721383759237843427'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/5721383759237843427'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/12/i-want-my-unicode-keyboard.html' title='I want my Unicode keyboard'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-1967032837824977050</id><published>2008-12-21T08:24:00.004-05:00</published><updated>2008-12-21T08:32:07.329-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='lambda renaissance'/><category scheme='http://www.blogger.com/atom/ns#' term='es4'/><title type='text'>Sign o' the times</title><content type='html'>&lt;blockquote&gt;"Who would have thought a &lt;a href="https://mail.mozilla.org/pipermail/es-discuss/2008-November/thread.html#8216"&gt;discussion&lt;/a&gt; &lt;a href="https://mail.mozilla.org/pipermail/es-discuss/2008-December/thread.html"&gt;about lambda syntax&lt;/a&gt; in JavaScript&lt;br /&gt;would go over 120 posts while a simultaneous &lt;a href="https://mail.mozilla.org/pipermail/es-discuss/2008-December/thread.html#8244"&gt;thread about class syntax&lt;/a&gt;&lt;br /&gt;has had little attention outside a handful of posters?&lt;br /&gt;&lt;br /&gt;Would this have been reverse 10 years ago?&lt;br /&gt;&lt;br /&gt;Sign of the paradigm shift? Maybe folks want an &lt;a href="http://groups.google.com/group/comp.lang.scheme/browse_frm/thread/7eccba9fb4eebb44"&gt;immutable cons cells&lt;/a&gt; too?"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-- &lt;a href="https://mail.mozilla.org/pipermail/es-discuss/2008-December/008372.html"&gt;Peter Michaux&lt;/a&gt;&lt;/blockquote&gt;&lt;a href="https://mail.mozilla.org/pipermail/es-discuss/2008-December/008372.html"&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-1967032837824977050?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/1967032837824977050/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=1967032837824977050' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/1967032837824977050'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/1967032837824977050'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/12/sign-o-times.html' title='Sign o&apos; the times'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-7620609470978233866</id><published>2008-12-19T11:00:00.003-05:00</published><updated>2008-12-19T11:03:36.713-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='naming conventions'/><category scheme='http://www.blogger.com/atom/ns#' term='coding style'/><title type='text'>A small peeve</title><content type='html'>Whenever I write a function with an external wrapper and an internal recursive function (say, to add an accumulator), I can never come up with a name for the internal function that I find satisfying. This is totally picking nits, but it bugs me for all the recursive calls to be to &lt;span style="font-family: courier new;"&gt;foo/aux&lt;/span&gt; or &lt;span style="font-family: courier new;"&gt;foo/helper&lt;/span&gt; or something like that. Come to think of it, somehow the prime symbol in Haskell and ML feels more natural.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-7620609470978233866?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/7620609470978233866/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=7620609470978233866' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/7620609470978233866'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/7620609470978233866'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/12/small-peeve.html' title='A small peeve'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-8679493545185892699</id><published>2008-12-13T10:34:00.002-05:00</published><updated>2008-12-13T10:37:33.985-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fun'/><category scheme='http://www.blogger.com/atom/ns#' term='quotes'/><title type='text'>Hats off to Duff</title><content type='html'>From an &lt;a href="http://lambda-the-ultimate.org/node/3108#comment-45394"&gt;LtU thread&lt;/a&gt;:&lt;br /&gt;&lt;blockquote&gt;When I see the phrase "Wiki type systems", I immediately wonder what a typed Wiki could possibly be. (Monadic pages? Contribution combinators? Co-recursive spam?) Of course you mean "Wiki-type systems", systems that are Wiki-like. But I was excited for a minute.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-- Tom Duff (yes, &lt;span style="font-style: italic;"&gt;the&lt;/span&gt; Tom Duff)&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-8679493545185892699?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/8679493545185892699/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=8679493545185892699' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/8679493545185892699'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/8679493545185892699'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/12/hats-off-to-duff.html' title='Hats off to Duff'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-7798063496746549022</id><published>2008-12-11T11:07:00.003-05:00</published><updated>2008-12-11T11:13:16.306-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='education'/><category scheme='http://www.blogger.com/atom/ns#' term='science'/><title type='text'>Author's summary</title><content type='html'>I spent a few days visiting &lt;a href="http://www.grinnell.edu"&gt;my alma mater&lt;/a&gt; last week and among the many engaging conversations I had were several with my dear friend &lt;a href="http://www.grinnell.edu/academic/biology/faculty/whitworth/jnl/"&gt;Gregg Whitworth&lt;/a&gt; about incorporating research into a liberal arts undergraduate education. It's very tricky, but Gregg pointed out several aspects of the field of biology that help. Gregg mentioned that many biology papers include authors' summaries. This just sounds like an all-around great idea, and one that's easily implemented: simply add a brief summary to your publications list on your web site.&lt;br /&gt;&lt;br /&gt;In some sense an abstract may be useful, but an author's summary could also be used to put work into broader context. Since it's not subject to the restrictions of the paper itself, it also gives authors more freedom to write whatever they like. And the benefit to students could be enormous: one of the hardest parts of breaking into a research field is understanding the larger conversation each paper participates in.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-7798063496746549022?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/7798063496746549022/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=7798063496746549022' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/7798063496746549022'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/7798063496746549022'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/12/authors-summary.html' title='Author&apos;s summary'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-5292423011521003058</id><published>2008-10-30T11:37:00.003-04:00</published><updated>2008-10-30T11:46:40.977-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='true unions'/><category scheme='http://www.blogger.com/atom/ns#' term='maybe type'/><category scheme='http://www.blogger.com/atom/ns#' term='Scheme'/><category scheme='http://www.blogger.com/atom/ns#' term='option type'/><category scheme='http://www.blogger.com/atom/ns#' term='failure'/><title type='text'>Maybe vs. exception vs. failure thunk in Scheme</title><content type='html'>It's pretty easy to switch back and forth between representing a function with a "maybe" result type as:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;returning X or &lt;span style="font-family: courier new;"&gt;#f&lt;/span&gt;;&lt;/li&gt;&lt;li&gt;returning X or raising an exception; or&lt;/li&gt;&lt;li&gt;returning X and taking a failure thunk&lt;/li&gt;&lt;/ol&gt;In Scheme, sometimes X might include the value &lt;span style="font-family: courier new;"&gt;#f&lt;/span&gt;. In that case I think representation #3 is the best one, since raising an exception is clunky. You can also combine #2 and #3 and take an optional thunk that by default raises an exception.&lt;br /&gt;&lt;br /&gt;This is one case where &lt;a href="http://calculist.blogspot.com/2008/02/true-unions.html"&gt;true unions&lt;/a&gt; do cause some problems, so maybe I should have tempered my earlier enthusiasm a little. Still, it's not insurmountable, and this cost needs to be weighed against &lt;a href="http://calculist.blogspot.com/2008/09/true-unions-revisited.html"&gt;the price of strictly disjoint unions&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-5292423011521003058?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/5292423011521003058/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=5292423011521003058' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/5292423011521003058'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/5292423011521003058'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/10/maybe-vs-exception-vs-failure-thunk-in.html' title='Maybe vs. exception vs. failure thunk in Scheme'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-7086704943183513067</id><published>2008-10-30T10:01:00.002-04:00</published><updated>2008-10-30T10:06:42.117-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='game programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>Sweet</title><content type='html'>&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/gVLFGQGRsDw&amp;hl=en&amp;fs=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/gVLFGQGRsDw&amp;hl=en&amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;A Super Mario Bros. clone, &lt;a href="http://groups.google.com/group/fa.haskell/browse_thread/thread/b6e41d00388de008"&gt;implemented in Haskell&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-7086704943183513067?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/7086704943183513067/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=7086704943183513067' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/7086704943183513067'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/7086704943183513067'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/10/sweet.html' title='Sweet'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-531913831041083666</id><published>2008-10-24T17:32:00.003-04:00</published><updated>2008-10-24T17:39:51.105-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comfort coding'/><title type='text'>Fun programming exercise</title><content type='html'>Off and on I work on my implementation of &lt;a href="http://planet.plt-scheme.org/display.ss?package=javascript.plt&amp;amp;owner=dherman"&gt;JavaScript in PLT Scheme&lt;/a&gt;. Implementing the standard library means translating the &lt;a href="http://www.ecma-international.org/publications/standards/Ecma-262.htm"&gt;spec&lt;/a&gt;'s low-level, imperative pseudocode (think &lt;a href="http://en.wikipedia.org/wiki/GW-BASIC"&gt;GW-BASIC&lt;/a&gt;) to Scheme. It's a fun and mostly mindless exercise to take code with assignments and &lt;span style="font-family: courier new;"&gt;goto&lt;/span&gt;, translate that into mutually tail-calling basic blocks, eliminate the assignments by parameterization, and then finally polish it into a more idiomatic style. Sort of my version of a Sudoku puzzle or something.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-531913831041083666?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/531913831041083666/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=531913831041083666' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/531913831041083666'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/531913831041083666'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/10/fun-programming-exercise.html' title='Fun programming exercise'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-6247849124322709677</id><published>2008-10-24T15:22:00.005-04:00</published><updated>2008-10-24T15:27:53.962-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='first-class continuations'/><category scheme='http://www.blogger.com/atom/ns#' term='first-class heaps'/><category scheme='http://www.blogger.com/atom/ns#' term='heap dumping'/><category scheme='http://www.blogger.com/atom/ns#' term='first-class stores'/><category scheme='http://www.blogger.com/atom/ns#' term='call/cc'/><title type='text'>Once you've already implemented it...</title><content type='html'>A common phenomenon in API design is to expose something simply because you've already put in all the effort required to implement it. For example, if your language runtime implements unbounded recursion, you've already gone a long way towards representing continuations as data. In that case, it's not much more work to offer first-class continuations as a data structure in the language. Similarly, languages often optimize their startup time by dumping the heap into a persistent data structure so they can cache the initialization of the standard library; once they've done this, heap-dumping is an easy feature to offer to users.&lt;br /&gt;&lt;br /&gt;On a semantic level, first-class continuations and first-class stores are obviously similar kinds of constructs. But I'd never noticed till now how they can both just sort of crop up as natural consequences of incidental needs in language implementations.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-6247849124322709677?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/6247849124322709677/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=6247849124322709677' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/6247849124322709677'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/6247849124322709677'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/10/once-youve-already-implemented-it.html' title='Once you&apos;ve already implemented it...'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-2942461147232762165</id><published>2008-10-20T14:15:00.003-04:00</published><updated>2008-10-20T14:31:07.569-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='lexical scope'/><category scheme='http://www.blogger.com/atom/ns#' term='compilation'/><category scheme='http://www.blogger.com/atom/ns#' term='eval'/><category scheme='http://www.blogger.com/atom/ns#' term='with'/><title type='text'>Updated javascript.plt</title><content type='html'>I've just updated my implementation of &lt;a href="http://planet.plt-scheme.org/display.ss?package=javascript.plt&amp;amp;owner=dherman"&gt;JavaScript in PLT Scheme&lt;/a&gt;. The latest version fixes some of the subtle ways I'd deviated from the spec with respect to variable binding. Back in the day, I was wooed into thinking that JavaScript was so similar to Scheme that I could pretty easily just compile JavaScript variable bindings directly to similar Scheme variable bindings. For the most part, I got variable hoisting (i.e., the scope of &lt;span style="font-family:courier new;"&gt;var&lt;/span&gt;-declarations being hoisted to the top of their nearest enclosing &lt;span style="font-family:courier new;"&gt;function&lt;/span&gt; body) right. But the real subtlety comes in with the &lt;span style="font-family:courier new;"&gt;with&lt;/span&gt; (dynamically add a computed object value to the runtime environment as a new environment frame) and &lt;span style="font-family:courier new;"&gt;eval&lt;/span&gt; constructs.&lt;br /&gt;&lt;br /&gt;I almost had &lt;span style="font-family:courier new;"&gt;with&lt;/span&gt; right: as soon as I detect that the programmer is using &lt;span style="font-family:courier new;"&gt;with&lt;/span&gt;, I enter a "stupid" mode, where I synthesize an explicit runtime environment and populate it with whatever's currently in the static environment. Within the body of the &lt;span style="font-family: courier new;"&gt;with&lt;/span&gt;, variable lookup is performed dynamically in this runtime environment. So outside of a &lt;span style="font-family:courier new;"&gt;with&lt;/span&gt;, you get normal, efficient lexical scope; inside a &lt;span style="font-family:courier new;"&gt;with&lt;/span&gt;, you get stupid, slow, dynamic scope. My only mistake there was forgetting to make the runtime environment entries aliases to the existing variables so that &lt;a href="http://planet.plt-scheme.org/trac/ticket/100"&gt;mutations persist after the &lt;span style="font-family:courier new;"&gt;with&lt;/span&gt;-block returns&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;But &lt;span style="font-family:courier new;"&gt;eval&lt;/span&gt; is hard: Scheme's &lt;span style="font-family:courier new;"&gt;eval&lt;/span&gt; doesn't have access to the lexical environment where it is called, whereas JavaScript's does. And JavaScript's &lt;span style="font-family:courier new;"&gt;eval&lt;/span&gt; also inherits the ambient "variable object" (&lt;a href="http://www.ecma-international.org/publications/standards/Ecma-262.htm"&gt;ECMA-262&lt;/a&gt; &lt;a href="http://bclary.com/2004/11/07/#a-10.1.3"&gt;10.1.3&lt;/a&gt;), which means that &lt;a href="http://calculist.blogspot.com/2008/10/todays-javascript-kookiness.html"&gt;&lt;span style="font-family:courier new;"&gt;eval&lt;/span&gt; code can create variable bindings in the caller's scope&lt;/a&gt;. Getting all of this right means simulating the variable object similarly to the way I simulate the runtime environment, and switching into "stupid" mode whenever I detect a potential application of &lt;span style="font-family:courier new;"&gt;eval&lt;/span&gt;. (The standard allows you to refuse to run &lt;span style="font-family:courier new;"&gt;eval&lt;/span&gt; in situations other than a "direct" call to a variable reference spelled e-v-a-l, so you don't have to treat every single function call as a potential call to &lt;span style="font-family:courier new;"&gt;eval&lt;/span&gt;. It's messy, but it's better than forcing you to implement a dynamic environment everywhere.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-2942461147232762165?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/2942461147232762165/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=2942461147232762165' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/2942461147232762165'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/2942461147232762165'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/10/updated-javascriptplt.html' title='Updated javascript.plt'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-8007269235891659481</id><published>2008-10-15T14:45:00.002-04:00</published><updated>2008-10-15T14:56:05.350-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='forall'/><category scheme='http://www.blogger.com/atom/ns#' term='GHC'/><category scheme='http://www.blogger.com/atom/ns#' term='higher-rank polymorphism'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>Unordered multi-arity binders</title><content type='html'>Cool: GHC knows that "∀" doesn't care what order you bind its type variables:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;{-# LANGUAGE RankNTypes, TypeOperators #-}&lt;br /&gt;&lt;br /&gt;f1 :: ∀ a b . a → b → b&lt;br /&gt;f1 x y = y&lt;br /&gt;&lt;br /&gt;f2 :: ∀ b a . a → b → b&lt;br /&gt;f2 x y = y&lt;br /&gt;&lt;br /&gt;h :: (∀ a b . a → b → b) → c → d → d&lt;br /&gt;h f x y = f x y&lt;br /&gt;&lt;br /&gt;a = h f1&lt;br /&gt;b = h f2&lt;/pre&gt;&lt;/blockquote&gt;Think about what this means for implementing a type-checker: to match one ∀-type against another, you have to find the right permutation of bound type variables. (A naive approach requires searching through all &lt;span style="font-style: italic;"&gt;n&lt;/span&gt;! permutations!) Presumably the actual implementation incrementally unifies the type variables as it recurs into the bodies of the ∀-types.&lt;br /&gt;&lt;br /&gt;Does anyone know of a paper that describes this aspect of implementing higher-rank polymorphism?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-8007269235891659481?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/8007269235891659481/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=8007269235891659481' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/8007269235891659481'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/8007269235891659481'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/10/unordered-multi-arity-binders.html' title='Unordered multi-arity binders'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-6541660126606711982</id><published>2008-10-14T09:14:00.004-04:00</published><updated>2008-10-14T09:49:22.093-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='eval'/><title type='text'>Today's JavaScript kookiness</title><content type='html'>One of the weirdest aspects of JavaScript's &lt;span style="font-family:courier new;"&gt;eval&lt;/span&gt; is that it not only has complete access to the lexical scope of its caller, but it even gets to add variable declarations to its caller's lexical frame. So I can write&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;(function() {&lt;br /&gt;  eval("var x = 10")&lt;br /&gt;  return x&lt;br /&gt;})()&lt;/pre&gt;&lt;/blockquote&gt;and get 10. Now, bearing in mind that &lt;span style="font-family:courier new;"&gt;var&lt;/span&gt; declares a binding for the entire containing function, &lt;span style="font-family:courier new;"&gt;eval&lt;/span&gt; combines in a truly spectacular way with lexical bindings. What does the following &lt;span style="font-family:courier new;"&gt;test&lt;/span&gt; function produce?&lt;blockquote&gt;&lt;pre&gt;function test() {&lt;br /&gt;  var x = 'outer'&lt;br /&gt;  return (function() {&lt;br /&gt;              {&lt;br /&gt;                  let x = 'inner'&lt;br /&gt;                  eval("var x = 'eval'")&lt;br /&gt;              }&lt;br /&gt;              return x&lt;br /&gt;          })()&lt;br /&gt;}&lt;/pre&gt;&lt;/blockquote&gt;Clearly the &lt;span style="font-family:courier new;"&gt;let&lt;/span&gt;-binding of &lt;span style="font-style: italic;"&gt;x&lt;/span&gt; seems to be in scope for the &lt;span style="font-family:courier new;"&gt;eval&lt;/span&gt; code. So we might expect the function to return the string &lt;span style="font-family:courier new;"&gt;'outer'&lt;/span&gt;, with the assumption that the &lt;span style="font-family:courier new;"&gt;eval&lt;/span&gt; code simply modified the inner binding. Then again, the &lt;span style="font-family:courier new;"&gt;eval&lt;/span&gt; code is creating a &lt;span style="font-family:courier new;"&gt;var&lt;/span&gt;-binding, so we might expect the function to return the string &lt;span style="font-family:courier new;"&gt;'eval'&lt;/span&gt;, with the assumption that the &lt;span style="font-family:courier new;"&gt;eval&lt;/span&gt; code is declaring a new variable &lt;span style="font-style: italic;"&gt;x&lt;/span&gt; to be local to the inner function. So what does it really return? &lt;span style="font-family:courier new;"&gt;undefined&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;What?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/__OULbbSCQyc/SPSjRFvUAWI/AAAAAAAAABk/EBivbtvK2KY/s1600-h/var.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://3.bp.blogspot.com/__OULbbSCQyc/SPSjRFvUAWI/AAAAAAAAABk/EBivbtvK2KY/s200/var.png" alt="" id="BLOGGER_PHOTO_ID_5257006179041935714" border="0" /&gt;&lt;/a&gt;If I've got this right, what's happening is that the &lt;span style="font-family:courier new;"&gt;eval&lt;/span&gt; code is creating a &lt;span style="font-family:courier new;"&gt;var&lt;/span&gt;-binding for &lt;span style="font-style: italic;"&gt;x&lt;/span&gt; in its containing function, but its initializer is mutating the current &lt;span style="font-style: italic;"&gt;x&lt;/span&gt; in scope, which happens to be the &lt;span style="font-family:courier new;"&gt;let&lt;/span&gt;-bound x. So the &lt;span style="font-family:courier new;"&gt;eval&lt;/span&gt; code is actually creating a variable binding &lt;span style="font-style: italic;"&gt;two&lt;/span&gt; lexical frames out. The &lt;span style="font-family:courier new;"&gt;eval&lt;/span&gt;ed &lt;span style="font-family:courier new;"&gt;var&lt;/span&gt;-declaration and its initializer are referring to two completely different bindings of &lt;span style="font-style: italic;"&gt;x&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Lest you think this is strictly an unfortunate interaction between the legacy &lt;span style="font-family:courier new;"&gt;var&lt;/span&gt; and &lt;span style="font-family:courier new;"&gt;eval&lt;/span&gt; semantics and the new (post-ES3) &lt;span style="font-family:courier new;"&gt;let&lt;/span&gt; declaration form, there are a couple of other local declaration forms in pure ES3, including &lt;span style="font-family:courier new;"&gt;catch&lt;/span&gt;. Consider:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;function test() {&lt;br /&gt;  var x = 'outer'&lt;br /&gt;  return (function() {&lt;br /&gt;              try { throw 'inner' }&lt;br /&gt;              catch(x) { eval("var x = 'eval'") }&lt;br /&gt;              return x&lt;br /&gt;          })()&lt;br /&gt;}&lt;/pre&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-6541660126606711982?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/6541660126606711982/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=6541660126606711982' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/6541660126606711982'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/6541660126606711982'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/10/todays-javascript-kookiness.html' title='Today&apos;s JavaScript kookiness'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/__OULbbSCQyc/SPSjRFvUAWI/AAAAAAAAABk/EBivbtvK2KY/s72-c/var.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-3989899601785975039</id><published>2008-10-06T11:56:00.003-04:00</published><updated>2008-10-06T16:42:01.374-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fail'/><title type='text'>That's not supposed to happen...</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/__OULbbSCQyc/SOp4EyjZo1I/AAAAAAAAABc/IBd9C4eK6aM/s1600-h/12-232-002-02.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://1.bp.blogspot.com/__OULbbSCQyc/SOp4EyjZo1I/AAAAAAAAABc/IBd9C4eK6aM/s200/12-232-002-02.jpg" alt="" id="BLOGGER_PHOTO_ID_5254143938966168402" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;When smoke comes out of your laptop, that's...bad, right?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Update:&lt;/span&gt; IDE-&gt;USB adapters are wonderful things.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-3989899601785975039?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/3989899601785975039/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=3989899601785975039' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/3989899601785975039'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/3989899601785975039'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/10/thats-not-supposed-to-happen.html' title='That&apos;s not supposed to happen...'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/__OULbbSCQyc/SOp4EyjZo1I/AAAAAAAAABc/IBd9C4eK6aM/s72-c/12-232-002-02.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-1135838669138174328</id><published>2008-10-03T07:39:00.003-04:00</published><updated>2008-10-03T08:49:35.152-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='metadata'/><category scheme='http://www.blogger.com/atom/ns#' term='Clojure'/><title type='text'>Clojure metadata</title><content type='html'>I watched the video of &lt;a href="http://clojure.blip.tv/file/1313398"&gt;Rich Hickey's talk&lt;/a&gt; about &lt;a href="http://clojure.org"&gt;Clojure&lt;/a&gt; at the &lt;a href="http://common-lisp.net/mailman/listinfo/boston-lisp"&gt;Boston Lisp&lt;/a&gt; group this week and was very impressed by his design. One of the features I've been mulling is Clojure's notion of &lt;a href="http://clojure.org/metadata"&gt;metadata&lt;/a&gt;: every value can be associated with extra associative data. That data does not affect the value's behavior under the standard equality predicate, so in some sense it can be seen as "invisible." This is kind of like JavaScript objects' arbitrarily extensible property tables, except for the very important difference that it's immutable. So you can create a value that's more or less equivalent to another (it is distinguishable by &lt;span style="font-style: italic;"&gt;identical?&lt;/span&gt;, but use of that predicate is discouraged) but with some extra information on the side.&lt;br /&gt;&lt;br /&gt;The first use I immediately thought of for this is when you're writing a compiler or interpreter that has AST nodes and you want to save source location information. This information shouldn't affect AST equality. Clojure metadata sounds like it could be a good way to separate that concern.&lt;br /&gt;&lt;br /&gt;I think it's confusing, at least for me, that Rich describes metadata as not being "part of the value"--where I come from, a value is the result of evaluating an expression. When you evaluate &lt;span style="font-family: courier new;"&gt;(with-meta v m)&lt;/span&gt; you &lt;span style="font-style: italic;"&gt;do&lt;/span&gt; get a new value that is associated with metadata m. What Rich is saying is that the metadata is not contained within &lt;span style="font-style: italic;"&gt;v&lt;/span&gt;. At first when he said it wasn't part of the value, I thought "that sounds brittle." But if I've understood it, a more accurate description might be that values in Clojure may carry with them an extra associative map that doesn't affect their printed representation or their equality.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-1135838669138174328?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/1135838669138174328/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=1135838669138174328' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/1135838669138174328'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/1135838669138174328'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/10/clojure-metadata.html' title='Clojure metadata'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-809087279365422612</id><published>2008-10-02T16:56:00.000-04:00</published><updated>2008-10-02T16:57:57.912-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='JVM'/><category scheme='http://www.blogger.com/atom/ns#' term='Clojure'/><title type='text'>Quote of the day</title><content type='html'>"As goofy as Java is, the JVM is stunning technology."&lt;br /&gt;     -- &lt;a href="http://clojure.org/"&gt;Rich Hickey&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-809087279365422612?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/809087279365422612/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=809087279365422612' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/809087279365422612'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/809087279365422612'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/10/quote-of-day.html' title='Quote of the day'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-562527358552125427</id><published>2008-10-02T09:19:00.003-04:00</published><updated>2008-10-02T09:23:55.417-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='actors'/><category scheme='http://www.blogger.com/atom/ns#' term='message-passing'/><category scheme='http://www.blogger.com/atom/ns#' term='CSP'/><category scheme='http://www.blogger.com/atom/ns#' term='concurrency'/><title type='text'>Web inching towards actors?</title><content type='html'>I learned about the new HTML 5 &lt;a href="http://ejohn.org/blog/postmessage-api-changes/"&gt;postMessage&lt;/a&gt; API recently, and it struck me that we are ever so slowly inching towards actors on the web: now all windows in a browser (including separate tabs and iframes) are communicating sequential processes.&lt;br /&gt;&lt;br /&gt;Now, &lt;a href="http://video.google.com/videoplay?docid=-2950949730059754521"&gt;if Alan Kay had had his way&lt;/a&gt;, every node in the DOM would be separately addressable (i.e., have its own URI) and would probably itself be an actor.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-562527358552125427?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/562527358552125427/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=562527358552125427' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/562527358552125427'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/562527358552125427'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/10/web-inching-towards-actors.html' title='Web inching towards actors?'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-4411854028251794491</id><published>2008-09-29T09:29:00.003-04:00</published><updated>2008-09-29T09:39:13.270-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='web continuations'/><category scheme='http://www.blogger.com/atom/ns#' term='web monad'/><category scheme='http://www.blogger.com/atom/ns#' term='modal web programming'/><title type='text'>Representing the cost of control</title><content type='html'>Every once in a while I play around with this idea for the design of a web language (server-side).&lt;br /&gt;&lt;br /&gt;The nice thing about using first-class continuations to implement a web library is that you can write your code in direct style, but a big down-side is that you still have to figure out how to manage the storage of those continuations. But the alternative of essentially representing the control with program data structures, i.e. with explicit representations of the state of the computation, is really painful.&lt;br /&gt;&lt;br /&gt;So I've thought of taking a page from Haskell's playbook: what if you separated a web language into two portions? One language would be for writing the "driver" of the program, where you can call &lt;span style="font-family: courier new;"&gt;send/suspend&lt;/span&gt; and computations may be suspended and restarted an arbitrary number of times. The other language would be "pure" (well, let's say full Scheme, but no &lt;span style="font-family: courier new;"&gt;send/suspend&lt;/span&gt;). In other words, replace Haskell's &lt;span style="font-family: courier new;"&gt;IO&lt;/span&gt; monad with the &lt;span style="font-family: courier new;"&gt;Web&lt;/span&gt; monad. As with Haskell, code in the &lt;span style="font-family: courier new;"&gt;Web&lt;/span&gt; monad can call pure code, but not vice versa.&lt;br /&gt;&lt;br /&gt;The benefit of this would be that you could still write in direct style, but you've made explicit the portions of the program where control will cost you. Then you could play with different ways of managing that cost--expiration of continuations, back-off for expiration, etc.--by playing with the design of the &lt;span style="font-family: courier new;"&gt;Web&lt;/span&gt; monad, which wouldn't affect the pure language.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-4411854028251794491?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/4411854028251794491/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=4411854028251794491' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/4411854028251794491'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/4411854028251794491'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/09/representing-cost-of-control.html' title='Representing the cost of control'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-5827628083149629561</id><published>2008-09-29T01:59:00.004-04:00</published><updated>2008-09-29T09:08:43.190-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tail calls'/><category scheme='http://www.blogger.com/atom/ns#' term='completion value'/><title type='text'>JavaScript completion value: pros and cons</title><content type='html'>In JavaScript the &lt;span style="font-style: italic;"&gt;completion value&lt;/span&gt; is the result value of a computation, which may result even from evaluating a statement. Simple statements like&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;{&lt;br /&gt;  2 + 2;&lt;br /&gt;}&lt;/pre&gt;&lt;/blockquote&gt;have result values (in this case 4), but so do complex statements like&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;for (var i = 0; i &amp;lt; n; i++)&lt;br /&gt;  f(i);&lt;/pre&gt;&lt;/blockquote&gt;Notice that if &lt;span style="font-family:courier new;"&gt;n&lt;/span&gt; is less than [&lt;span style="font-style: italic;"&gt;edit&lt;/span&gt;: or equal to] 0 in this example, there won't be any computation at all, in which case the statement can't really produce any reasonable value.&lt;br /&gt;&lt;br /&gt;I've just figured out how to articulate an intuition I've long felt about the completion value. The great thing is that it mitigates some of the awfulness of statements: even imperative code can still produce values! This means you can have some of the syntactic convenience of statements for writing effectful code, while still producing results. But the thing that always made me uncomfortable was how code like the &lt;span style="font-family:courier new;"&gt;for&lt;/span&gt;-loop above screws with the idea of a tail call. Because the &lt;span style="font-family:courier new;"&gt;for&lt;/span&gt;-loop may or may not produce a value, there's a sort of implicit return happening after the loop.&lt;br /&gt;&lt;br /&gt;There might be tricks you could pull using something like &lt;a href="http://users.csc.calpoly.edu/%7Eclements/papers/dissertation.pdf"&gt;continuation marks&lt;/a&gt; to allow tail position inside of loops, but I think a simpler answer in a JavaScript with proper tail calls would be to say that loops do not preserve tail position. So essentially tail position would include the last statement in a block, the arms of an &lt;span style="font-family:courier new;"&gt;if&lt;/span&gt; statement, and the arms of a conditional expression, and that's pretty much it. Inside a &lt;span style="font-family:courier new;"&gt;try&lt;/span&gt;-block, a loop, or a &lt;span style="font-family:courier new;"&gt;switch&lt;/span&gt; (because of the reliance on &lt;span style="font-family:courier new;"&gt;break&lt;/span&gt;) there simply wouldn't be any tail positions.&lt;br /&gt;&lt;br /&gt;Note that a) JavaScript doesn't have tail calls, and b) the only places where you can even observe the completion value of a statement are at a REPL or with &lt;span style="font-family:courier new;"&gt;eval&lt;/span&gt;. But I think JavaScript &lt;span style="font-style: italic;"&gt;could&lt;/span&gt; have proper tail calls (potentially), and I've always wondered whether the completion value should remain a hack isolated to &lt;span style="font-family:courier new;"&gt;eval&lt;/span&gt; or actually see its way into the design of other features for JavaScript.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-5827628083149629561?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/5827628083149629561/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=5827628083149629561' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/5827628083149629561'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/5827628083149629561'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/09/javascript-completion-value-pros-and.html' title='JavaScript completion value: pros and cons'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-8670442955226248896</id><published>2008-09-26T17:15:00.003-04:00</published><updated>2008-09-26T17:19:06.877-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='time management'/><title type='text'>Most productive conference trip ever</title><content type='html'>I can confidently say I've never accomplished so much actual &lt;span style="font-style: italic;"&gt;work&lt;/span&gt; at a conference before. I actually solved a research problem during downtime while at ICFP this week. As a fledgling PhD student I used to take advantage of my boundless free time to think about problems for hours on end, often working into the night. As time goes by I have less and less uninterrupted free time, so I guess that's making me more efficient at using my spare cycles in very short bursts. I guess &lt;a href="http://research.microsoft.com/Lampson/"&gt;Butler Lampson&lt;/a&gt; would classify that under &lt;a href="http://research.microsoft.com/Lampson/Slides/LazyAndSpeculativeAbstract.htm"&gt;speculative execution&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-8670442955226248896?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/8670442955226248896/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=8670442955226248896' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/8670442955226248896'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/8670442955226248896'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/09/most-productive-conference-trip-ever.html' title='Most productive conference trip ever'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-4833727599142930346</id><published>2008-09-22T10:42:00.004-04:00</published><updated>2008-09-22T11:01:25.643-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='printf'/><category scheme='http://www.blogger.com/atom/ns#' term='debugging'/><title type='text'>Debugger as library</title><content type='html'>The great thing about &lt;span style="font-family:courier new;"&gt;printf&lt;/span&gt;-debugging is that it's got about as low a barrier to entry as possible (unless you're using Haskell--don't get me started). You have implicit access to the program's control flow and I/O and the function is essentially always there. When you want to use a debugger, you usually have to search for a good one, download and install it, learn how it works, figure out how to set breakpoints, learn the language of breakpoint conditions, figure out how to inspect locals and evaluate expressions, etc. etc.&lt;br /&gt;&lt;br /&gt;What if debugging was just available as a library? What power would you need? I think PLT Scheme is uniquely suited to making this extremely practical. It's easy to implement a programmatic breakpoint: just &lt;span style="font-family:courier new;"&gt;call/cc&lt;/span&gt; and raise an exception with the captured continuation. You immediately have access to a nice language of boolean predicates for determining breakpoint conditions (Scheme), as well as a language to evaluate expressions with access to the locals (also Scheme). But PLT Scheme also provides &lt;a href="http://users.csc.calpoly.edu/%7Eclements/"&gt;continuation marks&lt;/a&gt;, which allow you to leave little bread-crumbs through the control flow of a program. What I'd really love to do is use this to allow the programmer to annotate interesting points in the control and connect this up to the DrScheme GUI libraries so that the programmer can do something like:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&amp;gt; (define bp (debug &lt;span style="font-style: italic;"&gt;&amp;lt;expression&amp;gt;&lt;/span&gt;))&lt;br /&gt;&amp;gt; bp&lt;br /&gt;#&amp;lt;breakpoint&amp;gt;&lt;br /&gt;&amp;gt; (show-control bp)&lt;/pre&gt;&lt;/blockquote&gt;and have a window pop open that displays a stack trace of the suspended program.&lt;br /&gt;&lt;br /&gt;I'm working on a PLaneT library to make this just about as low-tech and seamless as &lt;span style="font-family:courier new;"&gt;printf&lt;/span&gt;-debugging. You'll just need to throw in one extra line somewhere in the module:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;(require (planet dherman/debug))&lt;/pre&gt;&lt;/blockquote&gt;and this will allow you to throw in breakpoints and debug programs much like you could with a full debugging IDE, only with the directness and &lt;span style="font-style: italic;"&gt;intra&lt;/span&gt;-linguistic style of &lt;span style="font-family:courier new;"&gt;printf&lt;/span&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-4833727599142930346?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/4833727599142930346/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=4833727599142930346' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/4833727599142930346'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/4833727599142930346'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/09/debugger-as-library.html' title='Debugger as library'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-3879110405391549537</id><published>2008-09-21T13:53:00.006-04:00</published><updated>2008-09-21T16:34:09.881-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='operator overloading'/><category scheme='http://www.blogger.com/atom/ns#' term='overloading'/><category scheme='http://www.blogger.com/atom/ns#' term='F#'/><category scheme='http://www.blogger.com/atom/ns#' term='units of measure'/><title type='text'>Units of measure in F#</title><content type='html'>I'm at ICFP and just watched &lt;a href="http://research.microsoft.com/%7Eakenn/"&gt;Andrew Kennedy&lt;/a&gt; give a delightful invited talk about the support for &lt;a href="http://blogs.msdn.com/andrewkennedy/archive/2008/08/20/units-of-measure-in-f-part-one-introducing-units.aspx"&gt;units&lt;/a&gt; &lt;a href="http://blogs.msdn.com/andrewkennedy/archive/2008/09/02/units-of-measure-in-f-part-two-unit-conversions.aspx"&gt;of&lt;/a&gt; &lt;a href="http://blogs.msdn.com/andrewkennedy/archive/2008/09/04/units-of-measure-in-f-part-three-generic-units.aspx"&gt;measure&lt;/a&gt; in &lt;a href="http://research.microsoft.com/fsharp/fsharp.aspx"&gt;F#&lt;/a&gt;. It was a very impressive example of work that's well-designed all the way through, from theory to practice. In essence, it allows you to say things like&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;let gravity = 9.8&amp;lt;m/s^2&amp;gt;&lt;/pre&gt;&lt;/blockquote&gt;and the type system tracks not only the type &lt;span style="font-family:courier new;"&gt;float&lt;/span&gt; but also the unit of measure &lt;span style="font-family:courier new;"&gt;m/s^2&lt;/span&gt; and prevents unit-mismatch errors in the program.&lt;br /&gt;&lt;br /&gt;One of the questions I had was based on my brief experience several years ago with statistical natural language processing, where a lot of the computation we did was in logspace. In a situation like that you would like to keep track of both the ordinary units of measure as well as the fact that everything is in logspace.&lt;br /&gt;&lt;br /&gt;Dan Grossman took this a step further and pointed out that you want your arithmetic operations to have different types when you're working in logspace. For example, while the + operator usually has a type like:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;+: float&amp;lt;'u&amp;gt; -&amp;gt; float&amp;lt;'u&amp;gt; -&amp;gt; float&amp;lt;'u&amp;gt;&lt;/pre&gt;&lt;/blockquote&gt;in logspace it should instead have the type:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;+: float&amp;lt;log 'u&amp;gt; -&amp;gt; float&amp;lt;log 'v&amp;gt; -&amp;gt; float&amp;lt;log ('u · 'v)&amp;gt;&lt;/pre&gt;&lt;/blockquote&gt;Now, I don't know how much support there is for "unit constructors," but the F# unit system does allow you to use units with custom abstract data types. According to Andrew, F# also supports operator overloading and ties it in with the unit system. So it might in fact be possible to express the logspace version of the + operator!&lt;br /&gt;&lt;br /&gt;This integration between overloading and units could be a nice solution to the issue of different representations of numbers. Libraries like Java's &lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/java/math/BigInteger.html"&gt;&lt;span style="font-family:courier new;"&gt;BigInteger&lt;/span&gt;&lt;/a&gt; are a usability disaster, but we only have one syntax for numerals and operators. Tying a type-and-unit system in with overloading could allow you to use various machine representations (fixnums, flonums, IEEE754r decimal, bignums, exact rationals, ...) by annotating literals and variables, and type reconstruction could help with the operators. I'm not a big fan of unification-based inference, but in this case I wonder if simple structurally recursive reconstruction would be enough in practice.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Update:&lt;/span&gt; Ken Shan points out that only the implementation would use +, but you really would want to overload the * operator. Conceptually you're doing a multiplication.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-3879110405391549537?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/3879110405391549537/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=3879110405391549537' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/3879110405391549537'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/3879110405391549537'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/09/units-of-measure-in-f.html' title='Units of measure in F#'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-362064541396930622</id><published>2008-09-15T10:44:00.004-04:00</published><updated>2008-09-15T10:51:42.471-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='union types'/><category scheme='http://www.blogger.com/atom/ns#' term='true unions'/><category scheme='http://www.blogger.com/atom/ns#' term='typed scheme'/><category scheme='http://www.blogger.com/atom/ns#' term='non-disjoint unions'/><category scheme='http://www.blogger.com/atom/ns#' term='ad-hoc unions'/><title type='text'>True unions, revisited</title><content type='html'>I've spoken about &lt;a href="http://calculist.blogspot.com/2008/02/true-unions.html"&gt;true unions&lt;/a&gt; (or ad-hoc unions, or non-disjoint unions) sort of abstractly before, but &lt;a href="http://www.ccs.neu.edu/home/samth/typed-scheme/"&gt;Typed Scheme&lt;/a&gt; has 'em, and they're &lt;span style="font-style: italic;"&gt;great&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;In my recent experiences with Haskell and ML, the amount of unnecessary and distracting injection and projection that goes on starts to bloat code to the point of illegibility. Disjoint unions in ML and Haskell provide two orthogonal pieces of functionality in one feature. Typed Scheme separates these two: &lt;span style="font-family:courier new;"&gt;struct&lt;/span&gt; types give you disjointness, and unions give you, well, unions. It's up to you to guarantee that you don't create unions with overlap, but so far I haven't seen that cause any problems.&lt;br /&gt;&lt;br /&gt;Then you can build disjoint unions on top of that, as I have in my new &lt;a href="http://planet.plt-scheme.org/display.ss?package=types.plt&amp;amp;owner=dherman"&gt;types.plt PLaneT package&lt;/a&gt;:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;(define-datatype Expr&lt;br /&gt; [Var ([name : Symbol])]&lt;br /&gt; [Abs ([var : Symbol] [body : Expr])]&lt;br /&gt; [App ([rator : Expr] [rand : Expr])])&lt;/pre&gt;&lt;/blockquote&gt;macro-expands to:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;(begin&lt;br /&gt; (define-struct: Var ([name : Symbol]))&lt;br /&gt; (define-struct: Abs ([var : Symbol] [body : Expr]))&lt;br /&gt; (define-struct: App ([rator : Expr] [rand : Expr]))&lt;br /&gt; (define-type-alias Expr (U Var Abs App)))&lt;/pre&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-362064541396930622?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/362064541396930622/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=362064541396930622' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/362064541396930622'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/362064541396930622'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/09/true-unions-revisited.html' title='True unions, revisited'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-9057101227245176424</id><published>2008-09-15T10:15:00.003-04:00</published><updated>2008-09-15T10:22:07.859-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='records'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><title type='text'>Scheme record syntax</title><content type='html'>I think if I were designing my own Scheme I'd tighten up some of the aspects of PLT's structs into a smaller syntactic footprint. In PLT, when you say&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;(define-struct thing (foo bar))&lt;/pre&gt;&lt;/blockquote&gt;it binds &lt;span style="font-family:courier new;"&gt;thing&lt;/span&gt; to an identifier carrying static information about the struct type (which is needed for other macros such as &lt;span style="font-family:courier new;"&gt;match&lt;/span&gt;), &lt;span style="font-family:courier new;"&gt;struct:thing&lt;/span&gt; to a runtime value containing introspective information about the struct type, and &lt;span style="font-family:courier new;"&gt;make-thing&lt;/span&gt; to a constructor for the struct type.&lt;br /&gt;&lt;br /&gt;I think I would just bind the single identifier &lt;span style="font-family:courier new;"&gt;thing&lt;/span&gt; for all three purposes: statically, it would carry the static information for &lt;span style="font-family:courier new;"&gt;match&lt;/span&gt; and friends; dynamically, it would be the constructor. (I never liked the imperative-sounding "&lt;span style="font-family:courier new;"&gt;make-&lt;/span&gt;" prefix.) For dynamic introspection, I would probably include a library form where you could say &lt;span style="font-family:courier new;"&gt;(struct foo)&lt;/span&gt; to reflect the struct type information into a dynamic value.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-9057101227245176424?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/9057101227245176424/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=9057101227245176424' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/9057101227245176424'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/9057101227245176424'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/09/scheme-record-syntax.html' title='Scheme record syntax'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-1169170658701892497</id><published>2008-08-27T08:55:00.002-04:00</published><updated>2008-08-27T09:27:05.330-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ecmascript'/><category scheme='http://www.blogger.com/atom/ns#' term='namespaces'/><category scheme='http://www.blogger.com/atom/ns#' term='harmony'/><category scheme='http://www.blogger.com/atom/ns#' term='names'/><category scheme='http://www.blogger.com/atom/ns#' term='es4'/><title type='text'>The death of namespaces</title><content type='html'>As promised in my post on &lt;a href="http://calculist.blogspot.com/2008/08/ecmascript-harmony.html"&gt;ECMAScript Harmony&lt;/a&gt;, I want to talk about the problems with the proposed namespaces feature and why I'm glad it's gone.&lt;br /&gt;&lt;br /&gt;In ES3, one of the problems for information hiding is that the language's primary datatype is a mutable table mapping transparent strings to values. As a result, sharing an object creates abstraction hazards: anyone can view -- or even modify! -- an object's internals. Namespaces were an attempt to facilitate hidden properties by generalizing objects in a backwards-compatible way.&lt;br /&gt;&lt;br /&gt;So objects became mutable tables mapping namespace/string &lt;span style="font-style: italic;"&gt;pairs&lt;/span&gt; to values. This has precedent in Common Lisp, and it seems natural. But here's where it started going awry: JavaScript has an ill-conceived history of specifying variable scope by way of a specification construct known as the &lt;span style="font-style: italic;"&gt;variable object&lt;/span&gt;: a fictional JavaScript object that serves as a rib in the lexical environment. So JavaScript variables are conceptualized as being the same thing as properties. (I'm sure I know where this came from: implementors could use the same internal mechanism to lookup properties in an object inheritance chain as for looking up variables in the environment.) So now with namespaces, variable names were not just strings but also these (namespace &amp;times; string) pairs.&lt;br /&gt;&lt;br /&gt;But namespaces were first-class values. There were even forms for qualifying variable references with a dynamically computed namespace! Lexical scope was slipping away from JavaScript as an &lt;span style="font-style: italic;"&gt;almost-was&lt;/span&gt;. Even more troubling was the concept of "open namespaces." For convenience and backwards-compatibility, there has to be a reasonable default namespace for looking up unqualified variable and field references. The proposed spec allowed &lt;span style="font-style: italic;"&gt;multiple&lt;/span&gt; namespaces to be given as candidates for defaults, with a particular search order. Now, variable lookup is tough enough in JavaScript. With bizarre dynamic constructs like &lt;span style="font-family: courier new;"&gt;with&lt;/span&gt;, lexical &lt;span style="font-family: courier new;"&gt;eval&lt;/span&gt;, and the global object, there can be two dimensions of lookup: up the environment and up the inheritance chain of an object. Now with default namespaces there was a &lt;span style="font-style: italic;"&gt;third&lt;/span&gt; dimension of lookup. For implementors, this creates all sorts of efficiency nightmares. For language users, it would likely be a usability nightmare.&lt;br /&gt;&lt;br /&gt;There are ways to simplify namespaces; even Common Lisp's approach is simpler that what was originally on the table for ECMAScript. But when I heard that namespaces, which had been a part of the proposed standard since before I got involved, were on the chopping block, I was thrilled. It had never even occurred to me that they might be cut! I proposed a simpler solution: if we just add &lt;span style="font-style: italic;"&gt;gensym&lt;/span&gt; to the operations on property names, then we can create private, unguessable properties. No property name pairs, no extra dimension of search, just opaque names. In an OO world, this is more likely to look like &lt;span style="font-family: courier new;"&gt;new Name()&lt;/span&gt; than &lt;span style="font-family: courier new;"&gt;gensym()&lt;/span&gt;, but same difference.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-1169170658701892497?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/1169170658701892497/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=1169170658701892497' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/1169170658701892497'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/1169170658701892497'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/08/death-of-namespaces.html' title='The death of namespaces'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-2059428802571250208</id><published>2008-08-27T08:34:00.004-04:00</published><updated>2008-08-27T08:54:45.228-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='harmony'/><category scheme='http://www.blogger.com/atom/ns#' term='es4'/><title type='text'>ECMAScript Harmony</title><content type='html'>There's been a lot of buzz about recent events in Ecma TC39 since &lt;a href="http://weblogs.mozillazine.org/roadmap/"&gt;Brendan Eich&lt;/a&gt; made his &lt;a href="https://mail.mozilla.org/pipermail/es-discuss/2008-August/006837.html"&gt;announcement of ECMAScript Harmony&lt;/a&gt; resulting from the seminal Oslo meeting last month. Some of the public discussion has been so misleading I won't even link to it. I've been getting a number of questions from friends and colleagues, asking if it's true that we've stopped working on ECMAScript Edition 4. I'm giving them all the same answer: don't believe the hype!&lt;br /&gt;&lt;br /&gt;As an invited expert, I try to avoid politics. But from my perspective, the Harmony effort is promising to be a great development for the technical quality of the ECMAScript standard. Both sides of the split in the committee have good technical points to make and I've longed for more cooperation. Now we have much more cooperation, and the language design is improving for it.&lt;br /&gt;&lt;br /&gt;As for the future of ECMAScript Edition 4: whatever name gets attached to it, the work on improving and standardizing ECMAScript continues apace. We'd already deferred static types for potential future work well before the Oslo meeting, and as part of the Harmony effort we dropped some of the more questionable aspects of the proposed ES4, most notably namespaces. These were not pure political concessions but in fact good technical decisions. (I'll blog about this separately.) The proposed language is changing all the time, but reports of ECMAScript's death have been grossly exaggerated.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-2059428802571250208?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/2059428802571250208/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=2059428802571250208' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/2059428802571250208'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/2059428802571250208'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/08/ecmascript-harmony.html' title='ECMAScript Harmony'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-6254240551230980876</id><published>2008-08-08T17:21:00.001-04:00</published><updated>2008-08-08T17:22:12.115-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='epiphany'/><title type='text'>Nirvana</title><content type='html'>I have achieved hygienic macro enlightenment.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-6254240551230980876?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/6254240551230980876/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=6254240551230980876' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/6254240551230980876'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/6254240551230980876'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/08/nirvana.html' title='Nirvana'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-4215633557743425251</id><published>2008-06-24T21:01:00.004-04:00</published><updated>2008-06-24T21:23:10.402-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='term rewriting'/><category scheme='http://www.blogger.com/atom/ns#' term='open recursion'/><category scheme='http://www.blogger.com/atom/ns#' term='notational definitions'/><category scheme='http://www.blogger.com/atom/ns#' term='homomorphism'/><title type='text'>Implicit homomorphism</title><content type='html'>One of the really nice features of macros and their mathematical first cousin &lt;span style="font-style: italic;"&gt;notational definitions&lt;/span&gt; is that they leave their straightforward, recursive expansion implicit. When we write in math:&lt;br /&gt;&lt;blockquote&gt;A &amp;hArr; B = A &amp;rArr; B &amp;and; B &amp;rArr; A&lt;/blockquote&gt;what we really mean is that &lt;span style="font-style: italic;"&gt;all&lt;/span&gt; occurrences of &amp;hArr; should be recursively expanded within a term. But there's essentially an implicit structural recursion through all propositions in the logic (which is left &lt;a href="http://calculist.blogspot.com/2008/06/how-to-impair-declarative.html"&gt;open "until"&lt;/a&gt; all notational definitions have been provided) which expands any occurrences of notational definitions homomorphically through sub-propositions. We don't require anyone to go through the painstaking and virtually information-free process of explicitly marking all points of recursive expansion.&lt;br /&gt;&lt;br /&gt;I would love  a similar notational style for defining &lt;span style="font-style: italic;"&gt;annotations&lt;/span&gt;. I often find myself defining an instrumentation function that inserts one or two kinds of extra pieces of information into a tree. Maybe term-rewriting would work pretty well for this. Say we're writing a function that annotates certain &amp;lambda;-expressions with their height. We could write&lt;br /&gt;&lt;blockquote&gt;&amp;lambda; &lt;span style="font-style: italic;"&gt;x&lt;/span&gt; . &lt;span style="font-style: italic;"&gt;e&lt;/span&gt; &amp;rarr; &amp;lambda;&lt;span style="font-style: italic;"&gt;&lt;/span&gt; [ |&lt;span style="font-style: italic;"&gt;e&lt;/span&gt;| ] &lt;span style="font-style: italic;"&gt;x&lt;/span&gt; . &lt;span style="font-style: italic;"&gt;e&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-style: italic;"&gt;&lt;/span&gt;and then leave the compatible, reflexive, and transitive closure of this rewriting rule implicit, since they're obvious.&lt;br /&gt;&lt;br /&gt;Then I would really like some way to make this style of definition composable with other definitions, so for example I could define a type-checking-cum-instrumentation algorithm&lt;br /&gt;&lt;blockquote&gt;&amp;Gamma; ⊢ &lt;span style="font-style: italic;"&gt;e&lt;/span&gt; : &amp;tau; &amp;rarr; &lt;span style="font-style: italic;"&gt;e'&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-style: italic;"&gt;&lt;/span&gt;where the instrumentation portion (&amp;rarr; &lt;span style="font-style: italic;"&gt;e'&lt;/span&gt;) is mostly left implicit.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-4215633557743425251?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/4215633557743425251/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=4215633557743425251' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/4215633557743425251'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/4215633557743425251'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/06/implicit-homomorphism.html' title='Implicit homomorphism'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-7075762723985270367</id><published>2008-06-17T19:25:00.003-04:00</published><updated>2008-06-17T20:06:04.366-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='open recursion'/><category scheme='http://www.blogger.com/atom/ns#' term='declarative programming'/><category scheme='http://www.blogger.com/atom/ns#' term='imperative programming'/><title type='text'>How to impair a declarative</title><content type='html'>Declarative programming is a vague term but could loosely be interpreted to mean &lt;span style="font-style: italic;"&gt;not imperative programming&lt;/span&gt;. It's also about defining a program by breaking it into separate, modular units of partial specification.&lt;br /&gt;&lt;br /&gt;Of course, the language's semantics has to have some algorithmic means to combine these declarations into a complete program definition. And if the language admits recursive definitions, the combined program may contains cycles. So the implementation of a declarative language will often have an imperative flavor, combining recursive elements by incrementally updating the set of definitions.&lt;br /&gt;&lt;br /&gt;The question is whether it is still possible for the user to understand the semantics without resorting to reasoning about its possibly-imperative implementation. Specifically, the user shouldn't have to worry about &lt;span style="font-style: italic;"&gt;time&lt;/span&gt;. If the order in which definitions are combined matters, then the semantics becomes imperative. Worse, if the programming interface allows definitions in multiple files, the order of definition might not even be under the user's control--or worse, it might only be controllable through extra-linguistic means like compiler command-line arguments.&lt;br /&gt;&lt;br /&gt;Take as an example a language with &lt;span style="font-style: italic;"&gt;open recursion&lt;/span&gt;, the ability to define a recursive function in multiple, disparate pieces. If an open recursive function has overlapping cases in separate declarations, the language can handle this in one of several ways:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Let rules defined "later" take precedence over rules defined "earlier."&lt;/li&gt;&lt;li&gt;Define a total order on rule specificity, and let more specific rules take precedence over less specific rules.&lt;/li&gt;&lt;li&gt;Disallow overlapping cases statically.&lt;/li&gt;&lt;/ol&gt;Option #1 reintroduces the notion of time. The resulting semantics is less modular, because it requires understanding not just the individual modules, but subtle aspects of their composition. (If the algorithm for combining definitions is sophisticated--unification, for example--this order may even be a complicated dynamic notion, not just textual order.) The other two options eliminate the imperative flavor, defining time out of the semantics. This frees the programmer to reorder definitions without affecting the program's meaning, and making the program's meaning more modular.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-7075762723985270367?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/7075762723985270367/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=7075762723985270367' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/7075762723985270367'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/7075762723985270367'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/06/how-to-impair-declarative.html' title='How to impair a declarative'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-1250703465697182857</id><published>2008-06-17T19:19:00.003-04:00</published><updated>2008-06-17T19:25:32.620-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='expression closures'/><category scheme='http://www.blogger.com/atom/ns#' term='ADT'/><title type='text'>ADTs in JavaScript</title><content type='html'>&lt;a href="http://w3future.com/weblog/"&gt;Sjoerd Visscher&lt;/a&gt; has written a neat post about implementing &lt;a href="http://w3future.com/weblog/stories/2008/06/16/adtinjs.xml"&gt;algebraic data types in JavaScript&lt;/a&gt;. There are lots of ways to do this, but this one looks interesting. I don't quite understand it but I thought I'd point it out.&lt;br /&gt;&lt;br /&gt;Note the use of &lt;a href="http://developer.mozilla.org/en/docs/New_in_JavaScript_1.8#Expression_closures"&gt;expression closures&lt;/a&gt;! Good stuff.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-1250703465697182857?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/1250703465697182857/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=1250703465697182857' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/1250703465697182857'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/1250703465697182857'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/06/adts-in-javascript.html' title='ADTs in JavaScript'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-8067392014501816567</id><published>2008-06-12T08:45:00.003-04:00</published><updated>2008-06-12T08:57:02.944-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bleg'/><category scheme='http://www.blogger.com/atom/ns#' term='scope in logic'/><title type='text'>Clumsy existential</title><content type='html'>This might be a dumb question: I often want to prove something like this:&lt;br /&gt;&lt;blockquote&gt;(&amp;exist; &lt;span style="font-style: italic;"&gt;v&lt;/span&gt; . &lt;span style="font-style: italic;"&gt;e&lt;/span&gt; &amp;rArr; &lt;span style="font-style: italic;"&gt;v&lt;/span&gt;) &amp;hArr; (&amp;exist; &lt;span style="font-style: italic;"&gt;v&lt;span style="font-style: italic;"&gt;&amp;prime;&lt;/span&gt;&lt;/span&gt; ~ &lt;span style="font-style: italic;"&gt;v&lt;/span&gt; . [[&lt;span style="font-style: italic;"&gt;e&lt;/span&gt;]] &amp;rArr; &lt;span style="font-style: italic;"&gt;v&amp;prime;&lt;/span&gt;)&lt;/blockquote&gt;except that the scope doesn't work out: &lt;span style="font-style: italic;"&gt;v&lt;/span&gt; is only in scope in the first parenthesized proposition, so it can't be referred to in the second one. Of course, it's generally sufficient to prove co-termination and just leave out the relationship between the final values, since that's usually easily derivable. But it's an important part of the intuition behind correctness, so I want the relationship between answers to be in the statement of the theorem.&lt;br /&gt;&lt;br /&gt;An awkward way to make this work is to write big clunky conjunctions like:&lt;br /&gt;&lt;blockquote&gt;(&lt;span style="font-style: italic;"&gt;e&lt;/span&gt;&amp;dArr; &amp;hArr; [[&lt;span style="font-style: italic;"&gt;e&lt;/span&gt;]]&amp;dArr;) &amp;and; (&amp;forall; &lt;span style="font-style: italic;"&gt;v&lt;/span&gt; . &lt;span style="font-style: italic;"&gt;e&lt;/span&gt; &amp;rArr; &lt;span style="font-style: italic;"&gt;v&lt;/span&gt; . &amp;exist; &lt;span style="font-style: italic;"&gt;v&amp;prime;&lt;/span&gt; ~ &lt;span style="font-style: italic;"&gt;v&lt;/span&gt; . [[&lt;span style="font-style: italic;"&gt;e&lt;/span&gt;]] &amp;rArr; &lt;span style="font-style: italic;"&gt;v&amp;prime;&lt;/span&gt;)&lt;/blockquote&gt;But it would be nice if there were some way to write it more compactly like the first pseudo-proposition I wrote. I like that it reads almost like you'd say in English: "&lt;span style="font-style: italic;"&gt;e&lt;/span&gt; and [[&lt;span style="font-style: italic;"&gt;e&lt;/span&gt;]] always get the same answers."&lt;br /&gt;&lt;br /&gt;Anyone have any suggestions?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-8067392014501816567?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/8067392014501816567/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=8067392014501816567' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/8067392014501816567'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/8067392014501816567'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/06/clumsy-existential.html' title='Clumsy existential'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-1646004516966598617</id><published>2008-05-20T15:10:00.002-04:00</published><updated>2008-05-20T15:12:44.347-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='operators'/><title type='text'>The bat-signal operator</title><content type='html'>Starting now, I propose that every programming language strive to incorporate the &lt;span style="font-style: italic;"&gt;bat-signal operator&lt;/span&gt;: &lt;span style="font-family: courier new;"&gt;~@~&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-1646004516966598617?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/1646004516966598617/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=1646004516966598617' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/1646004516966598617'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/1646004516966598617'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/05/bat-signal-operator.html' title='The bat-signal operator'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-163705583424799859</id><published>2008-05-16T10:29:00.002-04:00</published><updated>2008-05-16T10:35:50.535-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fail-soft'/><category scheme='http://www.blogger.com/atom/ns#' term='error recovery'/><title type='text'>Fail-soft</title><content type='html'>Automatically repairing errors and continuing execution goes against the grain of software engineering, for good reason, but I've come to see that it's what makes the web go 'round. &lt;a href="http://weblogs.mozillazine.org/roc/"&gt;Robert O'Callahan&lt;/a&gt; has an interesting &lt;a href="http://weblogs.mozillazine.org/roc/archives/2008/05/status_5.html"&gt;market-oriented take on error recovery&lt;/a&gt;:&lt;br /&gt;&lt;blockquote&gt;...the economics of error recovery --- the fact that recovering from malformed input, instead of hard failure, is a competitive advantage for client software so in a competitive market it's sure to develop and you might as well put it in specifications...&lt;/blockquote&gt;In other words: ignore the errors, users will love you, and you win. We may not like it, but you fight economics at your own peril.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-163705583424799859?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/163705583424799859/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=163705583424799859' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/163705583424799859'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/163705583424799859'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/05/fail-soft.html' title='Fail-soft'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-1473670991556918293</id><published>2008-05-09T11:02:00.005-04:00</published><updated>2008-05-09T11:46:52.093-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='operator overloading'/><category scheme='http://www.blogger.com/atom/ns#' term='logical operators'/><title type='text'>N-ary infix predicates</title><content type='html'>In languages with operator overloading, it's possible to define binary infix predicates such as (using Haskell here):&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;infix &amp;lt;:&lt;br /&gt;(&amp;lt;:) :: Ty -&amp;gt; Ty -&amp;gt; Bool&lt;br /&gt;x &amp;lt;: y = x `subtype` y -- for some auxiliary subtype function&lt;/pre&gt;&lt;/blockquote&gt;With arithmetic operators that continue to return elements of the same type (does this make their types endofunctors? I'm no category theorist), so as long as you declare an associativity, the &lt;span style="font-style: italic;"&gt;n&lt;/span&gt;-ary case is easy to parse. Predicates aren't closed over their input type, though, so in Haskell I can't take the above definition and write:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;t1 &amp;lt;: t2 &amp;lt;: t3&lt;/pre&gt;&lt;/blockquote&gt;But in math, we overload binary predicates to the &lt;span style="font-style: italic;"&gt;n&lt;/span&gt;-ary case by assuming an implicit "and" between each pair. It would just take a little kludge (but one with the full weight of historical precedent) to let the operator overloading and type system conspire to determine that any binary predicate (i.e., with result type &lt;span style="font-family:courier new;"&gt;Bool&lt;/span&gt;) can be extended to the &lt;span style="font-style: italic;"&gt;n&lt;/span&gt;-ary case using &lt;span style="font-family:courier new;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;(You could maybe also extend this to any type &lt;span style="font-family:courier new;"&gt;Monad m =&amp;gt; m a&lt;/span&gt; using &lt;span style="font-family:courier new;"&gt;&amp;gt;&amp;gt;=&lt;/span&gt; instead of &lt;span style="font-family:courier new;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="font-family: lucida grande;"&gt;&lt;/span&gt;?)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-1473670991556918293?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/1473670991556918293/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=1473670991556918293' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/1473670991556918293'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/1473670991556918293'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/05/n-ary-infix-predicates.html' title='N-ary infix predicates'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-3185951038150933447</id><published>2008-05-08T17:02:00.003-04:00</published><updated>2008-05-08T17:04:57.685-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='eureka'/><category scheme='http://www.blogger.com/atom/ns#' term='research progress'/><title type='text'>Solving the wrong problem</title><content type='html'>I've been having a depressing couple of weeks trying to solve a really hard problem in my research. Occasionally I thought I had some promising leads, but usually they just led to more despair.&lt;br /&gt;&lt;br /&gt;Then I discovered today that I've been tackling the entirely wrong problem all along.&lt;br /&gt;&lt;br /&gt;I never knew feeling so stupid could feel so good.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-3185951038150933447?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/3185951038150933447/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=3185951038150933447' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/3185951038150933447'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/3185951038150933447'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/05/solving-wrong-problem.html' title='Solving the wrong problem'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-4176060845261450532</id><published>2008-05-05T12:38:00.002-04:00</published><updated>2008-05-05T12:53:21.029-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nancy'/><category scheme='http://www.blogger.com/atom/ns#' term='NaN'/><category scheme='http://www.blogger.com/atom/ns#' term='not-a-number'/><title type='text'>Sigh</title><content type='html'>&lt;blockquote&gt;&lt;pre&gt;&amp;gt; (eqv? +NaN.0 +NaN.0)&lt;br /&gt;#t&lt;br /&gt;&amp;gt; (eq? +NaN.0 +NaN.0)&lt;br /&gt;#t&lt;br /&gt;&amp;gt; (= +NaN.0 +NaN.0)&lt;br /&gt;#f&lt;br /&gt;&amp;gt; (equal? +NaN.0 +NaN.0)&lt;br /&gt;#t&lt;/pre&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-4176060845261450532?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/4176060845261450532/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=4176060845261450532' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/4176060845261450532'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/4176060845261450532'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/05/sigh.html' title='Sigh'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-2457256108477337108</id><published>2008-05-05T09:32:00.004-04:00</published><updated>2008-05-05T10:34:08.915-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fold'/><category scheme='http://www.blogger.com/atom/ns#' term='traversal'/><category scheme='http://www.blogger.com/atom/ns#' term='visitor pattern'/><title type='text'>A functional visitor pattern</title><content type='html'>When your data definitions get big enough, it becomes Tedious and Error-Prone (oh my!) to write multiple operations over the same datatype, so it's useful to define a generic traversal. Here's a pattern I used recently for the &lt;a href="http://www.ecmascript.org/download.php"&gt;ECMAScript Edition 4 reference implementation&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Lots of languages have mutually recursive AST definitions. For example, take a language with mutually recursive expressions &lt;span style="font-family:courier new;"&gt;Ast.expr&lt;/span&gt;, statements &lt;span style="font-family:courier new;"&gt;Ast.stmt&lt;/span&gt;, and declarations &lt;span style="font-family:courier new;"&gt;Ast.decl&lt;/span&gt;. Define an interface &lt;span style="font-family:courier new;"&gt;VISITOR&lt;/span&gt;:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;signature VISITOR = sig&lt;br /&gt;    datatype cmd = Stop | Skip | Cont&lt;br /&gt;&lt;br /&gt;    type ('a, 'z) method = 'a * 'z -&gt; 'z * cmd&lt;br /&gt;&lt;br /&gt;    type 'z visitor = { visitExpr : (Ast.expr, 'z) method,&lt;br /&gt;                        visitStmt : (Ast.stmt, 'z) method,&lt;br /&gt;                        visitDecl : (Ast.decl, 'z) method }&lt;br /&gt;&lt;br /&gt;    val foldExpr : 'z visitor * Ast.expr * 'z -&gt; 'z&lt;br /&gt;    val foldStmt : 'z visitor * Ast.stmt * 'z -&gt; 'z&lt;br /&gt;    val foldDecl : 'z visitor * Ast.decl * 'z -&gt; 'z&lt;br /&gt;end;&lt;/pre&gt;&lt;/blockquote&gt;A visitor is a record of operations, one for each variant of AST nodes. (Alternatively, we could have defined a single type &lt;span style="font-family:courier new;"&gt;datatype ast = Expr of ... | Stmt of ... | Decl of ...;&lt;/span&gt;. But there's no need for the extra indirection.) Each operation takes a node and an intermediate result, and produces a new intermediate result along with a "traversal command" &lt;span style="font-family:courier new;"&gt;cmd&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;This simple traversal language instructs the fold either to continue (&lt;span style="font-family:courier new;"&gt;Cont&lt;/span&gt;), to skip all descendants of the current node (&lt;span style="font-family:courier new;"&gt;Skip&lt;/span&gt;), or to abort the traversal entirely (&lt;span style="font-family:courier new;"&gt;Stop&lt;/span&gt;).&lt;br /&gt;&lt;br /&gt;The implementation of the fold uses a few auxiliary functions to compute a list of child nodes for each node:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;type children = Ast.expr list * Ast.stmt list * Ast.decl list&lt;br /&gt;&lt;br /&gt;fun exprChildren (e : Ast.expr) : children = ...&lt;br /&gt;fun stmtChildren (e : Ast.stmt) : children = ...&lt;br /&gt;fun declChildren (e : Ast.decl) : children = ...&lt;/pre&gt;&lt;/blockquote&gt;The fold itself is (internally) in CPS. At each node, there are three potential continuations: the empty continuation for aborting, the given continuation for skipping the current node's children, or a new continuation that first traverses the current node's children and then uses the given continuation.&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;type 'z cont = 'z -&gt; 'z&lt;br /&gt;&lt;br /&gt;fun cont (result : 'z, cmd : cmd)&lt;br /&gt;         (skipk : 'z cont)&lt;br /&gt;         (contk : 'z cont)&lt;br /&gt;    : 'z =&lt;br /&gt;    case cmd of&lt;br /&gt;        Stop =&gt; result&lt;br /&gt;      | Skip =&gt; skipk result&lt;br /&gt;      | Cont =&gt; contk result&lt;br /&gt;&lt;br /&gt;fun foldExprK (v as { visitExpr, ... }, expr, init) k =&lt;br /&gt;    cont (visitExpr (expr, init))&lt;br /&gt;         (fn x =&gt; foldAllK v (exprChildren expr) x k)&lt;br /&gt;         k&lt;br /&gt;&lt;br /&gt;and foldStmtK (v as { visitStmt, ... }, stmt, init) k =&lt;br /&gt;    cont (visitStmt (stmt, init))&lt;br /&gt;         (fn x =&gt; foldAllK v (stmtChildren stmt) x k)&lt;br /&gt;         k&lt;br /&gt;&lt;br /&gt;and foldDeclK (v as { visitDecl, ... }, decl, init) k =&lt;br /&gt;    cont (visitDecl (decl, init))&lt;br /&gt;         (fn x =&gt; foldAllK v (declChildren decl) x k)&lt;br /&gt;         k&lt;br /&gt;&lt;br /&gt;and foldAllK (v : 'z visitor)&lt;br /&gt;             ((exprs, stmts, decls) : children)&lt;br /&gt;             (init : 'z)&lt;br /&gt;             (k : 'z cont)&lt;br /&gt;    : 'z =&lt;br /&gt;    let&lt;br /&gt;        fun foldList f (v, asts, init) k =&lt;br /&gt;            case asts of&lt;br /&gt;                [] =&gt; k init&lt;br /&gt;              | [ast] =&gt; f (v, ast, init) k&lt;br /&gt;              | ast::asts =&gt; f (v, ast, init)&lt;br /&gt;                               (fn x =&gt; foldList f (v, asts, x) k)&lt;br /&gt;    in&lt;br /&gt;        foldList foldExprK (v, exprs, init) (fn result =&gt;&lt;br /&gt;            foldList foldStmtK (v, stmts, result) (fn result =&gt;&lt;br /&gt;                foldList foldDeclK (v, decls, result) k))&lt;br /&gt;    end&lt;/pre&gt;&lt;/blockquote&gt;I originally had &lt;span style="font-family:courier new;"&gt;foldList&lt;/span&gt; defined at the top-level, in the same mutual recursion group with &lt;span style="font-family:courier new;"&gt;foldExprK&lt;/span&gt; et al, and got smacked by SML because that would require &lt;a href="http://www.church-project.org/reports/Hal+Kfo:BUCS-TR-2004-004.html"&gt;polymorphic recursion&lt;/a&gt;. Luckily I was able to work around it by placing its definition inside the body of &lt;span style="font-family:courier new;"&gt;foldAllK&lt;/span&gt;, but since I'd never run into SML's lack of polymorphic recursion before, it took quite a while to decipher the type error (with help from &lt;span style="font-family:courier new;"&gt;#sml&lt;/span&gt;).&lt;br /&gt;&lt;br /&gt;Finally, the top-level functions seed the CPS functions with an initial continuation:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;fun id x = x&lt;br /&gt;&lt;br /&gt;fun foldExpr x = foldExprK x id&lt;br /&gt;fun foldStmt x = foldStmtK x id&lt;br /&gt;fun foldDecl x = foldDeclK x id&lt;/pre&gt;&lt;/blockquote&gt;(Note that because of the &lt;a href="http://calculist.blogspot.com/2008/05/arent-auto-curried-functions-non.html"&gt;value restriction&lt;/a&gt;, there's no possibility of refactoring these into point-free &lt;span style="font-family:courier new;"&gt;val&lt;/span&gt;-declarations.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-2457256108477337108?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/2457256108477337108/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=2457256108477337108' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/2457256108477337108'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/2457256108477337108'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/05/functional-visitor-pattern.html' title='A functional visitor pattern'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-2095690700147884977</id><published>2008-05-05T07:28:00.002-04:00</published><updated>2008-05-05T07:36:18.640-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='auto-currying'/><category scheme='http://www.blogger.com/atom/ns#' term='value restriction'/><category scheme='http://www.blogger.com/atom/ns#' term='eta'/><category scheme='http://www.blogger.com/atom/ns#' term='refactoring'/><title type='text'>Aren't auto-curried functions non-expansive?</title><content type='html'>The value restriction in ML is so limited. If I have an auto-curried function&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&amp;gt; fun foo (k : int -&gt; 'a) (x : int) = ...;&lt;/pre&gt;&lt;/blockquote&gt;it should be the case that partial application of foo is always non-expansive, right? It's really annoying that partial applications of auto-curried functions often can't be given general types.&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&amp;gt; val raisek (x : int) = raise (Fail (Int.toString x));&lt;br /&gt;&amp;gt; val fooRaise = foo raisek;&lt;br /&gt;Warning: type vars not generalized because of value restriction...&lt;/pre&gt;&lt;/blockquote&gt;I hate when the type system interferes with standard, semantics-preserving transformations.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-2095690700147884977?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/2095690700147884977/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=2095690700147884977' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/2095690700147884977'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/2095690700147884977'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/05/arent-auto-curried-functions-non.html' title='Aren&apos;t auto-curried functions non-expansive?'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-2901183776061890729</id><published>2008-04-30T09:18:00.003-04:00</published><updated>2008-04-30T10:22:58.329-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='REPL'/><category scheme='http://www.blogger.com/atom/ns#' term='modules'/><category scheme='http://www.blogger.com/atom/ns#' term='dynamic languages'/><title type='text'>Dynamic languages need modules</title><content type='html'>A dynamic language starts as an implementation. And that implementation almost always includes some variation on a REPL. Look at Lisp, Scheme, Python, Ruby, JavaScript, Lua, etc. One of the things that makes these languages "dynamic" is that they're attached to some long-running process: an IDE, a user prompt, an embedding application, a web page. So these languages are simply implemented with some global table of definitions that gets updated through the lifetime of the host process. Easy enough to understand from the implementor's perspective, but what happens to the user of the embedded language?&lt;br /&gt;&lt;br /&gt;The problem with the "top-level" (that ever-changing table of program definitions) is the creeping specter of &lt;a href="http://calculist.blogspot.com/search?q=dynamic+scope"&gt;dynamic scope&lt;/a&gt;. While static vs. dynamic typing may be a debate that civilization takes to its grave, the dust seems to have more or less settled on dynamic scoping. The fact is, even though many decisions a program makes must depend on its context, it's very hard to understand a program if you can't nail down its definitions.&lt;br /&gt;&lt;br /&gt;To some degree, if a dynamic language has &lt;span style="font-family: courier new;"&gt;lambda&lt;/span&gt;, you can escape the top-level with a design pattern that simulates a poor man's module. The &lt;a href="http://www.google.com/search?q=javascript+module+pattern"&gt;module pattern&lt;/a&gt; is almost always a variation of what Schemers call "left-left-lambda"--the immediate application of a function literal. Bindings inside the &lt;span style="font-family: courier new;"&gt;lambda&lt;/span&gt; are no longer floating in that airy and transient stratosphere of the top-level; they're nailed to the function that is being applied. And you know that function is being applied only once, because once you've created it, it's applied an discarded.&lt;br /&gt;&lt;br /&gt;This pattern goes a long way, and if you have macros, you can create sugar to give the pattern linguistic status. But a module system it ain't.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Linking&lt;span style="font-weight: bold;"&gt;:&lt;/span&gt;&lt;/span&gt; Nothing in this pattern deals with the relationships between modules. There's no way to declare what a module's imports and exports are. In fact, if you want a module to communicate with any other modules, the top-level's poison tends to seep back in. To export a value, a &lt;span style="font-family: courier new;"&gt;lambda&lt;/span&gt;-module can mutate some global variable, or it can return a value--but where does the caller save the value? You can always nest these solutions within more &lt;span style="font-family: courier new;"&gt;lambda&lt;/span&gt;-modules, but ultimately there's a problem of infinite regress: in the end you have to have at least one special top-most module surrounding your program.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Separate development:&lt;/span&gt; And that's only if you have control over the whole program. If you want to create a library and share it, there needs to be some shared common framework in which people and organizations can share code without stomping on each other's invariants or polluting each other's global environments. To be sure, a built-in module system doesn't eliminate all such issues (you still need conventions for naming and registering modules within a common framework), but modules help to standardize on these issues, and they can provide helpful errors when modules step on each other's toes, rather than silently overwriting one another.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Loading:&lt;/span&gt; There's not much flexibility in the loading of an immediately applied function. If your language involves multiple stages of loading, the implementation may be able to be smarter about loading and linking multiple modules at once.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Scoping conveniences:&lt;/span&gt; Lexical scope is a widget in the programmer's UI toolkit, and for different scenarios, there are different appropriate designs. The tree shape of expressions makes the lexical scoping rule ("inner trumps outer") appropriate; it favors the local over the global. But, ignoring nested modules for the moment, modules aren't tree shaped; they're more like a global table. In a sense, all modules are peers. So when you import the same name from two different modules, which one should win? You could say that whichever you import later wins, but this is much more subtle than the obvious nesting structure of ordinary variable bindings. I find it's more helpful for the module system to give me an error if I import the same name from different sources (unless it's a diamond import). Other useful facilities are selective import, import with renaming, or import with common prefixes. These are subtle usability designs where modules differ from &lt;span style="font-family: courier new;"&gt;lambda&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Extensibility:&lt;/span&gt; In &lt;a href="http://www.plt-scheme.org/"&gt;PLT Scheme&lt;/a&gt;, we've used the module system as the point for language design and extension. By allowing modules to be parameterized over their "language", we have a natural way for introducing modalities into PLT Scheme. As languages grow, these modalities are an inevitability (cf. "&lt;a href="http://perldoc.perl.org/strict.html"&gt;&lt;span style="font-family: courier new;"&gt;use strict&lt;/span&gt;&lt;/a&gt;" in Perl and &lt;a href="http://www.ecmascript.org"&gt;ECMAScript Edition 4&lt;/a&gt;). Buried within pragmas or nested expressions, this makes the design of the language much harder. But within a module, bindings are sacrosanct and interactions with other modules are limited to imports and exports. This significantly cuts down on the space of possible interactions and interferences between the language's modalities. As an example, &lt;a href="http://www.ccs.neu.edu/home/samth/"&gt;Sam Tobin-Hochstadt&lt;/a&gt; has made good use of this for the design of &lt;a href="http://www.ccs.neu.edu/home/samth/typed-scheme/"&gt;Typed Scheme&lt;/a&gt;, a statically typed modality of PLT Scheme that can still interact reliably with dynamically typed modules.&lt;br /&gt;&lt;br /&gt;The unrestricted mutation of the top-level environment is a good thing thing for many purposes: interactive development, self-adjusting execution environments, etc. But it's terrible for nailing down program definitions. Modules are a way of circumscribing a portion of code and declaring it "finished". It can still be useful to have an environment where modules can be dynamically loaded and possibly even replaced, but it's critical for the language to provide the programmer with basic invariants about the definitions within a module.&lt;br /&gt;&lt;br /&gt;All of this is stuff I wish I'd had a clearer head about earlier in the ES4 process. But I hope that, down the road, we'll consider a module system for ECMAScript.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-2901183776061890729?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/2901183776061890729/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=2901183776061890729' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/2901183776061890729'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/2901183776061890729'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/04/dynamic-languages-need-modules.html' title='Dynamic languages need modules'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-4930619817628981949</id><published>2008-04-28T17:26:00.002-04:00</published><updated>2008-04-28T17:33:34.582-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='literate code'/><title type='text'>Literate code</title><content type='html'>I used to find the notion of literate code attractive, but right now my dissertation prototype implementation is undergoing some serious redevelopment and the horribly out-of-date docs are dragging me down. Now I find myself wishing I'd kept them separate.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-4930619817628981949?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/4930619817628981949/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=4930619817628981949' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/4930619817628981949'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/4930619817628981949'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/04/literate-code.html' title='Literate code'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-3861985410942974730</id><published>2008-04-22T09:55:00.004-04:00</published><updated>2008-04-22T10:06:14.771-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='StopIteration'/><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript 1.7'/><category scheme='http://www.blogger.com/atom/ns#' term='mutable globals'/><title type='text'>How to spell StopIteration</title><content type='html'>Some of the pseudo-constants in JavaScript are actually mutable global variables: &lt;span style="font-family: courier new;"&gt;undefined&lt;/span&gt; is a notorious example. Luckily, there's generally some reliable way to generate such a value without having to hope that no one has reassigned a global variable.&lt;br /&gt;&lt;br /&gt;For &lt;span style="font-family: courier new;"&gt;undefined&lt;/span&gt;, it's the &lt;span style="font-family: courier new;"&gt;void&lt;/span&gt; operator, which, given any argument, produces the value that &lt;span style="font-family: courier new;"&gt;undefined&lt;/span&gt; is initially bound to. Conventionally, people write &lt;span style="font-family: courier new;"&gt;void(0)&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;In &lt;a href="http://developer.mozilla.org/en/docs/New_in_JavaScript_1.7"&gt;JavaScript 1.7&lt;/a&gt; and later, there's a special constant called &lt;span style="font-family: courier new;"&gt;StopIteration&lt;/span&gt; that's thrown after an &lt;a href="http://developer.mozilla.org/en/docs/New_in_JavaScript_1.7#Generators_and_iterators"&gt;iterator&lt;/a&gt; runs out of values. This too is a mutable global. But this value is a little trickier to get at reliably. Here's the simplest expression I could come up with that produces the &lt;span style="font-family: courier new;"&gt;StopIteration&lt;/span&gt; value:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;(function(){try{(function(){true||(yield)})().next()}catch(e){return e}})()&lt;/pre&gt;&lt;/blockquote&gt;The inner function is a generator by virtue of textually containing the &lt;span style="font-family: courier new;"&gt;yield&lt;/span&gt; keyword, but it returns immediately, yielding no values, because of the short-circuited logical &lt;span style="font-style: italic;"&gt;or&lt;/span&gt;. (Note that because of &lt;span style="font-family: courier new;"&gt;yield&lt;/span&gt;'s finicky grammar, it has to be parenthesized.) So by calling &lt;span style="font-family: courier new;"&gt;next()&lt;/span&gt; on it, it immediately raises &lt;span style="font-family: courier new;"&gt;StopIteration&lt;/span&gt;, which the outer function catches and returns.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-3861985410942974730?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/3861985410942974730/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=3861985410942974730' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/3861985410942974730'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/3861985410942974730'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/04/how-to-spell-stopiteration.html' title='How to spell StopIteration'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-2238416419809870585</id><published>2008-04-20T00:53:00.002-04:00</published><updated>2008-04-20T00:59:43.528-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='compilation'/><category scheme='http://www.blogger.com/atom/ns#' term='obfuscation'/><category scheme='http://www.blogger.com/atom/ns#' term='encryption'/><category scheme='http://www.blogger.com/atom/ns#' term='Futamura projections'/><title type='text'>Compilation, obfuscation, encryption</title><content type='html'>It's interesting that we tend to use compilation as a proxy for encryption. It seems to me it would help clarify the system design of a language semantics and architecture if you separate the concerns of code ownership with performance. Compilation is primarily used to cache the transformation of one semantics into another--a &lt;a href="http://en.wikipedia.org/wiki/Partial_evaluation"&gt;partial evaluation of an interpreter&lt;/a&gt;. Using this as a weak encryption mechanism is pretty silly. If you want to encrypt program source, why not use real encryption? That way you can use whatever representation of the code you want; source, byte-code, microcode, whatever.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-2238416419809870585?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/2238416419809870585/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=2238416419809870585' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/2238416419809870585'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/2238416419809870585'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/04/compilation-obfuscation-encryption.html' title='Compilation, obfuscation, encryption'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-9210477345416193964</id><published>2008-04-11T09:13:00.003-04:00</published><updated>2008-04-11T09:23:54.752-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='builders and defenders'/><title type='text'>A poem for the weekend</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/__OULbbSCQyc/R_9kPSHYvKI/AAAAAAAAAAs/xepho2wDCbo/s1600-h/hm.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://3.bp.blogspot.com/__OULbbSCQyc/R_9kPSHYvKI/AAAAAAAAAAs/xepho2wDCbo/s200/hm.png" alt="" id="BLOGGER_PHOTO_ID_5187975509477735586" border="0" /&gt;&lt;/a&gt;&lt;span style="font-size:130%;"&gt;Listen to Mustn'ts, child, listen to the Don'ts.&lt;br /&gt; Listen to the Shouldn'ts, the Impossibles, the Won'ts.&lt;br /&gt; Listen to the Never Haves, then listen close to me.&lt;br /&gt;Anything can happen, child, Anything can be.&lt;/span&gt;&lt;br /&gt;--&lt;span style="font-style: italic;"&gt;Shel Silverstein&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/__OULbbSCQyc/R_9kYyHYvLI/AAAAAAAAAA0/v0dwnWJcJ4A/s1600-h/Etoys1.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://1.bp.blogspot.com/__OULbbSCQyc/R_9kYyHYvLI/AAAAAAAAAA0/v0dwnWJcJ4A/s200/Etoys1.png" alt="" id="BLOGGER_PHOTO_ID_5187975672686492850" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-9210477345416193964?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/9210477345416193964/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=9210477345416193964' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/9210477345416193964'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/9210477345416193964'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/04/poem-for-weekend.html' title='A poem for the weekend'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/__OULbbSCQyc/R_9kPSHYvKI/AAAAAAAAAAs/xepho2wDCbo/s72-c/hm.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10770855.post-1099358164697374077</id><published>2008-04-08T09:11:00.002-04:00</published><updated>2008-04-08T09:22:21.337-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='generics'/><category scheme='http://www.blogger.com/atom/ns#' term='parameterized types'/><category scheme='http://www.blogger.com/atom/ns#' term='porous abstractions'/><title type='text'>Different perspectives on parameterized types</title><content type='html'>To the PL theorist, parameterized types are a necessity for the &lt;span style="font-style: italic;"&gt;expressiveness &lt;/span&gt;of a statically typed language. Imagine Hindley-Milner without them: you'd have to duplicate definitions all over the place. But in practice, statically typed languages have loopholes--long before generics, Java always had the type &lt;span style="font-family: courier new;"&gt;Object&lt;/span&gt; so that you could essentially "turn off" type-checking when you couldn't type things precisely. This meant that you could always write generic operations and generic collections, but without type-checking.&lt;br /&gt;&lt;br /&gt;So in practice, people don't look at parameterized types as increasing the expressiveness of Java at all; it just looks like a way to increase the amount of type-checking in the language, to make it &lt;span style="font-style: italic;"&gt;stricter&lt;/span&gt;. And they're right.&lt;br /&gt;&lt;br /&gt;So you have two correct perspectives on parameterized types: roughly, that they make the language less restrictive and more restrictive. It's not actually a contradiction, but it's enough to have caused me confusion in some conversations.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10770855-1099358164697374077?l=calculist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://calculist.blogspot.com/feeds/1099358164697374077/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10770855&amp;postID=1099358164697374077' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/1099358164697374077'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10770855/posts/default/1099358164697374077'/><link rel='alternate' type='text/html' href='http://calculist.blogspot.com/2008/04/different-perspectives-on-parameterized.html' title='Different perspectives on parameterized types'/><author><name>Dave Herman</name><uri>http://www.blogger.com/profile/00405190527081772997</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos17.flickr.com/19806846_e369431965.jpg?v=0'/></author><thr:total>1</thr:total></entry></feed>
