This function correctly handles aliased paths and adds an 'active' class
attribute to links that point to the current page (for theming), so all
internal links output by modules should be generated by this function if
possible.

However, for links enclosed in translatable text you should use t() and
embed the HTML anchor tag directly in the translated string. For example:

This keeps the context of the link title ('settings' in the example) for
translators.

Parameters

string $text:
The translated link text for the anchor tag.

string $path:
The internal path or external URL being linked to, such as "node/34" or
"http://example.com/foo". After the url() function is called to construct
the URL from $path and $options, the resulting URL is passed through
check_plain() before it is inserted into the HTML anchor tag, to ensure
well-formed HTML. See url() for more information and notes.

array $options:
An associative array of additional options. Defaults to an empty array. It
may contain the following elements.

'attributes': An associative array of HTML attributes to apply to the
anchor tag. If element 'class' is included, it must be an array; 'title'
must be a string; other elements are more flexible, as they just need
to work in a call to drupal_attributes($options['attributes']).

'html' (default FALSE): Whether $text is HTML or just plain-text. For
example, to make an image tag into a link, this must be set to TRUE, or
you will see the escaped HTML image tag. $text is not sanitized if
'html' is TRUE. The calling function must ensure that $text is already
safe.

'language': An optional language object. If the path being linked to is
internal to the site, $options['language'] is used to determine whether
the link is "active", or pointing to the current page (the language as
well as the path must match). This element is also used by url().

So that is correct for D6, @rjbrown99, but in D7 the 'class' attribute value must be an array (see the $options parameter explained above). Just see how l() manipulates the 'class' attribute in the function body above; that code will break if you pass a string as you suggested.

There is no use commenting here about proposed changes, if you want to change the way that l() works you need to open a ticket in the core issue queue and submit a patch that can be run through our standard QA processes.

If you want to link to a local anchor (# on the same page), it requires a bit of tweaking. Using an empty path will lead to the root of the site, so you need to pump in the current path using $_GET['q'].

This example will create a local link to the comments section of a node: $link = l(t('Comments'), $_GET['q'], array('fragment' => 'comments'));

I was wondering why the l() function removes all HTML and PHP tags in the title attribute.

The drupal_attributes() function called below will run all of the attributes across check_plain() which should do the job. This filtering seems unnecessary (CPU consuming) and may break the rendering of the desired tooltip.

What about if I would like to create a link with a tooltip such as this?