tag:blogger.com,1999:blog-24471741028135390492024-03-18T05:13:17.127-07:00Room 101A place to be (re)educated in NewspeakGilad Brachahttp://www.blogger.com/profile/17934280339206214042noreply@blogger.comBlogger75125tag:blogger.com,1999:blog-2447174102813539049.post-12860865321378776502022-08-15T23:17:00.000-07:002022-08-15T23:17:06.112-07:00What You Want Is What You GetHow do we resolve the classic tension between WYSIWYG and markup . Alas, one can't explain that properly in blogger, but if you follow <a href="https://blog.bracha.org/WYWIWYG/out/WYWIWYG.html?snapshot=WYWIWYGApp.vfuel">this link</a>, you'll see what I mean.
Gilad Brachahttp://www.blogger.com/profile/17934280339206214042noreply@blogger.com7tag:blogger.com,1999:blog-2447174102813539049.post-37952581454645414432022-06-30T21:10:00.000-07:002022-06-30T21:10:01.492-07:00The Prospect of an Execution: The Hidden Objects Among Us<i>Depend upon it, Sir, when a man knows he is to be hanged in a fortnight, it concentrates his mind wonderfully.</i>
<br>
-- Samuel Johnson
<br><br>
I wish to concentrate your mind, gentle reader, by focusing on an execution (not yours of course! I see you are already losing focus - no matter ...). My goal is to make you see the objects that are in front of you every day, hiding in plain sight.
<br><br>
So who are we executing? Or what? The condemned operates under a wide variety of aliases that obscure its true nature: <i>a.out</i> alias <i>.exe</i> alias <i>ELF file</i> alias <i>binary</i> and more. I mean to expose the identity that hides beneath these guises: it is an object!
<br><br>
When we run an executable file, we call a function in that file, and that function accesses the data in the file, possibly calling other functions in the same file recursively. Replace <i>function</i> with <i>method</i>, <i>call</i> with <i>invoke</i> and <i>file</i> with <i>object</i> in the previous sentence and you will begin to see what I mean:
<br><br>
When we run an executable object, we invoke a method in that object, and that method accesses the data in the object, possibly invoking other methods in the same object recursively.
<br><br>
The initial function, the entry point, is often called <i>main()</i>.
Consider the venerable <i>a.out
</i>: it is a serialized object on disk. When the system loads it, it's deserializing it. The system then invokes the object's <i>main()</i> method; essentially, the system expects the executable to have an interface:
<br><br>
<i><b>interface</b> Executable {main(argc: Integer, argv: Array[String])}</i>
<br><br>
<a href="https://en.wikipedia.org/wiki/Executable_and_Linkable_Format">ELF</a> can also be viewed as a serialization format for objects in this way. We aren't used to thinking of loading and running in this way, but that doesn't detract from the point. Once you see it, you cannot unsee it.
<br><br>
<a href="https://newspeaklanguage.org/">Newspeak</a> makes this point of view explicit. In Newspeak, an application is an object which supports the method <i>main:args:</i>. This method takes two arguments: a platform object, and an array object whose elements are any specific arguments required. The platform object provides access to standard Newspeak platform functionality that is not part of the application itself. To deploy an application, we serialize it using conventional object serialization. Objects reference their class, and classes reference mixins which reference methods. All of these are objects, and get serialized when we serialize the application object. So all the application's code gets serialized with it. Running the deployed app is a matter of deserializing it and calling <i>main:args:</i>.
<br><br>
<i>The advantage of recognizing this explicitly is conceptual parsimony, which yields an economy of mechanism. You can literally reuse your object serializer as a deployment format. Serializing data and serializing code are one and the same.</i>
<br><br>
Executables aren't the only objects that aren't recognized as such. Libraries are also objects. It doesn't matter if we are talking about DLLs at the operating system level or about packages/modules/units at the programming language level, or packages in the package-manager sense. The key point about all these things is that they support an API - an Application Programming Interface. We'll dispense with the acronym-happy jargon and just say <i>interface</i>. In all these cases, we have a set of named procedures that are made accessible to callers. They may make use of additional procedures, some publicly available via the interface, and some not. They may access data encapsulated behind the interface; that data may be mutable or not. The key thing is the notion of an interface.
<br><br>
Even if you are programming in a pure functional setting, such objects will make an appearance. The packages of Haskell, and certainly the structures of ML, are not all that different. They may be statically typed or they may be not. They may be statically bound at some level - but as long as we have separate compilation, this is just an optimization that relies on certain rigidities of the programming model. That is, your language may not treat these things a first class values, but your compilation units can bind to different implementations of the same package interface, even if they can only bind to one at a time. So even if the language itself does not treat these entities as true objects with dynamicly bound properties, they have to act as objects in the surrounding environment.
<br><br>
<i>In many systems, the API might expose variables directly. And they very often may expose classes directly as well. Nevertheless, these are all late-bound at the level of linking across compilation units or OS libraries.</i>
<br><br>
The notion of an interface is what truly characterizes objects - not classes, not inheritance, not mutable state. Read <a href="http://www.cs.utexas.edu/~wcook/Drafts/2009/essay.pdf">William Cook's classic essay</a> for a deep discussion on this.
<br><br>
So the next time someone tells you that they don't believe in objects, that objects are bad and one shouldn't and needn't use them, you can politely inform them that they shouldn't confuse objects with Java and the like, or even with imperative programming. Objects are always with us, because the concept abstracting over implementations via an interface is immensely valuable.Gilad Brachahttp://www.blogger.com/profile/17934280339206214042noreply@blogger.com15tag:blogger.com,1999:blog-2447174102813539049.post-30475460973358709912022-04-19T14:28:00.000-07:002022-04-19T14:28:03.779-07:00Bitrot Revisited: Local First Software and Orthogonal Synchronization<i>This post is based on a <a href="https://2022.programming-conference.org/details/programming-2022-Organizational/7/Day-2-Opening-Bitrot-Revisited-Local-First-Software-and-Orthogonal-Synchronization">invited talk</a> I gave recently at the <a href="https://2022.programming-conference.org/">Programming 22</a> conference.
<br><br>
The talk wasn't recorded but I've recorded a reprise at: https://youtu.be/qx6ekxXdidI </i>
<br><br>
The definition of insanity not withstanding, I decided to revisit a topic I have discussed many times before: <i>Objects as Software Services</i>. In particular, I wanted to relate it to recent work others have been doing.
<br><br>
<i>The earliest public presentation I gave on this at the <a href="https://bracha.org/oopsla05-dls-talk.pdf" target="_blank">DLS in 2005</a>. There are recordings of talks I gave at <a href="https://www.youtube.com/watch?v=_cBGtvjaLM0" target="_blank">Google</a> and <a href="https://www.youtube.com/watch?v=z0CVuM9uWSU" target="_blank">Microsoft Research</a>, as well as several blog posts (<a href="https://gbracha.blogspot.com/2007/03/sobs.html"> March 2007</a>, <a href="https://gbracha.blogspot.com/2008/04/everyone-is-talking-about-cloud.html">April 2008</a>, <a href="https://gbracha.blogspot.com/2009/04/last-week-i-was-at-lang.html">April 2009</a>, <a href="https://gbracha.blogspot.com/2010/01/closing-frontier.html">January 2010</a> and <a href="https://gbracha.blogspot.com/2010/04/brave-new-world-of-full-service.html">April 2010</a>). You can also download <a href="https://bracha.org/objectsAsSoftwareServices.pdf">the original write up</a>. </i>
<br><br>
The goal is software that combines the advantages of old-school personal computing and modern web-based applications. There are two parts to this.
<br><br>
First, software should be available at all times. Like native apps, software should be available even if the network is slow, unreliable or absent, or if the cloud is otherwise inaccessible (say due to denial-of-service, natural disaster, war or whatever). And, like a cloud app, it should be accessible from any machine at any location (modulo network access if it hasn't run there before). Recently, this idea has started to get more attention under the name <a href="https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=&ved=2ahUKEwiujpeg-of3AhU4EEQIHcrBAscQFnoECBIQAQ&url=https%3A%2F%2Fmartin.kleppmann.com%2Fpapers%2Flocal-first.pdf&usg=AOvVaw1fjDETTGrTQ5q-I7QcNGrm">local-first software</a>.
<br><br>
<i>Tangent: I've proposed a number of terms for closely related ideas in older posts such as <b>Software Objects</b>, <b>Rich Network Enabled Clients</b>, <b>Network Serviced Applications</b> and <b>Full-Service Computing</b>, but whatever name gets traction is fine with me.
</i>
<br><br>
Second, software should always be up-to-date (this is where Bitrot comes in). That means we always want to run the latest version available, just like a web page. This implies automatically updating application code over the network without disrupting the end-user. This latter point goes well beyond the idea of local-first software as I've seen it discussed.
<br><br>
Let's take these two goals in order.
<ul>
<li>For offline availability, one has to store the application and its data locally on the client device. However, unlike classical personal computing, the data has to be made available, <b>locally<i></i></b>, to multiple clients. Now we have multiple replicas of our data, and they have to be kept in sync somehow. My proposal was to turn that responsibility over to the programming language via a concept I dubbed <i>Orthogonal Synchronization</i>. The idea was to extend the concept of orthogonal persistence, which held that the program would identify which fields in every data structure were deemed persistent, and the system would take care of serializing and deserializing their contents, recursively. With orthogonal synchronization, the data would not only be persisted automatically, but synchronized.
<li>To keep the software up-to-date without disrupting the user, we want good support for dynamic software update. When the application code changes, we update the app live. How do we know when the code changes? Well, code is just data, albeit of a particular kind. Hence we sync it, just like any other persistent data. We reuse much of the same orthogonal synchronization mechanism, and since we sync both code and data at the same time, we can migrate data seamlessly whenever the code and data format changes. As I've discussed in the past, this has potentially profound implications for versioning, release cycles and software development. All this goes well beyond the focus of local-first software, and is way outside the scope of this post. See the original materials cited above for more on that aspect.
</li>
</ul>
There's only one small problem: merge conflicts. The natural tendency is to diff the persistent representations to compute a set of changes and detect conflicts. An alternative is to record changes directly, whenever setters of persistent objects are called. Either way, we are comparing the application state at the level of individual objects. This is very low level; it is an <i>extensional</i> approach, which yields no insight into the <i>intention</i> of the changes. As an example, consider a set, represented as an array of elements and an integer indicating the cardinality of the set. If two clients each add a distinct object to the set, we find that they both have the same set object, but the arrays differ. The system has no way to resolve the conflict in a satisfactory manner: choosing either replica is wrong. If one understands the <i>intention</i> of the change, one could decide to resolve the conflict by performing both additions on the original set.
<br><br>
Local first computing approaches this problem differently. It still needs to synchronize the replicas. However, the problem of conflicts is elegantly defined away. The idea is to use Conflict-free Replicated Data Types (CRDTs) for all shareable data, and so conflicts cannot arise. This is truly brilliant as far as it goes. And CRDTs go further than one might think.
<br><br>
CRDT libraries record <i>intentional</i> changes at the level of the CRDT object (in our example, the set, assuming we use a CRDT implementation of a set); sync is then just the union of the change sets, and no conflicts arise. However, the fact that no formal conflict occurs does not necessarily mean that the result is what we actually expect. And CRDTs don't provide a good solution for code update.
<br><br>
Can we apply lessons from CRDTs to orthogonal synchronization? The two approaches seem quite contradictory: CRDTs fly in the face of orthogonal persistence/synchronization. The 'orthogonal' in these terms means that persistence/synchronization is orthogonal to the datatype being persisted/synced. You can persist/sync any datatype. In contrast, using CRDTs for sync means you have to use specific datatypes. One conclusion might be that orthogonal sync is just a bad idea. Maybe we should build software services by using CRDTs for data, and structured source control for code. However, perhaps there's another way.
<br><br>
Notice that the concept of capturing intentional changes is distinct from the core idea of CRDTs. It's just that, once you have intentional changes, CRDTs yield an exceptionally simple merge strategy. So perhaps we can use orthogonal sync, but incorporate intentional change data and then use custom merge functions for specific datatypes. CRDTs could fit into this framework; they'd just use a specific merge strategy that happens to be conflict-free. However, we now have additional options. For example, we can merge code with a special strategy that works a bit like traditional source control (we can do better, but that's not my point here). As a default merge strategy when no intent is specified, we could treat setter operations on persistent slots as changes and just ask the user for help in case of conflict. We always have the option to specify an alternate strategy such as last-write-wins (LWW).
<br><br>
How might we specify what constitutes an intentional change, and what merge strategy to use? One idea is to annotate mutator methods with metadata indicating that they are changes associated with a given merge strategy. Here is what this might look like for a simple counter CRDT:
<br><br>
<b>class</b> Counter <b>= (|</b> count <Integer> ::= 0<b>. |)(</b>
<br>
<b>public</b> value <b>= (^</b>count<b>)</b>
<br>
<b>public</b> increment (* :crdt_change: *) <b>= (</b>
<br>
count: count + 1
<br>
<b>)</b>
<br>
<b>public</b> decrement (* :crdt_change: *)<b> = (</b>
<br>
count: count - 1
<br>
<b>)))</b>
<br>
The metadata tag (<i>crdt_change</i> in this case) identifies a tool that modifies the annotated method so that calls are recorded as change records with salient information (name of called method, timestamp, arguments) as well as a merge method that processes such changes according to a standardized API.
<br><br>
Now, to what extent is this orthogonal sync anymore? Unlike orthogonal persistence, we can't just mark slots as persistent and be done; we have to provide merge strategies. Well, since we have a default, we can still argue that sync is supported regardless of datatype. Besides, quibbling over terminology is not the point. We've gained real flexibility, in that we can support both CRDTs and non-CRDTs like code. And CRDT implementations don't need to incorporate special code for serialization and change reporting. The system can do that for them based on the metadata.
<br><br>
I've glossed over many details. If you watch the old talks, you'll see many issues discussed and answered.
Of course, the proof of the pudding is in creating such a system and building working applications on top. I only managed to gather funding for such work once, which is how we created Newspeak, but that funding evaporated before we got very far with the sync problem. Sebastián Krynski worked on some prototypes, but again, without funding it's hard to make much progress. Nevertheless, there is more recognition that there is a problem with traditional cloud-based apps. As the saying goes: this time it's different. Gilad Brachahttp://www.blogger.com/profile/17934280339206214042noreply@blogger.com5tag:blogger.com,1999:blog-2447174102813539049.post-18259594704453827602021-08-12T20:59:00.001-07:002021-08-12T20:59:32.523-07:00How is a Programmer Like a Pathologist?Blogging platforms like Blogger are totally inadequate, because they don't support embedding interactive code in posts.
So this is just an indirection for the real post at: https://blog.bracha.org/exemplarDemo/exemplar2021.html?snapshot=BankAccountExemplarDemo.vfuel#Gilad Brachahttp://www.blogger.com/profile/17934280339206214042noreply@blogger.com3tag:blogger.com,1999:blog-2447174102813539049.post-52804140962367689092020-05-24T18:59:00.013-07:002020-05-26T12:44:36.768-07:00Bits of History, Words of Advice<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">"Why do you jackasses use these inferior linguistic vehicles when we have something here that’s so </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">precious, so elegant, which gives me so much pleasure? How can you be so blind and so foolish?" </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">That debate you’ll never win, and I don’t think you ought to try.</span></div>
<b id="docs-internal-guid-44656a38-7fff-1aee-87d0-e5b95284f7e2" style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">- Alan Perlis, 1978</span></div>
<b style="font-weight: normal;"><br /></b><br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">In the late 1970s, researchers at Xerox Parc invented modern computing. Of course, there were others</span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> elsewhere - but Parc made a vastly disproportionate contribution.</span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">A large part of that was done in, and based upon, the Smalltalk programming language. Forty years</span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> ago, Smalltalk's dynamic update and reflection capabilities were more advanced than in any</span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> mainstream language today. The language leveraged those capabilities to provide an IDE that in</span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> many ways still puts the eclipses, black holes, red dwarfs and other travesties that currently </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">masquerade under that term to shame. The Smalltalk image provided a much better Docker than </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Docker.</span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Smalltalk and Smalltalkers invented not only IDEs, but window systems and their related paraphernalia</span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> (pop-up menus, scroll bars, the bit-blt primitives that make them possible) as well as GUI builders, </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">unit testing, refactoring and agile development (ok, so nobody's perfect).</span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">And yet, today Smalltalk is relegated to a small niche of true believers. Whenever two or more</span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> Smalltalkers gather over drinks, the question is debated: Why? </span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">The answer is unknowable, since we cannot run parallel universes and tweak things to see which </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">makes a difference</span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> I did describe such an alternate universe in a <a href="https://www.youtube.com/watch?v=BDwlEJGP3Mk">talk in 2016</a>; it may be the best talk I ever gave.</span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Nevertheless, I think we can learn something from looking into this question. I'll relate parts of history</span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> that I deem relevant, as I know them. I'm sure there are inaccuracies in the account below.</span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">There are certainly people who were closer to the history than I. My hope is that they'll expand on my </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">comments and correct me as needed. I'm sure I'll be yelled at for some of this. See if I care.</span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">On with the show.</span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre;">Lack of a Standard.</span><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> Smalltalk had (and still has) multiple implementations - more so than much </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">more widely used languages. In a traditional business, having multiple sources for a technology </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">would be considered an advantage. However, in Smalltalk's case, things proved to be quite different. </span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Each vendor had a slightly different version - not so much a different language, as a different platform. </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">In particular, Smalltalk classes do not have a conventional syntax; instead, they are defined via </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">reflective method invocation. Slight differences in the reflection API among vendors meant that the </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">program definitions themselves were not portable, irrespective of other differences in APIs used by the </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">programs. </span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">There were of course efforts to remedy this. Smalltalk standardization efforts go back to the late 80s, </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">but were pushed further in the 90s. Alas, in practice they had very little impact.</span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Newspeak of course, fixed this problem thoroughly, along with many others. But we were poorly funded</span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> after the 2008 crash, and never garnered much interest from the Smalltalk community. </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">The community's lack of interest in addressing weaknesses in the Smalltalk-80 model will be a</span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">recurring theme throughout this post.</span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre;">Business model.</span><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> Smalltalk vendors had the quaint belief in the notion of "build a better mousetrap </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">and the world will beat a path to your door". Since they had built a vastly better mousetrap, they </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">thought they might charge money for it. </span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">This was before the notion of open source was even proposed; though the Smalltalk compilers, tools </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">and libraries were provided in source form; only the VMs were closed source.</span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Alas, most software developers would rather carve their programs onto stone tablets using flint tools </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">held between their teeth than pay for tools, no matter how exquisite. Indeed, some vendors charged </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">not per-developer-seat, but per </span><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">deployed</span><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> instance of the software. Greedy algorithms are often </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">suboptimal, and this approach was greedier and less optimal than most. Its evident success speaks </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">for itself.</span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">In one particularly egregious and tragic case, I'm told ParcPlace declined an offer from Sun </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Microsystems to allow ParcPlace Smalltalk to be distributed on Sun workstations. Sun would pay a per </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">machine license fee, but it was nowhere near what ParcPlace was used to charging.</span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Eventually, Sun developed another language; something to do with beans, I forget. Fava, maybe? </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Again, dwell on that and what alternative universe might have come about.</span></div>
<b style="font-weight: normal;"><br /></b><br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre;">Performance and/or the illusion thereof.</span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Smalltalk was and is a lot slower than C, and more demanding in terms of memory. In the 1980s and </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">early 1990s, these were a real concern. In the mid-1990s, when we worked on Strongtalk, Swiss </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">banks were among our most promising potential customers. They already had Smalltalk applications </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">in the field. They could afford to do so where others could not. For example, they were willing to equip</span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">their tellers with powerful computers that most companies found cost-prohibitive - IBM PCS with a </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">massive 32Mb of memory! </span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">It took a long time for implementation technology to catch up, and when it did, it got applied to lesser </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">languages. This too was a cruel irony. JITs originated in APL, but Smalltalk was also a pioneer in that </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">field (the Deutsch-Schiffman work), and even more so <a href="https://selflanguage.org/">Self</a>, where adaptive JITs</span><span style="font-family: arial; font-size: 11pt; white-space: pre;"> were invented. </span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"><a href="http://www.strongtalk.org/">Strongtalk</a> applied Self's technology to Smalltalk, and made it practical. </span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Examples: Self needed 64Mb, preferably 96, and only ran on Sun workstations. Strongtalk ran in 8Mb </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">on a PC. This mattered a lot. And Strongtalk had an FFI, see below.</span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Then, Java happened. Strongtalk was faster than Java in 1997, but Strongtalk was acquired by Sun; </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">the VM technology was put in the service of making Java run fast. </span><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">The Smalltalk component of Strongtalk was buried alive until it was too late. By the time I finally got it </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">open</span><span style="font-family: arial; font-size: 11pt; font-style: italic; white-space: pre;">-sourced , </span><span style="font-family: arial; font-size: 11pt; font-style: italic; white-space: pre;">bits had rotted or disappeared, the system had no support, and the world had moved on.</span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: arial; font-size: 11pt; font-style: italic; white-space: pre;"> And yet, the </span><span style="font-family: arial; font-size: 11pt; font-style: italic; white-space: pre;">fact that the Smalltalk community took almost no interest in the project is still telling.</span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Imagine if all the engineering efforts sunk into the JVM had focused on Smalltalk VMs.</span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">It's also worth dwelling on the fact that raw speed is often much less relevant than people think.</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Java was introduced as a client technology (anyone remember applets?). The vision was programs </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">running in web pages. Alas, Java was a terrible client technology. In contrast, even a Squeak </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">interpreter, let alone Strongtalk, had much better start up times than Java, and better interactive </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">response as well. It also had much smaller footprint. It was a much better basis for performant client </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">software than Java. The implications are staggering. </span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">On the one hand, Netscape developed a scripting language for the browser. After all Java wouldn't cut </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">it. Sun gave them permission to use the Java name for their language. You may have heard of this </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">scripting language; it's called Javascript. </span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Eventually, people found a way to make Javascript fast. Which people? Literally some of the same </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">people who made Strongtalk fast (Lars Bak), using much the same principles.</span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Imagine if Sun had a workable client technology. Maybe the <a href="https://en.wikipedia.org/wiki/HotJava">Hot Java</a> web browser would still be </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">around.</span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">On the other hand, the failure of Java on the client led to an emphasis on server side Java instead. </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">This seemed like a good idea at the time, but ultimately commoditized Sun's product and contributed </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">directly to Sun's downfall. Sun had a superb client technology in Strongtalk, but the company's </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">leadership would not listen. </span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Of course, why would they? They had shut down the Self project some years earlier to focus on Java. </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Two years later, they spent an order of magnitude more money than it cost to develop Self, to buy back </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">essentially the same technology so they could make Java performant.</span></div>
<b style="font-weight: normal;"><br /></b><br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre;">Interaction with the outside world.</span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Smalltalk had its unique way of doing things. Often, though not always, these ways were much better </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">than mainstream practice. Regardless, it was difficult to interact with the surrounding software </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">environment. Examples:</span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre;">FFIs.</span><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> Smalltalk FFIs were awkward, restrictive and inefficient. After all, why would you want to reach </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">outside the safe, beautiful bubble into the dirty dangerous world outside?</span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">We addressed this back in the mid-90s in Strongtalk, and much later, again, in <a href="https://newspeaklanguage.org/">Newspeak</a>. </span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre;">Windowing.</span><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> Smalltalk was the birthplace of windowing. Ironically, Smalltalks continued to run on top </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">of their own idiosyncratic window systems, locked inside a single OS window. </span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Strongtalk addressed this too; occasionally, so did others, but the main efforts remained focused on </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">their own isolated world, graphically as in every other way. Later, we had a native UI for Newspeak as </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">well. </span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre;">Source control. </span><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">The lack of a conventional syntax meant that Smalltalk code could not be managed </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">with conventional source control systems. Instead, there were custom tools. Some were great - but </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">they were very expensive.</span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">In general, saving Smalltalk code in something so mundane as a file was problematic. Smalltalk used </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">something called file-out format, which is charitably described as a series of reflective API calls, along </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">with meta-data that includes things like times and dates when the code was filed out. This compounded </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">the source control problem.</span></div>
<b style="font-weight: normal;"><br /></b><br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre;">Deployment. </span><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Smalltalk made it very difficult to deploy an application separate from the programming </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">environment. The reason for this is that Smalltalk was never a programming language in the traditional </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">sense. It was a holistically conceived programming system. In particular, the idea is that computation </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">take place among communicating objects, which all exist in some universe, a "sea of objects". Some </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">of these object know how to create new ones; we call them classes (and that is why there was no </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">syntax for declaring a class, see above).</span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">What happens when you try to take some objects out of the sea in which they were created (the IDE)? </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Well, it's a tricky serialization problem. Untangling the object graph is very problematic.</span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">If you want to deploy an application by separating it from the IDE (to reduce footprint, or protect your IP,</span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">or avoid paying license fees for the IDE on each deployed copy) it turns out to be very hard.</span></div>
<b style="font-weight: normal;"><br /></b><br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">The Self transporter addressed this problem in a clever way. Newspeak addressed it much more </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">fundamentally and simply, both by recognizing that the traditional linguistic perspective need not </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">contradict the Smalltalk model, and by making the language strictly modular.</span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">The problem of IP exposure is much less of a concern today. It doesn't matter much for server based </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">applications, or for open source software. Wasted footprint is still a concern, though in many cases you </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">can do just fine. Avi Bryant once explained to me how he organized the server for the late, great </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Dabble DB. It was so simple you could just cry, and it performed like a charm using Squeak images. </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Another example of the often illusory focus on raw performance.</span></div>
<b style="font-weight: normal;"><br /></b><br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">So why didn't Smalltalk take over the world? </span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">With 20/20 hindsight, we can see that from the pointy-headed boss perspective, the Smalltalk value </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">proposition was: </span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Pay a lot of money to be locked in to slow software that exposes your IP, looks weird on screen and </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">cannot interact well with anything else; it is much easier to maintain and develop though!</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"><br /></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">On top of that, a fair amount of bad luck.</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"><br /></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">And yet, those who saw past that, are still running Smalltalk systems today with great results; efforts to </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">replace them with modern languages typically fail at huge cost.</span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">All of the problems I've cited have solutions and could have been addressed. </span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Those of us who have tried to address them have found that the wider world did not want to listen - </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">even when it was in its own best interest. This was true not only of short sighted corporate leadership, </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">but of the Smalltalk community itself. </span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"><br /></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><i>My good friends in the Smalltalk community effectively ignored both Strongtalk and Newspeak. </i></span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><i>It required commitment and a willingness to go outside their comfort zone.</i></span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">I believe the community has been self-selected to consist of those who are not bothered by Smalltalk's </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">initial limitations, and so are unmotivated to address them or support those who do. In fact, they often </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">could not even see these limitations staring them in the face, causing them to adopt unrealistic </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">business policies that hurt them more than anyone else.</span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Perhaps an even deeper problem with Smalltalk is that it attracts people who are a tad too creative and </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">imaginative; organizing them into a cohesive movement is like herding cats.</span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Nevertheless, Smalltalk remains in use, much more so than most people realize. Brave souls continue </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">to work on Smalltalk systems, both commercial and open source. Some of the issues I cite have been </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">addressed to a certain degree, even if I feel they haven't been dealt with as thoroughly and effectively </span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">as they might. More power to them. Likewise, w</span><span style="font-family: arial; font-size: 11pt; white-space: pre-wrap;">e still spend time trying to bring Newspeak back to a</span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: arial; font-size: 11pt; white-space: pre-wrap;">more usable state. </span><span style="font-family: arial; font-size: 14.6667px; white-space: pre-wrap;">Real progress is not made by the pedantic and mundane, but by the dreamers who</span></div><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: arial; font-size: 14.6667px; white-space: pre-wrap;">realize that we can do so much better.</span></div>
<b style="font-weight: normal;"><br /><br /></b><br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Eppur si muove</span></div>
<br />Gilad Brachahttp://www.blogger.com/profile/17934280339206214042noreply@blogger.com50tag:blogger.com,1999:blog-2447174102813539049.post-28877309226891196972020-01-06T20:27:00.000-08:002020-01-06T20:27:16.955-08:00The Build is Always Broken<div dir="ltr" style="line-height: 1.38; margin-bottom: 3pt; margin-top: 0pt;">
<span style="font-size: 14.6667px; white-space: pre-wrap;"><span style="font-family: arial;">Programmers are always talking about broken builds: "The build is broken", "I broke the build" etc. However, the real problem is that the very concept of </span><i style="font-family: arial;">the build</i><span style="font-family: arial;"> is broken. The idea that every time an application is modified, it needs to be reconstructed from scratch is fundamentally flawed.
A practical problem with the concept is that it induces a very long and painful feedback loop during development. Some systems address this by being wicked fast. They argue that even if they compile the world when you make a change, it's not an issue since it'll be done before you know it.
One problem is that some systems get so large that this doesn't work anymore.
A deeper problem is that even if you rebuild instantly, you find that you need to restart your application on every change, and somehow get it back to the stage where you were when you found a problem and decided to make a change. In other words, </span><i style="font-family: arial;">builds are antithetical to live programming</i><span style="font-family: arial;">. The feedback loop will always be too long.
Fundamentally, one does not recreate the universe every time one changes something. You don't tear down and reconstruct a skyscraper </span>everytime<span style="font-family: arial;"> you need to replace a light bulb.
A build, no matter how optimized, will never give us true </span>liveness<span style="font-family: arial;">
It follows that tools like </span><i style="font-family: arial;">make</i><span style="font-family: arial;"> and its ilk can never provide a solution. Besides, these tools have a host of other problems. For example, they force us to replicate dependency information that is already embedded in our code: things like imports, includes, </span><b style="font-family: arial;">uses</b><span style="font-family: arial;"> or </span><b style="font-family: arial;">extern</b><span style="font-family: arial;"> declarations etc. give us the same file/module level information that we manually enter into build tools. This replication is tedious and error prone. It is also too coarse grain, done at the granularity of files. A compiler can manage these dependencies more precisely, tracking what functions are used where for example.
</span><i style="font-family: arial;">Caveats: Some tools, like GN, can be fed dependency files created by cooperating compilers. That is still too coarse grain though.</i><span style="font-family: arial;">
In addition, the languages these tools provide have poor abstraction mechanisms (compare make to your favorite programming language) and tooling support (what kind of debugger does your build tool provide?). The traditional response to the ills of </span><i style="font-family: arial;">make</i><span style="font-family: arial;"> is to introduce additional layers of tooling of a similar nature, like </span><i style="font-family: arial;">Cmake</i><span style="font-family: arial;">. Enough!</span></span><br />
<span style="font-size: 14.6667px; white-space: pre-wrap;"><span style="font-family: arial;"><br /></span></span>
<span style="font-size: 14.6667px; white-space: pre-wrap;"><span style="font-family: arial;">A better response is to produce a better DSL for builds. Internal DSLs, based on a real programming language, are one way to improve matters. Examples are rake and scons, which use Ruby and Python respectively. </span></span><span style="font-family: arial; font-size: 14.6667px; white-space: pre-wrap;">These tools make defining builds easier - but they are still defining builds, which is the root problem I am concerned with here.</span><span style="font-size: 14.6667px; white-space: pre-wrap;"><i style="font-family: arial;">
</i><span style="font-family: arial;">
So, if we aren't going to use traditional build systems to manage our dependencies, what are we to do?
We can start by realizing that many of our dependencies are not fundamental; things like </span>executables<span style="font-family: arial;">, shared libraries, object files and binaries of whatever kind. The only thing one really needs to "build" is source code. After all, when you use an interpreter, you can create only the source you need to get started, and then incrementally edit/grow the source.
Using interpreters allows us to avoid the problems of building binary artifacts.
The cost is performance. Compilation is an optimization, albeit an important, often essential, one. Compilation relies on a more global analysis than an interpreter, and on </span>pre<span style="font-family: arial;">-computing the conclusions so we need not repeat work during execution. In a sense, the compiler is </span>memoizing<span style="font-family: arial;"> some of the work of the interpreter.
</span><i style="font-family: arial;">This is literally the case for many dynamic JITs, but is fundamentally true for static compilation as well - you just memoize in advance.</i><span style="font-family: arial;">
Seen in this light, builds are a form of staged execution, and the binary artifacts that we are constantly building are just caches.
One can address the performance difficulties of interpreters by mixing interpretation with compilation. Many systems with </span>JIT<span style="font-family: arial;"> compilers do exactly that. One advantage is that we don't have to wait for the optimization before starting our application. Another is that we can make changes, and have them take effect immediately by reverting to interpretation, while re-optimizing.
</span><i style="font-family: arial;">Of course, not all JITs do that; but it has been done for decades, in, e.g., Smalltalk VMs. One of the many beauties of working in Smalltalk is that you rarely confront the ugliness of builds.</i><span style="font-family: arial;">
And yet, even assuming you have an engine with a </span>JIT<span style="font-family: arial;"> that incrementally (re)optimizes code as it evolves, you may still be confronted with barriers to live development, barriers that seem to require a build.
</span><b style="font-family: arial;">Types.</b><span style="font-family: arial;"> What if your code is inconsistent, say, due to type errors? Again, there is no need for a build step to detect this. Incremental </span>typecheckers<span style="font-family: arial;"> should catch these problems the moment inconsistent code is saved. Of course, incremental </span>typecheckers<span style="font-family: arial;"> have traditionally been very rare; it is not a coincidence that live systems have historically been developed using dynamically typed languages. Nevertheless, there is no fundamental reason why statically typed languages cannot support incremental development. The techniques go back at least as far as </span><a href="http://projectsweb.cs.washington.edu/research/projects/cecil/www/cecil.html" style="font-family: arial;" target="">Cecil</a><span style="font-family: arial;">; See </span><a href="https://2016.splashcon.org/details/splash-2016-oopsla/36/Parallel-Incremental-Whole-Program-Optimizations-for-Scala-js" style="font-family: arial;" target="_blank">this paper</a><span style="font-family: arial;"> on </span>Scala<span style="font-family: arial;">.</span>js<span style="font-family: arial;"> for an excellent discussion of incremental compilation in a statically typed language.
</span><b style="font-family: arial;">Tests.</b><span style="font-family: arial;"> A lot of times, the build process incorporates tests, and the broken build is due to a logical error in the application detected by the tests. However, tests are not themselves part of the build, and need not rely on one - the build is just one way to obtain an updated application. In a live system, the updated application immediately reflects the source code. In such an environment, tests can be run on each update, but the developer need not wait for them.
</span><b style="font-family: arial;">Resources.</b><span style="font-family: arial;"> An application may incorporate resources of various kinds - media, documentation, data of varying kinds (source files or binaries, or tables or machine learning models etc.). Some of these resources may require computation of their own (say, producing </span>PDF<span style="font-family: arial;"> or HTML from documentation sources like TeX or markdown), adding stages that are seldom live or incremental.
Even if the resources are ready to consume, we can induce problems through gratuitous reliance on file system structure. The resources are typically represented as files. The deployed structure may differ from the source repository. Editing components in the source </span>repo<span style="font-family: arial;"> won't change them in the built structure.
It isn't easy to correct these problems, and software engineers usually don't even try. Instead, they lean on the build process more and more. It doesn't have to be that way.
We can treat the resources as cached objects and generate them on demand. When we deploy the application, we ensure that all the resources are precomputed and cached at locations that are fixed relative to the application - and these should be the same relative locations where the application will place them during development in case of a cache miss. The software should always be able to tell where it was installed, and therefore where cached resources stored at application-relative locations can be found.
The line of reasoning above makes sense when the resource is accessed via application logic. What about resources that are not used by the application, but made available to the user? In some cases, documentation and sample code and attached resources might fall under this category. The handling of such resources is not part of the application proper, and so it is not a build issue, but a deployment issue. That said, deployment is simply computation of a suitable object to serialized to a given location, and should be viewed in much the same way as the build; maybe I'll elaborate on that in separate post.
</span><b style="font-family: arial;">Dealing with Multiple Languages.</b><span style="font-family: arial;"> Once we are dealing with multiple languages, we may be pushed into using a build system because some of the languages do not support incremental development. Assuming that the heart of our application is in a live language, we should treat other </span><span style="font-family: Arial, Helvetica, sans-serif;">languages as resources; their binaries are resources to be dynamically computed during development and cached. </span></span><br />
<span style="font-size: 14.6667px; white-space: pre-wrap;"><span style="font-family: Arial, Helvetica, sans-serif;">
</span></span>
<h2>
<span style="font-size: 14.6667px; white-space: pre-wrap;"><span style="font-family: Arial, Helvetica, sans-serif;"><b>Summary</b></span></span></h2>
<span style="font-size: 14.6667px; white-space: pre-wrap;"><span style="font-family: Arial, Helvetica, sans-serif;">
</span></span><br />
<ul>
<li><span style="white-space: pre-wrap;"><span style="font-family: Arial, Helvetica, sans-serif;">Builds kill liveness. </span></span></li>
<li><span style="white-space: pre-wrap;"><span style="font-family: Arial, Helvetica, sans-serif;">Compilation artifacts are a form of cached resource, the result of staged execution. </span></span></li>
<li><span style="white-space: pre-wrap;"><span style="font-family: Arial, Helvetica, sans-serif;">To achieve liveness in industrial settings, we need to structure our development environments so that any staging is strictly an optimization</span></span></li>
<ul>
<li><span style="white-space: pre-wrap;"><span style="font-family: Arial, Helvetica, sans-serif;">Staged results should be cached and invalidated automatically when the underlying basis for the cached value is out of date. </span></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">This applies regardless of whether the staged value is a resource, a shared library/binary or anything else. </span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">The data necessary to compute the cached value, and to determine the cache's validity, must be kept at a fixed location, relative to the application. </span></li>
</ul>
</ul>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /><span style="font-size: 14.6667px; white-space: pre-wrap;">It's high time we build a new, brave, build-free world.</span></span><span style="font-family: arial; font-size: 14.6667px; white-space: pre-wrap;">
</span><br />
<div>
<br /></div>
</div>
Gilad Brachahttp://www.blogger.com/profile/17934280339206214042noreply@blogger.com11tag:blogger.com,1999:blog-2447174102813539049.post-75176625300305755702019-01-12T11:05:00.000-08:002019-01-12T11:05:47.173-08:00Much Ado About NothingWhat sweet nothing does the title refers to? It could be about null, but it in fact will say nothing about that. The nothing in question is whitespace in program text. Specifically, whether whitespace should be significant in a programming language.<br />
<br />
My instinct has always been that it should not. Sadly, there are always foolish souls who will not accept my instinct as definitive evidence, and so one must stoop to logical arguments instead.<br />
<br />
Significant whitespace, by definition, places the burden of formatting on the programmer. In return, it can be leveraged to reduce syntactic noise such as semicolons and matching braces. The alleged<br />
benefit is that in practice, programmers often deal with both formatting and syntactic noise, so eliminating one of the two is a win.<br />
<br />
However, this only holds in a world without civilized tooling, which in turn may explain the fondness for significant whitespace, as <i>civilized</i> tooling (and anything civilized, really), is scarce. Once you assume proper tooling support, a live pretty printer can deal with formatting as you type, so there is no reason for you to be troubled by formatting. So now you have a choice between two inconveniences. Either:<br />
<br />
<ul>
<li>You use classical syntax, and programmers learn where to put the semicolons and braces, and stop worrying about formatting, Or</li>
<li>You make whitespace significant, cleanup the syntax, and have programmers take care of the formatting.</li>
</ul>
<br />
At this point, you might say this a matter of personal preference, and can devolve into the kind of religious argument we all know and love. To tip the scales, pray consider the line of reasoning below. I don’t recall encountering it before which is what motivated this post.<br />
<br />
In the absence of significant whitespace, a pretty printing (aka code formatting) is an orthogonal concern. We can choose whatever pretty printing style we like and implement a tool to enforce it. Such a pretty-printer/code-formatter can be freely composed with any code source we have - a programmer typing into an editor, an old repository, and most importantly, other tools that spit out code - whether they transpile into our language or generate code in some other way.<br />
<br />
Once whitespace is significant, all those code sources have to be cognizant of formatting. The tool writer has to be worried about both syntax and formatting, whereas before only syntax was a concern.<br />
<br />
You might argue that the whitespace is just another form of syntax; the problem is that it is not always <b>context-free</b> syntax. For example, using indentation to nest constructs is context sensitive, as the number of spaces/tabs (or backspaces/backtabs) depends on context.<br />
<br />
In short, significant whitespace (or at least significant indentation) is a <b><i>tax on tooling</i></b>. Taxing tooling not only wastes the time and energy of tool builders - it discourages tooling altogether. And so, rather than foist significant whitespace on a language, think in terms of a broader system which includes tools. Provide a pretty printer with your language (like in Go). Ideally, there's a version of the pretty printer that live edits your code as you type.<br />
<br />
As a bonus, all the endless discussions about formatting Go away, as the designers of Go have noted. Sometimes the best way to address a problem is to define it away.<br />
<br />
There. That was mercifully brief, right? Nothing to it.Gilad Brachahttp://www.blogger.com/profile/17934280339206214042noreply@blogger.com11tag:blogger.com,1999:blog-2447174102813539049.post-53668695438482301972018-10-06T12:28:00.000-07:002018-10-06T19:08:07.578-07:00Reified Generics: The Search for the Cure<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: arial; font-size: 11pt; white-space: pre-wrap;">Many have argued that run time access to generic type information is very important. A very bitter debate about this ensued when we added generics to Java. The topic recurs whenever one designs a statically typed object oriented language. Should one reify generic types, or erase them? Java chose erasure, .Net and Dart chose reification, and all three solutions are in my mind unsatisfactory for various reasons, including but not limited to the handling of erasure or its presumed alter ego, reification. </span><br />
<span id="docs-internal-guid-6e2122d2-7fff-ca0b-45ab-7c215548dba2"><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><br /></span>
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><b>Pedantic note 1:</b> Throughout this post, I will use the terms erasure and reification as shorthand for erasure and reification of generic type information.</span><br />
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><br /></span>
<span style="font-family: arial;"><span style="font-size: 14.6667px; white-space: pre-wrap;">In a well designed object-oriented language, erasure and reification are not contradictory at all. This statement might bear some explanation, so here we go ...</span></span><br />
<div>
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
</div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">A while back, I discussed <a href="https://gbracha.blogspot.com/2014/09/a-domain-of-shadows.html">the problem of shadow language constructs</a>. I gave examples of shadow constructs such as Standard ML modules, traditional imports etc. Here is another: reified generics.</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">Generics introduce a form a shadow parameterization. Programming languages all have a perfectly good mechanism for declaring parameterized constructs and invoking them. You may have heard of it - it is widely known by the name <i>function</i>, and it goes back to the 17th century.</span><br />
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><br /></span>
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><b>Pedantic note 2:</b> Yes, programming language functions are usually not mathematical functions. The parameterization mechanism is however, essentially the same.</span><br />
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><br /></span>
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">Generics introduce a different form of formal and actual parameters. There is a purpose to that: static analysis. However, when languages try to provide run time access to these parameters (i.e., reification of generics), we are creating a lobotomized twin of the existing runtime parameter passing system. A new, redundant, confusing and costly set of mechanisms is added to the run time in order to declare, pass, store and access these parameters. </span><br />
<br /></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">The first guiding principle of any solution is to avoid shadow constructs. We already have parameterization support, let's use it. </span><span style="font-family: "arial"; font-size: 11pt; white-space: pre-wrap;"> </span><br />
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><br /></span>
<br />
<div dir="ltr" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small; line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">Generics are functions from types to types, typically classes to classes. </span><br />
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; white-space: pre-wrap;"><br /></span>
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; white-space: pre-wrap;"><b style="font-size: 14.6667px;">Pedantic note 3:</b><span style="font-size: 14.6667px;"> If your language is prototype based, generics might be considered functions between prototypes. If your language has primitive types - well, you're up the creek without a paddle anyway. <a href="https://gbracha.blogspot.com/2009/05/original-sin.html">There is no justification for primitive types in an object oriented language</a>.</span></span><br />
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; white-space: pre-wrap;"><br /></span>
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; white-space: pre-wrap;">If classes are expressions, we can write reified generics as ordinary functions. Here's some sample pseudo-code. It's given in a quasi-standard syntax, so I don't waste time explaining Newspeak syntax.</span></div>
<div dir="ltr" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small; line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; white-space: pre-wrap;"><br /></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><b>public var</b></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> List = (</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre;">function</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">(</span><span style="background-color: transparent; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">T)</span><span style="background-color: transparent; color: blue; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">{</span><span style="background-color: transparent; color: blue; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre;">return</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre;">class</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> {</span></div>
<div dir="ltr" style="line-height: 1.656; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre;"><b>var</b></span><span style="background-color: transparent; color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">hd, tl</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">;</span></div>
<div dir="ltr" style="line-height: 1.656; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre;"> class</span><span style="background-color: transparent; color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> Link {</span></div>
<div dir="ltr" style="line-height: 1.656; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre;"> public</span><span style="background-color: transparent; color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> datum;</span></div>
<div dir="ltr" style="line-height: 1.656; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre;"> public</span><span style="background-color: transparent; color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> next;</span></div>
<div dir="ltr" style="line-height: 1.656; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> }</span></div>
<div dir="ltr" style="line-height: 1.656; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre;">public</span><span style="background-color: transparent; color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">elementType()</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> { </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre;">return</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> T}</span></div>
<div dir="ltr" style="line-height: 1.656; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre;"> public</span><span style="background-color: transparent; color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> add(e</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">)</span><span style="background-color: transparent; color: blue; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">{</span></div>
<div dir="ltr" style="line-height: 1.656; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre;">var</span><span style="background-color: transparent; color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> tmp </span><span style="background-color: transparent; color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">:= Link new.</span></div>
<div dir="ltr" style="line-height: 1.656; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> tmp.datum := e;</span></div>
<div dir="ltr" style="line-height: 1.656; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> tmp.next := hd;</span></div>
<div dir="ltr" style="line-height: 1.656; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> tl := hd;</span></div>
<div dir="ltr" style="line-height: 1.656; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> hd := tmp;</span></div>
<div dir="ltr" style="line-height: 1.656; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre;">return</span><span style="background-color: transparent; color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> e;</span></div>
<div dir="ltr" style="line-height: 1.656; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> }</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> }</span></div>
<div dir="ltr" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small; line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span id="docs-internal-guid-0cc0c0b7-7fff-819e-b002-73da3dc7320a"></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">}).memoize();</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"><br /></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"><span style="font-family: "arial" , "helvetica" , sans-serif; font-size: small; font-style: normal; white-space: normal;"> </span><span style="font-family: "arial"; font-size: 14.6667px; font-style: normal;">Here's a summary of what the above means:</span></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
</div>
<ul>
<li><span style="font-family: "arial";"><span style="font-size: 14.6667px; white-space: pre-wrap;">We declare a variable named <i>List</i>, initialized to a closure.</span></span></li>
<li><span style="font-family: "arial";"><span style="font-size: 14.6667px; white-space: pre-wrap;">The closure takes a class <i>T</i> as a parameter and returns a class as its result.</span></span></li>
<li><span style="font-family: "arial";"><span style="font-size: 14.6667px; white-space: pre-wrap;">The result class is specified via a <i><b>class expression</b></i>, which implements a linked list.</span></span></li>
<li><span style="font-family: "arial";"><span style="font-size: 14.6667px; white-space: pre-wrap;">The class expression includes a nested class declaration, <i>Link</i>.</span></span></li>
<li><span style="font-family: "arial";"><span style="font-size: 14.6667px; white-space: pre-wrap;">The method <i>memoize()</i> is called on the closure to, well, memoize it. <i>Memoize()</i> returns a memoized version of its receiver.</span></span></li>
</ul>
<div dir="ltr" style="background-color: white; line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial";"><span style="font-size: 14.6667px; white-space: pre-wrap;">Each call to <i>List()</i> returns a list class specialized to the actual parameter of <i>List()</i>. We can create a list of integers by saying </span></span></div>
<div dir="ltr" style="background-color: white; line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial";"><span style="font-size: 14.6667px; white-space: pre-wrap;"><br /></span></span></div>
<div dir="ltr" style="background-color: white; line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial";"><span style="font-size: 14.6667px; white-space: pre-wrap;"><i><b>var</b> lst := List(Integer).new();</i></span></span></div>
<div dir="ltr" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small; line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
<div dir="ltr" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small; line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">and we can dynamically check what type of elements <i>lst</i> holds</span></div>
<div dir="ltr" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small; line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
<div dir="ltr" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small; line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><i>lst.elementType(); // returns Integer, the class object reifying the integer type.</i></span></div>
<div dir="ltr" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small; line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<br /></div>
<div dir="ltr" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small; line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">The reified element type is shared among all instances of a given list class, because it is stored in the closure surrounding the class. We avoid duplicating classes with the same parameters - this is just function memoization (and I assume a <i>memoize()</i> method on closures for this purpose). </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; white-space: pre-wrap;">All this works independent of any static types. We are just using standard runtime mechanisms like closures, memoized functions, objects representing classes and yes, class expressions. Smalltalk had these, in essence, over 40 years ago.</span><br />
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; white-space: pre-wrap;"><br /></span>
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; white-space: pre-wrap;">What if I don't have class expressions? Well, don't you know that everything should be an expression? Besides, this works fine if you have the ability to define classes reflectively like Smalltalk, or </span><span style="color: black; font-family: arial; font-size: 14.6667px; white-space: pre-wrap;">have properly defined nested classes like Newspeak, </span><span style="background-color: transparent; color: black; font-family: arial; font-size: 11pt; white-space: pre-wrap;"> though it may be a bit more verbose and require more library support to be palatable.</span></div>
<div dir="ltr" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small; line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; white-space: pre-wrap;"><br /></span></div>
<div dir="ltr" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small; line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; white-space: pre-wrap;">Now let's add types. In the code below, <b>t</b></span><span style="background-color: transparent; font-family: "arial"; font-size: 14.6667px; white-space: pre-wrap;"><b>ype annotations are completely optional, and have absolutely no runtime effect</b>. They are shown in </span><span style="background-color: transparent; color: blue; font-family: "arial"; font-size: 14.6667px; white-space: pre-wrap;">blue</span><span style="background-color: transparent; font-family: "arial"; font-size: 14.6667px; white-space: pre-wrap;">. </span></div>
<div dir="ltr" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small; line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; white-space: pre-wrap;"><br /></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"><b>public var</b></span><span style="font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"> List = (</span><span style="font-family: "arial"; font-size: 11pt; font-style: italic; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;">function</span><span style="font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;">(</span><span style="font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;">T</span><span style="color: blue; font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"> : Class</span><span style="font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;">)</span><span style="color: blue; font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;">{</span><span style="color: blue; font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"> </span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="font-family: "arial"; font-size: 11pt; font-style: italic; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;">return</span><span style="font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="font-family: "arial"; font-size: 11pt; font-style: italic; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;">class</span><span style="font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"> {</span></div>
<div dir="ltr" style="line-height: 1.656; margin-bottom: 0pt; margin-top: 0pt;">
<span style="color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"> <b>var</b> </span><span style="font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;">hd, tl</span><span style="color: blue; font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"> : Link</span><span style="font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;">;</span></div>
<div dir="ltr" style="line-height: 1.656; margin-bottom: 0pt; margin-top: 0pt;">
<span style="color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;"> class</span><span style="color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"> Link {</span></div>
<div dir="ltr" style="line-height: 1.656; margin-bottom: 0pt; margin-top: 0pt;">
<span style="color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;"> public</span><span style="color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"> datum </span><span style="color: blue;"><span style="font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;">: </span><span style="font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;">T</span></span><span style="color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;">;</span></div>
<div dir="ltr" style="line-height: 1.656; margin-bottom: 0pt; margin-top: 0pt;">
<span style="color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;"> public</span><span style="color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"> next :</span><span style="font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"><span style="color: blue;"> Link</span></span><span style="color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;">;</span></div>
<div dir="ltr" style="line-height: 1.656; margin-bottom: 0pt; margin-top: 0pt;">
<span style="color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"> }</span></div>
<div dir="ltr" style="line-height: 1.656; margin-bottom: 0pt; margin-top: 0pt;">
<span style="color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;">public</span><span style="color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;">elementType() </span><span style="color: blue; font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;">: Class</span><span style="font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"> { </span><span style="font-family: "arial"; font-size: 11pt; font-style: italic; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;">return</span><span style="font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"> T}</span></div>
<div dir="ltr" style="line-height: 1.656; margin-bottom: 0pt; margin-top: 0pt;">
<span style="color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;"> public</span><span style="color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"> add:(e </span><span style="color: blue; font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;">: T</span><span style="font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;">)</span><span style="color: blue; font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"> : T</span><span style="color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"> {</span></div>
<div dir="ltr" style="line-height: 1.656; margin-bottom: 0pt; margin-top: 0pt;">
<span style="color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;">var</span><span style="color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"> tmp: </span><span style="color: blue; font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;">Link</span><span style="color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"> := Link new.</span></div>
<div dir="ltr" style="line-height: 1.656; margin-bottom: 0pt; margin-top: 0pt;">
<span style="color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"> tmp.datum := e;</span></div>
<div dir="ltr" style="line-height: 1.656; margin-bottom: 0pt; margin-top: 0pt;">
<span style="color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"> tmp.next := hd;</span></div>
<div dir="ltr" style="line-height: 1.656; margin-bottom: 0pt; margin-top: 0pt;">
<span style="color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"> tl := hd;</span></div>
<div dir="ltr" style="line-height: 1.656; margin-bottom: 0pt; margin-top: 0pt;">
<span style="color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"> hd := tmp;</span></div>
<div dir="ltr" style="line-height: 1.656; margin-bottom: 0pt; margin-top: 0pt;">
<span style="color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;">return</span><span style="color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"> e;</span></div>
<div dir="ltr" style="line-height: 1.656; margin-bottom: 0pt; margin-top: 0pt;">
<span style="color: #222222; font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"> }</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"> }</span></div>
<div dir="ltr" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small; line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span id="docs-internal-guid-0cc0c0b7-7fff-819e-b002-73da3dc7320a"></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;">}).memoize();</span></div>
<div dir="ltr" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small; line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; white-space: pre-wrap;"><br /></span></div>
<div dir="ltr" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small; line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 14.6667px; white-space: pre-wrap;">You may notice one odd thing - we use the name of the formal parameter to the closure, </span><i style="font-family: Arial; font-size: 14.6667px; white-space: pre-wrap;">T</i><span style="font-family: "arial"; font-size: 14.6667px; white-space: pre-wrap;">, as a type. This is justified by the following rule.</span></div>
<div dir="ltr" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small; line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<br /></div>
<div dir="ltr" style="line-height: 1.656; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><b>Rule 1:</b> In any method or closure <i>m</i>, a formal parameter </span><span style="font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;">T</span><span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"> of type </span><span style="font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"><span style="color: blue;">Class</span></span><span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"> (or any subtype thereof) implicitly defines a type variable </span><span style="font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"><span style="color: blue;">T</span> </span><span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">which is in scope in type expressions from the point </span><span style="font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;">T</span><span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"> is declared to the end of the method/closure</span><span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">. </span></div>
<div dir="ltr" style="line-height: 1.656; margin-bottom: 0pt; margin-top: 0pt;">
<br /></div>
<div dir="ltr" style="background-color: white; font-family: Arial, Helvetica, sans-serif; font-size: small; line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">Next, we need to be able to use the information given by the declaration of <i>List</i> when we write types like </span><span style="background-color: transparent; font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><i><span style="color: blue;">List[Integer]</span></i></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">. We use the following rule.</span></div>
<div dir="ltr" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small; line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
<div dir="ltr" style="background-color: white; font-family: Arial, Helvetica, sans-serif; font-size: small; line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><b>Rule 2:</b></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"> If </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;">e</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"> is an expression of function type with parameter(s) of type </span><span style="background-color: transparent; font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"><span style="color: blue;">Class</span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"> and return type </span><span style="color: blue; font-family: "arial"; font-size: 14.6667px; font-style: italic; white-space: pre-wrap;">Class</span><span style="background-color: transparent; font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">, </span><span style="background-color: transparent; font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;">e</span><span style="background-color: transparent; font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">'s name</span><span style="background-color: transparent; font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"> can be used inside a type expression as a type function; an invocation of the type function <i>e[T1, ..., Tn]</i> denotes the type of the instances of the class returned by the value expression </span></div>
<div dir="ltr" style="background-color: white; font-family: Arial, Helvetica, sans-serif; font-size: small; line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<i style="font-family: Arial; font-size: 14.6667px; white-space: pre-wrap;">e(T1, ..., Tn)</i><span style="background-color: transparent; font-family: "arial"; font-size: 11pt; white-space: pre-wrap;">. </span></div>
<div dir="ltr" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small; line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
<div dir="ltr" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small; line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">We can then write, and typecheck </span></div>
<div dir="ltr" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small; line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span id="m_-4391720801157067180gmail-m_2703046546755666277gmail-docs-internal-guid-9465bad9-7fff-a555-ceac-831a714b081f"><br /></span></div>
<div dir="ltr" style="background-color: white; font-family: Arial, Helvetica, sans-serif; font-size: small; line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<i style="color: black; font-family: Arial; font-size: 14.6667px; white-space: pre-wrap;"><b>var</b> lst </i><span style="color: blue;"><i style="font-family: Arial; font-size: 14.6667px; white-space: pre-wrap;">:</i><i style="background-color: transparent; font-family: Arial; font-size: 14.6667px; white-space: pre-wrap;"> </i></span><span style="color: blue; font-family: "arial"; font-size: 14.6667px; font-style: italic; white-space: pre-wrap;">List[Integer] </span><i style="color: black; font-family: Arial; font-size: 14.6667px; white-space: pre-wrap;">:= List(Integer).new();</i></div>
<div style="background-color: white; font-family: Arial, Helvetica, sans-serif; font-size: small; line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"><span style="color: #222222;"><b>var</b> i </span><span style="color: blue;">: Integer</span><span style="color: #222222;"> := lst.add(3) + 4;</span></span></div>
<div dir="ltr" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small; line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<br /></div>
<div dir="ltr" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small; line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">Oh, and we can still do this: </span></div>
<div dir="ltr" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small; line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
<div dir="ltr" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small; line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><i style="color: black; font-size: 14.6667px;">lst.elementType(); // returns Integer, the class object reifying the integer type.</i></span></div>
<div dir="ltr" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small; line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><i style="color: black; font-size: 14.6667px;"><br /></i></span></div>
<div dir="ltr" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small; line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><span style="color: black; font-family: "arial"; font-size: 14.6667px;">Similarly, if you wish to create new instances of the incoming type parameters, you should be able to do that in the above regime - though you will have to confront the fact that different subtypes may have different constructors and plan around that explicitly - say, by defining a common construction interface for these types. </span></span></div>
<div dir="ltr" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small; line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
<div dir="ltr" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small; line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">The beauty of this scheme is that no runtimes were harmed in the making of this reified generic type system. The type system is completely optional. And this is my point: reification was there all along. The typechecker simply needs to understand this fact and leverage it. The basic approach would work with any language with types reified as values, regardless of whether it has generics. </span></div>
<div dir="ltr" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small; line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
<div dir="ltr" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small; line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">Interestingly, we now have reification of generics, and erasure, at the same time. The two are not in conflict. Reification is supported by the normal runtime mechanisms, independent of types, which are optional and always erased, carrying no runtime cost or semantics.</span></div>
<div dir="ltr" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small; line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<br /></div>
</div>
</span><br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">Reification of generics is now a choice for library implementers. If they think it is worthwhile to pay the costs, so that, for example, someone can cheaply test if a collection is a collection of integers or a collection of strings, they are free to do so. </span><br />
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><br /></span>
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><span style="font-size: 14.6667px;">If they don't want to pay a price for reification but still want to typecheck generics, they can do that too. Nothing prevents one from explicitly declaring type parameters (as opposed to the implicit ones derived from the class-valued value parameters used for reification).</span></span></div>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"><b>Tangent, TL; DR:</b> Now is the time to mention that traditional reification of generics - that is, runtime support for a shadow parameterization mechanism - is a disaster. It hurts performance in both space and time; Just ask the brave VM engineers who struggled with these issues on the Dart VM. Mitigating that introduces enormous complexity into the runtime and requires a huge effort, which would be better spent doing something good and useful instead.</span></div>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;">In systems designed to support multiple programming languages, reification brings a different problem. All languages must deal with the complexity of reification; worse they must conform to the expectations of the reified generic type system of the "master language" (C# or Java, for example). </span></div>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;">Consider .Net, the poster child of generic reification. Originally, .Net was intended to be a multi-language system, but dynamic language support there has suffered, in no small part due to reification. Visual Basic was a huge success until .Net came along and made it conform to C#. And what Iron Ruby/Python programmer ever enjoyed being forced to feed type arguments (whatever those might be) into a collection they are creating? </span></div>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;">In contrast, the JVM was conceived as a monolingual system. Sun management deluded themselves that Java was the ultimate programming language (though yours truly did try to hint, ever so gently, that further progress in PL was at least conceivable). And yet, the JVM has become home to a wide variety of languages. This is due to multiple factors, invokedynamic not the least among them. But erasure plays a crucial and underappreciated role here as well. If not for erasure, the JVM would have the above-mentioned problems wrt dynamic languages, just like .Net.</span></div>
<span style="font-family: "arial"; font-size: 11pt; white-space: pre-wrap;"><br /></span>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">Of course, generics have many issues that are independent of reification. The great difficulties with generics come up when they interact with subtyping. All the problems of variance, as well as inference, are rooted in that interaction. If you are happy with any existing approach, you should be able to incorporate it into the above reification strategy - but I am not aware of any pre-existing generic design that I would consider satisfactory. </span></div>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">I think I may now have a plausible approach to the typing issues, but the margins of this blog are too narrow to contain it. A follow up post will either make it all clear, or confess that it hasn't worked out. The above comments on reification stand on their own in any case.</span></div>
<div>
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
</div>
Gilad Brachahttp://www.blogger.com/profile/17934280339206214042noreply@blogger.com13tag:blogger.com,1999:blog-2447174102813539049.post-753024263759874332017-05-29T17:17:00.001-07:002017-07-04T13:47:35.245-07:00Dead Program's SocietyIn my <a href="https://gbracha.github.io/illiterateProgramming/out/illiterateProgramming.html" target="_blank">last post</a> I discussed live literate programming. I concluded the post by noting that the approach I had discussed had one glaringly obvious flaw. No one seems to have pointed out that flaw, so I was forced to point it out myself, in my <a href="https://youtu.be/HW7sqMjTkI0">Programming 17 keynote</a>. The recording of the talk was a bit deficient, in that the camera operator focused on me rather than on the screen. Alas, I am not nearly as interesting as the screen; the screen was where all the action, demos etc. took place. To rectify that, this post will include a few video snippets that should be very close to the demos given in the talk.<br />
<br />
But first, what of the glaring flaw?
The flaw is that the mechanism I described for creating literate programs using <a href="https://www.madoko.net/">Madoko</a> and Ampleforth was not compositional. It allowed for embedding live widgets inside rich text, but only at one level. The widgets themselves would contain text, but there wasn't a way to include widgets in that embedded text recursively. If only the rich text editor could treat itself as a widget that it could self-embed, the system would compose to arbitrary depth.<br />
<br />
Sadly, non-compositional text editors are the norm. Most widget sets have some sort of text widget, but that widget typically traffics in text only. Over twenty years ago, the <a href="http://www.strongtalk.org/">Strongtalk</a> system addressed this problem (and we were by no means the first to do so). I demo'ed this in my talk: here's a <a href="https://www.youtube.com/watch?v=5jRQcs9gx3Y">brief video recreating the main points of that demo</a>.<br />
<br />
The demo shows the embedding of live IDE components in both the ordinary text editors used to edit code, and in rich text generated from markup. One open question is when to use either approach, or how to integrate them. Another point I highlight is the failure of liveness in instance methods, something I've discussed in <a href="https://gbracha.blogspot.com/2013/04/making-methods-live.html">previous posts</a>. Having raised that problem, I moved on to showing my approach to solving it by demoing <a href="https://www.youtube.com/watch?v=Yv7yX27Tx4U">Newspeak's exemplar mode</a>.<br />
<br />
The Strongtalk demo emphasized literate programming issues; the <a href="http://newspeaklanguage.org/">Newspeak</a> demo focused on liveness. Ampleforth is aimed at addressing both of these, and so I went on to demonstrate Ampleforth, the system I described in my <a href="https://gbracha.github.io/illiterateProgramming/out/illiterateProgramming.html">prior post</a>. In the talk, I showed Ampleforth embedded in the presentation itself. Here's <a href="http://www.youtube.com/watch?v=eBuiL6asa5Y">a recording of essentially the same thing.</a><br />
<br />
Obviously, one cannot embed live programs in conventional presentation tools like PowerPoint or Keynote (or Prezi, for that matter). Instead, the presentation was built using <a href="https://leisure.handmade.network/">Lounge</a>, a system being developed by Bill Burdick. Bill shares a very similar vision for live literate programming, which he calls Illuminated programming. He uses Lounge to run Leisure, a purely functional, lazy language. Lounge certainly lacks the visual polish of commercial tools, but unlike those tools, its fundamental architecture is sound. A Lounge document (such as a presentation) is defined using emacs's <a href="http://orgmode.org/">Org mode</a> format. Some adjustments were necessary to embed Ampleforth into Lounge - basically setting things up to run within an IFrame; these tweaks should make it easier to embed Ampleforth into other web based tools as well.<br />
<br />
What of our glaring flaw? The flaw is not in Ampleforth itself. Rather, it lies in the text editors in which it is embedded and those which are embedded in the widgets we use. Fortunately, the DOM actually does better in this fundamental respect, and so on the web, this is fixable. Unfortunately, the web's basic text editing facility, content-editable text, is all but unusable.
Lounge itself has a text editor that doesn't suffer from this weakness. In principle, we could access the Lounge editor from Newspeak, but in this case we embedded Ampleforth with its rudimentary editor (based on content-editable text). I'm planning to modify Newspeak's web environment to use CodeMirror as its default editor, which should help as well.<br />
<br />
An important question that came up in the Q&A was whether liveness was actually desirable. After all, the code is supposed to be correct for all possible inputs, and relying on examples rather than abstract reasoning and proofs might be dangerous. My response was that liveness takes nothing away - you can go prove invariants to your heart's content. Liveness can be abused, but overall it makes people more productive by reducing the cycle between specifying intent and measuring actual results.<br />
<br />
Dave Ungar later gave another, even better answer: that invariants themselves should be reified in the environment, so we can remember them all, communicate them to others, ask them to monitor the program to see if they are violated etc.<br />
<br />
To Life, Literacy and the Pursuit of Happiness!<br />
<br />
<br />Gilad Brachahttp://www.blogger.com/profile/17934280339206214042noreply@blogger.com4tag:blogger.com,1999:blog-2447174102813539049.post-58762433375413535372016-11-20T18:35:00.000-08:002016-11-20T18:38:43.532-08:00Illiterate Programming<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
I have long been a fan of literate programming, especially <i>live literate programming</i>. I wrote a brief <a href="https://gbracha.github.io/illiterateProgramming/out/illiterateProgramming.html">note</a> about the topic a while ago, but for various reasons did not distribute it. Recently, the early release of <a href="http://incidentalcomplexity.com/index.html">Eve</a> (very nice work) has injected some new life in this area. So I decided to belatedly post my musings on the subject.<br />
<br />
Ironically, posting <b>live</b> programming content is difficult on many web publishing venues, such as this blog, or Medium. So if you actually want the substance of this post, you'll have to follow <a href="https://gbracha.github.io/illiterateProgramming/out/illiterateProgramming.html">this link</a>.</div>
Gilad Brachahttp://www.blogger.com/profile/17934280339206214042noreply@blogger.com2tag:blogger.com,1999:blog-2447174102813539049.post-33326458282683160122014-11-28T18:29:00.000-08:002014-11-28T19:04:59.585-08:00A DSL with a ViewIn a previous post, I promised to explain how one might define UIs using an internal DSL. Using an internal DSL would allow us to capitalize on the full power of a general purpose programming language and avoid having to reinvent everything from if-statements to imports to inheritance.<br />
<br />
Hopscotch, Newspeak's UI framework, employs such an internal DSL. Hopscotch has been discussed in a <a href="http://bracha.org/hopscotch-wasdett.pdf">paper</a> and in a <a href="http://download.microsoft.com/download/e/7/7/e77a8fce-0362-4930-bd5e-8a21ec77e38d/giladbracha.mp4">talk</a>. It will take more than one post to describe Hopscotch; here we will focus on its DSL, which is based on the notion of <i>fragment combinators</i>.<br />
<br />
<i>Fragments</i> describe pieces of the UI; they may describe individual widgets, or views constructed from multiple pieces, each of which is in turn a fragment. A fragment combinator is then a method that produces a fragment, possibly from other fragments.<br />
<br />
One of the simplest fragment combinators would be <i>label:</i>, which takes a string. The expression<br />
<br />
<i><span style="font-family: Courier New, Courier, monospace;">label: 'Hello Brave New World' </span></i><br />
<br />
would be used to put up the string "Hello Brave New World" on the screen. Other examples might be<br />
<br />
<span style="font-family: Courier New, Courier, monospace;"><i>button: 'Press me' action: [shrink]</i></span><br />
<br />
which will display a button<br />
<div>
<br /></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-fg2iGHFTBpU/VFWfUpE8i_I/AAAAAAAAEgw/7CP8fNC1Y_k/s1600/buttonExample1.tiff" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-fg2iGHFTBpU/VFWfUpE8i_I/AAAAAAAAEgw/7CP8fNC1Y_k/s1600/buttonExample1.tiff" /></a></div>
<br />
that will call the method <i>shrink</i> when invoked. The combinator <i>button:action:</i> takes two arguments - the first being a string that serves as the label of the button, and the second being a closure that defines the action taken when the button is pressed. Closures in Newspeak are delimited with square brackets, and need not provide a parameter list if no parameters are required. This is the most lightweight syntax for literal functions you will find. Along with the method invocation syntax, where method names embed colons to indicate where arguments should be placed, this gives a very readable notation for many DSLs.<br />
<br />
Further examples:<br />
<br />
<span style="font-family: Courier New, Courier, monospace;"><i>row: {</i></span><br />
<span style="font-family: Courier New, Courier, monospace;"><i> button: 'Press me' action: [shrink]. </i></span><br />
<span style="font-family: Courier New, Courier, monospace;"><i> button: 'No, press me' action: [grow].</i></span><br />
<span style="font-family: Courier New, Courier, monospace;">}</span><br />
<br />
The <i>row:</i> combinator takes a tuple of fragments (tuples in Newspeak are delimited by curly braces, and their elements are separated by dots) as its argument and lays out the elements of the tuple horizontally:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-3Zn-6dcuReA/VFWgPbfUemI/AAAAAAAAEg4/iHbVwFKIjag/s1600/buttonExample2.tiff" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-3Zn-6dcuReA/VFWgPbfUemI/AAAAAAAAEg4/iHbVwFKIjag/s1600/buttonExample2.tiff" /></a></div>
<br />
the <i>column:</i> combinator is similar, except that it lays things out vertically<br />
<br />
<span style="font-family: Courier New, Courier, monospace;"><i>column: {</i></span><br />
<span style="font-family: Courier New, Courier, monospace;"><i> button: 'Press me' action: [shrink]. </i></span><br />
<span style="font-family: Courier New, Courier, monospace;"><i> button: 'No, press me' action: [grow]</i></span><br />
<span style="font-family: Courier New, Courier, monospace;"><i>}</i></span><br />
<br />
produces:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-8o9aC-SpyRI/VFWhcSq00zI/AAAAAAAAEhE/bK8S5L30JrM/s1600/buttonExample3.tiff" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-8o9aC-SpyRI/VFWhcSq00zI/AAAAAAAAEhE/bK8S5L30JrM/s1600/buttonExample3.tiff" /></a></div>
<br />
<br />
In mainstream syntax (Dart, in this case) the example could be written as<br />
<br />
<span style="font-family: Courier New, Courier, monospace;"><i>column(</i></span><br />
<span style="font-family: Courier New, Courier, monospace;"><i> [button('Press me', ()=> shrink), </i></span><br />
<span style="font-family: Courier New, Courier, monospace;"><i> button('No, press me', () => grow)]</i></span><br />
<span style="font-family: Courier New, Courier, monospace;"><i><span style="font-size: x-small;"> )</span></i></span><br />
<br />
The Newspeak syntax is remarkably readable though, and its advantage over mainstream notation becomes more pronounced as examples grow. Of course none of this works at all if your language doesn't support both closures and literal lists/arrays.<br />
<br />
So far, this is very standard stuff, much like building a tree of views in most systems. In most UI frameworks, we'd write something like<br />
<br />
<span style="font-family: Courier New, Courier, monospace;"><i><b>new</b> Column([<b>new</b> Button('Press me', ()=> shrink), </i></span><br />
<span style="font-family: Courier New, Courier, monospace;"><i><b> new</b> Button('No, press me', () => grow)]</i></span><br />
<span style="font-family: Courier New, Courier, monospace;"><i> )</i></span><br />
<br />
which is less readable and more verbose. Since allocating an instance is more verbose than calling a method in most languages, the fact that fragment combinators are represented via methods, which act as factories for various kinds of views, helps make things more concise. It's a simple trick, but worth noting.<br />
<br />
The advantage of thinking in terms of fragments becomes clearer once you consider less obvious fragments such as <i>draggable:subject:image:</i>, which takes a fragment and allows it to be dragged and dropped. Along with the fragment, it takes a subject (what you might call a controller) and an image to use during the drag. Making drag-and-drop a combinator means <b>everything</b> is potentially draggable. Conventional designs would make this a special attribute of certain things only, losing the compositionality that combinators provide.<br />
<br />
<i>Presenters</i> are a a specific kind of fragment that is especially important. Presenters provide user-defined views in the Model-View-Controller sense. To define your own view, you subclass <i>Presenter</i>. Because presenters are fragments, any user defined view can be part of a predefined compound fragment like <i>column:</i> or <i>draggable:subject:image:</i>.<br />
<br />
A presenter has a method <i>definition</i> which computes a fragment tree which is used to render the presenter. The fragment DSL we discussed is used inside of presenters. All the combinators are methods of <i><span style="font-family: Times, Times New Roman, serif;">Presenter</span></i>, so they are inherited by any class implementing a view, and are therefore in scope inside a presenter class. In particular, combinators are available in the <i>definition</i> method.<br />
<br />
To see how all this works, imagine implementing the well known <b>todoMVC</b> example. We'll define a subclass of <i>Presenter</i> called <i>todoMVCPresenter</i> to represent the todoMVC UI. The UI is supposed to present a list of todo items. It consists of a column with:<br />
<br />
<br />
<ol>
<li>A header in large text saying "todos" </li>
<li>An input zone where new todos are added.</li>
<li>A list of todos, which can be filtered using controls given in (4). </li>
<li>A footer, that is empty if there are no todos at all. It materializes as a set of controls once there are todos.</li>
</ol>
<br />
<div>
We can translate these requirements directly:</div>
<div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><i>definition = (</i></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><i> ^column: {</i></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><i> (label: 'todos') hugeFont.</i></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><i> inputZone.</i></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><i> todoList.</i></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><i> footer.</i></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><i> }</i></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><i>)</i></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><i><br /></i></span></div>
<div>
<b>More notes on syntax:</b> <i>methods are defined by following their header with an equal sign and a body delimited by parentheses; <span style="font-family: Courier New, Courier, monospace;">^</span> signifies <b>return</b>; method invocations that take no parameters list no arguments, e.g., inputZone, not inputZone(); chained method invocation does not require a dot - so it's </i></div>
<div>
<i><span style="font-family: inherit;">(label: 'todos') hugeFont</span><span style="font-family: 'Courier New', Courier, monospace;"> </span>rather than label('todos').hugeFont.</i></div>
<div>
<br /></div>
<div>
We haven't yet specified what <i>inputZone</i>, <i>todoList</i> and <i>footer</i> do. They are all going to be defined as methods of <i>todoMVCPresenter</i>. We can define the UI in such a top down fashion because we are working with a language that supports procedural abstraction. You get it for free in an internal DSL. </div>
<div>
<br /></div>
<div>
We can then define the pieces, such as</div>
<div>
<br /></div>
<div>
<div>
<i><span style="font-family: Courier New, Courier, monospace;">footer = (</span></i></div>
<div>
<i><span style="font-family: Courier New, Courier, monospace;"> ^subject todos isEmpty </span></i></div>
<div>
<i><span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> ifTrue: [nothing]</span></i></div>
<div>
<i><span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> ifFalse: [controls]</span></i></div>
<div>
<i><span style="font-family: Courier New, Courier, monospace;">)</span></i></div>
</div>
<div>
<br /></div>
<div>
Here, we use conditionals to determine what view to produce, depending on the state of the application. The application logic is embodied in the controller, <i>subject</i>, which we query for the<i> todos</i> list<i>.</i> The <i>nothing</i> combinator does exactly what it says; <i>controls</i> is a method we would have to define in <i>todoMVCPresenter</i>, detailing what should appear in the footer if it is visible. Again, the code corresponds closely to the natural language description in bullet (4) above.</div>
<div>
<br /></div>
<div>
To elaborate <i>todoList</i> we'll need a loop or recursion or something of that nature; in fact, we'll use the higher order method <i>collect:</i>, which is Newspeak's version of <i>map</i>. </div>
</div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><i>todoList = (^list:[subject todos collect: [:todo | todo presenter]])</i></span></div>
<br />
<span style="font-family: Times, 'Times New Roman', serif; vertical-align: baseline; white-space: pre-wrap;">The </span><span style="font-family: Times, 'Times New Roman', serif; font-style: italic; vertical-align: baseline; white-space: pre-wrap;">list:</span><span style="font-family: Times, 'Times New Roman', serif; vertical-align: baseline; white-space: pre-wrap;"> combinator packages a list of fragments into a list view. We pass<i> list:</i> a closure that computes the list to todo items. </span><br />
<span style="font-family: Times, 'Times New Roman', serif; vertical-align: baseline; white-space: pre-wrap;"><br /></span>
<span style="font-family: Times, 'Times New Roman', serif; vertical-align: baseline; white-space: pre-wrap;"><i><b>Aside</b>: We could have passed it the list itself, computed eagerly. Often, fragment combinators take either suitable fragment(s) a closure that would compute them.</i></span><br />
<span style="font-family: Times, 'Times New Roman', serif; vertical-align: baseline; white-space: pre-wrap;"><br /></span>
<span style="font-family: Times, 'Times New Roman', serif; vertical-align: baseline; white-space: pre-wrap;">To compute the fragment list </span>we compute a presenter for each individual todo item by mapping over the original list of todos.<br />
The closure we pass to <i>collect:</i> takes a single parameter, <i>todo</i>. Formal parameters to closures are introduced prefixed by a colon, and separated from the closure body by a vertical bar.<br />
<br />
What are the odds that higher order functions (HOFs) were part of your external DSL? Even if they were, one would have to define a suite of useful HOFs. One should factor the cost of defining useful libraries into any comparison of internal and external DSLs.<br />
<br />
The Hopscotch DSL has other potential advantages. Because fragment combinators are methods, you can override them to customize their behavior.<br />
We believe we can leverage this to customize the appearance of things, a bit like CSS. To make this systematic, we expect to define whole groups of overrides in mixins. I'm not showing examples where Hopscotch is used this way because we have done very little in that space (and this post is already too long anyway). And we haven't spoken about the other advantages of Hopscotch. <br />
such as its navigation model, lack of modality and very clean embodiment of MVC.<br />
<div>
<br /></div>
Ok, now it's time for the caveats.<br />
<br />
<br />
<ol>
<li>First and foremost, Hopscotch currently lacks a good story for reactive binding. In our example, that means you'd have to put explicit logic to refresh the display in some of the controls. This makes things less declarative and harder to use. We always planned to solve that problem; I hope to address it in a later post. But the high order bit is that we have code in a general purpose language that gives a very readable, declarative description of the UI. It corresponds directly to the natural language description of the requirements.</li>
<li>Hopscotch lacks functionality in order to support richer UIs, but the design is naturally extensible: one adds more fragment combinators.</li>
<li>We also want more ports, especially to mobile/touch platforms. However, Hopscotch has already proven quite portable: it runs on native Win32, on Squeak's Morphic and on HTML (the latter port is still partial, but that is just an issue of engineering resources). More ports would help us deal with another controversial goal - defining a UI platform that works well across OS's and devices.</li>
</ol>
<br />
<br />
Regardless of the current engineering limitations, the point here is simply to show the advantages of a well-designed internal DSL for UI. The lessons of Newspeak and Hopscotch apply to other languages and systems, albeit in an attenuated fashion.<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />Gilad Brachahttp://www.blogger.com/profile/17934280339206214042noreply@blogger.com0tag:blogger.com,1999:blog-2447174102813539049.post-61602602811336384302014-09-29T22:20:00.000-07:002014-09-30T22:19:08.942-07:00A DOMain of Shadows<div class="p1">
<span class="s1">One of the advantages of an internal DSL over an external one is that you can leverage the full power of a general purpose programming language. If you create an external DSL, you may need to reinvent a slew of mechanisms that a good general purpose language would have provided you: things like modularity, inheritance, control flow and procedural abstraction.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">In practice, it is unlikely that the designer of the DSL has the resources or the expertise to reinvent and reimplement all these, so the DSL is likely to be somewhat lobotomized. It may lack the facilities above entirely, or it may have very restricted versions of some of them. These restricted versions are mere shadows of the real thing; you could say that the DSL designer has created a <i>shadow world</i>.</span></div>
<div class="p1">
<span class="s1">I discussed this phenomenon as part of <a href="http://www.infoq.com/presentations/past-present-future-programming"><span class="s2">a talk I gave at Onward</span></a> in 2013. This post focuses on a small part of that talk.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">Here are three examples that might not always be thought of as DSLs at all, but definitely introduce a shadow world.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p2">
<span class="s1"><b>Shadow World 1: The module system of Standard ML.</b></span></div>
<div class="p3">
<span class="s1"></span><br /></div>
<div class="p1">
<span class="s1">ML modules contain type definitions. To avoid the undecidable horrors of a type of types, ML is stratified. There is the strata of values, which is essentially a sugared lambda calculus. Then there is the stratum of modules and types. Modules are called <i>structures</i>, and are just records of values and types. They are really shadow records, because at this level, by design, you can no longer perform general purpose computation. Of course, being a statically typed language, one wants to describe the types of structures. ML defines <i>signatures</i> for this purpose. These are shadow record types. You cannot use them to describe the types of ordinary variables.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">It turns out one still wants to abstract over structures, much as one would over ordinary values. This is necessary when one wants to define parameterized modules. However, you can’t do that with ordinary functions. ML addresses this by introducing <i>functors</i>, which are shadow functions. Functors can take and return structures, typed as signatures. However, functors cannot take or return functors, nor can they be recursive, directly or indirectly (otherwise we’d back to the potentially non-terminating compiler the designers of ML were trying so hard to avoid in the first place).</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">This means that modules can never be mutually recursive, which is unfortunate since this turns out to be a primary requirement for modularity. It isn’t a coincidence that we use <b>circuits</b> for electrical systems and communication systems, to name two prominent examples. </span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">It also means that we can’t use the power of higher order functions to structure our modules. Given that the whole language is predicated on higher order functions as the main structuring device, this is oddly ironic.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">There is a lot of published research on overcoming these limitations. There are papers about supporting restricted forms of mutual recursion among ML modules. There are papers about allowing higher-order functors. There are papers about combining them. These papers are extremely ingenious and the people who wrote them are absolutely brilliant. But these papers are also mind-bogglingly complex. </span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">I believe it would be much better to simply treat modules as ordinary values. Then, either forego types as module elements entirely (as in Newspeak) or live with the potential of an infinite loop in the compiler. As a practical matter, you can set a time or depth limit in the compiler rather than insist on decidability. I see this as a pretty clear cut case for first class values rather than shadow worlds.</span></div>
<div class="p3">
<span class="s1"></span><br /></div>
<div class="p2">
<span class="s1"><b>Shadow World 2: Polymer</b></span></div>
<div class="p3">
<span class="s1"></span><br /></div>
<div class="p1">
<span class="s1">Polymer is an emerging web standard that aims to bring a modicum of solace to those poor mistreated souls known as web programmers. In particular, it aims to allow them to use component based UIs in a standardized way.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">In the Polymer world, one can follow a clean MVC style separation for views from controllers. The views are defined in HTML, while the controllers are defined in an actual programming language - typically Javascript, but one can also use Dart and there will no doubt be others. All this represents a big step forward for HTML, but it remains deeply unsatisfactory from a programming language viewpoint.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">The thing is, you can’t really write arbitrary views in HTML. For example, maybe your view has to decide whether to show a UI element based on program logic or state. Hence you need a conditional construct. You may have heard of these: things like if statements or the ?: operator. So we have to add shadow conditionals.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p4">
<span class="s1"><span style="font-family: Courier New, Courier, monospace;"><template if="{{usingForm}}"></span></span></div>
<div class="p4">
<span class="s1"><span style="font-family: Courier New, Courier, monospace;"><somecomponent></somecomponent></span></span></div>
<div class="p4">
<span class="s1"><span style="font-family: Courier New, Courier, monospace;"></span></span></div>
<div class="p4">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">is how you’d express </span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p4">
<span class="s1"><span style="font-family: Courier New, Courier, monospace;">if (usingForm) someComponent;</span></span></div>
<div class="p4">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">In a world where programmers cry havoc over having to type a semicolon, it’s interesting how people accept this. However, it isn’t the verbose, noisy syntax that is the main issue.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">The conditional construct doesn’t come with an <i>else</i> of <i>elsif</i> clause, nor is their a <i>switch</i> or <i>case</i>. So if you have a series of alternatives such as</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p4">
<span class="s1"><span style="font-family: Courier New, Courier, monospace;">if (cond1) {ui1}</span></span></div>
<div class="p4">
<span class="s1"><span style="font-family: Courier New, Courier, monospace;">else if (cond2) {ui2}</span></span></div>
<div class="p4">
<span class="s1"><span style="font-family: Courier New, Courier, monospace;"> else {ui3}</span></span></div>
<div class="p3">
<span class="s1"></span><br /></div>
<div class="p1">
<span class="s1">You have to write</span><br />
<span class="s1"><br /></span>
<br />
<div class="p1">
<span class="s1"><span style="font-family: Courier New, Courier, monospace;"><template if = </span><span style="font-family: 'Courier New', Courier, monospace;">"</span><span style="font-family: Courier New, Courier, monospace;">{{cond1}}</span></span><span style="font-family: 'Courier New', Courier, monospace;">"</span><span style="font-family: 'Courier New', Courier, monospace;">></span></div>
<div class="p1">
<span class="s1"><span style="font-family: Courier New, Courier, monospace;"><ui1></span></span></div>
<div class="p1">
<span class="s1"><span style="font-family: Courier New, Courier, monospace;"></template></span></span></div>
<div class="p1">
<span class="s1"><span style="font-family: Courier New, Courier, monospace;"><template if = </span></span><span style="font-family: 'Courier New', Courier, monospace;">"</span><span style="font-family: 'Courier New', Courier, monospace;">{{cond2 && !cond1}}</span><span style="font-family: 'Courier New', Courier, monospace;">"</span><span style="font-family: 'Courier New', Courier, monospace;">></span></div>
<div class="p1">
<span class="s1"><span style="font-family: Courier New, Courier, monospace;"><ui2></span></span></div>
<div class="p1">
<span class="s1"><span style="font-family: Courier New, Courier, monospace;"></template></span></span></div>
<div class="p1">
<span class="s1"><span style="font-family: Courier New, Courier, monospace;"><template if = </span></span><span style="font-family: 'Courier New', Courier, monospace;">"</span><span class="s1"><span style="font-family: Courier New, Courier, monospace;">{{cond3 && !cond2 && !cond3}</span></span><span style="font-family: 'Courier New', Courier, monospace;">"</span><span style="font-family: 'Courier New', Courier, monospace;">}></span></div>
<div class="p1">
<span class="s1"><span style="font-family: Courier New, Courier, monospace;"><ui3></span></span></div>
<span class="s1" style="font-family: Courier New, Courier, monospace;">
</span><br />
<div class="p1">
<span class="s1"><span style="font-family: Courier New, Courier, monospace;"></template></span></span></div>
</div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p4">
<span class="s1"><span style="font-family: Courier New, Courier, monospace;"><template if="“{{cond1”}}"></template></span></span></div>
<div class="p4">
<span class="s1"><span style="font-family: Courier New, Courier, monospace;"><ui1></ui1></span></span></div>
<div class="p4">
<span class="s1"><span style="font-family: Courier New, Courier, monospace;"></span></span></div>
<div class="p4">
<span class="s1"><span style="font-family: Courier New, Courier, monospace;"><template amp="" cond1="" if="“{{cond2"></template></span></span></div>
<div class="p4">
<span class="s1"><span style="font-family: Courier New, Courier, monospace;"><ui2></ui2></span></span></div>
<div class="p4">
<span class="s1"><span style="font-family: Courier New, Courier, monospace;"></span></span></div>
<div class="p4">
<span class="s1"><span style="font-family: Courier New, Courier, monospace;"><template amp="" cond2="" cond3="" if="“{{cond3"></template></span></span></div>
<div class="p4">
<span class="s1"><span style="font-family: Courier New, Courier, monospace;"><ui3></ui3></span></span></div>
<div class="p4">
<span class="s1"><span style="font-family: Courier New, Courier, monospace;"></span></span></div>
<div class="p4">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">A UI might have to display a varying number of elements, depending on the size of a data structure in the underlying program. Maybe it needs to repeat the display of a row in a database <i>N</i> times, depending on the amount of data. We use loops for this in real programming. So we now need shadow loops.</span></div>
<div class="p1">
<span class="s1"><br /></span>
<span class="s1">
</span><br />
<div class="p1">
<span class="s1"><span style="font-family: Courier New, Courier, monospace;"><template repeat = </span></span><span style="font-family: 'Courier New', Courier, monospace;">"</span><span style="font-family: 'Courier New', Courier, monospace;">{{task in current}}</span><span style="font-family: 'Courier New', Courier, monospace;">"</span><span style="font-family: 'Courier New', Courier, monospace;">></span></div>
</div>
<div class="p4">
<span class="s1"><span style="font-family: Courier New, Courier, monospace;"><template current="" in="" repeat="“{{task"></template></span></span></div>
<div class="p4">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">There’s also a for loop</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p5">
<span class="s1"><span style="font-family: Courier New, Courier, monospace;"><template repeat="{{ foo, i in foos }}"></template></span></span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace;"><span class="s1"></span>
</span><br />
<div class="p1">
<span class="s1"><span style="font-family: Courier New, Courier, monospace;"><template repeat= "{{ foo, i in foos }}"></span></span></div>
</div>
<div class="p3">
<span class="s1"></span><br /></div>
<div class="p1">
<span class="s1">Of course one needs to access the underlying data from the controller or model, and so we need a way to reference variables. So we have shadow variables like</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p4">
<span class="s1"><span style="font-family: Courier New, Courier, monospace;">{{usingForm}} </span></span></div>
<div class="p4">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">and shadow property access.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p4">
<span class="s1"><span style="font-family: Courier New, Courier, monospace;">{{current.length}}</span></span></div>
<div class="p4">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">Given that we are building components, we need to use components built by others, and the conventional solution to this is imports. And so we add shadow imports.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p4">
<span class="s1" style="font-family: Courier New, Courier, monospace;">
</span><br />
<div class="p1">
<span class="s1"><span style="font-family: Courier New, Courier, monospace;"><link rel = </span></span><span style="font-family: 'Courier New', Courier, monospace;">"</span><span style="font-family: 'Courier New', Courier, monospace;">import” href = </span><span style="font-family: 'Courier New', Courier, monospace;">"</span><span style="font-family: 'Courier New', Courier, monospace;">...</span><span style="font-family: 'Courier New', Courier, monospace;">"</span><span style="font-family: 'Courier New', Courier, monospace;">></span></div>
</div>
<div class="p4">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">UI components are a classic use case for inheritance, and polymer components support can be derived from each other, starting with the predefined elements of the DOM, via shadow inheritance. It is only a matter of time before someone realizes they would like to reuse properties from other components in different hierarchies via shadow mixins.</span><br />
<br /></div>
<div class="p1">
<span class="s1">By now we’ve defined a whole shadow language, represented as a series of ad hoc constructions embedded in string-valued attributes of HTML. A key strength of HTML is supposed to be ease-of-use for non-programmers (this is often described by the meaningless phrase <i>declarative</i>). Once you have added all this machinery, you’ve lost that alleged ease of use - but you don’t have a real programming language either. </span></div>
<div class="p3">
<span class="s1"></span><br /></div>
<div class="p2">
<span class="s1"><b>Shadow World 3: Imports</b></span></div>
<div class="p3">
<span class="s1"></span><br /></div>
<div class="p1">
<span class="s1">Imports themselves are a kind of shadow language even in a real programming language. Of course imports have other flaws, as I’ve discussed <a href="http://gbracha.blogspot.co.il/2009/06/ban-on-imports.html"><span class="s2">here</span></a> and <a href="http://gbracha.blogspot.co.il/2009/07/ban-on-imports-continued.html"><span class="s2">here</span></a>, but that is not my focus today. Whenever you have imports, you find demands for conditional imports, for an aliasing mechanism (<i>import-as</i>) for a form of iteration (wildcards). All these mechanisms already exist in the underlying language and yet they are typically unavailable because imports are second-class constructs.</span></div>
<div class="p3">
<span class="s1"></span><br /></div>
<div class="p2">
<span class="s1"><b>Beyond Criticism</b></span></div>
<div class="p3">
<span class="s1"></span><br /></div>
<div class="p1">
<span class="s1">It is very easy to criticize other people’s work. To quote Mark Twain:</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p6">
<span class="s1"><i>I believe that the trade of critic, in literature, music, and the drama, is the most degraded of all trades, and that it has no real value</i></span><span class="s3"> </span></div>
<div class="p6">
<span class="s3"><br /></span></div>
<div class="p1">
<span class="s1">So I had better offer some constructive alternative to these shadow languages. With respect to modularity, <a href="http://newspeaklanguage.org/"><span class="s2">Newspeak</span></a> is my answer. With respect to UI, something along the lines of the Hopscotch UI framework is how I’d like to tackle the problem. In that area, we still have significant work to do on data binding, which is one of the greatest strengths of polymer. In any case, I plan to devote a separate post to show how one can build an internal DSL for UI inside a clean programming language. </span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">The point of <i>this</i> post is to highlight the inherent cost of going the shadow route. Shadow worlds come in to being in various ways. One way is when we introduce second class constructs because we are reluctant to face up to the price of making something a real value. This is the case in the module and import scenarios above. Another way is when one defines an external DSL (as in the HTML/Polymer example). In all these cases, one will always find that the shadows are lacking. </span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<br />
<div class="p1">
<span class="s1">Let’s try and do better.</span></div>
Gilad Brachahttp://www.blogger.com/profile/17934280339206214042noreply@blogger.com23tag:blogger.com,1999:blog-2447174102813539049.post-6771774200852922712014-08-29T21:33:00.000-07:002014-08-30T15:07:13.241-07:00Taking it to Th’emacs<div class="p1">
<span class="s1">Emacs is my preferred text editor. I don’t use old-fashioned text editors as much as I used to, because I often need more specialized tools. I use IDEs for various programming languages and other things when producing high quality documents. And yet, I often wish I could subsume these with a tool that had the basic goodness of emacs.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">What makes emacs interesting all these decades after its inception is not what keyboard shortcuts it supports or what its basic editing functionality is. Rather, what matters are some of its underlying design principles.</span></div>
<ul>
<li class="li1"><span class="s1">Emacs has built-in scripting language. </span></li>
<li class="li1"><span class="s1">That language (elisp), while it has many flaws, is a flexible, dynamic, and rather general purpose language. </span></li>
<li class="li1"><span class="s1">All of the editor’s functionality is exposed via APIs written in the scripting language.</span></li>
</ul>
<div class="p1">
<span class="s1">As a consequence, you can control everything emacs does programmatically. This makes emacs extensible in a way that is far deeper and more powerful than a plug-in architecture. A plug-in architecture must anticipate every desired extension to the system. Since it never can, it always disappoints in the end. Along the way it grows ever more complex and bloated in its futile attempt to foresee every possible need. With a language, you can code any extension you need.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">If the scripting language is truly dynamic, and allows you to not only extend but also <i>modify</i> the running system, the possibilities are truly unlimited.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">The points above are not limited to editors. They are fundamentals of system design.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1"><i>There was a time when even Microsoft recognized this, making apps that could be programmed via VisualBasic. Sadly, they concocted a security nightmare, because malware can also control your application. Which is why being able to secure your application’s scripting language is critical as well. </i></span></div>
<div class="p1">
<span class="s1"><i><br /></i></span></div>
<div class="p1">
<span class="s1">Last June, <a href="http://www.infoq.com/presentations/web-programming-future"><span class="s2">I spoke at QCon NY</span></a>, and demonstrated a number of interesting web based systems that had some these properties (as well as a couple that did not, but were interesting for other reasons):</span></div>
<ul>
<li class="li1"><span class="s1"><a href="https://github.com/zot/Leisure">Leisure</a> is a presentation manager that incorporates a lazy functional programming language. Modulo some person-years of engineering, it is to PowerPoint what emacs is to NotePad. </span></li>
<li class="li1"><span class="s1">The <a href="http://lively-kernel.org/repository/webwerkstatt/gettingStarted.xhtml"><span class="s2">Lively Kernel</span></a> could be thought of as a GUI builder scripted via Javascript; this an insult to Lively of course, because it is much more than that. In Lively, the GUI is the GUI builder; every GUI you make is extensible and modifiable in the same way.</span></li>
<li class="li1"><span class="s1">Lastly I showed <a href="https://8a616521eaba88639fe08345a88fa288e26a6b34.googledrive.com/host/0B7VkTjJg2xYDNHphX3JSNFFsd1E/samples/MiniBrowser/MiniBrowser.html"><span class="s2">Minibrowser</span></a>, a prototype web based IDE for Newspeak. Like all IDEs in the Smalltalk tradition, it can be extended and modified from within itself.</span></li>
</ul>
<div class="p1">
<span class="s1">We really need an Emacs for the modern age. An editor, surely, but one that lets you edit rich text, images, audio and video. In fact, you should be able to embed arbitrary widgets. And of course it needs to be scriptable I just explained. So you might evaluate code that creates a UI element and inserts into the editor. </span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">Now you can make the editor modify its own GUI. In fact, the editor can be extended into a general purpose GUI builder just like Lively. And every such GUI can modify itself if you wish; sometimes you may wish to modify it so it can no longer modify itself, and then you have a frozen application. Your editor has become an IDE. In fact, it is a <i>live literate programming environment</i>. </span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p2">
<span class="s1">If the editor’s scripting language interoperates well with the surrounding environment, it can be used to control the computer and everything the computer itself controls. You can check in to the environment and hardly ever leave. You can lead your cyber life in it.: email, social media, live chats, streaming audio and video can all be incorporated. Moreover they can all be controlled and customized by you, the lucky user. </span></div>
<div class="p3">
<span class="s1"></span><br /></div>
<div class="p2">
<span class="s1">To a degree, Lively is such an editor. It’s biggest drawbacks are a lack of polish due to lack of engineering resources and that its scripting language is Javascript.</span></div>
<div class="p4">
<span class="s1"></span><br /></div>
<div class="p2">
<span class="s1">Now, imagine that the editor was polished and robust. Even more importantly the code you created in this environment was modular and secure and written in an elegant and principled language. Imagine you could deploy the same code either on the web, or natively on both desktop and mobile. Imagine that the applications built with the language support online and offline use out of the box, automatically synchronizing data and code between clients and servers. Imagine that they have built-in support for collaboration, either syncing in real time or merging offline as required. </span></div>
<div class="p3">
<span class="s1"></span><br /></div>
<div class="p2">
<span class="s1">Of course, it is the vision of such a language and platform that has always motivated the <a href="http://www.newspeaklanguage.org/"><span class="s2">Newspeak</span></a> project. I have discussed many of these points before. In particular, I’ve talked about the weaknesses of traditional IDEs (see for example <a href="http://gbracha.blogspot.com/2008/11/dynamic-ides-for-dynamic-languages.html"><span class="s2">this post</span></a> and <a href="http://gbracha.blogspot.com/2008/06/incremental-development-environments.html"><span class="s2">this one</span></a>), and the need for a platform that supports synchronization over the net (<a href="http://gbracha.blogspot.com/2007/03/sobs.html"><span class="s2">here</span></a> and <a href="http://gbracha.blogspot.com/2008/04/everyone-is-talking-about-cloud.html"><span class="s2">again here</span></a>) for a long time. Yet the message bears repeating. </span></div>
<br />
<div class="p3">
<span class="s1"></span><br /></div>
Gilad Brachahttp://www.blogger.com/profile/17934280339206214042noreply@blogger.com34tag:blogger.com,1999:blog-2447174102813539049.post-65003773976997387062013-04-04T22:21:00.000-07:002013-07-13T09:16:27.222-07:00Making Methods Live<br />
<div class="p1">
<span class="s1">A few months ago, <a href="http://gbracha.blogspot.com/2012/11/debug-mode-is-only-mode.html"><span class="s2">I suggested that IDEs should ensure that code is always “live”</span></a> in the sense that it is associated with runtime data so that any part of the code can be immediately executed. I proposed that tightly integrating editors and debuggers would be reasonable way to pursue the idea.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">I’ve put together a prototype, an extension of the Newspeak IDE. I demonstrated an early version at the <a href="http://program-transformation.org/WGLD/">WGLD</a> meeting in <a href="http://program-transformation.org/WGLD/Austin2012">December</a>. Since then there have been some improvements, though a lot of work remains to be done. Nevertheless, the system is already usable, at least by an experienced Newspeaker.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">In Newspeak, one typically edits individual methods in a class browser, as opposed to monolithic files. The prototype modifies the method browsers to present the method along with a view of a live stack frame. This is essentially the same view one sees in the debugger, where a series of activations are available; <a href="http://gbracha.blogspot.com/2008/07/debugging-visual-metaphors.html"><span class="s2">each such view shows a single stack frame along with the corresponding code</span></a>. </span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">I plan to show the latest version at the upcoming Live 2013 workshop. I’ve prepared a <a href="https://www.youtube.com/watch?v=74WqdS_58uY&feature=youtu.be"><span class="s2">short video</span></a> illustrating some of the capabilities of the system. The video is cut short because of time limitations of the workshop, but it shows something roughly similar to one of Brett Victor’s demos of editing and interacting with general purpose code.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">It is possible to select any subexpression in the code and evaluate it. In Smalltalk, it is customary to insert code snippets that illustrate how to use an API inside comments. This is possible here as well, but unlike Smalltalk, the snippets can make use of local variables and instance methods. It is also possible to step through code as in a debugger (in the interest of full disclosure, that bit is a tad flakey at the moment; this is very much a work in progress).</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">There are many things that need improvement, some of which you can see in the demo. Combining the debugger and method editor brings challenges. If you hit return, is that just a newline, or do you evaluate the code, and/or save it? In a classic REPL, you are not editing permanent code and so neither formatting nor saving are a concern, and each return evaluates the current line and moves to a new one. In contrast, in an editor, return is just formatting, and saving is a distinct operation. Our current approach is to keep all three operations distinct. However, it would be convenient to have keyboard shortcuts for evaluation and for evaluate and return. That would make the kind of interaction shown in the demo smoother. So would maintaining the selection across evaluations.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">There are also various nice features that aren’t illustrated in the demo due to lack of time. When an evaluation prints out its result the printout is a link to an object inspector on the result, where further evaluation can take place in the context of that object. This is a feature inherited from the existing Newspeak object inspectors.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">It is important to understand that you can do all this on any method of any class, whether you view it in a class browser, or in a list of senders or implementors etc. The goal of this effort is to completely eradicate any code view that does not support such live interaction. There are still some parts of the system where this has not yet been done, but a few more weekends and this will be addressed.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">If you get the latest <a href="http://www.mirandabanda.org/files/Cog/VM/VM.r2714/"><span class="s2">Newspeak VM</span></a> and the <a href="https://bitbucket.org/newspeaklanguage/newspeak/downloads/nsboot-2013-03-28.zip"><span class="s2">experimental image</span></a> you can play with the extension I’ve described, though you need to be comfortable with Newspeak. Otherwise, you will probably provoke some of the many bugs in the prototype.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">The goal is to get this into the production Newspeak IDE in the not too distant future. There is a good deal of work before we get there, and huge potential for improvement. Issues include efficiency (each method browser is potentially a thread) and the quality of the exemplar data displayed. There are interesting ways to improve the quality, including bidirectional linkage with unit tests and type annotations. There is probably scope for a masters of PhD thesis depending how far one wants to take it all.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">While it is a lot easier to do this sort of work in the Newspeak environment, the lessons learned pertain to other systems as well. </span></div>
<div class="p2">
<span class="s1"></span><br /></div>
Gilad Brachahttp://www.blogger.com/profile/17934280339206214042noreply@blogger.com8tag:blogger.com,1999:blog-2447174102813539049.post-39070419522823382922013-01-19T21:09:00.000-08:002013-01-20T07:46:13.276-08:00Inheriting Class
<br />
<div class="p1">
<span class="s1">I wanted to share a nice example of class hierarchy inheritance. Regular readers of this blog are no doubt familiar with the notion of virtual classes and class hierarchy inheritance. For those who aren’t, I’ll recap. Class hierarchy inheritance is exactly what it sounds like: the ability to inherit from an entire class hierarchy rather than a single class. </span></div>
<div class="p2">
<span class="s1"></span><br /></div>
<div class="p1">
<span class="s1">Nested classes, as originally conceived in Beta, were treated as dynamically bound properties of instances, just like methods. If you do that, overriding classes (aka virtual classes) is an automatic consequence of nested classes. If you miss this crucial point, you can easily end up with nested-classes design that has a great deal of complexity and almost no benefits (cf. Java).</span></div>
<div class="p2">
<span class="s1"></span><br /></div>
<div class="p1">
<span class="s1">The notion of class hierarchy inheritance has been around for many years, but has not yet caught on in the mainstream. It is supported in a few languages: Beta, gBeta, <a href="http://newspeaklanguage.org/" target="_blank">Newspeak</a> and several research projects.</span></div>
<div class="p2">
<span class="s1"></span><br /></div>
<div class="p1">
<span class="s1"><b><i>Tangent</i></b><i>: Apologies to any languages I’ve not explicitly mentioned. This is a blog, not a scientific paper, and exhaustive citations should not be expected.</i></span></div>
<div class="p2">
<span class="s1"><i></i></span><br /></div>
<div class="p1">
<span class="s1">The research on this topic has too often been focused on typechecking, under the rubric of family polymorphism. Fortunately, one can make excellent use of class hierarchy inheritance without worrying about complicated type systems.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1"><b><i>Note</i></b><i>: Virtual classes are distinct from virtual types.</i></span></div>
<div class="p2">
<span class="s1"></span><br /></div>
<div class="p1">
<span class="s1">To be honest, while class nesting has proven to be useful on a daily basis, class hierarchy inheritance occurs pretty rarely. The biggest advantage of late binding nested classes is not class hierarchy inheritance, but polymorphism over classes (acting as instance factories, ergo constructors), which promotes modularity. </span></div>
<div class="p2">
<span class="s1"></span><br /></div>
<div class="p1">
<span class="s1">Nevertheless, class hierarchy inheritance can be very useful at times. And since it comes for free, we might as well use it.</span></div>
<div class="p2">
<span class="s1"></span><br /></div>
<div class="p1">
<span class="s1">A classic example in the research literature is extending a class </span><span class="s2"><i>Graph</i></span><span class="s1"> that has nested classes like </span><span class="s2"><i>Node</i></span><span class="s1"> and </span><span class="s2"><i>Edge</i></span><span class="s1">. In Newspeak this would look roughly like this:</span></div>
<div class="p3">
<span class="s1"><i><b>class</b> Graph () (</i></span></div>
<div class="p3">
<span class="s1"><i> <b>class</b> Node ...</i></span></div>
<div class="p3">
<span class="s1"><i> <b>class</b> Edge ...</i></span></div>
<div class="p3">
<span class="s1"><i>)</i></span></div>
<div class="p2">
<br /><span class="s1"></span></div>
<div class="p1">
<span class="s1">One can introduce a new subclass of</span><span class="s2"> <i>Graph</i></span><span class="s1">, </span><span class="s2"><i>WeightedGraph</i></span><span class="s1">, modifying </span><span class="s2"><i>Edge</i></span><span class="s1"> to hold the weight etc.</span></div>
<div class="p2">
<span class="s1"></span><br /></div>
<div class="p3">
<span class="s1"><i><b>class</b> WeightedGraph = Graph ()(</i></span></div>
<div class="p3">
<span class="s1"><i> <b>class</b> Edge = <b>super</b> Edge ( | weight <number> ::= 0. | ) ()</number></i></span></div>
<div class="p3">
<span class="s1"><i>)</i></span></div>
<div class="p3">
<span class="s1"><i><br /></i></span></div>
<div class="p1">
<span class="s1">In </span><span class="s2"><i>WeightedGraph</i></span><span class="s1">, the class </span><span class="s2"><i>Edge</i></span><span class="s1"> inherits from the class </span><span class="s2"><i>Edge</i></span><span class="s1"> in the superclass </span><span class="s2"><i>Graph</i></span><span class="s1">. </span><span class="s2"><i>WeightedGraph</i></span><span class="s1">’s </span><span class="s2"><i>Edge</i></span><span class="s1"> adds a slot (aka field), </span><span class="s2">weight</span><span class="s1">, initially set to zero. Overriding of classes works just like overriding methods, so all the code that </span><span class="s2"><i>WeightedGraph</i></span><span class="s1"> inherited from </span><span class="s2"><i>Graph</i></span><span class="s1"> continues to work, except all uses of </span><span class="s2"><i>Edge</i></span><span class="s1"> refer to the weighted subclass.</span></div>
<div class="p2">
<span class="s1"></span><br /></div>
<div class="p1">
<span class="s1">In this post, I wanted to mention another nice example - one that arose in practice. Some former colleagues had implemented an external DSL on top of Newspeak, and naturally wanted to provide the nice IDE experience of Newspeak for their DSL as well. In particular, the debugger needed to support the DSL.</span></div>
<div class="p2">
<span class="s1"></span><br /></div>
<div class="p1">
<span class="s1">For the most part, the debugger is independent of the exact source language it is displaying. The system picks up the source code for each executing method and highlights the current call. However, difficulties arise because some methods created by the DSL implementation are synthetic. At run time, these methods have corresponding stack frames which should never be displayed. We need a small tweak to the debugger UI, so that these synthetic frames are filtered out.</span></div>
<div class="p2">
<span class="s1"></span><br /></div>
<div class="p1">
<span class="s1">The Newspeak debugger UI is implemented via a Newspeak module (a top level class) that contains classes responsible for the UI of the debugger, which in turn handles the UI of individual stack frames and of a stack as a whole. The debugger uses the Hopscotch UI framework; I’ll summarize salient characteristics here. Hopscotch applications consist of a <i>presenter</i> (the view of MVC), a <i>subject</i> of the presentation (roughly what some refer to as a ViewModel in MVVM) and <i>model</i> (a name everyone agrees on). And so, our UI includes a </span><span class="s2"><i>ThreadPresenter</i></span><span class="s1"> and a </span><span class="s2"><i>ThreadSubject</i></span><span class="s1"> (whose model is the underlying thread) and a number of </span><span class="s2"><i>ActivationPresenter</i></span><span class="s1">s and </span><span class="s2"><i>ActivationSubject</i></span><span class="s1">s (whose model is the context object representing an individual stackframe). The presenters and subjects listed above are all declared within the </span><span class="s2"><i>Debugger</i></span><span class="s1"> class, which is nested in the top-level class (aka module definition) </span><span class="s2"><i>Debugging</i></span><span class="s1">.</span></div>
<div class="p2">
<span class="s1"></span><br /></div>
<div class="p1">
<span class="s1">All we need then, is a slight change to </span><span class="s2"><i>ThreadSubject</i></span><span class="s1"> so it knows how to filter out the synthetic frames from the list of frames. One might be able to engineer this in a more conventional setting by subclassing </span><span class="s2"><i>ThreadSubject</i></span><span class="s1"> and relying on dependency injection to weave the new subclass into the existing framework - assuming we had the foresight and stamina to use a DI framework in the first place. We’d also need to rebuild our system with two copies of the debugger code, and in general be in for a world of pain.</span></div>
<div class="p2">
<span class="s1"></span><br /></div>
<div class="p1">
<span class="s1">Fortunately, the Newspeak IDE is written in Newspeak and not in a mainstream language, so these situations are handled easily. Dependencies that are external to a module are always explicit, and internal ones can always be overridden via inheritance.</span></div>
<div class="p2">
<span class="s1"></span><br /></div>
<div class="p1">
<span class="s1">So you subclass the </span><span class="s2"><i>Debugging</i></span><span class="s1"> module and override the </span><span class="s2"><i>ThreadSubject</i></span><span class="s1"> class so that it filters its list of activations.</span></div>
<div class="p4">
<span class="s1"></span><br /></div>
<div class="p3">
<span class="s1"><i><b>class</b> FilteredDebugging = Debugging () (</i></span></div>
<div class="p3">
<span class="s1"><i> <b>class</b> Debugger = <b>super</b> Debugger () (</i></span></div>
<div class="p3">
<span class="s1"><i><span class="Apple-tab-span"></span><b> class</b> ThreadSubject = <b>super</b> ThreadSubject () (</i></span></div>
<div class="p3">
<span class="s1"><i> ... code to filter activations ...</i></span></div>
<div class="p3">
<span class="s1"><i> )</i></span></div>
<div class="p3">
<span class="s1"><i> )</i></span></div>
<div class="p3">
<span class="s1"><i>)</i></span></div>
<div class="p2">
<span class="s1"></span><br /></div>
<div class="p1">
<span class="s1">You can define </span><span class="s2"><i>FilteredDebugging</i></span><span class="s1"> in the context of your complete DSL application. Or you could define it is a mixin, and just apply it to </span><span class="s2"><i>Debugging</i> </span><span class="s1">in the context of the DSL application.</span></div>
<div class="p2">
<span class="s1"></span><br /></div>
<div class="p1">
<span class="s1">No DI frameworks, no copied code, no plugin architecture that nobody can understand, and no need to have foreseen this circumstance in advance. It really is quite simple.</span></div>
Gilad Brachahttp://www.blogger.com/profile/17934280339206214042noreply@blogger.com20tag:blogger.com,1999:blog-2447174102813539049.post-17395877294623595472012-11-17T07:25:00.000-08:002012-11-17T08:02:48.978-08:00Debug Mode is the Only Mode<br />
<div class="p1">
<span class="s1">There has been a fair amount of discussion recently surrounding some of Bret Victor’s <a href="http://www.youtube.com/watch?v=PUv66718DII" target="_blank">talks</a></span> and <a href="http://worrydream.com/LearnableProgramming/"><span class="s2">blog posts</span></a>. If you haven’t seen these, I recommend them highly - with a grain of salt.</div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">These pieces make important points related to programming and programming environments, and are beautifully done. </span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1"><i>They also relate to education and other matters which I will not discuss here</i>.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">Because of their exquisite presentation, they’ve elicited far more attention than others making similar points have garnered in the past. This is a good thing. However, beneath the elegant surface, troubling questions arise.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">The demos Victor shows are spoiled by the disappointing realization that we are not seeing a general purpose programming environment that can actually work these miracles for us. Instead, they are hand crafted illustrations of how such a tool might behave. It is a vision of such an environment - but it is not the environment itself. Relatively little is said about how one might go about creating such a thing for the general case - but there are some hints.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">We should take these ideas as inspiration and see what one might do in practice. I expect this is one of the things Victor intends to achieve with these presentations. </span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">Victor recognizes that many of his examples depend on graphical feedback and don’t necessarily apply to other kinds of programming. However, his use of traces and timelines is something we can use in general. In <a href="http://youtu.be/PUv66718DII?t=18m5s"><span class="s2">one segment</span></a>, the state during a loop gets unrolled automatically by the programming environment - morphing time into space so we can visualize the progress (or lack thereof) of the computation.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">This specific example might be handled in existing debuggers using a tail recursive formulation of loops - without tail recursion elimination! Then the ordinary view of the stack in a debugger could be used - though the trace based view may have advantages in terms of screen real estate, since we need not repeat the code. Those advantages will apply to any recursive routine, so adding an unfolded view of a recursive call (or a clique of such calls) is a small concrete step one might want to investigate.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">Traces that show all the relevant data are intrinsically connected to time traveling debugging, because we want more than selective printouts - we want to be able to explore the data at any point in the trace, following the object graph that existed at the traced point where ever it may lead us.</span></div>
<div class="p2">
<span class="s1"></span><br /></div>
<div class="p1">
<span class="s1">I firmly believe that a time traveling debugger is worth more than a boatload of language features (especially since most such boatloads have negative value anyway). </span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1"><i>When I first saw Bil Lewis’ </i><span class="s2"><i><a href="http://www.lambdacs.com/debugger/">Omniscient Debugger</a></i></span><i>, I tried to convince my management to invest in this area. Needless to say, I got nowhere. </i> </span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">The overall view is that a program is a model of some real or imagined world that is dynamic and evolving. We should be able to experiment on that model and observe and interact with any part of it. One should be able to query the model’s entire history, searching for events and situations that occurred in the past - and then travel back to the time they occurred - or to a time prior to the occurrence, so we can preempt the event and change history at will.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">The query technology enabled by a back-in-time debugger could also help make the graphical demos a reality. You ask where in my code did I indirectly call the invocation that wrote a given pixel. It’s a complex query, but fundamentally similar to asking when did a variable acquire a given value.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">There is a modest amount of work in this area, some of it academic, some commercial (forgive me for not citing it all here), but it hasn’t really taken off. It is challenging, because programs generate enormous amounts of transient data, and recording it all is expensive. This gives a new interpretation to the phrase <i>Big Data</i>. Data is however central to much of what we do, and data about programs should not be the exception. </span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">A related theme is correlating data with code by associating actual values with program variables. One simple example of the advantage of having values associated with variables is that we can do name completion without recourse to static type information. We get the connection between variables and their values in tools like workspaces, REPLs, object inspectors and (again!) debuggers, but not when viewing program text in ordinary editors or even in class browsers. </span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">In Newspeak and Smalltalk, developers sometimes build up a program from an initial sketch using the debugger, precisely because while debugging they can see live data and design their code with that concrete information in mind. You’ll find an example of this sort of thing starting around 19:10 in Victor’s talk, where an error is detected as the code is being written based on runtime values.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">The <a href="http://www.smalltalk.org.br/movies/Self_big.mov"><span class="s2">Self environment</span></a> shows one way of achieving this integration of live data with code. Prototype based languages have a bit of an advantage here because code is tied to actual objects - but once we are dealing with methods that take parameters we are back to dealing with abstractions just like class or function based languages. </span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1"><i>You might even be tempted to say that Javascript, being a prototype based language, is a modern incarnation of Self. Please don’t drink and drive; at best this is a </i><a href="http://gaslight.mtroyal.ca/mnkyspaw.htm"><span class="s2"><i>cautionary tale</i></span></a><i> on the theme “be careful what you wish for”.</i></span></div>
<div class="p1">
<span class="s1"><i><br /></i></span></div>
<div class="p1">
<span class="s1">We need a process that makes it easier to go from initial sketches to stable production code. We’d like start from workspaces and being able to smoothly migrate to classes and unit tests. This is in line with the philosophy expressed in <a href="http://people.cs.aau.dk/~normark/asl2/paper.pdf"><span class="s2">this paper</span></a> for example.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">It seems to me that the various tools such as editors, class browsers, object inspectors, workspaces, REPLs and debuggers create distinct modes of operation. It would be great if these modes could be eliminated by integrating the tools more tightly. There would always be a live instance of your scope associated with any code you are editing, with the ability to evaluate incrementally as you edit the code (as in a REPL) and step backwards and forwards as in a time traveling debugger. The exact form of such a tool remains an unmet UI design challenge.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">All of the above holds regardless if whether you are doing object-oriented or functional programming (a false dichotomy by the way) or logic programming for that matter.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<i><b>Tangent</b>: I'm aware that the notion of debugging in lazy functional languages is problematic. But the need for live data and interactive feedback remains. And once a interactive computation occurred, the timing has been fully determined. So while stepping forward may be meaningless, going back in time isn't.</i></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">We should stop thinking of programs as just code. The static view of code, divorced from its dynamic extent, has been massively overemphasized in the PL community. This needs to change, and it will.</span></div>
<div class="p2">
<span class="s1"></span><br /></div>
Gilad Brachahttp://www.blogger.com/profile/17934280339206214042noreply@blogger.com28tag:blogger.com,1999:blog-2447174102813539049.post-88529812972411596962012-08-23T09:08:00.000-07:002012-08-23T13:25:34.294-07:00Newspeak on Dart<span style="background-color: white; color: #222222; font-family: Georgia, Times New Roman, serif;">We've wanted to run Newspeak to run in a web browser for a long time - actually, since before the Newspeak project started. The need for better programming languages for the internet platform has been evident for a while. In a better world, the Newspeak project would be focused on that from day 1. </span><br />
<div style="background-color: white; border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;">
<span style="font-family: Georgia, Times New Roman, serif;"><br /></span></div>
<div style="background-color: white; border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;">
<span style="font-family: Georgia, Times New Roman, serif;">However, this world is suboptimal. It was only in 2010 that I spent some time sketching out the first version of NS2JS, the Newspeak-to-Javascript compiler. It was a toy, but in 2011, Vassili Bykov managed to bring it to the verge of self hosting. Performance, however, was abysmal. Having since joined the Dart project and learned more and more about the challenges Javascript poses as a compilation target (or anything else) I guess this really should not have been a surprise.</span></div>
<div style="background-color: white; border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;">
<span style="font-family: Georgia, Times New Roman, serif;"><br /></span></div>
<div style="background-color: white; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;">
<span style="color: #222222; font-family: Georgia, Times New Roman, serif;">We were able to reuse a part of that effort this summer when Ryan Macnak came to Google in Mountain View as an intern with the Dart team. His mission: NS2Dart, a Newspeak to Dart compiler. A detailed report is available at</span></div>
<div style="background-color: white; border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;">
<span style="font-family: Georgia, Times New Roman, serif;"><br style="color: black; line-height: 18px;" /></span>
<a href="https://docs.google.com/document/d/1pU_nautpK49pJzwZkJM1NhACcad0Hjq0rjIomLSWQ1Y/edit" style="border: 0px; color: #3366cc; cursor: pointer; line-height: 18px; margin: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="font-family: Georgia, Times New Roman, serif;">https://docs.google.com/<wbr></wbr>document/d/1pU_<wbr></wbr>nautpK49pJzwZkJM1NhACcad0Hjq0r<wbr></wbr>jIomLSWQ1Y/edit</span></a></div>
<div>
<span style="font-family: Georgia, Times New Roman, serif;"><br /></span></div>
<div style="background-color: white; border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;">
<span style="font-family: Georgia, Times New Roman, serif;">The results are promising, though there is still a long way to go. Despite considerable losses due to impedance mismatches, on the Dart VM, NS2JS comes within a factor of 2 of the Squeak based Newspeak implementation (NS2Squeak). Given that the current version of NS2Squeak is twice the speed it used to be (thanks to <a href="http://www.mirandabanda.org/cogblog/about-cog/">Cog</a>) it looks like performance is tolerable already. And since Dart will get much faster (the numbers in the tech report are already out of date), the future looks bright.</span></div>
<div style="background-color: white; border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;">
<span style="font-family: Georgia, Times New Roman, serif;"><br /></span></div>
<div style="background-color: white; border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;">
<span style="font-family: Georgia, Times New Roman, serif;">Now, when someone says the future looks bright, you should be getting nervous. So, just sign the dotted line, and then I'll get to the caveats ...</span></div>
<div style="background-color: white; border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;">
<span style="font-family: Georgia, Times New Roman, serif;"><br /></span></div>
<div style="background-color: white; border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;">
<span style="font-family: Georgia, Times New Roman, serif;">The current version relies on access to Dart VM's embedding API, which means you cannot run it in the browser. Hopefully, over time enough functionality will get added in the way of mixins and mirror builders that the same results can be accomplished in pure Dart. That is not yet certain, but let's retain the uncharacteristically optimistic tone of this post, and assume that does happen.</span></div>
<div style="background-color: white; border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;">
<span style="font-family: Georgia, Times New Roman, serif;"><br /></span></div>
<div style="background-color: white; border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;">
<span style="font-family: Georgia, Times New Roman, serif;">Since most browsers are likely to run Dart via translation to Javascript for some time, we need to look at the NS-Dart-JS pipeline: compiling Newspeak via NS2Dart, and feeding the result to dart2js (The Dart to Javascript compiler) to obtain Javascript code that runs in any browser.</span></div>
<div style="background-color: white; border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;">
<span style="font-family: Georgia, Times New Roman, serif;"><br /></span></div>
<div style="background-color: white; border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;">
<span style="font-family: Georgia, Times New Roman, serif;">Early on, NS2Dart could run on top of dart2js (by cheating on things like dynamic mixin application) and results were much better than with NS2JS. This is to be expected: dart2js does the heavy lifting for us. The dart2js compiler already has 4-5 times as much code as NS2JS and is being developed by a very skilled team who understand JS performance inside and out. Furthermore, it has taken a while to get to this point and performance work is by no means done yet. So I don't feel too bad about our efforts on NS2JS.</span></div>
<div style="background-color: white; border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;">
<span style="font-family: Georgia, Times New Roman, serif;"><br /></span></div>
<div style="background-color: white; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;">
<span style="color: #222222; font-family: Georgia, Times New Roman, serif;">Nevertheless, there is a lot of uncertainty over how well Newspeak can run on top of current Javascript implementations. A key problem area are non-local returns (NLRs). These are essential for user defined control constructs. They are not supported in Dart precisely because it is not clear how efficiently they can be implemented on top of Javascript.</span></div>
<div style="background-color: white; border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;">
<span style="font-family: Georgia, Times New Roman, serif;"><br /></span></div>
<div style="background-color: white; border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;">
<span style="font-family: Georgia, Times New Roman, serif;">Mirror support on NS2Dart is very partial - the mapping to Dart's mirrors is pretty clean so far, but Dart mirrors are a work in progress, and so far only cover introspection. </span></div>
<div style="background-color: white; border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;">
<span style="font-family: Georgia, Times New Roman, serif;"><br /></span></div>
<div style="background-color: white; border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;">
<span style="font-family: Georgia, Times New Roman, serif;">Then there remains the small matter of the UI. I'd love to see the Hopscotch GUI on the browser, but that is a ton of work as well. We'll see what UI solutions shape up in that space - we can always just call out to whatever UI Dart exposes (Ryan also implemented a Dart Alien API). So altogether, it might be a tad premature to declare victory, but we are making progress.</span></div>
<div style="background-color: white; border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;">
<span style="font-family: Georgia, Times New Roman, serif;"><br /></span></div>
<div style="background-color: white; border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;">
<span style="font-family: Georgia, Times New Roman, serif;">The dream remains to get a fully functioning system, Hopscotch, IDE and all that works well in the browser. However, I can imagine that many applications could get by with a lot less. </span></div>
<div style="background-color: white; border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;">
<span style="font-family: Georgia, Times New Roman, serif;"><br /></span></div>
<div style="background-color: white; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;">
<span style="font-family: Georgia, Times New Roman, serif;"><span style="color: #222222;">The details are in Ryan's report and the code is in the </span><a href="https://bitbucket.org/newspeaklanguage/" style="color: #222222;">Newspeak repo</a><span style="color: #222222;">, where you can also get the latest Newspeak images with which to view it (I recommend you do that rather than use the old release; a new release will be out very soon). </span></span><span style="background-color: white; color: #222222; font-family: Georgia, 'Times New Roman', serif;">Thanks are due to Vassili (whose work on NS2JS made this possible) and to my colleagues on the Dart team, who graciously supported this effort in various ways, and most of all to Ryan.</span><br />
<span style="font-family: Georgia, Times New Roman, serif;"><span style="color: #222222;"><br /></span></span>
<span style="font-family: Georgia, Times New Roman, serif;"><span style="color: #222222;">Altogether, getting a top quality programming experience on the web requires a major effort. Dart is beginning to make this possible.</span></span></div>
<div style="background-color: white; border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;">
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div style="background-color: white; border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;">
<br /></div>
Gilad Brachahttp://www.blogger.com/profile/17934280339206214042noreply@blogger.com22tag:blogger.com,1999:blog-2447174102813539049.post-27735734700323521742012-07-23T22:17:00.001-07:002012-07-25T20:55:13.424-07:00Seeking Closure in the Mirror<br />
<div class="p1">
<span class="s1">I've discussed mirror based reflection many times in the past, in this <i><a href="http://gbracha.blogspot.com/2010/03/through-looking-glass-darkly.html">blog</a> </i>and in </span><i style="background-color: white;"><a href="http://www.hpi.uni-potsdam.de/hirschfeld/events/past/media/100105_Bracha_2010_LinguisticReflectionViaMirrors_HPI.mp4">talks</a>. </i><span style="background-color: white;">And of course I'm not the only one - you can read Alan Wirf-Brock's </span><span style="background-color: white;"><a href="http://www.wirfs-brock.com/allen/posts/228">posts</a> on mirrors in Javascript. In this post, I want to focus on a particular kind of mirror that has not received much attention. Before I get to deep into the details, a few words of background.</span></div>
<div class="p1">
<span class="s1"></span></div>
<div>
<br /></div>
<br />
<div class="p1">
<span class="s1">You cannot get at the internals of a function: you can only apply it to various arguments and see how it responds. This is sometimes known as <i>procedural abstraction</i>. Among other things, it is the basis for object-based encapsulation.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">Most languages that call themselves object-oriented do not actually support object-based encapsulation. One of the ways they get by despite this defect is to rely on procedural abstraction directly. Perhaps the most notable example of this is Javascript. The only way to encapsulate anything in Javascript is to put it inside a function. Elaborate design patterns leverage Javascript’s closures to provide encapsulation.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">You can see from the above that procedural abstraction is absolutely fundamental. There appear to be circumstances where we might nevertheless might wish to breach the defenses of procedural abstraction. </span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">Consider implementing a database interface in the style of LINQ, or Ruby on Rails, or <a href="http://www.glorp.org/"><span class="s2">Glorp</span></a>. The underlying model is that the database consists of collections, and that these collections are accessed via standard functional operations such filter, map, reduce etc. The arguments to these operations include closures. For example, you might write a query such as:</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p2">
<span class="s1"></span></div>
<div class="p1">
<span class="s1"><span style="font-family: 'Courier New', Courier, monospace;">cities.filter(function(city){return city.name = ‘Paris’;});</span></span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">and get back a collection of answers that included Paris, Texas, and perhaps some other cities. To implement this interface on top of a database, you might want to transform this code into a SQL query. To do that you need to understand what the closure is doing. In .Net, for example, the type system is designed to coerce a literal closure into an abstract syntax tree representing the expression inside it, which can then be compiled into SQL. </span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">Of course, it might be that you cannot reasonably compile the code into a SQL query at all. We will assume that the system is allowed to fail in any case it deems too hard, but we’d like to cope with as many situations as we can.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">The LINQ approach relies on static typing, but this is not essential, and in fact has drawbacks.</span></div>
<div class="p1">
<span class="s1">For example, the static approach precludes the following:</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1"><span style="font-family: 'Courier New', Courier, monospace;">query(f) {return cities.filter(f);}</span></span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">A more general alternative is to dynamically derive the AST of the closure body. Regardless, it seems I need a way to get the AST (or at least the source) of a closure - something that procedural abstraction is of course designed to preclude.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">Even if I can get the source or AST, that isn’t always enough. Suppose I want to write</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1"><span style="font-family: 'Courier New', Courier, monospace;">var cityNames = [‘Paris’, ‘London’, ‘New York’];</span></span></div>
<div class="p1">
<span class="s1"><span style="font-family: 'Courier New', Courier, monospace;">cities.filter(function(city){</span></span></div>
<div class="p1">
<span class="s1"><span style="font-family: 'Courier New', Courier, monospace;"> return cityNames.contains(city.name)</span></span></div>
<div class="p1">
<span class="s1"><span style="font-family: 'Courier New', Courier, monospace;">});</span></span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">I need the value of <span style="font-family: 'Courier New', Courier, monospace;">cityNames</span> in order to execute the query. In general, I need to get at the scope of the executing closure. </span></div>
<div class="p1">
<br /></div>
<div class="p1">
<span class="s1">Smalltalk and its relatives allow you to do this. How do they get around procedural abstraction? Well, in the case of closures, they basically throw procedural abstraction out the door. Every Smalltalk closure will gladly provide you its context, which is a reified scope that will allow you to find out what all the variables used in the closure are.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">Obviously, this is not a very secure solution. </span><span style="background-color: white;">One way we can usually reconcile security and reflection is via mirrors, and that is the focus of this post. Given an object mirror that has full access to the closure object's representation, you should be able to get all the information you need. This still has the drawback that the representation of closures is exposed as a public API. </span></div>
<div class="p1">
<span style="background-color: white;"><br /></span></div>
<div class="p1">
In this case, we want a <span style="font-family: 'Courier New', Courier, monospace;">ClosureMirror</span>. Essentially, there needs to be an object with the magical ability to see into the closure, overcoming procedural abstraction. The closure itself must not allow this; it must be impenetrable. The capability to look inside it must be a distinct object that can be distributed or withheld independently <span style="background-color: white;">(exercise for the reader: find another way to solve this problem).</span></div>
<div class="p1">
<br /></div>
<div class="p1">
<span class="s1">Concretely, a <span style="font-family: 'Courier New', Courier, monospace;">ClosureMirror</span> needs to able to provide the source code of the closure it is reflecting and a map from identifiers to values that describes the closure’s current scope.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">Another situation where closure mirrors would be handy is serialization. If you need to serialize an object that includes a closure, you again need access to the closure’s scope.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">I have not seen closure mirrors discussed elsewhere. As far as I know, the only implementation was done as part of the Newspeak-to-Javascript compiler. </span><span style="background-color: white;">We are also considering it in the context of the Dart mirror system. </span><span style="background-color: white;"> The Newspeak-on-Javascript implementation of closure mirrors is rather naive and inefficient. One reason for this inefficiency is that Javascript provides no support whatsoever to do this sort of thing. In any case, the idea is new and virtually untested, but I think it has potential.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1"><br /></span></div>Gilad Brachahttp://www.blogger.com/profile/17934280339206214042noreply@blogger.com16tag:blogger.com,1999:blog-2447174102813539049.post-35945834316497933822012-06-17T09:41:00.000-07:002012-06-29T08:03:04.690-07:00Source Control Freak<br />
<div class="p1">
<span class="s1">Source control is an area of software development in need of reform. There is need for a clean, clear semantic model. To the extent that existing source control systems have some sort of model, each system is different. Each has its own terminology, usually entangled with the mechanics of file systems and directories. As with IDEs, the use of files and text has spread in this domain because it is a lowest common denominator. </span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1"><b>Semi-tangent:</b> <i>Well, almost a common denominator; it doesn’t cover Smalltalk, but this can be fairly viewed as Smalltalk’s fault, not source control’s.</i></span></div>
<div class="p1">
<span class="s1"><i><br /></i></span></div>
<div class="p1">
<span class="s1">As with IDEs, the tie to files is unfortunate because low level abstractions like text files and file systems are completely extraneous to the problem at hand. </span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">The major advantage of the text file based approach is that, rather than invent a source control system for every language, we can build one system that assumes source code consists of text files and go from there. A big disadvantage is that such a system has no understanding of the source code. It doesn’t understand the structure of a program - be it functions or classes or prototypes or procedures or what-have-you.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">The mainstream approach also has another advantage: it can integrate artifacts from multiple languages. And another: we can go even lower than text files, and just consider files, so we can manage binaries and resources as well. In general, while we would like programming language-specific understanding, we also want to deal with multiple languages, and with artifacts that go beyond source code.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">Again, we return to the lack of a semantic model: not just for understanding the sources, but for the language-independent part of the system. What are versions, what are differences, what are repositories exactly? The answers differ from system to system, and are hard to disentangle from the mechanics of files and directories.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">People have addressed parts of the problem, but I don’t know of a completely satisfactory solution. For example DARCS has a model of differences that is rather interesting. However, it doesn’t tackle other issues, and the experience of the Haskell community using it has been mixed at best.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">In the Smalltalk world, Monticello (and more recently, Metacello) provide a language aware source code management (SCM) system. I’ve explained some of the problems with that approach above. We tried to mitigate these somewhat in the Hopscotch IDE, where we mated Monticello with svn and a new GUI. The idea was to use a mainstream standard tool with a language specific front end. No need to reinvent the entire wheel, only select parts. That too has been a mixed experience.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">On the one hand, we’ve enjoyed a nice GUI. For example, the changes presenter displays semantically meaningful diffs - the system tells us what classes have changed, and what methods within them, resorting to textual diffing only within methods. The diff is displayed side-by-side in the traditional manner; the key difference is that we get individual diffs for each unit of program structure. For example, if you’ve changed two methods in a class with 30 methods, you’ll only see the diffs for those two methods.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">In the screenshot, we can see that the <b>startup:</b> method in the class <b>ObjectiveCAlien</b> is the only thing that has changed.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p2">
<span class="s1"></span></div>
<div class="p2">
<span class="s1"></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-HenqE1-WI4k/T94FNfYIeII/AAAAAAAABOE/ma0HdsyOIfs/s1600/old-src-ctl.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="449" src="http://1.bp.blogspot.com/-HenqE1-WI4k/T94FNfYIeII/AAAAAAAABOE/ma0HdsyOIfs/s640/old-src-ctl.png" width="640" /></a></div>
<div class="p2">
<span class="s1"></span></div>
<div class="p2">
<span class="s1"></span></div>
<div class="p2">
<span class="s1"></span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">On the other hand, the cost and effort of rolling one’s own VCS tool is considerable even when it is done on top of a standard VCS that does the heavy lifting. Because of this, we have not yet been able to realize all of the advantages we could from such a system. We could potentially show you time-machine like views of individual classes or methods, since concepts like versions and history apply to these entities. </span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">The system shown above is based on svn, and svn doesn’t support distributed development well; this became an acute problem when the project went open source.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">So - do we need to build variants of such a system for other SCMs? Given N languages and M SCMs, you get N x M systems. Unattractive. One can see why people have stuck with the standard tools.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">If we had a uniform abstraction of an SCM then we could implement the abstraction once on top of every real SCM we wanted to use. We could then implement language specific functionality on top of the abstract model. Now you get N+M pieces you need to build. </span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">This is what Matthias Kleine set out to do in his <a href="http://www.hpi.uni-potsdam.de/hirschfeld/publications/media/KleineHirschfeldBracha_2012_AnAbstractionForVersionControlSystems_HPI54.pdf">masters thesis</a>. The result is Pur, which defines a model that is general enough to describe several of the leading SCMs (mercurial, git, svn). MemoryHole, a Newspeak specific version control tool, has been built on top of Pur using a binding to mercurial. Since August 2011, we’ve been using MemoryHole instead of the svn-based tools. One nice thing is that MemoryHole can work with git as well, and potentially even with old-fashioned svn. Here’s a screenshot of MemoryHole in action:</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p2">
<span class="s1"></span></div>
<div class="p2">
<span class="s1"></span></div>
<div class="p2">
<span class="s1"></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-KMT8rSFYnU0/T94E-GySxdI/AAAAAAAABN8/9Tt9wFyDYqQ/s1600/memoryHole-diff1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-KMT8rSFYnU0/T94E-GySxdI/AAAAAAAABN8/9Tt9wFyDYqQ/s1600/memoryHole-diff1.png" /></a></div>
<div class="p2">
<span class="s1"></span></div>
<div class="p2">
<span class="s1"></span></div>
<div class="p2">
<span class="s1"></span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">We see two columns listing top level classes that differ between the running system and a repository. Each class is presented as a tree view of parts that differ. At the level of individual methods, we revert to a text diff. The <b>configDo:</b> method of class <i>VCSMercurialBackedProvider`Backend`LocalRepository`Commands`NonCachingCommand</i> is expanded to show what’s changed (a flush was added, highlighted in red). </span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1"><b>Tangent:</b> <i>We see 4 levels of class nesting here, which is as deep as I’ve seen in any Newspeak program.</i></span></div>
<div class="p1">
<span class="s1"><i><br /></i></span></div>
<div class="p1">
<span class="s1">MemoryHole gives us a distributed source control GUI application that is language-aware, but can work with <i>differing</i> standard SCMs. And of course, it is written in Newspeak so it is modular and extensible.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">Keeping a language specific VCS running in sync with an evolving language was a problem in the early days of Newspeak. This is again part of the price one pays for dedicated language support. When the language is stable I think it is well worth the cost, just like any other language-aware tooling, be it an Eclipse plugin, an emacs mode, or something better.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">Indeed, the situation is analogous to what happens with text editors versus IDEs. The text editor is a lowest common denominator: the same tool can handle any programming language, and many other things as well. The IDE needs to be tuned extensively to each and every language, but in the end can give you a better experience. It took a long time for people to appreciate IDEs with their language specific support for editing, and to this day not everyone does. I imagine we’ll see a similar evolution in the area of source control.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">Most intriguing to me is the connection to the general problem of synchronizing data, including programs (being a special case of data), across the network. In the past, I’ve discussed the idea of <a href="http://www.youtube.com/watch?v=_cBGtvjaLM0"><span class="s2">objects as software services</span></a> and <a href="http://gbracha.blogspot.com/2010/04/brave-new-world-of-full-service.html"><span class="s2">full-service computing</span></a>. I see source control as just a special case of that. Something to discuss another time.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">The story doesn’t ned here of course. There is a need for mathematical models and theory, and bindings of many languages to many SCMs. In general, more researchers should look at source control; no doubt they will have their own ideas. I hope we move the world a little bit forward, beyond files and text diffs.</span></div>
<div class="p2">
<span class="s1"></span></div>Gilad Brachahttp://www.blogger.com/profile/17934280339206214042noreply@blogger.com18tag:blogger.com,1999:blog-2447174102813539049.post-54322389083769187142011-06-05T04:33:00.000-07:002012-06-29T08:11:29.976-07:00Types are Anti-ModularLast week I attended a workshop on language design. I made the off-the-cuff remark that types are actually anti-modular, and that comment resonated enough that I decided to tweet it. This prompted some questions, tweets being a less than perfect format for elaborate explanation of ideas (tweets are anti-communicative?). And so, I decided to expand on this in a blog post.<br /><br />Saying that types are anti-modular doesn’t mean that types are bad (though it certainly isn’t a good thing). Types have pros and cons, and this is one of the cons. Anyway, I should explain what I mean and how I justify it.<br /><br />The specific point I was discussing when I made this comment was the distinction between <span style="font-style:italic;">separate compilation</span> and <span style="font-style:italic;">independent compilation</span>. Separate compilation allows you to compile parts of a program separately from other parts. I would say it was a necessary, but not sufficient, requirement for modularity. <br /><br />In a typed language, you will find that the compiler needs some information about the types your compilation unit is using. Typically, some of these types originate outside the compilation unit. Even if your program is just: <span style="font-weight:bold;">print(“Hello World”)</span>, one may need to know that string literals have a type <span style="font-weight:bold;">String</span>, and that the argument type of <span style="font-weight:bold;">print</span> is <span style="font-weight:bold;">String</span>. The definition of <span style="font-weight:bold;">String</span> comes from outside the compilation unit. This is a trivial example, because it is common for <span style="font-weight:bold;">String</span> to be part of the language definition. However, substantial programs will tend to involve user-defined types at the boundaries of compilation units (or of module declarations,which may or may not be the same thing).<br /><br />A consequence of the above is that you need some extra information to actually compile. This could come in the form of interface/signature declaration(s) for any type(s) not defined within your compilation unit/module, or as binary file(s) representing the compiled representation of the code where the type(s) originated. Java class files are an example of the latter. <br /><br />Whatever the form of the aforementioned type information, you depend on it to compile your code - you cannot compile without it. In some languages, this introduces ordering dependencies among compilation units. For example, if you have a Java package <span style="font-weight:bold;">P1</span> that depends on another package <span style="font-weight:bold;">P2</span>, you cannot compile <span style="font-weight:bold;">P1</span> before compiling <span style="font-weight:bold;">P2</span>. You either compile them simultaneously (giving up on even separate compilation) or you must compile <span style="font-weight:bold;">P2</span> first so you have class files for it around. The situation is better if the language supports separate signature declarations (like Modula-3 or ML) - but you still have to have these around before you compile. <br /><br /><span style="font-style:italic;">Semi-tangent: Of course, you can fake signature declarations by dummy package declarations. Java chose to avoid the conceptual overhead of separate signature declarations, on the assumption that pragmatically, one could get by without them.</span><br /><br />Contrast this with independent compilation, where you compile your module/compilation-unit independently of anything else. The code that describes the values (and types) that your module requires may not even exist yet. Obviously, independent compilation is more modular than separate compilation. How do you achieve this in the presence of types? The short answer is you don’t. <br /><br />Wait: we are blessed, and live in a world where the gods have bestowed upon us such gifts as type inference. What if I don’t have to write my types at all, and have the compiler just figure out what types I need? The problem is that inference only works well within a module (if that). If you rely on inference at module boundaries, your module leaks implementation information. Why? Because if you infer types from your implementation, those types may vary when you modify your implementation. That is why, even in ML, signatures are declared explicitly.<br /><br />Wait, wait: Surely optional types avoid this problem? Not exactly. With an optional type system you can compile independently - but you cannot typecheck independently. Indeed, this is the point: there is no such thing as modular typechecking. If you want typechecking across modules, you need to use some of the same types in across modules. You can either replicate the types or place them in some specific module(s). The former clearly isn’t very modular. The latter makes some modules dependent on declarations defined elsewhere which means they cannot be typechecked independently. In the common case where types are mandatory, modules can not be compiled independently.<br /><br />Now, there is an argument to be made that modules have dependencies regardless, and that we cannot reason about them without being aware of these dependencies. Ergo, the types do not make change things fundamentally. All true. Even in dynamic language we have some notion of type or signature in our head. Formalizing that notion can be helpful in some ways, but it has downsides. One such downside is that formalizing the types reduces our ability to manage things in a perfectly modular way. You cannot typecheck modules in isolation (except in trivial cases) because types capture cross-module knowledge.<br /><br />One often hears the claim that types are in fact valuable (or even essential) to modularity because they can describe the interface(s) between modules. There lies the problem: the type cannot serve this purpose unless it is available in more than one module. Types are inherently non-local - they describe data that flows <span style="font-style:italic;">across<span style="font-weight:bold;"></span></span> module boundaries. The absence of types won’t buy you modularity on its own though. Far from it. But types and typechecking act as an inhibitor - a countervailing force to modularity.Gilad Brachahttp://www.blogger.com/profile/17934280339206214042noreply@blogger.com69tag:blogger.com,1999:blog-2447174102813539049.post-47447691209229882712011-03-20T10:05:00.000-07:002012-06-29T08:03:30.792-07:00The Truthiness Is Out ThereFor the past 5 years or so, I (like many others) have argued that Javascript is the assembly language of the internet platform. Over this period, some of the obstacles that limit the applicability of said platform have been slowly pushed aside. Things like client side storage, or decent performance.<br /><br />However, Javascript remains a seriously limited language for platform implementation. Here are some of the problems.<br /><br />Concurrency primitives. There aren’t any. Now I really should be thankful for that, as the last thing I want is another shared-state concurrency threading model a la Java. And yet, ingrate that I am, I remain dissatisfied. Yes, I can write my own scheduler to provide pseudo-concurrency, but there are no primitives that let me find out how much true concurrency is available and to let me use it. Nor is there any efficient way for me to preempt an activity. <br /><br />This lack of appropriate primitives for platform construction is a recurring theme. Take serialization for example. If I need to write a serializer that can incrementally store and retrieve arbitrary objects (say, because I want to implement orthogonal persistence) , I hit difficulties with things like closures. A closure in Javascript is a black box. This makes sense most of the time - but not for the system designer. One wants mechanisms that permit manipulation of the structure of all program elements - closures, prototypes, what have you. <br /><br />Of course, the challenge is to do this while preserving security. Not everyone should be able to do this - but a program should be able to do it on its own objects, for example.<br /><br />Another, somewhat related, problem area is stack manipulation. I want to implement an efficient debugger with fix-and-continue debugging for example. Or resumable exceptions. <br /><br />Weak pointers are another problem. For example, Newspeak mixins need to track all their invocations, so that when a mixin definition is modified, all classes derived from can be updated. You’d like to use a weak collection of these mixin invocations for that purpose.<br /><br />I’ve never been happy with the approach that says that the only true encapsulation mechanism in the language is closures. I find that very low level. I want objects that can hide their internals directly (private members) - and of course, I want a mechanism to get around that in some ways, so I can program the system in itself (and write things like serialization).<br /><br />I miss <span style="font-weight:bold;">doesNotUnderstand:<span style="font-style:italic;"></span></span>, which I can emulate by going through certain hoops. There is work going on to alleviate this with proxys but I don’t see them doing what I really want. I can however, use them to implement a mechanism that does.<br /><br />All of this may be too much to ask of a language where false can sometimes be interpreted as true, and where equality is non-transitive. But it isn’t too much to ask for the backbone of internet programming. <br /><br /><span style="font-style:italic;"><span style="font-weight:bold;">Tangent:</span> the occasional truthiness of false is a case study in the pitfalls of language design. It stems from the interaction of two bad decisions. First, we have the implicit coercion of any type to a boolean - a nasty C legacy. Then we have primitive types, which leads to (non-transparent) autoboxing. Since any object is truthy, and autoboxing false creates an object, you can end up with an automatic, hidden conversion that interprets false as true.</span><br /><br />I know that there is a lot of ongoing work to resolve this on the ECMAScript standards committee, whose members seem well aware of many of these issues. The timeline for addressing these problems is however, rather depressing. Between the time it takes to revise a standard, and the time it takes for it to be implemented and widely adopted (so you can actually rely on it) we may see these things fixed by the early 2020s (I kid you not).<br /><br />Will that make Javascript a language a human should program in? I doubt it, but that shouldn’t be the goal. The goal should be to provide a foundation that will help in building more attractive languages on top of Javascript and the browser.<br /><br />In this vein, work continues on Newspeak for the browser. We have a pretty solid Newspeak-to-Javascript compiler, though we still need to improve performance and add key platform functionality. At some point, I hope we can release this.<br /><br />The vision for the Ministry of Truthiness goes beyond just a compiler of course - we want Hopscotch as well of course. Calling the DOM API from Newspeak is possible of course, but not really attractive. We also want the IDE in the browser as well. At least as much of it as possible - debugging might require using a browser extension or something due to the difficulties cited above.<br /><br />Doing all this on top of Javascript has proven tedious and frustrating, and I hope things improve more quickly in the future; but we will get there in time.Gilad Brachahttp://www.blogger.com/profile/17934280339206214042noreply@blogger.com19tag:blogger.com,1999:blog-2447174102813539049.post-13471459383343823602011-02-28T18:49:00.000-08:002012-06-29T08:05:46.434-07:00The Ministry of Nesting & TestingUnit testing was introduced to the OO world by Kent Beck, in his <a href="http://www.xprogramming.com/testfram.htm">seminal work on SUnit</a>, the Smalltalk unit testing framework. Other languages have introduced their own unit testing frameworks following SUnit’s lead.<br /><br /><span style="font-weight: bold; font-style: italic;">Tangent:</span><span style="font-style: italic;"> Unit testing was part of the overall introduction of extreme programming/agile development, which is just one of the major trends Smalltalk has brought to the world. Along with refactoring (which we all know can’t be done without static types, which is why it was invented in a dynamically typed language), IDEs, reflective OO APIs, GUI builders, pop-up menus and bitmapped GUIs in general. Smalltalk is the veritable Prometheus of OO, and its destiny seems not dissimilar.</span><br /><br />Newspeak started out with an adaptation of SUnit, NSUnit, which is what you’ll find in the public release. It has a rather nice Hopscotch based GUI integrated into the IDE, but we always felt we could improve upon it.<br /><br />Minitest is our revised unit testing framework, which we’ve been using since, oh, mid-2010 or so. Minitest takes the opportunity to rationalize the way we structure unit tests and takes advantage of Newspeak’s support for nesting to make things simpler and easier to use.<br /><br />Minitest was designed by Vassili Bykov, and the examples below are shamelessly lifted from the superb documentation Vassili wrote for the Minitest class.<br /><br />In Minitest, you define a <span style="font-style: italic;">testing module</span>, that is designed to test a particular interface (not a particular implementation). To run tests, one needs to feed the testing module with the particular implementation(s) that one wishes to test. A <span style="font-style: italic;">test configuration</span> module does just that. Newspeak naturally enforces this separation of interface and implementation.<br /><br />The testing module class’s factory typically takes three arguments: the Newspeak platform, the testing framework (a Minitest instance) and a factory for the object under test.<br /><br /><br /><pre><span style="font-weight: bold; font-style: italic;">class ListTesting usingPlatform: platform minitest: minitest listClass: listClass = (<br /></span> <span style="font-weight: bold; font-style: italic;">|</span> <span style="font-weight: bold; font-style: italic;"> <br /> private TestContext = minitest TestContext.</span> <span style="font-weight: bold; font-style: italic;"> <br /> private List = listClass.</span> <span style="font-weight: bold; font-style: italic;"><br />|<br />)(</span><br /><span style="font-weight: bold; font-style: italic;"> class ListTests = TestContext (</span> <span style="font-weight: bold; font-style: italic;"><br /> | list = List new. |</span> <span style="font-weight: bold; font-style: italic;"> <br /> ) (</span> <span style="font-weight: bold; font-style: italic;"> <br /> testAddition = (</span> <span style="font-weight: bold; font-style: italic;"> <br /> list add: 1.</span> <span style="font-weight: bold; font-style: italic;"> <br /> assert: (list includes: 1)</span> <span style="font-weight: bold; font-style: italic;"> <br /> )</span> <span style="font-weight: bold; font-style: italic;"> <br /> testRemoval = (</span> <span style="font-weight: bold; font-style: italic;"> <br /> list add: 1; remove: 1.</span> <span style="font-weight: bold; font-style: italic;"> <br /> deny: (list includes: 1)</span> <span style="font-weight: bold; font-style: italic;"> <br /> )</span> <span style="font-weight: bold; font-style: italic;"> <br /> ) : (</span> <span style="font-weight: bold; font-style: italic;">TEST_CONTEXT = ()</span> <span style="font-weight: bold; font-style: italic;">)</span> <span style="font-weight: bold; font-style: italic;"><br />)</span></pre><br /><br />The example shows a hypothetical (and rather simplistic) module definition for testing lists. I’m sure all readers of this blog are fluent in Newspeak, but just in case, the module definition has a factory method that takes the 3 parameters mentioned above: <span style="font-style: italic; font-weight: bold;">platform</span> (the Newspeak platform, from which all kinds of generally useful libraries might be obtained), <span style="font-style: italic; font-weight: bold;">minitest</span> (an instance of Minitest, naturally) and <span style="font-style: italic; font-weight: bold;">listClass</span>, a factory that will produce lists for us to test.<br /><br />Nested inside the testing module is a <span style="font-style: italic;">test context</span> (aka <span style="font-style: italic;">test fixture</span>) class <span style="font-style: italic; font-weight: bold;">ListTests</span>, inside of which you write your tests. Test methods are identified by the convention that their names begin with <span style="font-weight: bold;">test</span>. Each test will be executed in a test context; that is, for each test method being run, Minitest will instantiate a fresh <span style="font-weight: bold; font-style: italic;">ListTests</span> object. That is why <span style="font-style: italic; font-weight: bold;">ListTests</span> is called a test context - it provides a context for a single test.<br /><br />It is common to define test context classes like <span style="font-style: italic; font-weight: bold;">ListTests</span> as subclasses of the class <span style="font-weight: bold; font-style: italic;">TestContext</span> defined by the Minitest framework, but that is not essential. <span style="font-style: italic; font-weight: bold;">TestContext</span> provides useful methods like <span style="font-weight: bold; font-style: italic;">deny:</span>, so it is convenient to use it. However, what identifies <span style="font-style: italic; font-weight: bold;">ListTests</span> as a test context is the marker class method <span style="font-weight: bold; font-style: italic;">TEST_CONTEXT</span>.<br /><br />Minitest will do its work by examining the nested classes of the test module and seeing which are test contexts (that is, which have a class method named <span style="font-style: italic; font-weight: bold;">TEST_CONTEXT</span>). For each test context tc, Minitest will list all its test methods (the ones with names beginning with <span style="font-weight: bold;">test</span>) and for each of those, it will instantiate tc and call the selected method on it, gathering data on success or failure.<br /><br />Minitest does away with concepts like <span style="font-style: italic; font-weight: bold;">TestResource</span>. that are typically used to hold data for tests.<br /><br />In the simple case above, the data for the test gets created by the instance initializer of <span style="font-style: italic; font-weight: bold;">ListTests</span> . However, what if the data for the test needs to be shared among multiple tests (say, because it is expensive to create)?<br /><br />As an example, suppose we want to test a compiler, and setting up the compiler is relatively costly.<br /><br /><pre><span style="font-weight: bold; font-style: italic;">class CompilerTesting usingPlatform: platform<br /> minitest: minitest<br /> compilerClass: compilerClass = (</span> <span style="font-weight: bold; font-style: italic;"><br />| Compiler = compilerClass. |</span> <span style="font-weight: bold; font-style: italic;"> )<br />(</span><br /><span style="font-weight: bold; font-style: italic;"> class CompilerHolder = (</span> <span style="font-weight: bold; font-style: italic;"> <br /> | compiler = Compiler configuredInAParticularWay. |</span> <span style="font-weight: bold; font-style: italic;"> <br /> )(</span> <span style="font-weight: bold; font-style: italic;"><br /> class StatementsTests ( ...) (....): ( TEST_CONTEXT = ())</span> <span style="font-weight: bold; font-style: italic;"><br /> )<br />)</span></pre><br /><br />Minitest leverages Newspeak’s nested structure in these cases. A test context (<span style="font-weight: bold; font-style: italic;">StatementTests</span> above) does not have to be a direct nested class of the test module. Instead, we can nest it more deeply inside another nested class (<span style="font-weight: bold;"></span><span style="font-weight: bold; font-style: italic;">CompilerHolder</span>). That nested class will serve to hold any state that we want to share among multiple tests - in our case, an instance of the compiler, which it will create and store as part of its initialization.<br /><br />As you can see there is no need for a special <span style="font-style: italic; font-weight: bold;">setUp</span> method or a test resource class. Newspeak’s nesting structure and built-in instance initializers take care of all that. If the shared resource is just an object in memory, then it will also be disposed of via garbage collection after the test is run. Of course, some resources cannot be just garbage collected. In that case, one should define a method named <span style="font-weight: bold; font-style: italic;">cleanUp</span> in the test context class.<br /><br />As mentioned in the beginning of the post, we need a test configuration to run the tests, as the test module definition is always parametric with respect to any implementation that we would actually test.<br /><br />A test configuration module is defined by a top level class with the factory method<br /><br /><span style="font-weight: bold; font-style: italic;">packageTestsUsing: ideNamespace</span><br />The factory takes a namespace object that should provide access to the testing module declaration and to any concrete classes or objects we want to test. This arrangement is very similar to how we package applications from within the IDE.<br /><pre><span style="font-weight: bold; font-style: italic;"> </span><blockquote><span style="font-weight: bold; font-style: italic;">class ListTestingConfiguration packageTestsUsing: ideNamespace = (</span> <span style="font-weight: bold; font-style: italic;"><br />|</span> <span style="font-weight: bold; font-style: italic;"> <br />private ListTesting = ideNamespace ListTesting.</span><br /><span style="font-weight: bold; font-style: italic;">private Collections = ideNamespace Collections.</span> <span style="font-weight: bold; font-style: italic;"><br />|</span> <span style="font-weight: bold; font-style: italic;"> )( ‘required’</span><br /><span style="font-weight: bold; font-style: italic;"> testModulesUsingPlatform: platform minitest: minitest = (</span> <span style="font-weight: bold; font-style: italic;"> <br /> ^{</span> <span style="font-weight: bold; font-style: italic;">ListTesting usingPlatform: platform<br /> minitest: minitest<br /> listClass: (Collections usingPlatform: platform) LinkedList.</span> <span style="font-weight: bold; font-style: italic;"> <br /> }<br /> )</span><br /><span style="font-weight: bold; font-style: italic;">)</span></blockquote></pre><br />The method <span style="font-style: italic; font-weight: bold;">testModulesUsingPlatform:minitest:</span> must be provided by the configuration. It will be called by Minitest to produce a set of testing modules, each of which will be processed by the framework as outlined above (i.e., searched for test contexts to be run). In the example, only one test module is returned, but if we wanted to process multiple <span style="font-style: italic; font-weight: bold;">List</span> implementations (say <span style="font-weight: bold; font-style: italic;">ArrayList</span> as well as <span style="font-weight: bold; font-style: italic;">LinkedList</span>) we could write:<br /><br /><pre><span style="font-weight: bold; font-style: italic;"> </span><blockquote><span style="font-weight: bold; font-style: italic;">class ListTestingConfiguration packageTestsUsing: ideNamespace = (</span> <span style="font-weight: bold; font-style: italic;"><br />|</span> <span style="font-weight: bold; font-style: italic;"> <br />private ListTesting = ideNamespace ListTesting.</span><br /><span style="font-weight: bold; font-style: italic;">private Collections = ideNamespace Collections.</span> <span style="font-weight: bold; font-style: italic;"><br />|</span> <span style="font-weight: bold; font-style: italic;"> )( ‘required’</span><br /><span style="font-weight: bold; font-style: italic;"> testModulesUsingPlatform: platform minitest: minitest = (</span> <span style="font-weight: bold; font-style: italic;"><br /> | collections = Collections using: platform. | <br /> ^{</span> <span style="font-weight: bold; font-style: italic;">ListTesting usingPlatform: platform<br /> minitest: minitest<br /> listClass: collections LinkedList.</span> <span style="font-weight: bold; font-style: italic;"> <br /> ListTesting usingPlatform: platform<br /> minitest: minitest<br /> listClass: collections ArrayList.</span> <span style="font-weight: bold; font-style: italic;"> <br /> }<br /> )</span><br /><span style="font-weight: bold; font-style: italic;">)</span></blockquote></pre><br /><br />The IDE recognizes test configurations based on the name of the factory method - that is, a class with a class method <span style="font-style: italic; font-weight: bold;">packageTestsUsing:</span> is considered a test configuration, and the IDE will provide a <span style="font-weight: bold; color: rgb(51, 102, 255);">run tests</span> link in the (upper right hand corner) class browser in that case, as shown in the screenshot below (click on it to enlarge).<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-CPuX26CGxgI/TWxlAm_fn6I/AAAAAAAAAJ0/y0ia_B0Of_M/s1600/CollectionsTestConfiguration.png"><img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 400px; height: 223px;" src="http://4.bp.blogspot.com/-CPuX26CGxgI/TWxlAm_fn6I/AAAAAAAAAJ0/y0ia_B0Of_M/s400/CollectionsTestConfiguration.png" alt="" id="BLOGGER_PHOTO_ID_5578945099546468258" border="0" /></a><br /><br />Clicking on the link will call the <span style="font-style: italic; font-weight: bold;">packageTestsUsing:</span> method on the class with an argument representing the IDE’s namespace, and feed the results into Minitest.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-2F-lo81mT78/TWxja680fvI/AAAAAAAAAJs/WdVbxTIirlA/s1600/CollectionsTestResults.png"><img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 400px; height: 185px;" src="http://2.bp.blogspot.com/-2F-lo81mT78/TWxja680fvI/AAAAAAAAAJs/WdVbxTIirlA/s400/CollectionsTestResults.png" alt="" id="BLOGGER_PHOTO_ID_5578943352557305586" border="0" /></a><br /><br />This is all you need to know to use Minitest. Actually, it’s considerably more than what you need to know, as I’ve also explained how a bit about how the framework goes about its business.<br /><br />It is worth noting how Minitest cleanly breaks down the multiple roles an SUnit <span style="font-weight: bold; font-style: italic;">TestCase</span> has. The definition of a set of tests is done by a test context. The actual configuration is done a test configuration. And the actual command to run a specific test (the thing that should be called <span style="font-weight: bold; font-style: italic;">TestCase</span>) is not the user’s concern anymore - the test framework handles it but need not expose it. In SUnit these three roles are conjoined. Perhaps this is why I never really felt comfortable with SUnit.<br /><br />Likewise, no need to worry over test resources and special set up methods. The net result is a framework that is very easy to use and simple to understand.<br /><br />It’s intriguing to note that one could actually structure a Java unit testing framework this way; we rely on introspection, interfaces and nested (inner) classes. However, it is not natural to do so in Java. Nested classes in Java are usually (and often rightly) regarded a trap to be avoided. A design like Minitest is much more likely to crop up in a setting where nesting is idiomatic, like Newspeak. Language influences thought - or lack of thought, as the case may be.Gilad Brachahttp://www.blogger.com/profile/17934280339206214042noreply@blogger.com4tag:blogger.com,1999:blog-2447174102813539049.post-40468392872753971772011-01-23T14:31:00.000-08:002012-06-29T08:12:14.107-07:00Maybe Monads Might Not MatterThis post isn’t really about the Maybe Monad of course. It is more focused on the State Monad, but I have a weakness for alliteration.<br /><br />What do<br /><br />space suits<br />nuclear waste containers<br />romantic conquests<br />monsters<br />macros<br />containers<br />conversations<br /><br />have in common? They’ve all been used as metaphors for monads.<br /><br />Last time I looked, the <a href="http://www.haskell.org/haskellwiki/Monad_tutorials_timeline">Haskell wiki</a> listed 29 tutorials on the subject, and that is where all these allusions come from.<br /><br />Such a wealth of explanatory fauna demands its own (meta-)explanation. Maybe monads are so wildly popular that there is monadic gold rush to cash in on the monad education and training market. And yet, the long-awaited landmark tome, “Category Theory for Dummies in 21 days and 1001 nights” is nowhere to be found.<br /><br /><span style="font-style: italic;">Tangent: There is of course, <a href="http://www.cis.upenn.edu/%7Ebcpierce/">Benjamin Pierce</a>'s <a href="http://www.amazon.com/Category-Computer-Scientists-Foundations-Computing/dp/0262660717">delightfully slim book</a> on the topic which is as close to a gentle introduction as one can come.</span><br /><br />Could it just be that people just have a hard time understanding monads? If so, what are the prospects of mass adoption? Or making Just(something) out of Nothing am I?<br /><br />By now you realize that if monads were a stock, I’d be shorting it. I’m going to go get myself in a huge amount of trouble now, just as I did when I took a hideously pragmatic tack on continuations some years ago.<br /><br />The most important practical contribution of monads in programming is, I believe, the fact that they provide a mechanism to interface pure functional programming to the impure dysfunctional world.<br /><br />The thing is, you don’t really need them for that. Just use actors. Purely functional actors can interact with the stateful world, and this has been known since before Haskell was even conceived.<br /><br /><span style="font-style: italic;">Tangent: Before you crucify me for being so narrow minded, pray consider the mitigating circumstance that I have used the words "practical" and "pure functional programming" in the same sentence. There are many who regard that, rather than my disrespectful attitude toward monads, as grounds for my institutionalization.</span><br /><br /><br />Some kind soul will doubtless point out to me how you can view actors as monads or some such. Be that as it may, it is beside the point. You can invent, build and most importantly, use, actors without ever mentioning monads. <a href="http://knol.google.com/k/carl-hewitt-s-homepage-http-carlhewitt-info#">Carl Hewitt</a> and his students did that decades ago.<br /><br /><span style="font-style: italic;">Tangent: I have to say how amazing that is. Actors were first conceived by Hewitt in 1973(!), and <a href="http://mitpress.mit.edu/catalog/item/default.asp?ttype=2&tid=9756">Gul Agha's thesis</a> has been around for 25 years. I firmly believe actors are the best answer to our concurrency problems, but that is for another post. </span><br /><br />You can write an actor in a purely functional language, and have it send messages to file systems, databases or any other other stateful actor. Because the messages are sent asynchronously, you never see the answer in the same activation (aka <span style="font-style: italic;">turn</span>) of the actor, so the fact that these actors are stateful and may give different answers to the same question at different times does not stain your precious snow white referential transparency with its vulgar impurity. This is pretty much what you do with a monad as well - you bury the stateful filth in a well marked shallow grave and whistle past it.<br /><br />Of course, your troubles are by no means over. Actors or monads, the state is out there and you will have to reason about it somewhere. But better you reason about it in a well bounded shallow grave than in C.<br /><br />What is important to me is that the notion of actors is intuitive (a pesky property of Dijkstra’s hated anthropomorphisms, like self) for many people. Yes, there are many varieties of actors and I have my preferences - but I’ll take any one of them over a sheaf of categories.<br /><br />Speaking of those preferences, look at the <a href="http://erights.org/">E</a> programming language (I often point at <a href="http://research.google.com/pubs/author35958.html">Mark Miller</a>’s <a href="http://erights.org/talks/thesis/index.html">PhD thesis</a>) or on <a href="http://soft.vub.ac.be/amop/">AmbientTalk</a>. I would like to have something similar in Newspeak (and in its hypothetical functional subsets, <a href="http://gbracha.blogspot.com/2010/01/avarice-and-sloth.html">Avarice and Sloth</a>).<br /><br />Of course, there is much to be said for a programming culture that excludes anyone without at least the potential of a PhD. Indeed, if you can surround yourself with such people, you can do amazing things with just Java, C++ and Python (though they will still be more productive if they have the good taste to use something nicer). So perhaps the true value of monads lies in their exclusionary nature.<br /><br />Nevertheless, there is more work to be done than some small, celebrated priesthood can or will do all by itself. There is real value in functional programming in some contexts, and it needs to integrate with stateful programming. Actors provide a model that is much easier for most humans to relate to.Gilad Brachahttp://www.blogger.com/profile/17934280339206214042noreply@blogger.com49tag:blogger.com,1999:blog-2447174102813539049.post-61834081823084653262010-12-11T17:57:00.000-08:002012-06-29T08:12:14.111-07:00Reflecting on Functional ProgrammingIn this post, I wanted to make a case for reflection in the context of pure functional programming. I don’t know that pure functional languages should be different than other languages in this regard, but in practice they are: they generally do not have reflection support.<br /><br />To demonstrate the utility of reflection, I’m going to revisit one of my favorite examples, parser combinators. In particular, we’ll consider how to implement executable grammars. Executable grammars are a special flavor of a parser combinator library that allows semantic actions to be completely separated from the actual grammar. I introduced executable grammars as part of the Newspeak project.<br /><br />Consider the following grammar:<br /><pre><br /><span style="font-style: italic;">statement -> ifStatement | returnStatement</span><br /><span style="font-style: italic;">ifStatement -> ‘if’ expression ‘then’ expression ‘else’ expression</span><br /><span style="font-style: italic;">returnStatement -> ‘’return’ expression</span><br /><span style="font-style: italic;">expression -> identifier | number</span><br /></pre><br />In Newspeak, we’d write:<br /><pre><br /><span style="font-weight: bold; font-style: italic;">class</span><span style="font-style: italic;"> G = ExecutableGrammar ( |</span><br /><span style="font-style: italic;">(* lexical rules for identifier, number, keywords elided *)</span><br /><span style="font-style: italic;">(* The actual syntactic grammar *)</span><br /><span style="font-style: italic;"> statement = ifStatement | returnStatement.</span><br /><span style="font-style: italic;"> ifStatement = if, expression, then, expression, else, expression.</span><br /><span style="font-style: italic;"> returnStatement = returnSymbol, expression.</span><br /><span style="font-style: italic;"> expression = identifier | number.</span><br /><span style="font-style: italic;">|)()</span><br /></pre><br />Now let’s define some semantic action, say, creating an AST. The Newspeak library let’s me do this in a subclass, by overriding the code for the production thus:<br /><pre><br /><span style="font-weight: bold; font-style: italic;">class</span><span style="font-style: italic;"> P = G ()(</span><br /><span style="font-style: italic;"> ifStatement = (</span><br /><span style="font-style: italic;"> super ifStatement wrap:[:if :e1 :then :e2 :else :e3 | </span><br /><span style="font-style: italic;"> IfStatementAST if: e1 then: e2 else: e3</span><br /><span style="font-style: italic;"> ].</span><br /><span style="font-style: italic;"> )</span><br /><span style="font-style: italic;"> returnStatement = (</span><br /><span style="font-style: italic;"> super returnStatement wrap:[:return :e | ReturnStatementAST return: e].</span><br /><span style="font-style: italic;"> )</span><br /><span style="font-style: italic;">)</span><br /></pre><br />No prior parser combinator library allowed me to achieve a similar separation of grammar and semantic action. In particular, I don’t quite see how to accomplish this in a functional language. <br /><br />In the functional world, I would expect one function would define the actual grammar, and another would perform the semantic actions (in our example, build the AST). The latter function would transform the result of basic parsing as defined by the grammar, producing an AST as the result. We’d use pattern matching to define this function. I’d want to write something like:<br /><pre><br /><span style="font-style: italic;">makeAST = </span><br /><span style="font-style: italic;"> <span style="font-weight: bold;">fun</span> ifStatement(ifKw, e1, thenKw, e2, elseKw, e3) = </span><br /><span style="font-style: italic;"> IfStatementAST(makeAST(e1), makeAST(e2), makeAST(e3)) |</span><br /><span style="font-style: italic;"> <span style="font-weight: bold;">fun</span> returnStatement(returnKw, e) = ReturnsStatementAST(makeAST(e)) |</span><br /><span style="font-style: italic;"> <span style="font-weight: bold;">fun</span> identifier(id) = IdentifierAST(id)</span> |<br /><span style="font-style: italic;"> <span style="font-weight: bold;">fun</span> number(n) = NumberAST(id)</span><br /></pre><br />where <span style="font-style: italic;">makeAST</span> maps a concrete parse tree into an abstract one. Which in this case looks pretty easy.<br /><br />The question arises: where did the patterns <span style="font-style: italic;">ifStatement</span>, <span style="font-style: italic;">returnStatement</span>, <span style="font-style: italic;">number</span> and <span style="font-style: italic;">identifier</span> come from?<br /><br />Presumably, our parser combinator library defined them based on our input grammar. The thing is, the library does not know the specifics of our grammar in advance. It cannot predefine data constructors for each conceivable production. Instead, it should create these data constructors dynamically each time it processes a specific grammar.<br /><br />How does one create datatypes dynamically in a traditional functional language? I leave that as an exercise for the reader.<br /><br />Ok, so while it is clear that creating datatypes on the fly would be very helpful here, it is also clear that it isn’t easy to do in the context of such languages. How would you describe the type of the library? The datatype it returns is created per grammar, and depends on the names of the grammar production functions. Not easy to characterize via Hindley-Milner. And yet, once the library created the datatype, we actually could utilize it in writing type safe clients.<br /><br />Instead, our library will probably generate values of some generic datatype for parse trees. A possible representation is a pair, consisting of a tag of type string representing the name of the production used to compute the tree, and a list consisting of the elements of the tree, including vital information such as where in the input stream a given token was found and what string exactly represented it. We cannot elide such lexical information, because some users of our library will need it (say, pretty printers). Then I can write:<br /><pre><br /><span style="font-style: italic;">makeAST = </span><br /><span style="font-style: italic;"> </span><span style="font-weight: bold; font-style: italic;">fun</span><span style="font-style: italic;"> parsetree(“if”, [ifKw, e1, thenKw, e2, elseKw, e3]) = </span><br /><span style="font-style: italic;"> IfStatementAST(makeAST(e1), makeAST(e2), makeAST(e3)) |</span><br /><span style="font-style: italic;"> </span><span style="font-weight: bold; font-style: italic;">fun</span><span style="font-style: italic;"> parsetree(“return”, [returnKw, e]) = ReturnsStatementAST(makeAST(e)) |</span><br /><span style="font-style: italic;"> </span><span style="font-weight: bold; font-style: italic;">fun</span><span style="font-style: italic;"> parsetree(“id”,[id]) = IdentifierAST(id)</span> |<br /><span style="font-style: italic;"> </span><span style="font-weight: bold; font-style: italic;">fun</span><span style="font-style: italic;"> parsetree(“number”,[in]) = NumberAST(in)</span><br /></pre><br />Obviously, we’ve lost the type safety of the previous version. Ironically, the inability of the language to generate types dynamically forces code to be less statically type safe.<br /><br />Now ask yourself - how does our combinator library produce values of type <span style="font-style: italic;">parsetree</span> with an appropriate tag? For each <span style="font-style: italic;">parsetree</span> value <span style="font-style: italic;">p(tag, elements)</span>, the tag is a string corresponding to the name of the production that was used to compute <span style="font-style: italic;">p</span>. How does our library know this tag? The tag is naturally specified via the name of the production function in the grammar. To get at it, one would need some introspection mechanism to get the name of a function at run time. Of course, no such mechanism exists in a standard functional language. It looks like you’d have to force the user to specify this information redundantly as a string, in addition to the function name (you still need the function name so that other productions can refer to it).<br /><br />You might argue that we don’t really need the string tags - just return a concrete parse tree and distinguish the cases by pattern matching. However, it isn’t generally possible to tell the parse tree for a number from that for an identifier without re-parsing. Even when you can tell parse trees apart, the resulting code is ugly and inefficient, as it is repeating some of the parser’s work.<br /><br />We could approach the problem via staged execution, writing meta-program that statically transformed the grammar into a program that would provide us with the nice datatype constructors I suggested in the beginning. If one goes that route, you might as well define an external DSL based on BNF or PEGs.<br /><br />So, I assert that reflection is essential to this task, and dynamic type generation would be helpful as well, which would require dependent types and additional reflective functionality. However, maybe I’ve overlooked something and there is some other way to achieve the same goal. I’m sure someone will tell me - but remember, the library must not burden the user by requiring redundant information or work, it must operate independent of the specifics of a given grammar, and it must keep semantic actions entirely separate.<br /><br />In any case, I think there is considerable value in adding at least a measure of introspection, and preferably full reflection, to traditional functional languages, and interesting work to be done fleshing it out.Gilad Brachahttp://www.blogger.com/profile/17934280339206214042noreply@blogger.com23tag:blogger.com,1999:blog-2447174102813539049.post-36273045518523949072010-07-31T15:47:00.000-07:002012-06-29T08:14:03.360-07:00Meta MorphosisRecently, I was pointed at <a href="http://antimatter15.com/misc/rotatedgooglecss3.html">rotated Google</a>. This is cool in a perverse sort of way, and it immediately reminded me of Morphic.<br /><br />For those who don’’t know, Morphic is the name of the Squeak (and in earlier times, Self) GUI. John Maloney (who nowadays does <a href="http://info.scratch.mit.edu/About_Scratch">Scratch</a>) introduced the original Morphic GUI back in the halcyon days of Self, and later adapted it to Squeak Smalltalk. The latest incarnation of a Morphic-style UI is Dan Ingalls’ <a href="http://www.lively-kernel.org/">lively kernel</a>, which adapted the ideas to Javascript and the web. You can <a href="http://www.lively-kernel.org/repository/lively-wiki/example.xhtml">check it out in your browser</a> right now.<br /><br />What makes Morphic interesting is that it is compositional. The basic building block is a <span style="font-weight: bold;">morph</span>, which is just a graphical entity. The key is that everything in Morphic is a morph - including not just the basic morphs like lines and curves, polygons, circles, ellipses but also text, buttons, lists, windows ... you name it.<br /><br />All morphs support pretty general graphical combinators - translation, rotation, scaling, non-linear warping, changing color, grouping/ungrouping etc. It follows that one can interactively rotate, scale or non-linearly warp an entire window running a live application.<br /><br />One of my favorite Squeak demos is a class browser that’s been animated so that it floats around the screen, rotating as it goes, coupled with sound effects (a croaking frog is my preference). Of course you can keep using the browser and add methods or remove instance variables on the fly while it’s doing that. It’s an amazing display of the power of compositionality in action. It’s also perfectly useless (like rotated Google).<br /><br />When running Morphic, you can always interactively ungroup a composite morph and get at its pieces. So you can disassemble the UI and find out what its made of. You can also do the opposite and assemble a UI out of simpler morphs; in a sense, <span style="font-weight: bold; font-style: italic;">the GUI is the GUI builder</span>.<br /><br />The situation is quite analogous to the physical world. A real window (the kind used to let light into your house) is assembled from physical pieces, and can be disassembled as well. The window as a whole, and each of its components, can be manipulated in space in uniform ways.<br /><br /><span style="font-style: italic;">Thankfully, the laws of physics are compositional, since they were not designed by software engineers on a standards committee.</span><br /><br /><span style="font-style: italic;">Put another way, if the universe was built like most software, it would have crashed long ago; the big bang would have a different meaning.</span><br /><br />As a demonstration of good computer science, Morphic is brilliant. However, as a working UI it is problematic. You don’t really want your windows to fall apart in the user’s hands because they accidentally pressed some control sequence.<br /><br />Looking at how physical windows work, we see that when they are assembled, they are secured so they are not disassembled too easily. Things are held together with glue or screws or whatever, and you need to make an effort to take the structure apart, perhaps using special tools.<br /><br />This points at the way morphic interfaces should evolve. It’s great to have the underlying flexibility that they give you, but we want mechanisms to prevent accidents. We don’t want our applications decomposing by mistake. We also don’t want loose windows rotating by mistake. We need the equivalent of screws to hold things in place. The nice thing about screws is that they can be be used to build things up from parts compositionally, and they can be unscrewed when necessary. That way, we can take advantage of the flexibility of the underlying framework and do cool things with it, while keeping it safe for the end-user.<br /><br />As rotating Google and (more significantly) Lively show, the web opens up the possibility of such UIs reaching a broad audience. I am sure we will get versions of morphic that are more refined, usable, attractive and polished - all less than three decades since they were introduced in Self. Instant progress!Gilad Brachahttp://www.blogger.com/profile/17934280339206214042noreply@blogger.com11