We are excited to announce Spritely Goblins v0.10, available for both Guile and Racket alike! Goblins is Spritely's distributed object programming environment, providing an intuitive security model, automatic local transactions for synchronous programming, and asynchronous programming allowing collaboration over the network with the same level of ease as local asynchronous programming. Goblins takes the pain out of reasoning about distributed and secure peer-to-peer programming: with Goblins, that's the default mode of operation!
Get Goblins 0.10!
The 0.10 release of guile-goblins is already available in Guix, so go get it!
$ guix pull
$ guix install guile-goblins
Or if you're on MacOS, you can use Homebrew:
brew tap aconchillo/guile
brew install guile-goblins
Racket folks can install racket-goblins with:
$ raco pkg install goblins
What's new
This is a big release and there are a lot of new features, especially in the Guile version. In short, Guile and Racket versions of Goblins can now talk to each other over OCapN, and the Guile version of Goblins is now Spritely's official and default recommended version of Goblins (though the Racket version will continue to be supported). The Guile version of Goblins is nearly at feature parity with the Racket version (with a couple of small exceptions) and in many ways is now ahead, providing an unparalleled level of comfort in development for a distributed development environment of its kind.
Racket and Guile Goblins can now talk over the network!
The Guile version of Goblins has been updated to be able to speak OCapN, finally allowing Guile users to be able to easily make awesome object-capability-secure peer-to-peer programs! What's more, the Guile and Racket versions of goblin-chat have been updated to be able to talk to each other over the network!
Seeing is believing:
Here we see a small demo end-to-end encrypted, peer-to-peer chat
program written in Goblins called goblin-chat
.
goblin-chat
was written originally as a demo project for
Goblins v0.7
(over two years ago!) but is still impressive for what it delivers:
both the core code for users and for chatrooms totals only
approximately 150 single lines of code (with no mention of the network
in the core code needed; Goblins provides a network abstration such that
such functionality is automatic once the program is connected to
OCapN).
But even more impressive: here we see the Racket version of goblin-chat and the Guile version of goblin-chat communicating seamlessly!
The power provided by Goblins' core integration with OCapN being shown off deserves underlining: thanks to the power of OCapN, once the Guile version of goblin-chat was ported (and Racket and Guile OCapN interoperability was hammered out more generally), the Racket and Guile versions of goblin-chat communicating with each other just worked!
Of course, in the future we aim to see OCapN implementations in more languages than just Racket and Guile. But we are happy to show off that two completely different runtimes are able to interoperate with each other, while both maintaining the abstract feeling and ease of just writing local asynchronous code. Now that's power!
Guile Goblins is now the primary implementation of Goblins
After long deliberation and extensive testing of both environments, we have decided that the Guile implementation of Goblins is the primary implementation of Goblins going forward.
What does this mean for the Racket version? We plan to still maintain and support it, and interoperability between Racket and Guile Goblins through OCapN will remain a high priority and strong source of pride. However, we have found that the ease of development and general direction of the Guile community (and largely also, the Guix community) is in strong alignment with our technical and social goals.
There are still a few things which will need to be ported over from Racket to Guile (namely a number of utilities in the actor-lib modules and, even more critically, the support for distributed acyclic garbage collection in OCapN/CapTP). However, Guile is nearly caught up and is in some ways ahead of the Racket version of Goblins. As such, the focus on new development environment features will be within the Guile version of Goblins. Some of these will be backported to Racket where appropriate, but this will not be the foundational goal.
On that note, let's look at some of these new features!
Vats on custom event loops! (Guile)
Goblins is designed to work with the vat model of computation, a special kind of communicating event loop system.
Goblins on Guile has implemented default vats on top of Fibers, which provides a wonderful event loop to use for most situations.
But... what if you're working with a cool program that uses its own event loop? For example, maybe you're building a GTK application or using the awesome Chickadee game library! Both of those already have their own event loop, so what you really need is a way to hook Goblins into it!
Thankfully, in v0.10 of the Guile version of Goblins, we have just such a feature! Here's an example of a custom vat used to fit into Chickadee (and shown off in the screenshot above, from the Networked Garden demo):
(define* (make-chickadee-vat #:key (name 'chickadee)
(agenda (current-agenda)))
(define vat-script #f)
(define message-queue (make-concurrent-queue))
(define (start churn)
(define (handle-messages)
(if (concurrent-queue-empty? message-queue)
(sleep (current-timestep))
(match (concurrent-dequeue! message-queue)
((msg return-channel)
(channel-put return-channel (churn msg)))
(msg
(churn msg))))
(handle-messages))
(with-agenda agenda
(set! vat-script (script (handle-messages)))))
(define (halt)
(cancel-script vat-script))
(define (send msg return?)
(if return?
(let ((return-channel (make-channel)))
(concurrent-enqueue! message-queue (list msg return-channel))
(channel-get return-channel))
(begin
(concurrent-enqueue! message-queue msg))))
(make-vat #:name name
#:start start
#:halt halt
#:send send))
Enter the vat for easier live development! (Guile)
Live development has gotten dramatically easier in this version
of Goblins!
Users of Guile's REPL can now enter a vat using the ,enter-vat
REPL "comma command":
scheme> (define a-vat (spawn-vat))
scheme> ,enter-vat a-vat
goblins[1]>
Now all Goblins objects are run within that vat context:
goblins[1]> (define alice
(spawn ^greeter "Alice"))
goblins[1]> ($ alice "Alfred")
; => "Hello Alfred, my name is Alice!"
Revamped manual (Guile)
The Guile manual has been largely overhauled and filled out. We dare say it's actually fairly usable finally! Plus you can read it online!
Onwards and upwards!
With this release we've pushed some new territory with two interoperable implementations talking over the network and a bunch of improvements which should make Goblins easier to pick up and use.
But we're not stopping there! We're immediately beginning work on the next major features for Goblins, including researching how to best integrate a time-traveling distributed debugger (we have the foundations, but we gotta make it good!) making persisting running Goblins programs into a first-class experience, and more!
In the meanwhile, if you make something cool with Goblins, you should let us know on our community forum (use OCAPN2023 for the Invite Code when you join.)