@@ -0,0 +1,405 @@
3+footer: Kostyuchenko Ilya, Static analyzer for the Nix Expression Language
5+[.header: alignment(center), Avenir Next]
8+## Static analyzer for the Nix Expression Language
10+### Статический анализатор для Nix Expression Language
15+_Author:_ Kostyuchenko Ilya
17+_Supervisor:_ Victor Kuliamin, Associate Professor, PhD
21+> Nix is a powerful package manager that makes package management reliable and reproducible.
22+-- [nixos.org](https://nixos.org)
32+- Ad hoc development environments
33+- Easy (cross-community) dependency management
35+- *And much more: NixOS, NixOps, Build Caching, Docker ...*
41+# Nix Expression Language
47+- **Strict, but not static typing**
52+let pkgs = import ./nixpkgs {};
55+ builder = "${pkgs.bash}/bin/bash";
56+ args = [ ./simple_builder.sh ];
58+ coreutils = pkgs.coreutils;
60+ system = builtins.currentSystem;
66+[.text: text-scale(0.75)]
68+# Terms and definitions
70+**Type system** – a logical system comprising a set of rules that assigns a property called a type to the various constructs of a computer program
72+**Type checking** – the process of verifying and enforcing the constraints of types.
74+**Hindley–Milner type system** – a classical type system for the lambda calculus with parametric polymorphism.
76+**Parametric polymorphism** – a type of polymorphism where types are specified by abstract symbols that can represent any type.
78+**Row polymorphism** – a kind of polymorphism that allows one to write programs that are polymorphic on record field types.
84+The Nix ecosystem is slowly becoming popular.
86+The central repository contains more than 60000 packages.
88+There is a need to make writing Nix expressions less error-prone.
90+
96+Nix Expression Language: **Strict, but not static typing**.
98+Adding static typing would:
100+- Increase reliability of code
101+- Lower costs of development (resolving issue earlier is cheaper)
103+_The typechecker should help find issues in existing code_
109+1. Develop a type static system for the existing Nix expression language
110+2. Develop a type checker for this type system
114+# Existing typecheckers
116+- github.com/regnat/ptyx – Abandoned and incomplete.
117+- github.com/regnat/tix – An older version of ptyx. Abandoned, terribly incomplete.
118+- github.com/haskell-nix/hnix – has a module with a type checker. Is very experimental and is not used.
122+# Existing approaches
124+Type systems for functional languages is an actively researched field.
126+The Hindley–Milner type system_[1]_ is a simple, but well-studied type system for a very simple language. It is fully decidable, does not require annotations. It is the basis for many real-world type systems.
130+# Functional requirements
132+- The system should perform type checking on expression.
134+- The system should analyze the types and presence of attributes in attribute sets.
136+- The system should report encountered typechecking.
138+- The system should report the use of undefined terms.
140+- The system should report the resulting types of expressions to the user.
144+[.text: text-scale(0.85)]
146+# Methods and algorithms
148+The type system will be heavily influenced by the Hindley–Milner_[1]_ type system.
150+The type system will implement parametric polymorphism to support code that does not require a specific type.
152+The type system will implement arbitrary-ranked polymorphism_[3]_ with deep instantiation to disambiguate types in existing untyped code.
154+The type system will implement row polymorphism to work with attribute sets.
158+[.build-lists: false]
163+2. Visual Studio Code
164+3. Haskell Language Server
171+The typechecker is implemented in a two-step architecture:
173+1. Inferring the types of terms and collecting constraints
174+2. Solving the collected constraints
180+A typechecker executable that successfully typechecks _most_ of the selected files from _nixpkgs_.
182+The typechecker currently has some support for all language constructs.
184+
188+[.build-lists: false]
194+1. Nix Expression Language (80%)
195+2. Existing typecheckers (100%)
196+3. Existing approaches (100%)
197+4. Architecture (20%)
198+5. Implementation (0%)
201+
207+- Better type rendering (predicates)
209+- A lot of minor big fixes in type inference
210+- Add type information about built-in functions
214+# Potential future developments
216+- Add support for user-supplied type annotations.
218+ - Bidirectional type inference_[4]_
220+- Language Server Integration
224+[.build-lists: false]
225+[.text: text-scale(0.7)]
229+1. Damas L., Milner R. Principal type-schemes for functional programs //Proceedings of the 9th ACM SIGPLAN-SIGACT symposium on Principles of programming languages. – 1982. – С. 207-212.
230+2. Jones S. P. et al. Practical type inference for arbitrary-rank types //Journal of functional programming. – 2007. – Т. 17. – №. 1. – С. 1-82. MLA
231+3. Stuckey P. J., Sulzmann M., Wazny J. Improved inference for checking type annotations //arXiv preprint cs/0507036. – 2005. MLA
239+## Parametric polymorphism
242+let f = x: y: { a = x; b = y + 1;}; in f
246+∀ α. α -> Integer -> {a = α; b = Integer;}
251+## Parametric polymorphism
254+let f = x: y: { a = x; b = y + 1;}; in f
258+∀ α. α -> Integer -> {a = α; b = Integer;}
264+let f = x: y: { a = x; b = y + 1;}; in f "hello" 42
268+{a = String; b = Integer;}
273+## Row-polymorphism with _attribute sets_
280+∀ α β. (α.a = β) => α -> β
287+## Row-polymorphism with _attribute sets_
294+∀ α β. (α.a = β) => α -> β
300+let f = x: x.a; in f {a = 1; b = "hello";}
309+## Row-polymorphism with _attribute sets_
316+∀ α β. (α.a = β) => α -> β
322+let f = x: x.a; in f {a = "1"; b = "hello";}
331+## Row-polymorphism with _attribute sets_
338+∀ α β. (α.a = β) => α -> β
344+let f = x: x.a; in f {b = "hello";}
348+Error: key "a" NotPresent in { b = String; }
353+## Row-polymorphism with _attribute sets_
356+let f = x: x // {a = 69;}; in f
360+∀ α β. (α // {a = Integer;} ~ β) => α -> β
365+## Row-polymorphism with _attribute sets_
368+let f = x: x // {a = 69;}; in f
372+∀ α β. (α // {a = Integer;} ~ β) => α -> β
378+let f = x: x // {a = 69;}; in f {a = "hello"; b = "world";}
382+{a = Integer; b = String;}
387+## Row-polymorphism with _attribute sets_
390+let f = x: x // {a = 69;}; in f
394+∀ α β. (α // {a = Integer;} ~ β) => α -> β
400+let f = x: x // {a = 69;}; in f {}