Monday, July 28, 2008

Mea Culpa re: Typing

I was going through some Rails code today, making sure that I had good coverage and writing or modifying whatever specs as needed. I found this code:


module DisplayHelper
# snip ...
EMPTY_STRING = %q[]
# snip ...
def should_see_edit_link?(options)
return EMPTY_STRING if options[:new_record]
return false unless (memoized_user = options[:user])
# more stuff with memoized_user ...
end
end


Do you see the problem? The first line within should_see_edit_link? should be


return false if options[:new_record]


My initial version was not a proper predicate, in that it did not restrict its returned values to only true or false. Bad coder. For what it's worth, the methods that use should_see_edit_link? themselves return EMPTY_STRING if should_see_edit_link? is truthy. Alas, not a good enough excuse.

This is exactly the sort of error that advocates of static typing mention as support for their preferred type system. The most experience I have with bondage & discipline typing is with Haskell, where I find it takes its proper place as part of a cohesive whole for understanding Haskell's approach to currying, implicit typing, the pointfree style, and so on. All of that is great, I just haven't found that static typing reduces the error rate in my code. In fact, it gets in my way more often than anything else. Maybe that's why I'm getting more into Erlang rather than Haskell. All of this is probably inseparable from the fact that I got into coding with dynamic languages.

The type error that prompted this blog post is atypical for me. I'm not claiming to write completely bug-free code, it's just that my errors tend not be the sort that can be caught by a static type checker. In fact, the only errors of this sort that I can remember making are this individual error and some others in Perl related to composite data structures being coerced into scalar context. The latter were more indicative of Perl's idiosyncratic (and in my opinion, failed) experiement with context than with dynamic typing as it's generally implemented outside of Perl. So I'm not sure that they count.

How about anyone else? Has static typing ever really saved your butt dramatically?

Caveat: Please don't interpret this post as going anywhere near addressing static typing as it relates to hardware optimizations during compile time. I'm just taking about human errors resembling the example.

Saturday, July 26, 2008

Mr. Neighborly's Ruby and Rails Bibliography

Jeremy McAnally recommended my book in his list of good Ruby books partitioned by skill level and specific interest. He placed mine in the sublist appropriate for "moderate programming experience". Seems appropriate.

Jeremy gave a very good presentation called Deep Ruby at MtnWest RubyConf2008 in Salt Lake City. He also has some of his own books in the same list where he graciously put mine. He's a good speaker who knows a lot about the language. Check him out.

I would add SICP to the list for becoming a more well-rounded programmer.

Friday, July 25, 2008

Wither Comments?

Jeff Atwood has an excellent post at Coding Horror about comments.


http://www.codinghorror.com/blog/archives/001150.html
.

Worth reading. I believe that function / method names should tell you what's happening (at a suitable level of abstraction), and any comments that do exist should explain the rare cases where your well-named entities could be misleading.

Avi Pilosof has an excellent related point about the kinds of comments that are often underused at http://blogs.msdn.com/avip/archive/2008/07/25/code-commenting-try-business-commenting.aspx.

Monday, July 21, 2008

First-Class Procedures, Part III: being returned as values of procedures

SICP demands that for functions to qualify as First Class Citizens,
they must satisfy several requirements. I've written about this before in reference to the first requirement: being able to assign names to procedures, and the second requirement: the ability to be passed as an argument to another function. Next on the list is being returned as a value from a procedure. Here we go with that.

Again: Ruby, SICP's original Scheme, Erlang, and Haskell, with JavaScript by my friend Aubrey Keus.

In Ruby:



def get_method_that_does_name(owner, name_as_sym)
owner.method(name_as_sym)
end

def get_double_plus_one
lambda { |x| (x*2) + 1 }
end


Here we've defined a method called get_method_that_does_name. It expects a Symbol argument preceded by an owning object, and returns a Method object, created via the aptly-named method method. The owning object provides the context for the method, similar to a closure in a purely-functional language. Here's an example of how get_method_that_does_name might be used in irb:


>> add1 = get_method_that_does_name(1, :+)
=> #<Method: Fixnum#+>
>> add1.call(2)
=> 3
>> greet = get_method_that_does_name('hello, ', :+)
=> #<Method: String#+>
>> greet.call('world')
=> "hello, world"


The method identified by + means something different when called on 1 than when called on hello, , as shown in the example.

The other example uses the more-familiar lambda keyword to generate a Proc.


>> dp1 = get_double_plus_one
=> #<Proc:0xb7cb2458@./first_class_functions_in_ruby.rb:39>
>> dp1.call(4)


In either case, the returned value from the method (whether
get_method_that_does_name or get_double_plus_one) is a procedure-like object callable with the call method.

In MIT Scheme:


$ mit-scheme

1 ]=> (define get-adder (lambda (x) (lambda (y) (+ x y))))
;Value: get-adder
1 ]=> (get-adder 2)
;Value 11: #[compound-procedure 11]
1 ]=> ((get-adder 2) 1)
;Value: 3


Thi sample code demonstrates a typical Scheme example of a procedure that returns another procedure. This particular syntax uses two lambdas, but note that the first line could have been expressed alternately in this manner:


1 ]=> (define (get-adder x) (lambda (y) (+ x y)))
;Value: get-adder


Usage in the 2nd and 3rd lines remain the same in either case. Line 2 shows us that calling (get-adder 2) returns a compound-procedure value, and line 3 shows us that that returned procedure takes an argument (y in our definition code), and adds it to the value of x that was used in the get-adder call that created the returned procedure in the first place.

One could argue that Scheme provides the most canonical syntax for defining a procedure that returns another procedure. This is unsurprising, given the roots of the language, especially in education.

In Erlang:



$ erl
Erlang (BEAM) emulator version 5.5.5 [source] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.5.5 (abort with ^G)
1> GetAdder = fun(X) -> (fun(Y) -> X + Y end) end.
#Fun<erl_eval.6.49591080>
2> GetAdder(2).
#Fun<erl_eval.6.49591080>
3> Add1 = GetAdder(1).
#Fun<erl_eval.6.49591080>
4> Add1(2).
3


This Erlang example differs slightly, of course. Erlang's variables are uppercase, and it uses the fun keyword rather than lambda. This particular example also happens to assign the value of GetAdder(1) into a variable called Add1, which erl dutifully reports back to us is of the type Fun. Calling Add1(2) then produces the expected result.

In Haskell:


Last time on this topic I used hugs, a REPL shell. This time I'll use GHCi.


$ ghci
GHCi, version 6.8.2: http://www.haskell.org/ghc/ :? for help
Loading package base ... linking ... done.
Prelude> let getAdder x = \y -> (y + x)
Prelude> let add1 = getAdder 1
Prelude> add1 2
3
Prelude> :quit


This actually uses Haskell's equivalent of lambda in the \, apparently chosen for its visual resemblance to the letter λ without a lower-left leg. If we wanted to use the pointfree style mentioned in the hugs portion of my previous post on this topic, we could replace the first line with


Prelude> let getAdder = \y -> (y +)


Notice how it leaves the x variable out entirely.

We can use Haskell's type system to reveal some other things of interest.


Prelude> :t getAdder
getAdder :: Integer -> Integer -> Integer
Prelude> :t (getAdder 1)
(getAdder 1) :: Integer -> Integer


The :t command in GHCi reports the type of its argument. getAdder has the type Integer -> Integer -> Integer. This means that it can either take two Integer arguments and return a single Integer, or it can take one Integer and return a function of type Integer -> Integer. This means that the returned function takes one Integer and returns one Integer. When we check the type of the expression (getAdder 1), it reports, as expected, that the expression takes a single Integer, returning another. This type system is crucial to understanding Hashkell's handling of currying, which I hope to get into in greater detail in a later post.

If we want to eliminate middle variables entirely, we can simply feed two Integers directly to getAdder, as in


Prelude> getAdder 1 2
3


In JavaScript:



function call_proc_arg_on_2(first_class_proc) {
return first_class_proc(2);
};

Number.prototype.call_proc_arg_on_self = function(first_class_proc) {
return first_class_proc(this);
};

call_proc_arg_on_2(add1);
Number(100).call_proc_arg_on_self(add1);


Aubrey's JavaScript code demonstrates both the initial example common across all the languages, as well as the equivalent of my second Ruby example, in which the desired behavior is attached to existing number objects within your language's existing workspace.

So that's it. I think all of these languages satisfy the requirement of returning procedures (however defined) as values from other procedures, at least from a practical perspective. The next (and final) post in this series will be about incorporating procedures into data structures. I'll get to the post when I can.