Your choices
Your choice of predicate is as follows:
Two concatenable terms as input (can split)
- atom_concat/3 (ISO)
- string_concat/3
Two more general concatenable terms as input (cannot split because arguments 1 and 2 are too general)
A list of concatenable terms as input (never split)
- atomic_list_concat/2 - generates atom at argument 2. Refuses string at argument 2 in accept mode (that's likely a bug).
- atomics_to_string/2 - generates string at argument 2. Refuses atom at argument 2 in accept mode (that's likely a bug).
A list of concatenable terms as input, and intersperse another string (can split at interspersed string)
- atomic_list_concat/3 - concatenate with separator ("intersperse", "join"). Refuses string at argument 3 in accept mode (that's likely a bug).
- atomics_to_string/3 - concatenate with separator ("intersperse", "join"). Refuses atom at argument 3 in accept mode (that's likely a bug).
Test code
:- begin_tests(atomic_list_concat).
test("atom_list_concat/2 always generates atom at the 3rd argument from any list-of-atomics") :-
atomic_list_concat([a,b],X1),
assertion(X1==ab),
atomic_list_concat(["a","b"],X2),
assertion(X2==ab),
atomic_list_concat([a,"b",12],X3),
assertion(X3==ab12).
test("atom_list_concat/3 in 'accept mode' (as expected) allows atomics in the list") :-
atomic_list_concat(["a",b],ab),
atomic_list_concat(["a",12,b],a12b).
test("atom_list_concat/3 in 'accept mode' (surprisingly) disallows string for argument 2",fail) :-
atomic_list_concat(["a",b],"ab").
test("atom_list_concat/3 edge case works as expected") :-
atomic_list_concat([],X1),
assertion(X1==''),
atomic_list_concat([''],X2),
assertion(X2==''),
atomic_list_concat(['',''],X3),
assertion(X3==''),
atomic_list_concat([""],X4),
assertion(X4==''),
atomic_list_concat(["",""],X5),
assertion(X5=='').
test("atom_list_concat/3 refuses to generate",error(instantiation_error)) :-
atomic_list_concat([a,_X,c],abc).
:- end_tests(atomic_list_concat).