understanding

Similar documents
Go Cheat Sheet. Operators. Go in a Nutshell. Declarations. Basic Syntax. Hello World. Functions. Comparison. Arithmetic. Credits

GO IDIOMATIC CONVENTIONS EXPLAINED IN COLOR

Go Forth and Code. Jonathan Gertig. CSC 415: Programing Languages. Dr. Lyle

go get my/vulnerabilities Green threads are not eco friendly threads

Let s Go! Akim D le, Etienne Renault, Roland Levillain. June 8, TYLA Let s Go! June 8, / 58

COMP-520 GoLite Tutorial

Go for Java Developers


Introduction to the Go Programming Language

GO SHORT INTERVIEW QUESTIONS EXPLAINED IN COLOR

Pierce Ch. 3, 8, 11, 15. Type Systems

CS201- Introduction to Programming Current Quizzes

Go Tutorial. To do. A brief, gentle intro to Go. Next Networking. q Today

The Go Programming Language. Frank Roberts

CS31 Discussion 1E Spring 17 : week 08

C Review. MaxMSP Developers Workshop Summer 2009 CNMAT

Distributed Systems. 02r. Go Programming. Paul Krzyzanowski. TA: Yuanzhen Gu. Rutgers University. Fall 2015

developed ~2007 by Robert Griesemer, Rob Pike, Ken Thompson open source

Introduzione a Go e RPC in Go

Homework #3 CS2255 Fall 2012

CS 61C: Great Ideas in Computer Architecture. C Arrays, Strings, More Pointers

Flow Control: Branches and loops

Arrays Arrays and pointers Loops and performance Array comparison Strings. John Edgar 2

Summary of Go Syntax /

William Kennedy. Brian Ketelsen Erik St. Martin Steve Francia FOREWORD BY MANNING WITH

CS61C Machine Structures. Lecture 4 C Pointers and Arrays. 1/25/2006 John Wawrzynek. www-inst.eecs.berkeley.edu/~cs61c/

CprE 288 Introduction to Embedded Systems Exam 1 Review. 1

EMBEDDED SYSTEMS PROGRAMMING Language Basics

Lecture 14. No in-class files today. Homework 7 (due on Wednesday) and Project 3 (due in 10 days) posted. Questions?

Dynamic Allocation in C

C Pointers. 6th April 2017 Giulio Picierro

CS2255 HOMEWORK #1 Fall 2012

CS 61c: Great Ideas in Computer Architecture

QUIZ. What is wrong with this code that uses default arguments?

APS105. Malloc and 2D Arrays. Textbook Chapters 6.4, Datatype Size

Conditionals & Loops /

Pointers, Dynamic Data, and Reference Types

Tokens, Expressions and Control Structures

Issue with Implementing PrimeSieve() in Go

CS2351 Data Structures. Lecture 7: A Brief Review of Pointers in C

Introduce C# as Object Oriented programming language. Explain, tokens,

The Awesomeness of Go. Igor Lankin DevFest Karlsruhe, Nov 2016

P.G.TRB - COMPUTER SCIENCE. c) data processing language d) none of the above

Flow Control. CSC215 Lecture

Cut. it s not just for Google. Eleanor McHugh.

Don t Go Java! Edition 2019

COMP 202 Java in one week

EMBEDDED SYSTEMS PROGRAMMING Language Basics

Discussion 1E. Jie(Jay) Wang Week 10 Dec.2

Structure and Interpretation of Computer Programs

Intro. Scheme Basics. scm> 5 5. scm>

Reference slides! C Strings! A string in C is just an array of characters.!!!char string[] = "abc";! How do you tell how long a string is?!

Operating Systems CMPSCI 377, Lec 2 Intro to C/C++ Prashant Shenoy University of Massachusetts Amherst

C++ ARRAYS POINTERS POINTER ARITHMETIC. Problem Solving with Computers-I

Creating a C++ Program

Go Tutorial. Arjun Roy CSE 223B, Spring 2017

In this assignment, you will implement a basic CHORD distributed hash table (DHT) as described in this paper:

Go Concurrent Programming. QCon2018 Beijing

PHPoC vs PHP > Overview. Overview

FORM 1 (Please put your name and section number (001/10am or 002/2pm) on the scantron!!!!) CS 161 Exam II: True (A)/False(B) (2 pts each):

Jagannath Institute of Management Sciences Lajpat Nagar. BCA II Sem. C Programming

Control Structures. Important Semantic Difference

Dynamic Allocation in C

Reference slides! Garcia, Fall 2011 UCB! CS61C L04 Introduction to C (pt 2) (1)!

Lecture Notes on Queues

Basic Types, Variables, Literals, Constants

PHPoC. PHPoC vs PHP. Version 1.1. Sollae Systems Co., Ttd. PHPoC Forum: Homepage:

M1-R4: Programing and Problem Solving using C (JAN 2019)

Lecture 9: Lists. Lists store lists of variables. Declaring variables that hold lists. Carl Kingsford, , Fall 2015

Short Notes of CS201

Introduction to C Language (M3-R )

BBM 201 DATA STRUCTURES

GO - QUICK GUIDE GO - OVERVIEW

QUIZ. What are 3 differences between C and C++ const variables?

CS201 - Introduction to Programming Glossary By

Software Engineering using Formal Methods

FOR Loop. FOR Loop has three parts:initialization,condition,increment. Syntax. for(initialization;condition;increment){ body;

A Fast Review of C Essentials Part I

Lecture 2: C Programm

WHAT POINTERS REALLY ARE

FORM 2 (Please put your name and form # on the scantron!!!!)

Agenda. Peer Instruction Question 1. Peer Instruction Answer 1. Peer Instruction Question 2 6/22/2011

Pointers. A pointer is simply a reference to a variable/object. Compilers automatically generate code to store/retrieve variables from memory

CS61C : Machine Structures

Lecture 10 Notes Linked Lists

Vector and Free Store (Pointers and Memory Allocation)

Heap Arrays and Linked Lists. Steven R. Bagley

Introduction to C: Pointers

A brief introduction to C programming for Java programmers

Variables Data types Variable I/O. C introduction. Variables. Variables 1 / 14

Kurt Schmidt. October 30, 2018

520 Principles of Programming Languages. Arithmetic. Variable Declarations. 19: Pascal

Tranquility Publications. Web Edition MAC

Formal Specification and Verification

Spin: Overview of PROMELA

COMPUTER APPLICATION

COMP520 - GoLite Type Checking Specification

2.1. Chapter 2: Parts of a C++ Program. Parts of a C++ Program. Introduction to C++ Parts of a C++ Program

Principles of Programming Pointers, Dynamic Memory Allocation, Character Arrays, and Buffer Overruns

Please refer to the turn-in procedure document on the website for instructions on the turn-in procedure.

Transcription:

understanding nil @francesc

thanks

welcome every single one of you

agenda what is nil? what is nil in Go? what does nil mean? is nil useful?

nil? you misspelled null

how I learn words

how I learn words

etymology nil Latin nihil meaning nothing null Latin ne + ullus meaning not any none Old English ne + ān meaning not one

names for the number zero in English - zero null duck nada zip naught aught - cipher love nil zilch the letter o nought ought source: wikipedia

nil is (a) zero

interlude a bit of history

I call it my billion-dollar mistake. It was the invention of the null reference in 1965. At that time, I was designing the first comprehensive type system for references in an object oriented language. - Sir C.A.R. Hoare

panic: runtime error: invalid memory address or nil pointer dereference

Uncaught TypeError: undefined is not a function

nil leads to panic

panic leads to fear by danpawley on Flickr

fear leads to by korymatthew on Flickr

λ functional programming

Functional Go? Thanks, but no - francesc at dotgo.eu 2015

there are many ways, nil is the Go way

</interlude>

zero values what are they?

zero values bool false pointers nil numbers 0 slices nil string "" maps nil channels nil functions nil interfaces nil

zero values for struct types type Person struct { AgeYears int Name string Friend []Person } var p Person // Person{0, "", nil}

the type of nil

... unless the value is the predeclared identifier nil, which has no type - Go language specification

untyped zero a := false a := "" a := 0 // a := int(0) a := 0.0 // a := float64(0) a := nil // use of untyped nil

nil is a predeclared identifier representing the zero value for a pointer, channel, func, interface, map, or slice type. - Go documentation for builtin package

nil is a predeclared identifier representing the zero value for a pointer, channel, func, interface, map, or slice type. - Go documentation for builtin package

twenty-five* keywords break default func interface select case defer go map struct chan else goto package switch const fallthrough if range type continue for import return var * plus the five secret ones, obviously

predefined vs keyword // YOLO var nil = errors.new( \_(ツ)_/ ) * For extra evilness: place at the end of doc.go

zero values what do they mean?

kinds of nil pointers slices maps channels functions interfaces

kinds of nil pointers slices maps channels functions interfaces

pointers in Go - they point to a position in memory - similar to C or C++, but - no pointer arithmetic memory safety - garbage collection

nil pointer - points to nil a.k.a. nothing - zero value of pointers

kinds of nil pointers slices maps channels functions interfaces

slice internals []byte ptr *elem len int cap int

a slice with five elements []byte ptr len 5 cap 5 [5]byte 0 0 0 0 0 s := make([]byte, 5)

nil slice []byte ptr nil len 0 cap 0 var s []byte

kinds of nil pointers slices maps channels functions interfaces

channels, maps, and functions ptr *something

channels, maps, and functions ptr implementation * implementations might not be cloud shaped

channels, maps, and functions ptr nil

kinds of nil pointers slices maps channels functions interfaces

(type, value)

var s fmt.stringer // Stringer (nil, nil) fmt.println(s == nil) // true

(nil, nil) equals nil

var p *Person // nil of type *Person var s fmt.stringer = p // Stringer (*Person, nil) fmt.println(s == nil) // false

(*Person, nil) doesn t equal nil

when is nil not nil?

when is nil not nil? func do() error { var err *doerror return err } // error (*doerror, nil) // nil of type *doerror func main() { err := do() fmt.println(err == nil) } // error (*doerror, nil) // false

do not declare concrete error vars

nil is not nil func do() *doerror { // nil of type *doerror return nil } func main() { err := do() fmt.println(err == nil) } // nil of type *doerror // true

nil is not nil func do() *doerror { return nil } // nil of type *doerror func wrapdo() error { return do() } // error (*doerror, nil) // nil of type *doerror func main() { err := wrapdo() fmt.println(err == nil) } // error (*doerror, nil) // false

do not return concrete error types

nil is not nil * for some kinds of nil

kinds of nil pointers point to nothing slices have no backing array maps are not initialized channels are not initialized functions are not initialized interfaces have no value assigned, not even a nil pointer

Make the zero value useful - Rob Pike in his Go Proverbs

how are these useful? pointers slices maps channels functions interfaces

how are these useful? pointers slices maps channels functions interfaces

pointers var p *int p == nil // true *p // panic: invalid memory address or nil pointer dereference

coding time

implement Sum type tree struct { v int l *tree r *tree } 6 2 1 func (t *tree) Sum() int 7 4 3 9 5 8

a first solution func (t *tree) Sum() int { sum := t.v 6 if t.l!= nil { sum += t.l.sum() } if t.r!= nil { sum += t.r.sum() } return sum } 2 1 7 4 3 9 5 8

issues Code repetition: if v!= nil { v.m() } Panic when t is nil var t *tree sum := t.sum() // panic: invalid memory address or nil pointer dereference

pointer receivers type person struct {} func sayhi(p *person) { fmt.println( hi ) } func (p *person) sayhi() { fmt.println( hi ) } var p *person p.sayhi() // hi

nil receivers are useful 零

nil receivers are useful: Sum func (t *tree) Sum() int { if t == nil { return 0 } return t.v + t.l.sum() + t.r.sum() }

nil receivers are useful: String func (t *tree) String() string { if t == nil { return "" } return fmt.sprint(t.l, t.v, t.r) }

nil receivers are useful: Find func (t *tree) Find(v int) bool { if t == nil { return false } return t.v == v t.l.find(v) t.r.find(v) }

keep nil useful if possible, if not NewX()

how are these useful? pointers slices maps channels functions interfaces

nil slices var s []slice len(s) // 0 cap(s) // 0 for range s // iterates zero times s[i] // panic: index out of range

append on nil slices var s []int for i := 0; i < 10; i++ { fmt.printf("len: %2d cap: %2d\n", len(s), cap(s)) s = append(s, i) }

$ go run slices.go len: len: len: len: len: len: len: len: len: len: 0 1 2 3 4 5 6 7 8 9 cap: 0 cap: 1 cap: 2 cap: 4 cap: 4 cap: 8 cap: 8 cap: 8 cap: 8 cap: 16 [] s is nil! [0] allocation [0 1] reallocation [0 1 2] reallocation [0 1 2 3] [0 1 2 3 4] reallocation [0 1 2 3 4 5] [0 1 2 3 4 5 6] [0 1 2 3 4 5 6 7] [0 1 2 3 4 5 6 7 8] reallocation

use nil slices they re often fast enough

how are these useful? pointers slices maps channels functions interfaces

nil maps var m map[t]u len(m) // 0 for range m // iterates zero times v, ok := m[i] // zero(u), false m[i] = x // panic: assignment to entry in nil map

using maps func NewGet(url string, headers map[string]string) (*http.request, error) { req, err := http.newrequest(http.methodget, url, nil) if err!= nil { return nil, err } for k, v := range headers { req.header.set(k, v) } return req, nil }

using maps NewGet( "http://google.com", map[string]string{ "USER_AGENT": "golang/gopher", }, )

$ go run request.go GET / HTTP/1.1 Host: google.com User_agent: golang/gopher

using empty maps NewGet("http://google.com", map[string]string{})

$ go run request.go GET / HTTP/1.1 Host: google.com

using empty maps NewGet("http://google.com", map[string]string{})

nil maps are valid empty maps NewGet("http://google.com", nil)

$ go run request.go GET / HTTP/1.1 Host: google.com

use nil maps as read-only empty maps

how are these useful? pointers slices maps channels functions interfaces

nil channels var c chan t <- c // blocks forever c <- x // blocks forever close(c) // panic: close of nil channel

coding time

b a func merge(out chan<- int, a, b <-chan int) out

a naive solution func merge(out chan<- int, a, b <-chan int) { for { select { case v := <-a: out <- v case v := <-b: out <- v } } }

$ go run naive.go 2 2 1 2 2 1 2 1 2 1 2 1 2 1 1 2 2 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

closed channels var c chan t v, ok <- c // zero(t), false c <- x // panic: send on closed channel close(c) // panic: close of nil channel

a naive solution func merge(out chan<- int, a, b <-chan int) { for { select { case v := <-a: out <- v case v := <-b: out <- v } } }

checking for closed chans case v, ok := <-a: if!ok { aclosed = true continue } out <- v // analogous code for case b

checking for closed chans func merge(out chan<- int, a, b <-chan int) { var aclosed, bclosed bool for!aclosed!bclosed { select { case v, ok := <-a: if!ok { aclosed = true; continue } out <- v case v, ok := <-b: if!ok { bclosed = true; continue } out <- v } } }

$ go run checkforclosed.go 1 1 2 1 1 2 2 1 1 2 1 2 2 1 2 1 2 1 2 2 fatal error: all goroutines are asleep - deadlock! goroutine 1 [chan receive]: main.main() /Users/campoy/src/github.com/campoy/talks/nil/talk/code/chans. go:97 +0x15a exit status 2

and closing channel out func merge(out chan<- int, a, b <-chan int) { var aclosed, bclosed bool for!aclosed!bclosed { select { case v, ok := <-a: if!ok { aclosed = true; continue } out <- v case v, ok := <-b: if!ok { bclosed = true; continue } out <- v } } close(out) }

and closing channel out func merge(out chan<- int, a, b <-chan int) { var aclosed, bclosed bool for!aclosed!bclosed { select { case v, ok := <-a: if!ok { aclosed = true; continue } out <- v case v, ok := <-b: if!ok { bclosed = true; continue } out <- v } } close(out) }

$ go run closingout.go 1 1 2 1 1 2 2 1 1 2 1 2 2 1 2 1 2 1 2 2

ship it! Fancy Gopher by Renee French

by hzeller on Flickr

let s log case v, ok := <-a: if!ok { aclosed = true fmt.println("a is now closed") continue } out <- v // analogous code for case b

$ go run withlogs.go 1 1 2 1 1 2 2 1 1 2 1 2 2 1 2 1 2 1 2 2 b is now closed b is now closed 1 b is now closed b is now closed 1 a is now closed

let s log var aclosed, bclosed bool for!aclosed!bclosed { select { case v, ok := <-a: if!ok { aclosed = true; continue } out <- v case v, ok := <-b: if!ok { bclosed = true; continue } out <- v } } close(out)

can we switch off a chan?

nil channels var c chan t <- c // blocks forever c <- x // blocks forever close(c) // panic: close of nil channel

switching off a channel case v, ok := <-a: if!ok { aclosed = true fmt.println("a is now closed") continue } out <- v // analogous code for case b

switching off a channel case v, ok := <-a: if!ok { a = nil fmt.println("a is now closed") continue } out <- v // analogous code for case b

switching off a channel; no logs func merge(out chan<- int, a, b <-chan int) { for a!= nil b!= nil { select { case v, ok := <-a: if!ok { a = nil; continue } out <- v case v, ok := <-b: if!ok { b = nil; continue } out <- v } } close(out) }

$ go run closingout.go 1 1 2 1 1 2 2 1 1 2 1 2 2 1 2 1 2 1 2 2

fancy party time! Fancy Gopher by Renee French

use nil chans to disable a select case

how are these useful? pointers slices maps channels functions interfaces

nil funcs Go has first-class functions functions can be used as struct fields they need a zero value; logically it is nil type Foo struct { f func() error }

nil funcs for default values lazy initialization of variables nil can also imply default behavior func NewServer(logger func(string, interface{})) { if logger == nil { logger = log.printf } logger("initializing %s", os.getenv("hostname")) }

how are these useful? pointers slices maps channels functions interfaces

interfaces The nil interface is used as a signal if err!= nil { }

why does nil *Person not equal nil interface? 零

summer type Summer interface { func Sum() int }

summer var t *tree var s Summer = t fmt.println(t == nil, s.sum()) // true 0

summer type ints []int func (i ints) Sum() int { s := 0 for _, v := range i { s += v } return s }

summer var i ints var s Summer = i fmt.println(i == nil, s.sum()) // true 0

nil values can satisfy interfaces 零

nil values and default values func dosum(s Summer) int { if s == nil { return 0 } return s.sum() }

nil values and default values var t *tree dosum(t) // (*tree, nil) var i ints dosum(i) // (ints, nil) dosum(nil) // (nil, nil)

nil values and default values http.listenandserve("localhost:8080", nil)

use nil interfaces to signal default 零

nil is useful

nil is useful pointers methods can be called on nil receivers slices perfectly valid zero values maps perfect as read-only values channels essential for some concurrency patterns functions needed for completeness interfaces the most used signal in Go (err!= nil)

nil is an important part Go 零

let s not avoid nil

let s embrace nil Thanks, @francesc golang.org/s/nil