Live data from Hacker News

Ruby and Python: pivot points

allthingsprogress.com

11–20 of 34 posts

Re: Ruby and Python: pivot points

#11
post #5

More 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

    alias :m :method
<3 <3 <3

Re: Ruby and Python: pivot points

#12
post #9
post #8

Earlier quoted context omitted.

> 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'

I stand corrected. However, I do think that in order to use this like I want ... 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.

Well... to make it easier you can think of classes as normal functions returning instances. For almost any practical purpose, that's true. Also, str.capitalize is (for any practical purpose again :) ) a one-argument function that takes a string and returns a capitalised string.

Re: Ruby and Python: pivot points

#13

The whole point of having join() as a method on the string is that it is meant to handle any kind of iterator. You can join a list, a generator, or the custom iterator of your choice. In any of those cases, it looks the same and is implemented only once. If 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…

Sounds to me like join would work better as a function ;)

Re: Ruby and Python: pivot points

#14
post #13

The whole point of having join() as a method on the string is that it is meant to handle any kind of iterator. You can join a list, a generator, or the custom iterator of your choice. In any of those cases, it looks the same and is implemented only once. If 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…

Sounds to me like join would work better as a function ;)

Except that it only makes sense in the context of strings, so it makes perfect sense to make it a string method.

Re: Ruby and Python: pivot points

#16
post #14
post #13

Earlier quoted context omitted.

Sounds to me like join would work better as a function ;)

Except that it only makes sense in the context of strings, so it makes perfect sense to make it a string method.

It seems to me like join makes sense in any context where you have multiple elements that you want joined. With strings, you happen to have a separator. But you might also want to join several lists into one flattened list. (Edit: I know there are ways to do this. The point is that join could be unified around this concept.)

Even if you disagree, the line between methods and functions in Python really isn't standardized.

Re: Ruby and Python: pivot points

#17
post #5

More 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

That's probably why explicitly calling transform inside the block, or making transform a method of the objects you're trying to transform, is more idiomatic Ruby.

You're right in that list comprehensions are semantically equivalent to combining map and select, not just select.

Re: Ruby and Python: pivot points

#18
post #16
post #14

Earlier quoted context omitted.

Except that it only makes sense in the context of strings, so it makes perfect sense to make it a string method.

It seems to me like join makes sense in any context where you have multiple elements that you want joined. With strings, you happen to have a separator. But you might also want to join several lists into one flattened list. (Edit: I know there are ways to do this. The point is that join could be unified around this concept.) Even if you disagree, the line between methods and functions in Python really isn't standardi…

You can join several lists into a flattened list as well:

reduce(operator.add, list_of_lists)

You can not say sum(), sadly, because it forces a restriction that you only sum numbers.

Re: Ruby and Python: pivot points

#20
post #16

Earlier quoted context omitted.

It seems to me like join makes sense in any context where you have multiple elements that you want joined. With strings, you happen to have a separator. But you might also want to join several lists into one flattened list. (Edit: I know there are ways to do this. The point is that join could be unified around this concept.) Even if you disagree, the line between methods and functions in Python really isn't standardi…

You can join several lists into a flattened list as well: reduce(operator.add, list_of_lists) You can not say sum(), sadly, because it forces a restriction that you only sum numbers.

It's not pretty, but you can do it:

  >>> sum([['a', 'b', 'c'], ['d', 'e', 'f']], [])
  ['a', 'b', 'c', 'd', 'e', 'f']
This makes use of the optional start argument and list add operator. However, Python's docs suggest using itertools.chain instead:

http://docs.python.org/library/functions.html#sum

  >>> import itertools
  >>> [l for l in itertools.chain(*[['a', 'b', 'c'], ['d', 'e', 'f']])]
  ['a', 'b', 'c', 'd', 'e', 'f']
(Of course you lose the benefit of a generator by using a list comprehension, but this is just an example.)
Post reply on HN