i am currently learning lisp (from LISP 3rd ed. Patrick Henry Winston) and i just got to the part on recursion. for example, to make a function that calculates an exponent you can multiply m (m^n-1). they have an example code using recursion for this:
(defun recur-expt (m n) (if (zerop n) 1 ( * m (recur-expt m (- n 1)))))
now how does interpreter program execute this? wouldnt it have to get caught in an infinite loop to execute it? to define recur-expt you need the definition for recure-expt, to define that recure-expt you need the defintion for recure-expt etc. so could somebody explain how this works? thank you.
"Cadwallader" <ccadw...@tampabay.rr.com> writes: > just got to the part on recursion. for example, to make a function that > calculates an exponent you can multiply m (m^n-1). they have an example code > using recursion for this:
> (defun recur-expt (m n) > (if (zerop n) > 1 > ( * m (recur-expt m (- n 1)))))
> now how does interpreter program execute this? wouldnt it have to get caught > in an infinite loop to execute it?
No. The if clause prevents this.
> to define recur-expt you need the > definition for recure-expt, to define that recure-expt you need the > defintion for recure-expt etc. so could somebody explain how this works?
I am fairly new to lisp too, but I try to through in mz 2-cents. Of course, anybody please correct me if am getting it wrong: The interpreter doesn't need the definition of recur-expt when it finds a function-call to it in a defun. defun defines a function, but doesnt execute it. The definition of recur-expt is only needed when there is a real function-call to it (while executing some code). So, when you call your function, it is already defined, and the interpeter can use it.
Example. If you defun something, you can put in nearly every kind of code, the errors while only arrise when you call it.
> i am currently learning lisp (from LISP 3rd ed. Patrick Henry Winston) and i > just got to the part on recursion. for example, to make a function that > calculates an exponent you can multiply m (m^n-1). they have an example code > using recursion for this:
> (defun recur-expt (m n) > (if (zerop n) > 1 > ( * m (recur-expt m (- n 1)))))
> now how does interpreter program execute this? wouldnt it have to get caught > in an infinite loop to execute it? to define recur-expt you need the > definition for recure-expt, to define that recure-expt you need the > defintion for recure-expt etc. so could somebody explain how this works? > thank you.
The four lines of code above defined 'recur-expt' completely. So your assertion that "to define recur-expt you need the definition for recure-expt" is incorrect. It would be correct to say " to execute recur-expt you need the definition of recur-expt," but that poses no problem at all, since by the time you are executing 'recur-expt', it has alreasy been defined.
Cad> (defun recur-expt (m n) Cad> (if (zerop n) Cad> 1 Cad> (* m (recur-expt m (- n 1)))))
Cad> now how does interpreter program execute this? wouldnt it Cad> have to get caught in an infinite loop to execute it?
This is a perfectly reasonable question to ask.
For more detail, you should consult a book on language implementation. There are several good books. I personally own copies of _The Essentials of Programming Languages_ by Daniel P. Friedman, Mitchel Wand, and Christopher T. Haynes; _LISP in Small Pieces_ by Christian Queinnec; and _Modern Compiler Implementation_ by Andrew W. Appel. The canonical language implementation book is _Structure and Interpretation of Computer Programs_ by Sussman et al, and the canonical compilers text is the Dragon Book (dunno what the actual title is) by Aho, Sethi, and Ulman. I haven't read the last two in this list, but I've read through the first three and they are excellent texts. Appel actually has three different versions of his book, one each for Standard ML, C, and Java. I own the Java version, and I'm considering buying the ML version as well.
Basically, as far as the translator is concerned (it's much the same for compilers as for interpreters), it sees your function as follows:
This is called an "abstract syntax tree" and in mentioned in greater detail in the texts to which I refer you. You should read this as each node in the tree being a structure of the named type, and each bit with ":name" being a field in the structure with the following as its value. My apologies if the representation I chose is confusing.
As you can see, the recursive call to RECUR-EXPT on line 4 of your function is treated by the translator as just another function call, not as some kind of macro expansion in which the text "(recur-expt m (- n 1))" needs to be replaced with the body of the RECUR-EXPT function.
HOWEVER, when one is writing a macro, then yes, one must make certain that the macro expansion process does terminate (and Very Bad Things happen when it doesn't). For example, let's re-write RECUR-EXPT as a macro which expands (RECUR-EXPT M N) into the appropriate number of calls to *:
Here, the macro is in control. Note that "(- n 1)" is evaluated at macro-expansion time, when previously it was evaluated at run time. Note also that the translator will expand all macros until there are no more macros, so:
(recur-expt-inline 3 2)
will expand (at translation time) in to:
(* 3 (recur-expt-inline 3 1))
then:
(* 3 (* 3 (recur-expt-inline 3 0)))
and finally:
(* 3 (* 3 1))
This last form is what is transformed into an abstract synax tree, and the macro itself is of no further importance.
Hopefully this makes sense. Abstract syntax trees are covered in much greater detail in the books to which I referred you. Macros are covered in much greater detail in _On Lisp_ by Paul Graham (another excellent book that I own).
Kind regards, #\X
-- UN-altered reproduction and DISSEMINATION of this IMPORTANT information is ENCOURAGED
Kenny Tilton <ktil...@nyc.rr.com> writes: > BTW, lots of compiled languages do not care if a function exists > when a call to one gets compiled, but they yell if by the time of a > second "link" step all such names have not been bound. I myself do > not know of any which like Lisp allow the function to be bound to > the symbol at runtime.
Java is another language with late binding.
-- vsync http://quadium.net/ - last updated Sat Oct 7 18:53:10 PDT 2000 (cons (cons (car (cons 'c 'r)) (cdr (cons 'a 'o))) ; Orjner (cons (cons (car (cons 'n 'c)) (cdr (cons nil 's))) nil))
* Xenophon Fenderson the Carbon(d)ated | Basically, as far as the translator is concerned (it's much the same | for compilers as for interpreters), it sees your function as follows: | | (FUNCTION-OF-N-ARGUMENTS | :arg-names-list ("M" "N") | :body ((IF-FORM | :test (FUNCTION-CALL | :func-name "ZEROP" | :arg-list ((VARIABLE-REFERENCE :symbol-name "M"))) | :then-clause (INTEGER-LITERAL :value 1) | :else-clause (FUNCTION-CALL | :func-name "*" | :arg-list ((VARIABLE-REFERENCE :symbol-name "M") | (FUNCTION-CALL | :func-name "RECUR-EXPT" | :arg-list ((VARIABLE-REFERENCE :symbol-name "M") | (FUNCTION-CALL | :func-name "-" | :arg-list ((VARIABLE-REFERENCE :symbol-name "N") | (INTEGER-LITERAL :value 1)))))))))) | | This is called an "abstract syntax tree" and in mentioned in greater | detail in the texts to which I refer you.
Which (Common) Lisp implementation did you dig this stuff out of?
If you made it up on the spot, and it looks like you did because you missed the fundamental idea in (Common) Lisp that symbols are not named in some silly "abstract syntax trees" by their _string_ names, would you apologize to the poor sap you lied to and retract it all?
#:Erik -- I agree with everything you say, but I would attack to death your right to say it. -- Tom Stoppard
* "Cadwallader" <ccadw...@tampabay.rr.com> | now how does interpreter program execute this?
A recursive function call is just a function call.
| wouldnt it have to get caught in an infinite loop to execute it? to | define recur-expt you need the definition for recure-expt, to define | that recure-expt you need the defintion for recure-expt etc.
You're actually asking about the way Lisp code is represented in memory more than how the interpreter (or even compiled code) executes the code. The function call (recur-expt m (- n 1)) is represented as a list with three elements: the symbol recur-expt, the symbol m, and the list of three elements: the symbol -, the symbol n, and the integer 1. But how did we get to the symbols?
When you type in expression to the Lisp, they function read is called upon to turn your textual representation into an in-memory structure that consists mostly of pointers to objects. One of Lisp's great and lasting ideas is that of having an external format for its internal memory structures and having reader and writer functions that convert between the two.
I'm sure you know how lists are represented in memory, so let's consider how symbols are read and represented. First, the reader collects all the characters that make up the name of the symbol. Then it looks up the symbol in the package (a named symbol table), or creates it there if it didn't already exist, and returns a pointer to the (new) symbol. This pointer is stuffed in the list.
The symbol itself has pointers to quite a number of things, among them the variable value and the functional value. When you define a function, you set the functional value slot of the symbol structure, but the neat thing is that the pointer to the symbol remains the same. The symbol also prints the same as before: with its name.
Through this indirection at two different times, we avoid the whole issue of referring directly to the function. The Lisp reader makes the list element refer to the symbol and when the interpreter needs to call the function, it looks up the functional value slot of the symbol and calls that value.
It's all exceptionally elegant and simple, and doesn't need any of the abstract syntax tree nonsense needed in other languages that haven't figured out that it's pretty damn smart to represent your code as a data structure from the get-go (I hope you ignored that elaborate explanation because it made no sense in a Lisp context).
#:Erik -- I agree with everything you say, but I would attack to death your right to say it. -- Tom Stoppard
> to define recur-expt you need the > definition for recure-expt,
In brief, no you don't. :) Try this;
(defun a () (b))
Your interpreter may give you a warning, or it may not. ACL does not, because all that happens at this point is that a note is made to call something called 'b at runtime. So with (defun a () (a)) (do not try that) by the same token the compiler just makes a note to call /something called 'a'/ when it gets to it at runtime.
Now try:
(a)
Now it is run time and your intrepeter actually tries to find B, you should get an error that function B does not exist. Had 'a been calling 'a, of course it would have found 'a and gone into a very tight loop. :)
now:
(defun b () (print "hello world"))
and try again;
(a) and you should see that all is well.The function is found at runtime.
Almost as an aside, some Lisps compile the whole thing then execute that. When the compiler gets to the recursive call to 'recur-expt, it does not panic because it already sees 'recur-expt is getting a definition (the function property of the symbol 'recur-expt is getting a value) and it inserts an instruction to call that symbol's function. It does not matter that that function is still being compiled, all it needs do then is to insert the instruction to call the function bound to the symbol 'recur-expt. I use ACL and that squawks if a called function does not exist when I compile, but not in the interpreter...but MCL compiles things entered in the Listener, so I wager it might squawk in the interpreter as well.
And if you are talking about an interpreter, hey, you can play the part of the interpreter by hand executing the code. What do /you/ do when you encounter the recursive call as you read the code? You go back to the beginning of the function and start a second trip thru with the new arguments...and now your only problem is making sure you have arranged things so that some trip thru does not lead to the invocation of 'recur-expt.
BTW, lots of compiled languages do not care if a function exists when a call to one gets compiled, but they yell if by the time of a second "link" step all such names have not been bound. I myself do not know of any which like Lisp allow the function to be bound to the symbol at runtime.
> i am currently learning lisp (from LISP 3rd ed. Patrick Henry Winston) and i > just got to the part on recursion. for example, to make a function that > calculates an exponent you can multiply m (m^n-1). they have an example code > using recursion for this:
> (defun recur-expt (m n) > (if (zerop n) > 1 > ( * m (recur-expt m (- n 1)))))
> now how does interpreter program execute this? wouldnt it have to get caught > in an infinite loop to execute it? to define recur-expt you need the > definition for recure-expt, to define that recure-expt you need the > defintion for recure-expt etc. so could somebody explain how this works? > thank you.
> i am currently learning lisp (from LISP 3rd ed. Patrick Henry Winston) and i > just got to the part on recursion. for example, to make a function that > calculates an exponent you can multiply m (m^n-1). they have an example code > using recursion for this:
> (defun recur-expt (m n) > (if (zerop n) > 1 > ( * m (recur-expt m (- n 1)))))
> now how does interpreter program execute this? wouldnt it have to get caught > in an infinite loop to execute it? to define recur-expt you need the > definition for recure-expt, to define that recure-expt you need the > defintion for recure-expt etc. so could somebody explain how this works? > thank you.
I'm totally an amateur at this, and have never had a computer course, but I did once write my own interpreter for LISP in BASIC on a machine with something like 16K of memory. What happens is that there's an area of memory organized as as "stack". The interpreter churns through the code and when it has to execute something like (+ a b), it pushes the "+" on the stack, evaluates a, pushes the result on the stack, evaluates b, pushes it. Then it goes down the stack looking for an operation, finds the "+", pops the top arguments and applies the "+" function to get the result. You can think of the stack as a way of organizing intermediate results of a calculation in a consistent way. Another way is to think of it as a reminder list that the interpreter writes for itself about what to do next. It turns out that the same idea works for a recursive function as for a non-recursive one one like "+". The interpreter calls recur-exp just like it did for "+". Since the "defun" has been executed previously, the code for "recur-exp" is sitting around in memory somewhere. With each call, it remembers that after returning it has to multiply the result by "m". After a finite number of recursions, the argument n is zero, the function returns 1 and the interpreter unwinds the stack. So for evaluationg it with m=10, the interpreter executes 20 or 30 pushes and pops of the stack in the background. Of course the interpreter can't make good on the implied promise of infinite recursion. If you change the "-" sign to a "+" in the definition, it will create a function that will create an infinite number of items on the stack. With a simple-minded interpreter and no protection from the operating system, something will blow up. On a free LISP interpreter (XLISP) I get a polite "error: argument stack overflow". I hope this has been helpful to you. It has been fun recalling the little Eliza Doolittle moments when I figured some of these things out.
In our last episode (Sun, 15 Oct 2000 18:59:30 GMT), the artist formerly known as Cadwallader said:
>i am currently learning lisp (from LISP 3rd ed. Patrick Henry Winston) and i >just got to the part on recursion. for example, to make a function that >calculates an exponent you can multiply m (m^n-1). they have an example code >using recursion for this:
>(defun recur-expt (m n) > (if (zerop n) > 1 > ( * m (recur-expt m (- n 1)))))
>now how does interpreter program execute this? wouldnt it have to get caught >in an infinite loop to execute it? to define recur-expt you need the >definition for recure-expt, to define that recure-expt you need the >defintion for recure-expt etc. so could somebody explain how this works? >thank you.
Certainly there's some _risk_ of an infinite loop, supposing the recursion function does not somehow succeed at "simplifying/reducing" the state.
For instance: (defun recur-oops (m n) (* m (recur-oops m (- n 1))) ... will never terminate, as it doesn't have any clause that _doesn't_ recurse.
On the other hand, the concern you seem to be having is of whether the recursive function can refer to its own name. Which is, frankly, not an issue at all.
Different compiler environments may evaluate function references a little differently, perhaps proposing inlining, if that improve performance.
But unlike languages like Pascal, Forth, and C, where there is some need to pre-declare variables/functions before referring to them, or some pretty special protocols to work around this need, it is perfectly acceptable for a function to refer to a function that has not yet been defined.
It matters not in what order I define: (defun addnmul (a b) (* (add2 a b) (add2 a 3))) (defun add2 (a b) (+ a b 3)) addnmul refers to add2, but I can define add2 later if I so desire.
And your "recur-expt" can have a reference to recur-expt inside it before the function has been fully defined. You won't want to _evaluate_ "recur-expt" before it has been fully defined, but that should not be much of an issue; you can hardly evaluate the function before you have finished defining it...
In effect, the function "name space" is dynamic; you can create a reference to a function name that does not yet exist. Of course, if you try to evaluate that unresolvable reference, you'll raise an error... -- aa...@freenet.carleton.ca - <http://www.hex.net/~cbbrowne/lsf.html> Nobody can fix the economy. Nobody can be trusted with their finger on the button. Nobody's perfect. VOTE FOR NOBODY.
* Kenny Tilton <ktil...@nyc.rr.com> | ACL does not, because all that happens at this point is that a note | is made to call something called 'b at runtime.
'b as read as (quote b)? Whatever does _quote_ do in this context?
I'll (reluctantly :) have to side with Barry Margolin on this one: People who think that it makes sense to write #'do and the like in text in order to half-pretend to be writing code in Lisp do more harm than good, and just as #'do doesn't even work, nobody calls 'b as a function. This is actually a case where the call is #'b, but in the interest of sanity, just keep it simple: It calls b.
#:Erik -- I agree with everything you say, but I would attack to death your right to say it. -- Tom Stoppard
On 16 Oct 2000 02:51:09 +0000, Erik Naggum <e...@naggum.net> wrote:
> I'll (reluctantly :) have to side with Barry Margolin on this one: > People who think that it makes sense to write #'do and the like in text > in order to half-pretend to be writing code in Lisp do more harm than > good, and just as #'do doesn't even work, nobody calls 'b as a function. > This is actually a case where the call is #'b, but in the interest of > sanity, just keep it simple: It calls b.
Would you mind expanding on this (or perhaps providing a pointer to where Barry wrote about this)? The reason I ask is that I am in the habit of writing #'foo when I'm talking about a function (in an effort to point out that I'm talking about a function) and I'd be interested to see how I'm doing more harm than good.
-- Take a look in Hagbard's World: | lbdb.el - LBDB interface. http://www.hagbard.demon.co.uk/ | sawfish.el - Sawfish mode. http://www.acemake.com/hagbard/ | uptimes.el - Record emacs uptimes. emacs software, including.......| quickurl.el - Recall lists of URLs.
>>>>> "Erik" == Erik Naggum <e...@naggum.net> writes:
Erik> Which (Common) Lisp implementation did you dig this stuff Erik> out of?
A Lisp implementation adapted from _The Essentials of Programming Languages_ by Friedman et al. While the language described in the book looks more Algoly than Lispy, my instructor for the course had us instead write a Scheme interpreter in Scheme to avoid a discussion of parsing. We used an abstract syntax tree (with various record types representing various primitive and non-primitive operations) to drive the interpreter, which seems to be a sensible design decision (vis. abstraction). In a later course on compiler construction, we revisited the topic and used the abstract syntax tree to drive the semantic analysis, optimization, and code generation phases of a simple compiler.
Erik> If you made it up on the spot, and it looks like you did Erik> because you missed the fundamental idea in (Common) Lisp Erik> that symbols are not named in some silly "abstract syntax Erik> trees" by their _string_ names, would you apologize to the Erik> poor sap you lied to and retract it all?
The individual's question was "how does recursion work?" with Lisp as the context, not "how could a Common Lisp implementation represent programs internally?". Hopefully, the answer I gave (along with showing him abstract syntax trees) was general enough to get this individual interested in language implementation in general, which is why I went through the trouble of tracking down the references I did.
So certainly, symbols in Common Lisp have not only a name (i.e. a string, usually converted internally to upper-case), but a package name and several other structure members that, along with the list structure syntax, make writing translators for Common Lisp much easier than in other languages. I apologize to the readership for willfully misleading them and recommend they add me to their filters immediately.
If you would, Mr. Naggum, please referencer me to the relevant literature that discusses modern alternatives to abstract syntax trees in interpreter and, especially, compiler construction.
Kind regards, #\X
-- UN-altered reproduction and DISSEMINATION of this IMPORTANT information is ENCOURAGED
| Would you mind expanding on this (or perhaps providing a pointer to where | Barry wrote about this)? The reason I ask is that I am in the habit of | writing #'foo when I'm talking about a function (in an effort to point out | that I'm talking about a function) and I'd be interested to see how I'm | doing more harm than good.
Check out this post:
From: Barry Margolin <bar...@genuity.net> Newsgroups: comp.lang.lisp Subject: Referring to #'<function> in text (was Re: Distance between two pts) Message-ID: <%f9w5.12$ge7.918@burlma1-snr2>
Jee, my NG does not show the original post, so I'll just respond to the ether in general....
Actually, until recently I would have written #'b, but I have always hated the shift key and have carpal tunnel syndrome, so now I just toss in a leading tick to make sure the referent stands out, seems more readable to me. As for sanity, boy, I gave up on that a while ago, feels terrific. (paraphrasing New Yorker cartoon)
Not sure how #'b is half-pretending anything, it seems to me quite precise to talk about calling a symbol's function--perhaps it is the assumption of Lisp-fluency that is objectionable?
Anyway, I consider my new octothorpe-free convention to be sloppy and am grateful that the text is being read by true natural language machines--they are so forgiving.
> * Kenny Tilton <ktil...@nyc.rr.com> > | ACL does not, because all that happens at this point is that a note > | is made to call something called 'b at runtime.
> 'b as read as (quote b)? Whatever does _quote_ do in this context?
No, not (quote b). This is in the British (perhaps Pythonesque) sense of "with antlers" or "without antlers", and here purely out of laziness I went with a one-antlered b to contrast it with b, which I am assuming is a special.
BTW, to avoid confusion, the above reference is to Python, not "Python".
Erik Naggum wrote: > would you apologize to the poor sap you lied to and retract it all?
where do you get off calling someone a liar because you disagree on the expansion of a function? and you pretend to be keeping this NG free of undesirables? not.
* Kenny Tilton <ktil...@nyc.rr.com> | Not sure how #'b is half-pretending anything, it seems to me quite | precise to talk about calling a symbol's function--perhaps it is the | assumption of Lisp-fluency that is objectionable?
You failed to recognize #'do as the example for what it is. That's pretty good for someone aspiring to sloppy. Keep it up!
| Anyway, I consider my new octothorpe-free convention to be sloppy | and am grateful that the text is being read by true natural language | machines--they are so forgiving.
Perhaps you should be a politician? You both lie like one and have figured out how to write nice words while being hostile. I'm sure almost nobody could see that you're seething, and they might even vote for you if you promised them something you couldn't deliver.
The solution to the shift-key problem is to use a computer that has a programmable keyboard so one can no longer blame it for the ills of having to type. The X Windows System has xmodmap, I'm sure the great _innovators_ in Redmond, WA, have managed to invent something about 10% as smart after the decade we have had X. Then there's Emacs (and some other programmable editors) that can do most of the work for you, and you can even teach Emacs or X not to require the normally intrusive modifier keys as simultaneous keypresses. The key to carpal tunnel syndrome or repetitive strain disorder (which is not actually caused by repetitive strain and is a problem whose occurrence pattern in groups and areas has no medical explanation, but is related to insurance companies' willingness to entertain the victims and the media coverage of the "problems" of new technology, just like we have had similar ailments and problems with every new technology, but the victims are no doubt in real pain and do suffer) is to get a more relaxed attitude to the movements required by the body in doing the work you want to do, not to regard the movements as a hindrance and annoyance. Most patients need medication and a sympathetic group of friends or co-sufferers to acquire this relaxed attitude.
Regardless of CTS or RSD, having to use the shift key to reach the parens and colon in particular are annoying to Common Lisp users. Just swap : and ;, and move () to were [] are, shift [], and move {} to where () were. Since Common Lisp has almost no use for =, swapping = and + helps, too. Additionaly, swapping ~ and ` might help unless you're writing more macros than format control strings, and so on. If your function keys are reasonably close to the top row of the keyboard proper (like Sun Type 4 keyboards), make them the shifted versions of the digit keys or something.
There's just no need to play victim in pain and explain that one does stupid things to other people with reference to a medically bogus syndrome or disorder. Just do the right thing, and let the computer help you in that most worthwhile of endeavors, don't fight it as if _it_ had caused the problems.
Just another helpful, constructive suggestion that is no dobut going to be read as hostile because the intended reader doesn't know how to read something for what it is and misplaces his irritation to begin with by effectively blaming # for his pain. Just get over it.
#:Erik, not quite the forgiving kind of guy -- I agree with everything you say, but I would attack to death your right to say it. -- Tom Stoppard
* Kenny Tilton <t...@liii.com> | where do you get off calling someone a liar because you disagree on the | expansion of a function? and you pretend to be keeping this NG free of | undesirables? not.
Since you know about this, where do _you_ get off deciding that it was simple _disagreement_ that caused me (conditionally, which you also ignored in your typical zest to blame me for something I don't do) to "call him a liar"? And has it occurred to you that someone is not a _liar_ simply because one has told a lie? I don't describe people, Kenny, I describe actions. You describe people, not actions. There's a word for your behavior: Undesirable. If you are intent upon continuing regardless of feedback and suggestions and hints, _you_ may become undesirable, too, but it will probably take a long time before you figure out the crucial difference between the adjective and the noun "undesirable" the way you're heading, and I very much doubt that I can say anything that will cause you to think about anything at all, anymore, because you prioritize people before truth, and for people who do that, there's only one chance: they have to rearrange their priorities before there is any hope at all.
By the way, what _is_ all this to you? Why is it so important to make an asshole of yourself by constantly proving that you judge and comment on people when you should judge and comment on their actions? What's the point to all this, Kenny? Do you think it's _right_ to judge people and not actions, perhaps? That's so under-evolved and so disturbingly brutal an attitude to justice that I wonder if you would survive if anyone treated you like that. Quit while you're alive and don't promulgate the idea that people aren't in control of their behavior, but must be branded and punished simply for being. It took mankind billions of unfairly lost lives to pay for the wisdom of the modern justice systems, yet we still have serious problems actually getting the message through to the population, especially with false group accusations like racism and the like, but if there is any hope for those living today, it is at least in the knowledge that the legal system isn't ruled by brutal mobs who lynch and kill people they don't like, regardless of what they did.
The mark of your evolution into a human being will be that you can listen to the experience of and the truth explained by someone you don't happen to like personally. You are not fully a human being if you disregard the truth if you believe that those who tell it are somehow incapable of truth and the same experiences that apply to you: That way lies the idea of sub-humans and group discrimination. Just exercise the intelligence you have and work hard at it if it doesn't come quickly to you, and you will grasp the idea that truth is independent of people, but has to be discovered by, propagated by, and held by people to work. Otherwise, untruth wins by default.
If I can keep your intellectually under-nourished attitudes at bay, Kenny, I can indeed pretend to keep this NG free of the undesirable that you (and some others) bring with them here. But it's not why I'm here, just like I'm interested in this aspect of society because I have to live in one with people who similarly destructive as you, not because I want to spend any time on it. Ideally, people would have parents and teachers who told them about justice and dispelled the notions that people _are_ bad because they _do_ bad. Some people _do_ bad because they _are_ bad, but some good people do bad, too, and the unfairness of treating them as bad people is the best way to turn good people into bad people. In fact, that's how the vast majority of bad people were created. It is in all our personal interests to see to it that we create as few bad people as possible and that we identify the few really bad people that are out there.
#:Erik -- I agree with everything you say, but I would attack to death your right to say it. -- Tom Stoppard
> | Would you mind expanding on this (or perhaps providing a pointer to where > | Barry wrote about this)? The reason I ask is that I am in the habit of > | writing #'foo when I'm talking about a function (in an effort to point out > | that I'm talking about a function) and I'd be interested to see how I'm > | doing more harm than good.
> Check out this post:
> From: Barry Margolin <bar...@genuity.net> > Newsgroups: comp.lang.lisp > Subject: Referring to #'<function> in text (was Re: Distance between two pts) > Message-ID: <%f9w5.12$ge7.918@burlma1-snr2>
Thanks for that, Deja still had it¹. I can fully see Barry's point and one thing I've always been careful of is function-quoting something that isn't a function. IOW I've always been careful not to place #' before the name of a macro.
I guess the point here is that #' is a desire to say "this is something you call" but that you can't always use it to mark something that you call. So, why bother, what not say "call <foo>" in the code?
Erik Naggum <e...@naggum.net> writes: > Regardless of CTS or RSD, having to use the shift key to reach the > parens and colon in particular are annoying to Common Lisp users. > Just swap : and ;, and move () to were [] are, shift [], and move {} > to where () were. Since Common Lisp has almost no use for =, > swapping = and + helps, too. Additionaly, swapping ~ and ` might > help unless you're writing more macros than format control strings, > and so on. If your function keys are reasonably close to the top > row of the keyboard proper (like Sun Type 4 keyboards), make them > the shifted versions of the digit keys or something.
please see below for some elisp that rebinds [] to (). i use it a lot. i'm sure it could be extended or that there are more general packages...
thi
__________________________________________________ RCS/square-braces-as-parens.el,v --> standard output revision 1.5 ;;; ID: square-braces-as-parens.el,v 1.5 2000/10/13 20:36:58 ttn Rel ;;; ;;; Copyright (C) 2000 Thien-Thi Nguyen ;;; This file is part of ttn's personal elisp library, released under GNU ;;; GPL with ABSOLUTELY NO WARRANTY. See the file COPYING for details.
;;; Description: Minor mode to bind parens to square-braces keys.
;;;###autoload (defvar square-braces-as-parens-mode nil "If non-nil, \"[\" and \"]\" insert \"(\" and \")\", respectively.")
In article <y16og0jaryy....@glug.org>, thi <t...@glug.org> wrote: > Erik Naggum <e...@naggum.net> writes:
> > Regardless of CTS or RSD, having to use the shift key to reach the > > parens and colon in particular are annoying to Common Lisp users. > > Just swap : and ;, and move () to were [] are, shift [], and move {} > > to where () were. Since Common Lisp has almost no use for =, > > swapping = and + helps, too. Additionaly, swapping ~ and ` might > > help unless you're writing more macros than format control strings, > > and so on. If your function keys are reasonably close to the top > > row of the keyboard proper (like Sun Type 4 keyboards), make them > > the shifted versions of the digit keys or something.
> please see below for some elisp that rebinds [] to (). > i use it a lot. i'm sure it could be extended or that there are > more general packages...
That's why Symbolics users **love** their keyboard. It's definitely the best keyboard on the planet. It's heavy (put into a guillotine you can kill people with it) and has the right touch. It has those "(", ")", ":", "'", Hyper, Super, etc. keys. And it has an ADB adapter for older Macs. :-)
Rainer Joswig <jos...@corporate-world.lisp.de> writes: > In article <y16og0jaryy....@glug.org>, thi <t...@glug.org> wrote: > > Erik Naggum <e...@naggum.net> writes:
[... regarding unshifted (. ). :, and others ... ]
> That's why Symbolics users **love** their keyboard. > It's definitely the best keyboard on the planet. It's heavy (put into > a guillotine you can kill people with it) and has the right > touch. It has those "(", ")", ":", "'", Hyper, Super, etc. keys.
...
And the "function keys" get larger the further they are from the home row. You can hit them reliably without looking. I miss those.