Hello Werner,
if I understood your post correctly, it contains basically two questions:
(1) how to make an expression in Mathematica type safe, so that incorrect types raise an error message
(2) how to create structures data types
Mathematica works more like an interpreter than a compiler, but supports compilation of functions. This can be employed to raise error messages in case of a type missmatch (which you already mentioned). Below is code (requires M12) that shows this for your examples:
Needs["Experimental`"]
First we define a function with excepts typed data, namely a list of two Real64.
tPointF = Function[
Typed[list1, TypeSpecifier["PackedArray"]["Real64", 1]], list1]
Next the function is compiled:
tPointT = FunctionCompile[tPointF]
Now we instantiate this function with two arguments, the first one fits the spec, whereas the second arguments is a list of two integers:
{tPointT[{1.23, 4.56}], tPointT[{1, 4}]}
The same can be done for a function that accepts one Real64:
zahlF = Function[Typed[zahl, "Real64"], zahl];
zahlT = FunctionCompile[zahlF];
Next step is to build a structure like datatype. The closest I came up with is a dataset:
createDataInstance[list_, zahl_] :=
Dataset[<|"p" -> tPointT[list], "z" -> zahlT[zahl]|>]
myDataInstance = createDataInstance[{1., 2.}, RandomReal[]]
Using a dataset you can access the data similar like from a struct:
{myDataInstance, myDataInstance["p"], myDataInstance["z"]}
And you can extract the raw data from it using Normal:
{myDataInstance // Normal, myDataInstance["p"] // Normal,
myDataInstance["z"]}
Is this what you had in mind?