code: def describe(self):
          
          #Interfaces are tricky because we can have an arbitrary number of embedded procedures
          #that each have different calling interfaces and return types. We are trying to 
          #summarize that information in a single interface. Interfaces can't mix executable
          #types; they are either all subroutines or all functions. 
          self.find_docstring()
          if not self.subroutine:
              #We have a return type to worry about, compile it from all the targets
              ret_type = []
              for target in self.targets:
                  if target.returns not in ret_type:
                      ret_type.append(target.returns)
  
              ret_text = ', '.join(ret_type)
          else:
              ret_text = ""
  
          #The list of types it accepts is constructed the same way for functions and subroutines.
          act_type = []
          for target in self.targets:
              param = target.ordered_parameters[0]
              if param.strtype not in act_type:
                  act_type.append(param.strtype)
  
          act_text = ', '.join(act_type)
  
          if self.subroutine:
              return "SUMMARY: {} | ACCEPTS: {}".format(self.summary, act_text)
          else:
              return "SUMMARY: {} | RETURNS: {} | ACCEPTS: {}".format(self.summary, ret_text, act_text)
docs: Returns a home-grown description that includes a summary of the calling interface
          for all the module procedures embedded in this interface.