Ralph Johnson, a member of the Gang of Four, once showed how the syntax of Smalltalk-80 can fit on a postcard. Now, almost 30 years after the appearance of the first version of Smalltalk, the fastest growing dialect of Smalltalk is Pharo, whose postcard will be further analyzed.
exampleWithNumber: x
Methods are declared as :
and are members of the class. A method with multiple parameters is declared as
rangeFrom: start to: end
The method name here is rangeFrom:to:
and the parameter names are start
and end
.
<syntaxOn: #postcard>
Pragma is used to annotate a method. This annotation can be used by the compiler or other methods as metadata.
"A ""complete"" Pharo syntax"
Comments are indicated by quotes. Quotes inside a comment are indicated by double quotes.
| y |
Local variables are used in calculations inside the method. Variable type declarations are not required because Smalltalk is a dynamically typed language.
Multiple variables are declared in one list.
| yx totalSum |
true & false not & (nil isNil)
Everything in Smalltalk is objects, and objects can receive messages. The order of execution (that is, the sending of messages) is from left to right, but messages without parameters are sent first of all in accordance with the priority rules, so the calculation order here will be
(true & (false not)) & (nil isNil)
There are only four priority rules in Smalltalk: the first messages are sent in parentheses, then unary (no additional parameters besides the receiving object itself, for example false not
), then binary ones (with one additional parameter, for example 1 + 2
), then messages with several parameters (for example, 15 between: 1 and: 2
). The priority of execution is indicated by a simple scheme.
brackets > unary > binary > messages with multiple parameters
These rules also apply to mathematical operations, so the result of the expression
1 + 15 / 4 " = (1 + 15) / 4 "
will be 4
. By the way, nil
also an object and can receive and respond to messages.
true & false not & (nil isNil) ifFalse: [ self perform: #add: with: x ].
Conditional execution is implemented by sending messages ifTrue
, ifFalse
to a logical value object. The argument of this message is a code block, indicated by square brackets, that is executed if the specified condition is met.
Smalltalk blocks are also used as anonymous functions:
sum := [ :x :y | x+y ]. " x,y -> x+y " sum value: 10 value: 25. " , - 35"
self perform: #add: with: x
The self
keyword is used as a reference to an object containing a method when sending messages to the object itself. Here we send the message perform: with: with arguments #add
and x
. The #
sign indicates a literal string, which is used here as a method identifier.
y := thisContext stack size + super size.
Variable assignment is denoted by the operator :=
. The super keyword is used to refer to a superclass object.
All Smalltalk objects inherit from either the Object
class, or from their superclass, which, in turn, inherits from its superclass or from the Object
class.
byteArray := #[2 2r100 8r20 16rFF].
byteArray
is a class instance variable declared when the class is declared. The byteArray array consists of integers written in different number systems in the form
<>r<>
The size of static arrays is fixed and set at compile time. Array indexing starts at 1
byteArray at: 2 " = 2r100 "
From the very beginning, Smalltalk was not only a language, but also an integrated development environment with its virtual machine: Smalltalk classes and methods are not stored in separate text files, but are immediately stored in the virtual machine image and declared through the development environment interface. For example, the class Counter
declared in the class section as
Object subclass: #Counter instanceVariableNames: 'count initialValue' classVariableNames: '' package: 'MyCounter'
and its methods are declared in the methods section of the Counter
class.
{ -42 . #($a #a #'I''m' 'a' 1.0 1.23e2 3.14s2 1) }
A dynamic array is created during program execution.
Arrays can contain data of different types: the first element of the array is the number -42, the second element of the array is an array with elements of different types:
$a
- the character "a"#a #'I''m'
- literal strings "a" and "I'm"'a'
- string "a"1.0 1.23e2
- floating point numbers3.14s2
- decimal fraction with a scale of 2 { -42 . #($a #a #'I''m' 'a' 1.0 1.23e2 3.14s2 1) } do: [ :each | | var | var := Transcript show: each class name; show: each printString ].
Loops in Smalltalk are implemented by sending a message to an array with a block that will be executed on each element of this array, which is very similar to the functional approach. At each iteration, the array element is passed as an argument to the block that performs some calculations on it. In the block in the example, the local variable var is declared, which is assigned the result of sending the last show message to the global Transcript
object.
An interesting feature of Smalltalk is the possibility of cascading messages: an expression
Transcript show: 'A'; show: 'B'.
sequentially outputs lines A
and B
to the Transcript
console window. This is equivalent to code.
Transcript show: 'A'. Transcript show: 'B'.
but avoids repeating the name of the transcript message receiving object. The result of cascading is the response of the object to the last message.
Return values from method
^ x < y
Returning a value is indicated by a ^
. In this case, a logical value is returned - the result of comparing x < y
.
Source: https://habr.com/ru/post/446578/
All Articles