Playing with Racket
Racket — defn.io
I've been playing around with Racket every chance I got since early
September of this year.  This post is going to serve as a sort of
experience report of my foray into Racket so far.Things I LikeEditor SupportGreg Hendershott's racket-mode for emacs has been wonderful to
work with.  It provides syntax highlighting, REPL integration and
auto-completion as well as a macro stepper.  All of which are highly
useful while working on Racket code.DocumentationThere seems to be a huge emphasis on documentation within the
community, which is great.  Everything is thoroughly documented and
the documentation for installed packages is all built locally (with
cross-references!) so you have access to it regardless of
connectivity.  And it's pretty!  The Racket ecosystem has some of the
most readable websites I've ever been to.ConsistencyThe language is remarkably consistent, from the way modules and
packages are organized to the way documentation is written.Interactive DevelopmentDespite primarily working with dynamic languages every day, I find
that I don't use the REPL with those languages nearly as much or as
tightly as I do with lisps.  I don't know for sure why that is but it
probably boils down to the nature of s-expressions: it's just so
convenient to eval-last-sexp in lisps in a way that you can only
approximate in a language like Python (and, believe me, I've tried!).ContractsContracts are a way to specify and validate the boundaries between
parts of a system.  They are highly expressive (eg. in-range?) and
composable and produce great error messages when the invariants they
describe get broken.  Unfortunately, they do incur a runtime cost and
there's no way to disable them automatically for production, but they
can be specified separately from the implementation of the things they
describe such that you can add them to the functions and structures
that your module exports and even have "unsafe" flavors of your
modules from which you export versions of the same functions and
structs without contracts for those times when performance really is
an issue.For a cool-but-unrelated-to-Racket talk on contracts, check out
"Contracts For Getting More Programs Less Wrong" by Rob Simmons from
this year's Strange Loop.ModulesI really like the fact that you have to be explicit about what things
your modules export.  This reminds me a lot of ML-style languages and
is great for encapsulation.Things I Dislike"Dislike" may be too strong a word for what I'm about to describe.
Most of these things simply represent different tradeoffs to what I'm
normally used to.Error ReportingThis may just be because I'm not used to the error messages yet, but I
find Racket's exception reporting hard to decipher and I often run
into errors that contain no information regarding where in the
source code the error occurred.Lack of DocstringsThere's no built-in support for function docstrings and most of the
code I've read seems to separate code and documentation.  On the one
hand this makes it so looking up a function's documentation via the
REPL is not possible which is slightly annoying (though racket-mode
provides racket-describe for this purpose), but, on the other hand,
I like that there is a single documentation format that everyone
agrees on (Scribble) and the prevalence of cross-references makes
looking up a function's documentation easy enough.Unit TestingRacket's rackunit is lacking support for a few things I'd expect
from such a library.  There doesn't seem to be any built-in way to do
set up and teardown (I've been using dynamic-wind for this purpose),
the facilities for grouping tests together feel flimsy and I don't
understand why test-suites have to be run manually.