Although I did report a bug for the problem I ran into and described above in bug #41831 I found a work-around by declaring a similar data structure differently. The new layout is handled properly by *customize*
buffer UI and I can identify a default with heterogeneous types in it.
Work-around defcustom declaration:
(defcustom pel-key-chords2
'((global ",." "<<<<<>>>>>\\C-b\\C-b\\C-p\\C-b\\C-b")
(global "<>" "<>\\C-b")
(global " q" pel-indent-rigidly)
(global "yu"
(lambda nil
(interactive)
(message "Hello You"))))
"Another way to implement the data structure, placing the choice
deeper inside the leaf data element.
This is handled properly by customize UI."
:group 'pel-pkg-for-key-chord
:type
'(repeat
(list
(symbol :tag "mode" :value global)
(string :tag "2-keys")
(choice (string :tag "expansion")
(function :tag "function")
(function :tag "lambda" :value (lambda () (interactive) <YOUR CODE HERE>))))))
In this new defcustom declaration, this is a list of 3 elements where the 3rd list element is a choice of 3 types, as opposed to a top-level choice of 3 lists of different 'sub-types' as I did originally and described in the question.
With the new declaration I can identify defaults, save the values and restore them as one would expect with Emacs customization mechanism.
So, at least, this works around the problem described in my original question, and it might help looking into the cause of the original Emacs defcustom UI implementation issue.
Important Note: another cause of the problem: unbound symbols at edit time
I also noticed that the customize UI will reject the data structure if a symbol identified in the data structure is not bound at the time the customize UI buffer is opened to edit the data structure.
So if something like pel-indent-rigidly is not bound when the customize buffer is opened and that symbol is part of the default quoted data structure, then the UI will fail and show the mismatch message again.
So in the end, it is important to ensure that the symbols will be bound when the defcustom default form will be shown for editing. That is what the defcustom :load keyword is for: to ensure that all symbols are known when the form is loaded for editing.