Hacker News new | past | comments | ask | show | jobs | submit login

I've been thinking about this at a meta level and I can't get to reach any conclusion.

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




When languages are consistent, they are much easier to learn. Spanish is fabulously regular, which helps many people learn 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.


When thinking about the API only, any one of your line implementations seems just as good as the other.

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."


If we're going to design our own syntax to draw lines, I'll add a few things to the host language: First, a "point" data type, and a "line" data type. Most language can do this already.

Then 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.


Apropos of nothing much, back when I was coding primarily in Objective-C (incidentally, for cross-platform Linux and Windows, but not anything Apple) the form of the function call would give another much more expressive option. I'd write something like this:

  [drawline  from: A
               to: B];
Obviously, some people hate it.


Objective-C syntax aside, keyword arguments are great for readability and maintainability.


The right answer for a API to draw a line like you describe is to provide every possible way to draw a line since you never know which one the user wants to use. Granularity is one of the general five properties of every good API, of course it is not always good to provide all possible ways since it hurts compactness. The best I have ever heared about API design was a talk from Casey Muratori: http://mollyrocket.com/casey/stream_0028.html


It's not that you want to provide "every possible way to draw a line".. ideally your API provides the primitives necessary for a client to draw lines in all the ways that are useful.

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/>.


For your particular example QBasic was actually a nice way of writing it:

    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 rectangle




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: