What can I do with VIEW DEFINITION permissions that I can't do with ALTER permissions? I have created a new user which has ALTER permissions on my database:
CREATE LOGIN [testuser] WITH PASSWORD = '...';
CREATE USER [testuser] FOR LOGIN [testuser];
GRANT ALTER TO [testuser];

To my surprise, ALTER does not imply VIEW DEFINITION:
SELECT HAS_PERMS_BY_NAME(DB_NAME(), 'DATABASE', 'ALTER'); -- yields 1
SELECT HAS_PERMS_BY_NAME(DB_NAME(), 'DATABASE', 'VIEW DEFINITION'); -- yields 0

And, indeed, according to the documentation, VIEW DEFINITION is only implied by CONTROL. So, apparently, VIEW DEFINITION includes some rights that ALTER doesn't.
Can someone give me an example of what can be done with VIEW DEFINITION permissions which cannot be done with ALTER permissions?
I did some tests (read column default values, script database object definitions), and I was unable to find an example myself - everything I tried &quot;just worked&quot; with ALTER permissions.
VIEW DEFINITION is a way to explicitly GRANT or DENY metadata visibility, but it's not the only way a user gets metadata visibility.
Users implicitly get metadata visibility without the VIEW DEFINITION permission on objects they own or have some other permission on:

The visibility of metadata is limited to securables that a user either
owns or on which the user has been granted some permission. For
example, the following query returns a row if the user has been
granted a permission such as SELECT or INSERT on the table myTable .

Metadata Visibility Configuration
And by default the public role has VIEW DEFINITION.  So while your user does not have the VIEW DEFINITION permission, ALTER on the database implies ALTER on all the objects, which allows the user to view the metadata of the objects.