comparative programming languages cm20253value (agda, coq, idris, etc.) for example intvec as a type...
TRANSCRIPT
TypesDependent Types
Next, there are dependent types, where a type depends on avalue (Agda, Coq, Idris, etc.)
For example IntVec<n> as a type of vectors of int of fixedlength n
Here, IntVec<3> is a different type to IntVec<7>
After all, it doesn’t make sense to pass a vector of length 3 to afunction that expects a vector of length 7
Advanced Exercise. But what about passing a vector of length7 to a function that expects a vector of length 3?
TypesDependent Types
Next, there are dependent types, where a type depends on avalue (Agda, Coq, Idris, etc.)
For example IntVec<n> as a type of vectors of int of fixedlength n
Here, IntVec<3> is a different type to IntVec<7>
After all, it doesn’t make sense to pass a vector of length 3 to afunction that expects a vector of length 7
Advanced Exercise. But what about passing a vector of length7 to a function that expects a vector of length 3?
TypesDependent Types
Next, there are dependent types, where a type depends on avalue (Agda, Coq, Idris, etc.)
For example IntVec<n> as a type of vectors of int of fixedlength n
Here, IntVec<3> is a different type to IntVec<7>
After all, it doesn’t make sense to pass a vector of length 3 to afunction that expects a vector of length 7
Advanced Exercise. But what about passing a vector of length7 to a function that expects a vector of length 3?
TypesDependent Types
Next, there are dependent types, where a type depends on avalue (Agda, Coq, Idris, etc.)
For example IntVec<n> as a type of vectors of int of fixedlength n
Here, IntVec<3> is a different type to IntVec<7>
After all, it doesn’t make sense to pass a vector of length 3 to afunction that expects a vector of length 7
Advanced Exercise. But what about passing a vector of length7 to a function that expects a vector of length 3?
TypesDependent Types
Next, there are dependent types, where a type depends on avalue (Agda, Coq, Idris, etc.)
For example IntVec<n> as a type of vectors of int of fixedlength n
Here, IntVec<3> is a different type to IntVec<7>
After all, it doesn’t make sense to pass a vector of length 3 to afunction that expects a vector of length 7
Advanced Exercise. But what about passing a vector of length7 to a function that expects a vector of length 3?
TypesDependent Types
This would allow a compiler to typecheck code like
// pair of vectors -> vector of pairs
fn pairvec<n: int>(v: DoubleVec<n>, w: DoubleVec<n>) -> ...
...
let pv = pairvec(a, b);
The compiler could check that the two vectors a and b havebeen declared with the same length
And possibly optimise the generated code as it then doesn’tneed a runtime length check, for example
TypesDependent Types
This would allow a compiler to typecheck code like
// pair of vectors -> vector of pairs
fn pairvec<n: int>(v: DoubleVec<n>, w: DoubleVec<n>) -> ...
...
let pv = pairvec(a, b);
The compiler could check that the two vectors a and b havebeen declared with the same length
And possibly optimise the generated code as it then doesn’tneed a runtime length check, for example
TypesDependent Types
This would allow a compiler to typecheck code like
// pair of vectors -> vector of pairs
fn pairvec<n: int>(v: DoubleVec<n>, w: DoubleVec<n>) -> ...
...
let pv = pairvec(a, b);
The compiler could check that the two vectors a and b havebeen declared with the same length
And possibly optimise the generated code as it then doesn’tneed a runtime length check, for example
TypesDependent Types
It may be that the lengths of a and b can only be determined atruntime
In that case, the compiler would try to prove that the lengths ofa and b must be the same
If it couldn’t prove that, it would raise an error and refuse tocompile the code: a type error
TypesDependent Types
It may be that the lengths of a and b can only be determined atruntime
In that case, the compiler would try to prove that the lengths ofa and b must be the same
If it couldn’t prove that, it would raise an error and refuse tocompile the code: a type error
TypesDependent Types
It may be that the lengths of a and b can only be determined atruntime
In that case, the compiler would try to prove that the lengths ofa and b must be the same
If it couldn’t prove that, it would raise an error and refuse tocompile the code: a type error
TypesDependent Types
More generally, the type can depend on any property
• Vectors of even length• Vectors whose elements are ordered (e.g., increasing)
according to a given function• Odd integers that are bounded by n• Pairs of integers where the first element is negative and
the second positive• And so on
TypesDependent Types
More generally, the type can depend on any property
• Vectors of even length
• Vectors whose elements are ordered (e.g., increasing)according to a given function
• Odd integers that are bounded by n• Pairs of integers where the first element is negative and
the second positive• And so on
TypesDependent Types
More generally, the type can depend on any property
• Vectors of even length• Vectors whose elements are ordered (e.g., increasing)
according to a given function
• Odd integers that are bounded by n• Pairs of integers where the first element is negative and
the second positive• And so on
TypesDependent Types
More generally, the type can depend on any property
• Vectors of even length• Vectors whose elements are ordered (e.g., increasing)
according to a given function• Odd integers that are bounded by n
• Pairs of integers where the first element is negative andthe second positive
• And so on
TypesDependent Types
More generally, the type can depend on any property
• Vectors of even length• Vectors whose elements are ordered (e.g., increasing)
according to a given function• Odd integers that are bounded by n• Pairs of integers where the first element is negative and
the second positive
• And so on
TypesDependent Types
More generally, the type can depend on any property
• Vectors of even length• Vectors whose elements are ordered (e.g., increasing)
according to a given function• Odd integers that are bounded by n• Pairs of integers where the first element is negative and
the second positive• And so on
TypesDependent Types
Dependent types are very hard to support in full generality, asthey can require the compiler to run arbitrary code to check thetype
E.g., vectors of prime number length
Exercise. Read about how C++ uses templates to support aform of dependent types
Exercise. Read about how Rust supports a very simple kind ofdependent types
TypesDependent Types
Dependent types are very hard to support in full generality, asthey can require the compiler to run arbitrary code to check thetype
E.g., vectors of prime number length
Exercise. Read about how C++ uses templates to support aform of dependent types
Exercise. Read about how Rust supports a very simple kind ofdependent types
TypesDependent Types
Dependent types are very hard to support in full generality, asthey can require the compiler to run arbitrary code to check thetype
E.g., vectors of prime number length
Exercise. Read about how C++ uses templates to support aform of dependent types
Exercise. Read about how Rust supports a very simple kind ofdependent types
Types
Such advanced types (higher kinds and ranks, dependent) areusually only seen in more experimental or research-drivenlanguages (Agda, Idris, some support in Haskell)
They are harder for the programmer to understand, and somehave theoretical problems, such as undecidable type inference
Simple fixed cases (like vector or structure constructors) arewidespread, but more programmatic use of higher level types isstill in the future for general-purpose languages
Though we are starting to see moderate support in languageslike C++ (templates), F# and Scala
And there is a history of “experimental” features eventuallyfinding their way into mainstream languages (e.g., classes)
Types
Such advanced types (higher kinds and ranks, dependent) areusually only seen in more experimental or research-drivenlanguages (Agda, Idris, some support in Haskell)
They are harder for the programmer to understand, and somehave theoretical problems, such as undecidable type inference
Simple fixed cases (like vector or structure constructors) arewidespread, but more programmatic use of higher level types isstill in the future for general-purpose languages
Though we are starting to see moderate support in languageslike C++ (templates), F# and Scala
And there is a history of “experimental” features eventuallyfinding their way into mainstream languages (e.g., classes)
Types
Such advanced types (higher kinds and ranks, dependent) areusually only seen in more experimental or research-drivenlanguages (Agda, Idris, some support in Haskell)
They are harder for the programmer to understand, and somehave theoretical problems, such as undecidable type inference
Simple fixed cases (like vector or structure constructors) arewidespread, but more programmatic use of higher level types isstill in the future for general-purpose languages
Though we are starting to see moderate support in languageslike C++ (templates), F# and Scala
And there is a history of “experimental” features eventuallyfinding their way into mainstream languages (e.g., classes)
Types
Such advanced types (higher kinds and ranks, dependent) areusually only seen in more experimental or research-drivenlanguages (Agda, Idris, some support in Haskell)
They are harder for the programmer to understand, and somehave theoretical problems, such as undecidable type inference
Simple fixed cases (like vector or structure constructors) arewidespread, but more programmatic use of higher level types isstill in the future for general-purpose languages
Though we are starting to see moderate support in languageslike C++ (templates), F# and Scala
And there is a history of “experimental” features eventuallyfinding their way into mainstream languages (e.g., classes)
Types
Such advanced types (higher kinds and ranks, dependent) areusually only seen in more experimental or research-drivenlanguages (Agda, Idris, some support in Haskell)
They are harder for the programmer to understand, and somehave theoretical problems, such as undecidable type inference
Simple fixed cases (like vector or structure constructors) arewidespread, but more programmatic use of higher level types isstill in the future for general-purpose languages
Though we are starting to see moderate support in languageslike C++ (templates), F# and Scala
And there is a history of “experimental” features eventuallyfinding their way into mainstream languages (e.g., classes)
Types Conclusion
Exercise. Read about sum and product types (see union andstruct in C and C++; or enum and struct in Rust)
Exercise. Function types can be constructed in somelanguages (using notation like lambda or -> or Fn). Read aboutthese
Exercise. Then find out about covariance and contravariance
Exercise. Read about algebraic data types
Exercise. Read about the Curry-Howard Correspondence
Types Conclusion
These days types are considered to be an essential part of alanguage
And so appear in many different kinds of ways
They are intended to reduce the opportunity for errors, or finderrors more quickly, or enable code to be more expressive
Even in early untyped languages there was a recommendationthat the intended type of a value be reflected in the name of avariable
iAge, fSalary. See Hungarian notation
Types Conclusion
These days types are considered to be an essential part of alanguage
And so appear in many different kinds of ways
They are intended to reduce the opportunity for errors, or finderrors more quickly, or enable code to be more expressive
Even in early untyped languages there was a recommendationthat the intended type of a value be reflected in the name of avariable
iAge, fSalary. See Hungarian notation
Types Conclusion
These days types are considered to be an essential part of alanguage
And so appear in many different kinds of ways
They are intended to reduce the opportunity for errors, or finderrors more quickly, or enable code to be more expressive
Even in early untyped languages there was a recommendationthat the intended type of a value be reflected in the name of avariable
iAge, fSalary. See Hungarian notation
Types Conclusion
These days types are considered to be an essential part of alanguage
And so appear in many different kinds of ways
They are intended to reduce the opportunity for errors, or finderrors more quickly, or enable code to be more expressive
Even in early untyped languages there was a recommendationthat the intended type of a value be reflected in the name of avariable
iAge, fSalary. See Hungarian notation
Types Conclusion
These days types are considered to be an essential part of alanguage
And so appear in many different kinds of ways
They are intended to reduce the opportunity for errors, or finderrors more quickly, or enable code to be more expressive
Even in early untyped languages there was a recommendationthat the intended type of a value be reflected in the name of avariable
iAge, fSalary. See Hungarian notation
Types ConclusionThere are many places to check for errors
• compile time: mostly type errors• run time: e.g., division by 0, null pointers, buffer overruns
(accessing beyond the ends of a vector)
Rust has pointers, but its type system is so strong it can avoidnull pointers at compile time and so can avoid this kind of runtime error
Haskell has no (explicit) pointers, and avoids these errors, too
Java has no explicit pointers, but still manages to get nullpointer exceptions
I don’t think there could reasonably be a language that checksfor 0 division at compile time!
Types ConclusionThere are many places to check for errors
• compile time: mostly type errors
• run time: e.g., division by 0, null pointers, buffer overruns(accessing beyond the ends of a vector)
Rust has pointers, but its type system is so strong it can avoidnull pointers at compile time and so can avoid this kind of runtime error
Haskell has no (explicit) pointers, and avoids these errors, too
Java has no explicit pointers, but still manages to get nullpointer exceptions
I don’t think there could reasonably be a language that checksfor 0 division at compile time!
Types ConclusionThere are many places to check for errors
• compile time: mostly type errors• run time: e.g., division by 0, null pointers, buffer overruns
(accessing beyond the ends of a vector)
Rust has pointers, but its type system is so strong it can avoidnull pointers at compile time and so can avoid this kind of runtime error
Haskell has no (explicit) pointers, and avoids these errors, too
Java has no explicit pointers, but still manages to get nullpointer exceptions
I don’t think there could reasonably be a language that checksfor 0 division at compile time!
Types ConclusionThere are many places to check for errors
• compile time: mostly type errors• run time: e.g., division by 0, null pointers, buffer overruns
(accessing beyond the ends of a vector)
Rust has pointers, but its type system is so strong it can avoidnull pointers at compile time and so can avoid this kind of runtime error
Haskell has no (explicit) pointers, and avoids these errors, too
Java has no explicit pointers, but still manages to get nullpointer exceptions
I don’t think there could reasonably be a language that checksfor 0 division at compile time!
Types ConclusionThere are many places to check for errors
• compile time: mostly type errors• run time: e.g., division by 0, null pointers, buffer overruns
(accessing beyond the ends of a vector)
Rust has pointers, but its type system is so strong it can avoidnull pointers at compile time and so can avoid this kind of runtime error
Haskell has no (explicit) pointers, and avoids these errors, too
Java has no explicit pointers, but still manages to get nullpointer exceptions
I don’t think there could reasonably be a language that checksfor 0 division at compile time!
Types ConclusionThere are many places to check for errors
• compile time: mostly type errors• run time: e.g., division by 0, null pointers, buffer overruns
(accessing beyond the ends of a vector)
Rust has pointers, but its type system is so strong it can avoidnull pointers at compile time and so can avoid this kind of runtime error
Haskell has no (explicit) pointers, and avoids these errors, too
Java has no explicit pointers, but still manages to get nullpointer exceptions
I don’t think there could reasonably be a language that checksfor 0 division at compile time!
Types ConclusionThere are many places to check for errors
• compile time: mostly type errors• run time: e.g., division by 0, null pointers, buffer overruns
(accessing beyond the ends of a vector)
Rust has pointers, but its type system is so strong it can avoidnull pointers at compile time and so can avoid this kind of runtime error
Haskell has no (explicit) pointers, and avoids these errors, too
Java has no explicit pointers, but still manages to get nullpointer exceptions
I don’t think there could reasonably be a language that checksfor 0 division at compile time!
Types Conclusion
There are other places for errors we often forget about
• link time, load time: making sure libraries are present,consistent and correctly called
• coding time: getting it right in the first place
Types Conclusion
There are other places for errors we often forget about
• link time, load time: making sure libraries are present,consistent and correctly called
• coding time: getting it right in the first place
Types Conclusion
There are other places for errors we often forget about
• link time, load time: making sure libraries are present,consistent and correctly called
• coding time: getting it right in the first place
Types Conclusion
“Strong types are for weak minds”Anon.