Leaning Smalltalk - how to modify BlockContexts

Brian Murphy-Dye brian.murphydye at mac.com
Sun Jun 13 23:36:45 UTC 2004


You raise interesting questions which I can't answer, but here is a 
simple solution that doesn't require any meta language tricks:

multipleBlock := [:a :b | a * b].
doubles := [:a | multipleBlock value: a value: 2].
x := doubles value: 12

Brian.


On Jun 13, 2004, at 5:13 PM, Edouard Poor wrote:

> 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