What Can You Put in a Refrigerator?
prog21.dadgum.comThe more I have to deal with corporate project management patterns, the more I think the whole approach behind specifications is wrong. Trying to focus on what the "domain objects" are and what is their flow is pointless, especially if you're dealing with real-world objects (like the fridge from TFA). You can model something this way, but it will be usually the imaginary perfect path, a narrow vision of how things should be done, that will break on first contact with the real world - a world that is messy and requires humans to improvise on the spot.
I'm starting to believe that one should focus on the workflow instead. After all, the reason for writing software as a tool is to simplify or automate some existing process. So focus on what people are already doing and what they're trying to achieve and find a way to remove repetitions, unnecessary delays, etc. Just look on what people are doing and find a way to do some parts of the process faster and better.
That's where user stories can help:
"As a user, I want to store my food and drinks in the refrigerator so they don't spoil"
"As a user, I want to store drinks in the refrigerator so I can drink them cold"
"As a user, I want to store my medicine in the refrigerator so it can stay below 25 C"
> Just look on what people are doing and find a way to do some parts of the process faster and better.
This requires buy-in from different parts of the company that are going to have their own opinions about how to do things. They can be surprising resistant to change.
The original spec, "Anything that fits into a refrigerator," is a pretty darn good one. It conforms to Postel's law: "Be conservative in what you do, be liberal in what you accept from others".
We can develop a spec in a vacuum, but we can't be sure what users actually want from our refrigerator. Maybe a live penguin actually does belong in there, as in the famous children's novel.
> "Be conservative in what you do, be liberal in what you accept from others"
Wikipedia has an example of a tag soup https://en.wikipedia.org/wiki/Tag_soup which is probably poster child example of this law:
<p>This is a malformed fragment of <em>HTML.</p></em>
What do we do here? Do we do what browsers have historically done? Or do we throw our hands up in the air when we see malformed tags?
HTML5 includes a well-defined algorithm for parsing such constructs, so with the HTML5 doctype that fragment is actually well-formed and normalized to the tree you'd expect.
Wait, if HTML5 specifies how to handle it... doesn't that make it syntactically valid?
That's right as far as I can tell. For another example of markup that's entirely valid in HTML5 but still considered icky by some people, the spec section on tag omission has an example of how to write tables more easily by skipping all the end tags.
I disagree with Postel's law, as it results in broken standards in practice.
Only because people break the first part of the law. Postel's law is absolutely crucial for communication between independent systems.
Violations of the first part of the law are inevitable once the number of "implementors" of the standard is large, not least because that implies low average competence.
You can perhaps (but my confidence is low) avoid violating the first part of the law if you're a TCP stack implementor, say. There just aren't that many such implementations nowadays and they're generally done by people who know what they're doing. But applying Postel's law to something like programming language implementations, where the "implementors" who would need to obey the first part are all the people writing programs in the language, pretty much guarantees violations of that first part. For any given programming language anyone cares about in practice, the number of people who know the spec for it well enough to only write code that conforms to that spec, even on their first try, is _tiny_ compared to the number of people writing programs in the language.
At that point your only option is to accept that the first part is going to be violated, and badly. Only once you have internalized that understanding can you have a constructive conversation about whether you want to do the second part and to what extent. The answers here will vary, of course.
Ignoring the reality of what people chose to ignore will end up making you very unhappy.
The alternative is even more against reality of what people do -- e.g. the classic proposal for a web browsers which would only accept very strict HTML (and this would supposedly make people fix their websites). In practice it would only have hindered the adoption of the web.
Can you put a baby or pet into a refrigerator? What about a freezer?
You certainly CAN. Whether you SHOULD is a philosophical question which is outside the scope of this specification.
Well, it isn't the refrigerator that's going to stop you.
Yes! Things shouldn't prevent all the crazy that's out in the world... Users will try to find creative ways around requirements, being more graceful in handling the crazy is usually appreciated
On the other hand "Make doing the right things easy and the wrong things hard" are good design rules. Putting something alive into a refrigerator and leaving it there, will probably make it dead. It might be a serious mistake by the end user. The smart refrigerator of the future might want to double check; "Are you sure you want to put the milk in the crib and the baby in the refrigerator?"
"Any contained item that can fit inside a refrigerator, whose quality would degrade significantly more when kept at room temperature rather than at 1-4°C, by the estimated time of use/consumption."
The term "contained" above is restrictive, and probably needs further precision. Only things that thrive inside an opaque and sealed container would fit the definition above. Otherwise, things that can affect the quality of other items (i.e., gas emanation), things that need light, things that need oxygen, things that need a specific range of moisture, things that can grow and/or move, would all need their containers to provide these conditions and/or have a dedicated location inside the refrigerator.
* Puff pastry that needs to be chilled for five minutes so that the butter doesn't melt into the flour before you do the next roll.
* Jello that needs to be set
* Sprouted beans / seeds for which you want to restrict the rate of growth
"Any contained item that can fit inside a refrigerator, whose quality would be better if kept at 1-4°C rather than at room temperature by the time it's used/consume."
I've definitely just placed a stalk of broccoli on the bottom shelf of my fridge with no container.
I would argue that the broccoli contains itself, or perhaps that the skin/surface of the broccoli is the container. (Though some people would argue that all vegetables in the fridge should at least be bagged, to prevent transfer of germs/grime.)
Does a bowl of hard-boiled eggs count as "contained"? It's not sealed.
Are they shelled?
Is the shell part of the food, or not? =)
What about activated charcoal or baking soda being used as a deodorizer? Or chilling a bottle of white wine, or pitcher of water, before drinking?
I thought about "things that are better consumed cold" but I forgot to include it.
Baking soda and charcoal deodorizer have been omitted because of the assumption that containers were sealed.
What about things still hot from the fire? You don't want to put those in the fridge either.
Looks like you missed the point of the article. That spec is just as flawed as the other examples.
Technically, that's an answer to "what you should put in refrigerator."
Anything the user decides to put in the refrigerator, provided we put warnings in small text on the document that accompanies the refrigerator for catogories of items we know to be unfit for the refrigerator so as to cover our asses if the user does not heed our warnings.
In terms of software, trying to decide up front for the user what they can do is the wrong approach. Even constraining them is flawed, with the exception of constraints for liability issues. What the user needs is the meas to express their decision making as to whether something should go into the fridge, so they need an input mechanism capable of doing selection, which has access to the context in which the item might be being placed into the fridge.
Does this sound like any configuration format you've ever used? The typical key-value stores which attempt to give you a declarative list of what you can put where, without the means to compute whether or not it might be a good idea first are almost ubiquitous, and the number of programs which take the right approach: give the user a proper, expressive programming language to configure the software, are few.
Just as it happens, we've developed ACME Refrigerator v2.0, which now allows you to store chocolate bars in it; a feature we missed in v1.0. Upgrade now for just $400.
The absurity of this idea with a fridge seems lost in software because we can upgrade at almost zero cost in just a few minutes, but that's only masking what is an obvious design flaw.
Which raises the question: What can you put in a software package definition?
Fun read. This reminds me of how "object-oriented" programming goes wrong for beginners. ...Not helped, alas, by all of the texts that thing it's helpful to demonstrate OO concepts by modeling things like "cat is a subclass of animal" :/
Not to derail too much, but.
I had a textbook that started to explain OOP by basically saying "A dog is a class. A dog has a tail that can be in a wagging state or not. A dog has a name..."
And I'm sitting there thinking "No, dog's don't 'have' names. We call them names and they respond to names. They sometimes know their name. It's a different kind of 'have' than having a tail. I have a name for my dog. Should the person class have a dogs_name member variable now?" A tail is a subset of a dog. A name is a property of the abstract system in which the dog resides.
A class is a model of something else. You can model a dog with an object, but you can't know how good of a model it is unless you dig down into it and see where it breaks down. It will break down, because software is an abstraction, and abstractions, being abstract, are not the things they are abstractions of. And there are not many things that behave like OO objects because they are far too simple to represent reality in any high-fidelity sense. And it's dishonest to pretend they do.
Not to say there isn't some pedagogical advantage to using the analogy, I just think a better one could be used. Like talking about messages or something.
Hopefully it wasn't "POOP": http://www.amazon.com/gp/product/1878739441.
The most insidious problem with these kinds of models is that they are trying to model reality.
Your example is modeling a real dog better than the sample you started with, but... what computer programs acts on a real, live dog, directly? Computer programs pretty much never interact directly with external reality, only with other software -- interfaces to hardware and other software systems. So software needs to be smart and clean about dealing with the actual interfaces. It's important to understand how reality will interact with the interfaces, of course, but relationships there are often irrelevant or misleading to designing the software.
So all of these poor students, when actually charged with designing a program dealing with, say cashiers, store managers, purchases, reports, etc., start off "well, cashiers and store managers are people, and actually both employees... I guess we need a company object in here", etc.. This almost always leads them into a mess, because they get lost in here before they even learn properly what the goals of their system are. E.g., this program just needs to run on the store managers PC, pull data from a dir full of files from the POS, and generate reports (in which the cashier is just another column value).
If they started OO as "modeling reality", just writing a program that does what's needed feels like cheating ("TODO: not really capturing the OO relationships here! rework for v2") -- and that's a bad thing.
This essay assumes the wrong answer. The intelligence has to be built into the item, not the appliance, just as we do now. Packages have messages such as "Refrigerate after opening" on them. Anything that needs to be refrigerated will need to communicate that need, along with details such as temp, to the automated system.
The article is on the difficulty of writing specifications. The fridge is a metaphor. Your insight amounts to “we can always assume that the specification has already been written and correctly implemented on the other side of the interface”.
This remark has a place in the discussion, but not the one you probably think.
So one only puts labelled packaged things in the refrigerator? I was recently thinking about the phenomenon of packaging but this takes it to the next level. I'm not sure if it feels ultra-modern or dystopian.
I was going down the...
...but then I realised this is the AI contextual knowledge problem.scan label if (grep "keep refridgerated after opening") AND (status OPEN) then store in fridge else askAnd what do you do with Avocados?
They don't last long enough in our household to reach the fridge. They get eaten as soon as they land.
My point being: contextual knowledge. I suppose you could program a fridge loading machine to watch humans for a couple of weeks then work out some rules...
I guess I need to put best before dates on all my fresh produce then. Otherwise how will I know whether I need to refrigerate my head of cabbage after opening it, and whether it is still edible or not?
Best before dates are a waste of time. I noticed this travelling in less devloped countries where they don't usually have them. And plenty of times I have had chicken that smells off despite being before the date on the packet. I had one cheese that got way better after being a month past the date.
Best before dates are a really good idea if you want to reduce the number of food poisonings in a large population. Food is (statistically) very safe before the best before date, assuming proper storage. Most of the time it's still safe well past that date, but you would dramatically increase the number of people who get sick.
It's the same with pasteurized milk. Unpasteurized milk is mostly safe to drink, but occasionally you get really sick. In a large population the difference is noticeable.
Again the same with the much stricter cleanliness rules for restaurants and the like. Usually it's safe to store prepared food without refrigeration for a day, restaurants mustn't. It's also mostly safe to cook on a dirty stove, restaurants mustn't. The difference between your home kitchen and the restaurant is the number of people served.
Best before dates have nothing to do with safety, they are about quality. They are (mostly) voluntary and set by the manufacturer.
http://www.webmd.com/a-to-z-guides/features/do-food-expirati...
I think somebody should extend this metaphor to demonstrate why garbage collection is rubbish.
Side-note: a lot of fresh chicken will smell bad for about 5 minutes when you remove it from a vacuum-sealed package, but the smell quickly dissipates and the chicken is good to eat. In the UK there's a label on some brands of fresh chicken to that effect. I must have thrown away a fair bit of good chicken before first realising this...
Well, with something like cheese it's a roll of the dice (except in a cheese production facility run by experts). It might well be the case that the random mold and bacteria hanging around your location make the cheese taste better. It also might taste terrible. It also might kill you or at least make you very sick. Listeria has about a 20% case fatality rate even with medical treatment.
We cannot always change the real world to adopt to our spec needs -- e.g. make things that need refrigerated communicate that need.
There are literary thousands of things we refrigerate that don't come in packages with neat "refrigirate" labels.
Although work is then required to package items appropriately, rather than the refrigerator automatically knowing what to do with items.
(More on-topic,) I think the point presented still holds. It's not possible to make an air-tight spec for absolutely everything.
The question is wrong, as it stands the answer is "any non-fluid or contained fluid that will fit".
"What should one store in a refrigerator?" is a better question.
Yeah. He was really trying to answer the 'should' question.
One could also refrigerate contained gases.
As your parent comment explicitly stated. Gases are fluids.
I would argue that pretty much anything you would put into your refrigerator is contained inside packaging. Sometimes that packaging is just a simple plate.
I put a cat in the refrigerator more than once - for some reason, my cats loved sitting there for few mintues long when there were young. There were definitely not packaged.
I put a lot of fruit and vegetables in my fridge with no packaging. Why would I contain them?
While arguably not correct, is there any particular reason to downvote this? I think it's a fairly valid point
It reminds me of this "What is a Photocopier?"
"Anything that fits in the refrigerator and will remain contained within it." Covers all uses for refrigerators and prevents anyone from putting bulk liquids, penguins, coyotes, live hand grenades, radioactive material, nuclear weapons or Indiana Jones inside.
But not pet hamsters!
Reminds me of a question I have been wondering about: Can you formally specify what is the purpose of a suitcase?
In principle, you could dump all your clothes, toiletries, etc. in a pile on the airport checkin counter, and if system were organized enough, it could deliver all your stuff to hawaii and lay it all out on the hotel bed for you.
E.g., a robot would scan all your belongings at the airport, and dump them all into a big pipe... each item would get properly routed to your hotel room... kinda like how the internets work!
Is it just a question of organization? "Everything in this suitcase belongs to this person and should move together to the same destination."
I can invent on the spot 10 uses for a suitcase that have nothing to do with moving things belonging to a single person together. First of all, you may have a couple packing their items in one suitcase. The suitcase may be used as a chair, as a table, as a structural support, to protect from rain, sun, lasers, alpha and beta radiation, it can be used as a weapon or as a shield, as a makeshift hammer, etc.
The problem is in your questions. "Purpose" is not something that is a part of an item. It is a part of our mind.
> "Purpose" is not something that is a part of an item. It is a part of our mind.
I love this insight.
> kinda like how the internets work!
Using this analogy, isn't a suitcase roughly equivalent to a packet? It's tagged with source/destination, and basically standardised so the routing gear doesn't need to care about the specific items you are routing.
You know, I think the analogy might actually be the wrong way round....
The analogy goes even further!
At certain points along a route, deep packet inspection is performed, and some packets will be modified to remove contents that the country in question does not want to route.
Bacon, cheese, steak, and bottled beer. Being single sure makes writing specs easier.
don't forget ketchup.
Heathen!
I think this is hinting at the problem that occurs in OOP, when the business rules of the system are expressed with virtual methods in classes as part of an inheritance chain, in the business domain
Example: eric lippert tries to model an RPG in OOP and tries to model the character "uses" command: http://ericlippert.com/2015/05/11/wizards-and-warriors-part-...
Anything that you can fit in and that you can also easily get out again.
(The latter requirement rules out not only liquids but also e.g. a pile of salt or rice.)
So, your pet cat?
If this is how you're defining requirements for software or new product creation you're doing it wrong.
The goal should never be to describe every single outcome or scenario- the goal should be to build understanding between business/product/development team so that they understand the point of the work that the software replaces. It's no different with hardware or really any new product creation. The goal is to create a conversation that gets us to solving the problem- when the spec gets to covering all cases the chances we get this wrong and stray from solving the actual problem goes up massively.
The article is making a point about understanding or what happens in a conversation for something like requirements, neither you nor him provided an exact answer as to how to define requirements, because it's something we havn't yet been able to automate.
Also it's starting a conversation about the very topic..
Good point- that all said, if we're automating requirements we're not solving the problems that tend to matter. The key to requirements building is in the process. The best process I've found so far is User Story Mapping (Jeff Patton has an amazing book on it)
I say we make a refrigerator library; then anyone can define a refrigerator within the library; then we can call the function and apply it to out arbitrary needs. #include <refrigerator.h>
Wrong. We need refrigeration factory that returns a class called RealRefrigerator that extends AbstractRefrigerator and implementing IRefrigerator, which then must be DI by configuring external XML (bonus points if the xml itself is stored in the database, so no way to reach the config with grep).
The outdated approach of if (food.canSpoil()) { refrigerator.put(food) } was too burdensome and did not conform to all of the best practices.
Amazing how many people try to create a specification without knowing the problem.
A specification should be for a solution to a problem - "We need a way to keep xxxxx cool". That problem defines what needs to go into the refrigerator from the outset.
What's the actual problem space here ?
You can sometimes explain better by a set of examples rather than an explicit categorical description. The base set of examples I started with is what my mother put in her refrigerator.
I'm reminded of an excellent quote from Bertrand Russell:
"Everything is vague to a degree you do not realize till you have tried to make it precise."
cream, mayonnaise, ketchup, soda and PAPER, SNOW, A GHOST.
- Joey Tribbiani, Friends episode 10.11
The penguin line made me lol.
I'm going to repost something I had said in response to this article on another site. I think it's an awesome example of what can happen when you create a language with extensibility in mind.
-------------------
Scala solves this problem really well with typeclasses.
You can define a typeclass like
case class Refrigerated[T](thing: T) // this is just something holding things that have been refrigerated.
trait Refrigeratable[T] { // this is the typeclass
def refrigerate(thing: T): Refrigerated[T]
}
Now we have a refrigerated object that holds some object that's been refrigerated, and it looks like I'm about to do some class composition, but I'm not. Bear with me.Now, we have some sort of data class
case class Pillow(fluffiness: Int, warmness: Int)
Pretty straight forward, we now have a Pillow with measurable fluffiness and warmthNext, lets implement refrigerated for pillow.
implicit val pillowRefrigerable: Refrigerable[Pillow] = new Refrigerable[Pillow] {
def refrigerate(pillow: Pillow): Refrigerated[T] =
Refrigerated(pillow.copy(warmness = pillow.warmness / 2))
}
So there's an implementation of Refrigerable for pillow. Refrigerating a pillow just cuts the warmness in half.So actually using the Refrigerable stuff. There's two ways to go about this. One way is to just use the Refrigerable instance to refrigerate the pillow.
def refrigeratePillow(pillow: Pillow): Refrigerated[Pillow] = pillowRefrigerable.refrigerate(pillow)
Nothing special there. You could basically do that in any language. So how does scala do it better? Well, we can define a refrigerate method for anything Refrigerable like this: def refrigerate[T](thing: T)(implicit refrigerableInstance: Refrigerable[T]): Refrigerated[T] =
refrigerableInstance.refrigerate(thing)
Now this is really cool. Anything type that we have a Refrigerable instance for, can be used as an argument for refrigerate. And we don't have to explicitly state what Refrigerable instance we're using. Calling it looks like val refrigeratedThing = refrigerate(anythingWithARefrigerableInstanceHere)
Okay. We still haven't gained a whole lot. All we've done so far, is make it so we don't have to explicitly state what Refrigerable to use. So let's go an extra step. Let's make it so we just call refrigerate on the Object itself rather than passing the object as an argument to a method. This is possible, because scala let's us make extension methods for generics. implicit class RefrigerableOps[T](thing: T)(implicit refrigerableInstance: Refrigerable[T]) {
def refrigerate: Refrigerated[T] = refrigerableInstance.refrigerate(thing)
}
Okay, now this is really cool. We've defined a method for any type for which we have Refrigerable in scope. This means we can now refrigerate our pillow more easily: val refrigeratedPillow = myPillow.refrigerate
What?! That's great! And it gets better. Now that we've implemented this boilerplate, giving other things this wonderful syntax is easy. Let's say I want to refrigerate my cousin, because she's too hot. case class Cousin(hotness: Int)
implicit val refrigerableCousin: Refrigerable[Cousin] = new Refrigerable[Cousin] {
def refrigerate(cousin: Cousin) =
Refrigerated(cousin.copy(hotness = cousin.hotness - 1))
}
Now we can make our cousin less hot! Great! val refrigeratedCousin = cousin.refrigerate
This is basically a good way to make things open to extension without subclassing it's awesome!You can even do more to simplify making the Refrigerable instances. You can effectively make them one liners.
A porpoise