Revolutionary Technology in Formula One: Downforce-Generating Wings

As the lessons demonstrated by Colin Chapman’s use of the monocoque chassis filtered down through the rest of the Formula One grid, the cars changed shape towards a cigar-like form typified by the bodywork of the 1966 and 1967 seasons. In 1966, there was another change in the regulations, once again allowing three-litre engines which produced in the order of 350 to 400 bhp, about twice the power of the engines used from 1961 to 1965. With such a surfeit of power, the cars were unpredictable and wild, and a bit of extravagant cornering wouldn’t sacrifice too much time around a lap. Within a few years, though, both the bodywork of the cars and the driving styles had begun to change, though, as the cars began to be pushed down into the track by aerodynamic effects and driving styles became more precise in order to compensate.

As with other revolutionary developments in the world of Formula One, the changes in this period were derived from the world of aeronautics. It has, and had been known for a very long time that an aerofoil could generate lift in accordance with Bernoulli’s principle, and aeronautical engineering had progressed in leaps and bounds during the years of the Second World War. Ideas had been hopping around the Formula One paddock for years about the effect of a reversed aerofoil, which would work in the opposite way to a typical aeroplane wing, and indeed, a few minor experiments had been tried with this idea in motor racing, including Jim Hall’s experiments with the Chaparral racing cars in the mid 1960s. Unlike an aeroplane wing, which generates lift by creating a pressure differential between the longer airflow path on top of the wing and the shorter path on the bottom of the wing, an automotive wing creates downforce by reversing the pressure differential, with a longer airflow path on the bottom rather than the top.

It took until 1968 for a downforce-generating wing to find its way into Formula One. Ferrari, having apparently got over its period of conservatism which cost it development time over the early garagiste teams, and Brabham were the first teams to try the idea of placing an aerofoil onto their cars. In the 1968 Belgian Grand Prix, raced at the fast, flowing Spa-Francorchamps circuit, Ferrari used a high-strutted rear aerofoil balanced off with little tabs mounted to the front of the nosecone, while Brabham used a lower-mounted rear wing, but balanced it off with larger front winglets. While neither Brabham affected the race much, both exiting due to reliability issues, the Ferrari of Chris Amon easily snatched pole – four seconds in front of Jackie Stewart in his Matra.

Amon then set about challenging for the lead when his radiator gave up, thus ending an interesting experiment. To be fair, the Ferrari was already a quick car, with the wingless car of Amon’s teammate, Jacky Ickx, finishing third, but the proof was there that wings were a useful addition to Formula One cars. Meanwhile, Bruce McLaren took a maiden victory for his eponymous team, while other teams looked on and wondered what they could do with the new aerodynamic aids.

Lotus was, unsurprisingly, one of these teams. With Colin Chapman having an interest in aeronautical developments, and having introduced an idea found in aeroplane design into his racing cars before, it had not escaped Chapman’s attention that a reversed aerofoil could be used in this fashion, even before Ferrari and Brabham tried their own experiments. The Lotus Formula One cars soon sprouted wings, which were bolted onto the suspension and towered up into the air on thin struts in a decidedly ungainly fashion. The highly-mounted wings suffered less from turbulence than wings mounted lower down, but were, as several incidents the following year would demonstrate, highly dangerous.

By the end of 1968, Graham Hill had taken his second World Drivers’ Championship driving for Lotus, which took the Constructors’ Championship along with it. The Lotus team, with an exceptional car, powered by a refined Cosworth V8 engine and using the nascent technology of its aerodynamic aids to its advantage, made the most of a year where their top driver, Jim Clark, was killed early on in a Formula Two race and Graham Hill had to step up to the role of leading the team. More teams throughout the year had seen the advantages of downforce-generating wings, and they spread throughout almost the entire grid.

By 1969, the high-strutted rear wing of the Lotus 49B had been joined by an equally tall front wing which towered over the front suspension. Other teams, including McLaren, had similar wing layouts, but these proved problematic. The tall struts that the wings were mounted to proved fragile, as demonstrated in the practice session at the first Grand Prix of the season, held at Kyalami in South Africa, and the practice of mounting the wings to the suspension also proved troublesome. When both Lotus cars crashed out of the Spanish Grand Prix a couple of months later, downforce-generating wings were temporarily banned, only brought back when the rules were rewritten to permit low-mounted wings bolted to the chassis. The wings of today’s Formula One cars roughly resemble the layout of the later Formula One cars of the 1969 season, although they are far more evolved.

The aerodynamic expertise of the Matra team helped them win both the Drivers’ Championship, with Jackie Stewart at the wheel, and the Constructors’ Championship by significant margins. Lotus only reached third in the Constructors’ Championship, as an season of unreliability for Jochen Rindt, and several finishes out of the points for Graham Hill left them floundering. Some wasted development on the unsuccessful four-wheel drive Lotus 63 kept them from focusing their full attention on the car with more potential, although Matra and McLaren did try their own unsuccessful four-wheel drive systems, with little more success than Lotus. The aerofoil was clearly the way forward and the best way to maintain grip in a Formula One car.

Since the late 1960s, aerodynamic wings have been an omnipresent sight on Formula One cars, and have evolved from simple aerofoils to sophisticated items designed to channel the air as precisely as possible to the most efficient places to create downforce with a minimum of drag. The wings have changed shape considerably through the years, with the development of the Gurney flap, among other things. During the 1970s, large table-shaped rear wings were the norm, with some peculiar front wing designs throughout the years, while some of the cars in the early 1980s shed their front wings in the era of ground effect.

The cars of the early 1990s had noses mounted close to the ground, but by the middle of the decade, most of the front-runners had changed to a more highly-placed nose more reminiscent of today’s cars. Sculpted front wings, designed to push the air towards various critical places on the chassis, have been a notable part of recent Formula One cars. Whatever their configuration, though, the aerodynamic effects of the wings have been critical for success in Formula One almost since their first development, and they not only changed the dynamics of Formula One cars permanently, but also the appearance, as the large wings of today’s Formula One cars are their most obvious element, even to an unfamiliar spectator.

Arguments to main() in C – A Brief Guide

In the previous tutorial on variable types, we declared main() without any arguments, and indeed, without any return type. However, this declaration style takes advantage of certain implicit declarations in C. Just as we have left the auto declaration off our variables, with the compiler implicitly treating them like auto variables, so we have let the compiler implicitly declare a return type for main(). However, since the introduction of the ISO standard in C back in 1990, this style of declaration has been considered to be mildly bad practice. In fact, a proper main() declaration with no arguments looks like this:

int main(void)
{
    ...
}

and returns a value of 0 if the program exits successfully; non-zero if there is an error. This tends to be useful for debugging purposes; knowing the return value of your programs can help identify where errors are resulting from.

However, what we’re really interested in at this point are the arguments that main() may be given. main() typically takes two arguments, an integer value named argc (for argument count), which contains the number of command-line arguments that have been taken in, and a pointer to an array of character strings named argv[] (for argument vector), which contains the contents of the individual arguments.

While arguments to main are fairly uncommon in GUI systems, they still find their uses, such as arguments made to open a specific configuration file when opening, or an argument made to a computer game not to display the splash screen when it is starting up. In a command-line system, like the Unix systems where C was born and gestated, they are particularly important for giving the user control over the way they wish the application to be used.

One of the simplest programs to use command-line arguments is echo. In its simplest manifestation, echo simply takes its arguments (apart from the name of the program) and prints them to the standard output with a space between each of the arguments. This simple application, as demonstrated in The C Programming Language (Brian Kernighan and Dennis Ritchie, 2nd Edition, 1988) can be demonstrated here:

#include <stdio.h>

/* echo command-line arguments */
int main(int argc, char *argv[])
{
    int i;
    for (i = 1; i < argc; i++)
        printf("%s%s", argv[i], (i < argc-1) ? " " : "");
    printf("\n");
    return 0;
}

The invocation of this application on the command line as such: “echo hello, world” will print simply, “hello, world”. Given a set of arguments, argc is equal to the number of arguments, which in this case is three. argv[] will contain the strings for each of these arguments; argv[0] will contain “echo“, argv[1] will contain “hello,” and argv[2] will contain “world“. Given these arguments, there is a printf() statement embedded within a for loop which begins at 1 – thus skipping argv[0], which contains the name of the program.

The printf() statement prints two strings, one equal to the value of argv[i] and the other depending on the conditional operator, which finds out if i is less to argc-1. In the case that i is less than argc-1, argc-1 being a value that would point to the last argument in the argv[] array, it prints a space; otherwise, if i is equal to argc-1, it prints out a null string.

There is some potential for confusion with the offset of 1 between argc and the last explicit argument of argv[]. In fact, argv[argc] is defined as a null string, which will make more sense when we cover strings, but until then, all of the useful arguments in argv[] are contained in the array indices from 0 to argc-1.

The echo command may seem a bit trivial, but it has actual applications in a Unix or Unix-like system, particularly when it comes to reporting things in shell scripts. However, a lot of the uses of command-line arguments come courtesy of the idea of setting “flags” for the program. In a Unix system, flags are usually denoted by the minus sign, “-” at the start of the command-line argument. In order to do this adequately, we must include a header file with a function which can be used to compare strings. We can illustrate a use of a flag by modifying our echo command to have a command-line flag argument which allows the user to choose whether they want echo to print a new line or not.

#include <stdio.h>
#include <string.h>

/* echo command-line arguments, allowing newline flag */
int main(int argc, char *argv[])
{
    int i;
    int newline = 0;
    for (i = 1; i < argc; i++) {
        /* Compares two functions, returns 0 if both match */
        if (strcmp(argv[i], "-n") == 0) {
            newline = 1;
        } else {
            printf("%s%s", argv[i], (i < argc-1) ? " " : "");
        }
    }

    if (newline == 1)
        printf("\n");
    return 0;
}

 

 

In the case that “-n” is one of the arguments to main, the newline flag is set, which is checked near the end of the program. All other arguments are echoed to standard output. The strcmp() function takes two string arguments and compares them. If both match, strcmp() returns 0; otherwise, it returns a non-zero value which depends on whether the value of the first string is judged to be greater or less than the second string. This function will be discussed, as with the null string, when we cover strings more completely.

Variable Types in C: Auto, Static, Register and External – A Brief Guide

Apart from the regular types that a variable may have, like int, float, char, et cetera, there are a set of other qualifiers which may be added onto this in order to give the variable scope of the variable, whether that is local or global. A variable may have only one of these additional qualifiers at once.

The first of these types is auto, and it isn’t terribly interesting. Indeed, the auto type is very rarely specified, as it is the default for any place where the declaration is legal, and invalid elsewhere. An auto variable has local variable scope, meaning that it is only “visible” or can only be accessed and changed within the function or block in which it is declared. An auto variable disappears when it goes out of scope, freeing the memory which it was declared with, and any subsequent declaration of the variable will likely take place in a different part of memory. The use of an auto variable can be illustrated:

int sum_consecutive(int lower_bound, int upper_bound)
{
    auto int i; /* Value unknown! Probably something crazy. */
    auto int sum = 0; /* Will disappear when function finishes! */
    for (i = lower_bound; i <= upper_bound; i++)
        sum += i;
    return sum;
}

Neither i nor sum exist until the function is called. Both variables will probably be filled with junk until they are defined. Both variables can only be called or changed within the function in which they were called. Finally, both variables will disappear once the function has ended, their places in memory freed for other data. These variables have no persistence in memory.

Most of the time, this will be the desired effect, which is why it is the default for anything where it is legal. Sometimes, though, you want a variable to persist throughout the running of the program. This is where the static type comes in. A static variable is declared once at the start of a program, and it doesn’t disappear once it goes out of scope, unlike an auto variable. This can be illustrated by this simple function, which does little of use, but which is sufficient for demonstrative purposes:

#include <stdio.h>
int times_called(void);
main()
{
    int i;
    for (i = 0; i < 10; i++)
    printf("times_called() has been called %d times\n",
            times_called());
}

int times_called(void)
{
    /* The variable is declared and defined once.
     * Subsequent uses of the function will skip the declaration line. */
    static int i = 0;
    ++i; /* Incrementing the variable */
    return i;
}

If an auto variable was used instead of a static variable in times_called(), the return value would simply be 1 every time the function was called. The use of the static variable allows the variable to be incremented and for the value to be remembered throughout the program. The use of a static variable allows the function to work correctly. In the words of Brian Kernighan and Dennis Ritchie (The C Programming Language, 2nd Edition, 1988), “[…] internal static variables provide private, permanent storage within a single function.”

A third type of variable resembles the auto variable declaration. This is the register type, and while today’s optimising compilers make it largely unnecessary, it has its uses with older compilers and certain embedded systems like elevator controllers and the like. The register specifier suggests to the compiler to place a variable into a register if possible, although the compiler is free to ignore this. The & reference operator cannot be used with variables which have been declared to be register variables, regardless of whether they are actually placed into a register.

The use of this specifier would seem to be most useful on RISC microprocessors with a lot of general-purpose registers, such as the SPARC, MIPS and Power architectures and less so on standard PCs with Intel processors. Feel free to ignore it for the purposes of your own programs; the compiler usually knows best.

The final type specifier to be covered is extern, but in order to understand how to use it, one must understand where it might be used. Sometimes, one doesn’t want a specific variable to be limited to one function, but instead be visible to all functions. This is where global variables come into play. A global variable can be “seen”, called and changed by all functions, and this can be illustrated here:

#include <stdio.h>

int i; /* Global variable, declared outside any function. */

void funct(void);

main()
{
    i = 0; /* i isn't declared in main(), but can still be changed */
    i++; /* Again, changing i by incrementing it */
    printf("The value of i is %d\n", i);
    funct();
    /* i will be different after funct() */
    printf("The value of i is %d\n", i);
}

void funct(void)
{
    i++; /* i isn't declared in funct() either. */
    i += 3;
}

Running this program, we get the following results:

The value of i is 1
The value of i is 5

Even though i isn’t declared in either function, it can be accessed and changed in both functions. Notice that we don’t have to do anything special to access the variable in either function. This is because of the place where i was declared, right at the top of the program and before any of the functions. If we changed the place where i was declared, as in the following program:

#include <stdio.h>

void funct(void);

main()
{
    i = 0; /* i can't be seen by main()! */
    i++; /* This is a syntax error, and the compiler will complain. */
    printf("The value of i is %d\n", i);
    funct();
    /* i will be different after funct() */
    printf("The value of i is %d\n", i);
}

int i; /* This comes after main() and is no longer in its scope! */

void funct(void)
{
    i++; /* i isn't declared in funct(), but can be changed. */
    i += 3;
}

we’ll get a compiler error. main() is trying to access a variable called i, which as far as it is concerned, doesn’t exist. However, by using the extern specifier, main() can find i and change it in the same way as it did in the first program illustrating external variables.

In order to do this, we change main() to look like this:

main()
{
    /* Declaring an external variable, which is somewhere in
     * global scope */
    extern int i;
    i = 0; /* i can be seen again! */
    i++;
    ...
}

At this point, you may be wondering why we would use extern at all when we can just place the variable at the top of the source file and have it accessible to any function that needs it. The answer is that most serious projects in C are made up of several source files – and as an exercise, you should find a simple, free, open-source program written in C, such as GNU Nano, and look at how the program is constructed. A variable declared in one source file doesn’t exist in another one, and therefore, extern specifiers are required if one wishes to use global variables declared in other source files.

Be careful with the use of external variables. It is noted early on by Kernighan and Ritchie that the use of external variables can be dangerous, because they are always there even when you don’t want them. They have a tendency to make programs fragile and monolithic, and to destroy the generality and modularity of functions, such that they can’t easily be reused in other programs. This is antithetic to the aim of C to create a degree of modularity in programming, and should be avoided if at all possible.

Recursion in C: A Brief Guide

The problem with recursion in C is that there are a lack of simple yet illustrative demonstrations of how it may work. Being an imperative programming language which deals in changes of state, recursive techniques are not as important in C as they are in some programming languages, such as the Scheme dialect of Lisp. As well as that, two of the traditional mathematic expressions used to illustrate recursion, calculating a factorial and calculating Fibonacci numbers, are both inefficient uses of recursion in a computer. However, for the sake of completeness, I’ll illustrate both of them and explain afterwards why they are inappropriate examples for recursion.

So, what is recursion? Simply, it could be described as a method where the solution of a problem depends on solutions to smaller instances of the same problem. This might manifest itself as a function calling itself with a smaller set of arguments, or a lower value for an argument, for instance. Any function in C may call itself, creating a new instance of the function with new arguments.

We can show this easily by taking a function which calculates the factorial of a number. A factorial is calculated by taking a base integer, and multiplying it by all integers lower in value than it down to 1.

For example:

1! = 1
3! = 3 * 2 * 1
5! = 5 * 4 * 3 * 2 * 1
8! = 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1
0! = 1 /* Special case scenario */

Because of the relationship between higher and lower factorials, the procedure of calculating a factorial can be described recursively, or in relation to the process of calculating a factorial itself:

8! = 8 * 7!
8! = 8 * 7 * 6!
8! = 8 * 7 * 6 * 5!
...

This can be illustrated in a C function as such:

unsigned int fact (unsigned int n)
{
  if (n < 2)
     	return 1;
  else
	return n * fact(n - 1);
}

The first calling of the function from outside the function itself initialises it with an unsigned integer value, which is checked. If the value for n is less than 2, the function ends very simply by returning 1. Otherwise, the return value multiplies n with whatever the result of calling the fact() function with a new value equal to (n – 1) is.

Let’s say we called fact() in main with the value 5:

fact(5) = 5 * fact(4)
fact(5) = 5 * 4 * fact(3)
fact(5) = 5 * 4 * 3 * fact(2)
fact(5) = 5 * 4 * 3 * 2 * fact(1)

At this point, fact(1) is called. The if statement in the function is now satisfied, and so this calling of the function returns the value 1.

fact(5) = 5 * 4 * 3 * 2 * 1
fact(5) = 5 * 4 * 3 * 2
fact(5) = 5 * 4 * 6
fact(5) = 5 * 24
fact(5) = 120

Note, however, the pyramidal shape of the arguments in this function. A new instance of the fact() function must be called each time that the value of n is greater or equal to 2, which requires additional memory. Using C’s loop structure, it is possible to calculate a factorial in a single function using an iterative strategy which has better memory efficiency, particularly for higher values of n. This is illustrated below:

unsigned int fact_iter(unsigned int n)
{
	int product = 1;
	for (n; n > 1; n--)
	    product *= n;
	return product;
}

A similar number of calculations takes place in the iterative strategy as in the recursive strategy, giving both functions O(n) time complexity (i.e. the time taken to finish the calculation is proportional to the value of n), but as only a single function is needed in the iterative strategy, the space complexity of the iterative strategy is superior to that of the recursive strategy. The amount of space required for the iterative strategy is constant for any value of n (i.e. O(1)); the amount of space required for the recursive strategy is proportional to the value of n (i.e. O(n)).

Another mathematical function which demonstrates a recursive nature is the calculation of the Fibonacci numbers. The Fibonacci numbers are interesting to mathematicians because of their close relationship to the Golden Ratio. Each Fibonacci number is the sum of the previous two, which leads to a list like so:

1 1 2 3 5 8 13 21 34 55...

This relationship can be described recursively as so:

fib(n) = fib(n - 1) + fib(n - 2)

In C, this would be written in this way:

unsigned int fib(unsigned int n)
{
	if (n < 3)
	   return 1; /* fib(1) == 1; fib(2) == 1 */
	else
	   return fib(n - 1) + fib(n - 2);
}

Unfortunately, this use of recursion is even less suitable than that used in the calculation of a factorial. The function calls itself twice every time that the value of n passed to it is greater than or equal to 3; for fib(20), this results in fib() being called over 13,000 times! This function therefore has a time complexity of O(fib(n)), demonstrating a completely absurd use of recursion when an iterative strategy like this:

unsigned int fib_iter(unsigned int n)
{
	int sum = 2;
	int minus_one = 1;
	int minus_two = 1;

	if (n < 3) {
            return 1;
        } else { 	/* Take away 3 from x and keep going while n > 1 */
	   for (n -= 3; n; n--) {
	       minus_two = minus_one; /* minus_two equals the old minus_one */
	       minus_one = answer; /* minus_one equals the old answer */
	       answer = minus_two + minus_one;
	   }
	}

	return sum;
}

has time complexity O(n), and therefore runs far quicker on any non-trivial case.

So far, we have two functions which demonstrate mathematical examples of recursion where it is not suitable to use that recursive nature to calculate them in a computer. At this point, you may be asking, “Is there any point to recursion?”

The answer is: “yes, but not with anything that’s particularly easy to explain.” There is, however, a very strong argument for having recursion in the C language, and one of the examples given in The C Programming Language (Brian Kernighan and Dennis Ritchie, 2nd Edition, 1988) proves why.

The quicksort, invented by C. A. R. Hoare in the 1960s when on an academic trip to Russia, is a comparison sort which, as the name suggests, is one of the quickest sorting algorithms that has ever been invented. It uses a “divide and conquer” strategy, where a single element is chosen as a “pivot value” and the rest of the values are partitioned into two subsets: Those values which are less than the pivot value, and those with a greater value. The same process is then done recursively to the two subsets, and the recursion continues until there is only one element in a subset, whereby nothing needs to be done.

The following code comes from the fourth chapter of The C Programming Language, and demonstrates a version of the quicksort algorithm suitable for sorting integer arrays. A version of this that is suitable for any sort of element is available in the C standard library, under the function name qsort() defined in <stdlib.h>.

/* qsort: sort v[left]...v[right] into increasing order */
void qsort(int v[], int left, int right)
{
	int i, last;
	void swap(int v[], int i, int j);
	if (left >= right) /* do nothing if array contains */
	   return;	/* fewer than two elements */
	swap(v, left, (left + right)/2); /* move partition elem */
	last = left;
	/* to v[0] */
	for (i = left + 1; i <= right; i++) /* partition */
	    if (v[i] < v[left])
	       swap(v, ++last, i);
	swap(v, left, last);  /* restore partition elem */
	qsort(v, left, last-1);
	qsort(v, last+1, right);
}

/* swap: interchange v[i] and v[j] */
void swap(int v[], int i, int j)
{
	int temp;
	temp = v[i];
	v[i] = v[j];
	v[j] = temp;
}

In this function, an integer array is passed to the function, along with the leftmost and rightmost bounds of the element that are to be sorted. A function, swap(), is defined, which has an integer array and two integer values corresponding to array elements as arguments. The operation of the swap() function is similar to the swapping operations done in the bubble sort and shaker sort algorithms.

From here, if the element to be sorted only has a single element, which is defined by the value of left being the same as the value of right, the function returns to the calling function. There is nothing to be done; the sub-array of one element is already sorted by default. Otherwise, the partitioning element, which is the middle element of the array in this partitioning strategy, is swapped with the first element. The position of the left element is stored in a separate integer variable named last, so that it may be restored later.

The partitioning then begins. For all values of the array subset apart from left, if the value of v[i] is less than v[left], the element v[i] is moved to the left-hand side of the array subset. This continues until all values have been divided into values smaller than v[left] and values larger than v[left]. The qsort() function is then called again twice, once for each subset that has been created.

Quicksort may be a lot more difficult to understand than the likes of bubble sorting because of the extra complexity, but in this circumstance, the extra complexity in the function, along with its recursive nature, makes this a quicker option than an iterative strategy like bubble sorting, selection sorting or even the relatively efficient Shell sort. With a time complexity of O(n log n) in the average case, it blows the likes of bubble sorting and selection sorting out of the water in most cases, while only the likes of merge sort and heapsort can really complete with the quicksort algorithm for speed in most cases.

Sean Sherlock is a turd

I have previously written about how I was glad to see the American Stop Online Piracy Act or SOPA bill crumble into dust as the internet backlashed against it. Similarly, I am glad to see the strong opposition to ACTA in Europe which will hopefully have that bill destroyed. However, I did note that vigilance was necessary, because others would continue along the same lines – like Sean Sherlock, the Irish Labour TD who purports to be the Minister for State in the Department of Enterprise, Jobs and Innovation.

Recently, this treacherous snake introduced an equivalent bill to SOPA into the Irish Oireachtas, one that wasn’t even voted on by the Oireachtas, let alone the Irish populace. In a country where the growing IT industry is one of the few assets of the economy, this slimeball decides to introduce a bill against the wills of at least the 80,000 people who signed a petition against the bill, and one which could well harm the chances of IT firms setting up in Ireland for fear that they might be repressed. Enterprise, jobs and innovation, my ass. All Sherlock (and we’re all aware of the irony of that particular name) cares about is his kickback from the fat cat media industry, rather than actually supporting innovation from the companies which don’t just rely on derivative bullshit to keep them afloat.

I don’t get many Irish readers, and less still from the Cork East constituency where Sherlock runs, but if I do reach anybody in the constituency, make sure you don’t let this cockweasel anywhere near even a local council seat, let alone the Dáil. Clearly, all he’s good for in his current position is representing a big joke – and not a very funny one.