Find related names in the table
You can use a recursive CTE for this, provided you don't have more than 100 relations (since you can't add MAXRECURSION inside the function, so you'd have to apply it on any query that references the function - see an example here).

The first step is to find all the parent-less parents, then use that as an anchor for recursion.

CREATE FUNCTION dbo.my_func(@input nvarchar(50))
RETURNS TABLE 
WITH SCHEMABINDING
AS
  RETURN
  (
    WITH Parents(name) AS
    (
      -- find parent-less parents:
      SELECT name FROM dbo._test
      EXCEPT 
      SELECT related_name FROM dbo._test
    ),
    children AS
    (
      -- use parents as anchor
      SELECT orig = name, name FROM Parents
      UNION ALL
      SELECT c.orig, related_name 
        FROM dbo._test AS t
        INNER JOIN children AS c
        ON c.name = t.name
    )
    SELECT name 
    FROM children AS o
    -- now filter only to a single, common anchor
    WHERE EXISTS
    (
      SELECT 1 FROM children WHERE name = @input AND orig = o.orig
    )
  );


Then you can query:

SELECT name FROM dbo.my_func(N'b');


Results:

name
----
a
b
c
d


Of course it is easy to break this with a circular reference. Don't do that.