i think if you create a role, you can GRANT EXECUTE TO YOURROLE, but that grants execute on all functions as well.
CREATE ROLE [ReallyReadOnly]
GRANT EXECUTE TO [ReallyReadOnly]
AFAIK granting permissions are two levels...you either grant access to everything, or you have to grant each object, one at a time...there;'s not any functionality to grant SELECT/UPDATE/DELETE/EXECUTE to say, just tables, or just views, or just procs...it's access to everything, or the hard way...a loop to do build/execute each statement for each object name.
you can use the metadata like sys.objects to build the GRANT EXECUTE ON [EachObjectName] TO YOURROLE statements, but if you added a new proc, or dropped and recreated the proc, then you have to remember to re-add the permissions again.
I wonder if you could build a DDL trigger that automatically added object names to some roles...
Lowell