📜 ⬆️ ⬇️

A programming language that fits on a postcard

image
A source


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.


Method declaration


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 .


Pragma declaration


 <syntaxOn: #postcard> 

Pragma is used to annotate a method. This annotation can be used by the compiler or other methods as metadata.


Comments


 "A ""complete"" Pharo syntax" 

Comments are indicated by quotes. Quotes inside a comment are indicated by double quotes.


Local variable declaration


 | 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 | 

Objects and Messages


 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.


Conditional execution and code blocks


 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" 

Send messages to yourself


 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.


Variable assignment


 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.


Static array


 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.


Dynamic array


 { -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:



Cycles


 { -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