Complex Values in Smalltalk
Total Page:16
File Type:pdf, Size:1020Kb
Complex Values in Smalltalk Thomas J. Schrader Christian Haider counseling developer Smalltalked Visuals GmbH [email protected] [email protected] Abstract Distinguishing between stateful objects powerful complementary modeling concept to conven- and Values has long been recognized as fruitful. Values tional objects. Properly distinguishing values from ob- are universal context free abstractions that prevent side- jects in order to permit a functional programming style effects and allow for a functional programming style. helps to overcome such problems.2 Though object-oriented programming languages pro- MacLennan stated four key properties of values: vide simple Values like Integer and String, more com- • values are abstractions (universals or concepts) plex Values are usually not supported. We show how to model complex structures as Values in Smalltalk, which • values are timeless and have no lifecycle allows for a simple and versatile implementation. The • values have no alterable state and can only be inter- resulting Smalltalk systems are simple, clear and easily preted, but not changed testable. • values are referentially transparent and prevent side- Categories and Subject Descriptors D.3.3 [Pro- effects when used on different parts of systems. gramming Languages]: Language Constructs and Following the evidence given by many practitioners3 it Features|Classes and objects significantly improves object systems when values are Keywords Value Objects, serialization, testability, modeled as Value Objects and used with value seman- refactoring, functional programming, Smalltalk tics wherever applicable instead of modeling them as mutable stateful objects. There are even comprehen- 1. Introduction sive compilations4 of Value Objects and other functional modeling patterns in object systems. Good Design: A system should be built with However, despite a wealth of research and practice a minimum set of unchangeable parts; those in the last 25 years,5 the support of Value Objects parts should be as general as possible; and all and value semantics in object-oriented programming parts of the system should be held in a uniform languages is still limited to some arbitrary simple cases. framework. [Ingalls81, 2nd principle] The implementation of more specific or more complex Object-oriented software designers have long real- Value Objects is still up to each designer and depends ized that conventional object systems can lack informa- on the specific situation, particularly the underlying tion integrity due to their design based on conventional language. changeable stateful objects. Particularly software work- Here, we present a simple object model and flows with lots of different data options are a common lightweight Smalltalk implementation to build more source of failure in conventional object systems and can complex Value Objects6. We draw upon our observa- be hard to design, to maintain and to test. tion that any data coming from and going to a sys- As early as 1982 Bruce MacLennan1 called for the tem eventually are simple literal values like numbers or recognition of values in object-oriented languages as a strings. Therefore it is always possible to print them. 1 see [MacLennan82] 2 In functional programming languages values are the only data option, which turns out to be very beneficial in design situations, where absolute reliability is required when lots of data are dis- tributed around and shared. 3 see [B¨aumer98] for an example 4 see [K¨uhne99] 5 [Riehle06] gives an example of such continuing effort. Copyright is held by the author/owner(s). 6 In the following we use the capitalized `Value' interchangeably with `Value Object' to indicate the object model; in contrast we ACM [to be supplied]. use the lowercase `value' for the common meaning of the word. So, a Value is created by a constructor which takes the Literal Objects. Other objects are immutable and have values of all its instance variables as parameters. Val- a literal representation, which makes them good Values: ues can print themselves in this constructor format, so • nil, true, false that the full definition of the Value is executable and visible at a glance. Since Values are context free and fi- • Numbers nite, they can always be written as code in a workspace • String, Symbol or a (testing) method. Values should naturally never • (literal) Array, ByteArray change after creation and do not provide any setters for instance variables. • LiteralBindingReference (only VisualWorks). In section2 we show some examples and give an String and Array can also become mutable in which overview of the core elements of our implementation. case they are not Values, but ordinary objects. We show a pragmatic way to support Values with a Instances of real Values can not be distinguished, simple generation framework. ideally referring to one single instance. This is true for Section3 introduces interface layers, shows how you nil, true, false and Symbols. Whereas Values like can explore your domains by modeling them with Val- String or Array create equal, but not identical copies. ues and gives an overview of the applications of Values, which made our Smalltalk systems more reliable and Value-like Objects. Many more Smalltalk objects are easier to maintain and to test. conceptually Values and are often handled with value In section4 we address object serialization which semantics although they are modeled like conventional is trivial for Values and meta descriptions which we objects in the library: noticed have something in common with our work. • Date, Time, Timestamp In section5 we summarize our implementation and • Point, Rectangle, Association shortly discuss pros and cons whereas in section6 we suggest more enhancements. • ColorValue. | but, let's get to work | These objects are composed of other objects or Values. Customarily, operations with these objects will return a copy and do not modify the instance. But they have 2. Complex Value Objects in Smalltalk setter methods for their instance variables so that at- 2.1 Values by Example tributes can be changed individually from the outside. Objects like Association may refer to arbitrary Examples are an important part of the descrip- tion of a programming language and environment. objects, not just Values. Only Association objects Many of the examples used in this book are taken containing Values are Values themselves, otherwise they from the classes found in the standard Smalltalk- are conventional objects. The same applies to Array and Dictionary objects. 80 system. [Goldberg83, p. 10] Only some of them are literal and can be written in Native Smalltalk Values. There are many Values source code directly, like Point (1 @ 2) or Association already available in a standard Smalltalk system. (#a -> 42). This is achieved not by special syntax rec- ognized by the compiler, but by using ordinary binary Immediate Objects. Objects like SmallInteger and operators to create them. Others can be created sending Character are represented by the object pointer di- messages like Rectangle (1 @ 2 extend: 10 @ 5). rectly instead of pointing to a location holding the ob- Often constructors are used to create a Value like: ject. We consider them Values because they are handled with perfect value semantics. Date So for instance a number like 42 exists as 42 in 4 2 newDay: day bytes (including a few bits to specify that the bytes monthNumber: monthIndex should be interpreted as SmallInteger). 4 year: year Immediate objects cannot be distinguished (it does not make sense to ask, which instance of 42 is used). Complex Value Objects. This paper is about com- It is not possible to change 42, since immediate objects plex Values. They are created by constructors, contain are atomic and do not have internal structure. only Values and are immutable and literal. When 42 is printed, it will produce a string '42'. A simple example for a Value is the login data for a This string is understood by the compiler to translate it user account: into the SmallInteger 42. Immediate objects are literal: User the compiler will recreate the object from its printed 6 name: 'guest' representation so we can use them in source code. password: 'guest'. We can describe a Store connection using another Value: Values (with a capital `V') are real objects. A Value is fully specified by its class and the defini- 8 PostgreSQL id: #publicCincom tion of its content. In general, we define Values as im- 10 dbId: #psql_public_cst_2007 mutable composites that can hold other Values in their environment: 'store.cincom...' instance variables. We define a different class for each 12 user: (User kind of Value giving it unique behavior. name: 'guest' As we saw in section 2.1 before, we can also directly 14 password: 'guest'). use some native atomic standard Smalltalk objects as Values. See the next section 2.3, how we convert such Other Values can reference the Store connection: Values into a form consistent with our Values model. Package We distinguish between three functionally different 16 name: 'DateField' types of instance variables regular objects can have: storeId: #publicCincom. • constant | The content of a constant instance vari- A Value can contain lists of other Values: able is initialized once and cannot change. 18 Bug • variable | Variable instance variables can freely be description: 'slow...' assigned from external via setters. 20 urgency: #high • changes: (Array cache | Cache instance variables initialize lazy on 22 with: (IssueEntered first access. Their content