Alan Perlis – SICP Quotes

Quotes from preface of Abelson and Sussman’s “Structure and Interpretation of Computer Programs”:

“I think that it’s extraordinarily important that we in computer science keep fun in computing. When it started out, it was an awful lot of fun. Of course, the paying customers got shafted every now and then, and after a while we began to take their complaints seriously. We began to feel as if we really were responsible for the successful, error-free perfect use of these machines. I don’t think we are. I think we’re responsible for stretching them, setting them off in new directions, and keeping fun in the house. I hope the field of computer science never loses its sense of fun. Above all, I hope we don’t become missionaries. Don’t feel as if you’re Bible salesmen. The world has too many of those already. What you know about computing other people will learn. Don’t feel as if the key to successful computing is only in your hands. What’s in your hands, I think and hope, is intelligence: the ability to see the machine as more than when you were first led up to it, that you can make it more.”
—Alan J. Perlis (April 1, 1922 February 7, 1990)

“Is it possible that software is not like anything else, that it is meant to be
discarded: that the whole point is to always see it as a soap bubble?”

ChicagoRuby Ruby Code Tweaks slides, code and video

The slides from my ChicagoRuby 2010/05/04 presentation :

http://kurtstephens.com/pub/ruby/ruby_code_tweaks/

All the raw data used to generate the graph should be referenced in the slides.

The code used to generate the slides is here:

http://github.com/kstephens/ruby_code_tweaks

I’m looking to increase the set of code “Problems” to cover other tiny code idioms and platform issues, for example: regular expressions, numerics, etc. If you have ideas, take a look at the code and contact me.

Justin Love gave a fantastic presentation on lambda and closure.

Thanks to everyone who came — hope it was helpful.

Video from the talk:

Ruby Code Performance Tweaks by Kurt Stephens from ChicagoRuby on Vimeo.

Ruby: Fixnum#gcd accepted into MRI

Ruby rational.rb clean-up and the Fixnum#gcd primitive was refactored into a new MRI extension. Fixnum#gcd is now defined during require ‘rational’.

This dramatically improves performance of Ruby Date class.

http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8/ChangeLog?…

http://redmine.ruby-lang.org/issues/show/2561

See http://devdriven.com/2007/03/ruby-date-rational-fixnumgcd-hack-increased-app-performance-by-15/ .

Ruby 1.8: Improved Rational performance by 15%

This should also speed up DateTime. This will not help 1.9 performance.

The attached file is based on MRI 1.8.6 rational.rb.

 > ruby rational_performance.rb 
                                              user     system      total        real
test_it                                  32.930000   3.030000  35.960000 ( 35.971832)
test_it                                  33.840000   2.910000  36.750000 ( 36.758585)
test_it ks_rational                      29.110000   2.460000  31.570000 ( 31.572762)

Overview:

  • case x; when Foo; ...; end is faster than if Foo.kind_of?(x).
  • Avoid recuring on ephemeral objects.
  • Avoid local variables, in-line expressions.
  • Avoid return in tail position.
  • String interpolation: "#{x}/#{y}" is faster than x.to_s + "/" + y.to_s.
  • Implement #-, #zero?, #nonzero? natively.
  • #abs returns self if > 0.

MRI 1.8.7 patch to follow shortly.

Abstraction .vs. Optimization

Abstractions can lead to greater flexibility and correctness at the expense of speed or size — there are good reasons that most programs are not crafted in machine code.

The key to improving an abstraction’s performance is to compile it. Dynamic environments like Common Lisp are superior to languages and tools like: Java, C++, and C#, in this regard, because one can create abstractions that compile to efficient code.

If the abstraction is cumbersome it might be a poor abstraction or its platform is poor for abstraction. Environments that give seamless access to a language’s compiler from inside the language itself are superior platforms for abstraction.

Ruby: Caching #to_s for immutables (and a possible future for constant-folding)

Reference: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/26869

I have a proof-of-concept patch to MRI that caches #to_s values for immutable values. It is implemented using a few fixed-size hash tables. http://github.com/kstephens/ruby/commits/to_s_maybe_frozen/

It reduces the number of #to_s result objects by 1890 during the MRI test suite for NilClass#to_s, TrueClass#to_s, FalseClass#to_s, Symbol#to_s, and Float#to_s.

It requires a minor semantic change to Ruby core. This minor change could cascade into a huge performance improvement for all Ruby implementations — as will be illustrated later:

#to_s may return frozen Strings.

This appears to not be a problem since any callers of #to_s are likely to anticipate that the receiver may already be a String and are not going to mutate it — #to_s is a coercion. The current MRI test suite passes if some #to_s results are frozen.

For code that may expect #to_s to return a mutable, an Object#dup_if_frozen method might be helpful. This method will return self.dup if the receiver is #frozen? and is not an immediate or an immutable. (Aside: a fast #dup_unless_frozen method might be helpful for general memoization of computations!)

This caching technique could be extended into other immutables (e.g.: the Numerics) and objects whose #to_s representations never change (e.g.: Class, Module?) and for #inspect under similar constraints.

In the patch, Fixnum#to_s is not cached because Fixnums are often incremented during long loops; any cache for it is quickly churned. However, this could be enabled if it proves useful in practice.

If this new semantic for #to_s is reasonable, I recommend explicitly storing frozen strings for true.to_s, false.to_s, nil.to_s and storing Symbol#to_s with each Symbol, likewise for #inspect.

In practice, most Ruby String literals become garbage immediately. If Symbol#to_s was guaranteed to be always be cached, this would enable the use of:

puts :"some string"

instead of

puts "some string"

as an in-line memoized frozen String that creates no garbage when calling puts which will call #to_s on its argument, but never mutate the result. A parser or compiler could recognize Symbol#to_s as an operation with no side-effect and elide it, providing a true String constant. This idiom would eliminate the pointless String garbage created by the evaluation of every String literal.

This is far more expressive and concise than:

SOME_STRING = "some string".freeze
...
puts SOME_STRING

The alternative to :"some string" might be to memoize all String literals as frozen. This is a superior syntax and semantic — old code would need to change on a massive scale, but any issues would be easy to diagnose:

str = ''       # Make a mutable empty string.
str << "foo"   # "foo" is garbage
str << "bar"   # "bar" is garbage

would become:

str = ''.dup   # Make a mutable empty string.
str << "foo"   # "foo" is not garbage
str << "bar"   # "bar" is not garbage

The latter is backwards-compatible with the current String literal semantics.