How to set add_query_arg properly for home page?

Is there a problem with the code?

Your code is already properly adding the lang query variable to the homepage URL. But you need to understand these points:

  1. On the homepage URL becomes http://localhost/mywebsitename/?lang=en which should be ok

    $wp->request is empty on the homepage, hence the above URL is expected. And you could use get_queried_object()->post_name to force the Page’s slug be in that URL, but WordPress would actually redirect you to the URL without that slug, because the Page is set as the static front page, which means the content at example.com and example.com/page-slug/ are identical and thus WordPress performs a (canonical) redirect when loading the latter URL.

  2. but supposedly it tries to load index.php instead of page.php, which generally wouldn’t be a problem but in that case some things like is_front_page() don’t behave as it should

    No, WordPress will try to load front-page.php, home.php or page.php before falling back to the index template. But even if the index template is used, is_front_page() would still behave properly — remember that the query determines the template and not the other way round.

    So one could say that “if is_front_page() returns true, page.php might be used”, but this is incorrect: “if index.php is used, is_front_page() would return false”.