ITT8060 Advanced Programming · Autumn 2026
Tallinn University of Technology
Lightning tour of F# as prose: notes.html
ITT8060Course team: Juhan Ernits · Hendrik Maarand · Ian Erik Varatalu · Kermo Kütsen (teaching assistant)
Contact: hendrik.maarand@taltech.ee — mention ITT8060 in the subject line.
Course page: fsharp.pages.taltech.ee
Moodle (gradebook, recordings, homework feedback): moodle.taltech.ee/course/view.php?id=38067
Teams: the link to the team is announced now and posted in Moodle.
Materials appear first at gitlab.cs.taltech.ee/itt8060-2026/course-materials.
ITT8060Recommended
Scott Wlaschin: Domain Modeling Made Functional — via O'Reilly library access with your uniid@taltech.ee address.
Don Syme, Adam Granicz, Antonio Cisternino: Expert F# 4.0 — via O'Reilly, as above.
Michael R. Hansen, Hans Rischel: Functional Programming Using F# — e-book at the TalTech library (Uni-ID login).
Supplementary
Tomas Petricek with Jon Skeet: Real-World Functional Programming (2010) — copies at the TalTech library. More at fsharp.org/learn.
ITT8060The course runs for 16 weeks. Each week a new topic in the lecture, then a practical session where you start on the homework.
Times and rooms: the timetable. Lectures are recorded.
The course is also offered as a Euroteq course; remote participation details are in Moodle.
This week's lab: sort out your Uni-ID (pass.taltech.ee), access to Moodle and GitLab, and see how automated test results are reported.
ITT8060Homework — 9 assignments × 4 points = 36%. Automated tests in your GitLab repository, plus oral defenses.
Midterm — week 9 (week of October 26, 2026), during the lecture, in person: 4%. You need to be there.
Exam — written, in person: 60%. At least half of the exam points are required to pass.
Grade scale: 91–100 → 5 · 81–90 → 4 · 71–80 → 3 · 61–70 → 2 · 51–60 → 1.
A bonus homework is planned for week 14.
ITT8060Every homework is tested automatically — and you must be able to explain your solution.
Defense required: homeworks 1, 4, 5 and 6. Passing these defenses is a prerequisite for admission to the exam.
Defense by random sampling: homeworks 2, 3, 7, 8 and 9 — a subset of submissions is called each round, so be prepared to defend any homework you submit.
A genuine effort trail with shortcomings → you get a chance to fix them.
No effort trail, or answers you cannot explain → the homework is not accepted, whatever the tests say.
ITT8060An AI assistant can produce a passing solution to every homework in this course. Passing tests therefore prove nothing about your learning — the defenses do.
Homework: AI tools are allowed as learning aids — explain a concept, explore an alternative, decode an error message. Solve it yourself first. The submission must reflect your own understanding: you explain, justify and modify any part of it on request.
Effort trail: develop in your homework repository with honest, incremental commits.
Midterm and exam: written in person, no AI tools.
Full policy: syllabus → Academic Practices → Use of AI Tools.
ITT8060
ITT8060In AI-assisted software development, producing code has become cheap.
What remains scarce:
Functional programming in F# trains you to think in types, transformations, invariants and effects — the skills you need to specify, review and supervise software regardless of who, or what, writes the code.
Correctness and clearly expressed intent matter more than typing speed.
ITT8060Think and program functionally: clean, well-structured programs whose correctness can be argued from their types and structure.
Model domains with types — discriminated unions and records that make the valid states explicit, so the compiler complains the moment code and intent diverge.
Build from pure, composable functions with visible effects — easier to reason about, test and safely modify, whoever makes the change.
Recognize where a functional approach is natural — and tell functional from imperative style in any language.
Test functional programs, including property-based testing; meet asynchronous and parallel programming in the functional setting.
ITT8060What was your first programming language?
Python · Java · C · C++ · C# · JavaScript · TypeScript · PHP · Kotlin · Swift · Scratch · Pascal · Basic · …
Was it functional?
Elixir · Erlang · Clojure · Racket · Haskell · OCaml · F# · Scala · Lean · Idris · Agda · Prolog · Whitespace · …
ITT8060Kotlin · Scala · Elixir · Erlang · Common Lisp · Clojure · Racket · Scheme · Haskell · Agda · Idris · OCaml · even C++ with the STL …
Most of them would teach the same ideas. F# lets us teach them in a language that is
open away;
ITT8060An industrially supported, functional-first .NET language.
Member of the eagerly evaluated ML family; closest relative: OCaml.
Integrates into existing .NET projects — C# code calls F# code without noticing.
F# is well designed. Did you read the paper?
Don Syme, The Early History of F#, HOPL IV, 2020 — doi.org/10.1145/3386325
In 2026 we use F# 10 on .NET 10. Course examples may use anything introduced up to that version.
ITT8060
ITT8060Computation is expressed in terms of a state and a sequence of state-changing operations.
i := 0; s := 0;
while i < length(A) do
s := s + A[i];
i := i + 1
od
An imperative model describes how a solution is obtained.
ITT8060An object is characterized by a state and an interface: a collection of state-changing operations.
Object-oriented models are expressed as collections of objects exchanging messages through their interfaces.
Object orientation adds structure to imperative models —
but an object-oriented model still describes how a solution is obtained.
ITT8060Focus is on what a solution is.
Logic programming — programs are formulas in a fragment of first-order logic, with a procedural reading based on inference.
Functional programming — a program is a mathematical function \(f : A \to B\), and function application guides the computation.
Some advantages: fast prototyping from abstract concepts · more advanced applications within reach · a complement to modeling and problem-solving techniques · runs in parallel on multi-core machines.
(Michael R. Hansen, 02157 Functional Programming, lecture 1)
ITT8060IEnumerable<string> GetExpensiveProducts() {
var infos = new List<string>();
foreach (var product in Products) {
if (product.UnitPrice > 75.00M) {
infos.Add(String.Format("{0} - ${1}",
product.ProductName,
product.UnitPrice));
}
}
return infos;
}
A growing list, a loop, a condition, an Add — state-changing operations.
To learn what comes out, you simulate the machine in your head.
ITT8060IEnumerable<string> GetExpensiveProducts() =>
from product in Products
where product.UnitPrice > 75.0M
select String.Format("{0} - ${1}",
product.ProductName,
product.UnitPrice);
Says what the result is: the expensive products, formatted.
Same language, same runtime — a different model of computation.
LINQ (2007) is functional programming in C#'s clothes.
ITT8060from product in Products
where product.UnitPrice > 75.0M
select String.Format("{0} - ${1}",
product.ProductName,
product.UnitPrice)
products
|> List.filter (fun p -> p.UnitPrice > 75.0M)
|> List.map (fun p ->
$"{p.ProductName} - ${p.UnitPrice}")
A pipeline: the data flows left to right through filter and map. Each stage is a function; nothing is mutated.
You will write this shape hundreds of times this semester.
ITT8060var updated =
from m in monsters
let nm = m.PerformStep()
where nm.IsAlive
select nm;
var updated =
from m in monsters.AsParallel()
let nm = m.PerformStep()
where nm.IsAlive
select nm;
LINQ on the left, PLINQ on the right: no shared state to protect, so one method call makes it parallel.
The payoff of declarative style: when you say what, the runtime may choose how.
ITT8060
ITT8060The model of computation in functional programming: application of functions to arguments — no side effects.
≈1930 — Church and Kleene introduce the λ-calculus while investigating function definition, application, recursion and computable functions.
\(f(x) = x + 2\) is written \(\lambda x.\, x + 2\).
Late 1950s — McCarthy's LISP: a type-less, functional-like language, used for AI problems.
ITT80601934 — Haskell Curry observes that the types of the combinators can be read as axiom schemes of intuitionistic implicational logic.
1958 — Curry: a Hilbert-style proof system coincides, on a fragment, with the typed part of combinatory logic.
1969 — Howard: natural deduction, in its intuitionistic version, is a typed variant of the λ-calculus.
Types are propositions, programs are proofs. That is why a compiler can check what you meant — and why week 15 visits Lean.
ITT80601977 — Backus' FP: a "variable-free" language built from a rich collection of functionals (combining forms for functions).
1970s — languages with strong type systems: ML (Milner) and Miranda (Turner).
Standard ML was designed for theorem proving: Logic for Computable Functions, Edinburgh LCF — Gordon, Milner, Wadsworth, 1977.
High-quality compilers built on a formal semantics: Standard ML of New Jersey, Moscow ML — Milner, Tofte, Harper, MacQueen, 1990 and 1997.
ITT8060SML-like systems (SML, OCaml, F#, …) are used far from their origins: compilers, artificial intelligence, data analysis, web applications, finance, mobile apps …
F# is a .NET language: The .NET Language Strategy.
Declarative features keep sneaking into the "mainstream" languages — LINQ, Java streams, pattern matching in C# and Python …
… and the ML family is often used to teach high-level programming concepts. Here too.
ITT8060F# was the first language to introduce an async modality to allow the localized reinterpretation of the existing control constructs of the language. Converting a piece of code from synchronous to asynchronous involved nothing more than wrapping async { ... } around the code and marking up the await points (let! in F#). This directly influenced the async/await mechanism added to C# 5.0 in 2012.
The C# async/await feature has been influential on TypeScript, Kotlin, Python 3.5, Java, JavaScript and other languages.
(Don Syme, The Early History of F#, 2020)
ITT8060
ITT8060functions and modules, higher-order functions · pipelines and composition · lists, arrays, sequences · pattern matching and active patterns · type inference
recursive functions and tail recursion · records and discriminated unions · option types · error handling by types · units of measure · property-based testing
object programming · asynchronous programming · computation expressions · type providers · quotations
Nearly all of them have counterparts in your other languages. Here you learn them where they are native.
ITT8060#r "nuget: FSharp.Data"
open FSharp.Data
[<Literal>]
let sample = """{ "data": [
{ "subject": "ITT8060",
"room": "ICO-221",
"start": "2026-08-31T10:00:00" } ] }"""
type Timetable = JsonProvider<sample>
for e in (Timetable.Parse sample).Data do
printfn "%A %s %s" e.Start e.Room e.Subject
A JSON sample becomes a type at compile time: e.Start is a DateTime, e.Room a string.
Misspell a field and the compiler tells you — before anything runs.
Types as specifications in daily work. Type providers: week 14.
ITT8060RE# — a derivative-based regular expression engine written in F# by Ian Erik Varatalu, and the fastest around on the standard benchmarks: cs.taltech.ee/staff/iavara/regex
Why it is fast: the paper at arxiv.org/abs/2407.20479.
Source: github.com/ieviev/resharp
ITT8060Now: VS Code, F# Interactive, and a first script — let, functions, tuples, pipelines, recursion, strings, and calling .NET.
Follow along in the notes: notes.html. The script is 01-introduction.fsx in course-materials.
Reading for this week: Hansen & Rischel, chapter 1; Wlaschin, part I.
Lab: Uni-ID, Moodle, GitLab — and a look at how automated tests report.
ITT8060