﻿WEBVTT

00:00:00.000 --> 00:00:02.160 align:middle
In this session, I'll introduce blocks.

00:00:02.320 --> 00:00:06.640 align:middle
They're sort of anonymous methods
also called lexical closures.

00:00:06.800 --> 00:00:08.720 align:middle
They're everywhere in Pharo.

00:00:08.880 --> 00:00:12.160 align:middle
They're the base of loops,
conditionals, iterators,

00:00:12.320 --> 00:00:14.680 align:middle
and even GUIs or dedicated languages.

00:00:14.840 --> 00:00:17.120 align:middle
They're at the heart of the system.

00:00:17.280 --> 00:00:21.280 align:middle
They've only been introduced
in the latest version of Java.

00:00:23.000 --> 00:00:27.400 align:middle
To define a block, use square brackets.

00:00:27.560 --> 00:00:28.920 align:middle
This an example:

00:00:29.080 --> 00:00:32.760 align:middle
[expressions...]

00:00:34.840 --> 00:00:37.840 align:middle
We'll talk about block definition.

00:00:38.000 --> 00:00:40.000 align:middle
Another example:

00:00:40.160 --> 00:00:42.840 align:middle
this expression, 1/0,

00:00:43.000 --> 00:00:46.760 align:middle
returns an error when executed.

00:00:47.760 --> 00:00:50.600 align:middle
Let's encapsulate it in a block

00:00:50.760 --> 00:00:54.920 align:middle
by defining a block that contains
the expression 1/0.

00:00:55.080 --> 00:01:00.040 align:middle
If I evaluate this block's definition,
nothing happens: no error.

00:01:00.200 --> 00:01:02.400 align:middle
It returns the block

00:01:02.560 --> 00:01:06.160 align:middle
as a block definition
doesn't execute its body.

00:01:07.720 --> 00:01:11.480 align:middle
You can define as many blocks
as you wish:

00:01:11.640 --> 00:01:14.240 align:middle
the expressions in its body are frozen.

00:01:15.240 --> 00:01:18.560 align:middle
To evaluate a block
and the expressions in its body,

00:01:18.720 --> 00:01:21.760 align:middle
you must do it explicitly
through the message value.

00:01:21.920 --> 00:01:24.520 align:middle
For instance, this is a block:
[2 + 6]

00:01:24.680 --> 00:01:26.640 align:middle
You send it the message value.

00:01:26.800 --> 00:01:29.760 align:middle
The expressions in the body
are evaluated.

00:01:29.920 --> 00:01:33.360 align:middle
It returns the result, 8.

00:01:34.320 --> 00:01:37.760 align:middle
However, if the block
contains erroneous expressions,

00:01:37.920 --> 00:01:40.960 align:middle
the error is returned
when the block is evaluated,

00:01:41.120 --> 00:01:42.720 align:middle
as in the example 2.

00:01:42.880 --> 00:01:46.560 align:middle
[1/0]: I send the message value
to the block.

00:01:46.720 --> 00:01:48.400 align:middle
It returns an error.

00:01:49.760 --> 00:01:52.960 align:middle
Blocks can also take arguments

00:01:53.120 --> 00:01:56.240 align:middle
as in this argument.
It's just like methods.

00:01:56.400 --> 00:02:01.400 align:middle
A block is always opened by [

00:02:01.560 --> 00:02:03.120 align:middle
and closed by ].

00:02:03.280 --> 00:02:08.360 align:middle
All the arguments are prefixed
by a colon.

00:02:08.520 --> 00:02:11.760 align:middle
Then there's |, a pipe.

00:02:11.920 --> 00:02:16.240 align:middle
It separates the argument declaration
from the block's body,

00:02:16.400 --> 00:02:18.200 align:middle
the expressions it contains.

00:02:18.360 --> 00:02:21.560 align:middle
The argument in this example is x.

00:02:21.720 --> 00:02:24.360 align:middle
x + 2 is the only expression
in the block.

00:02:24.520 --> 00:02:27.120 align:middle
If I send the message value
to the block,

00:02:27.280 --> 00:02:31.040 align:middle
you have to use a specific message,
value: with a parameter.

00:02:31.200 --> 00:02:35.600 align:middle
At the same time, you pass the value 5
which replaces the argument x

00:02:35.760 --> 00:02:38.560 align:middle
when the expressions of the block
are evaluated.

00:02:38.720 --> 00:02:42.880 align:middle
If I send the message value: 5
to this block,

00:02:43.040 --> 00:02:44.400 align:middle
it returns 7

00:02:44.560 --> 00:02:48.160 align:middle
since the value of x is 5
when the block is evaluated.

00:02:48.800 --> 00:02:50.680 align:middle
This is like my previous example,

00:02:50.840 --> 00:02:55.200 align:middle
but with several expressions
in the block.

00:02:55.360 --> 00:02:58.720 align:middle
I have two here: x+33 and x+2.

00:02:58.880 --> 00:03:01.400 align:middle
When I send value: 5

00:03:01.560 --> 00:03:04.680 align:middle
to evaluate the expressions
in the block,

00:03:04.840 --> 00:03:07.600 align:middle
the evaluation returns

00:03:07.760 --> 00:03:12.120 align:middle
only the value of the last expression
in the block.

00:03:12.280 --> 00:03:16.200 align:middle
It only returns the result of x+2,

00:03:16.960 --> 00:03:17.960 align:middle
7.

00:03:19.640 --> 00:03:22.480 align:middle
Blocks are normal objects in Pharo.

00:03:22.640 --> 00:03:25.120 align:middle
They can be stored
in temporary variables.

00:03:25.280 --> 00:03:28.160 align:middle
They can be sent messages
like normal objects.

00:03:28.320 --> 00:03:31.120 align:middle
This is the example I have for you here.

00:03:31.280 --> 00:03:35.160 align:middle
You can store the definition
of this block, x+2,

00:03:35.320 --> 00:03:37.080 align:middle
in a variable called add2.

00:03:37.240 --> 00:03:40.680 align:middle
Then you send messages
to evaluate the block several times.

00:03:40.840 --> 00:03:43.000 align:middle
I send the message value: once

00:03:43.160 --> 00:03:46.640 align:middle
by telling it to evaluate itself
with the value 5: it returns 7.

00:03:46.800 --> 00:03:49.720 align:middle
Then the message value: 33.

00:03:49.880 --> 00:03:51.920 align:middle
It returns 35.

00:03:52.080 --> 00:03:55.800 align:middle
You can also define blocks
with several arguments.

00:03:55.960 --> 00:04:00.720 align:middle
For instance, x and y.
This block has two arguments.

00:04:00.880 --> 00:04:05.160 align:middle
But how would you evaluate this block

00:04:05.320 --> 00:04:09.840 align:middle
since you need to pass two values
to trigger its evaluation,

00:04:10.000 --> 00:04:13.200 align:middle
5 and 7 which would replace x and y?

00:04:13.840 --> 00:04:19.040 align:middle
The answer is that you use
the message value: value:,

00:04:19.760 --> 00:04:22.760 align:middle
a method of the class block.

00:04:22.920 --> 00:04:28.080 align:middle
5 replaces x and 7 replaces y.

00:04:28.240 --> 00:04:29.880 align:middle
It returns 12.

00:04:32.880 --> 00:04:36.960 align:middle
Like methods, blocks
can also define temporary variables.

00:04:37.120 --> 00:04:40.680 align:middle
This example is an actual example:

00:04:40.840 --> 00:04:43.360 align:middle
it comes from the class Collection.

00:04:43.520 --> 00:04:47.880 align:middle
The block starts here.
It ends there.

00:04:48.880 --> 00:04:52.800 align:middle
It takes one argument called :index.

00:04:53.800 --> 00:04:57.520 align:middle
It takes one temporary variable
defined here between two |.

00:04:57.680 --> 00:04:58.960 align:middle
It's called args.

00:04:59.760 --> 00:05:02.200 align:middle
This temporary variable args

00:05:02.360 --> 00:05:07.160 align:middle
exists only during the evaluation
of the expressions in the block.

00:05:09.080 --> 00:05:11.920 align:middle
Blocks are defined in methods.

00:05:12.080 --> 00:05:16.240 align:middle
In a block, you can also use a return.

00:05:16.400 --> 00:05:20.600 align:middle
This is an example
from the class Integer.

00:05:20.760 --> 00:05:23.280 align:middle
The method is called factorial.

00:05:24.040 --> 00:05:27.960 align:middle
There are several blocks in the method.

00:05:28.120 --> 00:05:31.760 align:middle
These blocks contain returns, or ^.

00:05:31.920 --> 00:05:35.720 align:middle
The return helps
to exit the method factorial.

00:05:35.880 --> 00:05:39.600 align:middle
For instance, if I send the message
factorial to the integer 0,

00:05:39.760 --> 00:05:41.640 align:middle
it returns the answer 1.

00:05:41.800 --> 00:05:46.880 align:middle
I get this answer thanks to this ^,
the first in the block,

00:05:47.040 --> 00:05:49.640 align:middle
which helps
to exit the method factorial.

00:05:49.800 --> 00:05:52.920 align:middle
A return in a block helps
to exit the method

00:05:53.080 --> 00:05:54.960 align:middle
which defines the block.

00:05:56.680 --> 00:05:59.360 align:middle
A piece of advice
for when you use blocks:

00:05:59.520 --> 00:06:02.400 align:middle
blocks are extremely powerful elements.

00:06:02.560 --> 00:06:04.480 align:middle
You must use them carefully.

00:06:04.640 --> 00:06:08.440 align:middle
Don't go beyond two to three arguments
for one block.

00:06:08.600 --> 00:06:11.320 align:middle
If you have more,
it becomes incomprehensible.

00:06:11.480 --> 00:06:15.280 align:middle
It's better to define a class
with instance variables and methods:

00:06:15.440 --> 00:06:17.200 align:middle
it'll be much more legible.

00:06:17.960 --> 00:06:22.160 align:middle
In the course, we studied blocks,
their syntax,

00:06:22.320 --> 00:06:25.600 align:middle
the fact they were some sort
of anonymous methods,

00:06:25.760 --> 00:06:27.800 align:middle
that is, lexical closures;

00:06:27.960 --> 00:06:31.960 align:middle
they can be stored in variables
as they're like any other object.

00:06:32.120 --> 00:06:37.400 align:middle
In other lessons, we'll see that blocks
are the basis of many constructions

00:06:37.560 --> 00:06:40.440 align:middle
such as loops, iterations, etc.