5 ms·
Reading this again, I realize that the variable name "sum" was chosen badly. I'll change that in the post.
by heinrichhartman 8y ago
Reading this again, I realize that the variable name "sum" was chosen badly. I'll change that in the post.
- lispm 8y agoNeither Ruby nor Python support the idea of 'code is data'. Sure they are simpler. The concept of code is data is not about simplicity, it's there to support code translations. Most languages have constructs which don't behave like function calls and which have special evaluation rules. A simple example is the IF statement. It takes a condition and two expressions. Depending on the condition only one of the expressions will be evaluated. If you look around, you'll find a bunch of such constructs in most languages. Lisp also has such an IF operator. Lisp additionally allows us to write any amount of additional operators which have evaluation rules, which are not the evalation rule of a function call. Is the IF statement irregular? It isn't. It's just one of many operators which does not follow the evaluation rule of a function call. Something like Ruby has a lot of weirdness in its calling mechanism. Python has strange non-local transfers going on. There are lots of ways we can perceive 'irregularities'.
- heinrichhartman 8y ago> Neither Ruby nor Python support the idea of 'code is data'. Well, Python and Ruby have an "eval" statement. So "code as data" is supported, but discouraged. In contrast Lisp macros / "code as data" are commonly used. Why is there a difference in culture? Is the only reason, that strings are a lot harder to manipulate than lists? Is there more to it? Maybe translated code is harder to maintain and reason about? Maybe debugging and profiling is a lot harder (this is true for C macros at least). I have just shared one confusion that I was struggling with. I found python and ruby much easier to read and pick up. One reason for this is, that programmers are not allowed to define new irregularities. Maybe this insight is helpful for others, who are getting Lisp as well. At least this was my motivation for writing this post.
- lispm 8y agoPython and Ruby use flat strings as input to eval. That's an entirely different thing. To do ANY useful code transformations one needs to parse it. Lisp code already comes in a hierarchical token tree. Ruby and Python represent code as text. That's what Lisp does, too. One has a file of code. But Lisp has something which neither Python and Ruby do: the text is actually a data structure: lists, strings, numbers, vectors, symbols. Lisp provides a function READ. You can read code: CL-USER 73 > (with-input-from-string (stream "(1 + 2)") (print (read stream)) (values)) (1 + 2) It returns a list of three items. This then makes it easy to compute valid code and execute it: CL-USER 74 > (with-input-from-string (stream "(1 + 2)") (let ((code (print (read stream)))) (rotatef (first code) (second code)) (print code) (print (eval code))) (values)) (1 + 2) (+ 1 2) 3 Then put it into a macro: CL-USER 75 > (defmacro infix (expression) (setf expression (copy-tree expression)) (rotatef (first expression) (second expression)) expression) INFIX CL-USER 76 > (infix (1 + 3)) 4 CL-USER 77 > (macroexpand '(infix (1 + 3))) (+ 1 3) T Better, and complete infix macros exist. Or use infix conversion during reading. Write your code with sections of a more conventional syntax: CL-USER 80 > (defun hypot (a b) "Compute the length of the hypotenuse of a right triangle with sides A and B." #I( sqrt(a^^2 + b^^2) )) HYPOT CL-USER 81 > (hypot 1 2) 2.236068 Just put a quote in front of the expression and enter it at the repl -> the result is the transformed code. CL-USER 84 > '#I( sqrt(a^^2 + b^^2) ) (SQRT (+ (EXPT A 2) (EXPT B 2))) There is nothing like this in Ruby or Python. If you look at a Lisp interpreter, it actually executes Lisp data as code. Macros transform Lisp data as code. This is far far away from what Ruby or Python do. Python provides some access to its AST - that's also far away from what Lisp does. Lisp macros don't define irregularities. They do code transformations. Stuff where the language designer/implementor of, say, Python refuses to provide a control structure, you can do it yourself in Lisp in a few minutes or you can spend years to implement really cool stuff. The Common Lisp object system started as a large portable library (with only very little system dependent code), which code be loaded into Lisp and which the provided a very elaborate object system. This also included some clever macro code. I think titles like 'The problem of Lisp' may need a bit more reflection and patience. What is new for you is old news for the Lisp community. The exact same problem report can be already read in Lisp books from the 1960s. It's a bit like blogging 'The world isn't flat!.;-)