On 10/7/2017 5:09 AM, Steve D'Aprano wrote:
On Fri, 6 Oct 2017 11:44 pm, ROGER GRAYDON CHRISTMAN wrote:

Despite the documentation, I would still be tempted to say that range is a
function.
Taking duck-typing to the meta-level, every time I use range, I use its name
followed
by a pair of parentheses enclosing one to three parameters, and I get back
an
immutable sequence object.   It sure looks like a function to me.

I agree -- range() is a function in the (almost) mathematical sense, something
which takes arguments and returns a value. It's also a type (class), in the
OOP sense:


py> type(range)
<class 'type'>


The term "function" is ambiguous but normally clear from context. Often, the
differences make no difference, but when they are important, we can discuss
them:

- range is a callable (a callable object);

- it is also a type/class, and calling it returns an instance;

- it looks like, and behaves like, a function;

- and is, conceptually, a function;

- but it is *not* an instance of FunctionType:


py> from types import FunctionType
py> def function():
...     pass
...
py> isinstance(function, FunctionType)
True
py> isinstance(range, FunctionType)
False

No built-in function is an instance of FunctionType
>>> isinstance(compile, FunctionType)
False
>>> isinstance(print, FunctionType)
False
>>> type(compile)
<class 'builtin_function_or_method'>
>>> type(int.bit_length)
<class 'method_descriptor'>


FunctionType == function defined by def statement or lambda expression.
These are a subset of functions defined by Python code.

It is this last sense (an instance of FunctionType) which people are thinking
of when they state that range is not a function.

Unless one means 'function defined by def or class', excluding all functions defined in the interpreter implementation language, which can change as modules are recoded one way or the other, and some functions defined in Python, FunctionType is too narrow. The predecate would have to be at least

BuiltinFunction = type(compile)
MethonDescriptor = type(int.bit_length)
isinstance(x, (FunctionType, BuiltinFunction, MethodDescriptor))

but that still excludes bound methods and partial functions.

I have the impression that classes being functions is somewhat peculiar to Python but I have not been exposed to enough OOP languages to know.

The other sense in which 'range is not a function' makes some sense is when it means 'range is not *just* a function'. This is akin to when 'people are not animals' means 'people are not (or should not be) *just* animals'. Do people speaking other than English say subcategory Y of category X is special by saying 'Ys are not Xs'?

--
Terry Jan Reedy

--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to