You wrote "In general reversed/converse has no meaning for block."
That's entirely an artefact of representing blocks of different
arities by the same class.  In my own Smalltalk, NiladicBlock,
MonadicBlock, DyadicBlock, ... are different classes.  To put it
another way, your statement has exactly the same status as
"In general #value:value: has no meaning for block."
#converse has meaning for *all* DyadicBlocks, it is the
combinator flip f x y = f y x.  For that matter, it could
be generalised to all blocks of arity >= 2 as
[:a1 :a2 ... :an | body] converse
=> [:a2 :a1 ... :an | body]
i.e., flip the first two arguments.

My original implementation of #converse was
DyadicBlock
  methods for: 'combinators'
    converse
      ^[:x :y | self value: y value: x]
    "other combinators"

With a suitable set of combinators, I can do things like
#name ascending thenBy: #age descending thenBy: #weight ascending nilsFirst
without needing a SortFunction class.

​I do like the fact that SortFunction can support both 2-way and 3-way​
comparison.

Reply via email to