Madhu <enom...@meer.net> writes: > * Nicolas Neuss <878vywc43v....@ma-patru.mathematik.uni-karlsruhe.de> : > Wrote on Fri, 07 Jan 2011 13:04:04 +0100:
> |> > |> It solves a different problem. COMPRESS just removes repeated > |> duplicates. DELETE-DUPLICATES destructively removes all duplicates. > | > | You're right, it should be REMOVE-DUPLICATES, of course.
> No, that still removes ALL duplicates. I believe the requirement to > remove only consecutive duplicates, which is still different.
Thank you. You're right, of course. I should have read Thomas' message more carefully (not stopping at the word "destructively":-).
> Also, PUSH/PUSHNEW does not destroy or modify the original list, (as you > had implied, in an earlier post); these macros change the binding of the > variable to a new list which `shares structure' with the original list. > The original list is NOT destroyed or modified.
Yes I regretted that formulation immediately after I sent it. I wanted to say there that the PUSH macro is "imperative" modifying its second argument. (However, since complaining about the imperativeness of PUSH when recommending LOOP is somewhat gross, the best thing would probably have been to drop that point completely.)
>>> There's a school of thought among Lisp (well, CL, anyway) users that >>> you should never use CAR & CDR but rather FIRST & REST. I don't agree
>> I would certainly consider that to be a readability improvement. >> Using something with a verb-subject nomenclature would be even better: >> get-first, get-rest, pop-first, remove-first, etc.
> I would disagree here, because the verbosity introduced by "get-" does > not really help with understanding. In a functional setting, you would > expect that a function "gets" you a result. Similar with "pop-first" > and "remove-first". You should better teach people that simple lists > are constructed and accessed stack-like, i.e. only from one side (which > is from the beginning in Lisp).
I suggested that differentiation because it gives a clue as to what side affects the function has on the original data. FIRST could very well act as a pop, taking the first value out of the list and returning it to the calling function. For purely functional languages, this wouldn't be an issue as the source data could not be modified anyway; but, not all dialects of LISP are purely functional. Adding the verb makes explicitly clear exaclty what is going on.
In Erlang, and I suspect in several other functional languages, such a function is not needed because the because the language provides a pattern matching syntax that can be used to decompose the string:
[First | Rest] = List
>> Nevertheless, I wouldn't equate any programming language, which >> requires basic familiarity with the language, to be equivilant to >> psuedocode, visual diagrams, or basic descriptions and instructions in >> the user's native spoken language.
> They are different. Descriptions in standard language are usually > easier to understand, programs in any language are usually much more > precise. Being someone having posed a question in some newsgroup I > guess I would be grateful for both kinds of information.
Much agreed; but, my point is that code samples are only useful if you can make heads or tails of the language that they are written in. They don't have to be exact. Somebody who understands C++ will likely be able to make sense of an example written in Java. Somebody who understands Haskell could probably manage to interpret Erlang. Giving Erlang code to somebody who only knows Java is likely to cause quite a bit of confusion. The same might also be true vise-versa. I feel that it is important to at least try to make an effort to post examples in a language that the user is comfortable with.
> Visual diagrams can be nice too, but are so much work that a questioner > should better not expect them.
Discussion subject changed to "How to improve the readability of (any) LISP or any highlevel functional language to the level of FORTH ?" by Andrew Haley
In comp.lang.forth Xah Lee <xah...@gmail.com> wrote:
> On Jan 5, 8:21?am, Andrew Haley <andre...@littlepinkcloud.invalid> > wrote: >> Given that the article even manages to confuse Polish notation and >> Reverse Polish notation, I strongly recommend that everyone avoid it.
> I would certainly consider that to be a readability improvement. Using > something with a verb-subject nomenclature would be even better: get-first, > get-rest, pop-first, remove-first, etc.
I disagree about the GET- but - things should be assumed to be functional by default, with the marked form being the non-functional thing. Also, of course, they are only reasonable if you are thinking about lists not trees of paies.
> Nevertheless, I wouldn't equate any programming language, which requires > basic familiarity with the language, to be equivilant to psuedocode, > visual diagrams, or basic descriptions and instructions in the user's > native spoken language.
Descriptions in natural languages tend either to be ambiguous or spectacularly verbose (witness the entire legal profession).
> >>> There's a school of thought among Lisp (well, CL, anyway) users that > >>> you should never use CAR & CDR but rather FIRST & REST. I don't agree
> >> I would certainly consider that to be a readability improvement. > >> Using something with a verb-subject nomenclature would be even better: > >> get-first, get-rest, pop-first, remove-first, etc.
> > I would disagree here, because the verbosity introduced by "get-" does > > not really help with understanding. In a functional setting, you would > > expect that a function "gets" you a result. Similar with "pop-first" > > and "remove-first". You should better teach people that simple lists > > are constructed and accessed stack-like, i.e. only from one side (which > > is from the beginning in Lisp).
> I suggested that differentiation because it gives a clue as to what side > affects the function has on the original data. FIRST could very well act > as a pop, taking the first value out of the list and returning it to the > calling function. For purely functional languages, this wouldn't be an > issue as the source data could not be modified anyway; but, not all > dialects of LISP are purely functional. Adding the verb makes explicitly > clear exaclty what is going on.
> In Erlang, and I suspect in several other functional languages, such > a function is not needed because the because the language provides a > pattern matching syntax that can be used to decompose the string:
> In comp.lang.forth Xah Lee <xah...@gmail.com> wrote:
> > On Jan 5, 8:21?am, Andrew Haley <andre...@littlepinkcloud.invalid> > > wrote: > >> Given that the article even manages to confuse Polish notation and > >> Reverse Polish notation, I strongly recommend that everyone avoid it.
> Thank you, Xah. If I ever forget about RPN, I'll be sure to come > straight to you for a refresher. In the meantime, I suggest you fix > that article.
>> >>> There's a school of thought among Lisp (well, CL, anyway) users that >> >>> you should never use CAR & CDR but rather FIRST & REST. I don't agree
>> >> I would certainly consider that to be a readability improvement. >> >> Using something with a verb-subject nomenclature would be even better: >> >> get-first, get-rest, pop-first, remove-first, etc.
>> > I would disagree here, because the verbosity introduced by "get-" does >> > not really help with understanding. In a functional setting, you would >> > expect that a function "gets" you a result. Similar with "pop-first" >> > and "remove-first". You should better teach people that simple lists >> > are constructed and accessed stack-like, i.e. only from one side (which >> > is from the beginning in Lisp).
>> I suggested that differentiation because it gives a clue as to what side >> affects the function has on the original data. FIRST could very well act >> as a pop, taking the first value out of the list and returning it to the >> calling function. For purely functional languages, this wouldn't be an >> issue as the source data could not be modified anyway; but, not all >> dialects of LISP are purely functional. Adding the verb makes explicitly >> clear exaclty what is going on.
>> In Erlang, and I suspect in several other functional languages, such >> a function is not needed because the because the language provides a >> pattern matching syntax that can be used to decompose the string:
>> [First | Rest] = List
> What's wrong with
> (unify '(?first . ?rest) some-list)
1. My point in bringing up the Erlang syntax is that the sub-issue Antoniotti brought up, which only applies to purely functional languages where side affects cannot exist, doesn't exist for many purely functional languages. I maintain a preference for the verb form in LISP because:
A. it adds information for dialects where side affects are possible and
B. it mirrors a statement in English speech which is at the very least composed of a verb and a subject. The subject is sometimes implied. The verb is always necessary.
This point is at best a tangent to the main issue of the thread of conversation.
2. Back to the main issue, I didn't state that Erlang's syntax was any clearer or equated better to psuedocode. I made no claims to its superiority over any other syntax. I would not expect somebody who had not seem similar constructs before, to understand or make "heads or tails" out of it (pun intended). I can safely exibit it here because the meaning had already been discussed in a language that the parent understood.
3. I am sure your unify statement is perfectly readable to those familiar with LISP; but, that hardly passes for psuedocode for those who are not. I will give you an idea of what somebody without experience without LISP, another symbolic manipulation language, who as not other explanation of the statement, and who has not followed this thread might make of your statement:
A. To unify means to join. Therefore your function must join portions of a some-list using the DSL string to format how the portions are joined much like how "%02d" in C's printf (1) would specify how to interprate the remaining argument list. I am not really sure what the period refers to in this DSL.
(1) For those who are unaware, "%02d" as the first argument of printf(), which is used to display information on the terminal unless it has been redirected, would indicate to printf that it should have one other argument, that that argument should be interpreted as an integer, and that it should be displayed with a width of at least two characters with 0's to pad any missing higher digits. with 0's to pad any missing higher digits. with 0's to pad any missing higher digits. with 0's to pad any missing higher digits.
B. There must be a syntax error because the quote is unmatched.
C. The qustion marks must be sigils to indicate that these strings are to be interpolated as variables.
D. There is only one argument, so I must assume that the resulting join is saved to some-list and the first and last variables must be scoped to the outside context (whatever that happens to be for LISP).
E. Therefore, your statment, if you hadn't forgotten the closing quote, would join two lists placing something in between them where they are joined and saves this new list to some-list.
Even that is taking a lot of knowledge into account that I cannot even rid myself of. Somebody unfamiliar without LISP probably wouldn't even know that the first item is the function or that all of this has something to do with lists.
I reiterate my point: no programming language is intuitively obvious for those who have no familiarity with it. Knowledge derived from familiarity does not imply intuition. None of us are born with pre-knowledge of any programming language.
Tim Harig <user...@ilthio.net> writes: > On 2011-01-07, Tim Bradshaw <t...@tfeb.org> wrote: >> On 2011-01-07 02:19:24 +0000, Tim Harig said:
>>> This isn't merely a matter of >>> S-expressions but much more a result of cryptic standard function names >>> (car, cons, cdr, etc) that one needs to familiar with to understand what >>> is happening in a give piece of code.
>> There's a school of thought among Lisp (well, CL, anyway) users that >> you should never use CAR & CDR but rather FIRST & REST. I don't agree
> I would certainly consider that to be a readability improvement. Using > something with a verb-subject nomenclature would be even better: get-first, > get-rest, pop-first, remove-first, etc.
I'm just happy mathematicians don't name their functions get-sinus-of, get-cotangeant-of, etc.
Tim Harig <user...@ilthio.net> writes: > FIRST could very well act > as a pop, taking the first value out of the list and returning it to the > calling function.
Yes, but lispers don't like to shoot in their own feets. If an operators pops, then it's called POP, not FIRST.
>>> Nevertheless, I wouldn't equate any programming language, which
>>> requires basic familiarity with the language, to be equivilant to >>> psuedocode, visual diagrams, or basic descriptions and instructions in >>> the user's native spoken language.
>> They are different. Descriptions in standard language are usually >> easier to understand, programs in any language are usually much more >> precise. Being someone having posed a question in some newsgroup I >> guess I would be grateful for both kinds of information.
> Much agreed; but, my point is that code samples are only useful if you can > make heads or tails of the language that they are written in. They don't > have to be exact. Somebody who understands C++ will likely be able > to make sense of an example written in Java. Somebody who understands > Haskell could probably manage to interpret Erlang. Giving Erlang code to > somebody who only knows Java is likely to cause quite a bit of confusion. > The same might also be true vise-versa. I feel that it is important to > at least try to make an effort to post examples in a language that the > user is comfortable with.
Yes. However, lisp and scheme can be used for the same purpose, as proved by eg. SICP.
> Tim Harig <user...@ilthio.net> writes: > >>> Nevertheless, I wouldn't equate any programming language, which >>>> requires basic familiarity with the language, to be equivilant to >>>> psuedocode, visual diagrams, or basic descriptions and instructions in >>>> the user's native spoken language.
>>> They are different. Descriptions in standard language are usually >>> easier to understand, programs in any language are usually much more >>> precise. Being someone having posed a question in some newsgroup I >>> guess I would be grateful for both kinds of information.
>> Much agreed; but, my point is that code samples are only useful if you can >> make heads or tails of the language that they are written in. They don't >> have to be exact. Somebody who understands C++ will likely be able >> to make sense of an example written in Java. Somebody who understands >> Haskell could probably manage to interpret Erlang. Giving Erlang code to >> somebody who only knows Java is likely to cause quite a bit of confusion. >> The same might also be true vise-versa. I feel that it is important to >> at least try to make an effort to post examples in a language that the >> user is comfortable with.
> Yes. However, lisp and scheme can be used for the same purpose, as > proved by eg. SICP.
You are fighting a straw man. I never said the langauge was hard to learn or that it could not be used for teaching. Any language can used with a simple introduction. Even SICP feels the need teach its readers the fundimentals of s-expressions, mathematical expressions, assignments, conditionals, procedure definitions etc for LISP in the very first section and chapter of the book rather then simply throwing unexplained code at its readers. Why do you suppose that is.
Far more telling is the fact that it explains non-obvious primitive functions before they are used. You don't see SICP using list, cons, car, cdr, etc before being explained. The reader is never in the position to have to guess what a piece of example code is doing.
So no, SICP doesn't expect its readers to automatically understand the LISP language. It merely adopts a strategy of teaching them the langauge incrementally along with basic programming concepts as it goes. If the same level of care was being taken with posted LISP examples, I would not have felt the need to reply to this thread in the first place.
On 2011-01-08, Pascal J. Bourguignon <p...@informatimago.com> wrote:
> Tim Harig <user...@ilthio.net> writes: >> If the same level of care was being taken with posted LISP examples, >> I would not have felt the need to reply to this thread in the first place.
> Why should we include a lisp tutorial in each message to a generic > newsgroup showing lisp code, when
Because you are the one insisting that somebody else needs to learn yet another langauge just to read sample code rather then trying to find some common ground.
> 1- those tutorial are so easily accessible on the web,
So are tutorials for most other languages. I therefore assume that you thinks everybody else should learn your language that you should be just as eager to learn everbody elses.
> 2- the language is so simple that these tutorial mostly state the > obvious.
You assume that because it is obvious to you, who is already familiar with the language, that it is obvious to everbody else. I could make the same statement of any of the languages that I use. I could claim that Engish is more intuitive the Arabic. Most native English speakers would probably agree with me; but, I am sure people from the middle east would probably disagree.
If LISP is so obvious, then why do I have a LISP book that requires 600 pages to explain it? Why does SICP, your own example, need to teach the language throughout the book? Perhaps you would like to explain why somebody who has never encountered CDR should immediately understand its purpose?
The only difference between me with my language and you with your's is that I am objective enough to realize that people weren't born speaking my programming language; or any other.
That at least has the advantage to what most of us learned in elementry math class. The RPN version is only slightly less familiar to most of us. Both of them can be entered into commonly available calculators. Where do I buy a $20 LISP entry calculator?
But then, this is a contrived and overly simplified example. All languages look pretty simple when all you are doing is simple arithmetic. All of them get harder to follow when you add more functionality. My LISP book lists 129 primatives. I don't know about you, but I had to learn all of them *after* I was born.
> if you don't understand this expression without having to read the > previous explanations, perhaps you should not consider CS and > programming. Yes, I'd tend to take that as an IQ test...
No, it is a knowledge test. Somebody who has a IQ of 120 wouldn't have a clue about the meaning of those symbolic representations had they not been taught Arabic numerals and/or mathematics using "+-*" operators/functions. Or should I think you have a low IQ because you cannot solve equations written in Mayan? IQ is evident in how well you use them after you have learned their meaning.
Tim Harig <user...@ilthio.net> writes: > On 2011-01-08, Pascal J. Bourguignon <p...@informatimago.com> wrote: >> Tim Harig <user...@ilthio.net> writes: >>> If the same level of care was being taken with posted LISP examples, >>> I would not have felt the need to reply to this thread in the first place.
>> Why should we include a lisp tutorial in each message to a generic >> newsgroup showing lisp code, when
> Because you are the one insisting that somebody else needs to learn yet > another langauge just to read sample code rather then trying to find > some common ground.
>> 1- those tutorial are so easily accessible on the web,
> So are tutorials for most other languages. I therefore assume that you > thinks everybody else should learn your language that you should be just as > eager to learn everbody elses.
Why should *I* learn python or ruby or whatever to read your examples?
>> 2- the language is so simple that these tutorial mostly state the >> obvious.
> You assume that because it is obvious to you, who is already familiar > with the language, that it is obvious to everbody else. I could make > the same statement of any of the languages that I use.
Mostly, yes. A normal programmer should be able to understand an algorithm whatever the programming language used, even if he doesn't understand the fine details of the syntax.
Or said otherwise, if you write an algorithm in a programming language for human consuption, you should make it clear, and avoid any obfuscation.
> If LISP is so obvious, then why do I have a LISP book that requires 600 > pages to explain it? Why does SICP, your own example, need to teach > the language throughout the book? Perhaps you would like to explain > why somebody who has never encountered CDR should immediately understand > its purpose?
My point is that any programmer should have encountered CDR as well as BEGIN/END. After all, both are operators that are as old as computer programming.
> The only difference between me with my language and you with your's is > that I am objective enough to realize that people weren't born speaking > my programming language; or any other.
We're not talking about babies, we're talking about computer programmers.
> That at least has the advantage to what most of us learned in elementry > math class. The RPN version is only slightly less familiar to most of us. > Both of them can be entered into commonly available calculators. Where do > I buy a $20 LISP entry calculator?
Where do you buy a $20 calculator? It's been at least 20 years I've seen a calculator...
> But then, this is a contrived and overly simplified example. All languages > look pretty simple when all you are doing is simple arithmetic. All of > them get harder to follow when you add more functionality. My LISP book > lists 129 primatives. I don't know about you, but I had to learn all of > them *after* I was born.
But not after you became a programmer.
>> if you don't understand this expression without having to read the >> previous explanations, perhaps you should not consider CS and >> programming. Yes, I'd tend to take that as an IQ test...
> No, it is a knowledge test. Somebody who has a IQ of 120 wouldn't have a > clue about the meaning of those symbolic representations had they not been > taught Arabic numerals and/or mathematics using "+-*" operators/functions. > Or should I think you have a low IQ because you cannot solve equations > written in Mayan? IQ is evident in how well you use them after you have > learned their meaning.
No, IQ is how well you are able to guess or infer their meaning.
Babies don't have to read a grammar and a dictionnary to learn how to speak. Most programmers don't read language reference manuals either to learn a new programming language.
> Tim Harig <user...@ilthio.net> writes: >> On 2011-01-08, Pascal J. Bourguignon <p...@informatimago.com> wrote: >>> Tim Harig <user...@ilthio.net> writes: >>>> If the same level of care was being taken with posted LISP examples, >>>> I would not have felt the need to reply to this thread in the first place.
>>> Why should we include a lisp tutorial in each message to a generic >>> newsgroup showing lisp code, when
>> Because you are the one insisting that somebody else needs to learn yet >> another langauge just to read sample code rather then trying to find >> some common ground.
>>> 1- those tutorial are so easily accessible on the web,
>> So are tutorials for most other languages. I therefore assume that you >> thinks everybody else should learn your language that you should be just as >> eager to learn everbody elses.
> Why should *I* learn python or ruby or whatever to read your examples?
Which pretty much demonstrates my point. Why should anybody learn LISP to read yours? We have better things to do with our time and more advanced langauges to learn. With that, this conversation is basically finished.
>> If LISP is so obvious, then why do I have a LISP book that requires 600 >> pages to explain it? Why does SICP, your own example, need to teach >> the language throughout the book? Perhaps you would like to explain >> why somebody who has never encountered CDR should immediately understand >> its purpose?
> My point is that any programmer should have encountered CDR as well as > BEGIN/END. After all, both are operators that are as old as computer > programming.
So is the massively overloaded anachronism that is JCL's DD. I don't expect modern programmers outside of MVS to know how to use it either.
>> That at least has the advantage to what most of us learned in elementry >> math class. The RPN version is only slightly less familiar to most of us. >> Both of them can be entered into commonly available calculators. Where do >> I buy a $20 LISP entry calculator?
> Where do you buy a $20 calculator? It's been at least 20 years I've > seen a calculator...
I would suggest looking at your local office supply store.
Tim Harig <user...@ilthio.net> writes: > On 2011-01-08, Pascal J. Bourguignon <p...@informatimago.com> wrote: >> Tim Harig <user...@ilthio.net> writes: >>> On 2011-01-08, Pascal J. Bourguignon <p...@informatimago.com> wrote: >>>> Tim Harig <user...@ilthio.net> writes: >>>>> If the same level of care was being taken with posted LISP examples, >>>>> I would not have felt the need to reply to this thread in the first place.
>>>> Why should we include a lisp tutorial in each message to a generic >>>> newsgroup showing lisp code, when
>>> Because you are the one insisting that somebody else needs to learn yet >>> another langauge just to read sample code rather then trying to find >>> some common ground.
>>>> 1- those tutorial are so easily accessible on the web,
>>> So are tutorials for most other languages. I therefore assume that you >>> thinks everybody else should learn your language that you should be just as >>> eager to learn everbody elses.
>> Why should *I* learn python or ruby or whatever to read your examples?
> Which pretty much demonstrates my point. Why should anybody learn LISP to > read yours? We have better things to do with our time and more advanced > langauges to learn. With that, this conversation is basically finished.
Now, please explain why I can read algorithms written in python, PL/1 or Algol even while I never learned these programming languages?
(Granted, I'd have more difficulties with APL and perl, but Lisp is not like these language, it doesn't rely on syntax to convey meaning).
Tim Harig <user...@ilthio.net> writes: > On 2011-01-08, Pascal J. Bourguignon <p...@informatimago.com> wrote: >> Tim Harig <user...@ilthio.net> writes: >>> If the same level of care was being taken with posted LISP examples, >>> I would not have felt the need to reply to this thread in the first place.
>> Why should we include a lisp tutorial in each message to a generic >> newsgroup showing lisp code, when
> Because you are the one insisting that somebody else needs to learn > yet another langauge just to read sample code rather then trying to > find some common ground.
IIRC, we were starting from someone posing a programming question in a newsgroup. Assume that this person indeed got an answer with code in a programming language that (s)he does know. In my opinion, reasonable patterns of behaviour of this person could be:
- Wait for a better answer in another language (the chances are probably not bad if the newsgroup is language-agnostic and the previous answer used a "rare" language).
- Try to understand the code (maybe even by reading a tutorial on the unknown language). If necessary, ask about details. This would be the way of choice for a programmer with a little time and some self-respect.
What is not a reasonable pattern of behaviour (IMO) is to complain loudly about the impertinence of that answer. Remember that asking in newsgroups is not the same as paying for consulting.
Nicolas Neuss <lastn...@kit.edu> writes: > [...] newsgroup. Assume that this person indeed got an answer with code in a > programming language that (s)he does know. [...]
On 2011-01-08, Nicolas Neuss <lastn...@kit.edu> wrote:
> IIRC, we were starting from someone posing a programming question in a > newsgroup. Assume that this person indeed got an answer with code in a > programming language that (s)he does know. In my opinion, reasonable > patterns of behaviour of this person could be:
> - Wait for a better answer in another language (the chances are probably > not bad if the newsgroup is language-agnostic and the previous answer > used a "rare" language).
One could promote that; but, that tends to build barriers in communication between different groups of programmers. I don't really consider that to be a good thing.
> - Try to understand the code (maybe even by reading a tutorial on the > unknown language). If necessary, ask about details. This would be > the way of choice for a programmer with a little time and some > self-respect.
Some might do that, many won't or may not be able to do so. The fact that they have a problem indicates that they may not be the most autodidactic people to begin with. That being the case, having to deal with an unfamiliar language can confuse the issue even further and add interference to the lines of communication.
> What is not a reasonable pattern of behaviour (IMO) is to complain > loudly about the impertinence of that answer. Remember that asking in > newsgroups is not the same as paying for consulting.
People will be people. We cannot directly control their actions but we can modify how we respond to them so as to impact their future behaviors. I think you find posters more willing to modify their behavior for the better if they perceive an inviting community. Hostility is likely to be reflected back as hostility.
Once again we reach the top level of the stack in this conversation and return to the community issue. In the end, it is your collective choice the decides what actions you should take based on your goals. Somebody stepping up to provide the community with goals can have a strong positive impact whatever you decide your community means to you. A community without goals just tends to stagnate into the status quo.
On 2011-01-08 13:08:55 +0000, Marco Antoniotti said:
> Hey, I can throw in a few more punctuation characters. Can I get more > brownie points for that? :)
Yes, I think so. The trick is to try and sit on the border where it's clear you're not *just* taking the piss, but at the same time you *might* just be. Perl does very well here (as in most aspects of language design of course). Something like
bless([\%x, \%y], $C);
is really fine: it clearly does mean something, but what exactly is hard to tell. And notice the true mastery in the use of "\": one would naturally assume this was some kind of escape or quote for the next character, but in fact not at all, though in other contexts it is. Real brilliance.
Another improvement brought to mind by the above is the lack of obscurity in your naming. Anyone with the even slight knowlegde of computer science will realise immediately you're talking about some kind of graph-unification notion, and the meaning of the code will be very clear. Instead you should pick a term which is subtly compelling, yet non-standard and perhaps ambiguous. Perl's use of "bless" is a masterstroke of naming of this kind, only slightly spoiled by lack of capitalisation: "Bless" would, I think, have been better. In your case I think I would choose "Forge", which is both splendidly evocative (men wearing leather aprons hammering red-hot metal, lit only by the glow of coals and the evening light) and ambiguous.
Under no circumstances use internal capitalisation: this was once an interesting obfuscatory technique but is now considered extremely infra dig.
Discussion subject changed to "How to improve the readability of (any) LISP or any highlevel functional language to the level of FORTH ?" by Pascal Costanza
>>> Here is a (hopefully) rather perfect version using LOOP (it is more >>> complicated as the versions before because of the additional TEST and >>> KEY parameters[*]):
>>> (defun compress (list&key (test #'eql) (key #'identity)) >>> (loop for a in list >>> and key-of-a = (funcall key a) >>> and key-of-b = nil then key-of-a >>> and firstp = t then nil >>> unless (or firstp (funcall test key-of-a key-of-b))
>> Unfortunately, my hope was unjustified because this line should read:
>> unless (and (not firstp) (funcall test key-of-a key-of-b))
>>> collect a))
>> Nicolas
> Still not correct (I admit, LOOP can be a beast:-). Here is my final > word:
> (defun compress (list&key (test #'eql) (key #'identity)) > (loop for a in list > for key-of-a = (funcall key a) > and key-of-b = nil then key-of-a > and firstp = t then nil > when (or firstp (not (funcall test key-of-a key-of-b))) > collect a))
You can take advantage of the fact that variable scopes in LOOP forms are more liberal:
(defun compress (list &key (test #'eql) (key #'identity)) (loop for previous = (load-time-value (gensym) t) then current for element in list for current = (funcall key element) unless (funcall test previous current) collect current))
Pascal Costanza <p...@p-cos.net> writes: > You can take advantage of the fact that variable scopes in LOOP forms > are more liberal:
> (defun compress (list &key (test #'eql) (key #'identity)) > (loop for previous = (load-time-value (gensym) t) then current > for element in list > for current = (funcall key element) > unless (funcall test previous current) collect current))
For production-level code I would not use this approach, because the test is called with a (gensym) argument which might not be allowed by the caller.
Therefore I still stand by the version I posted at the end:
(defun compress (list &key (test #'eql) (key #'identity)) (loop for a in list for key-of-a = (funcall key a) and key-of-b = nil then key-of-a and firstp = t then nil when (or firstp (not (funcall test key-of-a key-of-b))) collect a))
I would be interested how this looks using SERIES or ITERATE.
>> You can take advantage of the fact that variable scopes in LOOP forms >> are more liberal:
>> (defun compress (list&key (test #'eql) (key #'identity)) >> (loop for previous = (load-time-value (gensym) t) then current >> for element in list >> for current = (funcall key element) >> unless (funcall test previous current) collect current))
> For production-level code I would not use this approach, because the > test is called with a (gensym) argument which might not be allowed by > the caller.
Right. There was also another bug in my version. Here is a better one:
(defun compress (list &key (test #'eql) (key #'identity)) (when list (cons (first list) (loop for previous = (funcall key (first list)) then current for element in (rest list) for current = (funcall key element) unless (funcall test previous current) collect element))))
* Pascal Costanza <8orfopFn1...@mid.individual.net> : Wrote on Sat, 08 Jan 2011 16:55:59 +0100:
| On 08/01/2011 16:40, Nicolas Neuss wrote: |> Pascal Costanza<p...@p-cos.net> writes: |> |>> You can take advantage of the fact that variable scopes in LOOP forms |>> are more liberal: |>> |>> (defun compress (list&key (test #'eql) (key #'identity)) |>> (loop for previous = (load-time-value (gensym) t) then current |>> for element in list |>> for current = (funcall key element) |>> unless (funcall test previous current) collect current)) |> |> For production-level code I would not use this approach, because the |> test is called with a (gensym) argument which might not be allowed by |> the caller. | | Right. There was also another bug in my version. Here is a better one: | | (defun compress (list &key (test #'eql) (key #'identity)) | (when list | (cons (first list) | (loop for previous = (funcall key (first list)) then current | for element in (rest list) | for current = (funcall key element) | unless (funcall test previous current) | collect element)))) |
I'd think you could still use the gensym kludge without calling the user supplied test routine on it, on the following lines: [I'll use DELETE-IF in my example because when TEST, KEY etc., are involved, I'd favour generic sequence functions over LOOP for production or rather publishing]
(defun compress (list &key (test #'eql) (key #'identity) &aux (prev #1='#:prev)) (remove-if (lambda (x) (prog1 (unless (eq prev #1#) (funcall test x prev)) (setq prev x))) list :key key))