# Difference between copy\_term/2 and functor/3

**URL:** <https://swi-prolog.discourse.group/t/difference-between-copy-term-2-and-functor-3/1139>\
**Category:** Help!\
**Created:** [September 2, 2019, 8:21am UTC](https://swi-prolog.discourse.group/t/difference-between-copy-term-2-and-functor-3/1139 "2019-09-02T08:21:19Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![swi](https://avatars.discourse-cdn.com/v4/letter/s/51bf81/32.png) [@swi](https://swi-prolog.discourse.group/u/swi)\
**Post date:** [September 2, 2019, 8:21am UTC](https://swi-prolog.discourse.group/t/difference-between-copy-term-2-and-functor-3/1139/1 "2019-09-02T08:21:19Z")

</div>

While [working](https://swi-prolog.discourse.group/t/declarative-predicates-by-limiting-resources/1114/30) on a directive to allow iterating through succeeding depths of recursion for an arbitrary predicate (even if the predicate does not terminate in normal prolog), it was pointed out that I should use `functor/3` instead of `copy_term/2` to obtain a most generic term.

What is the difference between these two if the argument of the compound terms is not instantiated?

```prolog
34 ?- copy_term(myterm(T),NewTerm1).
NewTerm1 = myterm(_1194).

35 ?- functor(NewTerm2,myterm,1).
NewTerm2 = myterm(_1104).

```

In my code it turns out the term generated by `functor/3` is more generic, than the one produced by `copy_term/2` as Jan pointed out.

I can’t grasp why the difference, if T is not instantiated.

EDIT: I understand `copy_term/2` shares ground terms and `functor/3` does not (of course), but here we’re dealing with an argument which is not instantiated.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [September 2, 2019, 8:36am UTC](https://swi-prolog.discourse.group/t/difference-between-copy-term-2-and-functor-3/1139/2 "2019-09-02T08:36:35Z")

</div>

I see. In your code the term that you copy is the most general term, so your copy will be most general too.

Probably using functor/3 is faster though. copy\_term/2 has to do a lot of work to figure out variable sharing, subtem sharing, cycles and ground terms. functor/3 simply allocates a term and fills it with variables.

---

<div class="post-metadata">

**Author:** ![swi](https://avatars.discourse-cdn.com/v4/letter/s/51bf81/32.png) [@swi](https://swi-prolog.discourse.group/u/swi)\
**Post date:** [September 2, 2019, 8:48am UTC](https://swi-prolog.discourse.group/t/difference-between-copy-term-2-and-functor-3/1139/3 "2019-09-02T08:48:20Z")

</div>

In my original code I was doing something like this:

```prolog
   functor(Head,Pred,Arity),
   % ...some code here...
   wrap_predicate(M:Head, iterate_depth, OrigPred,
      (
	 % We need to run iterate_depth_/4 only
	 % one time, on entry. Recursive calls
	 % need to be done normally (as if they
	 % were not wrapped)
	 prolog_current_frame(F),
	 prolog_frame_attribute(F,parent,P),
	 copy_term(Head,Head1),
	 ( prolog_frame_attribute(P,parent_goal,Head1)
	 -> call(OrigPred)
	 ; iterate_depth_(OrigPred, Start, Step, End, _Result)
	 )
      )
   ).

```

But this worked erratically until I changed it to `functor/3` like you suggested.

---

<div class="post-metadata">

**Author:** ![swi](https://avatars.discourse-cdn.com/v4/letter/s/51bf81/32.png) [@swi](https://swi-prolog.discourse.group/u/swi)\
**Post date:** [September 2, 2019, 8:49am UTC](https://swi-prolog.discourse.group/t/difference-between-copy-term-2-and-functor-3/1139/4 "2019-09-02T08:49:47Z")

</div>

> [@jan](#):
>
> Probably using functor/3 is faster though. copy\_term/2 has to do a lot of work to figure out variable sharing, subtem sharing, cycles and ground terms. functor/3 simply allocates a term and fills it with variables.

Thanks for this, I was using `copy_term/2` because I wrongly thought it would be faster.  
I’ll keep using `functor/3`.
