Hacker News new | comments | show | ask | jobs | submit login

What the hell, they're only karma points:

I lived with Python for 4 years before I lost an argument at my own company and had my project moved to Ruby. I've since moved in with Ruby and haven't looked back.

* Everything in Python feels like a symbol table hack. Private methods? We have those! Just exploit this bug in the class symbol table lookup code!

* First-class symbols. There may be little difference under the hood between a Ruby interned string and a Python string atom, but there's definitely a difference syntactically. This is a difference that is hard to articulate, but if you've written much C, it's like having every "enum" you could ever want predefined for you, and completely eliminates "magic numbers".

* Blocks and lambdas. I've read GvR's take on this. I know he thinks a named function is just as good --- maybe even better! --- than an anonymous function. I had nested named functions/functors in C++ and Java. Even Tcl "uplevel" is better than Python's castrated lambda.

* Method definitions in Ruby don't need to accept a "self" argument. Again: all of Python feels like a symbol table hack to me.

* Ruby has first-class Regexps. Python has an "re" library. You know what else has an "re" library? C.

* I haven't found an expression that is better written as a list comprehension than as a map/reduce/select expression.

There are painful things about Ruby:

* The FFI is immature. Outside of Common Lisp, Python ctypes may be the best FFI out there.

* I never got Python to crash on me (at least, not where it was Python's fault). I crash Ruby once a week.

* Ruby is palpably slower than everything. If performance matters to you and you don't know C, you may be better off in Python.

* The community is led by the nose by Rails developers, which can at times feel like a worst-of-all-worlds grab bag of methodology programmers, web designers, and dabblers.




Blocks and lambdas

Yeah, but this is an area where both languages are just a mess. If python's lambda is castrated, ruby's notion of an anonymous function is tumorous. We've got blocks, procs, lambdas and methods? What's the difference?

Ruby mixes up the syntactic requirements of "passing" some code to a loop to iterate with with the data requirements of binding a function to a scope. It's just a huge mess.

LISP and Scheme figured all this out decades ago, and yet only Javascript (and, almost, perl) among common scripting languages has managed to absorb the lesson.


You say "both languages are just a mess" as if to equate the two. But there's no comparison.

Your Ruby problem with blocks and Proc objects is a nit about elegance and semantics. How often does the difference between an actual Proc object and a block actually affect you? More importantly, if the cost of fixing that nit is that we wind up with Lisp's or Javascript's lambda notation, who would accept that? Javascript has relatively consistent semantics for anonymous functions, but extremely clumsy syntax.

Python simply doesn't have real lambdas. It has the ability to pass something called a lambda in place of a function, and that something forces you to think about things like the difference between a statement and an expression. It then tells you that you don't in fact want anonymous functions, but instead you want to define tens of itty bitty named functions and use them instead. You also "want" that "self" argument to all your methods, and you "want" to tack two underscores to the front of your method names to make them private.

So, I half agree with you. Yes, it would be nice if there was a (zero-cost) way of fixing Ruby's block semantics. Yes, I can rely on Lisp's lambda semantics slightly more than I can on Ruby's, which does start to matter when you start writing domain-specific language code. But I don't agree that this has any bearing on the Python vs. Ruby argument. Python lambdas suck.


True python's lambda's suck. And Ruby's lambda's for the most part don't suck.

But ruby's methods really do suck, and so do the complex construction of Blocks. While I recognize that blocks allow you to do weird things (like use return on the calling scope), the fact that they necessitate a special form (yield) and cannot be bound to a variable, and are not passed as standard function parameters just makes them inconsistent and gross.

Methods which aren't first class functions (but can be transformed into one with the helpful helper function!) also suck, and passing those around in a functional way is just a lesson in futility.

All that being said, I have much more faith in these warts being fixed as time goes on, than python's nasty lambda, and the gross over use of dunders.


"the fact that they necessitate a special form (yield) and cannot be bound to a variable, and are not passed as standard function parameters just makes them inconsistent and gross."

Which brings us to another point - when exactly do you actually need them? I have for every 1000 lines of ruby code maybe one line of "yield" code, and this is only to further extend classes for flexibility. Other languages dont allow you to choose what you want to have, ruby does.

You simply have to make decisions when to use what.

For me it is simplicity, elegance and beauty. These are my biggest design criterias.


I'm 100% with you on simplicity, elegance and beauty. I just demand that as much from the design of the languages I use as from my own code.

I've tried to explain it like this. To me ruby feels Turtles all the way down with respect to Objects, but some kind of nightmare tunnel of interleaved beasts down with Functions.

I don't think I should have to make that compromise, so I'll happily go about writing my ruby when I have to, but I'm waiting for the language that is consistent all the way down.

If I could replace every yield I've ever written in ruby with a .call() I would be so much happier :)


> I'm waiting for the language that is consistent all the way down.

Lua is close.


but I'm waiting for the language that is consistent all the way down.

Newspeak is coming... http://gbracha.blogspot.com/


Ok, now I'm not sure I follow. Apart from the performance issues, why can't you replace every method that "yields" with a method that takes the explicit block parameter, and .call() it?


sigh yeah... you could do that, but you often times you have to deal with methods that aren't invoked that way.

http://blog.sidu.in/2007/11/ruby-blocks-gotchas.html

is a good run down of some of the problems here


No it is not. You dodged the question again, by throwing a hardly related blog of someone else at it.

How many people will use yield _AND_ self.send in the same method please?! That seems like an awfully complicated and contrived example. Who the heck does this?


I think the "can't be bound to a variable" thing is a bit of a red herring too, especially if you're OK with Lisp and Javascript's syntax --- you can create a full-fledged Proc object with "lambda" any time you want.

The inconsistency is annoying, but 99.999% of the time, Ruby is actually giving you what you want.


Right, it just doesn't seem to be Ruby style, and it would be nice to be able to use the "pretty" block syntax to accomplish that.


   and cannot be bound to a variable
&block ?


The block itself isn't being bound; it's being converted to an explicit Proc object named "block".


Lua gets it right too.


As does nasal: http://plausible.org/nasal

That's my own language, and quite obscure (FlightGear uses it, and I've done quite a bit with it personally). But if you want to include Lua too, we might as well be consistent. I was trying to stay within languages with which most readers here would be familiar.


As does Eve (http://eve-language.blogspot.com/), as long as we're throwing out pet languages. ;-) Though I just redid virtually everything about Eve (changed it from a multiple-dispatch functional language to a single-dispatch prototype-based functional language) and haven't yet pushed the changes to GitHub.

For that matter, Ocaml/Haskell/Erlang all get it right, and those are not pet languages. And Cecil and Dylan almost get it right, but have some complications introduced by multimethods. So it's really just the popular languages tha screw up.


Interestingly enough the language everyone loves to hate, PHP, as of 5.3 has figured this out as well.


The "self" argument is great. It is the reason why methods in Python are normal functions and not special "methods".

It also makes this pointless but interesting piece of code possible:

  class foo(object):
     def subclassme(self):
          class subclass(type(self)):
              def __init__(self2):
                  self2.parentobj=self
          return subclass()


> Even Tcl "uplevel" is better than Python's castrated lambda.

Tcl, in its own way, is more powerful than both Ruby and Python in that only the syntax is a given. There is nothing special about 'if', 'while', and other control structures, which are not syntax, but commands. Indeed, you can write your own control structure commands in Tcl itself, with 'do ... while' being a classic example.


You can do the same thing in Japanese Tcl using blocks.


Ruby's lambda is worse than Python's.

Can you elaborate on why you think Python's lambda is castrated?


A python "lambda expression" can effectively only be a one-liner - basically the return line of a function minus "return".

That is why people consider them castrated - in most languages I'm aware of that have a "lambda" statement, it can be read as "create an anonymous function that executes this body of statements". In python it reads as "perform a simple transformation or calculation on or with these arguments", as that's all it's generally good for.


I think it is due to the statement/expression dichotomy that Python exhibits.

Python's lambda doesn't allow the use of statements (correct me if I'm wrong I haven't written Python in a few years and they may have "fixed" this).

Meanwhile Ruby only allows expressions too - the catch here is that everything in Ruby is an expression.


A lambda is traditionally a functional programming product--think Lambda Calculus. Functional programming doesn't have statements, and neither should lambdas. Or do you mean anonymous function, in which case you're right.


They don't plan to fix this, it's part of the core philosophy


* Everything in Python feels like a symbol table hack.

>It isn't bad at all. (And does not really matter)

* First-class symbols.

>Ok, but python has first class functions.

* Blocks and lambdas. I've read GvR's take on this.

>GvR is right.

* Method definitions in Ruby don't need to accept a "self" argument.

>It isn't bad at all. (And does not really matter)

* Ruby has first-class Regexps. Python has an "re" library. You know what else has an "re" library? C.

> Ruby has private methods. JAva has private methods too. Therefore ruby is bad.

And so on...

p.s. And if you need oop features why use ruby instead of java?


"p.s. And if you need oop features why use ruby instead of java?"

Probably because he values his sanity.


Why is 'symbol table hack' a 'bad' word? There is absolutely nothing wrong with the way symbol tables are used in python.


More to the point, it's a feature, not a bug. That everything is a symbol table hack makes metaprogramming much simpler.


What's a metaprogramming problem that's easy to solve in Python, and hard to solve in Ruby? Here's a metaprogramming tactic that is surprisingly annoying to duplicate in Python: "method_missing".


OK, show me how -- in Ruby -- to define a class, such that the class and all of its subclasses will have some special non-standard behavior (say, gaining or losing attributes or methods based on other things in the class definition)... without re-opening the class after its original definition or otherwise monkeypatching it once it's defined.

In Python you can fiddle with the machinery that creates class objects and use it to do whatever you need. In Ruby, as far as I know, that's simply not possible.

(and, yeah, you need to look up the attribute hooks in Python, because it looks kinda silly when your cherry-picked examples are of things you actually _can_ do in Python)


I am not entirely sure what you mean, but adding or removing methods from Ruby classes is extremely simple and there are a number of hooks in place that allow you to play with the class definition on inheritance. But here is another example of the power of Ruby metaprogramming. The example is sort of nuts, but something similar is actually used in the Camping microwebframework.

    Blah = {
      :foo => proc { puts "foo" },
      :bar => proc { puts "bar" },
      :baz => proc { puts "baz" }
    }

    def Monkey(method)
      klass = Class.new
      klass.class_eval do
        define_method :shout do
          Blah[method].call
        end
      end
      return klass
    end

    class Chimp < Monkey(:foo)
    end

    class Gorilla < Monkey(:bar)
    end

    a = Chimp.new
    a.shout # => "foo"

    b = Gorilla.new
    b.shout # => "bar"

    Blah[:foo] = proc { puts "I have changed" }
    a.shout # => "I have changed"


Well, except the example you've given isn't really "metaprogramming" in the sense I'm trying to get at. Here's a Python translation which shows why:

    def Monkey(word):
        class _Monkey(object):
            def shout(self):
                print word
        return _Monkey
    
    class Chimp(Monkey("foo")):
        pass
    
    class Gorilla(Monkey("bar")):
        pass
    
    c = Chimp()
    c.shout() # prints "foo"                                                                                                                                                                               
    
    g = Gorilla()
    g.shout() # prints "bar"
In other words, the Ruby code you've provided is basically a class factory taking advantage of closures. The Python example shows that a bit more clearly.

What I'm looking for is something equivalent to Python's "metaclass" declaration, which lets you completely control the way the class object is created. I've been told by fairly knowledgeable Rubyists that there isn't really an equivalent, and that after-the-fact monkeypatching or factory solutions like yours are the only way to come at the problem in Ruby.


Ruby doesn't have metaclasses, this is true. It won't let you subclass 'class'.

However it will let you subclass 'Module', which is the superclass of Class, and you can use this to achieve similar ends if not quite as elegantly.

The way class methods work wrt to inheritance is a bit different in ruby though, and gives you quite a lot of power to provide special behaviours to subclasses via class methods which can be called in the subclass class definition. The kind of "we provide a DSL for you to use in your class definitions to configure the subclass" tricks which (IIRC) tend to require metaclasses in python, don't require them in ruby.

There is also an 'inherited' class method callback on Class, which you can use to run code whenever a new class inherits from your class. And this can be used to achieve a lot of things that pythonistas might use metaclasses for.

On the whole I think anything possible in one language is possible in the other when it comes to metaprogramming, it's just a matter of how you go about it and how elegant it feels.


(where by 'one langauge' i obviously mean one of Ruby and Python)


One thing I dont understand is

print word

where does "word" come from?

Anyway, this setup is in no way different to ruby's super

super("foo") super("bar")

I really fail to see the point here. What is different? I simply do not see what the python example shows "a bit more clearly" here. I dont even get where "word" comes from.

Besides, "monkeypatching" is a deragotary term invented by pythonistas who do not understand Ruby or think that by adding complexity you can feel "meta" programming so clearly. In my opinion the metaprogramming demanding people are wanking hippos that continually feel a need to add needless and useless complexity on top of problems and in situations where there simply should not be any of that.

Both ruby and python are way to complicated. Can you believe this? At the same time, both are a LOT more elegant than languages like perl or php. Perl 6 still has not managed to get rid of the useless ; at line ends. They managed to eliminate () around if's.

Wow. I am soooo impressed. In 100 more years Perl 7 will be THE best language arrr!!!

But it is a shame that there are not more good languagesl ike ruby or python, because in fact there simply are not that many good languages existing anyway. It takes so much effort to grow a language....

And yes - both ruby and python are very good languages. The fact that there are idiots using the language who have a loud mouth badmouthing either of these two decent languages is annoying, but one can not do much about it.

For everyone else I recommend reading the "why it does not matter" blog. It really summarizes a lot of why ruby and python fill a very similar ecosystem, behaving like rivals who continually try to point out how incredibly stupid the other language is.

Grow up. Use what you prefer, and end this stupid war.


> One thing I dont understand is

> print word

> where does "word" come from?

    >>  def Monkey(word):
    >>        class _Monkey(object):
    >>            def shout(self):
    >>                print word
    >>        return _Monkey
Note that Monkey is a function that takes a parameter word. So every invocation of Monkey creates a class that will always .shout() the parameter word.

> Anyway, this setup is in no way different to ruby's super

> super("foo") super("bar")

No.

    >>    class Chimp(Monkey("foo")):
    >>        pass
    
    >>    class Gorilla(Monkey("bar")):
    >>        pass
You'll note that these two class definitions create a class Chimp that's descended from a class like _SomeMonkeyThatSaysFoo, and a class Gorilla that's descended from a class like _SomeMonkeyThatSaysBar.

That is what the parent poster has challenged anyone to reproduce in Ruby.

> Grow up. Use what you prefer, and end this stupid war.

Programming language wars are at least as old as the Internet, so the admonition to "Grow up" hold no water in this case.

I could quite reasonably parody your closing statement as: "Grow up. So who cares whether a hammer or celery makes a better tool? Just leave us alone, hammer-users."


OK. Like so:

module SpecialBehavioursForClass def extended(klass) klass.class_eval { ...do anything you like to classes including these behaviours as though you're in their class definition block itself... } end

  def special_class_method
    ...
  end

  def give_this_class_an_attribute(x)
    attr_accessor :x
  end
end

then

Class MySpecialClass extend SpecialBehavioursForClass

  give_this_class_an_attribute :abc
end

(note how there's already a class method 'attr_accessor' which does this - but just to reinforce how you'd go about making something similar yourself)

then: MySpecialClass.is_a?(SpecialBehavioursForClass) returns true.

However, MySpecialClass.class == Class it's not actually an instance of a metaclass as these don't exist in Ruby.

You can achieve the exact same things though, using Modules, class methods, and the .inherited / .included / .extended callbacks.


Sorry it bolloxed my formatting. Note to these people: tell us how your code formatting works, somewhere near the goddamn input field


I haven't used Ruby enough to have used method_missing, but I have used Python's __getattr__ to accomplish the same thing. Can you give an example of something that would be easy to solve in Ruby with method_missing but hard to solve in Python with __getattr__ ?


Yes: make this evaluate as Python (in Python idiom, of course):

    @bb = Bblock.make {
        push ebx
        mov ebx, dest
        pop ebx
        retn
    }
That's all method_missing.


like EliAndrewC said, __getattr__ is Python's version of method_missing: http://docs.python.org/ref/attribute-access.html

And no, that's not all method_missing. looks like method_missing plus a block.


How do you catch and transform method arguments with __getattr__? For instance:

   mov ebx, [ebp+4]
needs to detect that ebx matches a Register class constant and that [ebp+4] is not an array, but rather a register indirection expression.


__getattr__ needs to return a callable (usually a function, but you can 'call' other objects as well). And that callable will be called with the arguments to the method.

You can do all that stuff with python, though the syntax isn't as loose; you can't omit the () around method calls which is what I think you're doing here in Ruby. That restriction tends to improve readability and reduce bugs at the cost of making it harder to have a truly transparent DSL.


The parens thing is unfair; obviously, without parsing strings (avoiding which is the whole point of metaprogramming), you can't express assembly in Python.

But isn't it surprisingly annoying to do method_missing in Python? Again, you have to catch the exception case to the symbol table lookup, and cons up a callable that knows to catch the arguments the right way.

Here's the entire method_missing call I needed to make x86 work inside a Ruby block:

        def method_missing(meth, *args)
            k = Rasm.const_get(meth.to_s.capitalize)

            # If it's a class, it's an assembly opcode;                 
            # else it's a register or operand.
            if k.class == Class
                @insns << (k = k.new(*args))
            else
                k
            end
            return k
        end


Well, Python has the * args and * *kwargs thing too. So "knows how to catch the arguments the right way" isn't any more of a problem than it is in Ruby. I'm guessing you don't know much about Python; you keep saying "It must be hard not to be able to do X" when in fact you CAN do X.

No, it's not surprisingly annoying. You can override just about anything within the rules of the Python syntax. You can override what << and + and | all do. You can override [] and ().

You just have to live within the Python syntax, which unfortunately for DSLs is stricter than Ruby syntax. But when you're not doing DSLs, that stricter syntax is usually a good thing.


Instead of saying it "...isn't any more of a problem than it is in Ruby" and "I'm guessing you don't know much about Python", why don't you actually show us some Python code which does something similar? I know Ruby well but Python only rudimentarily, so I'm curious what the rough equivalent would look like. If you don't feel like doing that, fine, but I'm just going to ignore your arguments.


His example is too incomplete to translate properly (since I don't know the details of other stuff he's referencing), but the basic idea is this:

A callable object in Python (e.g., a function or method, though not necessarily limited to these) can take advantage of two special options in declaring its argument signature. One is a feature shared between Python and Ruby: you can prefix the final argument with a single asterisk, which will be interpreted as "accept any number of additional positional arguments, and store them as a list in a variable of this name".

So, for example:

    def print_args(*args):
        for arg in args:
            print arg
Which does pretty much what it looks like it should do; you pass any number of arguments, and it echoes them back, each argument printed on a separate line.

The other part is something Ruby doesn't really support, because Ruby doesn't have a true analogue of Python's keyword arguments: using a double asterisk says, essentially, "accept any number of keyword arguments, and store them as a key/value mapping in a variable of this name".

So, for example:

    def print_keyword_args(**kwargs):
        for key, value in kwargs.items():
            print "%s: %s" % (key, value)
If you then did, say, `print_keyword_args(name='Bob', email='bob@example.com')`, you'd get back the output (ordering of items may vary with the Python implementation, but usually you're not concerned with ordering -- that's what positional arguments are for):

    name: Bob
    email: bob@example.com
These can also be combined into a standard idiom for a callable which accepts any combination of any number of named and keyword arguments:

    def takes_any_arguments(*args, **kwargs):
        ...
These sorts of idioms are incredibly useful for dynamic programming; for example, I work with (and help develop) the Django web framework, and our object-relational mapper uses the `kwargs` idiom to set up query methods which dynamically adapt the arguments they accept to the particular data model you're querying against.


> That restriction tends to improve readability and reduce bugs at the cost of making it harder to have a truly transparent DSL.

I used to think this too. But, then I actually learned ruby, and it turns out to be pretty easy to discern method calls from local variables, unless you are working with horridly long methods, which is a separate issue.

Remember that an instance variable is prefixed with @ in ruby, so if you see something that looks like itĀ could either be a method call or a reference to a local variable, it's pretty easy to quickly examine the local scope to check. It's usually so obvious that you don't need to, though.

There are definitely some potentially tricky situations (closures, etc), but in over a year of working with ruby full time, I have yet to encounter one.


  fun1 x

  fun1 x + y

  fun1 x + y.foo

  fun1 x + y.foo bar
What will happen in this perfectly valid Ruby code? Where do the parentheses belong? Do you know off the top of your head?

While any programmer who would write this deserves to be fired, I can't come up with a good reason why it should be valid to write it in the first place.


Yes, I do know where the parentheses belong. Like I said earlier, it isn't hard to read ruby like this once you get used to reading ruby.

> While any programmer who would write this deserves to be fired...

That's exactly my point. The only example you could come up with was a straw man.

> ...I can't come up with a good reason why it should be valid to write it in the first place.

Can you come up with a good reason it matters in practical, real world situations?


Looks contrived, because I dont know many ruby users who would write fun1 for a method. Why? Because in ruby there are methods. You dont find many people doing "fun" for a method - the intent clearly was a "function". But where are they? ;)

Anyway, here is the one that comes to my brain flow naturally. It seems python writers need () in order to feel happy, otherwise they think they get confused about things (hopefully they dont have a small brain):

  fun1 x

  fun1 x + y

  fun1 x + y.foo

  fun1 x + y.foo bar
What will happen in this perfectly valid Ruby code? Where do the parentheses belong? Do you know off the top of your head?

fun1(x) fun1(x + y) fun1(x + y.foo()) fun1(x + y.foo(bar))

Btw you omitted what x and y are. My first assumption is that these must be variables that allow the + method

It does not really make a lot of sense though, give the last example:

class Cat def initialize(name) @name = name end def foo(how = :h) case how when :h how = 'happily' when :u how = 'unhappily' end puts @name+' meows '+how+'.' end end

y = Cat.new 'Tom'

y.foo # "Tom meows happily." bar = :u y.foo bar # "Tom meows unhappily."

x = '"At the end of the day "

x + y.foo bar # "At the end of the day Tom meows unhappily."

etc.. I simply have no idea what fun1 should do. Maybe it will involve Jerry mouse and return a conditional story where it is explained why Tom the cat is unhappy.

Btw this is a really contrived example because I tried to model your stipulation of the above code into this. It really makes no sense at all to use variables without any real idea why one should use that.

Why do people WANT to be complex when simplicity is so much more elegant?


This comment field is not very good, it killed my newlines! :(

I demand the pre tag or a "code" tag or something that allows us to add code nicely formatted :P


Anything indented two spaces acts like it's inside pre tags.

  Like this.
  And This.
  Etc.


Yes indeed. You have phrased it better.


I've somehow forgotten to rant about ruby's totally hackish broken tools for importing code. require and include are just heinous crimes against nice programming. (I /love/ it when I clobber my global namespace with an include in ruby).


That's never caused a problem for me. It's also a tradeoff: in Python, you have to meticulously "import" every symbol you might need, which is tedious. I compared a really good piece of Python code (CORE's Impacket library) to a similar piece of Ruby code (Jamis Buck's net/ssh), and it's 3-1 in average number of important statements per file.


from module import *

tada!

it's just considered bad python style to do that... because it tromples your global namespace!!


Number of times I've been bit by global namespace pollution in Python or Ruby: countable on 1 hand.

Number of times I've been bit by forgetting the right import statement for a piece of Python library functionality: considerably worse.

I know, "plural of anecdotes" and all that. I think it's hard to argue that Ruby isn't easier to use "out of the box" than Python is, though. How do you say:

    3.days.ago - 2.hours
in Python? Because, yeah, "days" and "hours" on Numeric? Shit's all crazy! But totally worth it.


yeah... cause you know... I never forget to include 'gems' because gems has to monkey patch the include function so that it can get at my installed libraries :P


You can use ruby without gems. I think you confuse gems with "pure" ruby as such. I have seen horribly code in gems and I think the whole gems idea is the wrong solution. But I am in a minority here.

I also do not know why cpan is mentiond FIRST as perl's greatest assets. To me i think a language should easily provide the capabilities to the programmer without addons, AND I also think that there SHOULD BE ONLY ONE "CPAN" FOR ALL THE SCRIPTING LANGUAGES OUT THERE.

I find it totally silly that there are any distinctions at all.

But back to gems:

I for example am using Ruby since almost 5 years without gems. Others seem to like it that you can simply do "gem install rails" and thats it (unless the debian package manager starts to hate it again... which is btw another thing that sucks.)

I agree that there are people who are concerned with "namespace" pollution, but I simply think so many people are trying to overemphasize. The worst was when I talked to a C# hardcore guy. He basically claimed that being flexible like Ruby is ALWAYS bad (C# does not allow you to change core methods. You must subclass and change that new class then. This is not a smart solution, it simply binds and restricts the developer, and claims that this will be better in the long run. My question is - why not allow being flexible AT THE CHOOSING OF THE DEVELOPER IN QUESTION? The reason is simple. C# is a typical language that is developed from the top-down.

It would be so much better if creating good languages would be a lot easier, so noone has to cater to arrogant developers who try to impose their thinking pattern onto your brain.


I don't think you read my comment, while I did take a stab at gems, the point was to simple to provide a counter point to his statement that he commonly forgets to import the right namespaces in python. The counter is of course, that I forget to import the right namespaces in ruby as well.

In fact I can think of a common one, that many people forget, we often forget the gem include (being why rails includes it for you).


Also I would like you to name which library specifically causes this problem :)

Whenever I read it, people seem to make up contrived problems - and do not give any example.

I would like specific examples please where this interferes with your code.

So far it simply did not interfere with my own ruby code, and I have written really a lot over the 5 years here, including my own bigger "alternative" to gems. (I wanted to release it, but I was lazy and always felt it is easier to use my own idioms. The problem with this approach is that, while it really makes creating something super fast, I would either have to unbundle everything again so I can distribute it, or bundle everything. Both things have huge problems, because if i unbundle everything it will take quite some time to rewrite things really "cleanly" enough for _other_ people. For my personal needs it is totally fine. And if I would distribute things "bundled" together, which means I could release today, then people would simply complain that there are so many things "bundled" together they simply wont need.

Complaining people are annoying.

i know because I am one of them)


I don't have any good ruby examples, but I've been bitten by namespace trampling behaviors in perl and php long enough to know that any code importing in languages I use need to make it explicit when that's occurring.


its not nearly as pretty, but its not terrible either.

from dateutils import relativedelta import datetime datetime.now() - relativedelta(days=3, hours=2)


"... I lived with Python for 4 years before I lost an argument at my own company and had my project moved to Ruby. I've since moved in with Ruby and haven't looked back. ..."

Where would we be without language wars?

Having said that the one thing that Ruby does have is current developer mindset. Important for language development and progression. Is Python to Ruby what Perl is to Php? Used a lot but not mentioned as much?



I think you might be confused as to what Python's lambdas are for. The name is very misleading - it really should be called a function expression. It's just a shortcut for declaring a function with an expression. It's useful for situations where you need to pass in a very simple utility function, as is usually the case with list.sort() and its comparison function argument.

I'm not sure what points you're trying to make with your other complaints, but I guess if you "feel" things are hackish, that's OK. What you might consider feeble-minded hacks Python coders consider simple, straightforward implementations.


> Ruby is palpably slower than everything.

Try 1.9. It's usable today, and should be fully stable by January. Performance-wise, it's on par with Python.


I want to focus on one point that I find an interesting study in language design:

> * I haven't found an expression that is better written as a list comprehension than as a map/reduce/select expression.

map/select are better iff you have a concise block syntax.

For mapping with a single ready function, all styles are reasonable:

    items.map foo
    items.map { |x| foo(x) }
    map(foo, items)
    [foo(i) for i in items]
Now suppose you want to modify the mapping function to foo(bar(i)). You could cascade it:

    items.map(foo).map(bar)
    map(foo, map(bar, items))
but this quickly gets out of hand and makes modifications painful. What you really want is a place to write arbitrary expressions instead of just a function name.

With comprehensions OR a good block syntax, it's a smooth transition:

    [foo(bar(i)) for i in items)]
    items.map { |i| foo(bar(i)) }
But without one, the change is ugly and annoying:

    map(lambda i: foo(bar(i)), items)

So why wouldn't Python just embrace a nice block syntax? Precisely because this naturally leads to expressing most control structures as functions taking blocks!

Now that is not wrong in itself, but it is a question of taste. Pythonic taste favors a different approach: instead of passing the block directly to a function, have a few built-in control structures that can act as combinators.

E.g. don't write an "each" method that accepts a block - write an iterator, and use the built-in "for" loop as a bridge between the iterator and the block. Why would this be any better?

1. Because we can: it turns out that the vast majority of custom control structures can be sorted into a few patterns (iteration, pre/post guards, function wrapping), each served by one natural combinator ("for", "with", decorators). There is a price: it takes time until new patterns are recognized and the missing combinator is added (e.g. "with" is a very recent addition).

2. Decoupling: an iterator is a self-contained passive object that can be used outside of a for loop. An "each" method takes control and is less versatile.

3. Readability: seeing the combinator gives you an immediate idea about the style of flow control. This is just a matter of taste (Lisp and Ruby solve this with naming conventions).

4. Syntax taste: stupid as it sounds, passing blocks to functions is just alien to Python's syntax. Many smart people tried to marry them - and it wasn't a pretty sight...

But in the end you can't judge decisions of taste by pro/con arguments. You have to look at the sweet spots (and the sour spots) that arise in practice. A particularly nice sweet spot that arose in Python is the combination of reduction functions with generator expressions:

    sum(i**2 for i in range(10))
    any(p % i == 0 for i in range(2, p - 1))
    dict((v, k) for (k, v) in dict_to_invert)
This is very cool because the map-reduce pattern covers lots of useful computations. Of course it's just a one case and YMMV. I'm sure Ruby has its own sweet spots...


You can add inline c to ruby for the few places where speed matters.


Yes, and that simply costs you the ability to distribute your software to anything but your own servers.




Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | DMCA | Apply to YC | Contact

Search: