Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Fuzzy generics
Search
Alexey Palazhchenko
February 05, 2022
Programming
0
130
Fuzzy generics
Alexey Palazhchenko
February 05, 2022
Tweet
Share
More Decks by Alexey Palazhchenko
See All by Alexey Palazhchenko
Using PostgreSQL's Background Worker Processes For Fun and Profit
aleksi
0
72
Песнь Хорьков и Гоферов
aleksi
0
340
On Ferrets and Gophers
aleksi
0
230
How to Go Wrong with Concurrency
aleksi
2
750
Adding context to existing code
aleksi
1
120
Зачем и как написать свой database/sql драйвер
aleksi
1
160
Cooking gRPC
aleksi
1
840
Profiling and Optimizing Go Programs
aleksi
1
1.7k
Go: начало
aleksi
0
100
Other Decks in Programming
See All in Programming
リアーキテクチャの現場で向き合う 既存サービスの読み解きと設計判断
ymiyamu
0
120
In geheimer Mission: AI Agents entwickeln
joergneumann
0
120
Boost Your Performance and Developer Productivity with Jakarta EE 11
ivargrimstad
0
900
最速Green Tea 🍵 Garbage Collector
kuro_kurorrr
1
130
The Nature of Complexity in John Ousterhout’s Philosophy of Software Design
philipschwarz
PRO
0
170
fieldalignmentから見るGoの構造体
kuro_kurorrr
0
140
「MCPを使ってる人」が より詳しくなるための解説
yamaguchidesu
0
190
今話題のMCPサーバーをFastAPIでサッと作ってみた
yuukis
0
130
カオスに立ち向かう小規模チームの装備の選択〜フルスタックTSという装備の強み _ 弱み〜/Choosing equipment for a small team facing chaos ~ Strengths and weaknesses of full-stack TS~
bitkey
1
150
はじめてのPDFKit.pdf
shomakato
0
100
大LLM時代にこの先生きのこるには-ITエンジニア編
fumiyakume
8
3.4k
flutter_kaigi_mini_4.pdf
nobu74658
0
150
Featured
See All Featured
Become a Pro
speakerdeck
PRO
28
5.3k
What’s in a name? Adding method to the madness
productmarketing
PRO
22
3.4k
The Illustrated Children's Guide to Kubernetes
chrisshort
48
49k
The Straight Up "How To Draw Better" Workshop
denniskardys
233
140k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
30
2.4k
Site-Speed That Sticks
csswizardry
6
540
Java REST API Framework Comparison - PWX 2021
mraible
31
8.6k
The Power of CSS Pseudo Elements
geoffreycrofte
75
5.8k
Practical Orchestrator
shlominoach
187
11k
Embracing the Ebb and Flow
colly
85
4.7k
Designing for humans not robots
tammielis
253
25k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
Transcript
Fuzzy generics Several months of using 1.18 features Alexey Palazhchenko
FOSDEM 2022-02-05
None
Why Go 1.18?
Why Go 1.18? Generics
Why Go 1.18? Generics Fuzzing
Why Go 1.18? Generics Fuzzing
Generics
Generics • Generics do not work there; let's go back
to interfaces
Generics • Generics do not work there; let's go back
to interfaces • Let me extract a small example for a talk
Generics • Generics do not work there; let's go back
to interfaces • Let me extract a small example for a talk • Hm, that's not that bad
BSON Document
BSON Document • Ordered map
BSON Document • Ordered map • Keys – string, values
– any BSON value, including other documents
BSON Document • Ordered map • Keys – string, values
– any BSON value, including other documents • The central data structure in FerretDB
Interfaces type BSONType interface { bsontype() // sealed } type
Int int func (Int) bsontype() {} type String string func (String) bsontype() {}
Interfaces type BSONType interface { bsontype() // sealed } type
Int int func (Int) bsontype() {} type String string func (String) bsontype() {} type Document struct { m map[string]BSONType keys []string } func (*Document) bsontype() {}
Interfaces func (d *Document) Set(key String, value BSONType) { if
_, ok := d.m[key]; !ok { d.keys = append(d.keys, key) } d.m[key] = value }
Interfaces d.Set("foo", Int(42))
Interfaces d.Set("foo", Int(42)) d.Set("qux", nil)
Generics type BSONType interface { int | string | *Document
}
Generics type BSONType interface { int | string | *Document
} type Document struct { m map[string]any keys []string }
Generics func (d *Document) Set[T BSONType](key string, value T) {
if _, ok := d.m[key]; !ok { d.keys = append(d.keys, key) } d.m[key] = value }
Generics func (d *Document) Set[T BSONType](key string, value T) {
if _, ok := d.m[key]; !ok { d.keys = append(d.keys, key) } d.m[key] = value } syntax error: method must have no type parameters
Generics func DocumentSet[T BSONType](d *Document, key string, value T) {
if _, ok := d.m[key]; !ok { d.keys = append(d.keys, key) } d.m[key] = value }
Generics DocumentSet(d, "foo", 42)
Generics DocumentSet(d, "foo", 42) // DocumentSet(d, "qux", nil)
Interfaces func MakeDocument(pairs ...BSONType) (*Document, error) { l := len(pairs)
if l%2 != 0 { return nil, fmt.Errorf("%d arguments", l)
Interfaces
Interfaces MakeDocument( String("foo"), Int(42), String("bar"), String("baz"), )
Interfaces MakeDocument( String("foo"), Int(42), String("bar"), String("baz"), ) MakeDocument(String("invalid number of
arguments"))
Interfaces MakeDocument( String("foo"), Int(42), String("bar"), String("baz"), ) MakeDocument(String("invalid number of
arguments")) MakeDocument(Int(42), String("invalid key type"))
Generics
Generics func MakeDocument[T BSONType](key string, value T) *Document
Generics func MakeDocument[T BSONType](key string, value T) *Document func MakeDocument2[T1,
T2 BSONType](key1 string, value1 T1, key2 string, value2 T2) *Document
Generics func MakeDocument[T BSONType](key string, value T) *Document func MakeDocument2[T1,
T2 BSONType](key1 string, value1 T1, key2 string, value2 T2) *Document func MakeDocument3[T1, T2, T3 BSONType](key1 string, value1 T1, key2 string, value2 T2, key3 string, value3 T3) *Document
Interfaces
Interfaces func (d *Document) Get(key String) BSONType { return d.m[key]
}
Interfaces func (d *Document) Get(key String) BSONType { return d.m[key]
} assert.Equal(t, Int(42), d.Get("foo")) assert.Equal(t, nil, d.Get("baz"))
Generics
Generics func DocumentGet[T BSONType](d *Document, key string) T { v,
_ := d.m[key].(T) return v }
Generics func DocumentGet[T BSONType](d *Document, key string) T { v,
_ := d.m[key].(T) return v } assert.Equal(t, 42, DocumentGet[int](d, "foo")) assert.Equal(t, "", DocumentGet[string](d, "foo"))
Generics vs Interfaces
Generics vs Interfaces • Better in some aspects
Generics vs Interfaces • Better in some aspects • Worse
in others
Generics vs Interfaces • Better in some aspects • Worse
in others
Fuzzing
Fuzzing • testing/quick on steroids
Fuzzing • testing/quick on steroids • MongoDB binary protocol parsing
packages
Fuzzing • testing/quick on steroids • MongoDB binary protocol parsing
packages • FerretDB had fuzzing tests even before unit tests
Table-driven tests type testCase struct { name string b []byte
v bsontype err error }
Table-driven tests type testCase struct { name string b []byte
v bsontype err error } • Unmarshal b to (v2, err2) • compare with v or err • Marshal v2 to b2 • compare with b
Table-driven tests func TestDocument(t *testing.T) { for _, tc :=
range testCases { tc := tc t.Run(tc.name, func(t *testing.T) {
Fuzzing func FuzzDocument(f *testing.F) { for _, tc := range
testCases { f.Add(tc.b) } f.Fuzz(func(t *testing.T, b []byte) {
When b2 != b
When b2 != b • b might be larger than
needed
When b2 != b • b might be larger than
needed • The unread portion of b should be removed
When b2 != b • b might be larger than
needed • The unread portion of b should be removed • Some bytes might be insigni fi cant
When b2 != b • b might be larger than
needed • The unread portion of b should be removed • Some bytes might be insigni fi cant • Use canonization (json.Compact, etc)
Fuzzing issues
Fuzzing issues • No subtests (testing.F.Run)
Fuzzing issues • No subtests (testing.F.Run) • Unnamed seed values
Fuzzing issues • No subtests (testing.F.Run) • Unnamed seed values
• Hanging detection is unreliable with unset GOMAXPROCS
Fuzzing
Fuzzing • Found a few bugs in `go test -fuzz`
Fuzzing • Found a few bugs in `go test -fuzz`
• Found many many bugs in FerretDB
Fuzzing • Found a few bugs in `go test -fuzz`
• Found many many bugs in FerretDB • De fi nitely use it for parsing
Links • https://github.com/AlekSi/ generics-vs-interfaces • https://github.com/akutz/ go-generics-the-hard-way • https://go.dev/doc/tutorial/ •
https://go.dev/doc/fuzz/ • https://www.ferretdb.io • https://github.com/FerretDB ⭐ • https://github.com/AlekSi • @paaleksey