lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Fri, Dec 14, 2012 at 10:10 PM, Andrew Starks <andrew.starks@trms.com> wrote:
> Some opinions that I have about API writing that will sound
> authoritative, but don't have a right to be ( I sound authoritative to
> beat my own bad habits back):
>
> Both set_enable[1] and enable are ambiguous.
> (Assuming you want true as default)

How is setEnabled ambiguous? (Use setEnabled and not setEnable if your
predicate is called isEnabled -- be consistent with your tense!)

> Generally, name your flags and booleans so that they read well in a
> "if" statement:

Which is what I said too. (The generic term here is "predicate".)

> Never use ordered arguments for function calls to an API. What is the
> point of the order ordered arguments? Is the third-ness of the third
> argument to a method helpful to me? Is that more memorable than
> saying:
>
> my_func{iPhone = "auto correcting type writer", writing = lua,
> at_night = "is a pain in the butt"}

It depends on the function. Positional parameters are more efficient
when you need performance and less verbose when it's something you use
a lot. You will find that named parameters are a common holy war, and
in my PERSONAL opinion they're only really appropriate for a function
with more than one optional parameter, and even then sometimes it
makes sense to have BOTH positional AND named. (Python supports this
effortlessly.)

> Don't be cool with a table or nil when a boolean describes the
> purpose. Ambiguity is never helpful because it often covers up two
> errors (1: I'm always evaluating to "true", 2: because...)

Considering how many functions are designed to return "nil, error" on
error failure, it is occasionally convenient to allow nil and false to
coincide. As with many maxims, it's not a blanket rule to be applied
blindly, but a guideline that you should think about when you're
making decisions.

> For the purposes of programming an API (or programming, generally)
> "nil" is not a value, even if Lua says it is. It's nothing. I wish
> this worked:
>
> local delete = function(variable)
>    variable = nil
> end
>
> It would be silly to do this, but delete(my_var) drives the intent
> home[2]. You're not assigning. You're removing/deleting.

Actually there is a way to pull this off using the debug library, but
it's ugly as sin and horribly unperformant. (Pass the variable name as
a string, loop over debug.getlocal until you find it, then use
debug.setlocal to nil it.)

> A small API that requires me to fill in my own code to cover the gaps
> is far better than a large one with a bunch of convenience methods
> that are there to "make life easy."

This is a matter of opinion, and one I strongly disagree with. I DO
want a small, sufficient API to be available, but I also think that
the PURPOSE of software is to automate repetitive tasks. Computers do
repetitive tasks much better than humans do, so forbidding convenience
functions is counterproductive.

> Don't bother writing an API that you're not going to document.

Counterpoint: Don't bother writing an API that doesn't document
itself. If you need to turn to the documentation, the function is
either not self-documenting enough or too complicated. (And sometimes
complicated functions have to happen, but it's better to avoid them
when possible.)

> Documentation that looks like this:
>
> get_by_id()
> property_id, number
> ID number for the property
>
> Is not documentation.

Yet that's exactly the kind of documentation you end up with if you
write good, self-documenting APIs with the long function names you
were describing.

/s/ Adam