Constrained genericity or bounded quantification means
that a parametrized type or function (see parametric polymorphism)
can only be instantiated on types fulfilling some conditions,
even if those conditions are not used in that function.

Say a type is called "eatable" if you can call the function eat on it.
Write a generic type FoodBox which contains a collection of objects of
a type given as parameter, but can only be instantiated on eatable types.
The FoodBox shall not use the function eat in any way (i.e. without the explicit restriction, it could be instantiated on any type).
The specification of a type being eatable should be as generic as possible
in your language (i.e. the restrictions on the implementation of eatable types
should be as minimal as possible).
Also explain the restrictions, if any, on the implementation of eatable types,
and show at least one example of an eatable type.

call dinnerTime "yogurt"
call dinnerTime .pizza~new
call dinnerTime .broccoli~new
 
 
-- a mixin class that defines the interface for being "food", and
-- thus expected to implement an "eat" method
::class food mixinclass object
::method eat abstract
 
::class pizza subclass food
::method eat
  Say "mmmmmmmm, pizza".
 
-- mixin classes can also be used for multiple inheritance
::class broccoli inherit food
::method eat
  Say "ugh, do I have to?".
 
::routine dinnerTime
  use arg dish
  -- ooRexx arguments are typeless, so tests for constrained
  -- types must be peformed at run time.  The isA method will
  -- check if an object is of the required type
  if \dish~isA(.food) then do
     say "I can't eat that!"
     return
  end
  else dish~eat