Showing posts with label starting Smalltalk. Show all posts
Showing posts with label starting Smalltalk. Show all posts

Friday, 23 October 2015

Pharo By Example, Ch. 3

Compile-time arrays are defined by #( ), surrounding space-separated literals. Everything within the parentheses must be a compile-time constant. For example, #(27 (true false) abc) is a literal array of three elements: the integer 27, the compile-time array containing the two booleans, and the symbol #abc. (Note that this is the same as #(27 #(true false) #abc).)

i.e. Compile-time arrays must contain unique objects - symbols or constants

Only run-time arrays can contain object instances like strings.

Run-time arrays. Curly braces { } define a (dynamic) array at run-time. Elements are expressions separated by periods. So { 1. 2. 1+2 } defines an array with elements 1, 2, and the result of evaluating 1+2.

The curlybrace notation is peculiar to the Pharo and Squeak dialects of Smalltalk! In other Smalltalks you must build up dynamic arrays explicitly.

How do you build up dynamic arrays explicitly?

-----

Local variable definitions. Vertical bars | | enclose the declaration of one or more local variables in a method (and also in a block).

-----

There are 6 reserved keywords, or pseudo-variables: nil, true, false, self, super, and thisContext.

You cannot assign a value to a pseudovariable.

self - the receiver of the currently executing method
super - the superclass of the receiver
(technically, the receiver, but doing method-lookup starting from the receiver's superclass)
nil - the undefined object. It is the unique instance of the class UndefinedObject. Instance variables, class variables and local variables are initialized to nil.
thisContext is a pseudo-variable that represents the top frame of the runtime stack. In other words, it represents the currently executing MethodContext or BlockClosure. thisContext is normally not of interest to most programmers, Message sends 53 but it is essential for implementing development tools like the debugger and it is also used to implement exception handling and continuations.
true and false are the unique instances of the Boolean classes True and False.

-----

Blocks

Code contained between [ and ]

They return the value of the last evaluated expression. (unless there is an explicit return (with ^), in which case it does not answer a value)

Blocks may take parameters. Each parameter is declared with a leading colon.

A vertical bar separates the parameter declaration(s) from the body of the block.

For a block with one parameter, you must send it the message value: with one argument.
For a block with two parameters, you must send it the message value:value:, each with one argument. with two argument.
For a block with three parameters, you must send it the message value:value:value:, each with one argument. 
For a block with four parameters,  you must send it the message value:value:value:value:, each with one argument. 
For a block with more than four parameters, you must send it the message valueWithArguments: and pass the arguments in an array.

A block with a large array of parameters is often the sign of a design issue.

Blocks may also declare local variables, which are surrounded by vertical bars, just like local variable declarations in a method. Locals are declared after any arguments, e.g.
[ :x :y | | z | z := x+ y. z ] value: 1 value: 2
→ 3

Blocks are instances of the class BlockClosure. This means that they are objects, so they can be assigned to variables and passed as arguments just like any other object.

-----

Loops and controls

control constructs are typically expressed by sending messages to booleans, numbers and collections, with blocks as arguments.

(condition)
ifTrue: [  ]
ifFalse: [  ]

[ ] whileTrue: [ ]
[ ] whileFalse: [ ]

nn timesRepeat: [ ]


Iterators

(nn to: nn) do: [ :x | result := result, x printString, ' ' ]

(nn: to nn2:) is a collection - a dynamic array
1 to 10 would give
result -> '1 2 3 4 5 6 7 8 9 10'


= has the same value as

== exactly equal to

(or else it's == and === )

[ n < 1000 ] whileTrue: [ n := n* 2 ].

collect: 

builds a new collection of the same size, transforming each element.

(1 to: 10) collect: [ :each | each * each ]

-> #(1 4 9 16 25 36 49 64 81 100)

select: and reject:
build subset collections

detect:
 returns the first element matching the condition
-----






Friday, 16 October 2015

Starting again, part 2



Basic loops
Loops are high-level collection iterators, implemented as regular methods.  

  to:do:
  to:by:do"

Transcript open.

1 to: 100 do:
  [:i | Transcript show: i asString; cr ]. 

1 to: 100 by: 3 do: [:i | Transcript show: i asString; cr]. 

Iterators
The message do: is sent to a collection of objects (Array, Set, OrderedCollection), evaluating the block for each element.

e.g.
#(11 38 3 -2 10) do: [:each |
     Transcript show: each printString; cr].  "do for each element in the array #(11 38 3 -2 10) and print to the Transcript"

"Some other really nice iterators"

#(11 38 3 -2 10) collect: [:each | each abs].  "collect means do for each and every member ?"

#(11 38 3 -2 10) collect: [:each | each odd].

#(11 38 3 -2 10) select: [:each | each odd].  "add each member that meets the criterion to a new collection?  Or to the subject of the message?"

#(11 38 3 -2 10) select: [:each | each > 10].

#(11 38 3 -2 10) reject: [:each | each > 10]. "remove each member that meets the criterion from the collection?  Or creates a new collection with the subset?"

#(11 38 3 -2 10)
     do: [:each | Transcript show: each printString]
     separatedBy: [Transcript show: '.'].

explore
All objects understand this message.  It opens an information window about the object.  All it's properties.

browse
brings up the Package Browser, which is the Class Browser plus info about packages (groups of classes)






Starting again

Time to retrace my steps, so I am sure I understand code that I read later

Download the PBE-OneClick, and started my way through it

ProfStef lessons 1st, then Pharo By Example, the book

Highlight text in the workspace and Alt-p or rt-click to "print it", and the expression is evaluated, then printed to the workspace.

It stays highlighted, so it is easy to then delete or backspace

Highlight text in the workspace and Alt-d to "do it".  Expression is evaluated.

Messages
Unary - one argument following an object

Binary one argument between two objects

Keyword - as many arguments as you like, each with a keyword preceding it.

Each keyword is suffixed by a colon.  e.g. Gordon middleName: 'Reynolds' lastName: 'Love'.

. (full stop) completes an expression

Precedence:  Unary then binary then keyword, left to right when of equal precedence

Always - even for arithmetic expressions.

Parentheses alter the precedence order

If you end an expression with ; (rather than . ), the subject of the next line is left implicit, and it will be the same as the subject of the line just ended.  This is called a message cascade.

e.g.
Transcript show: 'hello'.
Transcript show: 'Smalltalk'.
Transcript cr.

"is equivalent to:"

Transcript
  show: 'hello';
  show: 'Smalltalk' ;
  cr.

Blocks are
   anonymous methods that can be
      stored as variables and
      executed on demand
   delimited by square brackets [ ]

Here is a block that adds 2 to its argument (its argument is named x):"  :x is, in effect, also the local variable.

[:x | x+2].

"We can execute a block by sending it value messages."

[:x | x+2] value: 5.

[Browser open] value.

[:x | x+2] value: 10.

[:x :y| x + y] value:3 value:5.

Declare a variable, enclose it in | |  e.g.
|b| 

Blocks can be assigned to a variable, and executed later
|b|
b := [:x | x+2].
b value: 12.

Sends '12' into b, which is an object which takes its input and adds 2 to it.



Transcripts are little workpads on the screen
Transcript open.

Conditionals - messages sent to boolean objects

3 > 10 
ifTrue: [Transcript show: 'maybe there''s a bug ....']
ifFalse: [Transcript show: 'No : 3 is less than 10'].