code: def memoize(f):
      
      # Determine the location of the cache.
      cache_dirname = os.path.join(_get_xdg_cache_home(), 'proselint')
      legacy_cache_dirname = os.path.join(os.path.expanduser("~"), ".proselint")
  
      if not os.path.isdir(cache_dirname):
          # Migrate the cache from the legacy path to XDG complaint location.
          if os.path.isdir(legacy_cache_dirname):
              os.rename(legacy_cache_dirname, cache_dirname)
          # Create the cache if it does not already exist.
          else:
              os.makedirs(cache_dirname)
  
      cache_filename = f.__module__ + "." + f.__name__
      cachepath = os.path.join(cache_dirname, cache_filename)
  
      @functools.wraps(f)
      def wrapped(*args, **kwargs):
  
          # handle instance methods
          if hasattr(f, '__self__'):
              args = args[1:]
  
          signature = (f.__module__ + '.' + f.__name__).encode("utf-8")
  
          tempargdict = inspect.getcallargs(f, *args, **kwargs)
  
          for item in list(tempargdict.items()):
              signature += item[1].encode("utf-8")
  
          key = hashlib.sha256(signature).hexdigest()
  
          try:
              cache = _get_cache(cachepath)
              return cache[key]
          except KeyError:
              value = f(*args, **kwargs)
              cache[key] = value
              cache.sync()
              return value
          except TypeError:
              call_to = f.__module__ + '.' + f.__name__
              print('Warning: could not disk cache call to %s;'
                    'it probably has unhashable args. Error: %s' %
                    (call_to, traceback.format_exc()))
              return f(*args, **kwargs)
  
      return wrapped
docs: Cache results of computations on disk.