Ruby and Python: pivot points
allthingsprogress.com
Ruby and Python: pivot points
1–10 of 34 posts
Re: Ruby and Python: pivot points
#2Capitalizing things only makes sense on a string. Having a builtin function that could capitalize any input doesn't work, so it's better to explicitly make it clear that it's a string related function. If, for some reason, you're allergic to list comprehensions, you could always do map(lambda s: s.capitalize(), strlist).
Similarly, the string module has a join function, whose definition is: return sep.join(words). The standard ''.join() is unfortunate and unobvious to the newcomer, but it's idiomatic, and there probably are unusual cases where calling a non-method join doesn't work.
Re: Ruby and Python: pivot points
#3...
This is a problem because Python treats methods and functions differently. You can pass functions to other functions. But you can’t pass instance methods.
In Ruby, you can pass "TLDMs" by passing the symbol corresponding to their name, and calling send() on the symbol to call the method. Likewise, you can pass the object and the symbol in order to pass a method around.
Ruby lacks list comprehensions
Ruby does have the select method, which is semantically equivalent. List comprehensions are syntactic sugar for select (and I'll freely admit that Ruby can have a pretty bitter syntax at times, so maybe the sugar is justified).
Re: Ruby and Python: pivot points
#4If join() was not a string method then it would have to belong in some mixin that you slap onto your iterators, and that increases code complexity.
Also, you can do things like map(operator.methodcaller("capitalize"), iterator_of_strings), but that is probably bad style.
And in Ruby you can do your_object.method("foo") to turn your method into a lambda.
Re: Ruby and Python: pivot points
#5More importantly (and annoyingly), if I define a top-level method with def—let’s call those top-level def methods (TLDMs)—Ruby won’t let me pass it as a block to any other method. (TLDMs actually belong to an object, so strictly speaking, this makes sense. It’s still annoying.) In Python, we can pass lambdas and TLDMs like they’re identical. ... This is a problem because Python treats methods and functions differentl…
Regarding TLDMs, how do you propose mapping a TLDM over an array? For example:
def transform(x)
# implementation ...
end
list = [1, 2, 3]
# doesn't work ...
list.map &transform
Edit: &method(:transform) is way too verbose compared with Python's solutionRe: Ruby and Python: pivot points
#6With regards to the join and capitalize examples, once you consider the existence of the string module, the current way actually does make more sense. Capitalizing things only makes sense on a string. Having a builtin function that could capitalize any input doesn't work, so it's better to explicitly make it clear that it's a string related function. If, for some reason, you're allergic to list comprehensions, you co…
You could always do map(lambda s: s.capitalize(), strlist)
That I could, and in fact, I do give an example like that in the accompanying analysis article [1]. However, it's not simple as Ruby. This is a comparison, after all.The two essays I've written are essentially describing what is natural in each language, not what is strictly possible.
[1] http://allthingsprogress.com/posts/the-ugliness-of-python
Re: Ruby and Python: pivot points
#7Yes, you can:
>>> map(str.capitalize, ['alpha', 'beta', 'gamma'])
['Alpha', 'Beta', 'Gamma']Re: Ruby and Python: pivot points
#8More importantly (and annoyingly), if I define a top-level method with def—let’s call those top-level def methods (TLDMs)—Ruby won’t let me pass it as a block to any other method. (TLDMs actually belong to an object, so strictly speaking, this makes sense. It’s still annoying.) In Python, we can pass lambdas and TLDMs like they’re identical. ... This is a problem because Python treats methods and functions differentl…
I should also mention that this is false:
>>> x = 'a'
>>> def call(f): return f()
...
>>> call(x.capitalize)
'A'Re: Ruby and Python: pivot points
#9More importantly (and annoyingly), if I define a top-level method with def—let’s call those top-level def methods (TLDMs)—Ruby won’t let me pass it as a block to any other method. (TLDMs actually belong to an object, so strictly speaking, this makes sense. It’s still annoying.) In Python, we can pass lambdas and TLDMs like they’re identical. ... This is a problem because Python treats methods and functions differentl…
> This is a problem because Python treats methods and functions differently. You can pass functions to other functions. But you can’t pass instance methods. I should also mention that this is false: >>> x = 'a' >>> def call(f): return f() ... >>> call(x.capitalize) 'A'
map(str.capitalize, ['a', 'b', 'c'])
... you have to understand far too much of Python's implementation (for example, that str is not a function, but a class that kindof acts like a function) to program. I still think that methods + functions = a pain point in Python.
Re: Ruby and Python: pivot points
#10More importantly (and annoyingly), if I define a top-level method with def—let’s call those top-level def methods (TLDMs)—Ruby won’t let me pass it as a block to any other method. (TLDMs actually belong to an object, so strictly speaking, this makes sense. It’s still annoying.) In Python, we can pass lambdas and TLDMs like they’re identical. ... This is a problem because Python treats methods and functions differentl…
I don't think so, select is just a filter. List comprehensions map and select at the same time. Regarding TLDMs, how do you propose mapping a TLDM over an array? For example: def transform(x) # implementation ... end list = [1, 2, 3] # doesn't work ... list.map &transform Edit : &method(:transform) is way too verbose compared with Python's solution
def transform(x)
x * 2
end
list = [1, 2, 3]
p list.map &method(:transform)
<3 <3 <3 <3