Our second paper with @ququ7 and Niccolò on my PhD topic is out on arXiv!
https://t.co/D5kGnwaorH
We take the directed type theory and dinaturality story of our previous paper to make a more coherent (and simpler) story for the community interested in doctrines and rewriting.
The Tromp conjecture has just been revised. Two days ago someone on Discord found a way to implement a lambda calculus interpreter in 21 bytes instead of 24.
Side projects ARE the project.
In college, I was grinding so hard on side projects that they eventually paid for my college, became my thesis, and got me my job after college.
When I was interviewing, one of my most common questions was "So what are you working on at home?" That would annoy some, and yet excite others with the chance to be seen.
I believe certain creative people have a need to "get it out", and if you can't do it fully in your day job, you need to work on stuff at home.
You need to try new language features you aren't allowed to use at work yet. You've got to try new libraries outside your regular dependencies. Heck, learn Rust, I don't care. But growth happens "outdoors".
5 stages of NixOS users:
1: NixOS sucks, I have no use for it, I do not want my system to be immutable
2: Okay, immutability is fine. But I don't need it and want the flexibility
3: NixOS is awesome
4: NixOS sucks
5: NixOS sucks, but it's miles better than everything else
Type theory concepts and how important they're for a practical programming language.
Absolutely useless:
- Curry-Howard correspondence
- Decidability of type inference
- Decidability of type checking [1]
- Principality of typing
- Completeness
- Consistency
- W-types / TT containers
- Church-Rosser theorem
- Universe hierarchies
- Univalence
Basically useless:
- Totality (termination + productivity)
- Denotational semantics, especially categorical
- Gradual typing
More pain than gain:
- Let-generalization
- Recursion schemes
- Subtyping [3]
- Dependent typing [5]
- Refinement typing [6]
- Algebraic effects
Can be nice to have:
- Union and intersection types
- Proof search (for fancy autocomplete)
- Row polymorphism (for anonymous records)
Useful:
- Parametricity [4]
- Polarization
- Linear typing
- Type-level programming
- Data type encodings (for generics)
- Continuations
Very useful:
- Operational semantics
- Type-erasure semantics
- Normalization by evaluation
- Ad-hoc polymorphism
- Coherence
- Progress
- Subject reduction (preservation)
- Bidirectional typing (but not syntax)
- Pattern matching
- Exceptions
- Existentials (ideally strong ones)
- Higher-kinded types
- Metaprogramming (generics, staged etc)
[1] "I castrated my type checker so that I can prove that type checking terminates, potentially after the heat death of the universe" -- thanks, very useful
[2] Useful for instance resolution specifically, otherwise basically irrelevant
[3] Coercive + algebraic might be fine though
[4] There's a bazillion flavors of it and it has to be a lenient one
[5] Might be worth it if castrated like in Dependent Haskell
[6] Might be worth it if feature-rich and implemented intelligently, dunno
AI will ultimately be a powerful tool in the toolbox of every programmer, artist, and designer, just as high level languages, paint programs, and visual scripting were in previous eras. The opportunities available to everyone should ultimately increase as a result.
You can implement a basic dependently typed language from scratch in a couple of evenings.
If you gonna try that, I recommend elaboration-zoo by @andraskovacs6. In particular, 02-typecheck-closures-debruijn is a minimal dependent type checker (there's a parser too).
You can use the Escardó-Oliva functional write an X86 assembler. The encoding for a jump instruction depends on distances, which in turn depend on the encoding. It handles backtracking/pruning + picks the optimum!
https://t.co/DC6QnSswmK
Happily, it's a wonderful trick.
You iterate over the list twice simultaneously: by skipping two elements at once and by skipping just one. The former finishes right when the latter is in the middle of the list, so you get your latter half of the list (without recreating it, which would be unnecessary allocations) and can recreate the former one.
Here's how it looks in Haskell:
halve :: [a] -> ([a], [a])
halve xs0 = go xs0 xs0 where
go (_ : _ : xsFast) (x : xsSlow) = first (x :) $ go xsFast xsSlow
go _ xsSlow = ([], xsSlow)
Learned on MathOverflow: it is possible to write a finite formula for n! involving just the operations of addition, subtraction, multiplication, integer division, and exponentiation. Precise statement is here: https://t.co/g6QXAO9dxj
incredible new linguistic developments happening. my exchange student friends taught our japanese friends what “bruh moment” meant and theyve started shortening it to ブラモ
Compilers was was known to be the hardest CS class at Cornell which was hard as it is.
We were handed a 8-page PDF at the start of sem for a language spec we'd be implementing by the end of sem, split into 6 parts.
On part 5, the median was a 0/100 and most the class failed.