Top On Abstraction

(Continued from NodeJsAndHofDiscussion)

Top, you say SeparationOfConcerns is a myth in business software and avoid using most of the language techniques available for abstraction. It seems likely that you actually don't get abstraction. Perhaps you could try some of these features; you might find they do improve SeparationOfConcerns, for instance. -DavidMcLean??

That's a misrepresentation of my position. I suggest one read SeparationAndGroupingAreArchaicConcepts for more on this. (The topic could perhaps use a rename.) Also note that abstraction by itself is not always better. What are needed are good abstractions, not necessarily more abstractions. I've been burned many times by abstraction attempts that went wrong simply because they didn't fit future ChangePattern(s). As Yogi Berra once said, "It's hard to make predictions, especially about the future". See EightyTwentyRule.

Creating good abstractions takes experience and analysis. It's also a matter of knowing the domain (or similar domains) and "office psychology" and developer psychology, not necessarily just a focus on programming language features or technique. As geeks we sometimes focus too much on magic tools or magic languages instead of WetWare. This is often a mistake, I've come to learn the hard way. In the end, ProgrammingIsInTheMind. It's not really about machines.

When I'm designing software, I often come up with roughly 5 different draft designs for each major module in my head or on the back of scratch paper. I then run various change scenarios (based on experience) in my head and see how the draft designs stand up to each scenario. It's a short-form of CodeChangeImpactAnalysis essentially. My main goal is not abstraction for abstraction's sake, but rather to stand up to future changes without over-complicating the current (or new) version. Abstraction is just a means to an end. If it improves readability and change handling, then it's helpful. If it's there just because "it seems cool" or "Fred told me this was good", then you are probably doing it wrong.

Another thing is that an abstraction that makes sense to me may not make sense to others. I've rejected some "nifty" abstractions because other developers (current or future) may not be so appreciative of something "weird". Other times I "go for it" and make sure I gave a hefty comment explaining it.

Over the years I've learned to keep abstractions rather small and semi-disposable: HelpersInsteadOfWrappers. Big, overridding abstractions can fail badly when they fail because you can't back out of them very easily. I will also accept some amount of concept duplication sometimes to keep them small and disposable. I used to try to stomp out almost all duplication, but it made the code really difficult to follow and change.

--top

How exactly is it misrepresenting your position to claim that 'you say SeparationOfConcerns is a myth in business software and avoid using most of the language techniques available for abstraction'? -DavidMcLean?

What's this "most" stuff? I use objects too, just not everywhere. (And I probably wouldn't miss them, but sometimes they have a minor advantage in name-space management. Related: OopNotForDomainModeling)

Oh, you're not still claiming object-orientation is a conspiracy then? Okay, fair enough. You say SeparationOfConcerns is a myth in business software, despite avoiding some language features that afford abstraction. -DavidMcLean?

I'm claiming it was way over-hyped for about decade. "Conspiracy" is probably not quite the word I'd choose any more than a salesperson only telling you the upsides of a product but not the downsides is a "conspiracy". The industry has "hype-cycles" where many vendors hype a new concept in order to generate new sales. And sometimes it's just a kind of fashion statement among techies: "I know Foo Oriented Programming and you don't! Therefore, I'll get laid and you won't.".

You actually call OOP a conspiracy on your site, which is what I was talking about. -DavidMcLean?

Not really. It's just worded in kind of a playful speculation. At least that's how I intended it. Anyhow, do you have a point, or are we going to play LaynesLaw over "conspiracy"?

Yep, I had a point. From above: "You say SeparationOfConcerns is a myth in business software, despite avoiding some language features that afford abstraction." -DavidMcLean?

Can you provide the context and quote?

Certainly. From HofPattern: "It may be one of those "assume a spherical cow" moment. SeparationOfConcerns is often a myth or excessively ideal in the biz world.".

I meant "as currently practiced". I cannot re-paste all the context and disclaimers every time I casually mention another topic. I want to discuss strategy, not words. It's resulted in bad or overused things such as a MirrorModel.

I don't doubt that SeparationOfConcerns is a myth as currently practiced by you, because you eschew features that can improve SeparationOfConcerns. -DavidMcLean?

Show them doing such well in realistic environments (code samples), and I'll use such more. Lab and toy examples (ArgumentByLabToy) just don't cut it because they remove some of the lumpiness of the real world in order to make the concept stand out more (hopefully only) for illustrative purposes.

Whenever you're given a code sample you complain it's rigged (e.g., deleteWhere() and the JavaScript example on ArrayDeletionExample). Those are hardly unrealistic examples; the JS one is from an actual custom biz app. -DavidMcLean?

I'll LetTheReaderDecide whether my criticisms are legitimate. Obviously, we have different views on that. If you believe the examples are sufficient, state so and move on.

I do believe they're sufficient. However, you clearly don't, so let's look at another one: Enumerable, from Ruby's standard library. You've described it as the ability to put DatabaseVerbs on arrays, and in fact you're right. Enumerable lets you put DatabaseVerbs on arrays, files, sockets, hashes, recordsets… basically anything for which it makes sense to have such verbs. In short, it gives a common API to all collections and collection-like things; this is obviously useful, and in fact on your own site you discuss such a collection API ( http://www.geocities.com/tablizer/array1.htm ).

Later in ArrayDeletionExample you suggest that different shops will implement a different set of DatabaseVerbs on collections, so there's no consistent API. In Ruby at least this is absolutely false; because Enumerable is part of the standard library, individual shops aren't going to implement it. For all built-in collections, Enumerable's already set up; for a new collection type, all one needs to do is implement a single method (.each) so that Enumerable knows how to get stuff out of the collection, and then one will have access to all the database-y functionality afforded by Enumerable.

Not only is Enumerable clearly useful, you yourself have identified the need for it. -DavidMcLean?

Essentially you are reinventing a (partial) database in code. I agree that the idea in general is a good idea. However, we don't want to make it too easy to drift away from the "standard". This is similar to our "herding" discussion at [insert later] and about Lispers reinventing "creative" FOR-loops, etc. (LispIsTooPowerful). In my opinion, it's better to build such into the language to get standardization. (Some of Microsoft's languages allow basic SQL against certain data structures. This allows one to more easily "upgrade" to a full RDBMS when needed. Whether this is better than LINQ or not is another discussion.) It's a great idea for a hobby language, but I don't want to debug Picasso's code at work. -t

In Ruby, one doesn't usually drift away from using the .each method and Enumerable, for two reasons. Firstly, most programmers actually like consistency and don't need to be forced into making stuff consistent. Secondly, there are a lot of methods in Enumerable ( http://ruby-doc.org/core-1.9.3/Enumerable.html ), all of them are useful at one time or another, and it's a lot more work to implement them manually and following different conventions than it is simply to implement .each and include Enumerable. -DavidMcLean?

Well, I'm a bit skeptical. I've been burned by Picasso's.

Further, it's temping to over-use code for collection processing, and if the application grows larger or more complicated, we'll eventually have to move to a RDBMS. I'd rather have a language that fits SQL's idioms from the start to "close the gap" a bit rather than something very different that can push the app to drift off on its own. Ruby's essentially risking an "Ruby-to-Sql Impedance Mismatch". (Not that SQL is the ideal query language, but it's the current de-facto standard.) Related: EmbraceSql.

If you really embrace full-out "build your own meta-structures", then why not promote Lisp instead of Ruby? It's syntax is far simpler. (Personally, I'd prefer Masp as a hobby language - MaspBrainstorming.)

I'm focusing on Ruby because Enumerable's a good example. I don't think I've said anything about building your own "meta-structures", and I'm not entirely sure what you mean by it.

Flexibility: Essentially roll-your-own-language without starting from scratch. Your arguments are essential a rerun of those made during the "Lisp-craze" in the 80's.

Consistency trumps flexibility in CBA tools unless the flexibility advantage is pretty large because companies want PlugCompatibleInterchangeableEngineers. Yes, it can take some of the fun out of programming, but remember the upside is that you are less likely to get some nut-job's Picasso-Code to maintain.

I pointed out a couple of paragraphs ago that Enumerable, as a common interface available on all collections, increases consistency. If you've got a collection in Ruby, you know you can call #each, or #collect, or #detect, or #take_while, or any of the Enumerable methods, using exactly the same syntax and with precisely the same semantics as you'd have with some different collection. Code is therefore much more consistent than it would be in a situation where collections implement similar functionality manually, or a situation where the developer needs higher-level iteration (say, #collect) but is stuck with an ExternalIterator and must manually implement collecting with it. -DavidMcLean?

What do you mean by "available on all collections"? Do you mean built in or add-able? This also gets into the issue of app language design and what would be the "ideal" CBA app language. That's a big topic. I'm not in the mood to dive into that right now.

A lot of what you describe could perhaps be done with old-fashioned OOP. OOP gives one the option to associate different information with the "function", such as a title and meta data. It's more flexible than HOF's in many regards even if it is a bit more initial syntax to set up. This is because objects need a class "wrapper", while HOF's don't. However, having class packaging does allow such additions without modifying the original code. We can associate more info and data with the "function" without disturbing any existing references to the "function". You cannot "attach new things" to HOF's.

Anything you want to associate with the function can be in its return value.

What if you are already using the return value for another purpose? I'm looking at maintenance issues here, such as adding new information or behavior down the road.

Return a struct.

So you are saying build all HOF's to return a struct in advance even if we only need one value for initial roll-out? One might as well use objects then because the initial simplicity of HOF's would be gone if we always made structs. Objects *are* structs, pretty much.

Sorry, pressed for time, I read what you wrote -- misinterpreted it -- and responded in haste. I should have written that anything you wish to associate with the function can be put in a struct along with the function. Its return value is not relevant.

But that's essentially a class or object. And it's still a case of changing existing references, which we wouldn't have to do if we started out with an object to begin with. If "simple" HOF's are heavily used in an app, then the overall app may indeed be simpler. However, if only a few are used, then the syntax difference between an object and HOF are too miniscule to fret about. Objects are plenty sufficient, and more familiar to most CBAD's. We don't want to weigh down our tool-box with 12 kinds of screwdrivers when a few handle the low and medium needs sufficiently. Only if you often do tasks where the subtlety of the screwdrivers makes a significant efficiency difference, then 12 screwdrivers may be justified. Let's balance the tools in CBAD's tool-box based on actual usage patterns. If they do a lot of hammering a lot of different kinds of materials, then 12 hammers may make sense. Related: ParadigmPotpourriMeansDiminishingReturns.

True, a struct and a class are closely related. However, it's not unusual for developers to, e.g., explicitly create FunctorObjects or use a CommandPattern. In these cases, objects are used to emulate HOFs. HOFs, without the need for artifice, would be syntactically simpler and more direct -- at least for those who appreciate them. Of course, for those who don't, object oriented languages provide sufficient facilities that the shy developer can avoid HOFs if he wants to. But that's no reason to deny developers who would like to use them. I have a screwdriver with 98 interchangeable bits. Some of them I'll never use, and a few I've never seen before, but I'd rather have all of them at my disposal than risk rounding off a screw head because the bit doesn't quite fit. Explicit support for HOFs, in object oriented languages, is the same. You can do everything in conventional OO without HOFs, but sometimes HOFs fit better.

A screwdriver with 98 bits is still going to be a lot of metal to haul around, and woe be to those who dropped them all on the floor. Anyhow, again again, if you can show that such is common and useful (syntactically more natural or concise, for example) in CBA's via realistic code examples in descriptive scenarios, I'd be happy to endorse them. Heavy use of them may just simply be your personal style preference and/or you are not as skilled at other approaches.

See HofPattern for the quintessential illustration of the concept. By the way, the screwdriver set is in a nice hard case with rubber bumpers, and it weighs at most two pounds. The bits are organised in rows by type, and are labelled to make them easy to find. It's a marvel of elegant capability, just like a good programming language. Why, by the way, do you assume my use of HOFs is indication of some lack of skill? Have you considered the possibility that your rejection of HOFs is an indication that you lack skill in using them? Perhaps you just need some practice. Javascript is an excellent place to start.

I didn't mean to imply you were unskilled, I was merely suggesting possibilities about why you think they are better than the alternatives even if they may not be. I probably could have worded that better. And an "illustration of the concept" is not sufficient. We know "lab toy" examples illustrate concepts. The issue is whether "the concept" can be applied to common and typical CBA's. I don't think it's widely applicable to such. If you claim it is, then please provide something(s) demonstrating a specific business need so that I can see it being applicable with my own eyes (and other curious readers).

I remember I had this same "problem" with "heavy" OOP proponents. They came up with nice SystemsSoftware and engineering/physical simulation examples/scenarios, but not CBA examples (outside of GUI's and system interfaces). I kept asking and asking and they often insisted that I would eventually "get it" for the domain side if I just kept trying and trying long enough. Author Richard Mansfield also asked the industry for a "proof of concept" sample application after seeing many shops foul up OOP attempts. Eventually the industry woke up and mostly realized OopNotForDomainModeling (at least the biz domain). I believe I'm seeing a repeat of history with FP/HOF's. -t

I don't think you can meaningfully compare object-oriented programming with higher-order functions. The former is an entire programming paradigm, and it can radically alter the structure of entire applications. The latter, however, is a much more "local" tool: Calling a higher-order function is a technique on basically the same level as writing a for loop, or calling a method on an object, or simply making any function call.

Of course, because higher-order functions are a very generic tool (much like all functions), they may be used to build up a wide variety of more complex systems. NodeJsAndHofDiscussion looks at one of those. Despite this, however, higher-order functions are capable of much simpler feats than building an entire platform. They work just as well to abstract out collection interfaces, as in Ruby's Enumerable, or to abstract out problem-specific detail from an algorithm, as in HofPattern, for instance.

Personally, I think there's none of the potential "danger", which you foresee through an analogy to overuse of object-oriented programming, in using higher-order functions for these simpler local situations. I agree that it's a little drastic to use a quite different application structure without proof of the technique's value. Thus, I recommend trying out some of the smaller, localised uses of higher-order functions. They don't enforce a radical change in your app structure; they just make some aspects of your code shorter and clearer. As you grow more comfortable with using higher-order functions, you may find that using them on a broader scale isn't that daunting a prospect; even if you do only keep them localised, you can at least enjoy their benefits in factoring out code patterns. -DavidMcLean?

I've been looking for a good CBA use over the years, but so far haven't found any. That's why I'm asking you for realistic sample code/scenarios, etc. You seem to believe that their utility for CBA is common and clear, which implies you'd be the ideal person to produce such samples. But, sadly, they never come, and like above, you expect the reader to just take your word for it. I'm from the MentalStateOfMissouri. The intensity and repetition level itself of such claims should not and will not persuade me, and that should be the case for any reader reviewing any technology (unless they have to make a choice soon such that they stuck with the lower parts of the EvidenceTotemPole). -t

[1, 2, 3].each do |x|
[4, 5, 6].each do |y|
puts x+y
end
end

[1, 2, 3].each "|x|
[4, 5, 6].each \"|y|
puts x+y
\"
"

[1, 2, 3].forEach(function (x) {
[4, 5, 6].forEach(function (y) {
print(x+y);
});
});

[1, 2, 3].forEach("(x)
[4, 5, 6].forEach(\"(y)
print(x+y);
\");
");

I think HofPattern is about is clear an example as one can get, but as I mentioned elsewhere, I've dug up an old employee allocation application of mine -- based on a genetic algorithm -- that will make an ideal illustration. It was built in Java using a fairly conventional OO approach (Java doesn't support HigherOrderFunctions), but for illustration I'll convert part of it to use Javascript to illustrate how it would look using HOFs. That should provide a reasonable basis for comparison.

"As can get". Heckavity No! You can get clearer by applying it to something realistic. Lab toys clearly do labby things, no doubt, but that's not necessarily a demonstration of practical utility.

Well, it's as clear an example as one can get via an illustrative abstraction. However, I knew you'd once again bristle at its abstractness, which is why I mentioned that I'd present my real -- not just realistic, but real -- employee allocation application.

I cannot see your employee allocation application. There may be a non-HOF way to do it that you haven't thought of. And I do NOT "bristle at abstractions"! I use abstractions every day. But I want good abstractions; bad abstractions can make things worse. See TopOnAbstraction.

You will be able to see the application. Be patient. ;) Also, you may be defining "abstraction" differently to your above correspondent. HofPattern is an abstraction; it shows in the abstract a general pattern that may be applied to code where appropriate. You have indeed "bristle[d]" at the abstract nature of HofPattern, requesting non-abstract examples. -DavidMcLean?

It was worded poorly. The abstract-ness is NOT why I "bristled", but the way you wrote it implies it is.

Sorry? Are you saying you actually don't object to the way HofPattern is presented as a generic, illustrative abstraction? -DavidMcLean?

Your problematic implication was that I objected to HOF's mainly because they are (allegedly) "abstract".

No such implication was intended. It's not higher-order functions that are abstract; it's HofPattern. -DavidMcLean?

This "correction" doesn't change the nature of the problem, only the target.

How so? Is it not true that you objected to the way HofPattern is presented as a generic, illustrative abstraction? -DavidMcLean?

No. It's not. I object that you cannot find significant real CBA use for it, yet claim it "clearly" makes them better. It's this contradiction that is agitating me. I've said this like 50 times, yet you reinvent a different explanation above for my agitation. I will reject non-useful abstraction, if that's what you mean, but it's the "non-useful" that is the problem, NOT the "abstraction". 51 now. You put a giant bolt sticking out in the center of my wall, and then when I complain it's there without a use, you seem to see it as "you hate bolts". No, I hate useless and "distracting" bolts.

[What about the so-called "Brady Bunch" example, i.e., the Javascript-based multi-panel concurrent display at http://shark.armchair.mb.ca/~dave/hofajax that is also part of a real custom business application? Perhaps you could show a better way to implement it that doesn't use higher-order functions? We can happily ignore the fact that the DOM forces you to pass a function to setInterval(), as long as no other higher-order functions are used. Surely, if other approaches are equivalent or superior, you can alter this simple, real, non-abstract example to show it?]

See SummaryOfHofExamples

[By the way, I've changed it slightly to make it more reflective of its actual application and coalesced it into a single block of Javascript source -- I removed ajax.js. It's lost its "Brady Bunch"-ness, I'm sorry to say, but it's a better illustration.]

My comments on the applicability of the example is in SummaryOfHofExamples. By the way, I liked the brady-bunch version over the bar charts as far as an example.


[ToDo: split or move when edit-war has ended.]

Because StandardToolDependency?/StandardToolDependancy is stuck in an EditWar with G.V., here's some related material:

http://beust.com/weblog/2006/04/06/why-ruby-on-rails-wont-become-mainstream/

Some Quotes:

But it’s a complex language that contains a lot of advanced idioms which will be very hard for PHP and Visual Basic programmers to absorb.

But it’s still a very wide gap for corporate developers to cross. Sometimes, too much magic is too much magic, and it can definitely be the case that the flow of code is too direct or too clever to be understandable by regular developers...I don’t believe the Web world will ever be ready to embrace the Rails cleverness.

Have you ever come across Smalltalk or Lisp programmers? You know, these people who, no matter what you tell them, will always respond that "Smalltalk did that twenty years ago" or that "Nothing has been invented since Lisp". They listen to you patiently with an amused light in their eyes and when you’re done talking, they will just shrug away your points and kindly recommend that you read up on a thirty-year old technology that was the last thing they ever learned and that has been dictating every single technical judgment they have offered since then. (Emph. added)

I believe that in ten years from now, people will look back at Ruby on Rails and will have the same reaction. I’m not sure what Web frameworks we will have by then, but I’m quite convinced that a lot of the current Ruby on Rails fanatics will have the same kind of attitude: "That’s nice, but Ruby on Rails already did this ten years ago, and better".

Languages and tools keep reinventing Lisp's "meta" capabilities, but it never goes mainstream because the training needed to handle it is costly without a corresponding increase in documented productivity. Again, I generally agree the Lisper's are "right" from a purely technical perspective, but they don't understand the business side of unleashing an excessively powerful tool. It's too big of a chainsaw for the average lumber-jack. A handful of lumber-jacks may become super-productive, but too many will either not figure out how to use it right, or misuse it out of boredom or job security. The problems caused by the bad apples is equal to or greater than the productivity gains by the really good apples with with the super-saw.

PageAnchor: Abuse294

I would roughly estimate that a "high-brow" language will have this impact:

The downsides of the bad apples outweighs the upsides of the good apples.

I also believe "fans" of certain techniques exaggerate the upsides of "meta" techniques. The improvements are relatively minor in practice.

[On what do you base your belief that meta techniques have relatively minor improvements, when by your own admission you haven't used them much? -DavidMcLean?]

I haven't used them much because I haven't found much use for them in CBA, and apparently neither have you guys because you have difficulty showing practical and common scenarios.

We've shown practical and common scenarios -- those on SummaryOfHofExamples, and even gone so far as to show a general pattern in HofPattern -- and you reject them as not being practical or common. I'm curious where you get your figures to "roughly estimate that a 'high-brow' language will have this impact"... It looks like arbitrary speculation, with no basis in evidence other than your personal dislike of "'meta' capabilities", despite the real evidence that "'meta' capabilities" are being adopted by mainstream languages and used without fuss by mainstream developers. A handful of knee-jerk comments from 2006 -- shortly before RubyOnRails pushed Ruby into the awareness of every Web developer and significantly influenced Web framework design on every platform -- do not make your case.

Your counter arguments are no more than anecdotal also. And I do not "dislike" meta capabilities. The industry "dislikes" them for the reasons given. R-on-R may carve out a nice little niche, but I don't think it will go/stay mainstream. Something with the impact of the original Visual Basic and/or HTML will eventually come along and make web GUI's more of a commodity rather than the twiddly "dark art" it currently is. You speculate that I "hate" meta capabilities, so I can speculate that you want to protect your GUI dark-arts from the proletariat programmers to justify your higher wages. I can play the motivation speculation game also. GUI's can and should be commodity technology. The web has simply temporarily got in the way. Commodity stuff usually doesn't need HOF's. HOF's are for the early days before the patterns/standards figure themselves out and settle. If JQuery becomes the de-facto client GUI standard, it too will be re-packaged into something medium- or low-brow to make it more digestible to the programmer masses, especially for internal apps that don't need to keep up with the style Jones'. And OOP can do mostly the same thing. -t

This is all speculation, so I have nothing to offer except "we'll see".

And you still cannot find non-UI and non-performance-oriented CBA scenarios for HOF's. (And the UI and performance claims are still rigged in my opinion. I haven't conceded those.) Why must you keep turning to GUI's and performance for (allegedly) realistic scenarios? Is there a reasons for this pattern?

The "Brady Bunch" example is UI oriented because it's real, uses JavaScript which supports HOFs and is well-known, and because modern business applications are often Web-based and therefore use UIs based on JavaScript. In short, it's realistic and relevant.

     processHttpGet(url, timeout) {  // internal "system" function pseudo-code
       h = new httpGet(url, timeout);
       while (! h.finished) {
         doEvents();  // process any pending events
       }
       return(h.results);
     }
Which of the examples is performance oriented? I thought none of them were, unless you're referring to HOFs demonstrating better performance than eval and the like. In that case, it's true, but eval demonstrates no benefits whatsoever over HOFs. The only justification for using eval is having to use a language without HOFs.

Which means we can do almost the same thing without having to add new linquistical constructs.

I'm not clear on your point -- are you saying eval() is as good as HOFs? One of the strongest justifications for HOFs is to avoid all the downsides of eval.

Eval's, objects, case statements, and a 4th one I forgot (hats off to Rick Perry) are candidate alternatives, depending on the situation. I've said this already.

All have significant downsides compared to HOFs, which has already been demonstrated in considerable detail. Using case statements is almost ludicrously impractical compared to HOFs. Eval offers no benefits over HOFs, and HOFs offer considerable benefit over eval. Only object-oriented techniques come close, at the expense of some syntactic overhead. The only downside of HOFs is that some programmers might not be familiar with them. This is typically addressed by spending the hour or two of study needed to understand them, and in most cases even weak programmers find learning about HOFs after using functions no more difficult than learning 'for' loops after using 'while' loops.

That's your summary opinion, and I disagreed.

Why do you disagree?

I'm not going to repeat my points here. That's unnecessary duplication of text, something you don't seem particularly concerned about on this wiki.

[Top, if you've made any points which counter the fact that higher-order functions have exactly one downside, as mentioned above, please do repeat them here (or link to them). I had no idea they existed. -DavidMcLean?]

SummaryOfHofExamples. The bottom line is that HOF's confuse too many developers such that they create maintenance risk, and the alternatives are not that bad.

[Do you have evidence that higher-order functions confuse developers? -DavidMcLean?]

It's anecdotal based on experience. Your counter claims are also anecdotal.

[As was asked over on SummaryOfHofExamples: Have you asked your colleagues about HOFs? I'd be curious to know their specific responses. -DavidMcLean?]

Directly? Mostly not, but their code doesn't reflect any personal love for them and it's not what they talk about when we discuss code design strategies.

[Then you don't have any anecdotal evidence that they're confused by higher-order functions, now, do you? -DavidMcLean?]

Yes, "This JavaScript is weird. I miss VB's events."

[Of course it's "weird". It's different to VB. Anything unfamiliar starts out being "weird". It's pretty much the BlubParadox, really. However, in general familiarity with features like higher-order functions can be garnered with just a few hours of practice, at which point it will no longer be weird and its obvious superiority over VB's model may become apparent. -DavidMcLean?]

When they are kept simple. But if they get intermingled into a complex tool-kit or in the hands of somebody devious or abusive of code, then it's not so easy to comprehend what's going on.

[Any language feature may be abused. VB events, for example, are notorious for being misused (see EventsCallMethods). Do you have real examples of higher-order functions being abused to the level of non-comprehension of code? -DavidMcLean?]

Yes, but high abstraction is generally the most powerful form of abuse. A nuke in the hand of a mad-man is far more dangerous than a rifle. Excess repetition is annoying, but usually not a show-stopper. Something that is just too convoluted to figure out is a show-stopper. Telling your manager that it will take approximately 2 weeks to fix/add something generally goes over better than, "I don't have a damn clue, I still haven't figured out what's wrong yet." The path ahead is clearer with low and mid-brow tools. Organizations like programmer herding mechanisms: the sheep can wander, but not too far. There is a reason that citizens are hesitant about giving deputies automatic weapons even though they have far more potential power than hand-guns.

Worse-case productivity often affects decisions such that organizations may lower average productivity to reduce risk. You seem to focus on average productivity.

[I focus on programmers with actual programming ability. I don't think designing programming languages to cater to organisations with bad hiring processes is valuable. -DavidMcLean?]

You can focus on whatever specialty you want and complain about organization decision making, but ultimately you don't make those decisions for the majority of the marketplace. We can focus on the ideal or WhenInRome. I make tool design decisions based on how it will be received in the actual marketplace, not under the assumptions that somebody will solve the problem that HumansSuck. The Borg probably use Lisp. You are free to join them when they pass by.

[The Borg obviously only code in raw machine language. Programming languages should, primarily, be designed based on the needs and wants of programmers, because programmers are who have to use them. -DavidMcLean?]

Lisp is machine language on their hardware.

[The Borg is a LispMachine? I guess that makes sense -- if I was going to construct a ruthlessly intelligent distributed hive-species, I'd use LISP too.]

It's actually a giant ball of parentheses, not a cube. They only used a cube on the show because George Lucas would sue over similarity to the Death Star.


CategoryFunctionalProgramming


JanuaryThirteen


EditText of this page (last edited March 3, 2013) or FindPage with title or text search