Writing yaml

test(Id,Name,Description,IdFile,FileName,FileDescription,FileSize,FileType):-
    yaml_write(current_output,[thing{id:Id,name:Name, description:Description,data_distributions:[thing2{id:IdFile,name:FileName}]},thing{id:Id,name:Name, description:Description,data_distributions:[thing2{id:IdFile,name:FileName}]}],[]).

%%% ediprolog
%%%?- test(1,name,description,idFile,fileName,fileDescription,fileSize,fileType).
%@ - data_distributions:
%@   - id: idFile
%@     name: fileName
%@   description: description
%@   id: 1
%@   name: name
%@ - data_distributions:
%@   - id: idFile
%@     name: fileName
%@   description: description
%@   id: 1
%@   name: name
%@ true.

I expected:

%@ - id:1
%@   name: name
%@   description: description
%@   data_distributions:
%@   - id: idFile
%@     name: fileName
%@ - id:1
%@   name: name
%@   description: description
%@   data_distributions:
%@   - id: idFile
%@     name: fileName
%@ true.

My system expects the id to be the first item, then I do not think the order matters. Is there a way to get the yaml write to do this?

Your system is wrong, if it places significance on the key order.

E.g. Kubernetes will output YAML alphabetically sorted.

From a quick Googling:
https://yaml.org/spec/1.2.2/#mapping
“The content of a mapping node is an unordered set of key/value node pairs…”

Using yaml_write/3 to output a list, instead of a dict, would presumably retain the list order (I haven’t checked).

Here’s some code I wrote and have little-used, to convert between them:

% Recursively convert between Dict and pairs list
dict_pairs(Dict, Pairs) :-
    var(Pairs), !,
    % https://www.swi-prolog.org/pldoc/man?section=pairs
    dict_pairs(Dict, _, Pairs0),
    dict_to_pairs(Pairs0, Pairs).
dict_pairs(D, L) :-
    pairs_to_dict(L, D).

dict_to_pairs([], []).
dict_to_pairs([K-V|T], Pairs) :-
    is_list(V), !,
    dict_to_pairs(V, P),
    Pairs = [K-P|Pairs0],
    dict_to_pairs(T, Pairs0).
dict_to_pairs([K-V|T], Pairs) :-
    is_dict(V), !,
    dict_pairs(V, _, P0),
    dict_to_pairs(P0, P),
    Pairs = [K-P|Pairs0],
    dict_to_pairs(T, Pairs0).
dict_to_pairs([D|T], [P|Pairs]) :-
    is_dict(D), !,
    dict_pairs(D, _, P0),
    dict_to_pairs(P0, P),
    dict_to_pairs(T, Pairs).
dict_to_pairs([K-V|T], [K-V|Pairs0]) :-
    dict_to_pairs(T, Pairs0).

pairs_to_dict([], _{}).
pairs_to_dict([H|T], Dict) :-
    pairs_to_dict_([H|T], D),
    % Check whether list in K-V style
    (   D = [_-_|_] ->
        dict_pairs(Dict, _, D)
    ;   Dict = D
    ).

pairs_to_dict_([], []).
pairs_to_dict_([K-V|T], L) :-
    !,
    (   atomic(V) ->
        DH = V
    ;   pairs_to_dict(V, DH)
    ),
    L = [K-DH|Ds],
    pairs_to_dict_(T, Ds).
pairs_to_dict_([H|T], [D|Ds]) :-
    pairs_to_dict(H, D),
    pairs_to_dict_(T, Ds).

I actually think the software accepts the unordered list but as the yaml file is meant to also be read by people, and the reality I might have one hundred or more keys, it would good to retain the order, so the most pertinent keys such as id are at the top…

What’s stopping you from giving the humans a far more human-friendly output?

Do the humans need those 100+ keys detail?

It’s a good point.
But just trying to be consistent with how the files are used.
If there was a simple option I would use it, but if not then i’ll either live with it or write my own output format I guess.