This week we begin taking a look at Scrall action language examples.
Today, we’re just going to stick our hands in the cookie jar and grab objects directly. In next week’s post we will hop lithely across associations to find the objects we need.
Since we aren’t using any associations today, we will use single class examples only, like this one:

I will be using miUML in my examples which is quite similar to any sm (Shlaer-Mellor) executable UML, such as xtUML. See my previous post for more about sm UMLs. As we go along, I will be explaining any conventions unique to Shlaer-Mellor for those not familiar with this branch of executable UML.
The {I} notation is a standard miUML attribute tag which expresses the identity or uniqueness constraint. An identifier, in Shlaer-Mellor, is a set of one or more attributes such that a set of corresponding values will yield either one or zero objects in a populated model. In our example, Tail number is a single attribute identifier defined on the Aircraft class.
Task 1: Grab that object
We often receive an identifier value (or set of values) from some source and then try to grab a reference to the associated object. And this is exactly what we are doing here with Scrall:
my aircraft .= Aircraft( Tail number: in.aircraft id )
Starting on the right hand side of the assignment, we see a reference to the Aircraft class with a selection clause designated by the attached parentheses. The single identifier attribute Tail number is matched against the aircraft id
parameter which is an input to this activity as indicated by the in
keyword prefix.
And, oh yes he did, space character delimiters are valid inside variable and model element names.
You’re welcome.1
Convenience feature: Implicit matching
Read the :
symbol, in the context of selection, to mean ‘match using this criteria’. In the simplest and most common case, that criteria is ‘= x’ and since it is so common, it is the default matching criteria when no other criteria such as !=, > >=, etc is specified. Though, if you like, you could write Aircraft( Tail number: = in.aircraft id )
.
This is a minor thing, but the accumulation of many small conveniences will lead us to a language that is easier to read and write.
Implicitly defining an object variable
In the example above, we know that the Aircraft(…)
selection must return zero or one object reference every time. This is because an identifier value is being matched. Not so coincidentally, the .=
assignment operator requires an expression on the right hand side that returns zero or one object reference. Think of the .
as meaning ‘a single object or no object’.
The action language analyzer has access to the class model and will check to see if you are performing a selection matching an identifier value. If not, a .=
assignment will trigger a static error.
The special assignment operator is also saying: “It really is my intention to grab the empty set or a single object2”. We want the modeler’s intentions to be explicit so that we can spot mistakes more quickly and force the modeler to think things through.
On the left hand side, the .=
assignment operator requires a new or existing single object variable.
In this case, the .=
assignment operator establishes the type of the newly defined variable my aircraft
. (‘my’ is not a keyword, it is just part of the variable name3). The variable has been implicitly typed as a single Aircraft object. You may not later try to assign a Pilot object without getting a static error.
General rules about Scrall variables
- All variables are local to the current activity.
- Within an activity, all variables are at the same scope.
- Every variable has a type which is defined either implicitly through assignment or with an explicit definition. For object and relation4 variables, the assignment operator will determine the type. For data variables, the right hand type determines the type on the left side.
- Once defined, a variable may not be redefined. So the type of a variable never changes.
These rules may seem a bit restrictive compared to those for programming language variables. But we are taking advantage of the fact that local activity scope is tightly focused and we’ve got a CLASS MODEL so the notion of local/global becomes rather quaint.
Unique selection with multiple attributes
Here’s a class with a more interesting identifier:

Note that there are two {I} tags in this class which means that you need both an ID value (such as 090) and an Airport value (such as SFO) to tell one Runway object apart from another. The R8 tag, in miUML, indicates a referential attribute on an association named R8. The referential attribute tag expresses another constraint. The constraint is 1) that the Runway.Airport referential attribute corresponds to the Airport.ID identifier attribute5 and 2) that, for any Runway object, its Airport attribute value, if it has one6, must correspond to the ID value of some instance of Airport.
So to grab a particular instance of Runway using supplied parameters for Runway ID and Airport values, you would do this in Scrall:
assigned runway .= Runway( ID: in.ID, Airport: in.Airport )
Convenience feature: Parameter doubling unnecessary
In the above example the input parameter names just happen to match the attribute names. It is not at all uncommon to see the variable names for supplied values match attribute or formal parameter names. This parameter doubling pattern is common to all programming languages and I’ve always found it annoying.
So, as the mighty GOD of Scrall <thunder clap>, I hereby declare that when attribute or signature parameter names match, you need specify only the supplied value name without fear of smite from a nit-picky parser. For example…
assigned runway .= Runway( in.ID, in.Airport )
… will work just fine. The language analyzer will see that you haven’t specified the attributes and assume that the variable names must match. If they don’t, you will get a static error. And order does not matter so this also works:
assigned runway .= Runway( in.Airport, in.ID )
Now, there is one flaw in this plan and feel free to point it out to get bonus points! That said, I’ve already got a solution ready that will
- blow
- your
- mind
I’m going to save it for a future post though.
Task 2: Get me those objects
So much for single object variables. If you want multiple objects, you need to define a multi object variable. Let’s say you want to select all Aircraft above a certain altitude. You could do this in Scrall:
high flying aircraft ..= Aircraft( Altitude: > high alt )
The many object assignment operator ..=
implicitly defines high flying aircraft
as a multi object variable. After the assignment, this variable may refer to zero, one or many objects. To get all aircraft just do this:
allAircraft ..= Aircraft()
Actually, you don’t need the parentheses, so this is also fine:
allAircraft ..= Aircraft
By the way, all
is a keyword to be introduced later so you shouldn’t name your variable all aircraft
. Too bad there isn’t such a thing as a ‘hard space’ for the parser to detect. Then keywords wouldn’t be a problem!
Task 3: Get me some object
Maybe you only want one object, say, the fastest aircraft. Since there could be multiple aircraft flying at the same speed, you need to grab an arbitrary instance (for lack of any other criteria). Use the .=.
arbitrary object assignment operator.
fastest plane .=. Aircraft( ^+Airspeed )
Two things are going on here. The unary max ^+
operator selects out the Aircraft instances with the highest Airspeed attribute values. The .=.
operator assigns one of the available instances from the right hand side, or the empty set if there are none. You can think of the right dot feeding one object or no object into the assignment and flowing out the other side as a single object assignment.
The above example will fail with an error if you try to use the .=
assignment operator since the right hand expression can yield more than one object.
When multiple max,min operators are applied, the order within the selection clause matters:
lowest fastest aircraft .=. Aircraft( ^-Altitude, ^+Airspeed )
fastest lowest aircraft .=. Aircraft( ^+Airspeed, ^-Altitude )
The first assignment selects the highest aircraft first and then chooses the fastest among them. The second chooses the fastest aircraft first and then the lowest.
high fast aircraft ..= Aircraft( Altitude > high alt and Airspeed > high speed )
Standard logic operators like and, or, not
and comparison operators =, >, <, >=, <=, !=
may be used in a selection assuming they have been defined on the types being compared.
miUML supports and requires the definition of operations on types.
Other details
Names are not case sensitive.
Lines end on newline.
Backslash to connect long lines.
You don’t need backslashes if you split a line within parenthesis, brackets or braces.
Comments // and /* */ just like in C, C++
NEXT UP, relationship/association hopping. See you next week.
- This feature does challenge the parser. But we prefer to put the burden on the tools rather than the model developer. ↩
- In the context of Scrall I will use the term object instead of ‘object reference’ unless there is some reason to make a distinction. ↩
- The modeler must be careful not to use keywords in symbol names. Consequently, we strive to define as few keywords as possible and make them obvious. Is it too much to ask a developer to avoid using ‘if’ in a variable name? ↩
- Described in a future post. ↩
- The name mapping Runway.Airport -> Airport.ID is not shown on an sm UML class diagram, but is recorded in the Runway.Airport attribute description as well as the miUML metamodel. (The expert trick is to be systematic in your naming of referential attributes). ↩
- I will delve into the systematic handling and significance of ‘empty’ referential attributes in a later blog entry. For now, be happy that there are no zeros in the 1 to 1..* association to Airport 😉 ↩
I help agile software teams succeed with requirements analysis, domain definition, platform independent, executable modeling and high quality code generation. Other websites: executableuml.org, modelstocode.com
I forgot to mention that there is yet another constraint expressed by the identifier (ID + Airport) in the Runway class. Since the referential attribute Runway.Airport is part of the Runway identifier, you cannot have two Runways at the same Airport with the same ID. So the class is saying that you couldn’t have two 090 runways at the same Airport, for example. It is an excellent example of expressing a constraint directly in the class model which can be carried forward into the implementation, all without any OCL. And, yes, I know that this constraint precludes parallel runways! But we’re not going to solve that problem with a single class. (Well, we could, but it wouldn’t necessarily be the best solution).
When is graphical SCRALL coming? 😀
I took a failed run at that many years ago. And that work has somewhat informed the current project. Once T-Scrall is sorted out, I may take another stab at G-Scrall. That said, it is not high on my priorities.
So yet another textual language variant, like how many more
( Oops, accidental send there )
…. how many more do I need or have to master.
Leon failed way back with a graphical notation, so hey let’s do more text.
What did his failed look like? Was it his failure, or lack of market acceptance?
Have you learned a lot of action languages? I only know of 4 being used. I think Leon proposed the graphical SCRALL at least 10 years ago. At that time I commented that tooling might be difficult, but I think it’s more plausible now. Look at IFML. I don’t remember if there were any technical problems, but Leon never marketed it.
“In this case, the .= assignment operator establishes the type of the newly defined variable my aircraft. The variable has been implicitly typed as a single Aircraft object.” I wonder if this is not a bit misleading since the operator may or may not return an instance?
I wondered that too. In fact, I am still trying to decide if it is essential to distinguish between a single object set and a multiple object set at all in the action language. One of my tasks is to compile a good set of reasoning for one way or the other. My colleague Andrew Mangogna and I have been arguing this back and forth for a while.
That said, I think it should be okay for any set to be empty. Sets do that. It is critical however, to make it easy to test for the empty case and to encourage modelers to check for that case when necessary. I point out in the subsequent post, for example, that the empty set evaluates as false in any logical comparison.
This mean that the ‘my aircraft’ is actually a set and not a scalar of type Aircraft?
Yes, it is a set of at most one Aircraft object reference, so you can use it with set operators with other Aircraft single and multi object variables:
our aircraft ..= your aircraft + my aircraft
The operands can be single or multi, but the result must be a multi object variable since the ..= assignment operator is being used.
Regarding the discussion on graphical vs. text action language: Ultimately, I think a graphical action language could be a good thing. For me, at least, it is a low priority at the moment. Higher priority items are (and not entirely in order):
1) Devise good semantics for seamlessly operating on object, relational and scalar data
2) Provide a quality text syntax to support those semantics
3) Write a formal grammar for the text syntax
4) Metamodel the semantics
5) Get open source tools to support the above
6) Support, to the degree possible, FUML
7) a bunch of other stuff and THEN take another run at a graphical syntax AND
build a very smart editor that supports fast data entry and editing of the graphical syntax which is absolutely essential to its adoption in any practical context. And that is why I start with a text syntax because existing text editors are already awesome. Sadly, this cannot be said of any graphical model editors that I have seen.