4 ms·
For me the problem with Lisp is that it's just ugly to look at. Compare some Lisp code to an equivalent in Python, just in terms of the raw visual appeal of the
by d_burfoot 9y ago
For me the problem with Lisp is that it's just ugly to look at. Compare some Lisp code to an equivalent in Python, just in terms of the raw visual appeal of the text. The parentheses and indentations obscure the logical meaning of the code.
- KingMob 9y agoIt's interesting you mention Python, the only major whitespace-sensitive language. Many people have strong opinions about that, too, but like parens, it's not really relevant. Any decent Lisp editor will do automatic indenting, so you can still look at tab depth for meaning. You could always try Clojure, which swaps out () for [] and {} for various things (function arguments, bindings, array literals, map/set literals, etc.)
- lawpoop 9y agoHave a look at WISP, which I just found out about from this thread: http://dustycloud.org/blog/wisp-lisp-alternative/ http://dustycloud.org/blog/wisp-lisp-alternative/ LISP without parentheses.
- flavio81 9y agoPython and Lisp coder here. At first look, Lisp is ugly to look at. However once you start learning Lisp and writing your self programs, it becomes fairly easy to read not only your code but others' code. > The parentheses and indentations obscure the logical meaning of the code. Indentations have no effect in Lisp, they are only there to make code more readable. Parentheses are there to clearly tell you which statement is acting over which other statement, so they are there to give you a clear light about the meaning of the code. Visual appeal can be just fine, as long as the indentation is well-applied. The same is true for widely used languages like Java, C, C++, C#, and Javascript. Wrongly indented C code can be frustrating to read. Have this small, silly snippet of Common Lisp code and take a look. You should understand easily what each statement is doing. (defclass my-stack () ((name :initarg :name :initform "<Unnamed stack name>" ) (the-stack :initform () ))) So here we DEFine a class called "my-stack". With two members (or "slots") called "name" and "the-stack". "Name" will be an initial optional argument, with default value ("initial form") "<Unnamed stack name>" (defmethod into (item (s my-stack)) "Push an item into our stack" (with-slots (the-stack) s (push item the-stack))) Here we DEFine a silly method which pushes an item into an object S of type "my-stack". The explanation "Push an item into our stack" follows. Later what we say is, that, using the slot "the-stack", perform the following code: Push an item into the stack. Those two lines are almost English. (defmethod sum-all ((s my-stack)) "Return the sum of all items in our stack" (with-slots (the-stack) s (loop for item in the-stack summing item))) Here I show you that code can be really straightforward to read. Here to sum all the stack i use the following loop instruction: "loop for item in the-stack summing item" ... and it does exactly what it seems to be doing. It's just as if it was plain english! So one can write highly readable Common Lisp code if one wants to.
- kazinator 9y ago> Python and Lisp coder here. At first look, Lisp is ugly to look at. Maybe for you; Lisp was great for me to look at from the moment I laid eyes on it. Beauty is very subjective; but the technical advantages or disadvantages of a syntax aren't. Some years prior to becoming a Lisp programmer, I had one tiny interaction with Lisp that wasn't terribly good. It was this: some CLOS example code in a book on OOP by Grady Booch. I was trying to follow the syntax and it seemed to have weird repetition in it. That was arising from the defclass syntax for declaring accessors and initforms, like this (foo :initarg :foo) and (bar :accessor bar) type stuff. I was boggled by all the repetitions: why do we have foo and :foo, and so on. I had no clue about Lisp keyword symbols at that time. I didn't hate the syntax, and it seemed less verbose than C++, for sure. The parentheses in it seemed perfectly fine. It was just boggling a little bit: more so than something like (let ((x 2) (y 3)) (+ x y)), or (loop for x below 10 summing x).
- flavio81 9y ago> I was boggled by all the repetitions: why do we have foo and :foo, and so on. For what it's worth, here is my "defclass-easy" macro which will create a class with the slots you want, it also has a "required-slots" list as a parameter. Slots that are in both "slot-list" and "required-slots" will have an ":initarg" of the same name as the slot, and will raise an error if not supplied when making an object. Enjoy! (defmacro defclass-easy (class-name slot-list required-slots) ;;required-slots should be a list as well `(defclass ,class-name () ,(mapcar (lambda (x) (if (null(member x required-slots)) (list x) (list x :initarg (read-from-string (concatenate 'string ":" (string x))) ;creates :initarg :<slot name> :initform `(error ,(concatenate 'string "initarg required: " (string x)))))) ; (error "initarg required: xxxx") slot-list)))
- kazinator 9y agoIt's interesting to note that Lisp has some "def easys", just not for classes. There is a defsetf for simple situations, so you don't have to use define-setf-expander. defsetf's simplicity isn't one-size-fits-all either; it has a short form and a longer form. In the same area of functionality, there is define-modify-macro which handles simple cases, freeing the user from calling get-setf-expansion and dealing with its return values. P.S. (read-from-string (concatenate 'string ":" (string x))) ==> (intern (string x) 'keyword) `(error ,(concatenate 'string "initarg required: " (string x)) ==> `(error "initarg required: ~s" ',x)