Is it OK to leave the [ and ] out for messages like at:ifAbsent: if you don't need a full block?

368 Views Asked by At

In Smalltalk (and specifically Pharo/Squeak) I want to know if it is OK to leave out the "[" and "]" for the argument to messages like at:ifAbsent: if you don't need a block, like this;

^ bookTitles at: bookID ifAbsent: ''.

and

^ books at: bookID ifAbsent: nil.

the code works because (in Pharo/Squeak) Object>>value just returns self. But I want to know how accepted this use is or if you should always type the [ and ] even when you don't care if the argument is evaluated quickly or more than once.

5

There are 5 best solutions below

0
On

I would say that it is not a good idea to leave them out. The argument will be evaluated eagerly if you leave out the parens, and will be sent #value. So if "slef doSomething" has side-effects, that would be bad. It could also be bad if #value does something you don't expect e.g. the perhaps contrived

bookTitles at: bookID ifAbsent: 'Missing title' -> 'ISBN-000000'

4
On

This is what Pharo’s Code Critics say about similar situations:

Non-blocks in special messages:

Checks for methods that don't use blocks in the special messages. People new to Smalltalk might write code such as: "aBoolean ifTrue: (self doSomething)" instead of the correct version: "aBoolean ifTrue: [self doSomething]". Even if these pieces of code could be correct, they cannot be optimized by the compiler.

This rule can be found in Optimization, so you could probably ignore it, but i think it is nicer anyway to use a block.

Update:

at:ifAbsent: is not triggered by this rule. And it is not optimized by the compiler. So optimization is no reason to use blocks in this case.

0
On

If your code works and you are the only person to view the source, then its ok. If others are to view the source then I would say a empty block [] would have been more readable. But generally speaking if you really care about bugs its a good idea not to venture outside standard practices because there is no way to guarantee that you wont have any problem.

0
On

Not all Smalltalk dialects implement #value on Object out of the box, so your code might not run on other Smalltalk dialects, IF you hand in an object that does not understand #value.

It is okay to pass objects of whatever kind as long as you know that what #value does is what you expect,

Your code may look strange to people who come from other smalltalk dialects or are new to Smalltallk, because they learned that what you pass in here is a Block, but so does sending messages like #join: to a Collection of Strings...

In the end, I'd say don't worry if portability is not a major issue to you.

0
On

The signature:

at: key ifAbsent: aBlock 

declares an intention of using a block as a 2nd parameter... But Smalltalk is not a strongly typed language, so, what kind of objects can you pass there? any kind that understand the message #value, so, be careful about each particular meaning of #value in each case, but take advantages of polymorphism!