brandonbloom / fipp

Fast Idiomatic Pretty Printer for Clojure
525 stars 44 forks source link

emit-document, defemitter, :data op, multimethods #14

Closed micha closed 10 years ago

micha commented 10 years ago
(def doc
  [:group [:data {:type :symbol, :text "map"}]
          [:line]
          [:data {:type :symbol, :text "capitalize"}]
          [:line]
          [:data {:type :string, :text "\"abcdef\""}]])

(emit-document doc {:width 4})
brandonbloom commented 10 years ago

Hey Micha, I'm swamped with work at the moment, so I don't have time to really dig in to this, but after a quick peek... It looks like there are some refactoring and at least 2 new features mixed in here? Can you explain/motivate any new features and separate them out in to isolated commits so that we can look at refactorings separately from features?

brandonbloom commented 10 years ago

Also, multimethods are notoriously slow, but that probably only really applies for class-based dispatch. What's the perf impact of these changes?

micha commented 10 years ago

Motivation

The biggest job that fipp does is to compute where and how to insert whitespace in a document. The actual printing to the screen is secondary. The emit-document function and defemitter macro facilitate using fipp as a document->document transformation instead of using it just to produce side effects (printing to the screen or a string buffer).

Related to this document transformation use case is the situation where you are not simply dealing with strings. Like in the example above, I have objects that include other information in addition to the actual text (the type of atom, for example, so it can be rendered in a special way later). Adding the :data op allows you to use these richer types in a fipp document.

Finally, in order to make it easier to extend fipp, and specifically to add the :data op without spaghetti-ing up the case analysis, I added multimethods to delegate computing an atom's length (how many columns it would consume) and formatting. With these multimethods in place people can add ops without making pull requests to you :)

Perf

No idea. How do you benchmark fipp?

brandonbloom commented 10 years ago

You can do a pretty naive benchmark by running the contents of lightening.clj in your repl from this branch I just pushed: https://github.com/brandonbloom/fipp/tree/lightening

I've been meaning to put together a proper benchmark suite...

brandonbloom commented 10 years ago

@micha if you still want these changes, please open separate tickets for the separate parts.