Archive for deployment

Suspend in the browser, resume on the desktop.

Posted in Appsterdam, consulting, Context, Naiad, Smalltalk, Spoon with tags , , , , , , , , on 29 October 2016 by Craig Latta

In yesterday’s post, I showed how Bert Freudenberg’s SqueakJS can extend Smalltalk‘s traditional host platform integration for the web, with DOM access through my class ThisWebpage. With this we can build any front-end HTML5 webapp behavior that any other JavaScript framework can. Another thing we can do with ThisWebpage is install the native-app version of Squeak, giving us the full speed of Eliot Miranda’s Cog virtual machine.

Running Smalltalk on the web is a satisfying thing, but there are times when you need more speed or host operating system access than JavaScript in a web browser can provide. Eventually, we’ll be able to embed native code in web browsers using WebAssembly, which will be a big improvement. Even then, though, there will still be the platform access compromises that come with a sandboxed web environment. So, one obvious thing to do with our JavaScript access is move our Smalltalk processes to the desktop, where we can use the high-performance Cog virtual machine.

platform portability

Smalltalk is an image-based system. In addition to modeling an idealized processor, with its own instruction set, the Smalltalk virtual machine models the processor’s memory. The virtual machine can make a snapshot of this memory, as a normal host platform file called an image. This snapshot captures the complete execution state of the Smalltalk system (the object memory), including the program counters of every process that was running at the time. The virtual machine can also resume this snapshot, restoring that system state so that the system may continue. This is similar to the “sleep” function of a laptop.

Since the virtual machine provides a consistent platform abstraction above whatever host is running it, we can suspend the system on one host and resume it on another. Smalltalk programmers have taken great advantage of this for years, writing single systems which run on multiple operating systems (e.g., Macintosh and Windows). Java attempted to provide consistent execution semantics, under the tagline “write once, run anywhere” (with mixed results), but this did not extend to a continuous memory image. We can make an object memory snapshot with SqueakJS in a web browser, and resume it with Cog in a native app.

exporting ourselves

SqueakJS uses the HTML5 “indexed database” feature for persistent storage, making it look like a normal filesystem. We can write a snapshot of the running SqueakJS system this way. We can then use ThisWebpage to download the snapshot to the user’s machine. We add a link to the document in which SqueakJS runs, and synthesize a click on it, invoking the download.

We also use ThisWebpage to detect the user’s host operating system, and download a platform-specific Cog installer. I’ve written installers for macOS, Windows, and Linux. Each one downloads the Cog virtual machine, installs a platform handler for “squeak://” URLs that runs Cog, and invokes a squeak:// URL that runs our snapshot. This URL encodes the name of the snapshot file, Cog parameters (such as whether or not to run the system headless), and a base64-encoded JSON dictionary of other parameters that the Smalltalk object memory can process.

making contact

Now our object memory is running both in the browser in SqueakJS, and in Cog as a native app. The current Black Page Digital object memory for Squeak connects the two with a remote-messaging network service. When the SqueakJS-hosted instance invokes the local one, it also forks a process that periodically attempts a remote-messaging connection. When the memory resumes on a non-web host, it starts a WebSocket-based server to provide remote messaging service.

With the two Squeaks connected, objects in one can send messages to objects in the other, creating a distributed system. The Cog-based system now has access to the DOM of the web browser through ThisWebpage in the SqueakJS-based system, and the SqueakJS-based system has unsandboxed access to the host operating system through the Cog-based system. In particular, SqueakJS can use Cog to run network servers, so one can create a distributed system from SqueakJS instances running in many web browsers on many machines.

In tomorrow’s post, I’ll discuss the remote messaging protocol in more detail. After that, I’ll introduce a distributed network service that takes advantage of it.

 

SqueakJS changes its world with ThisWebpage

Posted in Appsterdam, consulting, Context, Naiad, Smalltalk, Spoon with tags , , , , , , , , , , , , on 28 October 2016 by Craig Latta

a new platform

Since becoming a virtual-machine-based app, Smalltalk has integrated well with other operating systems, providing the illusion of a consistent unified platform. With the ascendancy of JavaScript, the common execution environment provided by web browsers is effectively another host operating system. Smalltalk runs there too now, thanks to Bert Freudenberg’s SqueakJS. So in addition to macOS, Windows, and Linux, we now have the Web host platform.

While all platforms expose some of their functionality to apps through system calls, the Web exposes much more, through its Document Object Model API (DOM). This gives Smalltalk a special opportunity to enable livecoded apps on this platform. It also means that Smalltalk can interoperate more extensively with other Web platform apps, and participate in the ecosystem of JavaScript frameworks, both as a consumer and a producer.

to JavaScript and back

The part of SqueakJS which enables this is its bidirectional JavaScript bridge. This is implemented by class JSObjectProxy, and some special support in the SqueakJS virtual machine. One may set Smalltalk variables to JavaScript objects, send messages to JavaScript objects, and provide Smalltalk block closures as callback functions to JavaScript. One may interact with any JavaScript object in the Web environment. This means we can manipulate DOM objects as any other JavaScript framework would, to create new HTML5 user interfaces and modify existing ones.

In particular, we can embed SqueakJS in a web page, and modify that web page from SqueakJS processes. It would be very useful to have a Smalltalk object model of the host web page. I have created such a thing with the new class ThisWebpage.

reaching out with ThisWebpage

I chose the name of ThisWebpage to be reminiscent of “thisContext”, the traditional Smalltalk pseudo-variable used by an expression to access its method execution context. In a similar way, expressions can use ThisWebpage to access the DOM of the hosting Web environment. One simple example is adding a button:

ThisWebpage
  createButtonLabeled: 'fullscreen'
  evaluating: [Project current fullscreen: true]

Behind the scenes, ThisWebpage is doing this:

(JS document createElement: 'input')
  at: #type
  put: 'button';
  at: #onclick:
  put: [Project current fullscreen: true]

Class JSObjectProxy creates JS, an instance of itself, during installation of the JavaScript bridge. It corresponds to the JavaScript DOM object for the current web browser window, the top of the DOM object graph. By sending createElement:, the expression is invoking one of the DOM methods. The entire set of DOM methods is well-documented online (for example, here’s the documentation for Document.createElement).

So far, ThisWebpage has some basic behavior for adding buttons and frames, and for referring to the document elements in which SqueakJS is embedded. It can also create links and synthesize clicks on them. This is an important ability, which I use in making a Squeak object memory jump from SqueakJS in a web browser to a native Cog virtual machine on the desktop (the subject of tomorrow’s post).

The possibilities here are immense. ThisWebpage is waiting for you to make it do amazing front-end things! Check it out as part of the Context 7 alpha 1 release.

 

Caffeine: live web debugging with SqueakJS

Posted in Appsterdam, consulting, Context, Naiad, Smalltalk, Spoon with tags , , , , , , , , , , , , , , , , , , , , on 26 October 2016 by Craig Latta

In February 2015 I spoke about Bert Freudenberg’s SqueakJS at FOSDEM. We were all intrigued with the potential of this system to change both Smalltalk and web programming. This year I’ve had some time to pursue that potential, and the results so far are pretty exciting.

SqueakJS is a Squeak virtual machine implemented with pure JavaScript. It runs in all the web browsers, and features a bi-directional JavaScript bridge. You can invoke JavaScript functions from Smalltalk code, and pass Smalltalk blocks for JavaScript code to invoke as callbacks. This lets Smalltalk programmers take advantage of the myriad JavaScript frameworks available, as well as the extensive APIs exposed by the browsers themselves.

The most familiar built-in browser behavior is for manipulating the structure of rendered webpages (the Document Object Model, or “DOM”). Equally important is behavior for manipulating the operation of the browser itself. The Chrome Debugging Protocol is a set of JavaScript APIs for controlling every aspect of a web browser, over a WebSocket. The developer tools built into the Chrome browser are implemented using these APIs, and it’s likely that other browsers will follow.

Using the JavaScript bridge and the Chrome Debugging Protocol, I have SqueakJS controlling the web browser running it. SqueakJS can get a list of all the browser’s tabs, and control the execution of each tab, just like the built-in devtools can. Now we can use Squeak’s user interface for debugging and building webpages. We can have persistent inspectors on particular DOM elements, rather than having only the REPL console of the built-in tools. We can build DOM structures as Smalltalk object graphs, complete with scripted behavior.

I am also integrating my previous WebDAV work, so that webpages are manifested as virtual filesystems, and can be manipulated with traditional text editors and other file-oriented tools. I call this a metaphorical filesystem. It extends the livecoding ability of Smalltalk and JavaScript to the proverbial “favorite text editor”.

This all comes together in a project I call Caffeine. had fun demoing it at ESUG 2016 in Prague. Video to come…

Context status 2015-01-16

Posted in Appsterdam, consulting, Context, Naiad, Smalltalk, Spoon with tags , , , , , , , on 16 January 2015 by Craig Latta

Hoi all–

Context is the umbrella project for Naiad (a distributed module system for all Smalltalks), Spoon (a minimal object memory that provides the starting point for Naiad), and Lightning (a remote-messaging framework which performs live serialization, used by Naiad for moving methods and other objects between systems). I intend for it to be a future release of Squeak, and a launcher and module system for all the other Smalltalks. I’m writing Context apps for cloud computing, web services, and distributed computation.

Commits b7676ba2cc and later of the Context git repo have:

  • Support for installable object memories as git submodule repos.
  • Submodule repos for memories for each of the known Smalltalk dialects, with Naiad support pre-loaded. I’m currently working on the submodules for Squeak and Pharo.
  • A web-browser-based console for launching and managing object memories.
  • A WebDAV-based virtual filesystem that enables Smalltalk to appear as a network-attached storage device, and mappings of the system to that filesystem that make Smalltalk accessible from external text editors (e.g., for editing code, managing processes and object memories).
  • Remote code and process browsers.

There’s a live discussion site and a mailing list. The newsgroup is gmane.comp.lang.smalltalk.squeak.context.

Thanks for checking it out!

Craig

a detailed Naiad description

Posted in Appsterdam, consulting, Naiad, Smalltalk, Spoon with tags , , , , , , , , , on 21 October 2012 by Craig Latta

(from the Spoon release notes)

Spoon is a project to make Smalltalk systems more understandable, by removing unnecessary stuff, reorganizing what remains, and making it easier to share and deploy. If you’re interested in teaching, modules, bootstrapping, minimalism, remote messaging, proxies, metaprogramming, streams, sockets, or namespaces, you may be interested in this.

Motivation

Smalltalk began as a part of a vision to provide extraordinary computing power to creative individuals. Although computer networks grew alongside it, Smalltalk was released into the world while its support for collaboration was still rudimentary. The system uses the concept of a virtual machine, including a model of the machine’s memory, composed entirely of objects. Besides providing a very portable execution model, this scheme gives the system a powerful continuity: everything happens as the result of sending messages to objects. When it comes to sharing objects with other people, however, this continuity is violated.

Traditionally, to share code with another Smalltalk programmer, one writes source code to a file, and shares the file. One is no longer sending messages to objects, and the behavior being shared is reduced from live objects to a textual form which requires compilation to reanimate. When it is in that form, one cannot ask it to do things, as with objects. Worse, source code is ambiguous; the result of compilation depends on the environment in which it takes place. It’s easy for the target compilation environment to be different from the original one in very subtle ways. Even referring to a class by name is risky; there is no way to be sure that the class with that name in the target compilation environment (if there even is one) is equivalent to the one in the original.

With the means of code-sharing being relatively unexpressive and inconvenient, Smalltalk object memories develop mostly in isolation, and quickly diverge from one another. And within each memory, support for describing the component behavior of different subsystems is weak. The result, after over thirty years of evolution, is that it is difficult even to describe what behavior one wants to transfer, before subjecting it to the inaccuracies of the transfer itself. Object memories have grown into large knots which are hard to untangle manually. Smalltalk’s designers pursued a system that one person could understand and maintain. These problems hinder that pursuit, and make working in teams much harder than it could be. They make the experience of teaching and learning the system awkward, and this is one reason why the Smalltalk community is small.

Approach

Smalltalk programmers who persevere in spite of these problems live with them for quite a while. They often don’t even notice them, both because the system in general is so much more powerful and fun than those they have used before, and because the peculiarities of the development process are longstanding traditions. When it becomes too painful to ignore, many people contemplate something better, but end up using workarounds that seem to make a reasonable trade between improvement and compatibility. There always seem to be more important things to work on. I think the workarounds created so far have made team development tolerable (for example, Monticello and SqueakSource), but they don’t make the system much easier to understand.

For me, the point at which the pain became intolerable came while I was teaching a Squeak course at Stanford University. There’s nothing like explaining the system to a room full of inquisitive college students to make its shortcomings clear. You see the system with new eyes, and a fresh sensibility. In order to explain one concept, I had to explain several interdependent pieces of folklore. I wanted to show how object-oriented programming enables powerful divisions of responsibility, but it was tricky to do this with Smalltalk as my exemplar.

I decided it was time for the extraneous stuff to go. I wanted to know what is truly essential for a functioning Smalltalk system, so I could show it to others. Once I had identified that, I wanted a way to compose larger systems while avoiding the knots of the past.

Nuke It From Space; It’s The Only Way To Be Sure

I started by creating a proxy system and a remote system browser that used it, so that I could remove things from afar. As anyone who has tried to refactor the user interface knows, it’s tricky to do that while using it. By changing the system remotely, I could use another system’s user interface instead. I was able to remove large swathes of the system with impunity, which was fun.

I got pretty far with this before I realized there’s a better way to discard unused objects: throw away all the methods that haven’t been run recently. I modified the virtual machine to set a mark bit in each method it runs, and wrote a version of the garbage collector which treats unmarked methods as garbage. I could clear the marks on all the methods in the system, then run the system for a while (ideally, run unit tests). When I ran the new collector, all the unmarked methods got discarded.

More importantly, all the literals of those methods got discarded, if there was no other path from them to some marked method. By running this from a remote browser while the target system ran headlessly, I was able to discard the entire graphics system, including Morphic, in one stroke. This led to a series of small object memories, the smallest being 1,337 bytes long (it adds 3 and 4 and then exits).

Visualization

I realized I now had memories with fewer bytes than there were pixels on my screen. I wanted to see what they looked like. I extended Squeak’s virtual machine simulator to write the object memory as a picture, one pixel per object byte, with the color of each pixel determined by the class of the corresponding object. By writing such a picture every few instructions, I made animations that showed contexts being created, and objects allocated and reclaimed. I made an interactive browser that could magnify a region of one picture, and print detailed information about the object corresponding to a pixel chosen with the mouse.

I also wanted a visualization of the references between objects. Again I extended the simulator, to output a directed graph of all object references at a single moment in time, readable by the Walrus interactive hyperbolic graph viewer. This provided the most compelling illustration yet of a Smalltalk memory’s contents. Check out the demonstrations of all these visualization tools.

Imprinting

At the same time I was ripping things out, I was using remote messaging to put things in. I designed a way to transfer compiled methods from one system to another directly. I call this imprinting. I extended my remote browser to compile source code in the user-interface memory, and transfer the results directly to the remote memory. With this direct transfer, the compilation environment of the target memory matters much less, because no compilation is necessary in the target memory. If you can transfer a method’s literals and instructions correctly, then source code becomes an optional piece of documentation for the benefit of humans. In Spoon, literal markers describe method literals. They are transferred instead of the literals themselves, and they can recreate those literals when their methods are installed.

Transferring some method literals, like strings, is trivial. Others pose a challenge. In particular, how should one transfer a class reference? If a class object in one system and the corresponding class object in another system are truly equivalent in how they define the state of their instances, then we can refer to them using a single unique identifier. Like source code generally, class names become an optional piece of documentation. Compiled methods, and the virtual machines that run them, don’t care what the names of the classes are. It is only important that the instances the methods manipulate are of the expected storage format. This led to the namesake concept of Spoon’s module system.

NAIAD: Name and Identity Are Distinct

When you compile a method from source code that refers to a class, that method object has a reference to a unique live class object in the system. By using a unique identifier to refer to that class, rather than a textual name, we can preserve the identity of that class object across multiple object memories. By transferring methods directly, without resorting to recompilation, we can preserve the behavior of the instances of that class across memories too.

Naiad, Spoon’s module system, provides a framework for structured imprinting. With it, we can not only transfer methods, but also refer to particular versions of execution environment components, including methods, modules (groups of methods), classes, authors, comments, tags, and checkpoints. We can create collections of these references, called edit histories, that can answer important questions about the execution environment over time.

Identifiers and Editions

The basis for these references is the identifier, or ID. Each class in the system (both meta and non-meta) is given a universally unique identifer, or UUID, also known as its base ID. Add to that the UUID of the author who defined the class, and a version, and you have a class ID. Add to that the selector, version, and author UUID of a method of that class, and you have a method ID.

With these IDs, we can record the act of installing the corresponding components, as editions. An edition is a description of a component, sufficient to create an identical instance of that component in another memory. For example, a method edition records the header, literal markers, initial and ending program counter values, instructions, and class edition of a method, and a class edition records the format, superclass ID, and method editions of a class.

A class in Spoon still has a name, but it is part of the state of that class, along with its base ID. Each class is responsible for its own name, and there is no longer a need for a central registry of names. In Spoon there is no system dictionary. The compiler asks a class directly for its name binding. The system roots, including class Object, are known to the compiler. One could argue that, apart from the pseudovariables (true, false, nil, and thisContext), there are no global variables in Spoon.

Edit Histories and Modules

The place where we record editions is an edit history. Here editions are associated with the IDs of their components. We can then look up the edition for any component, given its ID. For example, we can ask a class for its base ID, and ask the edit history for the active class edition for that base ID. Editions have references to the previous and next editions timewise for their component, so we can make more complex queries such as “What are classes in the system that have ever had a method version written by this author?”

Modules are collections of method IDs. A module transfers the methods it describes to a remote memory by creating a copy of itself in the remote system, and guiding that system through a synchronization of the two memories. By “synchronization”, I mean that the original module is smart about not installing components which are already present in the remote memory. Many of the questions that an original module will ask its remote copy are ultimately answered by the edit history of the module copy’s system.

The edit history also augments the traditional Smalltalk source files (“changes” and “sources”). For a given development system, it occupies its own object memory, called a history memory, maintaining a remote messaging connection to the memory it describes, called the subject memory. It’s feasible to give the edit history its own memory because memories are now small by default.

Note that in cases where live system synchronization is not possible due to connectivity constraints, one can still send an entire history memory asynchronously to the requestor and let the synchronization happen locally. Similarly, the history memory that a developer uses can be located on any connected machine. For example, one could use a subject memory on an iPhone that has its history memory in the cloud.

Module Discovery

Finally, Naiad provides a means of finding module objects that one would like to install. It uses Google to index web pages that describe all available modules. Each module page includes a link to a local Spoon web server that, when followed, instructs the local Spoon system about how to install the module.

You can read about the Naiad object model in greater detail elsewhere on my blog. And again, all the Naiad classes are here in the system you can run now.

Future Work

There are at least two significant things missing from the current release. The first is a reorganization of the virtual machine, which is itself another sprawling and confusing knot (although the least so of the Smalltalk VMs I’ve encountered). The second is support for secure messaging (unless one uses an end-to-end scheme based on SSH tunnels or a VPN). The remote messaging system here is a minimal bootstrapping measure. Clearly one can imagine using something more sophisticated, like TeaTime. Again, though, I think a major simplification would be in order.

I want to extend Spoon beyond Squeak to other Smalltalk implementations. That’s my project for Camp Smalltalk at various conferences. I’m available to apply this work in paid and academic contexts. I’m currently a consultant based in Amsterdam, eager to work with clients worldwide. I would also like to pursue a PhD degree based on this work. I would love to hear from you.

Thanks

Thanks for reading this far, or just being interested enough to see what’s at the end. :) If you have any questions, please feel free to ask! I am usually on the Spoon IRC channel between 9am and 9pm GMT.

%d bloggers like this: