Leaning Smalltalk - how to modify BlockContexts

Edouard Poor edouard.lists at gmail.com
Sun Jun 13 23:13:27 UTC 2004


Gidday - I'm new to Smalltalk, but have been playing around with
Squeak for the last month or so. Congrats to everyone involved in the
project - it's both very comprehensive, and extremely easy to start
using.

As a learning excercise I've been mentally translating what I'm used
to in C++ into Smalltalk, and have been very impressed so far at the
power of the language - until I wanted to start manipulating
BlockContext objects.

The idea I wanted to use from C++ (well, from STL, so it has a more
functional origin) was that of binding arguments in a BlockContext in
order to create a new BlockContext with one or more of the arguments
fixed with a binding.

e.g. (in C++)

int multiple( int a, int b ) { return a * b );
function<int, int> doubles = bind( multiple, _1, 2 );
x = doubles( 12 );   // x equals 24

So we have a function (or it can be a C++ object) that takes two
parameters, and we bind the second parameter to "2", making an object
that takes one parameter (and multiples it by 2). The _1 indicates
that the first argument is still unbound.

So what am I looking for in Smalltalk?

Something like

multipleBlock := [ :a :b | a * b ].
doubles := multipleBlock bindSecond: 2.
x := doubles value: 12.   " x equals 24"

C++ gives a few binding options - the older "bind1st()" and
"bind2nd()", and the newer bind(...) calls with fixed and free
parameters (e.g. bind( _1, 100, "string", _1, _2 ) )

Just to test whether something basic would work I added
BlockContext>>bindSecond to my image as:

bindSecond: second
| newBlock |
self numArgs < 2 ifTrue: [ self error: 'Block has less than two parameters' ].
newBlock := [ :first | self value: first value: second ].
^ newBlock.

This made my little code example with the multipleBlock being
converted into doubles work fine. And that's where I started to run
out of knowledge in Smalltalk and Squeak.

When I tried to make a more general version that would work with any
block, regardless of the number of parameters, and would work with
'valueWithArguments:' as well as 'value:value: ...' I started running
into primitives rather than code I could easily change.

Also I'm not sure what to do with the home context - I'd like the new
block to have the same home as the original it is binding, but when I
tried simple assignment things started giving backtraces.

So my questions are:

1/ Is BlockContext something I cannot easily change without changing
the primitives in Squeak?

2/ How can I, at least in my simple bindSecond attempt above, make the
new BlockContexts home the same as the original?

3/ Since no-one has added ways of binding arguments in Smalltalk
before now, I assume that it's just not a pattern that is used - is
that correct? Are there other ways of passing simple actions around
and being able to manipulate them?

(I'm using Squeak 3.6beta5 on a Mac OS X laptop and all the code above
is from memory - sorry if I've made any typos)

Cheers,
Edouard.



More information about the Squeak-dev mailing list