A taste of implicit receivers

One of the features that distinguish Smalltalk from most other languages is the keyword message syntax, and one of those that distinguish Newspeak from Smalltalk are implicit receivers. They work very nicely together to allow writing very readable code. Here is a drag-and-drop related method I just wrote:

createDropTargetFor: session <DragDropSession> ^<DropTarget> = (
	^if: session source
		isMovingMyItem: [createDropTargetForItemMove]
		otherwise: [createClientSuppliedDropTargetFor: session]

What we have here is a method with the selector createDropTargetFor:. The things in angle brackets are type annotations–essentially, optional structured comments telling the reader what the method expects and returns. Unlike Smalltalk, the body of the method is explicitly delimited by “=(” and “)”.

The three message sends in the body have no explicit receivers, which in this case means they are sent to self, self being what any Smalltalker would expect. In the general case, however, because of class nesting there may be a choice of selves available, so the receiver is not necessarily the object whose class contains the method with the send. This is why “implicit receiver” is a more precise term. For details, see Gilad’s On the Interaction of Method Lookup and Scope with Inheritance and Nesting.

Comments (2) left to “A taste of implicit receivers”

  1. emp wrote:


    The only things I think Smalltalk might have gone wrong with syntax are:
    # should have been for comments (and #. to end comments)
    “” should have been for symbol.

    Now upside down :(

  2. emp wrote:

    How about:

    createDropTargetFor: session ^ = (
    ^you if: session source
    isMovingMyItem: [you createDropTargetForItemMove]
    otherwise: [you createClientSuppliedDropTargetFor: session]

    Some benifits by introducing a #you preserved word (which means *my sender*):
    1 Objects will know who sends a message to it
    2 Parts/guests will know the whole/host, the time they are being referred to

    For example, in Squeak:
    DropEvent>>sentTo: anObject
    “Dispatch the receiver into anObject”
    self type == #dropEvent ifTrue:[^anObject handleDropMorph: self].

    could now be:
    “formerly known as #sentTo: anObject”
    “Dispatch the receiver into anObject”
    self type == #dropEvent ifTrue:[^you handleDropMorph”: self” “reciever knows sender so this is not needed anymore”].