Can you pass 8th Grade Math?
You Passed 8th Grade Math |
Congratulations, you got 10/10 correct! |
You Passed 8th Grade Math |
Congratulations, you got 10/10 correct! |
So the beer has been brewed, and, as of this morning is bubbling away happily in the primary fermenter. It's not as heavy as I had planned, coming out at 1.042 Original Gravity, partly due to brewing 5 1/2 gallons, rather than 5, and also to poor mash efficiency. I think I let the mash cool off too much during sparging, and didn't rinse the sugars out as effectively as possible.
I pitched a 1 liter starter of the White Labs Duseldorf Alt yeast, and fermentation was active several hours later, and well going by the morning. I'll move it to the basement tonight, to keep it a bit cool.
Here's the plan for today's brew. An Alt, brewed with an Maerzen grain bill and hopping, so it should be similar in style to a O'fest. I'm planning a single decoction mash, so I'll be pretty busy.
Oktober Ale
Recipe oktober ale Style Oktoberfest/Marzen
Brewer Steve Downey Batch 5.00 gal
Recipe Characteristics
Recipe Gravity 1.054 OG Estimated FG 1.013 FG
Recipe Bitterness 24 IBU Alcohol by Volume 5.4%
Recipe Color 13° SRM Alcohol by Weight 4.2%
Ingredients
Quantity Grain Use
7.00 lb Vienna Malt mashed
1.00 lb German Munich mashed
1.00 lb White Wheat mashed
1.00 lb CaraVienne mashed
0.25 lb Belgian Special "B" mashed
Quantity Hop Form Time
1.00 oz Hallertauer pellet 45 minutes
0.75 oz Hallertauer pellet 30 minutes
1.00 oz Liberty pellet 15 minutes
Yippe! I'm brewing this weekend (weather, wife, and kids permitting)
GR410 | Malt - | 7.00 | 1.30 | 9.10 |
GR405 | Malt - German | 1.00 | 1.45 | 1.45 |
GR390 | Malt - White Wheat | 1.00 | 1.35 | 1.35 |
GR590 | Malt - Caravienne | 1.00 | 1.55 | 1.55 |
GR593 | Malt - Special B | 1.00 | 1.55 | 1.55 |
Hhal2 | Hop (Pellets) - Hallertauer (2 oz) | 1.00 | 3.00 | 3.00 |
Hlib2 | Hop (Pellets) - | 1.00 | 2.25 | 2.25 |
WLP036 | White Labs Yeast ( | 1.00 | 5.50 | 5.50 |
FIN20 | Clarifiers - Irish Moss (1oz) | 1.00 | 1.35 | 1.35 |
Before you begin, you will need to read the Release Notes. Really. The whole thing.
Thanks to David Abrahams, we have a framework to discuss the relative exception safety of C++ components. Quick reiteration:
# The basic guarantee: that the invariants of the component are preserved, and no resources are leaked.
# The strong guarantee: that the operation has either completed successfully or thrown an exception, leaving the program state exactly as it was before the operation started.
# The no-throw guarantee: that the operation will not throw an exception.
A corner case, that came up recently in discussion about shared_ptr, is how to describe the situation where the invariants of the component are preserved, the state of the component is what it was before, but the state of the program is not exactly as it was before the operation started.
shared_ptr potentially can throw an exception during construction. If it does, the pointer that it is constructed on is deleted (or the deleter called). This is important, as it prevents any resource leak. But it does mean that there is a change in the state of the program. Whatever the pointer is pointing to is gone. Does this mean that shared_ptr only provides the basic guarantee?
That would be unsatsifying.
The only way out of it that I see is that any attempt to observe the changed state would involve undefined behavior. And it would be the same undefined behavior, at that point in the code, if the operation did succeed.
Concrete, simple, case:
Widget * w = new Widget; // 1
// ... some more code
shared_ptr sp_w = shared_ptr
// ... yet more code.
w->widgetOp(); // 3
How could we arrive at 3 if an exception was thrown at 2? Only if 2 was inside a try block of some kind, which implies at least one block scope level difference between //1 and //2.
Which means that when that scope was exited, sp_w would have gone out of scope and been deleted, so that any reference to w at //3 would be invalid.
It seems to me that the program state in the strong guarantee must be one that is marked as being the beginning of a transaction by opening a try block. That this is necessary, although not sufficient for transactional behavior. Of course to accomplish this, each component must revert its state to the initial conditions, no component can know enough to revert the state of the entire program.
This the outside, now
This is our new walk-in closet and bathroom
This is a panoramic picture of the bedroom