2 ms·
Ah, this is more interesting. I see what you're getting at; a lifting function is something like, in Python: mapF = lambda f: functools.partial(map, f) Th
by vertex-four 13y ago
Ah, this is more interesting. I see what you're getting at; a lifting function is something like, in Python:
mapF = lambda f: functools.partial(map, f)
The thing is, in Python, there's a set of "magic methods" that any object of mine can implement (or which more commonly are implemented by generator objects), and Python's built-in iteration tools will then work on them. Using these is then as simple as:
def doAThing(x):
return foo(bar(xyz(x)))
a = MyIterableClass()
b = (doAThing(x) for x in a)
c = (doAnotherThing(self.bluh, x) for x in a)
doTheNextThing(c)
This pattern is reasonably common, popping up all over my code, and seems fairly reasonable to me. It's a bit more typing, but that's never been a bother for me.
When I need to implement a lifting function myself, it's pretty obvious that I do, and it's not something I think particularly deeply about.
I'm just not really sure where the novelty comes from, I suppose. Is this less common in other languages?
- chas 13y agoYou are absolutely right that this isn't particularly novel. It generalizes a pretty wide range of concepts, which makes it hard to talk about accurately without resorting to jargon. Iterators and generators are solutions to the same sort of problem but aren't quite as general. They do a good job of abstracting over streams and data structures, but I don't think they are as useful for dealing with single pieces of data with something special about them such as computations that could fail. It would be interesting to hack __iter__ to cover that case, but it's not idiomatic python. I think the "special types of data" idea works better in a statically-typed language so it would be non-pythonic on a couple of levels. I use generators extensively in my python code, but I find they tend to infect programs. Once generators are used in one place, everything that interacts with that code works better as a generator. In Haskell, it is easier to use lifting for part of an expression without affecting the style of the rest of the program. In addition, Haskell's type system and type inference make it possible to use these techniques in ways that would be very strange and difficult to do in Python which I didn't get in to in my original post because I wanted to stay in somewhat familiar territory. For example, functions are Functors and there are some interesting patterns that can be abstracted over by taking advantage of that. That said, if you thought of lifting like this as a strongly-typed slightly more general __iter__, you could be quite productive with it in Haskell. This is also useful for other languages because it makes it clear how much more general the __iter__ interface is and how it can be applied to things that are not data structures or streams.