I want to learn some language from Lisp family. It may be CL or Scheme and try to use it for web programming. Just for fun. I have significant C++ experience (prefessional development).
But I want my choice be modern language without legacy (in language itself and library), because I want learn good design patterns from the start.
I can't decide what is better: CL or Scheme. CL has much greater and standartized library and frameworks (Weblocks), but I heard that it has MUCH开发者_如何学运维 of legacy in its syntax and libraries. Scheme is another: simple, concise syntax but poor library. I'd prefer CL if it has no legacy.
I don't like to learn another monster like C++. Is it true that CL is like C++ in Lisp family? And Scheme is like, say, C# or Java - "revised" C++.
Edit: I want to write in functional style, OOP may be, but optional.
Scheme has been invented in the mid 70s.
CL has been developed starting 1982. The first definition was published 1984: Common Lisp the Language.
That Scheme has no legacy or is more modern is a myth. Scheme has been defined before Common Lisp by almost a decade. Scheme still had legacy like s-expressions, cons cells, symbols, car, cdr, cons, and more. That Scheme has legacy makes it a member of the family of Lisp languages which has its roots in the first Lisp from 1958.
Scheme's initial goal was to be a small clean language that is closer to lambda calculus, than traditional Lisp. Thus lexical binding as a default in a Lisp language was a first.
Unfortunately it was a toy language in many other respects. It had only a very small set of features, features you would need for writing programs, like a useful form of error handling.
Common Lisp's design goals a decade later were different. It was designed to write commercial software, large software, performant software. Another goal was that it was in the tradition of the main line of Lisp dialects (here Maclisp), so that programmers who had already large libraries or programs would not start at zero.
Common Lisp added from day one a lot of features that were thought useful:
- lexical binding as a default
- records (called structures)
- a base library
- I/O
- type declarations
- argument lists with keyword arguments
- compiler hints
- a reader
and much more.
in the mid 90s a revision of CL was published. It added:
- an object system with an optional meta object protocol
- an extensive error handling system, the condition system
Since CL started bigger as Scheme, some design decisions make CL better to use than Scheme. For example Scheme has only primitive argument lists and that alone makes libraries harder to use.
Scheme had more revisions of its standard, but the basic design decisions remained and the community was struggling with basics like error handling, records, object system, etc. R6RS turned out to be controversial and I would agree with the critics. I think R6RS is extremely disappointing, both in its direction and its contents.
There are two other point of views: semi-standards and individual implementations.
The Scheme community produced a lot of semi-standard extensions. That should be viewed as a success.
The implementations OTOH diverged widely for Scheme. There was a is little consensus about them. There are many very small implementations and many large implementations.
CL implementations OTOH already contain a large language, so they don't start small. Keyword arguments are just there. Same for the object-system. Over time several applications have made sure that they can run mostly unchanged on many of the implementations. Additionally individual implementations have added a lot of features like Unicode support, threads, concurrent execution, etc etc.
So current Lisp implementations can have a lot of features.
Both Common Lisp and Scheme share the legacy of Lisp: symbols, s-expressions, car, cdr, cons, cons cell based lists, ... and more.
Common Lisp has some parts that are not so great, but are defined in the standard. One example is that CL symbol names are uppercase internally. The idea of 'sequences' is not extensible in the standard. And more. Individual implementations handle many of the limitations of the CL standard. So for example in most implementations the I/O system is written with CLOS, conditions are based on CLOS, there are extensible sequences for SBCL, and more.
CL may be a huge language, but it is no C++. Many parts are surprisingly well designed and easy to use. Many problems also can be repaired by the user, since Common Lisp is a programmable programming language. You don't like the built-in LOOP? Use ITERATE, if you like that more or even write your own.
Common Lisp has a lot of idiosyncrasies, several of them probably stemming from legacy (don't know my Lisp history well enough to say for sure). There's quite a few warts such as inconsistencies in function nomenclature and and argument orders. But the actual language itself is, although a bit odd in places, rather sane. Unlike, say, C++...
Scheme has warts too, but I'd think to a lesser extent. On the other hand, Scheme's standard library is tiny in comparison to CL's, so there's also less room for warts. :-)
Aside from plain CL and Scheme implementations, you also have a couple of "next-generation Lisps", such as Clojure (probably the most "modern" of them all - designed from the ground up for heavy concurrency) and newLISP, and the "next-generation Scheme", Racket (formerly known as PLT Scheme).
I'm personally quite impressed by Racket, and I hope I can use it for something, some day.
I'm a fan of Scheme because it was designed from the ground up to be consistent and simple, but still have advanced features not found in most other languages. For those reasons, it's especially popular in education and academia.
I'd recommend the book The Little Schemer and either Racket or Petite Chez Scheme (both are free) if you want to learn functional programming.
精彩评论