Vsevolod Dyomkin, a Lisp programmer, writes about Common Lisp, algorithms, Clojure, and interviews with Lisp developers.
Commenters describe him as a known name in the Common Lisp community, linking his Clojure critique, list comprehension post, and algorithms book.
Pascal Costanza exemplifies a lot of what I love about Lisp. It's interesting to note that not too long before this was written, he was highly opinionated about the language in a very different way:
> I have participated in one of the first Feyerabend workshops, organized by Richard Gabriel, one of the main drivers behind the original Common Lisp effort. I have also read his book Patterns of Software around that time. Later we had a small discussion in the patterns discussion mailing list. He tried to promote Lisp as a language that has the "quality without a name", and I made some cursory remarks about Lisp's unnecessarily complicated syntax, just like anybody else who doesn't get it yet.
> To me, the most important comment he made in that discussion was: "True, only the creatively intelligent can prosper in the Lisp world." The arrogance I perceived in that comment annoyed me so much that it made me want to learn Lisp seriously, just to prove him wrong and show him that Lisp is not as great as he thought it is. As they say, the rest is history.
[http://lisp-univ-etc.blogspot.com/2012/04/lisp-hackers-pascal-costanza.html]
Once you begin to peek under the hood of the language, there's no end to the secrets it starts revealing and no end to the intellectual rewards it brings to curious (and yes, even arrogant) newcomers. P-cos has since gone on to do some of the most interesting work in Lisp since the ANSI standardization, such as ContextL. It would be interesting to see…
Things that also get my goat (from a less type theoretic point of view):
- Assuming that type checking is the only thing you might want to do with your program at compile time. There are, in fact, arbitrarily many things you might want to do at compile time. Textual preprocessing, expansion macros, type checking, C++ template metaprogramming, etc. are all obvious examples. The fact that most languages bolt all of these things on as one-off features is a sign that something deeper is being missed (perhaps the 3-Lisp[1] idea, for example, or just consider plain ol' Lisp macros).
- Assuming that totality, soundness, and lack of side effects are always type checking virtues. Sometimes I'd like a "typechecker" that isn't always guaranteed to terminate. Sometimes I'd like my typechecker to launch some missiles. This is really more about the previous point.
- Assuming that type checking is NOT desired at runtime. Sometimes it is. Clojure's core.typed has the property that it is "just code" and can therefore be run at anytime and used for things other than checking that your code is safe to ship. [2]
- Assuming that a program that fails type checking shouldn't be run. Maybe it should and the parts of the program that fail type checking should be run inside some monadic context. Maybe we want not only gradual typing, but gradual enforcement. Maybe if we had richer type data, then "failing type checking" wouldn't be binary. Perhaps a program that fails certain type checks has to…
Consider this snippet of C code:
struct foo {
int x;
}
Do you care how the structure definition is represented in your
compiler? is it a list, a vector or a custom data-structure? You don't
know, and it doens not matter to you. Besides, it is totally different
from what you manipulate at runtime (for type definitions, not
much). Consider the second snippet:
for(int i = 0; i < n; ++i) {
// something
}
Should the internal representation for the block delimited by braces
be necessary the same as the one used to represent the fields in the
previous structure? I mean, do the brace characters always map to the
same internal data-structure? Probably not. In C, the concrete syntax
has generally nothing to do with the abstract syntax. This is not the
case in Lisp, because each syntax is used to parse a specific type of
data.
In Clojure, you write #{...} and the reader (LispReader.java) sees the
sharpsign followed by brace and builds a set containing the values
inside the braces. That set is contained inside the AST, and acts as a
literal value. That value is shared among all invocations of your
code, meaning that if you call the enclosing function at different
places, the same literal object is shared. Since this data is
immutable, this is not really a problem because when you add more
elements at runtime, the original literal is not modified. OTOH, you
can still invoke EvalReader, #=(), which evaluates code at
read-time. I believe that you can…
> I think easily and uniformly programming disparate compute devices (CPUs, SIMD, GPUs, FPGAs, ISPs, DSPs, and eventually quantum) is the next BIG problem in programming languages.
The biggest challenge to producing a unified programming model across all of these is dealing with moving data around. CPU vs GPU vs FPGA all have very different memory access characteristics. Gary Sabot was the first to try to tackle the problem of dealing with memory layout/locality in a language with what he called the Paralation model (http://www.amazon.com/The-Paralation-Model-Architecture-Independent-Intelligence/dp/0262192772) and a lot of that work carried over into NESL (http://www.cs.cmu.edu/~scandal/nesl.html). Hadoop is a very lobotomized and hard to use modern version of these ideas.
I wouldn't knock DSLs - a lot of people are having good results using DSLs to program FPGAs (for example that's pretty much what http://www.novasparks.com/ does - http://lisp-univ-etc.blogspot.com/2013/06/lisp-hackers-marc-battyani.html).
You probably mean reader macros. Here are a few resources:
Hyperspec reference for predefined sharpsign reader macros: http://www.lispworks.com/documentation/HyperSpec/Body/02_dh.htm
A blog post where Vsevolod Dyomkin creates a reader macro to notate list comprehensions to his liking: http://lisp-univ-etc.blogspot.com/2013/01/real-list-comprehensions-in-lisp.html
A blog post where Inaimathi mentions using CLSQL reader macros to facilitate reading SQL expressions in code: http://langnostic.blogspot.com/2011/03/clsql-and-nothing-else.html
Let Over Lambda chapter 4 which has various examples: http://letoverlambda.com/index.cl/guest/chap4.html
Marijn Haverbeke, a freelancer hired by Mozilla to work on it mentioned that they plan on using it for their browser development to replace C++: http://lisp-univ-etc.blogspot.com/2012/04/lisp-hackers-marijn-haverbeke.html
"Rust is a programming language that's supposed to fit the C++ niche, without the insanity of actual C++. If the project works out, and it's going swimmingly so far, Mozilla will try to apply it to writing a next-generation browser, without the constant danger of buffer overrun exploits and threading bugs that comes with C++. True to Mozilla's spirit, all development on Rust is happening in the open, on github."