3 ms·
I don't think I read On Lisp the same way. From 3.1: "If a function is advertised as destructive, that doesn't mean that it's meant to be called for side-effect
by nonrecursive 12y ago
I don't think I read On Lisp the same way. From 3.1: "If a function is advertised as destructive, that doesn't mean that it's meant to be called for side-effects. The danger is, some destructive functions give the impression that they are. For example,(nconc x y) almost always has the same effect as (setq x (nconc x y))". Calling it dangerous sounds like a warning to me. I definitely agree, though, that he makes the case that the preferred approach is writing side-effect free functions. I'm not sure what you mean by "persistence" though, because Common Lisp doesn't have persistent data structures.
I don't know if its emphasis on functional programming and values makes Clojure unique, but that's definitely one of its core design concerns. The "article" is a chapter from a book on Clojure, and learning to write in a purely functional style is essential to learning Clojure. The point of the chapter isn't to get to the heart of what makes the language unique, it's to offer instruction on how to use it.
- brudgers 12y agoHere's the recycled cons at the car of ANSI Common Lisp section 12.4: Common Lisp includes several functions that are allowed to modify list structure. These functions are destructive for reasons of efficiency. Though they may receive conses passed to them as arguments, they are not meant to called for their side-effects. For example, delete is a destructive version of remove. While it is allowed to trash the list passed to it as an argument, it doesn't promise to do anything. This is what happens in most implementations: > (setf lst '(a r a b i a)) (A R A B I A) > (delete 'a lst) (R B I) > lst (A R B I) As with remove, if you want side-effects, you should use setf with the return value: (setf lst (delete 'a lst)) Because garbage collection and homoiconicity can sometimes feel like magic, it can be hard to think of Common Lisp running closer to the metal than a language like C. But it does. Cons cells are locations in memory, and symbols are pointers and there's nothing in between. A programmer doesn't even get `free(array)`. Memory locations can be shared willy-nilly because just as in Clojure, two distinct lists/sequences can share a tail. From ANSI Common Lisp section 12.8, "Constant Structure": > (defun arith-op (x) (member x '(+ - * /))) <function:arith-op> > (setf lst '(as it were) (AS IT WERE) > (nconc (arith-op '*) lst) (* / AS IT WERE) > (arith-op '-) (- AS IT WERE) ;; bad > (arith-op 'as) (AS IT WERE) ;; even worse "Oh Shit!" moments like this are why Lispers like Graham developed a functional programming style. It's a lot of what motivated the design of Scheme. It's not really what motivated Clojure because Java already solves this problem. Clojure is designed to solve the problems Java doesn't more easily. That fundamental goal is why what makes Clojure unique matters when explaining Clojure. It's also what makes Clojure a less than ideal vehicle for teaching functional programming style - it's designed for programmers who are solving problems on the JVM [or CLR or V8], and not really so much as a general purpose language. It's designed around interop. As weavejester says in his linked talk, Clojure is a Java library. There are better languages for teaching functional programming - Scheme/Racket. What makes them objectively better is that helping people learn to program in a functional style is one of the problems they are trying to solve, and they have almost four decades of development toward that goal. Education is entirely orthogonal to Clojure, even more so than Java with its two decades of introductory text development and promotion via vocational arguments in CS departments. And, Racket/Scheme isn't trying to solve JVM problems. Teaching functional programming style is hard, but a largely solved problem because the internet allows pointers to excellent materials. http://learncodethehardway.org/blog/AUG_19_2012.html http://learncodethehardway.org/blog/AUG_19_2012.html
- nonrecursive 12y agoYou're right about being able to point to the same tail from two different lists in common lisp, of course. I'm not very experienced with scheme so I can't comment much on that. Clojure is different in the way it implements its data structures, so "structural sharing" in that context refers to its use of tree structures to implement vectors, maps, etc. Still, though, I think you have it wrong about Clojure's design. You mentioned the talk "the value of values." Immutability and functional programming are core to Clojure's philosophy. This is pointed out on the clojure.org home page. I'm not sure why you think it's not? Also, Clojure is meant to be a general-purpose language. Also from the home page: "It is designed to be a general-purpose language". So I'm not sure why you think otherwise? I started learning Clojure with 0 experience with the JVM, and many others are doing the same. I'm also not sure what you mean by "education is entirely orthogonal to Clojure." I think you're commenting on the value of producing an introductory Clojure book? In any case - you mention that "there are better languages for teaching functional programming." The point of Clojure for the Brave and True is not to teach functional programming, it's to teach Clojure.
- brudgers 12y agoIf the purpose of Clojure for the Brave is not to teach functional programming, why bother teaching it? Why go through the motions when not fully committed? Is it better than pointing the student to excellent resources despite those resources using another form of Lisp? To put it another way, is anyone really going to know Clojure without knowing the something about SICP? Is there anything out there that more fully captures Clojure's definition of functional programming than On Lisp or Learn You a Haskell for Great Good? OK so here's where we differ. It's in our definitions [what could be more Clojuresque] of "learning Clojure". Sure, Clojure's syntax takes an hour versus the thirty minutes Ableson takes to cover Lisp syntax including the substitution model. Then what? Well I'm saying the two things a person needs to learn Clojure are the practices already described in four decades of Lisp's literature and the Clojure interop. Without either piece, I won't know Clojure. http://norvig.com/21-days.html http://norvig.com/21-days.html
- 12y ago