Scheme as a "Real-World" Language?
A few thoughts (applicable to many languages besides Scheme as well)...
Although I have enjoyed reading through Prof. Dybvig's excellent book on Scheme, I still disagree about the utility of language. I'm trying to keep an open mind and I'm becoming more fluent in Scheme, but it still seems like a step backwards from modern languages. It is interesting and elegant, to be sure, but that may come at the price of not being useful enough for real work. IMHO, major issues for using Scheme on large projects include:
- Lack of standardization. In other languages, it's in more esoteric parts of the language where different implementations have slightly different language features. In Scheme, each implementation can have differences at a basic level. Sure, one could write syntactic extensions to port one to another, but it's not trivial.
- Lack of data typing. Schemers probably see this as a feature, but I'd rather let the compiler do the work of type checking. In fact, while the Scheme way is to ignore data structures as much as possible, for me the data structure is one of the most important parts of software design. The algorithms I typically write don't require lots of tail-recursion, data/code interchangeability, and 1st-class continuations. Instead, they involve operating on collections of data using functions associated with the data types.
- No standard OOP. This fits in with the previous point: there is no standard way to create objects and encapsulate functionality. Again, there are extra packages available to provide OOP, but there are a lot of different ones, and OOP seems to go against the philosophy of Scheme in any case. Even simple data/functionality encapsulation would be nice, but you have to roll-your-own system for tying procedures to a certain data structure. Is there a Scheme answer for the classic OO design patterns in the GoF book? (perhaps this book provides some answers)
- Feature-poor development environments. Of course, the geeks' motto is that "real geeks don't use IDEs", but those of us who like to get projects done appreciate productivity improvements. Context-sensitive command completion, variable type information, a steppable debugger, etc. each add a tremendous boost to one's "getting things done" factor. Emacs might be able to provide a weak form of command completion, but Scheme's focus on syntax extension without core standards make this goal impractical. In addition, the lack of type checking removes much of the benefit of a good IDE. For a great discussion, see the paper by the authors of Dr. Scheme, where they discuss "the poor quality of programming environments for functional langugages", among other things. While the authors restrict their discussion to Scheme as a pedagogical tool, I think their comments apply in general to any language used for almost any purpose. Their criticism of emacs also rang true: "...the graphical capabilities of modern displays remain unexploited."
- Barely-useful debugger (a.k.a. Error in car: () is not a pair): If Chez Scheme would say, for instance, " "Error in car: () is not a pair on line 147, filename.ss", then it might be possible to be productive using the language; as it is, any fancy improvements to my net programming time due to language tricks are compensated for by oversights like this in the environments.
- "If you make mistakes you shouldn't be using a non type-checked language". I'll hapilly admit to making mistakes; my focus when I'm writing code is on solving a problem quickly and thinking about the high-level behavior I'm interested in (e.g. modelling aspects of cognition). I don't have the extra brainpower to remember the names/types/semantics of all the variables and functions I've written along with the complete API for the libraries I'm using. "Letting the compiler help" shouldn't be regarded with derision; don't forget that the computer is a tool -- a means to an end.
- Lack of standard libraries. Sure, there are various Scheme libraries around, but it's doubtful that any compare with the STL or the .NET framework.
- Bad libraries for GUI development. No Scheme libraries for building a GUI compare with visual designers in other language IDEs. The OOP paradigm seems well-suited to GUI objects, so there isn't much hope in this area.
- Syntactic Extensions increase maintenance cost. Reading a Scheme program incurs extra up-front time to decipher what is going on, because the language is intended to be extended with its macro facility. It's fun to extend the language (and necessary when the core language is so small) but this nonstandardization is difficult to cope with on a large project.
- Unnatural for understanding and commenting. The language syntax based on lists intentionally makes code and data look the same. This is great for writing programs that deal directly with source code, but it removes visual syntax cues, adding more time to the human comprehension process ("Hmmm. is this a procedure name or data in a list?") Scheme is elegant, but that's better for computers than people; we speak natural language, which isn't particularly elegant and has all sorts of redundancy built in to ease comprehension. This all has the side effect of making it difficult to place comments in a reasonable location in the code, because the order of operations in the syntax is often reverse from the order in which we think about things.
- Consider the following chunk of supposedly high-quality Scheme code, typical of the entire sample. Note that there are only around 20 lines of (very terse) comments within the entire 700 line of source code; there are none nearby to explain this:
(((unquote . stuff) Dots)
(ellipsis? #'Dots)
(syntax-case syn (unquote ->)
(((unquote [MyCata -> Var ...]) Dots)
(andmap Var? #'(Var ...))
(with-syntax (((Temp) (generate-temporaries '(x)))
(Depth+1 (add1 depth)))
(values #'each-any
(cons #'Temp vars)
guards
(cons #'[Temp Depth+1 MyCata Var ...] cdecls))))
- "The best thing about Scheme is that it makes it easy to write a Scheme interpreter". That's good news for those studying programming languages, but the best thing about other modern languages, in contrast, is that they make it easy to write robust, understandable, well-documented, maintainable applications.
Some Useful Scheme Resources