0

I'm joining development on an existing SwiftUI / Combine iOS project, which is my first exposure to the technology.

The names of functions like assign(to:on:) are easy enough to grok, but I'm lost at sink.

This function is mentioned in some of the most basic Apple documentation, but seemingly never defined.

Combine provides two built-in subscribers, which automatically match the output and failure types of their attached publisher:

  • sink(receiveCompletion:receiveValue:) takes two closures. The first closure executes when it receives Subscribers.Completion, which is an enumeration that indicates whether the publisher finished normally or failed with an error. The second closure executes when it receives an element from the publisher.

https://developer.apple.com/documentation/combine/receiving-and-handling-events-with-combine

What is a "sink" function in the the world of SwiftUI, Combine, reactive programming?

Why is it called "sink"? What's the etymology? What's the meaning?

Is it intended to refer to "sync" as in syncing? Kitchen sink? Heat sink? Going below the surface? Why is the name "sink"?

pkamb
  • 33,281
  • 23
  • 160
  • 191
  • 1
    Considering concept of events pipelining, it is rather *kitchen sink*... but review WWDC sessions about Combine... probably WWDC2021, as I recall. – Asperi May 06 '22 at 18:36
  • 1
    https://forums.swift.org/t/a-brief-rant-on-naming-combines-sink-operator/50076 – rob mayoff May 07 '22 at 05:48

4 Answers4

1

let's start from the beginning.

What is Combine?

The Combine framework provides a declarative Swift API for processing values over time. These values can represent many kinds of asynchronous events. Combine declares publishers to expose values that can change over time, and subscribers to receive those values from the publishers.

in Reactive programming, the connection between a Publisher (Observable) and Subscriber (Observer) is called a Stream. The reason behind this naming is that this connection really looks like a stream that an Event Publisher uses to deliver things (Events) to the observers.

enter image description here

During this stream, just like a real stream we can create branches or transform it into a completely new stream using Operators like Map, ...

Why Sink?

the "Sink" function represents the end of the stream and it means that you do not access the stream anymore after you sink it. You can't have any operator after Sinking a stream.

We have upstream and downstream as well Which makes the naming more reasonable.

         upstream          downstream
source <--------- operator -----------> consumer/further operators 

I think it is worth mentioning that because of functional programming and function composing, we need an executor, I mean you can compose Operators together as much as you want on a stream, but they don't do anything if you don't run the composed function. Sink and Assign are considered as Executors (It's my personal naming) that execute the final composed function and handle the results.

0

Sink : (verb) intransitive verb

  1. to soak or become absorbed : PENETRATE

  2. to become impressively known or felt

    the lesson had sunk in

  3. to become deeply absorbed

    sank into reverie

The formal connection and point in time where data that is being sent from a publisher is sank/sunk/sinked in with your app's subscriber.

stromyc
  • 488
  • 6
  • 13
0

This same topic was discussed on the Swift forum:

A brief rant on naming: Combine’s “sink” operator

https://forums.swift.org/t/a-brief-rant-on-naming-combines-sink-operator/50076

The replies make it clear that "source" and "sink" are established terms from graphy theory / flow networks.

“Source” and “sink” are established names from graph theory. I agree that it’s not an everyday use of the word “sink”, though, or at least it’s a stretch.

and

In engineering generally, where there are flows (of anything: heat, data, water, etc.) the terms ‘source’ and ‘sink’ are commonly used to refer to locations where whatever is flowing (respectively) starts out / is produced and ends up / is consumed. So heat flows from its source toward a heat sink, water flows down a (kitchen?) sink, and Combine reactive streams flow toward a .sink(receiveValue:).

pkamb
  • 33,281
  • 23
  • 160
  • 191
-3

In SwiftUI we use a different assign: assign(to:) which "Republishes elements received from a publisher, by assigning them to a property marked as a publisher." I've always considered sink as meaning down the drain, i.e. something you would not want to use in SwiftUI.

malhal
  • 26,330
  • 7
  • 115
  • 133