Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When trying to remove first object, how can I catch an empty LinkedList exception in Smalltalk?

I'm new at Smalltalk and trying not to use if statements! On Python I would write:

try:
   element = LinkedList.remove()
except:
   element = "nil"
finally:
   return element

What is the equivalent in Smalltalk?

like image 683
Agustina Avatar asked Dec 24 '22 21:12

Agustina


1 Answers

Short answer:

^aLinkedList remove: aLinkOrObject ifAbsent: [nil]

Note that in Smalltalk all collections that support the removal of elements also support the remove:ifAbsent: message. The first argument is the element to remove and the second a block that would handle the case where the element is not in the collection.

More generally, the way to handle exceptions in Smalltalk follows the pattern:

[<Smalltalk expression>] on: Error do: [:ex | <handle ex>]

Even more generally, the argument Error can be replaced with any subclass of the Exception hierarchy, meaning that your code will only handle certain kinds of exceptions.

Exception handling is a broad topic in Smalltalk, so consider this answer as a hint to help you write some preliminary Smalltalk code.

EDIT

The answer and comments by @SeanDeNigris made me realize that my answer is incomplete in, at least, one aspect: how do we determine the first element of the list? In fact, the expression that uses remove:ifAbsent: says nothing about the first argument, which the original question identifies as the first element. To complete the answer we have to resolve also this issue.

In a first attempt we could try:

^aLinkedList remove: aLinkedList first ifAbsent: [nil]

But the problem is that the message aLinkedList first will signal an error if the list happens to be empty. In other words, the ifAbsent: part will be useless. So, as Sean suggests, we are left with two alternatives. In the first one we use conditional logic to establish a distinction on whether the list is empty or not:

^aLinkedList isEmpty
    ifTrue: [nil]
    ifFalse: [aLinkedList remove: aLinkedList first]

The second alternative consists in using exceptions:

^[aLinkedList remove: aLinkedList first] on: Error do: [nil]

At this point we are faced with the question of which alternative is better. A good criterion to apply is simplicity. Which solution is simpler? Clearly the first one. Error handling is an advanced capability that uses some non-trivial machinery. The first solution relies on elementary conditional logic. Moreover, what's the point of pretending that we cannot anticipate an exception if we know in advance that the only expected error will happen if the list is empty. In this regard the use of exceptions and on:do: is overkilling and we should avoid it here.

like image 54
Leandro Caniglia Avatar answered May 20 '23 11:05

Leandro Caniglia