It was pointed out to me that you can assign a UDT variable to a function by making the function "as string". The conversion from string to UDT is a "feature". An example:

[code=thinbasic]
dim v1 as UDTOne
v1 = Func1()

Function Func1() as string
local v as UDTOne
v.whatever = whatever
Function = v
End Function
[/code]

You can carry the "feature" further to pass UDT parameters which allows nesting of UDT functions just like you can nest regular functions. The danger in this is that there is no type-checking. You can do your own type-checking to be safer. But I think I'm going to use the concept. Here's an example.

[code=thinbasic]
Uses "Console"
' Example of Functions returning string=UDT,
' and UDT parameters as string

Type VectorXY
t as long ' for type checking?
x as single
y as single
End Type

Main()
WaitKey

Sub Main()
dim v1 as VectorXY
v1 = vLoad(11, 12) ' uses "feature"
vPrintAsVector("v1 = ", v1) ' normal call
vPrintAsString("v1 = ", v1) '
' vPrintAsVector("nested v = ", vLoad(21, 22)) ' can't do - wrong type
' example of nested parameters
vPrintAsString("nested v = ", vLoad(31, 32)) ' can do
End Sub

Function vLoad(x as single, y as single) as string ' really want "as VectorXY"
dim v as VectorXY
v.t = 1234 ' means type VectorXYZ
v.x = x: v.y = y
Function = v
End Function

Sub vPrintAsVector(s1 as string, v1 as VectorXY)
' normal - implicit type checking
Printl s1 & v1.x & ", " & v1.y
End Sub

Sub vPrintAsString(s1 as string, sv1 as string) ' accepts nested parameters
dim v as VectorXY
v = sv1 ' string to UDT
' have to do your own type-checking - may prevent difficult bugs
if v.t <> 1234 then Printl "TypeErr in vPAS": stop
Printl s1 & v.x & ", " & v.y
End Sub
[/code]

I hope I'm not into "dangerous" programming here.