Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

you seem to go a long way to reinvent python builtins like reverse() any() all() enumerate(), itertools and functors. another python style you violate is that mutable methods return None in general.

from the outset you haven't made any attempt to learn python style. go and read the zen of python.

I only picked on a handful of examples, but wait! theres more - almost every example on your page has a way to do it in python. that other python developers use and understand.

#chaining example:

you say 'we believe chaining constructs are easier to read and maintain than deeply nested expressions.'

zen: flat is better than nested

> Dict(a=1, b=2).update(c=3).rem(lambda x, y: x=='a')

becomes

> d = dict(a=1, b=2)

> d['c'] = 3

> del d['a']

#'partial application' example

> List([1,2,3]).map(string.zfill, 8, _)

becomes

> [str(i).zfill(8) for i in [1,2,3])

# magic argument names

zen: 'explcit is better than implicit'

different methods have different magic attached: it isn't obvious from the outset why update takes named args but keep takes args are named operators

> List([1,2,3]).keep(gt=1)

becomes

> [x for x in [1,2,3] if x > 1]

# you reinvent all

> List(range(1,10)).all(lambda x: x < 100))

becomes

> all(x < 100 for x in range(1,10))

# 'compact' example

> List([None, 0, 2, []]).compact()

becomes

> [x for x in [None, 0 , 2, []] if x]

# 'list is empty' example

> List([]).empty()

becomes

> bool([])

# 'sort'

> List([5,3,1]).sort()

becomes

> sorted([5,3,1])

'uniq'

> List([1,1,2,3,2,1]).uniq().sort()

becomes

> collections.Counter([1,1,2,3,2,1])

for every example you give, there is an equivalent piece of python code to do it, designed in mind with the rest of python. the built in operations give you flexible control over the evaluation too - you can have generator expressions and list expressions. many iterable versions of the standard operators exist in itertools.

really, this is the least pythonic thing since ruby came out. it seems I can only spell this out to you by elaborating through your jquery library and presenting you with python code python developers understand.

please stop re-inventing python without trying to understand why it looks that way first.



Thanks for all the good points. To be honest, I'm not sure what you're trying to say. I've been coding in python for years and Moka was built from my annoyance using functional paradigms with the stdlib.

As you clearly showed, Python doesn't have an uniform syntax to deal with this paradigm. I.e. there are lots of different constructs and, as you said, common idioms or patterns. Have you already argued with a Java programmer saying that these 'Design Pattern' are just a limitation of the language.. whereas in Python you'd probably just use a simple Dict (or whatever)? I'm sure you did. I feel the same with the idioms and patterns.

See, in Clojure (And Arc, and even Ruby), there is an uniform syntax.. whereas in Python we've got itertools, list comprehension, builtins map/filter, random builtins functino such as sorted().

I have to agree with you that Moka is not Pythonic in the There's only one way to solve a problem as we add a new way. However, Moka was created because there was so much inconsistent alternatives..

However, Moka is Pythonic in how it behaves. God knows I could have use all nifty hacks to make it behaves magically.. but I chose to take the explicit route by overriding list/dict. I could have used string interpolation for function (See http://osteele.com/sources/javascript/functional/); but instead went the Pythonic way with standard lambda functions. Maybe you are right about the operator keywords shortcut (i.e. using List().keep(operator.eg) instead of List().keep(eg=); However, I still feel it was a way to make it even easier to integrate with existing tools from the stdlib.

Lastly, you said:

    zen: flat is better than nested
    > Dict(a=1, b=2).update(c=3).rem(lambda x, y: x=='a')
^^^^^^^^^^ This is not nested, this is chained.

This, however, is nested: # Taken directly from the itertools stdlib page. next(islice(iterable, n, None, default)

    # Here, this is not nested.. this is chained:
    def logged_user(self):
        return (self.users
                      .keep(User.is_logged) 
                      .keep(lambda u: u.is_active)
                      .map(lambda x: User.objects.get(id=x)))


so you're admitting you're writing an incompatible dialect of python in python?

that was my point. if you think it is worthwhile, well - enjoy :-)

if you want to write in something with a uniform syntax, use scheme or clojure. python things look different for a reason.


Maybe I don't understand what you mean by "incompatible dialect". These are simple classes inheriting from list/dict. Basically, it simply add a couple methods to these objects. I.e. You can still use all the idioms/patterns; these are list/dict. I'm not creating a new paradigm, or writing a new language by tweaking the syntax. There's really nothing magic going down here. I.e. you can do

    return List(..).update(..).update(..) 
Instead of;

    l = List(...)
    l.update(...)
    l.update(...)
    return l
You can still use lisp comprehension, itertools, etc. In fact, I could pass a moka.List to your existing code and you wouldn't even notice it. (And you do, it's a mistake that I'd fix).

I do agree that I might have been overkill with some useless methods and I'm thinking about removing them. (I.e. such as 'join' as it's really not needed)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: