anchor.diff:    # the `tr' command except that one character can be replace by multiple
     # ones.  e.g.,
     # replaceChars ["<" ">"] ["&lt;" "&gt;"] "<foo>" returns "&lt;foo&gt;".
  -  replaceChars = del: new: s:
  +  replaceChars = builtins.replaceStrings or (
  +    del: new: s:
       let
         substList = lib.zipLists del new;
         subst = c:
  
positive.code:   # will likely be horribly inefficient; Nix is not a general purpose
    # programming language.  Complex string manipulations should, if
    # appropriate, be done in a derivation.
    stringToCharacters = s: let l = stringLength s; in
      if l == 0
      then []
      else map (p: substring p 1 s) (lib.range 0 (l - 1));
  
  
    # Manipulate a string charcater by character and replace them by strings
    # before concatenating the results.
    stringAsChars = f: s:
      concatStrings (
        map f (stringToCharacters s)
      );
  
  
    # same as vim escape function.
    # Each character contained in list is prefixed by "\"
    escape = list : string :
      stringAsChars (c: if lib.elem c list then "\\${c}" else c) string;
  
  
    # still ugly slow. But more correct now
    # [] for zsh
    escapeShellArg = lib.escape (stringToCharacters "\\ ';$`()|<>\t*[]");
  
  
  
negative.code: 
  rec {
  
    inherit (builtins) stringLength substring head tail isString replaceStrings;
  
  
    # Concatenate a list of strings.
  