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

5

7

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.

Optics answered 1/2, 2014 at 10:38 Comment(0)
Y
4

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!

Yurikoyursa answered 5/2, 2014 at 13:51 Comment(0)
W
2

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.

Wordsmith answered 1/2, 2014 at 12:23 Comment(4)
But the compiler doesn't treat at:ifAbsent: specially like ifTrue: and using at:ifAbsent: in this way doesn't trigger that Critic.Optics
Hm, i just tried some things and couldn’t see any big difference in execution time. I’m curious if there are other answers. Interesting question..Wordsmith
To me the comment of CodeCritics in Pharo is wrong for methods where there is no Compiler optimization. In case of ifTrue: or ifNil:, the tool is correct, but not for many of the methods that "usually" accept a block, but then simply send #value to it.Cesium
But this was my mistake. at:ifAbsent: is not triggered by this rule. I just (wrongly) assumed, it would be a similar situation. I updated the answer.Wordsmith
C
2

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.

Cesium answered 2/2, 2014 at 12:29 Comment(0)
E
1

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'

Excide answered 2/2, 2014 at 6:40 Comment(0)
M
0

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.

Moiramoirai answered 2/2, 2014 at 11:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.