HackerTube 中文?
Software boundaries and change →

What does a module promise its callers?

Try replacing a module whose callers rely on its incidental return order. Start with what the interface says, then trace the decisions it hides and the behaviors people have learned to expect.

Questions in this reading · 35
  1. Which choices should an API leave out?
  2. How much can a small interface hide?
  3. Small objects or small interfaces?
  4. When does a module boundary freeze a decision?
  5. When does an implementation detail become a promise?
  6. When does an implementation detail become a promise?
  7. Can two versions coexist under the same name?
  8. Which operations is the caller buying?
  9. Does a valid signature settle which history to keep?
  10. Where did the hidden cost go?
  11. Is starting the old program enough for compatibility?
  12. Who migrates when a field becomes mandatory?
  13. How long must “it heats” hold to count as delivery?
  14. Does perception hand over pixels or an interpreted scene?
  15. How many execution orders can one serial program allow?
  16. What obligation can one old web page create?
  17. How much handwork does a wider alley invalidate?
  18. How does an unauthorized read become visible?
  19. Running code is only the first part of the handoff
  20. Was waste heat part of the traffic light’s job?
  21. Following a promise through a handover
  22. Which server actually receives the request?
  23. Hold one wheel still to test what the axle promises
  24. Who adapts to whom at a shared interface?
  25. What crosses the room boundary?
  26. What does delivering one sensor reading promise?
  27. Who pays for the next update to custom software?
  28. Why can a matching outline still fail as a replacement?
  29. Can two functioning turbines start together?
  30. Who must keep up after a compatibility decision?
  31. Does putting the lid back restore the seal?
  32. What test could a promise of “the cloud” actually fail?
  33. Which part actually charges the battery?
  34. Compatible with the socket—and with the surroundings?
  35. Should a menu describe its role or command all input?

Which choices should an API leave out?

Removing an uncertain feature reduces what clients must learn. Separating tangled concerns reduces how many choices they must consider together.

Compare original passages and timestamps · 2
When it doubt, leave it out.
How To Design A Good API and Why it Matters · ▶ 24:42–24:45
start seeing interconnections between things that could be independent
"Simple Made Easy" - Rich Hickey (2011) · ▶ 59:28–59:32

How much can a small interface hide?

A small API reduces the concepts callers must learn. A deep module makes that small surface useful by hiding substantial implementation behind it.

Compare original passages and timestamps · 2
When it doubt, leave it out.
How To Design A Good API and Why it Matters · ▶ 24:42–24:45
very simple interface with a very large amount of functionality underneath it
A Philosophy of Software Design | John Ousterhout | Talks at Google · ▶ 14:24–14:29

Small objects or small interfaces?

One talk breaks code into smaller responsibilities. The other limits what callers must learn. Count the decisions exposed to callers as well as the objects inside the implementation.

Compare original passages and timestamps · 2
make smaller things
RailsConf 2014 - All the Little Things by Sandi Metz · ▶ 0:54–0:58
When it doubt, leave it out.
How To Design A Good API and Why it Matters · ▶ 24:42–24:45

When does a module boundary freeze a decision?

An interface can shelter callers from a changing implementation. Once clients depend on its behavior, changing the interface itself becomes more expensive.

Compare original passages and timestamps · 2
the higher the cost of communication the less iteration will happen there
The Only Unbreakable Law · ▶ 27:06–27:16
not be able to take it out once you put it into an API.
How To Design A Good API and Why it Matters · ▶ 24:57–25:03

When does an implementation detail become a promise?

Callers can depend on observable behavior that was never documented. Changing an interpreter or a library then becomes a compatibility decision.

Compare original passages and timestamps · 2
people actually depend in very bizarre ways on some of the internals
How Python was Shaped by leaky Internals, Armin Ronacher, Flask framework · ▶ 4:31–4:38
anything a user can observe about the implementation of your API
CppCon 2017: Matt Kulukundis “Designing a Fast, Efficient, Cache-friendly Hash Table, Step by Step” · ▶ 5:19–5:27

When does an implementation detail become a promise?

Interpreter behavior, hash tables and public APIs illustrate how callers come to rely on what they can observe. Observable behavior need not have been formally guaranteed.

Compare original passages and timestamps · 3
people actually depend in very bizarre ways on some of the internals
How Python was Shaped by leaky Internals, Armin Ronacher, Flask framework · ▶ 4:31–4:38
they will rely upon it, given enough users.
CppCon 2017: Matt Kulukundis “Designing a Fast, Efficient, Cache-friendly Hash Table, Step by Step” · ▶ 5:27–5:32
not be able to take it out once you put it into an API.
How To Design A Good API and Why it Matters · ▶ 24:57–25:03

Can two versions coexist under the same name?

A module name can force a choice between versions. Identifying content by its hash gives each version a separate address.

Compare original passages and timestamps · 2
we would have to make S modules also have a version identifier
How Python was Shaped by leaky Internals, Armin Ronacher, Flask framework · ▶ 39:11–39:16
then it would be perfectly fine to allow as many different versions of the same library in our code base
"Unison: a new distributed programming language" by Paul Chiusano · ▶ 26:04–26:16

Which operations is the caller buying?

A caller using a square root can leave the improvement of successive guesses inside the procedure. A tree interface promising constant-time parent lookup makes a second commitment. The succinct-structures lecture encodes the tree as bits and relies on rank and select for navigation. Write down separately what the operation returns, how much time it may take, and how much extra index space that time requires. Replacing the representation can preserve one promise while breaking another.

Passages and timestamps · 3
using black-box abstraction to suppress detail.
Lecture 1A: Overview and Introduction to Lisp · ▶ 13:03–13:07
If I have rank and select in constant time, now I can do left child, right child, parent in constant time.
17. Succinct Structures I · ▶ 32:35–32:41
all I'm allowed for rank and select is little o of n space.
17. Succinct Structures I · ▶ 33:34–33:39

Does a valid signature settle which history to keep?

Send one payment to two nodes. Each can check the signature, but if two individually valid histories conflict, the signature does not choose between them. Gensler asks who appends the next block; the Bitcoin walkthrough introduces cumulative work as part of the rule for choosing a valid history. The 256-bit calculation instead estimates generic trials to hit a particular hash target. That measures one computational task. It cannot certify the separate rules for authorizing messages, validating ledger entries and selecting a history.

Passages and timestamps · 3
how do you decide who appends that next block?
1. Introduction for 15.S12 Blockchain and Money, Fall 2018 · ▶ 18:33–18:39
the one with the most work put into it
But how does bitcoin actually work? · ▶ 19:10–19:22
on average, 2 to the 256 guesses
How secure is 256 bit security? · ▶ 0:33–0:37

Where did the hidden cost go?

One hash lookup may probe a dense run of entries; another may chase pointers to distant addresses. Carruth’s data-structures talk follows the actual accesses. Carry that question into his talk on abstractions: tidy instructions at one call site can coexist with compilation costs or a calling-convention penalty at another boundary. A performance promise needs a workload, a boundary and an account of who pays.

Passages and timestamps · 2
maximize the cache locality of of handling a collision
CppCon 2014: Chandler Carruth "Efficiency with Algorithms, Performance with Data Structures" · ▶ 49:33–49:43
it just means the cost is paid somewhere else
CppCon 2019: Chandler Carruth “There Are No Zero-cost Abstractions” · ▶ 16:44–16:51

Is starting the old program enough for compatibility?

Rename a field in a message and the producing service may still compile. Hickey points out that names crossing a process boundary have other readers. Goetz distinguishes linking an old binary, recompiling old source and preserving behavior at runtime. Keep an old artifact, old source and an old message, then exercise them separately. Each tests a different promise.

Passages and timestamps · 2
as your names start escaping out of your processes, that they are global names
The Language of the System - Rich Hickey · ▶ 21:29–24:03 · passage interval
existing class files will continue to link
Brian Goetz - Stewardship: the Sobering Parts · ▶ 20:53–20:59

Who migrates when a field becomes mandatory?

In Hickey’s terms, a mandatory field raises the caller’s obligations. Winters’s diamond dependencies explain why two teams may not move together: each reaches a shared component through a different intermediary. Wright supplies a migration order: offer the replacement while retaining the old default, move callers in batches, then end the transition. A version number can identify the two interfaces but cannot supply the missing data for an unmigrated caller.

Passages and timestamps · 3
if you require more than somebody who's giving less now is not going to get what they want
Spec-ulation Keynote - Rich Hickey · ▶ 24:55–25:05
If everyone in your infrastructure doesn't upgrade at the same time, then we have version skew.
CppCon 2017: Titus Winters “C++ as a "Live at Head" Language” · ▶ 15:30–15:36
Usually you add the new thing without making it the default.
CppCon 2018:H. Wright “Large-Scale Changes at Google: Lessons Learned From 5 Yrs of Mass Migrations” · ▶ 13:15–13:19

How long must “it heats” hold to count as delivery?

Thwaites counts hundreds of pieces in a cheap toaster. His own device heats briefly before its element melts. As interface promises, “produces heat when switched on” and “continues heating for a useful interval” give different verdicts on the same device. To test the latter, include the duration and the state after failure in the acceptance example.

Passages and timestamps · 2
that, inside this object, which I'd bought for just 3.49 pounds, there were 400 different bits made out of a hundred-plus different materials.
Thomas Thwaites: How I built a toaster -- from scratch · ▶ 1:39–1:51
And for about five seconds, the toaster toasted, but then, unfortunately, the element kind of melted itself.
Thomas Thwaites: How I built a toaster -- from scratch · ▶ 10:31–10:40

Does perception hand over pixels or an interpreted scene?

In Musk's description the controller receives vectors for lanes, vehicles and pedestrians. Compare two failures: perception omitted a car, or the controller received the car and chose a bad path. Their final trajectories may look alike. To diagnose the former you need the perception input and output; testing the controller on the supplied vectors will not make the missing car reappear.

Passages and timestamps · 2
you've got cars and humans and lane lines and curves and traffic lights
Elon Musk: SpaceX, Mars, Tesla Autopilot, Self-Driving, Robotics, and AI | Lex Fridman Podcast #252 · ▶ 69:49–70:02
It's outputting proper vectors to the C++ control code
Elon Musk: SpaceX, Mars, Tesla Autopilot, Self-Driving, Robotics, and AI | Lex Fridman Podcast #252 · ▶ 92:29–92:34

How many execution orders can one serial program allow?

Expand a product from the left or the right and the scratch work differs while the answer agrees. Wolfram uses this to illustrate a property one must check for a system of rewrite rules. Keller faces a physical instruction stream: find dependencies, start independent operations and track which results may finish in which order. First specify what an observer gets to see. For the algebra example the final expression suffices. A processor must also respect observable effects such as memory ordering, so checking only the final number can miss a broken promise.

Passages and timestamps · 4
you'll get different orders
Stephen Wolfram: Fundamental Theory of Physics, Life, and the Universe | Lex Fridman Podcast #124 · ▶ 95:37–95:40
you'll always get the same answer
Stephen Wolfram: Fundamental Theory of Physics, Life, and the Universe | Lex Fridman Podcast #124 · ▶ 95:29–95:31
go figure out the dependency graph
Jim Keller: Moore's Law, Microprocessors, and First Principles | Lex Fridman Podcast #70 · ▶ 8:24–8:29
what order should these operations finish in
Jim Keller: Moore's Law, Microprocessors, and First Principles | Lex Fridman Podcast #70 · ▶ 8:01–8:05

What obligation can one old web page create?

Eich explains why early JavaScript choices survived: other people had shipped pages that used them. Van Rossum recalls a different route, fitting information for an external checker into existing Python syntax. Lattner presents gradual type adoption as a Mojo design goal. Take an old unannotated function and ask three questions. Must its result stay the same? Which tool reads the new information? Can an unmigrated caller still use it? The compatibility obligations differ across the three projects.

Passages and timestamps · 4
the force of web compatibility meant early mistakes couldn't be fixed
Brendan Eich: JavaScript, Firefox, Mozilla, and Brave | Lex Fridman Podcast #160 · ▶ 18:48–18:55
a compromise syntax
Guido van Rossum: Python and the Future of Programming | Lex Fridman Podcast #341 · ▶ 84:58–85:04
use that existing dummy syntax
Guido van Rossum: Python and the Future of Programming | Lex Fridman Podcast #341 · ▶ 85:50–85:54
progressively adopt types into your program
Chris Lattner: Future of Programming and AI | Lex Fridman Podcast #381 · ▶ 32:43–32:46

How much handwork does a wider alley invalidate?

Each Another World level carried its own copy of the hero’s behavior. Changing the hero meant editing every copy. Spider-Man exposes a second route for a change to spread. Widen an alley and several generated tiles may change under an artist’s finished work. Before adding a regenerate button, list what the generator owns and which human edits have to survive. Build time alone misses much of the cost.

Passages and timestamps · 2
for every change I was making on generic things, I had to do it on all files
Classic Game Postmortem - Another World · ▶ 17:26–17:34
just adjusting the alley width in one region could affect many surrounding tiles
Procedurally Crafting Manhattan for Marvel's Spider-Man · ▶ 36:36–36:43

How does an unauthorized read become visible?

Two workers can finish in a fortunate order and draw a perfectly good frame. Destiny adds a second observation during development. The engine checks the dependency graph and validates access permissions when code touches resources. Alongside “Was the final frame right?” ask “Did any job read something it had no permission to read?” That question can expose a violation even on the lucky schedule.

Passages and timestamps · 2
identifying unsafe patterns, but it's going to be doing it during development
Multithreading the Entire Destiny Engine · ▶ 21:47–21:52
every time that you access the data, it's checking dynamically right there and then for whether or not you have permission
Multithreading the Entire Destiny Engine · ▶ 52:31–52:37

Running code is only the first part of the handoff

Suppose you can execute a jump on a game console. Does jumping to the Linux entry address make it a PC? The PS4 team lists the preconditions for the handoff, including placing the kernel in memory, preparing page tables and stopping other CPUs. Connecting the southbridge to another motherboard also gave them a device they could observe and test separately. Write this interface in two columns: what the caller must prepare before the jump and what peripheral state the incoming system can assume.

Passages and timestamps · 2
Now the southbridge is a PCIe card for us.
Console Hacking 2016 (33c3) · ▶ 7:30–7:34
shut down FreeBSD cleanly, halt secondary CPUs, make new pagetables
Console Hacking 2016 (33c3) · ▶ 11:13–11:16

Was waste heat part of the traffic light’s job?

A bench can verify the new LED’s brightness. A snowstorm reveals a second service the incandescent light provided: heating its face. Sealed-beam headlights illustrate the reverse problem. Replacing the light also renewed its optical surfaces. Would separating source and housing preserve that maintenance benefit? Ask a technician what a single replacement used to fix before specifying a substitute.

Passages and timestamps · 4
keeping snow and ice from building up
The LED Traffic Light and the Danger of "But Sometimes!" · ▶ 5:49–5:54
sensors onboard measuring temperature and humidity
The LED Traffic Light and the Danger of "But Sometimes!" · ▶ 10:24–10:28
a standard performance benchmark was established
Old car headlights were all the same — which was a fairly bright idea · ▶ 4:08–4:15
you’re getting an entirely new headlight every time it goes out
Old car headlights were all the same — which was a fairly bright idea · ▶ 18:21–18:25

Following a promise through a handover

In the filmed request for kernel source, the person who replied to earlier emails has left. The practical question becomes who can locate the matching version and who can deliver it. Apply that to a module: when a caller requests documented behavior after its author leaves, which project record still makes the promise actionable?

Passages and timestamps · 2
He has left the company.
Getting GPLv2 Compliance From A Chinese Company- In Person! · ▶ 4:46–4:47
I am here for the kernel source code.
Getting GPLv2 Compliance From A Chinese Company- In Person! · ▶ 4:37–4:43

Which server actually receives the request?

Apple’s WWDC presentation describes limits on the data sent for a task and the software state a server must report before a device will talk to it. Inspect a request for the former and the remote software record for the latter. An encryption indicator alone cannot do either job. The passage records what Apple promised at the presentation.

Passages and timestamps · 2
send only the data that's relevant to your task
WWDC 2024 — June 10 | Apple · ▶ 74:51–74:58
unless its software has been publicly logged for inspection
WWDC 2024 — June 10 | Apple · ▶ 75:23–75:27

Hold one wheel still to test what the axle promises

The tabletop demonstration puts two requirements in view. The engine must drive both rear wheels, yet the outer wheel must turn faster in a corner. Splitting the axle allows the speed difference. After adding a pivoting crossbar, the demonstrator holds one wheel still while the other continues to receive drive. That input distinguishes the designs. For a software interface, which call would exercise both halves of its promise at once?

Passages and timestamps · 2
a greater distance to travel in the same length of time.
Around The Corner - How Differential Steering Works (1937) · ▶ 2:18–2:22
When we stop one wheel, the crossbars will continue to push the spokes
Around The Corner - How Differential Steering Works (1937) · ▶ 5:32–5:38

Who adapts to whom at a shared interface?

Battery swapping moves charging until after the driver leaves by requiring the car to fit the station. Wired highways place the compatibility requirement on a lane and a pantograph, with onboard power taking over beyond the wire. Marlinspike discusses a similar coordination cost across deployed messaging clients. Alongside the current interface, write one more line: who must adapt when either side upgrades or leaves?

Passages and timestamps · 6
we can charge the batteries at their low speed.
A robot just swapped my electric car's battery · ▶ 2:33–2:36
only works for cars that are built for it.
A robot just swapped my electric car's battery · ▶ 3:46–3:48
the pantograph will automatically drop down immediately
The highway where trucks work like electric trains · ▶ 1:16–1:19
with batteries taking a couple of miles at each end.
The highway where trucks work like electric trains · ▶ 2:06–2:09
different implementations, different deployments and so making any changes becomes extremely difficult.
36C3 - The ecosystem is moving · ▶ 5:39–5:48
you lose your entire social graph at that moment
36C3 - The ecosystem is moving · ▶ 41:01–41:05

What crosses the room boundary?

At the outlet a single-hose AC delivers cool air. Draw a box around the room and the air expelled through its condenser has to be replaced. Describing an ultrasonic humidifier only by its humidity output likewise misses the minerals in the droplets. Label the arrows at the boundary with air, water, heat and dissolved material, then check which flows the specification left implicit.

Passages and timestamps · 4
air that they just cooled, mind you
Portable Air Conditioners - Why you shouldn't like them · ▶ 6:28–6:31
You can’t just expel air from a room without it getting replaced somehow
Portable Air Conditioners - Why you shouldn't like them · ▶ 7:22–7:26
you can experience a white dust forming on objects
Humidifiers: Simpler is better? · ▶ 10:01–10:04
Evaporative humidifiers simply help water evaporate
Humidifiers: Simpler is better? · ▶ 10:50–10:53

What does delivering one sensor reading promise?

In the LoRa tutorial, range, rate and power constrain the message. One received sample establishes delivery at that load. Faster sampling or many simultaneous devices introduces throughput and latency requirements. Specify number of devices, message size, deadline and tolerable loss before treating reach as an application guarantee.

Passages and timestamps · 2
increase transmission power or decrease the bandwidth
#112 LoRa / LoRaWAN De-Mystified / Tutorial · ▶ 2:53–3:01
The smaller the bandwidth, the lower the capacity of our channel.
#112 LoRa / LoRaWAN De-Mystified / Tutorial · ▶ 3:09–3:14

Who pays for the next update to custom software?

Customizing a package for one Japanese customer's workflow could win a contract without producing something another customer could immediately adopt. Fragmented platforms also spread update work across implementations. Alongside the initial contract, track who maintains the differences and which tested behavior a second customer can inherit.

Passages and timestamps · 2
modified for customers' existing business practices
Why is Japan So Weak in Software? · ▶ 5:48–5:53
there was no widely accepted platform or operating system
Why is Japan So Weak in Software? · ▶ 11:59–12:08

Why can a matching outline still fail as a replacement?

The iron lung collar must keep a seal while it moves. Its replacement needs appropriate dimensions, material and elasticity. Alongside a photograph of the sample, give a new supplier the acceptance conditions under operating load. Matching a static outline and maintaining a working seal are separate checks.

Passages and timestamps · 2
that collar was very tricky.
Project "Iron Auntie" Success! Helping one of the last polio survivors in an iron lung. · ▶ 2:37–2:41
the right material, with just the right amount of elasticity.
Project "Iron Auntie" Success! Helping one of the last polio survivors in an iron lung. · ▶ 2:41–2:51

Can two functioning turbines start together?

Cross-fed preburners and turbines can be drawn in their steady operating state without explaining how that state is reached. For each flow, list the required upstream pressure, mass flow or ignition condition. Then find the condition that depends on the other side. A steady-state diagram and a feasible startup sequence establish different properties.

Passages and timestamps · 2
you've got two turbines and two preburners.
Elon Musk Explains SpaceX's Raptor Engine! · ▶ 12:05–12:09
they're cross feeding one another.
Elon Musk Explains SpaceX's Raptor Engine! · ▶ 12:10–12:12

Who must keep up after a compatibility decision?

In the Soviet planning history, compatibility with existing software, access to programming methods and time to delivery could favor different options. Follow compatibility over one update: can a current program run, which documentation and skills are needed for the next release, and which supplier must act? That turns a checkbox into a maintenance obligation.

Passages and timestamps · 2
compatibility, learn British programming methods
Why the Soviet Computer Failed · ▶ 15:17–15:22
push back the project's delivery date
Why the Soviet Computer Failed · ▶ 15:23–15:28

Does putting the lid back restore the seal?

Both openers deliver an open can, one through the lid and another through its seam. The latter lid can look reversible when placed back, but placing it does not recreate the original joint. Test “covers the opening” separately from “restores the manufactured seal” before relying on the apparent reversibility.

Passages and timestamps · 2
cuts not through the lid’s top but through the can’s double seam.
Lessons from a Can Opener · ▶ 6:23–6:29
not with any sort of positive seal
Lessons from a Can Opener · ▶ 8:43–8:48

What test could a promise of “the cloud” actually fail?

The fictional spokesman in The Onion’s sketch lists applications and buzzwords without specifying an observable behavior. Replace the product noun with an operation: after a phone saves a file, under what conditions can a second device read which version? Add a failure during upload. Whether readers retain the old version, see a partial one or get a retry signal supplies a boundary the slogan lacks.

Passages and timestamps · 2
How does the cloud work?
HP Offers 'That Cloud Thing Everyone Is Talking About' · ▶ 1:00–1:05
It's so simple and intuitive I don't need to waste your time explaining it.
HP Offers 'That Cloud Thing Everyone Is Talking About' · ▶ 1:05–1:09

Which part actually charges the battery?

The conspicuous wall box and plug obscure a charger carried inside the car. Watson opens the AC supply equipment and traces how it signals connection. In another demonstration, an EV supply and a dryer have different neutral requirements despite using the same residential service. Write the two interface promises separately: which connection state and AC supply can the car rely on, and across which two points does the quoted voltage apply?

Passages and timestamps · 4
The car itself contains the battery charger.
Electric car chargers aren't chargers at all – EVSE Explained · ▶ 3:25–3:27
the proximity pilot and ground pin are connected via a resistor
Electric car chargers aren't chargers at all – EVSE Explained · ▶ 10:52–10:57
Across either of those and neutral you get 120V
The US electrical system is not 120V · ▶ 5:51–5:55
the charging station just has two hots and a ground.
The US electrical system is not 120V · ▶ 12:41–12:46

Compatible with the socket—and with the surroundings?

Valve’s teardown exposes two kinds of fit in the Steam Deck. Screws engage plastic bosses, so repeated assembly can affect that joint. Elsewhere, the chosen SSD was tested for radio interference. A drive that enters the slot has passed a shape check; what happens to the neighboring wireless link remains a separate question. Before calling a replacement compatible, name two adjacent components and look for specifications covering their interaction.

Passages and timestamps · 2
self-tapping screws
Take a look inside Steam Deck™! · ▶ 1:18–1:20
not interfere with WiFi and Bluetooth.
Take a look inside Steam Deck™! · ▶ 3:52–3:54

Should a menu describe its role or command all input?

Stone adds a concrete test to an interface contract. When a menu opens, does the application say “this is a popup triggered by this click,” or demand all input and a fixed window position? In his 2013 account, conflicts involving volume keys and screensavers show how the latter agreement spreads a local need across the desktop. Device enumeration provides a second example of the boundary: using the same event format for current devices and later hotplug notifications lets callers use the same handling logic. For your own interface, list the intent the caller actually knows and the actions that belong with whoever coordinates global state. That reveals more about responsibility than counting parameters.

Passages and timestamps · 2
Wayland is also descriptive, not prescriptive.
The Real Story Behind Wayland and X - Daniel Stone (linux.conf.au 2013) · ▶ 31:35–31:39
these are all the current devices in the same format
The Real Story Behind Wayland and X - Daniel Stone (linux.conf.au 2013) · ▶ 34:38–34:42

Try it on your own example

For an interface you plan to change, which behaviors are guaranteed and which have merely stayed the same?