Tomáš Petříček, 309 (3rd floor)
petricek@d3s.mff.cuni.cz
https://tomasp.net | @tomaspetricek
https://d3s.mff.cuni.cz/people/tomaspetricek/
More programming language research in Prague
Ask about reading group!
Do a PL project or thesis!
Join us for a PhD?
Language should be based on sound formal foundations!
Haskell and pure functional languages
Self and pure object-oriented programming
Should be easy to compile and close to the underlying system!
Fortran, C but also
the Go language
Language should integrate well with the rest of the ecosystem
Scratch, HyperTalk, BASIC and aspects of Visual Basic
LINQ queries in Visual Basic .NET and C#
Dim db As New northwindDataContext
Dim ukCompanies =
From cust In db.Customers
Where cust.Country = "UK"
Select cust.CompanyName, cust.City
Why confuse programmers familiar with SQL?
SELECT [CompanyName], [City]
WHERE [Country] = 'UK'
FROM dbo.[Northwind]
Well, actually...
TypeScript by Microsoft
Hack by Facebook
Any new language version?
External definitions for existing libs (.d.ts
)
Not everything can be typed (allow any
)
JavaScript quirks
(null
vs. undefined
)
// Union type and null type
getElementById(elementId:string):
HTMLElement | null
// Overloaded function
// String literal types
createElement(tagName:"input"):
HTMLInputElement
createElement(tagName:"button"):
HTMLButtonElement
Overloaded functions
But with single implementation!
Flow-sensitive typing
To eliminate nulls
Union and literal types
More generally useful
type Option<'T> =
| Some of 'T // Option has a value
| None // Option has no value
match optElement with
| None -> failwith "out element missing"
| Some element ->
el.appendChild(input)
el.appendChild(btn)
typeof
works[42]
[0|1, number]
// Multiple overload signatures
function speak(animal:"dog") : void
function speak(animal:"cat") : void
// One compatible implementation
function speak(animal:string) {
switch(animal) {
case "dog":
console.log("woof")
return
case "cat":
console.log("meow")
return
}
}
Implementation signature is hidden
Overload signature has to be compatible with the implementation
Overloads can differ
in return type!
T1 | T2
)T1 & T2
)// Algebraic data type that
// represents an expression
type Expr =
// Numerical constant
| Const of int
// Named variable
| Variable of string
// Unary & binary operators
| Unary of string * Expr
| Binary of string * Expr * Expr
// Function with arguments
| Function of string * Expr list
Popular functional modelling tool
Entity consists of multiple sub-entities (operator + arguments)
Entity can be one of several options (number, variable, ...)
{ t:"s1" } | { t:"s2" }
= { t:"s1" | "s2" }
switch
!// Contact is an algebraic type
type Contact =
ContactEmail
| ContactPhone
| ContactAll
interface ContactEmail {
type: 'email'
email: string
}
interface ContactPhone {
type: 'phone'
number: number[]
}
interface ContactAll {
type: 'all'
email: string
number: number[]
}
Do they represent the same data?
interface Student1 {
name: string
email: string | null
number: number[] | null
}
interface Student2 {
name: string
contact: Contact
}
A->B
behave as \(B^A\)\(Contact = (Phone * Email) + Email + Phone\)
\(Student2\)
\(\quad =Name * Contact\)
\(\quad {\color{green}=Name * ((Phone * Email) + Email + Phone)}\)
\(Student1\)
\(\quad = Name * (Phone+1) * (Email+1)\)
\(\quad = Name * ((Phone+1) * Email + (Phone+1) * 1)\)
\(\quad = {\color{blue}Name * ((Phone * Email) + Email + Phone }{\color{red}\;+\;1})\)
// Returns book information consisting
// of title and year and description
// (only when detailed=true)
function getBook(index, detailed) {
let b = lookup(index);
if (detailed)
return {
title:b.title, year:b.year,
description:b.description }
else
return {
title:b.title, year:b.year }
}
How to check more dynamic behaviour?
Dependent types!?
Return type depends on the value (type) of the argument
List n T
List n T -> List m T -> List (n+m) T
type LabelOrId<T> =
// If T is a number,
// result has id:number
T extends number ?
{ id:number } :
// If T is a string
// result has label:string
T extends string ?
{ label:string } :
// Otherwise return
// unusable type
never;
cond ? type1 : type2
Result type depends
on another type
Condition can only check using extends
(subtype)
{ age:number; name:string }
keyof(P) = "age"|"name"
P["age"] = number
P[keyof P] = "number"|"string"
Pattern matching at the type level using infer/extends
Type level array and string interpolation
Representing numbers at the type level
You can do (big) arithmetic in TypeScript types
Why?
Good question...
but maybe matrix operations?
Safe data manipulation or charting libraries in TypeScript?
Types for untyped languages with existing codebase (R, Python)?
Advanced types in TypeScript
Tomáš Petříček, 309 (3rd floor)
petricek@d3s.mff.cuni.cz
https://tomasp.net | @tomaspetricek
https://d3s.mff.cuni.cz/teaching/nprg077