code: public static Printer newPrinter(final Protocol<Printer.Fn<?>> fns,
              final Appendable out) {
          return new Printer() {
              int softspace = 0;
  
              public void close() {
                  if (out instanceof Closeable) {
                      try {
                          ((Closeable)out).close();
                      } catch (IOException e) {
                          throw new EdnIOException(e);
                      }
                  }
              }
  
              public Printer append(CharSequence csq) {
                  try {
                      if (softspace > 1 && csq.length() > 0 &&
                              !CharClassify.isWhitespace(csq.charAt(0))) {
                          out.append(' ');
                      }
                      softspace = 0;
                      out.append(csq);
                      return this;
                  } catch (IOException e) {
                      throw new EdnIOException(e);
                  }
              }
  
              public Printer append(char c) {
                  try {
                      if (softspace > 1 && !CharClassify.isWhitespace(c)) {
                          out.append(' ');
                      }
                      softspace = 0;
                      out.append(c);
                      return this;
                  } catch (IOException e) {
                      throw new EdnIOException(e);
                  }
              }
  
              public Printer printValue(Object ednValue) {
                  @SuppressWarnings("unchecked")
                  Printer.Fn<Object> printFn = (Printer.Fn<Object>)
                  fns.lookup(getClassOrNull(ednValue));
                  if (printFn == null) {
                      throw new EdnException(String.format(
                              "Don't know how to write '%s' of type '%s'",
                              ednValue, getClassOrNull(ednValue)));
                  }
                  printFn.eval(ednValue, this);
                  return this;
              }
  
              public Printer softspace() {
                  softspace += 1;
                  return this;
              }
  
          };
      }
docs: Return a new Printer with the printing protocol given as {@code
  fns}. Everything the printer prints will be appended to {@code
  writer}. {@link Printer#close()} will close {@code out}, if
  {@code out} implements {@link Closeable}.
  
  @param fns a Protocol which knows how to print all the classes
  of objects that we'll be asking our Printer to print.
  Never null. Never null.
  @param out to which values will be printed. Never null.
  
  @return a Printer, never null.