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).
A hand-coded "intersperse" might be written like this
intersperse(['',In2|Ins] ,['/'|Outs]) :- !, intersperse([In2|Ins],Outs). intersperse([In1,In2|Ins],[In1,'/'|Outs]) :- !, intersperse([In2|Ins],Outs). intersperse([''],[]) :- !. intersperse([In],[In]) :- !. intersperse([],[]).
Test code
:- begin_tests(atomics_to_string_3). test("atomics_to_string/3 always generates atom at the 3rd argument from any list-of-atomics") :- atomics_to_string([a,b],'&',X1A), assertion(X1A=="a&b"), atomics_to_string(["a","b"],'&',X2A), assertion(X2A=="a&b"), atomics_to_string([a,"b",12],'&',X3A), assertion(X3A=="a&b&12"), atomics_to_string([a,b],"&",X1S), assertion(X1S=="a&b"), atomics_to_string(["a","b"],"&",X2S), assertion(X2S=="a&b"), atomics_to_string([a,"b",12],"&",X3S), assertion(X3S=="a&b&12"). test("atomics_to_string/3 in 'accept mode'") :- atomics_to_string([a,b],'&',"a&b"), atomics_to_string(["a","b"],'&',"a&b"), atomics_to_string([a,"b",12],'&',"a&b&12"), atomics_to_string([a,b],"&","a&b"), atomics_to_string(["a","b"],"&","a&b"), atomics_to_string([a,"b",12],"&","a&b&12"). test("atomics_to_string/3 in 'accept mode' (surprisingly) disallows atom for argument 2",fail) :- atomics_to_string(["a",b],'&','a&b'). test("atomics_to_string/3 edge case works as expected") :- atomics_to_string([],'',X1), assertion(X1==""), atomics_to_string([''],'',X2), assertion(X2==""), atomics_to_string(['',''],'',X3), assertion(X3==""), atomics_to_string([""],'',X4), assertion(X4==""), atomics_to_string(["",""],'',X5), assertion(X5==""). test("atomics_to_string/3 splits as it should") :- atomics_to_string(L1,"&","a&b&c"), assertion(L1==[a,b,c]), atomics_to_string(L2,'&',"a&b&c"), assertion(L2==[a,b,c]), atomics_to_string(L3,"&",'a&b&c'), assertion(L3==[a,b,c]), atomics_to_string(L4,'&','a&b&c'), assertion(L4==[a,b,c]), atomics_to_string(L5,'&',"a&&b&&c"), assertion(L5==[a,'',b,'',c]), atomics_to_string(L6,'&','&a&&b&&c&'), assertion(L6==['',a,'',b,'',c,'']). test("atomics_to_string/3 processing input consisting only of splitters") :- atomics_to_string(L1,'&','&&&'), assertion(L1==['','','','']), atomics_to_string(L2,'foo','foofoo'), assertion(L2==['','','']). :- end_tests(atomics_to_string_3).