Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!cs.utexas.edu!samsung!think!think.com!barmar From: barmar@think.com Newsgroups: comp.lang.lisp Subject: Re: NCONC & Functions Keywords: Franz Message-ID: <31819@news.Think.COM> Date: 30 Nov 89 05:37:27 GMT References: <464@ntcsd1.UUCP> <465@ntcsd1.UUCP> Sender: news@Think.COM Distribution: na Organization: Thinking Machines Corporation, Cambridge MA Lines: 56 In article <465@ntcsd1.UUCP> mps@ntcsd1.UUCP (Michael Smith) writes: > But what really bothers me is this: (SYMBOL-FUNCTION foo1) evaluated >before the NCONC yields: > (NAMED-LAMBDA FOO1 NIL > (BLOCK FOO1 > '(A B C))) >After the NCONC, we get: > (NAMED-LAMBDA FOO1 NIL > (BLOCK FOO1 > '(A B C D E F))). >These look like different functions to me. Just because they look different doesn't mean they *are* different. That's the problem with destructive operations. Consider: (setq *foo* (list 1 2 3)) *foo* => (1 2 3) (nconc *foo* '(a b c)) *foo* => (1 2 3 A B C) The two values of *FOO* look different, but they are the same Lisp object. One of the fundamental concepts of Lisp is that programs and data are made up of the same "stuff". Therefore, when you NCONC a list that is in a program, you are modifying the program itself. By the way, Lisp is *not* unique in this regard. In C you are not permitted to modify a string that was created as a result of a literal string constant in the program. In implementations that don't put them on a read-only page you're likely to change the copy in the text section of the program. Consider the following program excerpt: func(x) int x; { char *string = "abcd"; if (x) string[0] = 'q'; printf ("%s ", string); } main() { func(0); func(1); func(0); } I believe that this will print out "abcd qbcd qbcd" in many implementations, because the string constant is modified during the second call. Barry Margolin, Thinking Machines Corp. barmar@think.com {uunet,harvard}!think!barmar