Showing posts with label ruby. Show all posts
Showing posts with label ruby. Show all posts

Tuesday, August 23, 2011

.NET is Stale?

Here's dhh on twitter: "Wish someone would study the cultural inhibitions in Denmark that binds it to stale, conservative platforms like .NET"

.NET is stale?  Fuck you!

Not to mention the language features of C#:

Is C# the most elegant language ever invented?  No, but it is one of the most elegant I have used, especially for a statically typed language.  And the language itself is clearly one of the most advanced available.  This is stale?

Did all of these ideas originate in .NET?  No, but what the hell difference does that make?!  The .NET community finds and adopts the best ideas, whether they started in Java, Ruby, or Python.  This is stale?

Are there companies still using .NET 2.0 and little to no open source software?  Yea, there are also companies on the bleeding edge, using all the tools listed above.  From organizations with strict upgrade guidelines, to organizations that wait for the first service pack, to organizations that go to production on beta releases.  You'll find it all in the .NET community.  This is stale?

Ruby is a joy to program in.  Dynamic languages are more fun to do TDD with.  Percentage wise, I'm sure more Ruby programmers participate in the open source community.  There are a wide array of really great things about Ruby (and Python, etc etc).  There are also plenty of shitty things (poor backwards compatibility, poor documentation, poor tutorials, elitist attitude, etc etc).

But this bullshit attitude that .NET is stale, outdated, joyless, or somehow dramatically inferior is nothing but short sighted and stupid.  Get over your buyer's remorse and go build some software that contributes to something larger than yourself.

* Did I leave off your favorite fresh .NET tool or feature?  Leave it in the comments.

Monday, June 20, 2011

How Powerful is Your Language?

Most mainstream programming languages today are basically the same.  I mean, they are all Turing complete, they can all access databases, the web, and so on.  What else is there?

Well, my comparative languages class in college said there were four factors for evaluating programming languages:
  1. Readability
  2. Writability
  3. Reliability
  4. Cost
I would add a 5th, which is maintainability.  The argument I'm going to attempt to make today is that Dynamic Languages, and Ruby in particular, score better in these factors than static languages, and therefore are more powerful languages.

The first thing you might think of is syntax, and there is certainly something to be said for that.  Clean syntax makes for enhanced readability and writability.  And the ability to create DSLs in your language is another major plus to readability and writability.  So right off the bat Ruby is off to a pretty good start.

But I think the argument actually goes deeper than that.  Consider the SOLID design principles:
  • SRP: Single Responsibility Principle
  • OCP: Open Closed Principle
  • LSP: Liskov Substitution Principle
  • ISP: Interface Segregation Principle
  • DIP: Dependency Inversion Principle
These are principles we use to describe good code.  That is, more readable code, more reliable code, more maintainable code, and less costly code.  And I believe that Ruby, as a language, has many of these principles built right in.  And that means that it scores higher on the comparative ladder, and therefore is a better, more powerful, language!

Lets start with SRP.  So Ruby has Modules, which are pretty great.  And I would argue that they are a helpful tool for SRP.  I've had some awesome conversations on this point, but I land on the side of saying that Modules and MixIns are totally useful for SRP.  But that's about as far as we go for language support for SRP, so lets move on!

OCP is a bit more interesting, though still straight forward.  Dynamic languages like Ruby allow you to open up any class from a distance and add new methods to them, or change the definitions of existing methods.   So you can change anything in the class without having to open up the actual class definition. That's some pretty serious built in OCP support.  Of course, to be fair, this isn't a feature you're likely to depend on when you're implementing a class you want to follow OCP...  Its more of a last resort really, but we'll find its very useful for mocking which we'll talk about later.

When talking about LSP Wikipedia has this to say: "Behavioral subtyping is a stronger notion than typical subtyping of functions defined in type theory."  This is a super-wonderful sentence for my purposes here!  LSP is all about the behavior of subclasses matching their parent classes, and the beauty of this is that dynamic languages are ALL about behavior, you tend not to get to hung up with "types".  So, you still have to be careful that your derived classes' behavior is consistent with that of their parent's, but since you're already thinking about behavior instead of types, you are off to a much better start.

Interface Segregation seems simple at first glance, dynamic languages don't have interfaces, end of story right?  Not quite, because while ISP is about interfaces, what's its saying is that your interfaces should be highly cohesive so that you cannot divide the methods of an interface into discrete sets based on who calls them.  This is because we don't want to be coupled to methods we don't care about.  But in a dynamic language, the caller just sends whatever "messages" it wants to the object it is calling, so by default our "interfaces" are as segregated as they could ever possibly be!  We have perfect, automatic ISP in dynamic languages.

Dependency Inversion is sort of the crowning jewel of built in principles in dynamic languages.  Most of the time in static languages our main reason for caring about Dependency Inversion is for unit testing.  We invert our dependencies so that we can mock them out in our tests.  This is outrageously annoying because it means we can never ever ever call a constructor.  So we are forced to either a) make all our dependencies stateless or b) wrap all our constructors with factories.  It also means we have to introduce interfaces to describe a huge number of our classes. In Ruby, we don't have to think about this.  At all.  We can stub out the calls to constructors and return our own mock versions.  It's so easy it's totally stunning the first time you do it.

So there you have it!  Dynamic languages are awesome, in part, because they have the SOLID design principles built in, which makes them score better on the comparative language scale.

Tuesday, January 18, 2011

Strings in Ruby vs. C#

In Ruby:
s1 = "string"
s2 = s1
s2 << "a"
s1.should == s2

In C#:
string s1 = "string";
string s2 = s1;
s2.Insert( 0, "a" );
Assert.NotEqual( s1, s2 );

Strings in C# are immutable. So trying to change a string actually creates a new string. So updating s2 does not update s1.

Strings in Ruby are mutable. So strings in Ruby act like pointers and s1 is updated when you update s2.

UPDATE 1/19/2011:
To be more clear, here are some more examples of how Ruby behaves:

s1 = "string"
s2 = s1
s2 += "a"
s2.should_not == s1

s1 = "string"
s2 = s1
s2.gsub!('s','z')
s2.should == s1