5 ms·
Moka - Minimalist functional python library
- hyphyphyph 15y agoYuh yeah ! :) Congrats on the release. You're definitely going to run into resistance from more hardcore Python guys I think, as it's very "unpythonic" but who cares ? I'll be curious to see everyone's reaction after the presention on Monday.
- Codayus 15y agoThis is pretty interesting looking. I'm tempted to try using it on my next project...anyone else used it yet? Seem stable/bug free?
- phzbOx 15y agoIt's fairly new but feel free to browse the code; it should be pretty straightforward to you. I've tried to provide good examples to make it easy to learn/use on phzbox.com/moka/.
- tmcw 15y agoNeeds a README and examples without a hop.
- phzbOx 15y agoClickable link for the doc: http://phzbox.com/moka/index.html http://phzbox.com/moka/index.html Moka is still in an alpha stage; but that being said, I'd love to hear some feedback. Feel free to browse the code, it should be pretty straightforward to any python dev.
- andrewcooke 15y agotwo small suggestions: change .saving() to .mutable() and .rem() to .remove() (or filter(), reversing the semantics, since that is already in python) (every other method is a full word). also, maybe .mutable() would be better as a flag in the constructor. it makes no sense to use it in a chain (in fact, that could be confusing) and is the kind of thing you should probably fix on construction rather than changing later. ps. it's not clear to me that this is better than list comprehensions, which already do much of what you have.
- phzbOx 15y agoThanks for the feedback; I agree with you. Here's the reasoning behind these odds choice.. List is-a list, and Dict is-a dict.. and thus, I'd like to make it possible to safely pass these objects to already existing code. If I rename .rem to .remove, I'd break that. The reason for the chaining saving() is because it's useful to be able to toggle it. For instance: self.x = Moka.List(range(1,10)).mutable() return (self.x.map(lambda x: x*2) .immutable() .keep(gt=5)) So, basically, you change self.x with the map, but don't necessarily want to change it with the keep(). (I'm not saying it is the right thing, just why it's done that way.)
- inportb 15y agoWhat if your mutation functions accepted a flag that set the saving behavior, and you used a sensible default?
- DanielRibeiro 15y agoA good source of inspiration: Ruby's Enumerable[1] and Scala's Iterable[2]. Toguether, they have one of the most complete functional collection methods library. [1] http://ruby-doc.org/core-1.9.3/Enumerable.html http://ruby-doc.org/core-1.9.3/Enumerable.html [2] http://www.scala-lang.org/api/current/scala/collection/immutable/Iterable.html http://www.scala-lang.org/api/current/scala/collection/immut...
- tef____ 15y agoYou've invented your own incompatible dialect of python. You've broken composition, objects and the general design choices of python. 1. You break Composition Your magic flag within a list changes all the semantics of the methods between immutable and mutable lists. > x = List([1,2,3]).saving() So now, if you're passed a list you have no idea if the operations you do will mutate the list. This breaks composition entirely. You can't pass a mutable list into a function built for immutable lists without destroying things. 2. You break objects Picking another example, this breaks duck typing and inheritance and polymorphism. >def user_logged(users): > return List(users).all(User.is_logged) this does not have the same semantics as: > def user_logged(users): > return all(user.is_logged() for user) Because the method lookup is done per instance, rather than assuming everything is the same class. 3. You're writing jquery in python Python chose not to demand that all iterables implement a series of operators, but provides them as functions within a module. The rationale is that it is easier to add new functions within itertools, and there is far less to do to correctly implement the iterator protocol You can see this in the "".join(foo) operator too. Instead of demanding all iterables support join, string takes an iterable as argument. Making readable and maintainable python comes from using the existing idioms within the language and used within the community. Your proposed solution isn't readable, and it isn't pythonic.
- phzbOx 15y agoThanks for the feedback, these are interesting points. I'd like to clarify a couple of things about your #2 and #3. def user_logged(users): > return List(users).all(User.is_logged) # If you want per instance: def user_logged(users): > return List(users).all(lambda x: x.is_logged()) And, about the "".join; you are right. However, Moka's construct allow you to use whatever you want, i.e.: moka.List(['a', 'b']).do(string.join, '').last_value Or, you can still use: ''.join(moka.List(['a', 'b'])) However, about the #1, I have to agree. I've added the saving() recently and had a bad taste about it. The right way to do it might be to make it mutable by default and only toggle it off in certain circumstances. Please note that everything done by the community is still perfectly usable; in fact, it's even easier to use useful high-level functions. I.e. map(str, range(1,10)) or List(range(1,10)).map(str); is syntactically different but does the same job.
- rhizome31 15y agoYou should really give Ruby a try.
- ynd 15y agoThe doc at http://www.phzbox.com/moka/index.html http://www.phzbox.com/moka/index.html is pretty complete. The only thing I find is missing is a few words about efficiency. Does calling List(l) copy the list l for example?
- phzbOx 15y agoOptimizing for performance is the next big step of Moka and I understand that it's the breaking point for lots of python developers. So, I'll make sure to work on that and provide realistic benchmarks. As for the copy, yes it does as it tries to act like a builtin list as much as possible. (In fact, moka.List inherit from list). When it's in immutable state, a new list is returned at each step. If it's in mutable, self[:] = (..) is used.
- ericmoritz 15y agoLooks like it.
- lucian1900 15y agoThis is indeed minimalist, there's less code in it than I'd expected. The idioms it introduces do clash with Python ones, but on the other hand, I've been learning Clojure lately and my Python code has more comprehensions than previously. I'm not sure what to think.
- sashahart 15y agoHere's a gist comparing the Moka front page example to a slightly more typical Python way of doing things: https://gist.github.com/1380898 https://gist.github.com/1380898 EDIT: using the timeit module on these, the Moka version is about 18 times slower on my machine... not that this matters much if it's a much nicer way of expressing the program
- phzbOx 15y agoThanks for sharing. And ya, it's freaking slow right now.