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
200
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Fuzzy generics
Alexey Palazhchenko
February 05, 2022
More Decks by Alexey Palazhchenko
See All by Alexey Palazhchenko
Using PostgreSQL's Background Worker Processes For Fun and Profit
aleksi
0
200
Песнь Хорьков и Гоферов
aleksi
0
400
On Ferrets and Gophers
aleksi
0
290
How to Go Wrong with Concurrency
aleksi
2
810
Adding context to existing code
aleksi
1
180
Зачем и как написать свой database/sql драйвер
aleksi
1
220
Cooking gRPC
aleksi
1
930
Profiling and Optimizing Go Programs
aleksi
1
1.8k
Go: начало
aleksi
0
150
Other Decks in Programming
See All in Programming
AIエージェントで 変わるAndroid開発環境
takahirom
2
680
【やさしく解説 設計編 #0】DDDのコード、読めるのに分からない人へ
panda728
PRO
2
270
任せる範囲はこう広がった / How the Scope of AI Delegation Has Expanded
nrslib
1
260
エンジニアにデザインハーネスを 〜デザインプロセスを規定するためのハーネス〜 / Design harness from an engineer's perspective
rkaga
2
1.6k
Welcome to the "Parametricity" 🏙️ − Generic だけど Specific な世界 −
guvalif
PRO
1
170
鹿野さんに聞く!『TypeScriptコードレシピ集』で磨く実践力
tonkotsuboy_com
4
1.1k
Generative UI & AI-Assistants for Your Angular Solutions
manfredsteyer
PRO
0
120
はてなアカウント基盤 State of the Union
cockscomb
1
1.3k
技術記事、 専門家としてのプログラマ、 言語化
mizchi
14
7.5k
Hatena Engineer Seminar #37「言語モデルの活用に関する研究」
slashnephy
0
530
Embedded SREと共に達成した会員管理システムのAWS移行 - SRE NEXT 2026 ランチスポンサーセッション
niftycorp
PRO
1
2.7k
吝嗇家のためのAI活用 / AI development for miser - ChatGPT + Issue Driven Development
tooppoo
0
190
Featured
See All Featured
Statistics for Hackers
jakevdp
799
230k
Code Reviewing Like a Champion
maltzj
528
40k
SEO in 2025: How to Prepare for the Future of Search
ipullrank
3
3.6k
The Illustrated Guide to Node.js - THAT Conference 2024
reverentgeek
1
410
Docker and Python
trallard
47
4k
Learning to Love Humans: Emotional Interface Design
aarron
275
41k
Measuring & Analyzing Core Web Vitals
bluesmoon
9
890
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
64
56k
4 Signs Your Business is Dying
shpigford
187
22k
Highjacked: Video Game Concept Design
rkendrick25
PRO
1
410
Unsuck your backbone
ammeep
672
58k
Conquering PDFs: document understanding beyond plain text
inesmontani
PRO
4
2.9k
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