
Beyond the type system - ingve
http://lucteo.ro/2018/06/17/beyond-the-type-system/
======
codebje
The purpose of a type system is to allow the programmer to more fully express
their intent in a way that allows static analysis to reject code which runs
counter to that intent. Not to alter the compiled code.

That there's no difference between a const ptr and a ref at runtime is
irrelevant, because there's a significant difference at compile time.

~~~
ivanbakel
A good type system can affect the compiled code through valuable static
analysis, though. Recognising when optimisations are possible via type
restrictions or techniques like monomorphising is an important part of modern
typed compilers.

~~~
AstralStorm
I'd prefer stronger methods like logic proofs and constraint or contract
specifications. Compilers could use those even better to optimize and check
the meaning of the program. Types are very limited logic constraints after
all.

While at it, you could ditch some of the old language.

Ultimately, everything is just some place in memory, cache and/or CPU
register.

~~~
icebraining
Dependent types can encode constraints and require proofs.

~~~
AstralStorm
Yes they do. In a supremely roundabout way typically making for ugly fat
proofs for anything high order. Sometimes, rarely, they make proofs cleaner
and more direct than high order logic.

Plus there is the potential undecidability if you want to use automated type
deduction. Hard to spot where the types have to be so to speak reified with
bad error messages.

------
wruza
>The type of %1 is %struct.MyType* and not %struct.MyType [1]. In the case of
references and pointers, clang actually transforms them into double pointers.
This is the first indicator that lvalues (all these C++ variables are lvalues)
are translated into pointers.

This statement can confuse those who never did assembly. The fact is that CPU
has only few fixed-size registers and there is no such thing like struct/array
value without an address [2]. So, when you write “struct MyType v”, it will
have an address on the stack, which will be loaded into the register for
further access. But naming it a pointer (and a pointer to it a double pointer)
is vague move. It is like naming an array a pointer too, since you have to
know head address to index elements beyond it. “v” is an address at low level,
but not a pointer, and while author is technically right, the terminology is
mixed and thus misleading.

[1] author wrote * here, but probably meant none.

[2] unless it is small enough to be completely optimized into registers.

Edit: punctuation

~~~
gpderetta
Even if the structure is not small enough, unless the address does not escape
(which can be common for local objects), the compiler is free to split it up
in its constituents and only store some (or none) of its constituents in
memory, which doesn't even need to be contiguous. I think this optimization is
called scalar replacement of aggregates.

/pedantic

------
mpweiher
Interesting.

In assembly and pre-ANSI-C, only (roughly) register sized things could be
values. So you had a split of things that lived in registers and things that
had to live in memory (everything that had the potential for being bigger,
structs, arrays).

OOP decided that everything should be like the things in memory.

FP decided that everything should be like the things in registers.

