Bug in PL/pgSQL function creation
This particular example can be simpler.
You can TRUNCATE multiple tables at once. Aggregate all tablenames and execute a single statement:

CREATE OR REPLACE FUNCTION truncate_tables(_username text)
  RETURNS void AS
$func$
BEGIN
   EXECUTE (
      SELECT 'TRUNCATE TABLE '
             || string_agg(quote_ident(t.tablename), ', ')
             || ' CASCADE;'
      FROM   pg_tables t
      WHERE  t.tableowner = _username
      AND    t.schemaname = 'public'
   );
END;
$func$ LANGUAGE plpgsql;


Call:

SELECT truncate_tables('postgres');


string_agg() requires PostgreSQL 9.0 or later.
In 8.4 you can substitute:

array-to_string(array_agg(quote_ident(t.tablename)), ', ')


For v8.3 you would write your own aggregate function - rather simple, yet not simpler than the looping solution any more.



Performance degrades when deleting or truncating many tables at once in PostgreSQL 9.1. A fix for this in the upcoming version 9.2. I quote the release notes:


  Improve performance of checkpointer's fsync-request queue when many
  tables are being dropped or truncated (Tom Lane)


Related thread at pgsql-hackers.

@Craig's related answer at SO helped me discover this.