Functional Programing: Function Output Should Always Have the Same Structure

By Xah Lee. Date: . Last updated: .

This page discuss a issue about function programing. That is, function's return value should always have the same structure.

Emacs Lisp example: thing-at-point

The elisp function (thing-at-point 'line) is quite annoying.

It is used to grab the current line. Like this:

(defun xxtest ()
  (let (myline)
    (setq myline (thing-at-point 'line) )
    (message "got this: %s" myline)
    ) )

It grabs the line including the line return character at the end. However, if the line is the end of file then it does not include the end of line char.

This means, you have to do manual checking after you grab the line.

(You should use “line-beginning-position” and “line-end-position” instead. See: Elisp: Functions on LineElisp: thing-at-point.)

Functional Programing: Function Chaining

This problems happens often in programing langs, in Perl, Python, unix shells, all faak up on this. Even lisp, as far as i know, does not stick with the principle.

In Mathematica, there's a principle, that a function's return value always have same structure. For example, a function that solves equation or filters a list, it normally returns a list {…}. But what if the input has no solution? In other langs, they might return nil, null, none, undef. In Mathematica, it simply returns the same form (same tree structure), in this case a empty list {}.

The advantage of returning the same structure is that the programer do not have to do extra checks, or extra “if” statement, when chaining functions. Imagine, water is flowing thru pipes. If no water, or bad water, your filter or checkpoint doesn't have to cut the pipe open to exam it.

This principle is important in functional programing. In imperative programing and languages, it matters less, because programer don't chain functions that much (because the lang can't), and basically the entire source code is just miscellaneous blocks to do this and that.

In functional programing, overall you simply have 2 blocks in your source code. One for function definitions. And the other, is abstractly one single line of chained functions. Even lisps, usually fail grasping this fundamental idea. (and due to the cumbersome nested paren, which effectively stop the chaining paradigm. [see Fundamental Problems of Lisp] )

The following articles are all relevant: