The Little Manual of API Design (2008) [pdf]
www4.in.tum.de
www4.in.tum.de
Think of a simple instruction: draw a line from (a,b) to (c,d).
How many ways can it be "encoded as an API"? we already have a gazillion forms of drawing: SVG, OpenGL, Postscript, Asymptote, PGF/Tikz, Canvas, and so on. Why?
Forget about existing line-drawing APIs. Which of these would you choose?
- line(a,b,c,d)
- Line (a,b) to (c,d)
- draw-line (a,b) (c,d)
- drawline
- make-a-line
- line-from-to
- ...
- ...
Not to mention placement of parentheses (C vs s-expression), curly braces or angle bracket. The list goes on.
I started reading Bertrand Russell's 'On Denoting' but I'm not really sure it'll help me out (although I haven't finished reading it yet).
At another level: once you've converted your vector graphics primitive to "pixel maps", that itself is no less of a language. So at a more fundamental level, it's really information represenation, not language.
I'm not sure where the problem is, language vs computable-form vs information-representation.
Not to mention metalinguistics. Because API is not just one layer on top of your program. You build an API/language layer as a scaffolding, to use it to build a higher level API/language layer. And apparently its turtles all the way up and all the way down.
It's all very confusing
But if you also ask "which of these makes sense for the client application" that will likely narrow your options down.
Indeed, the parent PDF says that before even writing any code, write use cases. "The implementation should adapt to the user, not the other way around."
The primitives that you provide relate to the overall goal of your API. Do you want people to use it for mathematical graphing? Will they start with an equation? Or is this for a website, where all you really want is <hr/>.
[drawline from: A
to: B];
Obviously, some people hate it.When a second language is similar to your native tongue, it is much easier. Swedish speakers have very little trouble learning Danish, but Turkish is a bunch harder, and Korean is _very_ tough.
My point here is that your example is difficult because it lacks any larger context. If you want your API to be easy to learn for Lispers, then s-expressions are going to be better. If the rest of your API uses verbs like "make-a-box" and "paint-the-background", then "make-a-line" is probably the right fit.
Design always works this way: it is defined by its users and its context. When you hit trouble like this, step back.
LINE (a,b)-(c,d), colour
On the other hand, they went nuts with it and had ways of making rectangles with the same syntax, too: LINE (a,b)-(c,d), colour, B ' Rectangle
LINE (a,b)-(c,d), colour, BF ' Filled rectangleThen I'd add some special syntax to denote points. Like one of those:
(a, b) -- ordinary tuple. Of the shelf in ML and Haskel.
[a, b] // may work in C and C++
(a; b) // Alternative syntax
We also need an operator to draw the line. Possibly a triple dash: (a, b) --- (c, d)
And of course this can be combined together (here in my custom version of C): Point p = (a; b);
Line l = p --- (c; d);
Now we need a way to actually draw the line. As a side effect. It could be a procedure, but when there's one line, there will be others. So, we often need to draw a list of lines. This syntax might work: draw {
p --- (c; d);
(e; f) --- (g;h);
(g; h) --- p;
}
The semantics would be what you'd expect, with the possible benefits of some optimisation (some constructors can be avoided, the data can be packed before we draw all the lines at once…)---
Now If I get to really try that in a real-world project, I'll probably find many ways to improve this lousy design.
the <b>goto <u>label</b></u> statement
What sort of demonic possession bullshit going on here? Who is "encouraged" to do such thing? <u>Underlined. <b>Bold and underlined.</u> Bold only.</b>
Why shouldn't that work?Though I'm not sure sure if the HTML / TeX comparison is the best to exemplify the concept. I feel that if a beginner were to make the conceptual mistake that HTML tags are not nested that they may also not grasp that {}'s are to be nested as well. Thus falling into the same trap as HTML.
I'll admit that {}'s look more obvious to form a nested structure but it may also be that my eyes are trained to see them exactly as such.
One advice in this pdf is that on designing first before implementing. I think iterative cycles of design / implement / use / design /implement use yield better results.
Personally, when it comes to APIs, you can tell those that have been designed upfront rather than iteratively; they are generally better IMHO.
If you have an API that does something well known, find and learn from existing APIs that do that. If not, then he prepared for lots of trial and error, scenarios you didn't think of, and so on. It might make sense to put out a "worse is better" API first so the learning and feedback loops can start.
We often change our point of view on how to solve a problem (private part), but rarely the problem itself changes (public part).
Iterate away your (internal) architecture as much as you want, but when dealing with the API (your external world interface) make sure to put yourself in your user shoes.