I saw this recently:
token = request.headers.get('Authorization') token = token.split(' ')[1]
From an imperative programming point of view, there is nothing
wrong with this. We assign to the token
variable the
contents of the Authorization
header, then we assign to
the token
variable the second substring after splitting
along spaces. After executing these two
statements, token
will contain the desired value.
From a declarative programming point of view, this is terrible.
The first statement binds the name token
to
the Authorization
header, but the second statement
contradicts the first by changing the binding of token
to mean something else. Thinking declaratively, we'd much prefer
either
header = request.headers.get('Authorization') token = header.split(' ')[1]or
token = request.headers.get('Authorization').split(' ')[1]
The first option avoids the contradition and reassignment by simply
using a separate variable. The item we get
from request.headers
isn't a token, it's a header, so
we should name the variable appropriately. The token is a separate
quantity that we compute from the header and the code directly reflects
that.
The second option just avoids the intermediate variable and lets
the compiler choose how to deal with it. Again, there is no
contradiction or reassignment, token
receives its final
value when it is bound.
The problem is this: in the original pair of statements, the first statement
token = request.headers.get('Authorization')while imperatively a valid command, is declaratively a lie. It says that
token
is literally the Authorization header,
but it isn't. The second statement patches things up by fixing
the value of token to be what it ought. It seems poor practice to
deliberately put these sorts of lies in our programs. We can
make the first statement true by simply renaming the variable.
Naming is the hardest thing in Computer Science.
ReplyDeleteI'm increasingly convinced that declarative programming is wholly underappreciated (perhaps its association with CSS has biased opinion against it). Especially when declarative programming is combined with relational programming (as in SQL or miniKanren), you can accomplish quite a lot in very little code with little or no sacrifice of readability.
ReplyDelete