Friday, 29 March 2013

Tricky

An answer to Dicky, by Robert Graves is Tricky, by Sam Liddicott

First the original poem, and then the answer.

DICKY by ROBERT GRAVES

Mother:
Oh, what a heavy sigh!
Dicky, are you ailing?

Dicky:
Even by this fireside, mother,
My heart is failing.

To-night, across the down,
   Whistling and jolly,
I sauntered out from town
   With my stick of holly.

Bounteous and cool from sea
   The wind was blowing,
Cloud shadows under the moon
   Coming and going.

I sang old roaring songs,
   Ran and leaped quick,
And turned home by St. Swithin's
   Twirling my stick.

And there as I was passing
   The churchyard gate,
An old man stopped me, 'Dicky,
   You're walking late.'

I did not know the man,
   I grew afeared
At his lean, lolling jaw,
   His spreading beard,

His garments old and musty,
   Of antique cut,
His body very lean and bony,
   His eyes tight shut.

Oh, even to tell it now
   My courage ebbs...
His face was clay, mother,
   His beard, cobwebs.

In that long horrid pause
   'Good-night,' he said,
Entered and clicked the gate,
   'Each to his bed.'

Mother:
Do not sigh or fear, Dicky.
   How is it right
To grudge the dead their ghostly dark
   And wan moonlight?

We have the glorious sun,
   Lamp and fireside.
Grudge not the dead their moon-beams
   When abroad they ride.

In my poem, I wished to tell the other side of a perhaps less fearful story.
Thinks aren't always what they seem, and sometimes, not even that.

Tricky, by Sam Liddicott


Uncle:
Oh, what a merry sound!
Ricky, are you chuckling?

Ricky:
This evening by this fire,
Uncle, My heart is laughing.

To-night, across the down,
   Whistling and jolly,
From town young Dicky sauntered
   With a stick of holly.

Bounteous and cool from sea
   The wind was blowing,
Cloud shadows under the moon
   Coming and going.

He sang old roaring songs,
   Ran, and leaping quick,
He turned home by St. Swithin's
   Twirling his stick.

And there as he was passing
   The churchyard gate,
Greeting him, I said: 'Dicky,
   You're walking late.'

I think he did not know me,
   He looked afeared
And my jaw, open fell,
   My theatre beard!

This outfit old and musty,
   Of antique cut!
I rocked in silent laugher,
   My eyes tight shut.

Oh, even to tell it now
   My humour rises...
His face was petrified,
   by costume trousers!

After an awkward pause
   'Good-night,' I said,
Passing through the churchyard gate,
   'Each to his bed.'

Uncle:
Do not laugh at fear, Ricky.
   How is it right
To terrify a little lad
   in the moonlight?

When by the glorious sun,
   Lamp and fireside.
 He knows you as a friend; so:
   Do not deride.

A long time ago I helped form the Open Rights Group.


Sunday, 3 February 2013

Forgiveness

I post this to point out that forgiveness isn't something available on demand, and also the dangers of letting the perpetrator define what forgiveness does and does not mean.

It can take the victim longer to work out forgiveness than it took the culprit to commit the offences and finally achieve a change of heart. This is something a repentant perpetrator may or may not be able to comprehend.

For example I might finally forgive my accountant for ripping me off and dashing my dreams and losing my house, but I wouldn't give him the chance to do it again, and I don't expect to be able stop suffering the injury and seeking revenge and punishment at his demand and admission. It would take time and effort and more time and more effort.

In other words I can eventually stop suffering from the injury, and I can eventually stop seeking revenge and punishment. But I don't have to give him access to my bank account in order to prove to him that I have reached or am trying to reach that state.

If someone thinks I haven't forgiven them, then that is their problem whether or not they are right. They just might have to forgive me.

Only the innocent victim knows what forgiveness entails, and only the repentant perpetrator wants it badly enough to wait for it.

And, for accuracy, there is one truly innocent victim who provides the means of healing and forgiveness for the injured and the guilty; when they want it badly enough to receive it.



Thursday, 31 January 2013

bash signal handling

A signal trap will not be executed while bash is implicitly waiting for an external command to complete.

I mean:

#! /bin/bash



trap "echo signal" 10
( sleep 1 ; kill -s 10 $$ ) &


sleep 5

We would expect the word signal to be emitted after 1 second, but the signal handler will not run until the sleep 5 is complete.

However, the built-in bash command wait does not have that problem, and so we can run the task in the background and immediately wait as in this example where the signal runs after 1 second.

#! /bin/bash



trap "echo signal" 10
( sleep 1 ; kill -s 10 $$ ) &


<&0 sleep 5 & wait

The <&0 is required to cover the case that the background command needs to read stdin which would otherwise not be connected for a background command.

The script also quits after 1 second even though the sleep is still running, so this variant detects if the background is still running and waits again:

#! /bin/bash



trap "echo signal" 10
( sleep 1 ; kill -s 10 $$ ) &


sleep 5 & wait
kill -s 0 $! &>- && wait

Of course this is insufficient for 2 reasons; the extra wait should be in a loop, but worse, the exit code is lost.

Tuesday, 29 January 2013

Poem: The smelly dog-pooh man


I wrote this in early 2008 for the Agbrigg & Belle Vue Community News

The smelly dog-pooh man

© 2008 Sam Liddicott

I'm the smelly dog-pooh man,
I walk around the town,
and leave my smelly dog pooh
where my doggie puts it down.

Not in gutters or in hedges
where no foot will hardly tread,
but the middle of the pavement
there to cake your shoes with dread.

Where the young ones and the old ones
and so many in between,
will spread about my pavement paste
from clumps they hadn't seen.

It's rather hard to miss something
so small and hard to see,
It's also hard to miss it
when its spread so wide and free

So the pushchairs and the children
do a dance around the mess,
that's been spread in pretty patterns –
now the cause of their distress

No-one sees me do it,
though you may observe my work,
or attempts by my apprentices
to spread a little dirt,

and I get a secret pleasure; when–
from behind a mother's door,
I hear the sound of pavement paste
discovered on the floor.

It's not that I'm too lazy
although that's also true,
but I like to punish others
with the things I hate to do.

So I'll leave it on the pavement
and pretend it isn't mine,
Till vengeful neighbours tell on me
and make me pay the fine.

Monday, 28 January 2013

gensym and unwind-protect for plain C

I wanted some simple C (I mean gcc's C, of course) version of unwind-protect, a clean-up block that was guaranteed to execute when scope for function finished. And a nice way to express it.

How does this look?

void do_test3() {
  int y=3;
  printf("hello\n");
  scope_cleanup {
    printf("cleaning up %d\n", y);
  }
  { int z=2;
    scope_cleanup { printf("inner cleanup %d\n", z); }
  }
  printf("bye\n");
}

main() {
  do_test3();
}

And when run it emits:

hello
inner cleanup 2
bye
cleaning up 3

Well darn tootin'! And you can have more than one in a function or scope too, without conflict!

How 'tis done

It's only half the story, but of course the heavy lifting is done with gcc's non-standard __attribute((cleanup(...))) which can be appended to any variable definition causing the function whose name is at ... to be called (with a pointer to the variable) when the variable goes out of scope.

Anyone who has used this feature will know how useful (though cumbersome) it is; e.g.

void free_ptr(void* ptr) {
  free(*(void**)ptr);
}
...
void* ptr=malloc(MAX_BUFFER) __attribute((cleanup(free_ptr)));

or

void close_ptr(void* ptr) {
  close(*(int*)ptr);
}
...
int fd =open(path, O_RDONY) __attribute((cleanup(close_ptr)));

But what I really want is to be able to specify is not a function but a clean-up block of code, and not tied to any particular variable, but which is executed when the scope end - like unwind-protect and such,

Something like that can be implemented using this method, but I was looking up nested function definitions in C today (I don't remember why) and I noticed that nested functions can be pre-declared using auto which made it possible to define a macro that would expand to this:

auto void cleanup (void* x);
int cleanup_var __attribute((cleanup(cleanup)));
void cleanup(void* x) ...

Of course the ... isn't part of the definition, it is the point at which a block can be expressed; which will be incorporated into the body of a nested function hastily called cleanup in this example.

Without pre-declaring the cleanup method, the cleanup method must be defined before the variable is declared, making it ugly having to pass the code block as a macro parameter.

gensym

Clearly it is easily possible to over-use the variable name cleanup_var and the function name cleanup simply by doing this more than once per function; what is needed is a way to generate unique symbol names in the C preprocessor.

It isn't possible, sadly (not really! got you there!) because the pre-processor cannot manage counters. But, (thinks I) we all know that a macro expands out to a single line and so one pre-processor symbol that always changes but remains the same for an expansion is __LINE__ (and "that be so" says you)
* see also __COUNTER__

So we have these definitions for gensym

#define GENSYM_CONCAT(name, salt) name ## salt
#define GENSYM2(name, salt) GENSYM_CONCAT(name, salt)
#define GENSYM(name) GENSYM2(name, __LINE__)

And this definition for cleanup (for those that couldn't work it out)

#define scope_cleanup auto void GENSYM(__cleanup__) (void* x); \
int GENSYM(__cleanup_var__) __attribute((cleanup(GENSYM(__cleanup__)))); \
void GENSYM(__cleanup__)(void* x)

of course, I am rather abusing the meaning of gensym by having it return the same name each time... the proper way would be to call gensym once and pass it's result to another macro but that would increase the risk of shadowing existing definitions, for which reason we are using gensym in the first place.

The original example expands out something like:

void do_test3() {
  int y=3;
  printf("hello\n");
  auto void __cleanup_29 (void* x); int __cleanup_var_33 __attribute((cleanup(__cleanup_29))); void __cleanup_29(void* x) {
    printf("cleaning up %d\n", y);
  }
  { int z=2;
    auto void __cleanup_33 (void* x); int __cleanup_var_33 __attribute((cleanup(__cleanup_33))); void __cleanup_33(void* x) { printf("inner cleanup %d\n", z); }
  }
  printf("bye\n");
}


Friday, 18 January 2013

A word on Technicalities

I read a comment from a chap who didn't care at all about technicalities but just thought people should pay their share of tax.

He didn't understand that it is the technicalities that make it possible to know what one's share of tax is so that one can pay it.

I think he felt like a benevolent dictator who could whip people into paying their share, but didn't realise the chaos that would ensue when the dictator next to him did the same thing but with a slightly different idea of what the share should be.

It was a sad case of the dangerous liberal dictators which goes like this: "If only everyone would do it my way it would all be so much better and we'd all get along so nicely."

It also reminds me of the more rabid US anti-gun folk who steam away thinking: If only we could MAKE them give up their guns, the country would be more safe and more peaceful; but without realising that they would have to MAKE them like it too, which is no more possible than making the anti-gun chaps like guns.

In other words: We only have these hard conversations because agreement is hard. Yet another attempt to sweep away disagreement isn't going to work.

Technicalities bring peace and order to confusion and disagreement without the need for full agreement.

It is sometimes easier to agree on technicalities than on principle; and that is what politics is, although in politics often the principle is not so much at stake as is who will get the bigger slice of pie.