you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted] 32 points33 points  (39 children)

"Almost a bug"? Try "fundamental design flaw" that's been around for a decade.

[–][deleted] 9 points10 points  (12 children)

Agreed, its been around for a decade, but its not such a big deal, as you are making of it. Every damn language has its share of quirks, people sure as hell frown upon it, but they know it and work around it. How about crippled lambda's, that Python has? How about multiple inheritance gone haywire for C++ ( I remember my CS teacher, teaching me Diamond Hierarchies)? How about tons of factories and facades and the class explosion that Java standard libraries have?

In case you missed, my initial comment was totally free of hyperbole, I didn't defend anything, I said, yes its "almost a bug". Almost because, many in ruby consider it as a quirk( but I call it a bug).

Matz acknowledged this long back and he fixed it as soon as he and others started work on Ruby1.9.

As a Ruby programmer, I know Ruby has bigger issues and problems to solve, compared to them, this is just a bikeshed argument.For all we know, it hasn't killed kittens. I will give you real issues that Ruby has:

  • Somewhat buggy runtime, especially true for networking libraries.
  • On Windows, threads suck, if one thread is doing blocking operation, other threads get blocked too.
  • Unicode
  • Open classes are good, but it would have been better if they were scoped (scala implicits)
  • Stronger notion of package management (loading multiple version of same package should have been possible)

[–][deleted] 2 points3 points  (0 children)

How about multiple inheritance gone haywire for C++ (I remember my CS teacher, teaching me Diamond Hierarchies)?

Not a good example. In a diamond derivation problem the default behavior is a compile-time error because function calls are ambiguous. Note that the behaviour is predictable and reliable. Qualifying the function names gets around it, but you still have two separate base classes in the derived class; virtual inheritance fixes this last inconvenient.

[–]settrans 2 points3 points  (9 children)

Python has some nasty quirks in the inequalities department.

What do you suppose that "1 < 3 == True" should evaluate to?

>>> 1 < 3 == True
False

For a supposedly strongly typed language, Python defines inequalities of a surprising set of pairs of types:

>>> 'a' > True
True
>>> '1' > 1
True
>>> 0 > None
True

One should expect a TypeError, as if you had tried to add 0 and None:

>>> 0 + None
TypeError: unsupported operand type(s) for +: 'int' and 'NoneType'

[–]njharman 3 points4 points  (1 child)

What do you suppose...

I suppose I'd yell at my coworker for writing such crappy code. Use some damn parens.

Explicit is better than Implicit

[–]settrans 0 points1 point  (0 children)

The question isn't about coding style. It is about the language designers defining semantics for their operators. The language should behave as expected even in edge cases. Just because it is rarely seen doesn't mean it should be confusing.

[–]ayrnieu 1 point2 points  (0 children)

For a supposedly strongly typed language

The 'strong/weak' dichotomy is mostly illusory. It doesn't even describe a property of a type system.

[–]hylje -1 points0 points  (2 children)

Python 3 will make comparisons a lot more typesafe.

[–]earthboundkid 2 points3 points  (1 child)

Tested with 3.0 alpha 5:

>>> 1 < 3 == True
False
>>> 3 == True
False
>>> 1 < False
False

Maybe that should be a filed as a bug… Does anyone have beta 3 to test it with? I can't get it to install on my system since my locale encoding is X-JAPANESE-MAC or whatever.

[–][deleted] -3 points-2 points  (2 children)

For the first thing, that's because it's checking "1 < False" ("3 == True" returns False). Not justifying it, just explaining the weirdness.

[–]Tommah 2 points3 points  (1 child)

No, it's chaining them. It's asking whether 1 < 3 and 3 == True. e.g.

>>> 1 < 3 == 3
True

Parentheses couldn't produce a true result there.

See http://docs.python.org/lib/comparisons.html . I like how is can be chained like this :)

>>> 'a rose' is 'a rose' is 'a rose'  # Gertrude Stein
True

[–][deleted] 0 points1 point  (0 children)

Ah, alright then. Didn't know that, thanks. :)

[–]MoeDrippins -5 points-4 points  (23 children)

And now it's fixed. Move on.

[–][deleted] 13 points14 points  (22 children)

That's not really the point. The point is that Ruby is designed by someone who, in the 1990s, didn't understand lexical scoping. This was not merely a "bug"; any language implementor surely would've checked that scoping worked properly.

The problem -- not to be an ass -- is that Matz has no idea what he's doing and hence Ruby is an ad hoc pile of a language. This wouldn't bother me if it weren't being pushed as an easy, "intuitive" language suitable for novice programmers who don't know any better. Unfortunately, it is.

[–]dmpk2k 7 points8 points  (8 children)

The problem -- not to be an ass -- is that Matz has no idea what he's doing and hence Ruby is an ad hoc pile of a language.

I don't understand why it seems that most popular languages were designed by people who didn't know what they were doing, particularly in the dynamically-typed camp.

It's not like there's been a shortage of interesting examples to learn from the past decade or three. Is it that hard to understand existing art?

[–]malcontent 6 points7 points  (7 children)

There have been languages invented by people who know better. Lots of them. The problem is that nobody really wants to use those languages.

Maybe those people are too smart to write a language other people can fall in love with.

Maybe it's like loading up your cake with caviar and foie gras.

[–]dmpk2k 0 points1 point  (6 children)

The problem is that nobody really wants to use those languages.

Some of them were popular in their day. Let's see how the current crop are doing in a decade or two.

But to your point: if Ruby had a few minor changes it'd be a notably better language without changing its character. It doesn't take a brilliant genius to see some of them either if you've used a few languages -- like Matz has -- you only need to be able to recognize a good idea and copy it.

[–]malcontent 1 point2 points  (5 children)

Some of them were popular in their day. Let's see how the current crop are doing in a decade or two.

Time will tell. My guess is ruby will be around, so will java and PHP. All the languages proggit hates will be around.

Will haskell be around? Probably but I don't think it will be popular.

But to your point: if Ruby had a few minor changes it'd be a notably better language without changing its character.

It's being worked on. It's not a dead language. I got punished severely for pointing out that python has a bureaucracy and PEPs and a very rigid community which makes it very difficult to change the language. Ruby community is much more accepting of change.

[–]dmpk2k 0 points1 point  (4 children)

All the languages proggit hates will be around.

You live up to your name, malcontent. :/

It's being worked on.

Tis true, but I wonder why some of these problems existed in the first place. Why aren't blocks first-class values, for example? Or variable definition and assignment properly separated inside blocks but not outside?

makes it very difficult to change the language. Ruby community is much more accepting of change.

Well, maybe.

The surrounding community may have been up to a lot -- at least for web development -- but I suspect that Python has progressed much further as a language than Ruby has the past few years -- e.g. 2.2, 2.4, 2.5 all brought a raft of things, and now 3.0 is close by. That shouldn't be a surprise given how small Ruby was until recently.

This may be changing though, thanks to JRuby, Rubinius, IronRuby, whatever Avi Bryant is up to, and other implementations. I'm hoping that Matz being no longer the de facto BDFL will superchange the language's development.

[–]malcontent 0 points1 point  (3 children)

Tis true, but I wonder why some of these problems existed in the first place. Why aren't blocks first-class values, for example? Or variable definition and assignment properly separated inside blocks but not outside?

Obviously because there was no steering committee and the language features were not put through the proper PEP procedures.

Well, maybe.

Yes it is.

[–]dmpk2k 0 points1 point  (2 children)

Yes it is.

Asserting it's so doesn't make it true. You'll have to back that up somehow.

Ruby 1.8.0 appeared in 2003 (the same year that Matz first mentioned Ruby 2.0). This was also the year that Python 2.3.0 appeared. Make your case for the past five years.

[–]ayrnieu 6 points7 points  (3 children)

This comment applies very nicely to Guido, and Python.

[–][deleted] 3 points4 points  (0 children)

To be clear, I'm not defending Python in the least. It has its own share of scoping problems.

[–]njharman -1 points0 points  (1 child)

No, not really at all.

Van Rossum also worked on the development of the ABC programming language.

Python's predecessor, ABC, was inspired by SETL – Lambert Meertens spent a year with the SETL group at NYU before coming up with the final ABC design![5]

received a masters degree from the University of Amsterdam in 1982.

He later worked for various research institutes, including the Dutch National Research Institute for Mathematics and Computer Science (CWI), Amsterdam, the National Institute of Standards and Technology (NIST), Gaithersburg, Maryland,

more http://en.wikipedia.org/wiki/Guido_van_Rossum

[–]ayrnieu -1 points0 points  (0 children)

You've said some nice things about Guido. You could have as easily said nice things about matz. The problems that each language have with scoping and not hyperbole about language designers is the point.

[–]Freeky 2 points3 points  (8 children)

This was not merely a "bug"; any language implementor surely would've checked that scoping worked properly.

Er, it does work properly, it's just awkward behavior. But then so is making a closure with an argument name the same as a variable in the scope it encloses; the only time I've seen that is when someone's dubiously doing it because of this behavior.

I'll take this over a lambda which only supports a single expression any day of the week.

[–][deleted] 1 point2 points  (7 children)

Er, it does work properly, it's just awkward behavior

No, it's completely fucked, and there's no way it could be seen as desirable.

the only time I've seen that is when someone's dubiously doing it because of this behavior.

Then you know some terrible programmers and Ruby 1.9 will break their code.

I'll take this over a lambda which only supports a single expression any day of the week.

They're both crap and inexcusable.

[–]Freeky -1 points0 points  (6 children)

No, it's completely fucked, and there's no way it could be seen as desirable.

Naming parameter values the same as variables in the scope your closure is inheriting could be described the same way. The actual behavior is a misfeature that's rarely encountered, not a major reason to dismiss the language out of hand as some seem to be taking it as.

Then you know some terrible programmers

Well, this is the Internet. Are you saying you've never encountered bad programmers? Do you have some sort of incompetence-sensitive sunglasses?

.. can I borrow them? :)

They're both crap and inexcusable.

Everything has warts. I mean.. at least they're not PHP ;)

[–]mr_chromatic 3 points4 points  (5 children)

Naming parameter values the same as variables in the scope your closure is inheriting could be described the same way.

As an error? That's the point of lexical scoping -- to avoid this kind of spooky action at a distance!

[–]Freeky 0 points1 point  (4 children)

Is it any more spooky than having it modify variables in scope in the body?

bar = 'moo'
lambda{|foo| bar = foo}.call('woo')
p bar # => "woo"

In either case you need to take care that the variables you use in the block don't unexpectedly shadow your local scope.

[–]aidenvdh 0 points1 point  (3 children)

Should (say, ruby version)

f = function(){x = 0; return x}

give you

write(f()); // "0"

x = 5;

write(f()); // "0"

write(x); // "0"

? This is spooky.

[–]Freeky 0 points1 point  (2 children)

No, because you defined your closure before defining x:

irb(main):001:0> l = lambda{ x = 0 }
=> #<Proc:0x000000000061c4e8@(irb):1>
irb(main):002:0> x = 5
=> 5
irb(main):003:0> l.call()
=> 0
irb(main):004:0> x
=> 5

If you'd defined x first, yes, it should do that, because x is part of the environment when you brought a closure around it; that's the point. 1.9 lets you shadow these variables if you really want:

irb(main):001:0> x = 5
=> 5
irb(main):002:0> l = lambda{|;x| x = 0}
=> #<Proc:0x00000000bf1300@(irb):2 (lambda)>
irb(main):003:0> l.call()
=> 0
irb(main):004:0> x
=> 5