liveBook · Manning

First-class object

As explained in Learn Concurrent Programming with Go

A first-class object is a value that a programming language allows to be stored, passed as an argument, returned from a function, or otherwise handled like other ordinary values.

A first-class object can be handled like an ordinary value: stored in a variable, passed to or returned from a function, and even sent on a channel. In Go, channels have this property. That makes a channel-producing function more than a one-off worker: its returned channel can become an input to later concurrent operations. section 8.1.1 section 9.0

This flexibility supports message-passing designs in which goroutines keep isolated state rather than sharing memory directly. Instead of fixing every connection in advance, a program can pass channels through functions and alter the structure of its communicating processes while it runs. section 9.1.2 section 9.4

First-class channels enable several practical design moves:

  • Return an output-only channel from a goroutine-creating function, so callers can reuse it as a building block. section 8.1.1
  • Accept channels as function parameters, allowing pipeline stages to be connected without sharing state. section 9.4
  • Pass a channel on another channel, enabling a pipeline to grow as new work requires new stages. section 9.2.7
  • Create or remove channels at runtime when program logic needs a different process topology. section 9.1.2

Returning channels for select

A writeEvery function creates a string channel, starts an anonymous goroutine, periodically sends a message, and returns that channel. Calling it twice produces independent Tick and Tock streams. A select then blocks until either returned channel has a message; if multiple cases are ready, the selected case is random, so code must not depend on case order. section 8.1.1

Listing 9.20 The primeMultipleFilter() goroutine
package main

import "fmt"

func primeMultipleFilter(numbers <-chan int, quit chan<- int) {
    var right chan int
    p := <-numbers                                     #1
    fmt.Println(p)                                     #1
    for n := range numbers {                           #2
        if n%p != 0 {                                  #3
            if right == nil {                          #4
                right = make(chan int)                 #4
                go primeMultipleFilter(right, quit)    #4
            }
            right <- n                                 #5
        }
    }
    if right == nil {
        close(quit)                                    #6
    } else {
        close(right)                                   #7
    }
}
#1 Receives the first message containing the prime number p on the input channel and prints it
#2 Reads the next number from the input channel
#3 Discards any received number that is a multiple of p
#4 If the current goroutine has no right, it starts a new goroutine and connects to it with a channel.
#5 Passes the filtered number to the right channel
#6 Closes the quit channel if there are no more numbers to filter and the goroutine has no right channel
#7 Otherwise, closes right channel

The prime filter keeps its downstream channel in a variable. On the first non-multiple, it creates that channel and passes it to a new filter goroutine, extending the pipeline only when needed. section 9.2.7

How Learn Concurrent Programming with Go covers it

How deep it goes
Defines first-class channels and works through returned streams and a dynamically growing prime-filter pipeline.
Examples
Demonstrates periodic Tick/Tock channels selected together and a prime-number sieve that adds filter goroutines.
What you can do after
Apply it via Go channels to compose reusable stages and change a concurrent program’s channel topology at runtime.
How it connects
Connects first-class channels with CSP, goroutines, message passing, select, pipelines, fan-in, fan-out, and broadcast.

Also explained in

Compare how 7 books explain first-class object →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Learn Concurrent Programming with Go. The section links point to the parts of the book it draws on.