Circular data types are perfectly fine with optional types. You can have optional<*raw_pointer> for example which after compilation may even be equivalent to a simple null, since valid pointers are not-null.
You also need type polymorphism (which Java and most of the languages under discussion did not have/did not start with), or it will drive you crazy.
And you may start needing fancier versions of polymorphism to express things like "this accepts a T=Foo or Optional<Foo>, and returns Bar<T>".
In passing, I remain to be convinced that that x?.length/etc syntax (and equivalents in other variations of Optional) is really a good idea - to me, it feels like an error-prone way of papering over the fact that non-explicit null(aka absent-optional) checks are just too painful to program with. Phrased differently, I see no reason to believe that the sufficiently-common-to-warrant-special-support appropriate handling of null is just to feed it up through as the computation of the computation if it occurs in any part.
There's one difference between nullable/non-nullable types and Optional type, which is nesting, right?
I'd assume that while Kotlin's String? is equivalent to Optional<String>, Kotlin has no equivalent to Optional<Optional<String>>.
Which, personally, I think I'd prefer Kotlin's approach, because that means you can do `maybeString = "exists"`, which is more readable than `maybeString = Optional::Exists("exists")`
Interesting, I haven't heard this argument before. So what is it about null that makes it more feasible here than for example option types/tagged unions?
Also, regarding your third point, IMO the question mark syntax in for example TypeScript and C# is fine.
Way back when when the JVM/CLR were being originally designed, I'm not sure that Option types as a concept were quite as proven, and both languages were trying to be "safe" languages that didn't have any complicated or new concepts in them. Optional types might not be that now, but they probably were then, when they were strictly in the domain of fairly academic languages.
2. Restricting a language to non-circular data structures will not be popular.
3. Having a nullable and non-nullable version of every pointer or reference type is not usually super popular either.
Phrased differently: nullable types are actually a fairly reasonable compromise from a set of not fully appealing choices.