text: #>>>>>>>>>> Icon example of recursive generator >>>>>>>>>
  ##procedure star(chars)
  ##   suspend "" | (star(chars) || !chars)
  ##end
  ##
  
  class bang(object):
      """ a generator with saved state that can be reset """
      def __init__(self, arg):
          self.arg = arg
          self.reset()
      def __iter__(self):
          for item in self.iterable:
              yield item
      def next(self):
          return self.iterable.next()
      def reset(self):
          if  hasattr(self.arg, '__iter__') and \
                  hasattr(self.arg, 'next') :
              self.iterable = self.arg
          elif hasattr(self.arg, '__getitem__'):
              if self.arg:
                  self.iterable = iter(self.arg)
              else: self.iterable = iter([""])
          else:
              self.iterable = iter([self.arg])
      def __repr__(self):
          return repr(self.arg)
  
  def alternation( *items ):
      """Lazy evaluation that flattens input items """
      for alt_item in items:
          if hasattr(alt_item, '__iter__'):
              #flatten generator item
              for item in alt_item:
                  yield item
          else:
              yield alt_item
      
  def concatenate(g1, g2):
      """Lazy evaluation concatenation """
      #list, tuple, and string iterators are not used implicitly
      #Not generalized for sequences other than strings
      if hasattr(g1, '__iter__') and hasattr(g2, '__iter__'):
          #concatenations of left items to right items
          #map(operator.plus, leftseq, rightseq)
          for x in g1:
              g2.reset()
              for y in g2:
                  yield x + y
      elif hasattr(g1, '__iter__') :
          #concatenations of left items to right sequence
          #map(operator.plus, [leftseq]*len(rightseq), rightseq)
          for x in g1:
              yield x + g2
      elif hasattr(g2, '__iter__') :
          #concatenations of left sequence to right items
          #map(operator.plus, leftseq, [rightseq]*len(leftseq))
          for x in g2:
              yield g1 + x
      else:
          #string concatenation like Python
          yield g1 + g2
  
  def star(chars):
      """ Recursive, infinite generator for all permutations
          of a string taken 1 to N characters at time """
      for item in alternation("", concatenate(star(chars),  bang(chars))):
          yield item
  
  #star test >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  chars = 'abc'
  limit = 3 # Limit infinite recursion
  for n, x in enumerate(star(chars)):
      if len(x) > limit: break
      print n+1, repr(x)
  