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
110
Fuzzy generics
Alexey Palazhchenko
February 05, 2022
Tweet
Share
More Decks by Alexey Palazhchenko
See All by Alexey Palazhchenko
Песнь Хорьков и Гоферов
aleksi
0
310
On Ferrets and Gophers
aleksi
0
220
How to Go Wrong with Concurrency
aleksi
2
730
Adding context to existing code
aleksi
1
110
Зачем и как написать свой database/sql драйвер
aleksi
1
140
Cooking gRPC
aleksi
1
790
Profiling and Optimizing Go Programs
aleksi
1
1.7k
Go: начало
aleksi
0
92
What the fuzz?
aleksi
0
490
Other Decks in Programming
See All in Programming
創造的活動から切り拓く新たなキャリア 好きから始めてみる夜勤オペレーターからSREへの転身
yjszk
1
130
Amazon S3 NYJavaSIG 2024-12-12
sullis
0
100
見えないメモリを観測する: PHP 8.4 `pg_result_memory_size()` とSQL結果のメモリ管理
kentaroutakeda
0
450
採用事例の少ないSvelteを選んだ理由と それを正解にするためにやっていること
oekazuma
2
1k
暇に任せてProxmoxコンソール 作ってみました
karugamo
2
720
良いユニットテストを書こう
mototakatsu
8
3k
PHPとAPI Platformで作る本格的なWeb APIアプリケーション(入門編) / phpcon 2024 Intro to API Platform
ttskch
0
290
Fibonacci Function Gallery - Part 1
philipschwarz
PRO
0
220
Recoilを剥がしている話
kirik
5
6.9k
MCP with Cloudflare Workers
yusukebe
2
220
testcontainers のススメ
sgash708
1
120
KubeCon + CloudNativeCon NA 2024 Overviewat Kubernetes Meetup Tokyo #68 / amsy810_k8sjp68
masayaaoyama
0
260
Featured
See All Featured
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
17
2.3k
Rebuilding a faster, lazier Slack
samanthasiow
79
8.7k
Building Better People: How to give real-time feedback that sticks.
wjessup
366
19k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
45
2.2k
BBQ
matthewcrist
85
9.4k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
226
22k
Reflections from 52 weeks, 52 projects
jeffersonlam
347
20k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
656
59k
Building Your Own Lightsaber
phodgson
103
6.1k
Building Adaptive Systems
keathley
38
2.3k
Thoughts on Productivity
jonyablonski
68
4.4k
How GitHub (no longer) Works
holman
311
140k
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