Sunday, November 20, 2005

Code as Language

Code should be more like language.  Code should speak to people.

After reading some of Brian Marick's stuff I have been wondering if there were other projects on the web working to the same goal.

Guess what?  If you can think it, on the internet you find it :-)

Here is a small review and lots of cut&paste, mainly from comp.lang.ruby..

From "Readability" inflation:

Excerpt I

Similarly, if you're used to:

   f = lambda {|a,b| ... }

then after a while, you might find that so natural that you feel
"ready" for

   f = lambda -> (a,b) { ... }

Well, of course, it allows you to write more uniform code, transforming the block definiton into a tool to define new syntax.

Excerpt II

>    def foo(a =>, b =>, c =>)
>    obj = -> (a, b = 1){ block }

Does

    def foo(a:, b:, c:)

look any better?

Yep, it does.  Much better.
I used to think of named parameters (an Ada idiom, if I am not wrong) as a bureaucratic heritage from dying programming languages.  These days I think they are fundamental to write readable programs.  How else would you know the meaning of a parameter, without chasing words with the mouse to get tooltips to pop up?

Still, I think they should be optional.  There is no point in saying:

plot_point x: x, y: y, color: chosen_color

since this would make perfect sense:

plot_point x, y, chosen_color

Excerpt III

Consider Microsoft's Monad's

   get-childitem | sort-object extension | foreach { $_.filename}

vs Ruby's

   get-childitem.sort_by{|child| child.extension}.map{|child| child.filename}

Msh makes Ruby's 4-time repetition of "child" look quite tedious,
without adding any readability that I can see over the Microsoft version.


Must agree with Microsoft, just this time.  The implicit result variable makes beautiful code possible.


Excerpt IV

> Case in point, what's the english equiv of #===. I'd really like to
> have one.

How about "contains" or "includes"?

     String contains "abc"
     0..10 contains 5
     1,2,3,4 contains 3
     /^[a-z]*$/ includes "apple"

It would be nice if Array#=== was aliased to Array#include?  So that

     somearray === someval

would check for membership.

Very nice, I'll check if it has been aliased in any ruby library


From Ruby Facets 0.6.2:

Excerpt V

Perhaps it would also be a nice idea to add Enumerable#count,
Kernel#with and Object.new with a template block?

Samples:

[1, 2, 3].count { |item| item > 1 } # => 2
with("foo") { reverse } # "oof"

obj = Object.new("foo") { def reverse() "bar" end }
obj # => "foo"
obj.reverse # => "bar"


This is the way I understood how 'with' would work:

s = "hello"
with(s) {
  reverse!
  capitalize!

}

I like the count, it reminds me of the COUNTIF in Excel.  Actually I would rename it to count_if.
The  'with' is quite cool.  How do they do it?  I wonder how it is implemented.
I like to be able to make context explicit.

Excerpt VI

Thanks for that. Can I humbly suggest that Numeric#ago be changed to
Numeric#before? If we're trying to mimic English, you'd never say "10
days ago yesterday" in English, but you would say "10 days before
yesterday". So instead of making people call

10.days.ago( Time.now - 1.day )

they could call

10.days.before( Time.now - 1.day )

instead. And if Time.yesterday and Time.tomorrow had been defined, you
could simply call

10.days.before Time.yesterday

And maybe this would cause transitional issues, but it might be good to
redefine Numeric#ago to refer to a time relative to the current moment,
which is in line with what it means in English.

yesterday = 1.day.ago
last_monday = 8.days.ago

Similarly, Numeric#later could go the other way:

tomorrow = 1.day.later
next_tuesday = 6.days.later

And Numeric#after could add time to any arbitrary starting point:

three_days_later = 2.days.after Time.tomorrow

very nice, I am impressed.  great readibility.

I'll explore some more examples and possibly some libraries.  I will also try to organize the material that I find in some categories.







Comments: Post a Comment



<< Home

This page is powered by Blogger. Isn't yours?