This always seemed a little overblown to me. A lot of arguments are something trivially obvious from both the type and the name, like "Environment environment", or they're a very generic type that's meaningless without the name, like "int num_players". I'm not saying you're wrong, just that types aren't automatically good documentation, and at least a good bit of the time they don't tell you any more than the name.dpJudas wrote:To me, the key feature of static typing is that it is documentation. To me, and the IDE 'go to reference' system. The type being used is often more useful knowledge to me than the variable name, or at the very least a strong hint what I can expect it to contain. I'm yet to find a way in dynamic languages to convey this information to other developers in a realistic way.
Oh, certainly. I'm aware I'm arguing this both ways.dpJudas wrote:A fine example of what you get from types being clearly declared to your fellow programmers.

I'm not completely opposed to static typing. I do like the look of Rust, though I haven't found an excuse to write something substantial in it yet. My objections are that it's a lot of upfront effort that only might justify itself later, and most type systems just aren't good enough. Squabbling with a type system because it just doesn't have a way to express an otherwise robust idea is incredibly annoying. So is using a type system that can't express constraints I think are important, like "this is not nullable".
It's nicer to have for a larger codebase, but I seriously doubt many ZDoom mods will compare in size to, say, ZDoom.
I'm aware! I've used them before.dpJudas wrote:But at least you know its a sector_t* and not a subsector_t*. In a dynamic language there is no way of knowing.

You're thinking about it in terms of a static language without the type annotations. In some ways (not all!) it could be easier in a dynamic language, because none of those types would be declared in the first place; they would just be "something like a number". You could convert a few fixeds to doubles at a time and let them propagate throughout the system without having to change anything else. Rig math operators to convert fixed operands to doubles, change a few macros, and you're already mostly done.dpJudas wrote:Imagine the floating point rewrite done to the software renderer in a dynamic language. As it is right now, half the types are double and other half fixed_t. I can see exactly which are which - in a dynamic language I'd be doomed.
I've done some wacky refactors on fairly large dynamic codebases, and they're much less intimidating if you're willing to embrace the dynamism when it's helpful. Especially for refactors that touch runtime behavior more than mere code structure. You're free to introduce temporary wrapper types, for example, without touching either the underlying type or the code that consumes it.
Fair! I do think I could make actor class creation work with Lua, which doesn't even have classes, but I haven't actually tried it yet. Or maybe not having classes would make it easier?Graf Zahl wrote:Let's not forget something: ZScript needs to interact and integrate with a large and complex existing native C++ class hierarchy.
Strong typing means no implicit runtime conversion. Python is fairly strongly typed; C is somewhat weakly typed.Graf Zahl wrote:@dpJudas: I fully agree on the documentation feature of strong types. The last Javascript project I worked on was a textbook example of playing loose with a liberal language: It was close to impossible to deduce what was which because the former developer showed no discipline either documenting his code or giving his variables self-descriptive names, or even using them consistently.
If this developer can't even name variables sensibly, what makes you think the code would've been any better in a statically-typed language? I envision that kind of dev making a struct like this and using it everywhere:
Code: Select all
struct data {
int int1;
int int2;
int int3;
string str1;
string str2;
};
// arg1 is an x/y coordinate, where (int1, int2) are (x, y)
// arg2 is the player data, where str1 is the name and ints 1-3 are a model color
// now imagine these comments weren't here. good luck!
void create_player(data& arg1, data& arg2);
I need a shower after writing that struct. Let's hope this hypothetical person doesn't find out about downcasting.
I think you have this backwards. People use TypeScript because they want to — because they're already putting thought into their architecture, and they want a compiler to double-check their effort. Someone who doesn't value good architecture isn't going to suddenly "get it" because they have to write out type names. The whole point of static typing is that you get to express the constraints you made up; nothing says the constraints have to be sensible.Graf Zahl wrote:To be blunt: It's the completely wrong way to go, and the mere fact that Microsoft invented TypeScript to get around Javascript's deficiencies tells me more than anything else. A typed language forces the programmer to put in a lot more thought up front and to me that's only a good thing.
At the end of the day, ZScript is yours to design however you want, but please at least believe that it's entirely feasible to write typeless code that isn't total garbage — and equally feasible to write typeful code that is.
