64b6459784b4 — Sean Russell 1.0 12 years ago
Removes the commentary on Ruby and Go; fixes some of the usage documentation.
1 files changed, 25 insertions(+), 94 deletions(-)

M README.rst +25 -94
@@ 33,13 33,17 @@ You may also optionally configure it.
-- Ruby >= 1.8
+- Ruby >= 1.8 (for the Ruby version)
+- `Google Go <http://golang.org>`_ (for the Go version)
 - Mercurial >= 1.6 (for versioning)
-The application follows a simple contract:
+Currently, the Ruby and Go versions differ in behavior.  This will be fixed, to
+make the Ruby version behave like the Go version.
+The Ruby application follows this contract:
 - Any object X may descend from any objects B0, B1, ..., Bn
 - X inherits all attributes from all parents in a defined order

@@ 47,6 51,24 @@ The application follows a simple contrac
 - X is versioned
 - X must not be an ancestor of itself (a config forms a directed, acyclic graph)
 - Inheritance is determined at creation time, not at run time
+The Go application follows this contract:
+- An object X may descend from another object Y.  There is only a single
+  direct inheritance, but there may be multiple ancestors
+- The ancestor objects of X may or may not exist
+- X inherits all attributes from all parents
+- X may override any attribute inherited from a parent
+- X is versioned
+The Ruby version is entirely encapsulated in the file ``config.rb``; to run it,
+run ``ruby config.rb``, or ``ruby config.rb --help`` for usage instructions.
+The Go version must be compiled; run ``gomake`` to compile it -- the output is
+a native executable called ``conv``.  Run this to run the server.  Run ``conv
+--help`` for usage instructions.  Run ``gomake functional`` for the functional
+test suite; run ``gotest`` to run the unit tests.

@@ 116,98 138,6 @@ repo_dir
   The path to the version control executable (including the executable name
   itself).  Currently, only Mercurial is supported.
-An implementation note
-The original version of this application was written in Ruby, a language that I
-was once extremely well-versed in, but which I haven't used for anything but
-one-off command-line scripts in a few years.  It took me about 6 hours to write
-the thing.
-Out of curiosity, and since the project was so small, I decided to re-implement
-it in `Go <http://golang.org>`_.  This was the second time I'd looked at Go
-syntax; the first was to fix a small benchmark program that was comparing Go to
-`Vala <http://live.gnome.org/Vala>`_, so it really was the first time I'd
-written any Go; I was utterly unfamiliar with the packages.  This second version
-took me about 20 hours.  That time includes unit tests and a couple of
-refactorings to improve segregation of responsibility; I guesstimate that if I
-performed the same refactoring and writing unit tests for the Ruby code, I could
-probably spend another 6-10 hours -- on the one hand, I know the shape of the
-modules/packages; on the other, writing unit tests always takes a lot of time.
-`Cloc <http://cloc.sourceforge.net>`_ tells us this:
----------------------------- -------------- ------------ ----------------- ----
-Language                     files          blank        comment           code
-============================ ============== ============ ================= ====
-Go                               7            104             43            482
-Ruby                             1             59             55            326
----------------------------- -------------- ------------ ----------------- ----
-This excludes unit tests.  So here's my (subjective) take on this:
-- I'm frankly amazed that the Go LOC is so close to the Ruby LOC (33%
-  larger). If I refactored the Ruby code to be more well-structured and
-  encapsulated (and unit-testable), that LOC delta would shrink even more.
-- The Ruby program is a single, executable-and-library file.  This was
-  intentional.  I was able to break up the Go code into more files because the
-  end artifact would also be a single executable.
-- The Go compiler is wicked, stupid fast.  ``gomake`` is nice, in that it uses
-  standard Makefiles but provides includes to greatly simplify the Makefiles.
-- The Go unit test package is anemic, providing only the bare minimum of
-  functionality.
-- Go has such potential for mixing in, but the language spec disallows it (you
-  can only define functions on structures that are within your own package).
-- Even if I were as knowledgeable about Go as I am about Ruby, I'd still have
-  been able to whip the Ruby version out faster.  On the other hand, the Go
-  version is much safer, and I trust that program a *lot* more -- it is, after
-  all, type-checked.  I guarantee that no matter how much I look at the Ruby
-  code, if it runs for any length of time I'll eventually encounter a typing
-  error because of a bug in the code.
-- Go has an amazingly useful set of built-in libraries, without being package
-  and class bloated (like, say, Java).  Although, the crypto package is
-  curiously huge.
-- http://golang.org/pkg FTW!
-- Doing system exec stuff is easier in Ruby, but not by a lot.
-All in all, Go surprises me; it's concise, easy, encourages good separation of
-concerns, is easy to read, and much more functional in feel than you'd expect
-from looking at the tutorial. At the same time, it has some unfortunate quirks:
-it's (currently) relatively slow for a compiled language, and builds large
-executables; some language constructs are just baffling in their constraints,
-such as ``range`` only being applicable to a small set of built-ins, rather than
-working on some well-defined interface; tail-call optimization is extremely
-limited, which is such a shame for a language as close to being a functional
-language as Go is; and the lack of ability to mix in to extra-package types is
-To the first point in my list of Go quirks, I have no doubt that this will
-change rapidly, and Go will catch up; it's a very young language, after all.  As
-to the last point, the explanation put forth by the Go developers is, frankly,
-weak.  It's the same argument Gosling made about not supporting multiple
-inheritance in Java, which basically boils down to "programmers are stupid, and
-this feature will confuse them." I don't buy it; I'd rather have extra-package
-mix-ins with limitations based on technical merit than none at all.
-I've learned that I vastly prefer the cost of slower development time to gain
-reliability and safety, as long as the cost isn't too high.  Haskell is even
-safer, but it pushes the boundaries of how much pain I'm willing to endure
-trying to get code to pass through the type checker.
-Right now, I'm thinking Go's a keeper. It is more productive than C, more
-reliable than Ruby, easier than Haskell, is superior to Erlang in a whole host
-of ways I won't enumerate here (although, I do like the features that the OTP
-brings to the table, many of which are "killer" features unavailable in any
-other language, which keeps Erlang highly relevant), and is far better than Java
-in terms of simplicity, syntax, typing, threading, native compilation, and
-memory use. Each of these languages surpasses Go in their own ways, but I
-believe that Google has successfully found that sweet spot in a practical
-language that minimizes the annoying attributes and boiler-plate, and provides
-strong typing, resulting in a highly "writeable" language that compiles to
-native executables. We'll see how I feel with a few gross more hours under my

@@ 216,3 146,4 @@ Links
 * `Project page <http://redmine.germane-software.com/projects/configserver/wiki/Home>`_
 * `Status  <http://redmine.germane-software.com/projects/configserver/wiki/Status>`_
 * `Repository <http://hg.germane-software.com/ConfigServer/summary>`_
+* `Thoughts about Ruby and Go <http://goo.gl/S8IC9>`_