Choosing between "loose and strict types"

Imagine that you have a binding language that enables you to bind values of your system in a text document e.g.

  • a directory with key-value pairs and more directories
  • or tables that act as collection of rows where each row in the same table has the same set of keys with different values

You can access these values by addressing the chain of directories followed by an optional table and finally the key name…

Here are some examples:

Dear [[input.recipient.name]],

[[UPPER(Input.message)]]

Best regards,
[[user.name]]

The binding language can be seen within the double brackets. E.g. user.name is the name of the user creating the document. user is the name of a directory or table and name the name of the key.

Creating this template would result in a greeting line like “Best regards,\nLotes”.

Also notice that the language provides function calls to built-in functions like UPPER(string).

Ok… puh that was the introduction…

Now imagine that following is given:

  • there is a table students whose rows are of type STUDENT(name: string, studentId: number)
  • there is a table employees whose rows are of type EMPLOYEE(name: string, salary: number)
  • a function GET_NAME(person: P) where P needs to be determined…

Now my problem:

Either the typesystem is loose or it is strict.

Typescript is loose, because the structure of the type is making the type. Its name is very unimportant. If two types have the same structure, they are the same. For example, if P is interface {name: string} both table row types are implicitly of interface P.

C# is strict, because the name of the type and their type dependencies have priority over its structure. If two types have the same structure, they are different except they share the same type dependencies. P is again interface {name: string}, but the table row types need to implement P in order to make GET_NAME work.

My final and maybe naive question is: what are the benefits and pitfalls for each decision? Strict or loose?
Because I think there is no middle way of deciding this. Once you have chosen a way, every action towards the opposite solution might end up in a hack… that is some gut feeling.

Does someone know this problem? Are there any pointers or did I create only a problem in my head? I called these principles loose and strict, maybe there are other names for them?

In some languages, an ID would be some unique value across the system, and not compatible with an amount of money. If your use a simplistic typing system like JS uses, then structurally, the STUDENT and EMPLOYEE records have the same quantity and position of fields, but the names don’t match, and JSON encoding of those two records would not match.

People get twisted into knots debating the various forms of type checking, and i see an awful lot of jargon tossed around. Fundamentally you have data whose storage format in RAM might be tagged (JS) or assumed by the compiler. Nobody is really arguing much about data; it is the variables in a program, and the implied variables that are in parameter lists that are constantly discussed.

Myself if find it very helpful if a program stays perfectly consistent about naming fields, so that every field with the name salary is always an amount of money for example, not suddenly a yes/no field.

Typing has the benefit of catching dumb errors, like putting “hello” into a salary field, which can’t possibly work. This type of error is invariably a typographical error on the part of the programmer, and strongly typed languages do a better job of catching errors before the program is run.

Theoretically they can also inform the compiler about how to optimize things, but with JIT technology, that advantage is diminished greatly, and we are seeing loosely typed languages, which allow quick and dirty programming, become very dominant.

This is not loose vs strict but structural vs nominal.

“Loose” or “weak” typing is usually employed to mean that the compiler or runtime liberally applies type conversions (e.g. from number to string and vice-versa). JavaScript and PHP are loosely-typed languages.

“Strict” or “strong” typing is used for languages that sparingly employ type conversions, requiring the developer to be explicit instead if they want to convert an object to a different type. Java, C#, Python, Common Lisp are strongly-typed languages.

This is, in principle, orthogonal to static vs dynamic typing (types are enforced by the compiler vs types are checked at runtime), but in practice statically typed languages tend to be strongly typed too.

2 Likes

Thank you, @alessio.stalla !!!

Finally, I have the right names :)…

Then, my question is about advantages and disadvantages using structural or nominal type systems :slight_smile:

I will look up myself. But maybe someone already knows and wants to tell me haha

One decision critera might be your domain: How probable are two types that have the same fields, but should not be the same or even only compatible?
For example, if you had lots of external references that are just strings or URLs, but are semantically very different: DataSource { URL } and DecidingOracle { URL } from smart contract domain would be structurally the same, but not semantically.
Other examples might be Duration { int[seconds] } vs. Timeframe { int[seconds] } from any time-related domain, or Legal Person { name, address } vs. Natural Person { name, address } from legal or tax domain.
The latter example provokes a thought: If both types extend Person { name, address } and don’t add any field, are they even meaningful? I.e. structural typing might be a bit at odds with OO inheritance?

For me this leads to the question “what makes a good object design and which paradigma helps more to achieve it?”…

I like nominal typing… like in XML namespaces or maybe Javascripts “symbols” feature… you define a name with some semantic… like: This is a name only for lakes and should not be miked with a name of a city…
Nominal typing feels like you can define better constraints. Whereas structural typing makes it easier to combine or exchange data…

I guess the question about what to choose is independent of how to achieve a good design…