./2). If successful, 
write a reference to the head of the list into h and a 
reference to the tail of the list into t. This reference to h 
may be used for subsequent calls to this function. Suppose we want to 
return a list of atoms from a char **. We could use the 
example described by
PL_cons_list(), 
followed by a call to PL_unify(), 
or we can use the code below. If the predicate argument is unbound, the 
difference is minimal (the code based on PL_cons_list() 
is probably slightly faster). If the argument is bound, the code below 
may fail before reaching the end of the word list, but even if the 
unification succeeds, this code avoids a duplicate (garbage) list and a 
deep unification.
Note that PL_unify_list() 
is not used with env but with
tail, which is a copy of env. PL_copy_term_ref() 
creates a copy term_t holding the same Prolog term, i.e., not 
a copy of the Prolog term. The only thing that is allowed to be done 
with an argument to a foreign predicate (such as env) is 
unification; for anything that might over-write the term, you must use a 
copy created by PL_copy_term_ref(). 
The name PL_unify_list() 
is slightly misleading - it unifies the first argument (l but
overwrites the second (h) and third (t) 
arguments.
foreign_t
pl_get_environ(term_t env)
{ term_t tail = PL_copy_term_ref(env);
  term_t item = PL_new_term_ref();
  extern char **environ;
  for(const char **e = environ; *e; e++)
  { if ( !PL_unify_list(tail, item, tail) ||
         !PL_unify_atom_chars(item, *e) )
      PL_fail;
  }
  return PL_unify_nil(tail);
}
In this example, item is initialized outside the loop. 
This allocates a single new reference to a term, which is used as a 
temporary inside the loop - there is no need to allocate a new reference 
each time around the loop because the item term reference 
can be reused and the call to PL_unify_list() 
copies a reference to the new list cell's head into the the term 
referenced by
item.