Oh My - It Really Is A Padawan’s Hat!

So I read about a paper co-authored by Natalie Portman (who played Padme in Star Wars and the girl in V for Vendetta) under her True Name of Natalie Hershlag.

I figured that had to be worth a click, and found Frontal Lobe Activation during Object Permanence: Data from Near-Infrared Spectroscopy. They used strong near infrared light as a non-invasive way to detect blood flow in the prefrontal cortex, and showed that where infants are able to track things that they can’t see any more, the PFC is developed and active. Quite on topic! Then I reached this image:

I mean… come on:

Then it occurred to me that we can explain a lot of tales of mysterious, spooky intuitive consciousness with the idea that the full range of PFC functionality is not available to most of the people most of the time. A Jedi Master would probably be interested in monitoring a padawan’s PFC function. So Ms. Hershlag would be quite entitled to claim her apparatus really is a primitive padawan’s hat, thank you very much!

I tried to program by not thinking once. You know - like Tommy and Luke Skywalker. I was really tired and there was just one thing left to do. I had to convert an integer to an appendix designation. It’s horrible and not like proper counting. The first appendix is “A”, then “B”, through “Z”. Then it goes “AA” through “AZ”, “BA” through “BZ” and so on. The carries are all wrong. (And it might have actually mattered in service. Someone could reasonably collate a large amount of evidential material as lots of appendices.)

I didn’t have the mental stamina left to compose by iterating juxtapositional and focussed attention as I normally would, so I brought to mind the recursive printf(3) definition and went for it:

string PcmProposalImp::MakeAppendixDesignation(int Order)
{
   return(((Order / 26) > 0 ? MakeAppendixDesignation((Order / 26) - 1)
                            : string("")) +
                              char('A' + (Order % 26)));
}

It worked. How spooky is that? I don’t advocate programming with eyes closed in general, but it might just be that my PFC in juxtapositional mode is actually better at all the Obi Wan gotchas in there than my PFC in focussed mode is. I usually get that stuff exactly wrong, even when I remember I always get it exactly wrong.

Phew. Reached the end without mentioning Attack of the Clones.

D’oh!

Neuroscience, All Postings, Programming

Response to a Reddit Comment

A link to this blog appeared on Reddit, and a reader posted a critical comment which it’s worth addressing in detail. The big picture I’m describing is not one that readers will have seen before, and that’s a situation where it’s often necessary to allow misunderstandings to provide the structure for clarification. Please be warned that the comment contains language which is common in Reddit flames, although I would not use it normally on this blog. If vulgarity distresses you, please skip this post!

Insofar as he says everyone can program, he is a complete fucking moron. It is blatantly impossible.

I wouldn’t go so far as saying that everyone can program. There are some people who just can’t get their heads around formal syntax - they can’t get the semi-colons and other little things right, because they aren’t at all familiar with that kind of precision. Others don’t like working with keyboards and screens, and in the current generation of technology that’s a big problem. Maybe one day we’ll have some kind of gesture based immersive Squeak environment with voice recognition and inference, but for now the little things can still be a problem. When it comes down to it there are even some people who can’t cope with being indoors, and rainwater plays havoc with most current hardware!

What I do claim is that (almost) everyone who is currently working as a programmer can become one of the currently rare super programmers who deliver super productivity. They were born with the necessary faculties but background social stress, which is addictive for most people, takes those faculties offline. To become a super programmer they need support to reduce their level of stress, bring the missing faculties online, and become aware of them. Furthermore, in people who do not wish to be programmers the same faculties are important for doing other things, which I suspect include things like being able to correctly evaluate some kinds of biopsies using a microscope, and all kinds of creative arts.

In the twenty years I’ve been exploring this, I’ve met two people who I couldn’t get anywhere with even though all the conditions were right. One was a male who was unable to give up a very aggressive approach which had served him well in the usual snake pit of bombast and blame avoidance. The rest of his team were able to build authentic self-confidence and quickly got better at seeing what each other were on about. This led to a deepening and enrichment of everyone’s understanding of the technical problems they had to solve, and their project quickly transformed from the site’s greatest embarrassment to the only one that produced clean results in every one of the customer’s acceptance tests. He was trapped in a zero sum game, and every success made his nightmare worse. Everyone on a stressed-out team is something of a nutter, but this guy’s problems went way deeper. My guess was that he’d probably been like that since he was a toddler. Eventually he transferred to a sales support engineer’s job, where he did very well. He knew where he was in a stressed-out and basically distrustful context where his aggression enabled him to break deadlocks. There are some situations where the military idea that a quick decision is better than a correct one applies, and there he was happy.

The other was a female who was similarly trapped in a simple strategy that she’d obviously learned as a small child. I don’t know what became of her because I didn’t spend as long with that team, but I will say this - little girls go kind of weird when they reach 50 and it doesn’t work at all any more. What she was doing working in a local government IT department I do not know.

I’ve described these two cases because they make an important point. I am not a psychotherapist, and I’ve never made any attempt to pretend to be one. I’ve only ever been able to destress teams by giving them good reason to be self-confident in technical areas. In almost every case that’s been enough. You do not have to be a “people person” to use this approach, there is nothing “fuzzy” about it. If workers need professional help that’s their private business and not yours, but sometimes you can support them if they want to do something more suited to them as they are.

Look, I have known people who write P and not P in consecutive paragraphs. They don’t just believe in contradictory ideas, they believe in two exact negations separated by maybe 5 seconds in time. And it’s not an “error” since even after it’s pointed out to them, they don’t see the fucking problem!

I absolutely agree. It’s astonishing but it’s true. The approach I describe in this blog is no trivial thing. It includes a radical reconsideration of just how peculiar the state we usually call “normality” really is. We didn’t evolve to be stressed out all the time, and now that as a culture we’re addicted to a background level of social stress it has profound effects on our cognition. I describe this phenomenon of believing contradictory statements, even when the contradiction is pointed out, in the section Expecting Self-Consistency. When stress reduces a person’s ability to juxtapose, they stop being aware of self-consistency (or the lack of it) in any collection of statements. Tell them two contradictory things and the alarm bells of contradiction don’t ring.

How does a person know what’s what if at the time, they cannot detect contradiction? Instead of using their own good senses they rely on compliance. If someone else tells them X and Y, they will accept X and Y as true, and will not worry that X contradicts Y. They haven’t been told about that, so they don’t worry about it. So long as they have complied with what they have been told, nothing else matters. Just as self-confidence is a self-sustaining spiral of improvement, so the lack of trust in our own good senses is a self-sustaining spiral of decline.

It’s also an empirical fact that most people cannot handle logical syllogisms. They can’t comprehend that “if A then B, and A, then B”. And this isn’t due to lack of education because we’re talking about college students here. Hell, I have known professors teaching symbolic logic who don’t comprehend logical syllogisms. Try to wrap your head around that one.

But it might not be. How can we tell? This is the origin of long-term stressed out people’s attitude to “mere facts”. We must not be to blame, so unless someone has told us B, we should not accept it. This is why, in stressed out schools with stressed out teachers “socializing” children by addicting them to stress, children will get detentions for contradicting clearly incorrect statements made by teachers. Only compliance can save us from the unknowable chaos that surrounds us.

As to professors, likely more of them are in the grip of social stress addiction than programmers are. They stand up and go “Blah blah blah”, the students write down every blah, but the content often isn’t significant at all. I once saw a remarkable demonstration of this by a gifted Economics lecturer. Part way through a talk on classical elasticity of demand he started to talk utter nonsense. He didn’t give any “Laugh now” cues with his tone of voice or cadence, he just said that demand for products usually purchased by women did not exhibit significant price elasticity because research has shown that women’s brains are smaller than mens, and on like that. Most of the students just kept scribbling, scribbling, scribbling. The minority of students who were lucky enough to keep their wits about them in conditions of addictive social stress did notice, but it took a few minutes before their rising disquiet cued the majority that something was going on, and then they started performing the political protest procedures that they had been habituated to - also by rote.

In the modern school systems of America and the UK, the scribbling students would be called “alert” and “able to focus”, while the really alert ones would be called “unable to resist distraction”, which is often “co-morbid with oppositional syndrome”. The introspective, stress addicted worm swallows its own tail, endorses its own errors.

And to beat them all, I have known people who can’t comprehend structural identity, even after an hour trying to explain it to them. They can’t comprehend, and will not accept, that two molecules of CO2 are absolutely identical and that swapping their positions swaps their identities.

You see, they can’t comprehend the abstract concept of an abstract concept because they don’t believe in the existence of abstract concepts. Because abstract concepts don’t exist in their brains.

I think that second sentence was intended to read, “… swapping their positions doesn’t swap their identities.” After all, that’s what equivalence means. I describe this on the Logical Effects page. It’s the same as the Monty Hall problem.

A person familiar with juxtapositional awareness will be able to spontaneously notice things, in an “all-or-nothing insight” way. Therefore when they do the famous symbol based thinking, they are able to bear in mind that the symbols are a (partial) representation of an external reality. Without this experience, the symbols and the reality are confused. The map becomes the territory. So in the Monty Hall problem, the internal symbols of the initial statement of the problem don’t change when the host supplies additional information, so people can’t believe that their choice might now be improved by changing. The same thing prevents people from getting their heads round Bayesian statistics.

So they can do symbols, but what they can’t do is the reality that the symbols represent. Anything involving imperfect knowledge or external identity becomes very confusing. This returns to Dijkstra’s observation that in mathematical proofs, “The underexploitation of the equivalence, i.e. the failure to exploit inherent symmetries, often lengthens an argument by a factor of 2, 4 or more.”

Consider: Prohibition creates the market for gangsters to make huge profits. Anyone who wishes to take drugs this weekend will be able to acquire them. Therefore, clearly, the solution to the gangster problem is… more Prohibition!

It is a sorry state.

Now you tell me, how the hell is it ever possible for such people to learn to program in any environment? How is it even conceivable? You would have to be some kind of fucked up retard to deny the overwhelming empirical evidence. Evidence which is literally all around you if you will just open your eyes to it.

People in the stressed state can’t program. Period. We have a software industry which is like a black comedy, with projects going over budget by orders of magnitude and many other problems, because the ability of some people to program most of the time, and most programmers to program on rare occasions, has led us to believe that all programmers can program all the time.

Try the experiment of going round your colleagues, inviting them to write a simple program to say, read in a string, reverse it and output it. It is shocking to discover how few of your colleagues will be able to swing round, open a file and type in such a program.

However, as I have explained in great detail, these problems come from social background stress preventing the prefrontal cortex from functioning in a way which permits programming. If we give people good reason to be self-confident we can reduce background stress and they turn on like lightbulbs.

It seems to me that the poster of this comment has become so distressed by the stress-induced stupidity all round him, that he has not bothered to follow the directions on the page What To Do Per Individual before making the empirical observations. It’s strange that after I’ve described much deeper problems than the poster has, the poster believes that I’m unaware of problems.

Many people who are immune to social stress addiction because of a broken DRD4 dopamine receptor, or an very active DAT allele, have been driven to a state of demented despair by the seemingly cynical, dishonest, arrogant, slothful, conspiratorial, delusional and evasive behaviour of those around them, which is just like the behaviour of those who induce a delusional state by raising their dopamine levels by taking cocaine.

If you program then know this: most people do not think like you, most people CANNOT think like you, most people can never comprehend you. But you can understand them if you just learn the basic concepts that underpin their minds. Of course, if you do this, you will become elitist.

If I did not know from personal experience that it’s a matter of health, and most people have all the truly normal faculties but in a dormant state, then I would be an extreme elitist. Try the following idea, which is something which might produce feelings of either satisfaction or compassion, depending on the depth of your rage: There’s a phenomenon called the “second childhood”. In this, elderly people develop unpredictable and exploratory behaviours like dragging abandoned shopping carts out of rivers. We know that advancing age reduces the neurochemical response to stress, and retirement significantly reduces a person’s participation in the social stress economy, so they wake up and really do become more like kids, before stress addiction sets in. This exploratory behaviour is annoying to their middle-aged, stress-addicted offspring, who start describing them as mentally handicapped - as they do their non-stress addicted children.

Now there’s another strange effect associated with the “second childhood”. The elderly person find that their memories of childhood are sharp, but their memories of most of their life are poor and indistinct. This is usually described as a bizarre failure mode of the elderly people’s advancing senility, but in the stress addiction model there’s a more chilling interpretation. As children they experienced their lives fully, and they remembered their experiences in the way that human memory should work. Then, at around age 6 they went to sleep. They stayed asleep until 65, when they woke up again, old and near the end of their lives. Those shoddy memories were all they had of most of their existence.

I have concluded that social stress addiction, as exposed by studying the mysterious subject of the practical industrial psychology of computer programming and then identifiable all over the place, is the greatest curse the human race has ever suffered.

All Postings, Logical Effects, Stress Addiction, Programming

Noise In Open Plan Offices

Way back in Peopleware, DeMarco and Lister were very critical of open plan offices, particularly the incessant noise of ringing telephones and other people’s conversations.

More recently at Joel on Software, Joel Spolsky has been saying the same thing over and over. So interesting to notice an abstract, Creativity and Breadth of Attention, which concludes that:

(a) trait breadth of attention was correlated modestly and positively (r =. 20) with creative performance; (b) creative performance was impaired by exposure to noise, especially noise that was unpredictable or intelligible; and (c) noise impaired creative performance more in participants whose trait breadth of attention was wide than in those whose trait breadth of attention was narrow.

So people with greater environmental sensitivity are more creative (here determined by writing poems, an acceptable alternative to writing Java), unpredictable phones and intelligible conversations are most impairing, and they impair the best people the most.

So open plan offices are shown to impair the performance of the highly priced workers put in them. This is bad accounting. Perhaps the motive for this bad accounting is an unconscious desire on the part of accountants to creative stressful, dopamine raising environments.

Neuroscience, All Postings, Stress Addiction, Programming

Variable Number of Adverts in Sidebar

I want a minimal look for this blog, with the text flows running cleanly down the middle, and ads in the sidebars. I want the ads to run to the bottom of the text flow, otherwise it’s just wasted space. I googled, expecting to find a code fragment to fill up my WordPress sidebar with ads, but found nothing. Then I realized I’d only ever seen blogs with the ads tailing off - sometimes near the top of a long flow, which then has very wide margins down to the bottom.

Here I explain how I did the left sidebar of this page, which you will notice is filled to the bottom with ads. The right sidebar is similar, it’s just a bit more complicated because there I have some lumps of layout above the ads, some space to make the Amazon ads on both side line up, then two groups of ads - one from Google and the other from Amazon.

Bear in mind: Google do not object to their ads being on the same page as Amazon Omakase ads, but they do limit you to 3 ads. (It’s bizarre - I thought they wanted to pump the stuff out.) I’ll take the 3 ads though, if only because then I know they’ll crawl the blog.

Anyway, here’s how it works. Amazon gave me the following code to embed in my pages:

  <script type="text/javascript"><!--
  amazon_ad_tag = "my_amazon_id";
  amazon_ad_width = "160";
  amazon_ad_height = "600";
  amazon_ad_logo = "hide";
  amazon_ad_link_target = "new";
  amazon_ad_border = "hide";
  amazon_ad_discount = "remove";
  amazon_color_link = "0000FF";
  amazon_ad_categories = "abcefg";//--></script>
  <script type="text/javascript"
          src="http://www.assoc-amazon.com/s/ads.js"></script>

I put in a few newlines for readability and put my_amazon_id where yours should go, but otherwise that should be a good example of what you got from Amazon - maybe with some different options chosen.

I placed it into my dynamic JavaScipt like this:

<script type="text/javascript"><!--

  count =
    Math.floor(document.getElementById('content1').offsetHeight / 600);

  chorus = "";

  if((navigator.appName.indexOf("Microsoft") == -1) &&
     (navigator.userAgent.indexOf("Firefox/1.0") == -1))
  {
    chorus += "<scr";
    chorus += "ipt type=\"text\/javascript\"><!--\r";
    chorus += "amazon_ad_tag = \"my_amazon_id\"; ";
    chorus += "amazon_ad_width = \"160\"; ";
    chorus += "amazon_ad_height = \"600\"; ";
    chorus += "amazon_ad_logo = \"hide\"; ";
    chorus += "amazon_ad_link_target = \"new\"; ";
    chorus += "amazon_ad_border = \"hide\"; ";
    chorus += "amazon_ad_discount = \"remove\"; ";
    chorus += "amazon_color_link = \"0000FF\"; ";
    chorus += "amazon_ad_categories = \"abcefg\"; ";
    chorus += "\/\/--";
    chorus += ">";
    chorus += "<\/scr";
    chorus += "ipt>";

    chorus += "<scr"
    chorus += "ipt type=\"text\/javascript\" ";
    chorus += "src=\"http:\/\/www.assoc-amazon.com\/s\/ads.js\"><\/scr";
    chorus += "ipt>";
  }
  else
  {
    chorus += "<scr";
    chorus += "ipt type=\"text\/javascript\" ";
    chorus += "src=\"http:\/\/the-programmers-stone.com\/level0.js\">";
    chorus += "<\/scr";
    chorus += "ipt>";

    chorus += "<scr";
    chorus += "ipt type=\"text\/javascript\" ";
    chorus += "src=\"http:\/\/www.assoc-amazon.com\/s\/ads.js\"><\/scr";
    chorus += "ipt>";
  }

  for(loop = 0; loop < count; loop++) document.write(chorus);
//--></script>

You might want to cut and paste that so you can look at it while reading the discussion!

I also created two files on my server, level0.js and level1.js. I’ll explain what these are for later on. The code above contains the full pathname to level0.js - make your adjustments. File level0.js contains:

document.write("<scr"+"ipt
src=\"http:\/\/the-programmers-stone.com\/level1.js\"
type=\"text\/javascr"+"ipt\"><\/scr"+"ipt>");

You’ll need to join those three lines of document.write() together, with spaces between the segments for it to work - I split it to make it fit.

File level1.js contains:

amazon_ad_tag = "my_amazon_id";
amazon_ad_width = "160";
amazon_ad_height = "600";
amazon_ad_logo = "hide";
amazon_ad_link_target = "new";
amazon_ad_border = "hide";
amazon_ad_discount = "remove";
amazon_color_link = "0000FF";
amazon_ad_categories = "abcefg";

You’ll want to put your own Amazon ID where indicated.

Now to explain it all! Amazon’s code contains two pieces of JavaScript. The first sets some global variables to choose options, then the second fetches some more JavaScript from Amazon and runs it.

I quickly discovered that just repeating the second piece doesn’t work, even if I hardcode it on the page. Instead of getting more ads the same shape as the first, all the others had default properties which included being short and fat instead of tall and thin. Obviously the second piece of JavaScript trashes the global variables set by the first, so it is necessary to repeat both pieces for each ad.

So I need to write a piece of JavaScript which figures out how tall the central section is (that’s the bit you’re looking at now), divide it by 600 pixels (which is the height of an ad), and execute both pieces of Amazon’s code that many times.

I know from looking at the files in my theme that the central section’s div is called content1, so in JavaScript I can get its height by saying:

  count =
    Math.floor(document.getElementById('content1').offsetHeight / 600);

It turns out that making this work in Internet Explorer and Firefox 1 is different to Safari, Opera, later Firefox or Konqueror. It’s probably why there are all those blogs with the ads trailing off. So I detect non-odd browsers and get them out of the way. It may be necessary to improve the list of odd browsers, but I think I’m already covering the vast majority in use today.

The non-odd code is quite simple. It assembles a string equivalent to Amazon’s code. When I write the string into the document, it will be interpreted and the JavaScript will be executed exactly as if it was hardcoded on the page. The only thing to watch out for is the escaping.

  • I broke all HTML <script> tags into more than one line, so the top level browser won’t think literals, inside quotes, inside JavaScript, are intended for it.
  • I put a backslash in front of each rabbit ears (") within Amazon’s code, so JavaScript wouldn’t think it was the end of the string I was appending.
  • Also a backslash in front of every slash. I don’t know what breaks without this but something does.
  • I made sure the newline after the HTML comment start (<--) was present using \r - I don’t care about any other newlines.
  • The HTML close comment (-->) which protects old browsers from JavaScipt code they don’t understand also had to be broken up.

Then all I have to do is write that string into the document as many times as I want ad blocks.

The problem with the odd browsers concerns breadth first vs. depth first recursion. In depth first recursion, we document.write() some <script> tags with JavaScript between them, and the browser detects the JavaScript and runs it straight away. If that JavaScript document.write()s more tags and code, the browser detects that and runs it, until it runs out of nesting and pops back up again.

In breadth first recursion, the browser goes through the whole document, finding the JavaScript and remembering where it was. Then at the end, it runs all the bits of Javascript one after the other, and inserts any document.write()s into the document. Then it scans the whole document again, until there’s no more to be done. It doesn’t help that the external JavaScript at Amazon is actually a wrapper that calls another external JavaScript at Amazon, because that makes the nesting problems really kick in.

It means that a program that tries to say:

  Set variables
  Call Amazon wrapper
      Call Amazon worker.
  Set variables
  Call Amazon wrapper
      Call Amazon worker.
  Set variables
  Call Amazon wrapper
      Call Amazon worker.

ends up saying:

  Set variables
  Call Amazon wrapper
  Set variables
  Call Amazon wrapper
  Set variables
  Call Amazon wrapper
    Call Amazon worker.
    Call Amazon worker.
    Call Amazon worker.

Oh dear. We are not setting the global variables prior to each call to the Amazon worker. We can arrange to do this by synchronising the depth of the variable setter with the depth of the Amazon worker. We say:

  Call set variables wrapper
    Call set variables worker
  Call Amazon wrapper
    Call Amazon worker
  Call set variables wrapper
    Call set variables worker
  Call Amazon wrapper
    Call Amazon worker
  Call set variables wrapper
    Call set variables worker
  Call Amazon wrapper
    Call Amazon worker

We get:

  Call set variables wrapper
  Call Amazon wrapper
  Call set variables wrapper
  Call Amazon wrapper
  Call set variables wrapper
  Call Amazon wrapper
    Call set variables worker
    Call Amazon worker
    Call set variables worker
    Call Amazon worker
    Call set variables worker
    Call Amazon worker
 

And that’s what level0.js and level1.js do! I know I could take the contents of level1.js, escape it, embed it in level0.js, escape the whole thing and embed it in the original call, but I fear I’d go mad before I got it right, and as far as I can tell from the server logs, the files get cached anyway.

I should add that by putting traces into files like level0.js and level1.js I discovered that most of the browsers actually perform horrible mixtures of depth and breadth first recursion in their execution paths, so some of them must be doing complicated variable scoping to simulate pure depth first recursion as far as side-effects on global variables are concerned. The odd browser solution, which should work everywhere with reduced efficiency, does not work on Safari. The breadth first solution probably stresses the depth first simulation on that browser. So the right approach seems to be: assume (simulated) depth first execution, if that doesn’t work then the simulation is poor enough that it won’t be confused by a breadth first algorithm.

When I did the Google ads on the right, I found that they just have a worker without a wrapper. So in that case the code on the page just calls level1.js directly.

I tested the technique on Safari 2, Firefox 2, Opera 9 (MacOs), Firefox 2, Konqueror 3 (Linux), IE6, IE7, Firefox 1, Firefox 2 (Windows XP), Dillo (pdaXrom). I got Konqueror to hang by scrolling up and down like crazy while the ads were loading, but I’ve seen Konqueror do that under much lighter loads, I don’t know anyone who uses it as a browser (it’s a great file manager), and anyway it installs with the ad filters on by default. Dillo doesn’t do JavaScript at all, but the text flow renders cleanly.

Beware that long sidebars can have overlap problems in IE6, if the main text flow has italics in it. You can solve this problem by conditionally linking a special CSS file as described here, which specifies a normal font style for the <blockquote> and <em> tags. Then use <em> like you should :-)

Obviously the depth synchronising trick is vulnerable to Amazon changing their depth of nesting, in a way that depth first recursion would not be. If they do change, the change will have to be investigated and fixed.

Programming