I almost never decide based on parameter mutability/immutability, but I've seen people mostly use the following rules (that are partially based on language features, partially on common sense):
If you want to use dot syntax for calling, put object of that type as a first parameter. This might be what you ment by "complex types", though only related to the first argument.
Optional parameters (with default values) should be put last - this is very common in almost all languages that support default argument values.
If you want to pass some parameter as block expression put it last (it might clash [1] with optional parameters, so you need to decide which one is more important)
While it is possible to put arguments aftervarargsI find this not really intuitive and try to avoid. So put varargslast when possible (and they also clash [1] with optional arguments)
Mutability/immutability is not really important for me personally, but things like add, incl, and others of course look better when you use seq.add(element)instead add(element, seq)`. But the difference is not so drasitic I think, so I would advise to decide on case-by-case basis.
[1]By "clash"I mean it might look really strange to the user - for example people might be confused by how variadic: varargs[int], defaulted: int = 2would be interpreted.
I do: The main calling object first so that dot syntax looks nice. Then everything else. Then optional parameters. I try to keep things consistent between similar functions. Maybe group similar types together like floats first then booleans. Thats about it. I don't overthink it.