BowtieOrientedProgramming? comes along, for example, and everybody is raving about it as the next SilverBullet. However, proponents cannot produce external, obvious evidence that is convincing, often even to other co-proponents. (Co-proponents may agree with the benefits, but not the example as a demonstration tool.) No obvious improvement in OnceAndOnlyOnce, no dramatic reduction in code size, etc., are produced. Often the benefit is allegedly some kind of hard-to-measure change in mental process. The New Thing makes you "think better", but only if you "get it". The burning question is, "How can something be so great, not just slightly better, without leaving a good trail of evidence"?
Beware the LongTitlesSmell.
Alternative suggestions welcome.
Lisp is one of the older languages, and lacks the libraries. Fortran has almost the same age, and has TONS of libraries. Perl is young comparatively and has tons of libraries. PHP is even younger and has lots of libraries. Java too. Something must be bad with Lisp if only now their fans are trying to build a decent library base.
[The CommonLisp standard is largely about what would be libraries in other languages. One of the reason you don't find many libraries out there for CommonLisp to do mundane tasks is because they come standard with the language.]
I can't say I believe you. Yes, there are some libraries that come into CommonLisp, but there are lots of things to do out there. And you can't do it in CommonLisp, or ar least, not in a portable way. Even PaulGraham recognizes this:
[Quite aside from whether Lisp is a good or bad language, higher order functions themselves are so obviously a good thing, at least in some situations, at least in moderation, that there has never been any true counter-argument, to my knowledge, in all seriousness. One might as well demand to hear an argument in favor of floating point versus integer. Integer-only programmers may not grok the point of floating point, but that's their own private self-education problem, not by any means the start of an argument (despite the well-known problems with numerical analysis). Same thing with basic use of higher order functions. There's no debate, there are no sides, there is no subjectivity. There's knowing and there's not knowing, that's all.]
[I assume you personally do know higher order functions and you're just playing devil's advocate, but I disagree that that is appropriate on that particular topic.]
[Some things are in the "RTFM" category, basically meaning "I would die of shame before flaunting abysmal ignorance of such a basic topic that I could educate myself about so easily, and you should feel the same way, so stop flaunting and start reading." The question of why the entire gestalt of a language, whether Lisp, Haskell, Java, or whatever, is thought to be an effective choice, is not necessarily an RTFM matter. Utility of e.g. floating point or higher order functions is.]
I would further invite the proponents of various languages to provide any examples they can find of ObjectiveAdvantagesOfLisp, ObjectiveAdvantagesOfCee, ObjectiveAdvantagesOfOo, ObjectiveAdvantagesOfFp, ObjectiveAdvantagesOfRelational, and so forth.
If there is no such thing, then can we respect each other's choices without making them feel inferior for not buying into your pet technology?
This whole page is about pain and pain avoidance. Fear of feeling inferior. Why not simply acquaint yourself with many a tool and transcend them? One has lots of time to slowly get to know many ideas. Defining yourself with respect to a toolset is one of the most self-destructive things one can do.
That may be so. Then again, it may not. I did not write any of the above, so I do not pretend to know exactly why it was written. Still, I can imagine reasons for writing it other than "Fear of feeling inferior." Personally, I work primarily with PerlLanguage and a little bit of CeeLanguage most of the time. This does not stop me from recognizing the many advantages of LispLanguage, and it does not keep me from seeing the validity of the points being made by the SmugLispWeenies.
Question: why have you not abandoned Perl for Lisp? I agree that Lisp is a good language. However, some sell it as a SilverBullet.
I'm the PerlLanguage user above. I'm not sure which place to put this answer to make the most sense. Refactoring welcome.
I have not abandoned Perl for Lisp for lots of reasons. I work at a university. What code I write is usually in the service of some other in-house project. There are several other people in-house who know Perl but do not know Lisp, and do not want to learn. We have lots of custom library code in Perl (much written by yours truly).
Perl has higher order functions. It has closures. It has TailCallOptimization (though you need to ask for it with the MagicGoto). It has a decent package system. It has enough ObjectOrientedProgramming capabilities to do what I need. It has garbage collection (although it is just reference counting). It can do some syntactic abstraction via prototypes, if you really want it to.
Much of what I have learned in my independent studies of Lisp has been directly applicable to Perl programming. This is no surprise given that many of Perl's features originated in Lisp! I can do DataDirectedProgramming? when I need to. I can do FunctionalProgramming when I need to. I can do ObjectOrientedProgramming when I need to. I can do plain old boring imperative programming when I feel like it.
I really like AutoVivification. If I say something like:
my(%foo); $foo{'bar'}{'baz'}{'quux'} = 3;The first line declares a local hash named %foo. The second line:
Creates a new hash and assigns a reference to it to $foo{'bar'}. Creates another new hash and assigns a reference to it to $foo{'bar'}{'baz'}. Stores the integer 3 into $foo{'bar'}{'baz'}{'quux'}.This is very convenient when I am building a nested data structure and new data comes in. I can just assign it to the correct place on the tree, and if the intermediate nodes don't exist yet, they spring into existence. In most other languages (including, I believe, Lisp) I would need to check for and create each of the intermediate nodes myself.
Trees? Yuk. Table-time, guys. Nested arrays suck -- top
When I am talking to a Lisp interpreter, I feel like I really know what is going on in there. Even if the interpreter isn't implemented using my mental model, it still behaves like my mental model.
Programming in Perl is more like talking to a person. When I need to do something funky, when I need to nest behaviors, I sometimes guess at the syntax. Usually Perl understands, and sometimes I need to rephrase. LarryWall claims that this is an advantage and that he deliberately made Perl resemble natural language in this way.
There's also CPAN versus macros. Frequently I don't actually need to solve my problem in Perl. I can just download someone else's solution, and fill in a few parameters. I know similar things exist for Lisp, but they are smaller and I haven't learned them yet. But with Lisp, I know that I can build anything I need. There is a nice, liberating, completely in control feeling that I enjoy when working with Lisp.
So, that's where I am. Like I said, I still appreciate the truth behind things people say about LispMachines. Yes, LispMachines failed for political reasons and not technical ones. The vendors got greedy. The software was proprietary. Sure, technically they may be the best solution for many, if not most computing problems. I know that my tools are in some sense inferior to the best that they could be. That doesn't make me inferior. It doesn't make me afraid to listen to ways that someone else's tools might be better than mine, or ways that someone else's idioms might be better than mine.
You seem to agree with me that Lisp is a good language, maybe even the best, but *not significantly* better than other languages, just a little bit at most, especially when compared to other very dynamic languages such as Perl, TCL, etc. I do believe that dynamic languages can run rings around C++ and Java, but those are easy to beat.
Please don't put words into my mouth. I'll say plenty of dumb things without your help, I promise. ;-)
I believe that Lisp is a much better language than Perl, taken language-against-language. The thing is, the real contest isn't just language-against-language. There are also issues of culture, development environment, legacy code, and so on. There is also an issue of need. For my day job, I just don't need Lisp's power, no matter how convenient it would be, so those other factors tend to come to the front, especially the cultural one (other Perl programmers around) and the legacy code.
BUT! None of that is my main point. My main point is in response to the above comment to the effect that this whole page is motivated by fear of being inferior. I believe that it is valuable to discuss the relative merits of different programming languages, tools, and techniques, and I don't think that such discussion must center around fear of being inferior or desire to be superior.
I studied Lisp because I wanted to. It has made me a better Perl programmer. Sometimes I resort to a little GreenSpunning, but because I have a strong understanding of what I want to do, and how I would do it if I had the tools available to me, I can do it in a minimal and targeted manner. This doesn't make me feel inferior (because I'm ReinventingTheWheel) or superior (because I know these l33t c0d1ng t3chn1qu3s). It just makes me a better programmer than I was.
Re: "There is also an issue of need. For my day job, I just don't need Lisp's power"
I meant "great" from a practical standpoint, not a MentalMasturbation standpoint.
I guess it's all a matter of perspective. If I were starting from scratch, I think the difference in ease would be significant. Starting where I am now, I don't know if it would be possible to sell the boss and my coworkers on a change to Lisp, and even if I could, I don't know if the improvement would be "great" enough to offset the effort of the migration. I still maintain hope, though. Frequently, when someone notices an especially clean and good solution in my code, I mention that it is based on a technique I picked up from the Lisp community "...although it would be even easier in Lisp." ;-)
I HaveThisPattern too, whenever someone compliments something elegant in my code, I almost always credit either Lisp or Smalltalk for the idiom, hoping that someday they'll get the point.
Closure in csharp
interface UnaryProcedure { void Run(object anArg); } class SomeClosure : UnaryProcedure { public void Run(object anArg){ some code } } new SomeClosure();Closure in Java
interface UnaryProcedure { void Run(object anArg); } new UnaryProcedure { public void Run(object anArg){ some code } }Closure in Smalltalk
[anArg|some code]Closure in Lisp
(lambda (anArg)(some code))If you don't think that's a huge difference, then you don't understand programming with closures.
// this is actually in the BCL, so you don't need to implement it yourself // along with: bool Predicate<T>(T obj); U Converter<T,U>(T from); int Comparison<T>(T x, T y); delegate void Action<T>(T obj); delegate(type AnArg?){some code}which is almost the same number of characters as the lisp example (discounting the delegate declaration, which written for you and contained in the base class library, the only difference is the required type annotation for the argument).
[Further, the justification for closures as "significantly better" than alternatives has not been established. Do you guys use lots of closures, or occasional closures?]
The benefits of almost every concept that I consider "good" are either explainable with relatively small examples or are something I realize is purely a personal subjective preference. However, some claim that some things don't fall into one of these two categories; that benefits can only be seen after years and years of exposure to a concept, and even then they are still not easily articulatable. Being that I have never encountered this 3rd category in my entire life, I am very skeptical it exists. Either I have reached the limit of my brain or experience that keeps me from seeing the 3rd category anywhere, or claimants of the 3rd category are either deceiving themselves or are shitty articulators.
Sigh. More exaggerated strawmen. If you're talking about the Lisp discussions, then nobody says it takes years and years to see the benefits. A few weeks of part-time playing around, perhaps. You have to learn enough of the unfamiliar concepts to see how they work together to make programming life more pleasant, and you may have to add some time to get past the unfamiliarity of working with the unfamiliar syntax and some of the unfortunate historical names of basic functions. (I still struggle with the latter, since I don't program in Lisp all that much - yet.) -- DanMuller
[To put it bluntly, you have to have an open mind and be willing to learn new things on your own. No one will do it for you and you won't ever get it as long as you're waiting for someone else to prove it to you, that's not how programming works. Only those who put forth the effort to "learn" will understand, and top, you aren't in that category, you're a HostileStudent.]
I guess what I am trying to say is that in the past, benefits of great concepts were not that hard to explain (if you know how). I find Lisp concepts good, but not great. I don't see a revolution in there. How can a revolution be obscure? Past revolutions were not obscure, so why has the pattern allegedly changed?
Great concepts are frequently difficult to explain, because they are so new and/or different from existing concepts that it is difficult to tie them back to the existing concepts that the listener knows. Consider how much trouble children have with fractions, or how difficult it is for many people to accept that there is no fraction representing the length of a unit square's diagonal. The newer a concept is, the less it has in common with your existing body of knowledge, the more work it will take to assimilate, and the more doing so will broaden your understanding of the world.
[The pattern hasn't changed, you've just stopped learning. It's not obscure at all, it's blindingly obvious and has been pointed out many times on this Wiki, including on this page. You're mind is so set on tables and databases that you ignore everything else, to your own detriment.]
My mind just naturally gravitates toward tables. I cannot stop it without a lobotomy. And, they bring consistency to data structures that you map-pointer-network and tree fans lack. I don't think anyone has challenged the consistency complaint.
[Like I said, you've stopped learning, you think tables are the GoldenHammer to solve all problems and you fail to see that they are but one of many many useful data structures. There is no one perfect data structure, certainly not tables, real problem require flexibility and choices, and the willingness to use the appropriate tool for the job. You need to get beyond your table fetish if you ever want to progress as a programmer.]
Let's see what happens when you say the same thing about EssExpressions as the one-size-fits-all. Glass-house accusations about my pet technologies are flying all over the place here.
[I don't, nor have I ever. I don't believe in GoldenHammers, that's your bit.]
Well, many on wiki do believe in them, just not the same one. If you are not one, then ignore this topic because it is not relevant to you.
[ You're stuck in the past, programming wise, and pretty much refuse to learn anything new as far as I can tell. You think people are going to force you to keep up... think again. Yes the relational model is awesome for dealing with data... but it has little effect on most programming tasks and patterns. How many times are you going to write the same loop over that recordset before you realize that's a generic pattern that should be encapsulated into a higher order function so you never have to write it again? Tell you what... paste up some of your common code patterns, and we'll see if we can't package them better using some of these concepts you don't seem to be grasping.]
RE: there's the argument that "technology A is the ideal solution to problem W and is a workable solution for X, Y, and Z - so I'll just use A to do the whole thing". Which may be true, but it might be the case that technology B is the ideal solution for Y and Z, and an adequate solution for W and X. Or, by use of C and D, you can have near-BestOfBreed solutions for all the problems in your problem set. Always know your requirements...
The idea that programming technologies are tools is problematic in its own way, cf. FallacyOfTheRightTool. One must ask not only whether some technology A supports an ideal or adequate solution for specific problems, but also whether the resulting subprograms can be effectively integrated, configured, reused, extended, deployed, ported, maintained, upgraded, and so on. A requirement to "always know your requirements" is a bad thing because our hindsight is much sharper than our foresight. A more adaptable technology that reduces the need for foresight may be a better one even if it is non-optimal for individual tasks, cf. CodeChangeImpactAnalysis.
Focus on individual problems is terribly short-sighted; the bulk of programming effort regards integration anyway, the space between the solutions. As illustrated by Thomas Guest:
WRONG RIGHT(Full articles: http://wordaligned.org/articles/distorted-software, http://www.johndcook.com/blog/2011/11/15/plumber-programmers/)
It isn't GoldenHammers or SilverBullets we need. It's MagicWire?s, or maybe a broth or putty. And it is developing such where UniformityUberAlles can be a big win, and where small toy-examples can fail to demonstrate much advantage. The world-wide web isn't great because of individual pages, but because (at scale) everything gets connected together. There are many technologies of a similar nature. If you try to measure wires by the same metrics you measure hammers, you're an idiot. If every concept that you consider "good" is explainable with relatively small examples, you have a lot to learn.
Re: How many times are you going to write the same loop over that recordset before you realize that's a generic pattern that should be encapsulated into a higher order function so you never have to write it again?
I agree that things like closures can reduce loop coding. However, only about 15% of my code is loop setup.
That's 14% too much
You need to significantly help the other 85% to move from "good" to "great".
What's your other 85%, do tell, we'll simplify it.
Try ChallengeSixVersusFpDiscussion.
That's not code, it's report writing. That barely requires more than SQL, show me some real code, some application code, crud stuff with business rules and workflow, not reporting.
Never said it was
Besides, many "traditional" loops can often be simplified if one works at it enough.
One shouldn't have to work at it at all, it should be wrapped, given a name, and used as an abstraction
GoldenHammer's on wiki seem to be based on 3 different data structures as the root:
Nested Lists: Lisp Interlinked Maps: OO Tables: T.O.P.Just to clarify in case there are misconceptions: Advocating Lisp does not imply advocating nested lists (sexprs) as the GoldenHammer of data structures. They're great for hierarchical data, but CommonLisp has a reasonable set of native data structures, for convenience and efficiency, including hashes, arrays, structs, and classes. A common complaint of Lispers is that many college Lisp courses are still taught as if all data were represented by lists. Even Scheme, with its minimalist orientation, has strings and vectors.
Ideally ComputerScience should actually distance itself from technology (products) and use theoretical pseudolanguages instead of specific on-the-market implementations of a language. The problem with technology and the consumer market, is that it is infected with crap and quackery. One does not need to teach a certain technology or product in order to teach good education about a concept. For imperative programming as an example: you could simply teach in a pseudolanguage that you made up yourself, teaching people about a list of things that happen in the program. Or consider relational: teaching kids SQL in school isn't a good idea, since SQL is a product/technology that has strayed away from relational model. Confusing students isn't a good thing, and products/technologies are often infected with confusing garbage or things that are simply wrong.
How to use a HashTable in CommonLisp is not an important ComputerScience subject. How to create a HashTable given vectors or arrays is an important ComputerScience subject.
In SoftwareEngineering, the situation is reversed. How to use a HashTable in the language you are working with at the moment is very important. How to implement a HashTable is completely unimportant if your environment provides one.
That's not unusual, however. Any engineer should have a good understanding of the science underlying his discipline; even if he seldom employs it directly in practice. A civil engineer should have a good understanding of soil science and other relevant materials science, even though no civil engineer makes his own concrete or forges his own steel. A chemical engineer should have a good understanding of both chemistry and fluid dynamics, even though he won't manufacture pipes.
Students should also have a good introduction to relational theory and techniques. Some schools skip that, and grads end up using arrays for everything because they don't know anything else. -- top
Definitely agree; the RelationalModel is a fundamental part of ComputerScience, as is database theory (transaction semantics, etc.)
Yup, they use arrays and lists and pointers to them, along with structs, when they could be using relational techniques. Problem is, no mainstream product or technology out there actually makes it easy to use relational techniques in our programs. How do you do relational stuff in CeeLanguage for example? Answer: you don't. You call some function like mysql_query() and then you have to work with ugly strings and convert the tables into arrays once you receive the resultset. You do iterative looping and use pointers and such low level garbage. In PredictTheFuture I suppose we should say something about languages of the future providing more relational abilities than our current languages.
One of the best litmus test is a realistic UseCase. If one cannot produce a scenario where their pet technique is clearly better (less code, less change-points), then generally I will write them off.
As I see it, the problem is that without any external evicence produced by the current "thing", it is impossible to produce external evidence that the new thing is better. There is no baseline of current software development approaches to compare against, so evaluations must be done based on theory.
Products and what people are using can act as external evidence, but it is also a TragedyOfTheCommons too. Just because millions of people are using SQL products, doesn't mean SQL is better than some other theoretical language which addresses SQL's problems. If the masses use something, that means there is massive evidence that something is extremely useful. It doesn't mean it is the best solution. OOP is used by the masses for GUI widgets so that people can reuse and inherit the widgets, and it seems that the masses do okay with these techniques. Is there a better way than OOP? possibly, but OOP works for the masses, and SQL works for the masses, so that is evidence for all of us right there that both OOP and databases are useful tools.
There is indeed something to be said about achieving years of road-testing and being at least "good enough" to get the job done. There are many tools/projects that DON'T get the job done such that getting it done does stand out. However, that doesn't mean we should stop being critical of them and stop testing new ideas. Just don't experiment on critical projects. OOP has worked fairly well for GUI's and SQL RDBMS are a clear improvement over what came before. They are that old pair of shoes that allow you to walk normally and don't hurt your feet, even as they give you that nagging feeling that they are missing newer styles/ideas.
See BlubParadox, BenefitsAreSubjective, ComparingParadigms, LanguageEvangelism?, ObjectiveMeasuresOfEffectiveness?, ExampleSizeIssues, IfFooIsSoGreatHowComeYouAreNotRich, GoodMetricsUseNumbers, ExtraordinaryClaimsRequireExtraordinaryEvidence, UniformityUberAlles