We build on the parsers from part 2 of this series to enhance and extend their capability. In particular, we extend the concept of modular grammars to construct chains of parsers which define a multi-stage transformation pipeline. The parsers forming these chain are enhanced to match and transform tree-structures, rather than being limited to simple […]
It’s usually not enough to simply recognize patterns in an input stream. Soon we will want to take action based on what we recognize. In order to facilitate this, we will begin creating semantic values from the input tokens and trigger semantic actions when certain patterns are recognized. In part 1 of this series we […]
Parsing Expression Grammars (PEGs) define a powerful class of matchers for recognizing strings of a formal language [1]. They’re well suited to parsing the syntax of computer languages. PEG-based tools like OMeta [2] have been successfully applied to a wide variety of transformation problems [3] [4]. The fundamental elements of PEGs can be described compactly […]
Happy New Year and welcome to 2011. With the coming of the new year, I’m happy to announce the availability of a simulator/debugger environment for Humus, currently hosted at http://dalnefre.com/humus/sim/humus.html Please note that this is a simulator of the Humus language written in JavaScript, so it runs very slowly. It is intended to allow experimentation […]
In part 7 of our series implementing programming language constructs with actors, we implement parallel execution of block statements. Parallel execution motivates the use of single-assignment data-flow variables. We also introduce transactions and exception handling. The only extension required to our grammar from part 6 is the inclusion of a THROW statement: stmt ::= ‘LET’ […]
Posted in Uncategorized | Tagged actor, concurrency, data-flow, evaluation, exception, execution, language, parallel, protocol, synchronization, transaction |
In part 6 of our series implementing programming language constructs with actors, we explore meta-circular definition of imperative actor primitives. We have now moved beyond expressions which yield values, and focus on statements which cause effects. The constructs explored here are the heart of any actor-based system. In order to support actor primitive statements, our […]
Posted in Uncategorized | Tagged actor, evaluation, imperative, language, pair, primitive, protocol, sequence, serializer, state-machine, synchronization, value |
Some language environments provide an interactive interface called a Read-Eval-Print-Loop (abbreviated REPL). One key characteristic of a REPL is the ability to incrementally define, extend and re-define your environment. This is particularly challenging in a pure-functional context, such as the evaluator we have developed so far. Modularity and incremental development seems to imply the need […]
Posted in Uncategorized | Tagged actor, data-flow, equation, evaluation, imperative, language, pattern-matching, protocol, recursion, synchronization, unification, value |
In part 4 of our series implementing programming language constructs with actors, we extend our pattern matching behaviors to support pattern equations. These are true equations that express relationships between patterns. They form the basis for introducing LET and IF expressions. The grammar for our extended language is shown below. Changes from part 3 are […]
Posted in Uncategorized | Tagged actor, equality, equation, evaluation, identity, language, pair, pattern-matching, protocol, unification, value |
In part 3 of our series implementing programming language constructs with actors, we explore parallel evaluation of sub-expressions and introduce pairs. Pairs allow the construction of tuples, generalizing structured multi-part patterns and values. In order to support pair expressions and patterns, we’ve refactored the grammar from part 2 to separate out literal constants expressions and […]
We continue exploring actor implementation of programming language constructs by adding a special form for conditional expressions. This will not increase the expressive power of the language. In part 1 we implemented a Turing-complete pure untyped lambda calculus. Now we add direct efficient support for conditional expressions and introduce basic pattern matching. Changes from the […]
One of the best ways to understand programming language constructs is to implement them. We will begin by implementing a simple, yet Turing-complete, functional expression language. In subsequent articles, we will extend this language with additional features. For now we will focus on just the “untyped” lambda calculus, augmented with constants. The grammar for our expression […]
The “Dining Philosophers” problem is a classic example used to illustrate various challenges with concurrency. We will approach this problem by incrementally designing the actors which model the problem and its solution in Humus. Through this example we will explore the avoidance of deadlock and starvation in the design of actor-based systems. Basic Thinking/Eating Cycle […]
This is part two of an article exploring what we mean when we say “message-passing”. Part one described how synchronous rendezvous can be expressed with actors. Part two describes an actor implementation of object-oriented method invocation. For Object-Oriented developers from the Smalltalk tradition, message-passing involves a dynamic method lookup, invocation of that method with the target […]
What do we mean when we say “message-passing”. For Object-Oriented developers from the Smalltalk tradition, message-passing involves a dynamic method lookup, invocation of that method with the target object as an implicit parameter, and return of a result object. By contrast, message-passing in synchronous communication models (such as π-calculus) involves “rendezvous” between sender and receiver, […]
In his article about state management in Clojure, Rich Hickey discusses his reasons for choosing not to use the Erlang-style actor model. While Erlang has made some implementation choices that can lead to problems, the problems are not intrinsic to the Actor Model. As the actor implementation with the longest history of success, Erlang naturally represents […]
Posted in Uncategorized | Tagged actor, blocking, Clojure, data-flow, deadlock, debugging, distribution, Erlang, functional, protocol, scalability, value |
A classic problem in concurrent programming is known as the “same fringe” problem [1]. What is the same fringe problem? As described by Richard Gabriel [2]: The samefringe problem is this: two binary trees have the same fringe if they have exactly the same leaves reading from left to right. There are many different approaches […]
A significant challenge in developing concurrent systems is the problem of composability. We create a solution that works properly in isolation, but when composed with other solutions leads to interference. The actor model ensures that individual actors may be composed without changing their behavior. Interference is prevented by definition, keeping the system consistent. In order […]
The Actor Model of Computation, as defined by Carl Hewitt [1] and elaborated by Gul Agha [2], defines three primitive operations. These operations are “Send”, “Create” and “Become”. The “Send” operation transmits an asynchronous message to a known receiver. The “Create” operation constructs a new actor with a specified initial behavior. The “Become” operation defines […]