What kind of material are you using in your study of Common Lisp?
/// -- The past is not more important than the future, despite what your culture has taught you. Your future observations, conclusions, and beliefs are more important to you than those in your past ever will be. The world is changing so fast the balance between the past and the future has shifted.
francoisrel...@email.com (Francois Reland) writes: > Wich is the right strucuture?
> (if (> Vble 4) > ((do if yes) > (do if yes)) > ((do if not) > (do if not)))
It is (if TEST-FORM THEN-FORM ELSE-FORM), where ELSE-FORM may be omitted. For example:
(if (> variable 4) (write-line "variable is greater than 4") (write-line "variable is not greater than 4"))
or omitting the ELSE-FORM:
(if (> variable 4) (write-line "variable is greater than 4"))
(I suspect someone will now write I should call FRESH-LINE first.)
> I mean, how can I separate the if-yes commands from the if-not's?
You can only have one THEN-FORM in an IF, so if there is another form after the THEN-FORM, it must be the ELSE-FORM.
If you need multiple forms in the THEN-FORM, you can use PROGN:
(if (> variable 4) (progn (write-line "variable is greater than 4") (write-line "(therefore it's also positive)")) (write-line "variable is not greater than 4"))
If there is no ELSE-FORM, it looks like this:
(if (> variable 4) (progn (write-line "variable is greater than 4") (write-line "(therefore it's also positive)")))
Or you can abbreviate with WHEN:
(when (> variable 4) (write-line "variable is greater than 4") (write-line "(therefore it's also positive)"))
COND can be useful for long if-then-elseif-then-else chains:
(cond ((> variable 4) (write-line "variable is greater than 4") (write-line "(therefore it's also positive)")) ((minusp variable) (write-line "variable is negative")) ((zerop variable) (write-line "variable is zero")) (t (write-line "variable is a small positive number")))
> Another question... how can I query for (not(> Vble 4)) (in this > example, it would be '<=' instead of '>', but with others).
You can use NOT, like you wrote:
(if (not (> variable 4)) (progn (write-line "variable is not greater than 4") (write-line "(not a very large number, then)")))
It works with WHEN too (or in any expression, for that matter):
(when (not (> variable 4)) (write-line "variable is not greater than 4") (write-line "(not a very large number, then)"))
There is also UNLESS:
(unless (> variable 4) (write-line "variable is not greater than 4") (write-line "(not a very large number, then)"))
<mdan...@andrew.cmu.edu> wrote in message news:20011201051600.F2173@emu... > On Sat, Dec 01, 2001 at 01:55:08AM -0800, Francois Reland wrote: > > Good morning.
> > Wich is the right strucuture?
> > (if (> Vble 4) > > ((do if yes) > > (do if yes)) > > ((do if not) > > (do if not)))
> > I mean, how can I separate the if-yes commands from the if-not's?
* Coby Beck | Advised by whom? IF looks right to me....
Me, I guess, but you would probably not have seen that, kill-files being rather coarse-grained devices to block one's view to shocking truths. Go look up the article I wrote on conditionals if you can read this.
The lack of an implicit progn in the if form is a hint that cond, which has an implicit progn for each branch, would be more appropriately used for bodies with side-effects and if for expressions.
/// -- The past is not more important than the future, despite what your culture has taught you. Your future observations, conclusions, and beliefs are more important to you than those in your past ever will be. The world is changing so fast the balance between the past and the future has shifted.
"Coby Beck" <cb...@mercury.bc.ca> writes: > <mdan...@andrew.cmu.edu> wrote in message news:20011201051600.F2173@emu... > > On Sat, Dec 01, 2001 at 01:55:08AM -0800, Francois Reland wrote: > > > Good morning.
> > > Wich is the right strucuture?
> > > (if (> Vble 4) > > > ((do if yes) > > > (do if yes)) > > > ((do if not) > > > (do if not)))
> > > I mean, how can I separate the if-yes commands from the if-not's?
> > However it is advised that you use the COND form instead of the above:
> Advised by whom? IF looks right to me....
IF winds up forcibly drawing in PROGN forms, which falls into the "isn't that artificially ugly?" category.
Two other possibilities:
(loop for v = (> vble 4) when v do (do-something) do (do-something-again) when (not v) do (do-something-else) do (do-something-else-again))
(if* (> vble 4) then (do-something) (do-something-again) else (do-something-else) (do-something-else-again))
But I think the latter would cause #Erik's head to explode, so it's not a terribly serious suggestion :-).
All in all, COND would seem the most natural choice of those available. -- (reverse (concatenate 'string "moc.enworbbc@" "enworbbc")) http://www.cbbrowne.com/info/multiplexor.html Instead of talking to your plants, if you yelled at them would they still grow, only to be troubled and insecure?
* cbbro...@acm.org | But I think the latter would cause #Erik's head to explode, so it's | not a terribly serious suggestion :-).
Thank you for your concern. :)
Note that if* is merely syntactic saccharin for cond. You have all the benefits of if* without either bad style or bad taste if you use cond.
/// -- The past is not more important than the future, despite what your culture has taught you. Your future observations, conclusions, and beliefs are more important to you than those in your past ever will be. The world is changing so fast the balance between the past and the future has shifted.
Erik Naggum <e...@naggum.net> writes: > * cbbro...@acm.org > | But I think the latter would cause #Erik's head to explode, so > | it's not a terribly serious suggestion :-).
> Thank you for your concern. :)
> Note that if* is merely syntactic saccharin for cond. You have > all the benefits of if* without either bad style or bad taste if > you use cond.
Stepping back a little bit, it's a _little_ irritating that there's not a convenient way to get an IF to encapsulate appropriate implicit PROGNs.
The creation of IF* apparently resulted from someone being _massively_ irritated by this, to the point apparently of desiring to redesign chunks of CL.
There's a bit of a parallel in the Arc stuff; apparently Paul Graham (and whomever else may be involved) wants to revisit some of the control structures. (Strangely enough, he seems to want COND to _get rid_ of the implicit PROGN; obviously people head in some different directions :-).)
I quite agree with him on the notion that DO is pretty painful to use; he phrases it as "do feels like object code."
The disagreements over "syntactic sugar" _don't_ make it evident to me that it's dramatically worthwhile to start everything all over from scratch. I'm not sure but that Arc couldn't be implemented atop a combination of CL macros and maybe a readtable or two.
And once they get around to trying to _implement_ something, there are vast quantities of implementational hoops that they'll have to jump through. - They haven't decided what pathnames will look like; - They haven't defined what their math libraries will look like; - They haven't described any sort of "virtual machine" or other sort of model of what code is allowed to believe it's running on.
The point to Arc seems to be to fix up the things Graham thinks are "crufty" about existing Lisps. He's certainly free to hold such opinions; the thing that seems broken about the idea is that it seems to throw out a whole lot of stuff that _isn't_ broken, infrastructure that involves a whopping lot of work to reimplement. -- (concatenate 'string "cbbrowne" "@cbbrowne.com") http://www.cbbrowne.com/info/wp.html Rules of the Evil Overlord #9. "I will not include a self-destruct mechanism unless absolutely necessary. If it is necessary, it will not be a large red button labelled "Danger: Do Not Push". The big red button marked "Do Not Push" will instead trigger a spray of bullets on anyone stupid enough to disregard it. Similarly, the ON/OFF switch will not clearly be labelled as such." <http://www.eviloverlord.com/>
* cbbro...@acm.org | Stepping back a little bit, it's a _little_ irritating that there's not a | convenient way to get an IF to encapsulate appropriate implicit PROGNs.
But what does progn mean to you? I read prog1, prog2, and progn with the same eye to _incidental_ side effects to a returned value, just in order to avoid really hairy expressions and deep nesting. The same thing may be accomplished with let*, of course, For some reason, I prefer implicit progns when I want bodies with several forms for pure side-effect, but do not see explicit progns as anathema to good style, like some other people.
It is not particularly hard to write an if macro that lets the third form start with then to mean progn, and the fourth form start with else to mean progn. The infamous else-if "problem" could then simply be a new if in the else-branch. No keywords, no magic, and standard navigability and formatting, with almost complete compatibility with existing Common Lisp code, unless they had functions or macros called "then" or "else", so it would be a very good idea to put this in a new package to avoid problems and not pretend it "is" Common Lisp. I am not at all sure this would buy anyone anything, however.
| I quite agree with him on the notion that DO is pretty painful to use; | he phrases it as "do feels like object code."
I only think DO is ugly if the step-form is identical to the init-form -- it is so common that it should have had support, but all suggestions are fairly ugly. (Like using a dotted list (var init-form . t), although I prefer (var #1=init-form #1#) which is at least conforming Common Lisp.) Otherwise, stepping multiple variables is far a superior technique to the usual one-variable looping constructs.
| I'm not sure but that Arc couldn't be implemented atop a combination of | CL macros and maybe a readtable or two.
If this is impossible, it is at _best_ due to incompetence. It would be _so_ smart of someone who wanted to build a new language to capitalize on existing compilers before he could build his own that it is _unthinkable_ for someone who should have known Common Lisp well who does _not_ harbor a personal grudge against Common Lisp to specifically circumvent such a possibility.
| He's certainly free to hold such opinions; the thing that seems broken | about the idea is that it seems to throw out a whole lot of stuff that | _isn't_ broken, infrastructure that involves a whopping lot of work to | reimplement.
Suppose there is an axis with language implementer on one end and user on the other. Let it be used to represent where the responsibility for implementing a feature lies. Common Lisp and Java would be on the far end towards the implementer, while Scheme and other toy languages would be on the far end towards the user. If you are a user, you want the language implementer to take care of things for you. If you are a lazy, egoistic implementer, you want the user to take care of most things for you, but if you are conscientious implementor, you realize that the user community benefits greatly from a common implementation of a lot of functionality. It is odd that Arc goes in the "user" direction when the languages that Paul Graham appears to think have had success are all based on baking almost everything useful into the language implementation.
/// -- The past is not more important than the future, despite what your culture has taught you. Your future observations, conclusions, and beliefs are more important to you than those in your past ever will be. The world is changing so fast the balance between the past and the future has shifted.
Erik Naggum <e...@naggum.net> writes: > * Coby Beck > | Advised by whom? IF looks right to me....
> Me, I guess, but you would probably not have seen that, kill-files being > rather coarse-grained devices to block one's view to shocking truths. Go > look up the article I wrote on conditionals if you can read this.
> The lack of an implicit progn in the if form is a hint that cond, which > has an implicit progn for each branch, would be more appropriately used > for bodies with side-effects and if for expressions.
I thought that was a very good argument for COND in this case. For a newbie, though, I would advise using COND all the time. Tell them about IF, then say, "but use COND for now." Why? Because using IF traps you in the little world of IF. It's ugly to have more than one condition, and it's ugly to have more than one them or else clause. I use COND unless I know for certain that I won't need more than one clause, nor will I need to use PROGN in either of them. Because I tested myself, and I'll avoid nested IFs and PROGNs in then/else clauses when I use IF -- I assume because the operator itself discourages them.
So, whom? Me, too.
-- /|_ .-----------------------. ,' .\ / | No to Imperialist war | ,--' _,' | Wage class war! | / / `-----------------------' ( -. | | ) | (`-. '--.) `. )----'
> > * Coby Beck > > | Advised by whom? IF looks right to me....
> > Me, I guess, but you would probably not have seen that, kill-files being > > rather coarse-grained devices to block one's view to shocking truths. Go > > look up the article I wrote on conditionals if you can read this.
> > The lack of an implicit progn in the if form is a hint that cond, which > > has an implicit progn for each branch, would be more appropriately used > > for bodies with side-effects and if for expressions.
> I thought that was a very good argument for COND in this case. For a > newbie, though, I would advise using COND all the time. Tell them > about IF, then say, "but use COND for now." Why? Because using IF > traps you in the little world of IF. It's ugly to have more than one > condition, and it's ugly to have more than one them or else clause. I > use COND unless I know for certain that I won't need more than one > clause, nor will I need to use PROGN in either of them. Because I > tested myself, and I'll avoid nested IFs and PROGNs in then/else > clauses when I use IF -- I assume because the operator itself > discourages them.
The COND/IF controversy was among the first places I started to learn life lessons about how history is cyclic, and got a first-hand understanding of the idea that people who do not learn from history are doomed to repeat it. I've seen waves of people who grew up on IF going COND-crazy when they found out how it freed them of PROGN, and as many waves of people going IF-happy when they found out how it simplified out the extra parens for the simple cases. People do so love to have a simple answer and to not have the complex choice of deciding which to use on a case-by-case basis, but not until they just embrace the fact that it's a subjective choice and that sometimes one is better than the other and other times vice versa can they really rest.
I think the same of "time sharing" / "multiprocessing" was originally not in computers, then as computers grew became important to make efficient use of hardware, then as loads grew and machines got cheap became something people outgrew, and then as machines were found largely empty and wasted became more popular again, and ....
Client/side and Server/side computation has the same cyclic pattern of evolution, each becoming popular with companies, and so with headhunters, and so with universities, and then as quickly replacing the other again, until finally negotiated peer-to-peer stabilizes things in a recognition that neither client-side or server-side can really ever win...
So I say, take a few minutes out of talking about IF/COND to teach the ways of the world, and then once your students understand that dynamic tension that is just doomed to be present in life itself, come back and teach the IF/COND situation as a tiny little instance of it, and the whole debate will seem a lot less "big"...
> * Coby Beck > | Advised by whom? IF looks right to me....
> Me, I guess, but you would probably not have seen that, kill-files being > rather coarse-grained devices to block one's view to shocking truths. Go > look up the article I wrote on conditionals if you can read this.
You've never been in my kill-file! And I never look away from what shocks me anyway, truth or otherwise. Besides, I can't really say anything you write shocks me. On top of that I would have missed your "feeling one's teeth" discussion. (very entertaining!)
I read your article on conditionals, at least most of it and skimming the rest. I guess for me the number of branches rather than side-effects or not guides my choice of IF or COND. I guess it was mostly the passive tense "it is advised" phrase that made me want to point out that is hardly a universal axiom of IF that more than on form in a branch means it should be a COND.
> The lack of an implicit progn in the if form is a hint that cond, which > has an implicit progn for each branch, would be more appropriately used > for bodies with side-effects and if for expressions.
This is a strong argument, though one more from tradition than other stylistic concerns. I still like the strong visual signal an IF form gives you that there are two and only two branches. Variety is the spice of life, I like very much that lisp provides so many ways to express your code. -- Coby (remove #\space "coby . beck @ opentechgroup . com")
> Suppose there is an axis with language implementer on one end and > user on the other. Let it be used to represent where the > responsibility for implementing a feature lies. Common Lisp and > Java would be on the far end towards the implementer, while Scheme > and other toy languages would be on the far end towards the user. > If you are a user, you want the language implementer to take care > of things for you. If you are a lazy, egoistic implementer, you > want the user to take care of most things for you, but if you are > conscientious implementor, you realize that the user community > benefits greatly from a common implementation of a lot of > functionality. It is odd that Arc goes in the "user" direction > when the languages that Paul Graham appears to think have had > success are all based on baking almost everything useful into the > language implementation.
I get the impression that while the language itself will have less baked into it, there will be repositories ("huge libraries") of code for the user to take advantage of. --Like perl's CPAN.
cbbro...@acm.org writes: > (loop > for v = (> vble 4) > when v > do (do-something) > do (do-something-again) > when (not v) > do (do-something-else) > do (do-something-else-again))
There's two problems with it: (1) you're going to loop forever, and (2) you're second do's will always get executed since do introduces an implicit progn and the second do introduces a new clause.
Combine those observations with the fact that when and unless as loop keywords support an else clause and we get:
(loop for v = (> vble 4) repeat 1 when v do do-something do-something-again else do do-something-else do-something-else-again)
You may even repeat the when by if ;-)
-- Lieven Marchand <m...@wyrd.be> She says, "Honey, you're a Bastard of great proportion." He says, "Darling, I plead guilty to that sin." Cowboy Junkies -- A few simple words
My mistake -- I thought had said you did, once. My apologies.
| I guess it was mostly the passive tense "it is advised" phrase that made | me want to point out that is hardly a universal axiom of IF that more | than on form in a branch means it should be a COND.
I hope style is not considered "axiomatic" anywhere.
* Erik Naggum
> The lack of an implicit progn in the if form is a hint that cond, which > has an implicit progn for each branch, would be more appropriately used > for bodies with side-effects and if for expressions.
| This is a strong argument, though one more from tradition than other | stylistic concerns.
| I still like the strong visual signal an IF form gives you that there are | two and only two branches.
That seems like a reasonable rationale, but it appears to me (i.e., pretty weak certainy) that most of the uses have one branch with a single form, like return or error, and the other a larger body of something. I tend to use one-branch conditionals and know that that branch terminates the function or asks the operator to fix an error -- sometimes one can turn an error into a continuable error, then the function should not simply error out
| Variety is the spice of life, I like very much that lisp provides so many | ways to express your code.
I second that.
/// -- The past is not more important than the future, despite what your culture has taught you. Your future observations, conclusions, and beliefs are more important to you than those in your past ever will be. The world is changing so fast the balance between the past and the future has shifted.
* Ed L Cashin | I get the impression that while the language itself will have less | baked into it, there will be repositories ("huge libraries") of code | for the user to take advantage of. --Like perl's CPAN.
My impression of the CPAN is that it is a whole bunch of code of very dubious and uncertain quality, and not at all what I would want to base anything on in a real project. It is fine for the kinds of things that Perl is used for. Why anyone would want a piece of that market eludes me. Perl should reign supreme in that corner and not cause anything else to be polluted by its mind-set.
/// -- The past is not more important than the future, despite what your culture has taught you. Your future observations, conclusions, and beliefs are more important to you than those in your past ever will be. The world is changing so fast the balance between the past and the future has shifted.
> Coby Beck > * Erik Naggum > > The lack of an implicit progn in the if form is a hint that cond, which > > has an implicit progn for each branch, would be more appropriately used > > for bodies with side-effects and if for expressions.
> | This is a strong argument, though one more from tradition than other > | stylistic concerns.
> | I still like the strong visual signal an IF form gives you that there are > | two and only two branches.
> That seems like a reasonable rationale, but it appears to me (i.e., > pretty weak certainy) that most of the uses have one branch with a single > form, like return or error, and the other a larger body of something.
I think I'll start examining the way I use IF and see if this is not the case, it sounds likely. I have to admit having extablished some of my usage patterns based on thinking it ugly to use return-from forms in the middle of functions. But I can see how doing that together with using WHEN and UNLESS as primarily error-throwing and return-from code prevents these exit points from hiding.
Actually, now that I think about it, this is exactly the right fix for a real head-shaker of a function I inherited at one job.
(if (something) (progn 200+ lines) (error (couldn't get database handle)))
(nested in another identical if statement, BTW)
That was a real headache to read. Obviously this should have been: (ignoring the simple improvement of breaking it into smaller functions)
Erik Naggum <e...@naggum.net> writes: > * Ed L Cashin > | I get the impression that while the language itself will have less > | baked into it, there will be repositories ("huge libraries") of code > | for the user to take advantage of. --Like perl's CPAN.
> My impression of the CPAN is that it is a whole bunch of code of very > dubious and uncertain quality, and not at all what I would want to base > anything on in a real project. It is fine for the kinds of things that > Perl is used for. Why anyone would want a piece of that market eludes > me. Perl should reign supreme in that corner and not cause anything else > to be polluted by its mind-set.
It is true that you have to examine a module from CPAN for quality before choosing to make use of it, but I have found that most of the modules that become popular are stable, usable code.
It can be a real life-saver to find out that someone else has already done the groundwork -- and done it well -- on a new challenging area. It can make the difference between saying, "Yes, we can do that," or, "We will get back to you."
Many languages preach code reuse and modularity, but the CPAN repository is, as far as I know, the greatest example to date of modular code sharing.
> Many languages preach code reuse and modularity, but the CPAN > repository is, as far as I know, the greatest example to date of > modular code sharing.
I have to second that. In fact, I'd go further and say that CPAN is the _ONLY_ reason I would consider valid for using Perl.
I guess you can tell from my (now aging) .sig that I once thought perl was rather cool... I guess we all grow up eventually. :-)
-- It would be difficult to construe Larry Wall, in article this as a feature. <1995May29.062427.3...@netlabs.com>
cbbro...@acm.org writes: > Erik Naggum <e...@naggum.net> writes: > > * cbbro...@acm.org > > | But I think the latter would cause #Erik's head to explode, so > > | it's not a terribly serious suggestion :-).
> > Thank you for your concern. :)
> > Note that if* is merely syntactic saccharin for cond. You have > > all the benefits of if* without either bad style or bad taste if > > you use cond.
> Stepping back a little bit, it's a _little_ irritating that there's > not a convenient way to get an IF to encapsulate appropriate implicit > PROGNs.
You can create a macro which expresses your own preference in programming conditionals.
> The creation of IF* apparently resulted from someone being _massively_ > irritated by this, to the point apparently of desiring to redesign > chunks of CL.
No, the design and implementation of IF* predates CL by several years.
[Note: I make no judgement for or against IF* here. It has pros and cons for its usage, just as IF and COND have pros and cons for their usage. Appropriate use is the key. As a personal style, I use all of the power of CL, including IF and COND, as well as IF*, and I also use WHEN and even UNLESS, which I also consider useful constructs (when appropriate). I would also not be adverse to using a new conditional macro designed by anyone, one which solved some of the problems which IF and COND have, as well as IF*'s problems.]
-- Duane Rettig Franz Inc. http://www.franz.com/ (www) 1995 University Ave Suite 275 Berkeley, CA 94704 Phone: (510) 548-3600; FAX: (510) 548-8253 du...@Franz.COM (internet)
In article <4667o44ii....@beta.franz.com>, Duane Rettig <du...@franz.com> wrote:
>cbbro...@acm.org writes: >> The creation of IF* apparently resulted from someone being _massively_ >> irritated by this, to the point apparently of desiring to redesign >> chunks of CL.
>No, the design and implementation of IF* predates CL by several years.
It should be noted that in the Lisp dialects that preceded CL, there were a preponderance of different IF macros. The version in PDP-10 Maclisp and Zetalisp had a single then-clause and an implicit PROGN for the else-clause, and this survives now in GNU Emacs Lisp. Multics Maclisp didn't have a built-in IF, but Multics Emacs had a version with 'then' and 'else' keywords (or maybe 'then' was implicit, I don't remember for sure).
For Common Lisp they deliberately chose a minimalist version, I think to avoid the political issue of picking one form over any other.
-- Barry Margolin, bar...@genuity.net Genuity, Woburn, MA *** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups. Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
Barry Margolin wrote: > It should be noted that in the Lisp dialects that preceded CL, there were a > preponderance of different IF macros. The version in PDP-10 Maclisp and > Zetalisp had a single then-clause and an implicit PROGN for the > else-clause, and this survives now in GNU Emacs Lisp. Multics Maclisp > didn't have a built-in IF, but Multics Emacs had a version with 'then' and > 'else' keywords (or maybe 'then' was implicit, I don't remember for sure).
This brings to mind the worst IF I ever saw: on the PL/1 -based Emacs in its Lisp on Prime minicomputers there was an IF where the then -branch returned a value, and the else -branch didn't (or was it the other way?). Made programming it a little convoluted.