5 ms·
It's interesting to note that a dictionary ("catalog") of values is essentially the same concept as an object. This is clearer in Javascript, where `{...}` nota
by chriswarbo 8y ago
It's interesting to note that a dictionary ("catalog") of values is essentially the same concept as an object. This is clearer in Javascript, where `{...}` notation is called an "object" rather than a "dictionary" and the `.foo` and `["foo"]` notations are mostly interchangable.
Storing functions in a dictionary is very close to storing methods in an object. The only differences are sharing state via a `self` (or `this`) argument, and inheritance chains (either from classes or prototypes).
Also interesting to note that many of the author's functions, like `lambda x, y: x + y`, only make sense because the underlying language (Python) thought that constructs like `+` shouldn't be functions for some reason. Many languages seem to do this, e.g. here's a bug report I raised for PHP https://bugs.php.net/bug.php?id=66368 https://bugs.php.net/bug.php?id=66368
When we introduce arbitrary distinctions, like dictionary vs object, named vs anonymous functions, functions vs operators, etc. then we end up with all of the choices and complications like those shown in this article.
One of the principles I try to follow when programming is to avoid making distinctions, or breaking symmetries, unless my hand is forced by the underlying dynamics. Experience has taught me that introducing distinctions in one place just introduces complication elsewhere (e.g. more cases to handle when metaprogramming).
- Felk 8y agoI don't know why operators are the way they are in Python, but to me it looks like an oversight, which ultimately let to the "operator" module, exposing all operators as functions
- guitarbill 8y agoAt the risk of oversimplifying/getting the subtleties wrong, operators are syntactic sugar to call magic methods. You could still call the magic method itself: >>> a = 1 >>> a.__add__(2) 3 >>> b = [] >>> b.__len__() 0 It's rare I have to use the "operator" module, and I find Python pretty well thought out w.r.t. consistency. All in all, seems fine to me.
- chriswarbo 8y ago> You could still call the magic method itself Only if you have the first argument available. As a silly example, we might want to do the following (in analogy to the built-in `sum` function): product = lambda vals: reduce(operators.__mult__, vals, 1) We can't use a bound `__mult__` method for situations like this. More generally, looking up methods from particular objects forces our code to be "first order", i.e. we have to explicitly deal with intermediate results which don't appear in higher-order programming. For the `product` case we could do: def product(vals): result = 1 for val in vals: result *= val return result 3/5 of these lines deal with `result`, which doesn't appear at all in the `reduce` version. The same thing happens with stuff like composition too, e.g. the `x` in `lambda x: foo(bar(x))` when we could just `compose(foo, bar)`. When code is bound up in methods, we're often forced to expose these intermediate values, in order to call their methods. Of course, we can abstract over such boilerplate too, with functions like `lambda o, m: o.__getattribute__(m)`, etc. but at that point we're fighting against the language. PS: Yes, I know Guido doesn't like `reduce` and moved it out into `functools` for Python 3.
- coldtea 8y ago>Also interesting to note that many of the author's functions, like `lambda x, y: x + y`, only make sense because the underlying language (Python) thought that constructs like `+` shouldn't be functions for some reason Actually python's + (and most operators) are available as functions, and allow for overloading as well: >>> import operator >>> operator.__add__(1,2) 3 >Many languages seem to do this "Many"? Unless you ever only touched Smalltalk, Lisp or some fringe languages, this is the norm for most languages -- operators are distinct from functions (same as expressions are different than statements). Whether this is a good idea or not, I wont go into, but it's not like this is something surprising, or something that merely "many" languages seem to do. Not just many, but almost ALL mainstream languages (C, C++, Java, C#, etc) do it.
- annabellish 8y ago>operators are distinct from functions >c# As python, C#'s operators are backed by functions - they're just static ones on the class.
- deleted 8y ago[deleted]
- agumonkey 8y agopersonally I always always hated operation segregation
- deleted 8y ago[deleted]
- kazinator 8y agoLisp operators are distinct from functions. It's just that arithmetic operations are functions; Lisp dialects use operators for various other constructs that cannot follow the function call evaluation rules. C++ sort of makes operators functions. Any overloaded operator is a function. If a is a class object then a + b can be spelled otherwise as a.operator+(b). This doesn't work for the built-in definitions of the operator, as in 2.operator+(2). The built-in + operator in C++ can also do things that used to be impossible in C++ until its template system became more powerful. Namely, the result type of the built-in + is deduced from both operands and can be different from both of them. If C++ were being redesigned clean-slate, it would likely be that operator overloading is allowed for the non-class types like int, and all the built-in operators are defined in terms of templates, whose deduction/instantiation reproduces all the rules.